d2d0d0f4fd6e1780d37dbffdd4c8a2f0c8f957de
577 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d2d0d0f4fd |
spec: 0102 project-as-crate load boundary (boss-signed)
Grounding-check PASS as the autonomous signature: 7 load-bearing current-behaviour assumptions each ratified by a named green test; greenfield surfaces (descriptor, loader, Aura.toml) excluded per contract. Design decisions and provenance: the decision-log on the milestone reference issue. refs #180 |
||
|
|
d7c935dd77 |
audit: cycle 0101 tidy (drift-clean after one ledger alignment)
Architect review of 8814e295..HEAD. What holds: the cosmetic-only claim is verified (every -/+ pair in the code diff is a string literal; no exit(), channel, or control-flow byte moved; the C14 usage=2/runtime=1 partition preserved at every touched site); grep gates exact (zero lowercase usage: literals, 11 'Usage: aura' source lines = 10 edited + the pre-conforming run_args_from); fieldtests corpus and refusal diagnostics byte-identical. The recorded spec deviation (3 additive house-style pins) strengthens coverage over a real pin gap and is decision-logged on the issue. Regression: cargo build rc=0, cargo test --workspace rc=0 (cli_run 133 passed / 0 failed), clippy -D warnings rc=0, doc build rc=0. No baselines exist to move, so nothing to ratify. Drift resolved in this commit: the C14 ledger note still described the casing normalization as deferred after #179 landed - rewritten to record the landed house style (usage lines 'Usage: aura <verb> ...', refusal diagnostics deliberately unprefixed). Ephemeral cycle artifacts removed per convention: spec 0101, plan 0101. refs #179 |
||
|
|
9402afe958 |
polish(cli): normalize usage-message casing to the clap house style
Every hand-rolled usage line now reads 'Usage: aura <verb> ...' — capital prefix plus the program name, the shape clap itself and the built-in run branch already spoke. 10 literal edits: 6 lowercase 'usage:' flips (graph introspect, run blueprint x2, runs family, mc blueprint, mc built-in), 4 bare closures gain the prefix (sweep/walkforward, blueprint + built-in branches); the mc built-in line names the program in both |-separated alternatives. Refusal diagnostics, the conforming run_args_from literal, clap output, and the fieldtests corpus stay byte-identical; exit codes keep the usage=2 / runtime=1 partition. Lockstep pin: the single casing-sensitive assertion (mc --real) flips to capital 'Usage'. Three additive regression tests pin the house style itself (bare-closure prefix, both mc alternatives, mc blueprint branch) — the pre-existing pins checked only verb tokens / a single Usage occurrence; deviation from the spec's no-new-test-bytes wording recorded on the issue. Verification: cargo test --workspace rc=0 (cli_run 133 passed), clippy -D warnings clean, grep gates exact (zero lowercase 'usage:' literals; 11 'Usage: aura' source lines), smoke 'aura sweep --strategy bogus' prints the house-style line and exits 2. closes #179 |
||
|
|
ab7f0b0650 |
plan: 0101 normalize CLI usage-message casing
One lockstep task: 10 byte-exact literal edits (6 lowercase usage: flips, 4 bare closures gain the 'Usage: aura ' prefix, mc built-in gets the program name in both alternatives) + the single casing-sensitive pin flip in cli_run.rs, then build / targeted test / full suite / clippy / grep gates / diff-shape gate / sweep smoke. refs #179 |
||
|
|
7a386dc9bb |
spec: 0101 normalize CLI usage-message casing (boss-signed)
Single house style for every hand-rolled usage line: 'Usage: aura <verb> ...' (clap's capital prefix + program name), 10 literal edits + the one casing-sensitive test pin in lockstep. Refusal diagnostics, the conforming run_args_from site, clap output, and the fieldtests corpus stay byte-identical. Grounding-check PASS is the autonomous signature; scope-fork decisions are recorded on the issue. refs #179 |
||
|
|
8814e29597 |
audit: cycle 0100 tidy (drift-clean after one ledger alignment)
Architect review of 88e9c9a..HEAD. What holds: token purity of the rename (removed + mapping == added, 33 sanctioned prose rewordings, numeric golden bytes untouched); CLAUDE.md invariant 7 now matches the ledger C10 section clause-by-clause; no silent alias for the old selectors (unknown-selector exit-2 path is tested). Regression: cargo build / clippy -D warnings / doc build clean; cargo test --workspace rc=0, 51 targets, 0 failures. No baselines exist to move, so nothing to ratify. Drift resolved in this commit: the C10 terminology note (INDEX.md) still called Stage-1 a surviving identifier name after the glossary recorded the rename - aligned to name the r-family rename (#174). Remaining low items: the spec's own survivor-list contradiction was ratified and recorded on the issue; the RGrid const-seeding debt is recorded on the harness-retirement issue (refs #159). Ephemeral cycle artifacts removed per convention: spec 0100, plan 0100, and the spent prior-milestone fieldtest spec. refs #174 |
||
|
|
4de6d5cbad |
rename: retire the stage1-* family for the r-family (r-sma / r-breakout / r-meanrev)
The stage1 ordinal has been dead vocabulary since the C10 reframe dropped the two-stage research model: a 1 structurally implies a 2 that no longer exists. The family is renamed by its live discriminator - the R yardstick - with members named by their signal, uniform with their signal-named siblings (sma, macd, momentum): - selectors: stage1-r -> r-sma, stage1-breakout -> r-breakout, stage1-meanrev -> r-meanrev (old tokens are usage errors, exit 2 - no silent alias) - identifiers: Strategy::RSma/RBreakout/RMeanRev, HarnessKind::RSma, r_sma_*/r_breakout_*/r_meanrev_*, wrap_r, run_signal_r, RGrid, R_SMA_* - persisted identity: the sma_signal composite (param prefix sma_signal.fast.length / .slow.length; fixtures regenerated; content-ids shift - no test pins a literal hash, the registry parses no record names) - e2e test files git-mv'd to r_sma_e2e / r_breakout_e2e / r_meanrev_e2e - dead Stage-1/Stage-2 prose reworded to post-C10 vocabulary across rustdoc, Cargo.tomls, ledger live lines, and the glossary (historical entries stay; fieldtests corpus untouched) - CLAUDE.md invariant 7 rewritten to record the ratified C10 reframe faithfully (the token-swap alone would have laundered the retired gated-currency/realistic-broker design into unmarked live prose); the unbacked account-mode clause dropped Verification: cargo build/test --workspace green (51 targets), clippy -D warnings clean, doc build clean, acceptance grep gate leaves exactly the one resampling-stage false positive (harness.rs), smoke: --harness r-sma runs, --harness stage1-r exits 2 with the new usage line. Decision log: forks and rationale recorded on the issue (reconciliation + implementation-phase comments). closes #174 |
||
|
|
e1b04439c0 |
plan: 0100 rename the stage1-* family to the r-family
Five ordered tasks: aura-cli source + include_str-coupled fixtures, the cli_run suite, engine e2e git-mvs + doc-refs, dead-ordinal prose across rustdoc/CLAUDE.md/glossary/ledger live lines, and a workspace grep gate. Substitutions are ordered longest-token-first; every task carries its own verification gate. refs #174 |
||
|
|
f029c35374 |
spec: 0100 rename the stage1-* family to the r-family (boss-signed)
The stage1 ordinal is dead vocabulary since the C10 reframe; the spec renames the selector/identifier family to r-sma / r-breakout / r-meanrev (signal-named members under the R-yardstick marker), reworders dead Stage-1/Stage-2 doc prose, and pins the survivors (history, fieldtests). Signed autonomously under /boss on the grounding-check PASS; fork decisions recorded on the reference issue. refs #174 |
||
|
|
88e9c9a539 |
fix(cli): symmetric sweep/mc family-verb polish (closed error, mc seed label, mandatory-knob docs)
Three polish items surfaced by the World/C21 milestone fieldtest:
- A sweep of a fully-bound (closed) blueprint is refused up front with a clear
"this blueprint is fully bound; nothing to sweep" message — the symmetric
inverse of blueprint_mc_family's closed-blueprint guard — instead of leaking a
misleading UnknownKnob for a knob that is not unknown but bound out.
blueprint_sweep_family's error contract widens to String; the sweep terminal's
BindError (a genuine unknown/kind-mismatch axis) still surfaces verbatim.
- mc reproduce lines now carry each member's seed=<N> label. Monte-Carlo members
hold no tuning params, so the member label was blank; the seed is each draw's
realization identity. Sweep / walk-forward labels (which echo params) unchanged.
- docs (design ledger + glossary): state that every open knob --list-axes prints
is mandatory on sweep / walkforward — a subset is refused with the missing knob
named (BindError::MissingKnob), there is no default; pin a knob you do not want
to vary with a single-value axis.
RED-first for the two behaviour items. One existing unknown-axis E2E is re-pointed
from the closed fixture (which now hits the new "nothing to sweep" pre-check) to
the open fixture; it still exercises UnknownKnob("nope") specifically — resolve
raises UnknownKnob in phase 1 before MissingKnob in phase 2 — so the property is
preserved, not weakened.
closes #178
|
||
|
|
a45d16b054 |
docs: add a top-level README mapping the shipped CLI surface
The repo had no README, and a milestone fieldtest found the whole blueprint-data verb family (run / sweep / mc / walkforward over a blueprint.json), the graph build / graph introspect construction surface, and the op-list document shape discoverable only from the design ledger — a downstream consumer with just the binary could not find the milestone's own surface. Document them as a discoverability map: each verb's purpose and shape, the open-vs-closed and family concepts, and a worked op-list example (copied from a compiling test). Per-flag detail is kept light and delegated to `aura <cmd> --help` and the ledger, so the README neither duplicates nor collides with the in-flight help rework and does not drift as flags evolve. This is the discoverability half of the harness-retirement work; retiring the hard-wired harnesses themselves stays gated on the project-as-crate authoring layer. refs #159 |
||
|
|
8b2defa653 |
fix(cli): reject a silent-vacuous blueprint Monte-Carlo instead of returning it
`aura mc <bp.json>` builds a per-seed synthetic price walk with a fixed 60-bar SyntheticSpec. A deeper-lookback loaded blueprint warms poorly over that walk, so every seed can collapse to a bit-identical draw and the family was returned as an Ok result — a single point masquerading as a distribution, a wrong result with no error. Guard it: with >= 2 seeds, if every draw's metrics equal the first draw's, refuse with a named error (C10 refuse-don't-guess), rather than auto-sizing the walk (which would have to guess a warm-up depth the harness does not surface). Compares `report.metrics`, not the whole RunReport — the manifest seed differs per draw by construction, so a whole-report compare could never detect the collapse. RED-first; the existing `blueprint_mc_family_seeds_differ` pins that a legitimate (differing-draw) MC is not falsely rejected. Interim guard only — the real-data moving-block-bootstrap headline stays gated on the DataServer seam. refs #172 |
||
|
|
e20dd9ae49 |
Merge main into the clap-adoption cycle — re-integrate the two parallel CLI fixes
main advanced with two `fix(cli)` commits ( |
||
|
|
fa0d30c0fd | tweak(aura-cli): understate the --help about-line (drop the game-engine framing) | ||
|
|
27f0f8ea11 |
audit(0099): cycle close — CLI clap adoption; ledger refreshed (C14); rm ephemeral spec/plan
Architect drift review (scope 780d823..HEAD, the sole gate — no regression script) returned one medium ledger-gap, now resolved; otherwise drift-clean with a positive What-holds: - invariant 8 / C16 engine-domain separation preserved: clap is confined to crates/aura-cli/Cargo.toml; the whole diff touches only aura-cli/ + Cargo.lock + ephemeral docs; no engine/std/composites/analysis/registry/core/ingest crate mentions clap, so the frozen deploy artifact structurally cannot pick it up (aura-cli is a leaf binary). The 16 new lock entries are exactly clap's tree. - C16 per-case admission honest: clap admitted with a documented rationale at the Cargo.toml site (replaces the hand-rolled parser + ten help surfaces; dev-loop tax, not frozen-artifact tax), the same admission form as sha2/libc. - C14 automation-face served, execution layer intact: the usage=2/runtime=1 partition, scoped --help, --version, and GNU flags match the spec; the domain fns keep their signatures (arg-plumbing via thin *_from adapters); new behaviour is pinned (partition property test, version, scoped-help, dual-grammar stray-positional guard). Ledger refreshed: the C14 realization block now records the clap adoption + the exit-code partition (usage=2/runtime=1) as a durable automation contract, before the ephemeral spec that first stated it is removed (the drift item the architect raised). Deferred/forward: error-message casing normalization (#179, idea); the machine-first help surface stays on the #157/C21 track (Fork B settled this cycle as human/GNU convention compliance). Verified green (orchestrator, this session): cargo build --workspace clean; cargo clippy --workspace --all-targets -- -D warnings clean; cargo test --workspace green. Cycle drift-clean. closes #175 |
||
|
|
fa42bf3878 |
feat(0099): CLI exit-code split (iteration 2) — usage=2, runtime=1
Apply the clean exit-code partition (#175 deviation #8) on top of the clap migration: runtime failures now exit 1, usage errors stay exit 2, with no same-class inconsistency. Partition (attribution principle): exit 2 = a command-line fault (a bad flag value, an inapplicable combination, or the content of an argv-named file); exit 1 = the command was well-formed but the environment / recorded state it needs is missing, or piped stdin data is bad. The 6 boundary cases the spec's "parse-time vs run-time" rule under-specified are resolved on #175 (malformed/open argv blueprint -> usage 2; stdin op-script content -> runtime 1; applicability refusals -> usage 2; unknown --axis / --metric -> usage 2). Flipped 2->1 (runtime): no local data, no recorded geometry, no recorded run/family, "run has no tap named", trace-name collision, family/trace persist-write failures (normalizing the lone generalize inconsistency -- all persist -> 1 together), missing/corrupt content-addressed store state (the reproduce path), chart-read failures, and graph stdin op-script content + stdin-read I/O. reproduce-diverged stays exit 1. Usage sites (clap parse, argv-applicability guards, the dual-grammar blueprint-file read/parse) stay exit 2. Tests: ~8 domain-refusal pins flipped Some(2)->Some(1) (message substrings unchanged), the four runtime tests renamed _exit_2 -> _exit_1, and a partition property test added. Orchestrator fix after the loop: 3 sibling no-data skip-guards (run_real_with_trace + the two generalize cross-instrument tests) that the plan's Task-1 list missed -- left at Some(2), they would fall through to assert Some(0) and FAIL on a data-less machine; flipped to Some(1) for consistency with the flipped code. Deferred (cosmetic, filed forward): full "Usage:" / "usage:" / bare error-message casing normalization -- no functional impact, high pin-churn. Verified green (orchestrator, this session): cargo build --workspace, cargo clippy --workspace --all-targets -- -D warnings, and cargo test --workspace all clean (0 failed across every test binary). This completes the #175 clap-adoption cycle (iteration 1 = clap migration at 366170a; iteration 2 = this exit-code split). refs #175 |
||
|
|
ffb2624dd7 |
plan: 0099 CLI exit-code split (iteration 2)
Iteration-2 plan for #175: apply the clean exit-code partition (deviation #8) on top of the clap migration — runtime failures exit 1, usage errors exit 2, no same-class inconsistency. Uses the attribution principle (command-line fault = 2, missing-environment/bad-stdin = 1) to resolve the 6 boundary cases the spec under-specified. refs #175 |
||
|
|
366170aeab |
feat(0098): CLI clap migration (iteration 1) — scoped help, --version, GNU flags
Replace the hand-rolled aura-cli argv parser with a clap derive parser. Delivers, all from one declarative source: - scoped `aura <sub> --help` (stdout, exit 0) — each subcommand's own Options section; retires the #131 uniform-global-blob help - `--version` / `-V` → `aura 0.1.0` (stdout, exit 0) - GNU `--flag=value`, the `--` end-of-options terminator, and long-option abbreviation (`--harn` → `--harness`) Architecture: one root Cli/Command enum, one `*Cmd` struct per subcommand. The four dual-grammar subcommands (run/sweep/walkforward/mc) map the loaded-blueprint branch as an optional `[blueprint]` positional + a post-parse `is_file()` dispatch on a single-sourced predicate; each built-in handler re-asserts a stray-positional guard (refuse-don't-guess) so clap's optional positional cannot silently swallow a typo (pinned by two new E2E tests). The execution layer (run_*/emit_*/runs_*/reproduce_*) is untouched — only arg-plumbing changes, via thin `*_from` adapters reusing the existing value helpers. Exit codes behaviour-preserved: clap parse errors exit 2 (matching the old usage-error=2); domain refusals stay exit 2; reproduce-diverged stays exit 1. The exit-code split (2=usage / 1=runtime) is iteration 2. clap is admitted under the C16 per-case review (research-side CLI, invariant 8 untouched — a dev-loop compile tax, not a frozen-artifact tax). Forced plan corrections (implementer; verified against the diff): - Step 6's deletion of the `parse_*_args` fns orphaned ~34 grammar unit tests that called them; those were deleted and that grammar coverage moved to the renegotiated cli_run.rs E2E pins (`parse_select` kept + retested). - run_malformed_cost_value_...: a bad cost value is now a clap value-parse error (no "Usage:" line); renegotiated to pin exit 2 + empty stdout + the flag name "--cost-per-trade"; the units note stays pinned via `run --help`. - `allow_hyphen_values` on the three cost flags so `--cost-per-trade -0.5` reaches the non-negativity guard (else clap rejects -0.5 as an unknown option). - Deleted the now-dead `RealWindowGrammar` (clippy -D warnings). Orchestrator additions after the loop: - Enabled long-option abbreviation (`infer_long_args` on the root — one attribute, it propagates to subcommands) + a test, closing spec acceptance criterion 4 which the plan's RED tests did not cover. Decided to deliver rather than amend the spec: the two ratified decisions conflict on this low-tier item — Fork B (GNU compliance, getopt_long abbreviates) vs F5 (LLM/automation-first, human-only niceties deprioritized) — and the cost tiebreaker (one attribute, not per-struct work) resolves to deliver. Carry-on debt (not this iteration): the error-message "Usage:"/"usage:"/bare casing is now mixed (clap's capitalized "Usage:" beside preserved lowercase aura messages); a deliberate quality-hold since the casings are pinned by renegotiated/preserved tests. Cosmetic; a candidate for the iteration-2 exit-code-split cleanup. Verified green (orchestrator, this session): cargo build --workspace, cargo clippy --workspace --all-targets -- -D warnings, and cargo test --workspace all clean (0 failed across every test binary, including the renegotiated cli_run pins and the new --version / scoped-help / GNU-flag / dual-grammar tests). refs #175 |
||
|
|
215f403496 |
plan: 0098 clap migration (iteration 1)
Iteration-1 plan for #175: replace the hand-rolled aura-cli argv parser with a clap derive parser (scoped `aura <sub> --help`, `--version`/`-V`, per-flag Options section, `--flag=value`/`--`/long-opt abbreviation), behaviour-preserving on exit codes. Task 1 adds clap + RED tests for the new behaviour; Task 2 is the atomic migration + renegotiation of the help/usage pins the migration inverts (the four dual-grammar subcommands mapped as optional [blueprint] positional + post-parse is_file() dispatch; execution layer untouched). The exit-code split is iteration 2. refs #175 |
||
|
|
6a775f700f |
fix(cli): walkforward validates its --axis grid once, not once per window
`aura walkforward <bp> --axis <name>=<v>` emitted a rejected axis's diagnostic more than once (a racy 1-3x) when the grid did not resolve. `blueprint_walkforward_family` resolved the axes *inside* the per-window closure, and `walk_forward` fans that closure out across the windows in parallel — so several windows each `eprintln!` the same `BindError` and `exit(2)` before any one exit tears the process down. Axis resolution is window-independent, so it is hoisted to a single dispatch-boundary pre-flight (mirroring `aura sweep`, which validates its axes once before any member runs): the first in-sample window is resolved up front, surfacing the `BindError` exactly once; the per-window closure then resolves already-validated axes and cannot re-raise (`expect`). RED-first: cli_run.rs `aura_walkforward_emits_an_unknown_axis_rejection_once` drives the verb 20x and asserts the rejection is single every run (the emit count was racy, so a single invocation would be a flaky assertion). Surfaced by the World/C21 milestone fieldtest. closes #177 refs #170 |
||
|
|
e2e3a51c6c |
spec: 0098 CLI GNU/clig.dev compliance via clap adoption (boss-signed)
Replace the hand-rolled aura-cli argv parser with a clap derive parser: scoped `aura <sub> --help`, `--version`/`-V`, a per-flag Options section, and `--flag=value`/`--`/long-opt abbreviation for free. Two iterations — (1) clap migration, behaviour-preserving on exit codes; (2) exit-code split (usage=2, runtime=1). clap is admitted under the C16 per-case review (research-side CLI, invariant 8 untouched). Forks ratified by the user (clap over hand-rolled; GNU-compliance over the machine-first reframe; exit-code Option A) and the three spec-time derived decisions (dual-grammar clap mapping, parse-vs-runtime exit classification, two-iteration split) are recorded on #175. Boss-signed on grounding-check PASS (independent, fresh-context; 13 current-behaviour assumptions all ratified by named green tests). refs #175 |
||
|
|
dec07809df |
fix(cli): aura run refuses an open blueprint with a clean exit 2, not a panic
`aura run <blueprint.json>` bootstraps the loaded signal over the EMPTY param point (a closed-blueprint assumption) and `.expect()`s `compile_with_params`, which panics (exit 101, ParamArity) when the blueprint carries >=1 free knob. The sibling `aura mc` already refuses an open blueprint cleanly at the dispatch boundary; `run` now does the same. The `["run", ..]` `.json`-discriminator arm probes the wrapped param_space (`blueprint_axis_probe`, the single source of that wrap) and, when it is non-empty, emits a "run requires a closed blueprint … N free knob(s) — bind them or use `aura sweep --axis`" diagnostic and exits 2 — mirroring `blueprint_mc_family`'s closed-guard. No panic on a naive consumer's first move (author an open blueprint, run it). RED-first: cli_run.rs `aura_run_rejects_an_open_blueprint_without_panicking` pins exit 2 + the named requirement + no `panicked`. Surfaced by the World/C21 milestone fieldtest. closes #176 refs #170 |
||
|
|
780d823067 |
fieldtest: World/C21 milestone — 4 examples, 9 findings (functional promise holds)
Milestone-close validation of the World/C21 blueprint-data family surface, run
from the PUBLIC interface only (design ledger + op-script grammar; blueprints
authored as a consumer via `aura graph build`, no crates/ source read). Binary
built from
|
||
|
|
4710fccf32 |
audit(0097): cycle close — IS-refit walk-forward over a loaded blueprint; ledger refreshed (C24/C18); rm ephemeral spec/plan
cycle 0097 tidy (clean). Architect drift review over 485f3c8..HEAD: no code drift, no debt. Regression: no dedicated script (architect is the sole gate); its "What holds" is non-empty (design commitments confirmed against the diff): - Inv. 8 / 9: the cycle touches only crates/aura-cli (main.rs + cli_run.rs + the ephemeral spec/plan); walk_forward/WindowRoller/FamilyKind::WalkForward/ append_family/put_blueprint are read-only reuse, no engine/registry change. - Inv. 1 / 2: blueprint_walkforward_family reuses the generic walk_forward roller (windows disjoint-parallel, across-sim); each IS-sweep/OOS-run sees only its window's windowed_sources; IS precedes OOS per window — no look-ahead. - Reproduce lockstep: the reproduce_family_in WalkForward arm rebuilds each OOS slice from stored.manifest.window (before the _ => run_sources fallthrough that would rebuild the wrong full-window source); winner params via the shared manifest->cells recovery; pinned by the reproduces_bit_identically E2E. - Structural mirror + panic-safety: one-substitution-deep twin of the hard-wired Stage1R arm (select_winner + walk_forward reused, metric sqn_normalized); run_blueprint_walkforward follows the content-addressed sibling pattern (no ensure_name_free); blueprint_sweep_over returns Result<_,BindError>, a bad axis is in-closure exit 2 (never a panic); run_oos_blueprint derives pip internally (7 args, no #[allow]). Ledger: refreshed the C24 realization block (docs/design/INDEX.md) — replaced the now-false "Walk-forward is deferred (#173, dep #169)" sentence with the "IS-refit walk-forward shipped (cycle 0097)" note; and extended the C18 reproduction note — reproduce now spans the third family kind (WalkForward), so all three FamilyKind variants persist AND reproduce through the one shared topology_hash+put_blueprint hook. Milestone: the World/C21 blueprint-data family surface (run/sweep/mc/walkforward/ list-axes/reproduce) is coherent and complete per the architect review — no structural gap. This audit proves drift-clean; a green end-to-end MILESTONE FIELDTEST remains the deliberate gate to formally close the World/C21 milestone. Ephemeral spec/plan git-rm'd per the lifecycle convention. refs #173 |
||
|
|
ff20f74e8f |
feat(0097): IS-refit walk-forward over a loaded blueprint — aura walkforward <bp.json> --axis
Ship the World/C21 milestone's last piece (Arm A, #173): a true in-sample-refit walk-forward over a loaded blueprint. `aura walkforward <blueprint.json> --axis <name>=<csv> [--axis …] [--select argmax|plateau:mean|plateau:worst]` rolls 24/12/12 IS/OOS windows over the synthetic span; per IS window it re-optimizes the blueprint's params over the user's --axis grid (the #169 prefixed names), selects the winner by sqn_normalized, runs it out-of-sample, and aggregates the per-window OOS reports into a FamilyKind::WalkForward family — content-addressed (put_blueprint) and aura-reproduce bit-identical. Structure mirrors the hard-wired stage1-r walk-forward arm one substitution deep: the generic engine walk_forward driver + select_winner + the synthetic schedule are reused; only the per-window IS-sweep (blueprint_sweep_over) and OOS-run (run_oos_blueprint) source the loaded blueprint via cycle-0096's blueprint_axis_probe. reproduce_family_in gains a WalkForward arm reconstructing each OOS window's windowed slice from the member manifest's window bounds (winner params via the shared manifest->cells recovery, as the MonteCarlo/Sweep arms do). Panic-safety: blueprint_sweep_over returns Result<_, BindError>; a bad/unknown --axis is a clean in-closure exit 2 (mirroring the hard-wired arm's select_winner handling), never a panic — pinned by the rejects_an_unknown_axis E2E. A no-axis invocation (nothing to re-fit) is a usage error; a malformed blueprint is rejected at the dispatch boundary (exit 2, no panic). Reduce-mode members carry R-metrics (no raw pip curve) → empty stitched equity; oos_r is the meaningful summary (C10 R-first yardstick). Held quality finding adjudicated: run_oos_blueprint's plan-prescribed redundant `pip: f64` (== data.pip_size()) removed — derived internally to match its siblings run_oos_r / blueprint_sweep_over, which also drops the too_many_arguments band-aid #[allow] (8->7 args). Two plan transcription typos the loop caught and fixed verified correct: BindError renders via Debug ({e:?}), parse_select via map_err (Result, not Option). Verified myself: cargo build --workspace, cargo clippy --workspace --all-targets -- -D warnings, cargo test --workspace all green; 2 new unit tests + 5 new cli_run E2Es (persist shape, reproduce bit-identical, no-axis, malformed-safety, unknown-axis) pass; no regression in the hard-wired walkforward / sweep / mc / reproduce suites. Engine/registry untouched (invariants 1/2/8/9). closes #173 |
||
|
|
c8c34c72e7 |
plan: 0097 IS-refit walk-forward over a loaded blueprint
Four tasks, one iteration: (1) the windowed IS-sweep + OOS-run helpers + blueprint_walkforward_family (mirrors the hard-wired Stage1R walkforward arm one substitution deep — loaded blueprint via blueprint_axis_probe); (2) the --axis/--select parse grammar + IO wrapper (persist via put_blueprint + append_family, content-addressed like aura mc) + the .json walkforward dispatch arm; (3) the reproduce_family_in WalkForward branch (persist+reproduce land together); (4) the E2Es (persist shape, reproduce bit-identical, no-axis reject, malformed-safety) + the full clippy/suite gate. Panic-safety: blueprint_sweep_over returns Result<_, BindError> (user --axis fallible); a bad axis → clean in-closure exit 2 (mirrors the hard-wired arm's select_winner handling), never a panic. reduce-mode members carry R-metrics (no raw pip curve) → empty stitched equity, oos_r is the meaningful summary (C10 R-first). Closes the World/C21 milestone's last piece. refs #173 |
||
|
|
1e2ac82473 |
spec: 0097 IS-refit walk-forward over a loaded blueprint (boss-signed)
Add `aura walkforward <blueprint.json> --axis <name>=<csv> [--axis …]`: a true in-sample-refit walk-forward over a loaded blueprint (Arm A, #173). Per IS window it re-optimizes the blueprint's params over the user's --axis grid, selects the winner by sqn_normalized, runs it out-of-sample, and aggregates the per-window OOS reports into a FamilyKind::WalkForward family that is content-addressed (put_blueprint) and aura-reproduce-aware. Closes the World/C21 milestone's last piece (the walk-forward half of #170). Design (Arm A settled by the user; sub-forks derived and recorded on #173): the loaded-blueprint WF mirrors the hard-wired stage1-r walk-forward arm one substitution deep — the generic engine walk_forward driver + select_winner + the 24/12/12 synthetic schedule are reused verbatim; only the per-window IS-sweep and OOS-run source the loaded blueprint (wrap_stage1r via cycle-0096's blueprint_axis_probe) over the user --axis grid. Persist + reproduce ship together (coupled — a persisted family with no store hook is unreproducible, the #170 hazard); the reproduce WalkForward branch reconstructs each OOS window's windowed source + winner params from the member manifest, mirroring the 0095 MonteCarlo branch. Loaded members are reduce-mode (R-metrics, no raw pip curve), so the WF is measured in R (oos_r), stitched pip-equity empty — consistent with the C10 R-first yardstick. Boss-signed on grounding-check PASS (independent, fresh-context; all 8 load-bearing current-behaviour assumptions ratified by named green tests — incl. an empirically-confirmed one: a loaded-blueprint member carries and ranks by sqn_normalized. One spec-internal tension flagged + fixed before sign). Engine/registry untouched (invariants 1/2/8/9). refs #173 |
||
|
|
485f3c8c89 |
audit(0096): cycle close — axis discovery over a loaded blueprint; ledger refreshed (C24); rm ephemeral spec/plan
cycle 0096 tidy (clean). Architect drift review over ebebc24..HEAD: no drift, no debt. Regression: no dedicated script (architect is the sole gate); its "What holds" is non-empty (design commitments confirmed against the diff + a green test run, not the commit body): - Inv. 8 / 9: the cycle touches only crates/aura-cli (main.rs + cli_run.rs + the ephemeral spec/plan) — no engine/registry/blueprint.rs change; those are read-only callees. - Inv. 1: --list-axes is a pure read-only probe (short-circuits before run_blueprint_sweep; builds the wrapped composite, reads param_space, prints — no run, no seed, no engine execution). - Behaviour-preserving single-source: blueprint_axis_probe is token-identical to the two former inline probes; three copies (sweep/mc/list) collapse to one; the reload closures survive (topology_hash + per-member run); clippy -D warnings clean, no dead code; the subsumed tests (blueprint_sweep_member_equals_single_run_and_shares_topology_hash, blueprint_mc_family_rejects_an_open_blueprint) stayed green. - The blueprint_axis_probe .expect is not a latent panic: the ["sweep",..] arm validates blueprint_from_json first (exit 2), pinned by the shipped aura_sweep_list_axes_rejects_malformed_blueprint E2E (no panic). Ledger: refreshed the C24 realization block (docs/design/INDEX.md) — reclassified the "axis-name discovery surface" from tracked debt to shipped (cycle 0096), recording the single-sourced blueprint_axis_probe and the listed==swept-by- construction property. Per-member trace-writing (#168) remains the one tracked debt in that block. Milestone World/C21 stays OPEN — the walk-forward half (#173, IS-refit, now unblocked by this #169) remains. Ephemeral spec/plan git-rm'd per the lifecycle convention. refs #169 |
||
|
|
bd2003e217 |
feat(0096): list a loaded blueprint's sweepable axes — aura sweep <bp.json> --list-axes
A data-level author can now discover a loaded blueprint's open sweepable knobs before sweeping: `aura sweep <blueprint.json> --list-axes` prints one `<name>:<kind>` line per open knob, in param_space() order, then exits 0. Before this the only way to learn the names was to guess a `--axis` and read the MissingKnob/UnknownKnob error — which names only the rejected knob, never the valid set. Prerequisite for #173 (IS-refit walk-forward must know which axes to re-fit per in-sample window). Design (derived, recorded on #169): the query lands on the SWEEP verb, not `graph introspect`, because the accepted axis names are produced by the sweep's own harness-wrapping (wrap_stage1r nests the loaded signal as a BlueprintNode::Composite named "stage1_signal", so collect_params prefixes them — stage1_signal.fast.length, not the raw fast.length). Only the sweep verb owns that wrapping. A new blueprint_axis_probe helper single-sources the wrapped probe and now subsumes the two previously-inline copies (blueprint_sweep_family + blueprint_mc_family), so listed == swept by construction (and stays so across #159's harness retirement) — no second source of truth. --list-axes is a standalone query (valueless flag handled before the per-flag value-consume; rejected with exit 2 if combined with any other flag). A closed blueprint prints nothing (exit 0). A malformed blueprint is rejected at the existing dispatch boundary (exit 2, UnknownNodeType), never a panic. Tests: unit blueprint_axis_probe (prefixed names + empty for closed) + unit parse grammar (standalone), and five cli_run E2Es — prints names, closed-empty, rejects-other-flags, malformed-safety (no panic), and a round-trip that DERIVES the names from --list-axes and feeds them back into a working sweep (pins the listed==swept invariant #169 exists to close). Verified myself: cargo build --workspace, cargo test --workspace, cargo clippy --workspace --all-targets -D warnings all green; no regression in the refactored sweep/mc probes. Engine and registry untouched (invariants 1/8/9). closes #169 |
||
|
|
581c86b091 |
plan: 0096 discover a loaded blueprint's sweepable axes
One iteration, three tasks: (1) extract blueprint_axis_probe and subsume the two existing inline copies of the wrapped-namespace probe (blueprint_sweep_family + blueprint_mc_family) into it — the single source the spec's rationale requires; (2) the --list-axes surface (SweepBlueprintArgs field, valueless-flag parse + standalone guard, list_blueprint_axes, dispatch short-circuit); (3) four E2Es (open lists prefixed names, closed empty, combined-flags reject, malformed-blueprint safety — no panic). refs #169 |
||
|
|
a78a0557f4 |
spec: 0096 discover a loaded blueprint's sweepable axes (boss-signed)
Add `aura sweep <blueprint.json> --list-axes`: a read-only query sub-mode that lists a loaded blueprint's open sweepable knobs (one `<name>:<kind>` per line, param_space() order), then exits. Closes the discovery gap #169 surfaced — today the only way to learn the axis names is to guess one and read a MissingKnob/UnknownKnob error, and that error names only the rejected knob, never the valid set. Prerequisite for #173 (IS-refit walk-forward must know which axes to re-fit per in-sample window). Derived surface decision (recorded on #169): the query lands on the SWEEP verb, not `graph introspect`. The axis names `--axis` accepts are produced by the sweep's own harness-wrapping — the loaded signal (name "stage1_signal") is nested via wrap_stage1r as a BlueprintNode::Composite, so collect_params prefixes the names (stage1_signal.fast.length), NOT the raw param_space (fast.length; empirically: the bare name → UnknownKnob). Only the sweep verb, which owns the wrapping, can print the names the user will actually pass; a shared blueprint_axis_probe single-sources the probe for both the sweep terminal and --list-axes, so listed == swept by construction (and stays correct across #159's harness retirement). Boss-signed on grounding-check PASS (independent, fresh-context; one BLOCK raised + fixed: the malformed-sweep .expect panic-path is now pinned by a this-cycle E2E over unknown_node.json, not an untested current-behaviour claim). Engine/registry untouched (invariants 1/8/9). refs #169 |
||
|
|
ebebc2401b |
audit(0095): cycle close — MC over a loaded blueprint; ledger refreshed (C18/C21); rm ephemeral spec/plan
Architect drift review (scope cec7811..HEAD, the sole gate — no regression script) returned drift-clean with positive What-holds: - invariants 8/9: the whole cycle is aura-cli (main.rs + cli_run.rs + ephemeral docs); nothing entered aura-engine/aura-registry; FamilyKind::MonteCarlo, monte_carlo, append_family, mc_member_reports are pre-existing seams reused. - invariant 1 / C1: draws run disjoint-parallel via the engine monte_carlo seam (seed-input order, no within-sim concurrency); bit-identity proven by the reproduce round-trip (unit + E2E). - the C1 lockstep is a single shared fn: synthetic_walk_sources (one fixed SyntheticSpec) is called by BOTH the persist path and the reproduce MonteCarlo branch; pip is lockstepped too (both pass DataSource::Synthetic). - the sweep-sibling pattern matches: Result<McFamily,String> + boundary render. - scope honesty: WF deferral (#173, dep #169) and synthetic-walk-DGP (#172) are named in the spec + feat body, not silent. Carry-on debt (does NOT block close, filed forward, NOT new-this-cycle drift): synthetic_walk_sources' len:60 is hand-calibrated to the shallow stage1 warm-up; a deep-lookback closed blueprint warms poorly -> silent-vacuous draws with no error, and the anti-degenerate test only exercises the shallow fixture. Folded into #172 (real-data DGP retires the length calibration) per the architect's recommendation, rather than a new thread. Ledger refreshed: the C21 realization block now records the MC verb shipped (cycle 0095) with WF deferred; the C18 reproduction block notes aura reproduce now spans FamilyKind::MonteCarlo. Verified green (orchestrator, this session): cargo build --workspace clean; cargo clippy --workspace --all-targets -- -D warnings clean; cargo test --workspace green. Cycle is drift-clean (not a milestone close — #170's WF half remains, milestone stays open). refs #170 |
||
|
|
14e27a978b |
feat(0095): monte-carlo over a loaded blueprint — aura mc <bp.json> --seeds N
The MC half of #170 (World/C21): `aura mc <closed blueprint.json> --seeds N` builds a FamilyKind::MonteCarlo family from a loaded CLOSED blueprint. Each seed draws a distinct synthetic price walk (synthetic_walk_sources, the mc_family pattern), so members differ in the DATA (not just a manifest label) — the sim is deterministic (C1), so MC variation must come from re-drawing the input. Draws run disjointly in parallel via the shared monte_carlo helper (invariant 1). The canonical blueprint is stored once keyed by the shared topology_hash (the 0094 hook), and reproduce_family_in gains a MonteCarlo realization branch that reconstructs each member's seed-driven walk from manifest.seed — so a persisted mc family 'aura reproduce's bit-identically (the store-hook proof). Closed-blueprint only: MC binds no axis, so a free knob has no binder; an open blueprint yields a named Err (rendered to stderr + exit 2 at the run_blueprint_mc boundary, mirroring blueprint_sweep_family — no hidden process exit in the pure builder), pre-empting the compile_with_params arity panic. Two quality-gate-driven improvements over the ratified plan, both applied and verified: (1) delegate the disjoint draws to the engine monte_carlo seam instead of a hand-rolled loop (my plan's 'closure-shape mismatch' rationale was wrong — the Fn(u64,&[Scalar]) closure ignores the unused base_point, exactly as mc_family does); (2) the closed-blueprint guard returns Result rather than exiting inside the builder, matching the sweep sibling's contract and making the rejection unit-testable. Engine + registry untouched (invariants 8/9). Verified: cargo build --workspace clean; cargo clippy --workspace --all-targets -- -D warnings clean; cargo test --workspace green (5 new tests: the parser, anti-degenerate family, MC reproduce round-trip, and two E2Es incl. the open rejection; no regressions). refs #170 |
||
|
|
860b89ad93 |
plan: 0095 monte-carlo over a loaded blueprint
4 tasks: parse_mc_blueprint_args, blueprint_mc_family (closed-blueprint guard + seed-driven synthetic walks), the reproduce MonteCarlo realization branch, and run_blueprint_mc + the .json dispatch arm + E2E. All in aura-cli/main.rs (engine/registry untouched). |
||
|
|
7116660fe8 |
spec: 0095 monte-carlo over a loaded blueprint (boss-signed)
The MC half of #170 (World/C21): aura mc <closed blueprint.json> --seeds N builds a FamilyKind::MonteCarlo family from a loaded closed blueprint, each seed drawing a distinct synthetic price walk (the mc_family pattern), sharing one topology_hash, written once to the content-addressed store (the 0094 hook) so aura reproduce re-derives it bit-identically. Scope narrowed from #170's two verbs by two read-only review gates: - spec-skeptic: a loaded-blueprint 'walkforward' with no in-sample refit under the verb name that hard-wired walkforward uses for real IS-optimization is a guarantee collision -> walk-forward deferred to #173 (deps #169 axis-discovery). - grounding-check: there is no per-knob declared-default mechanism and the raw bind path panics on arity mismatch -> MC runs a CLOSED blueprint over the empty point (as aura run does), rejecting an open blueprint with a named error + exit 2. Grounding-check PASS on the revised spec; decisions logged on #170. refs #170 |
||
|
|
cec7811c32 |
audit(0094): cycle close — content-addressed reproduction; ledger refreshed, coverage closed; rm ephemeral spec/plan
Architect drift review (4751d4b..HEAD): drift_found — ledger-currency only; the
code is clean.
What holds (architect, confirmed by diff + green tests):
- Inv 8 / C9: aura-engine byte-untouched; content_id + sha2 in aura-cli, the
store in aura-registry.
- Inv 9: Registry::{put,get}_blueprint is a dumb bytes-by-key store (opaque
String keyed by String hash; no sha2, no parse, no sha256==hash verify — the
caller owns the hash). No domain knowledge crept into the engine or registry.
- C1: the run_blueprint_member extraction is behaviour-preserving (keystone
blueprint_sweep_member_equals_single_run_and_shares_topology_hash unchanged +
green); serde_json/float_roundtrip serves determinism (disk==recomputed), not a
mask (1-ULP canary green).
- C11/C12: one blueprint stored per family, keyed by the shared topology_hash.
Resolutions:
- [ledger] Refreshed C18 + C24: added the cycle-0094 Realization (the
content-addressed store runs/blueprints/<hash>.json + aura reproduce), and
retired the now-false "content-addressed identity / full reproduction deferred"
claims (INDEX.md:1261, C24 deferred block). Only the structural-axis /
whole-harness content-id (and the debug-name-in-id question) genuinely remains,
filed forward (#171, #170).
- [debt->closed] Added the two untested refuse-don't-guess E2E arms
(aura_reproduce_rejects_a_non_generated_family — a hard-wired sweep member has
no topology_hash; aura_reproduce_rejects_a_missing_stored_blueprint — the store
was deleted), and a cross-surface unit pin
(topology_hash_is_the_content_id_of_the_canonical_form) so the two acc-1 paths
cannot silently drift.
- [scaling] MC/walk-forward-from-blueprint (#170) will need the same put_blueprint
hook or reproduce won't cover them — noted on #170.
No regression scripts in this project (Test is the gate): full workspace suite
green (51 suites), clippy -D warnings clean, binary verified end-to-end.
Ephemeral spec/plan git-rm'd per the lifecycle convention; durable rationale is in
the ledger. The World/C21 milestone stays open (#170 remains).
closes #158
|
||
|
|
717a0b70af |
feat(0094b): content-id surface + Tier-1 stability — aura graph introspect --content-id (iter 2)
Completes #158 acceptance (acc 1 + acc 3) on top of iteration 1's reproduction: - acc 1: `aura graph introspect --content-id` reads an op-script and prints the content id of its canonical blueprint — the SHA256 (hex) of the same blueprint_to_json bytes `graph build` emits. Extracted the single `content_id` primitive shared by this surface AND topology_hash, so the two command paths (this surface / hashing a `graph build` output) agree by construction. Verified live: both e2be81b2… for the SMA-cross op-script. Deterministic + distinguishes topologies; a malformed op-list fails cleanly (exit 2, no partial hash). - acc 3: a Tier-1 optional field the blueprint does not use is tolerated by the loader (#156) and absent from the canonical omit-defaults form, so the content id is unchanged (content_id_is_stable_across_a_tolerated_tier1_field); plus content-id stability across the serialize -> reload -> re-serialize store round-trip (#164), the property reproduction rests on. Finding (documented, filed forward): an op-script and the Rust `stage1_signal` builder produce DIFFERENT canonical forms — the composite debug-name ("graph" vs "stage1_signal"), a named vs unnamed Sub, and an unbound vs bound Bias.scale — so they are different topologies by the byte definition and get different content ids. Content-addressing keys on the canonical form, which currently includes the composite debug-name (a non-load-bearing symbol, invariant 11). Whether the content id should exclude the debug-name (a topology-canonical form distinct from the byte-canonical form, which would also change the shipped cycle-0092 topology_hash values) is a forward design question, not this cycle. Verified: full workspace suite green (51 suites); clippy -D warnings clean. refs #158 |
||
|
|
008692c043 |
feat(0094): content-addressed reproduction — aura reproduce <family-id> (iter 1)
Restore C18 reproducibility for generated (blueprint-sweep) runs (#158, acc 2): a sweep's topology is stored once, content-addressed by the topology_hash the manifest already carries, and `aura reproduce <family-id>` re-derives every persisted member bit-identically (C1) from the stored blueprint. - aura-registry: a dumb content-addressed bytes store — Registry::put_blueprint / get_blueprint / blueprints_dir over runs/blueprints/<hash>.json. No sha2 dep (caller owns the hash; reproduction's bit-identical compare is the integrity check); absent id -> Ok(None) (treat-as-empty, like load). - aura-cli: run_blueprint_member extracted from blueprint_sweep_family's member closure (behaviour-preserving; keystone stays green) so the sweep AND reproduce re-run the identical reduce-mode path — bit-identity by construction. The store write hooks the sweep persist seam (one blueprint per family, shared topo). reproduce_family_in loads each member's blueprint by hash, reconstructs the point from the recorded params (point_from_params, inverse of zip_params, over the WRAPPED signal's param_space so the prefixed knob names match), re-runs, and compares metrics. `["reproduce", id]` dispatch arm; refuse-don't-guess on an unknown id / missing stored blueprint (exit 2), DIVERGED -> exit 1. Dependency decision (per-case review, ratified): enabled serde_json `float_roundtrip`. Stored member metrics round-trip through families.jsonl as f64 JSON; the default parser can be 1 ULP off, which would make disk-loaded != recomputed and "bit-identical" (C1) physically impossible. The feature guarantees exact f64 round-trip. Blast-radius clean (full workspace suite green); it serves determinism, the invariant reproduction rests on. Canary: f64_blueprint_param_survives_store_round_trip_bit_identically. Two plan bugs caught + fixed by the implement loop and verified: reproduce's param_space must come from the wrapped signal (prefixed names, the #167 lockstep), and the family id is 0-indexed (live-0 / smacross-0, not -1). Verified: full workspace suite green (51 suites); clippy -D warnings clean; and the binary end-to-end — `aura sweep` (3 members, one shared stored blueprint) then `aura reproduce live-0` (3/3 bit-identical incl the open-at-end member), unknown id -> exit 2. acc 1 (graph introspect --content-id) + acc 3 (Tier-1 id stability) land in iteration 2 (plan 0094b). refs #158 |
||
|
|
a6d3774d04 |
plan: 0094 content-addressed reproduction (iteration 1)
Iteration 1 (acceptance 2, the heart): the content-addressed blueprint store (Registry::put_blueprint/get_blueprint under runs/blueprints/), the store write at the sweep persist seam, the extracted shared run_blueprint_member, and `aura reproduce <family-id>` re-deriving every persisted member bit-identically from the stored blueprint. acceptance 1 (graph introspect --content-id) and 3 (Tier-1 id stability) deferred to plan 0094b. refs #158 |
||
|
|
4b6bc52794 |
spec: 0094 content-addressed reproduction (boss-signed)
Restore C18 reproducibility for generated (blueprint-sweep) runs. Since cycle 0093 a sweep member's topology is a generated data value, so commit alone no longer identifies the graph and the manifest is not a complete re-derivation recipe (#158). Design: content-address the topology. The canonical blueprint JSON is stored once, keyed by the topology_hash the manifest already carries (cycle 0092), under runs/blueprints/<hash>.json (a dumb bytes-by-key store in aura-registry, no sha2 dep — the reproduce path's bit-identical compare is the integrity check). `aura reproduce <family-id>` loads each member's blueprint by hash, re-bootstraps with the member's params/window/seed, re-runs, and asserts the metrics are bit-identical (C1). acc-1 (two paths -> same content id) via a minimal `graph introspect --content-id`; acc-3 (Tier-1-stable id) composes the #156 omit-defaults pin. Derived forks (logged on #158): content-address (not carry-inline) — keeps the manifest tiny (C18) and dedups one topology across a family (C11/C12); hash domain = signal-only this cycle (the scaffolding is not yet blueprint-data, C24), boundary documented, whole-harness id deferred (#156/#159). Engine untouched (C9); store + hash off the frozen engine (invariant 8). boss-signed on a grounding-check PASS (9/9 current-behaviour assumptions ratified by green tests). refs #158 |
||
|
|
4751d4b590 |
audit(0093): cycle close — sweep-from-blueprint; ledger refreshed, debt filed; rm ephemeral spec/plan
Cycle-close drift review (architect) for cycle 0093 / #166 (aura sweep <blueprint.json>). Drift-found on debt only; no contract violation. What holds (architect, evidence of review): invariant 9 fail-clean (resolve_axes runs before the sweep closure → named BindError UnknownKnob/MissingKnob/KindMismatch, exit 2; UnknownNodeType on load; no registry); C1/C12/C18 shape verbatim from stage1_r_sweep_family (members disjoint + enumeration-ordered; shared topology_hash correct, consistent with the cycle-1 #158 signal-only scope; append_family/ sweep_member_reports reused); reload-per-member is sound (Composite !Clone, #164); stdout uses family_member_line with family_id, run_sweep-consistent. Resolved: ledger refreshed (C24 Status — the cycle-0093 realization: the World now orchestrates FAMILIES from blueprint-data; the open-vs-bound fixture fact + the reload-per-member rationale recorded). Drift filed forward: #168 (--trace writes no per-member traces — silently like --name, debt-med), #169 (no axis-name discovery for loaded sweeps, debt-low), #170 (MC/walk-forward over a loaded blueprint — the next family-verb cycle, assigned to the milestone). Ephemeral 0093 spec + plan git-rm'd per the lifecycle convention. closes #166 |
||
|
|
481add0ca2 |
feat(0093): sweep-from-blueprint — aura sweep <blueprint.json> over named axes
Cycle 2 of the World/C21 milestone (#166): the World now orchestrates FAMILIES from blueprint-data. `aura sweep <blueprint.json> --axis <name>=<csv> …` loads an OPEN signal blueprint, grids the by-name axes against its param_space, builds each member via cycle-1's wrap_stage1r seam, and aggregates to a FamilyKind::Sweep family — byte-identical in shape to the hard-wired sweep. - `parse_sweep_blueprint_args` + `SweepBlueprintArgs`: repeatable `--axis name=csv` (lexed i64-then-f64; resolve_axes kind-checks), `--name`/`--trace`, the shared `--real/--from/--to` accumulator → DataChoice. - `blueprint_sweep_family` (pure) + `run_blueprint_sweep` (IO) mirror stage1_r_sweep_family with three deviations: by-name axes (verbatim param_space names, e.g. `stage1_signal.fast.length`), reload-per-member (Composite is !Clone — its build closures are Box<dyn Fn>, #164 — so a fresh signal is re-loaded from the doc per member), and a per-member shared topology_hash. Members share the hash (same signal topology, only params vary); member_key distinguishes them. - The `aura sweep <file.json>` `.json`-discriminator arm mirrors cycle 1; the hard-wired `--strategy` sweep is untouched (#159). Task-3 design gap resolved: a sweep needs an OPEN blueprint (open knobs to grid), distinct from cycle-1's fully-bound run fixture (a bound blueprint has an empty param_space). New `tests/fixtures/stage1_signal_open.json` = blueprint_to_json(stage1_signal(None,None)); a sweep must bind ALL open knobs, so the E2E grids fast×slow (2×2 = 4 members). Verified end-to-end by running the binary: `aura sweep stage1_signal_open.json --axis stage1_signal.fast.length=2,4 --axis stage1_signal.slow.length=8,16 --trace f` persists a discoverable 4-member Sweep family; an unknown axis fails clean. Member equivalence vs run_signal_stage1r + shared-hash/distinct-member_key unit-tested. Full workspace suite green; clippy --all-targets -D warnings clean. refs #166 |
||
|
|
b6d4ebfe23 |
plan: 0093 sweep-from-blueprint
Three-task decomposition of #166 (sweep a loaded blueprint): the parser (parse_sweep_blueprint_args + SweepBlueprintArgs + --axis i64-then-f64 lexing), the member-build (run_blueprint_sweep — a structural mirror of stage1_r_sweep_family with three deviations: by-name axes, reload-per-member since Composite is !Clone, per-member topology_hash) + the .json dispatch arm, and the tests (grammar + equivalence-vs-run_signal_stage1r + the binary sweep-family E2E + unknown-axis fail-clean). Purely additive; reuses the engine sweep machinery + cycle-1's wrap_stage1r unchanged. Grounding decisions (Q1-Q5) recorded on #166. refs #166 |
||
|
|
132dee2437 |
spec: 0093 sweep-from-blueprint (boss-signed)
Cycle 2 of the World/C21 milestone (#166): `aura sweep <blueprint.json> --axis <name>=<csv>` sweeps a loaded signal over its named param-space axes, reusing the existing stage1-r sweep machinery with the signal source swapped to cycle-1's wrap_stage1r seam, aggregating to a FamilyKind::Sweep family; each member manifest carries the shared topology_hash. Derivable extension, not a fork (recon + grounding confirm): the sweep is by-name param-space-driven (SweepBinder.axis / resolve_axes / bootstrap_with_cells), so a loaded blueprint's param_space slots in; wrap_stage1r nests an arbitrary signal; append_family is blueprint-agnostic. Scoped to sweep (the keystone family); MC / walk-forward over a loaded blueprint are the same machinery per verb and follow as a fast follow-on. Decisions recorded on #166. Boss-signed on a grounding-check PASS: all six load-bearing current-behaviour assumptions ratified by named green tests (wrap_stage1r arbitrary-signal nesting, the by-name param-space sweep, stage1_r_sweep_family, append_family/FamilyKind::Sweep, topology_hash, the .json-discriminator dispatch precedent). refs #166 |
||
|
|
327d71b1d4 |
audit(0092): cycle close — run-from-blueprint; ledger refreshed, drift filed; rm ephemeral spec/plan
Cycle-close drift review (architect) for cycle 0092 / #165 (aura run <blueprint.json>). Drift-found on ledger currency only; the code is clean and correct. What holds (architect, evidence of review): the stage1_signal/wrap_stage1r split is behaviour-preserving (golden metrics byte-unchanged; loaded_signal bit-identical green; the STAGE1_R_SMA_* constants keep the hashed signal == the executed signal); sha2 + the topology_hash helper live in aura-cli only, aura-engine stays sha2-free (invariant 8 / C16); the resolver resolves the closed std_vocabulary set, unknown type -> UnknownNodeType, no registry (invariant 9); topology_hash is a correct Tier-1 optional and the RunManifest <-> RunManifestRead read-mirror both carry it. Resolved: ledger refreshed (C24 Status — the cycle-0092 run-from-blueprint realization + the topology_hash #158 anchor landing; #158 reframed from "premature" to "field landed, full reproduction remains"). Drift filed forward: #167 (single-source the stage1-r suffix-remapping lockstep — debt-med), and a scope note on #158 (the hash currently covers the signal only; a structural-variant content-id is the #158/#166 concern). The spec's illustrative instrument:"GER40" example (note-low) is moot — the ephemeral spec is removed here. Ephemeral 0092 spec + 0092/0092b plans git-rm'd per the lifecycle convention. closes #165 |
||
|
|
2b1c24668d |
test(0092): run-from-blueprint E2E + bit-identical keystone + demo fixtures
Closes the cycle-1 test coverage for #165. The `aura run <blueprint.json>` CLI arm itself (the .json dispatch + parse_blueprint_run_args + BlueprintRunArgs) shipped in ff4a1b3; this adds the coverage that proves it and the in-repo demo blueprint: - crates/aura-cli/tests/fixtures/stage1_signal.json — the canonical SMA-cross signal (blueprint_to_json of stage1_signal(2,4)); emit_demo_signal_fixture (#[ignore]) regenerates it. - crates/aura-cli/tests/fixtures/unknown_node.json — one type set to "Nope" for the fail-clean guard. - loaded_signal_runs_bit_identical_to_rust_built (the keystone, C1): a signal serialized -> loaded via blueprint_from_json -> run is bit-identical to its Rust-built twin, incl. topology_hash (64-hex). - topology_hash_is_stable_and_distinguishes (#158 anchor property). - cli_run.rs E2E: `aura run <demo>` exits 0 with topology_hash in the manifest; an unknown-node blueprint fails clean with UnknownNodeType (the #160 closed-set guard at the data-plane face, invariant 9). Verified end-to-end by actually running the binary: `aura run stage1_signal.json` -> RunReport with a 64-hex topology_hash, sim-optimal+risk-executor broker, R metrics; `aura run unknown_node.json` -> UnknownNodeType("Nope"), exit 2. Full workspace suite green; clippy --all-targets -D warnings clean. refs #165 |
||
|
|
43a25547ce |
plan: 0092b run-from-blueprint CLI arm + tests (continuation)
The remaining Tasks 4-5 of #165 after the
|
||
|
|
ff4a1b3d4a |
feat(0092): run-from-blueprint infrastructure — restructure + topology_hash + shared seam (Tasks 1-3)
Cycle-1 infrastructure for #165 (World/C21). Behaviour-preserving + workspace green; the CLI arm + tests (Tasks 4-5) follow. Task 1 — restructured stage1_r_graph into stage1_signal() (the serializable signal leg: SMA-cross -> Bias, a `price` input-role + a `bias` output) + wrap_stage1r(signal, ...) (broker/sinks/exec/cost around a nested signal), with stage1_r_graph() = wrap_stage1r(stage1_signal(...)). DEVIATION from the plan's "callers untouched" claim, verified behaviour-preserving: nesting the signal prefixes its param-space names (stage1_signal.fast.length), which broke the sweep's bare .axis("fast.length"); fixed exactly as the #137 stop-knob machinery does — FAST_LENGTH_SUFFIX/SLOW_LENGTH_SUFFIX suffix-resolution + stage1_r_friendly_name arms mapping the prefixed names back to the bare manifest names. All observable behaviour (manifest names, member keys, metrics, traces) byte-identical; the flat graph and every metric unchanged (full suite green, incl. sweep/walkforward/MC). Task 2 — RunManifest.topology_hash: Option<String> (Tier-1 optional, serde default/skip — old manifests byte-identical, #156), threaded None into all 24 literal sites across 7 crates. Also fixed the aura-registry RunManifestRead read-mirror to carry topology_hash (it was hardcoding None on load) — else a stored hash would silently drop on the registry round-trip once Task 3 stores a real one. Task 3 — the shared run_signal_stage1r seam (hash the signal, wrap, compile with params, bootstrap, run, manifest with params from param_space + topology_hash) + the sha256_hex topology_hash helper (sha2 in aura-cli, off the frozen engine, invariant 8). run_stage1_r now carries its topology_hash too (every run becomes self-identifying, #158). The seam is unwired until Task 4 (transient #[allow(dead_code)], retired there); RED-first seam tests added. Verified: cargo test --workspace green (51 suites, 0 failures); cargo clippy --workspace --all-targets -D warnings clean. refs #165 |
||
|
|
e25ca15be4 |
plan: 0092 run-from-blueprint
Five-task decomposition of #165 (run a serialized signal blueprint): 1. behaviour-preserving restructure of stage1_r_graph into stage1_signal() + wrap_stage1r() (the serializable signal boundary + the shared wrapping), gated by the stage1-r + bit-identical-e2e tests staying green; 2. RunManifest.topology_hash (Tier-1 optional) + thread None into the ~24 workspace literal sites (one compile-gate); 3. the shared run_signal_stage1r seam + the sha256_hex helper (sha2 in aura-cli, off the frozen engine, invariant 8) + run_stage1_r gains its topology_hash; 4. the `aura run <blueprint.json>` CLI arm (.json discriminator, --params cells), leaving the existing harness-kind dispatch intact (#159 stays); 5. demo signal blueprint + the bit-identical / determinism / E2E tests. Tasks 1-2 (restructure + field-add) run and verify first. Derived grounding decisions (the restructure target, param_space-derived manifest.params, the Q4 behaviour-preserving semantics) recorded on #165. refs #165 |
||
|
|
29a519dbf6 |
spec: 0092 run-from-blueprint (boss-signed)
Cycle 1 of the World/C21 milestone (#165): `aura run <blueprint.json>` loads a serialized C24 signal blueprint, wraps it in the existing Stage-1-R run scaffolding via a shared seam extracted from run_stage1_r, compiles + bootstraps + runs, and emits a RunReport whose RunManifest carries a new Tier-1-optional topology_hash (SHA256 of the canonical blueprint form, #158 anchor). A serialized blueprint is a SIGNAL (sinks/brokers/data/clock out of the round-trippable set, C24), so aura run WRAPS the loaded signal in a runnable harness — the same wrap the Rust path does, shared as one function so "bit-identical to the Rust path" is the same seam over the same signal. The round-trip bit-identity is already proven (blueprint_serde_e2e.rs); cycle 1 lifts it to the CLI + adds topology_hash. Boss-signed on a grounding-check PASS: all six load-bearing current-behaviour assumptions ratified by named green tests (blueprint_from_json, the bit-identical round-trip, the run_stage1_r compile/bootstrap/run path, RunManifest's Tier-1 optional-field pattern, canonical blueprint_to_json, window_of). Derived wrapping decision recorded on #165. sha2 enters under the C16 per-case dependency review (SHA256 user-settled). refs #165 |