Iteration-2 tasks (9-12) appended to the cycle-0088 plan: the JSON op-list serde
DTO (CLI-side, engine Op stays serde-free), `aura graph build` (replay -> emit
#155 / fail fast at op N), `aura graph introspect` (--vocabulary / --node /
--unwired), and an E2E suite driving the aura binary. All changes in aura-cli;
the engine core (ea1ca32 + 27ac4dc) is consumed unchanged. Wire-format forks
derived + recorded on #157.
refs #157
Iteration-1 §A of the construction service (#157): the surface-agnostic shared
predicates the eager op-script path and the holistic finalize gates both call —
no second validator (C24).
- edge_kind_check (blueprint.rs): the per-edge producer/consumer kind check,
lifted verbatim out of validate_wiring's edge loop into a pub(crate) fn that
validate_wiring now calls — behaviour-preserving (same Bootstrap(KindMismatch)
variant; the existing compile-time gate test stays green).
- resolve_input_slot / resolve_output_field (builder.rs): the exactly-one-match
name→index resolution extracted as pub(crate) fns over (&NodeSchema, &str), so
the runtime-String op-script names share GraphBuilder's resolution; GraphBuilder
delegates and maps to the unchanged BuildError variants.
- try_bind + BindOpError (aura-core node.rs): the fallible Result twin of bind
(bind keeps its panic contract and pinned messages verbatim; try_bind is a
separate method reporting the same three conditions as values).
- check_param_namespace_injective + validate_wiring widened to pub(crate) for the
finalize-stage reuse by the upcoming GraphSession::finish (§B).
Partial iteration: §B (the GraphSession/Op/replay surface + introspection) and
the §A→§B integration land next (plan Tasks 4-8). compile_with_params /
check_ports_connected are behaviourally unchanged. Full suite green; clippy clean.
Plan correction folded in: Task 3's test originally referenced aura_std::Sma —
infeasible inside aura-core (aura-std depends on aura-core; the reverse edge is a
dependency cycle). Adapted to a local PrimitiveBuilder probe with identical
assertions.
refs #157
Iteration-1 plan for #157 §A+§B: the eager/holistic gate split (extract
edge_kind_check + shared name-resolution helpers + try_bind, all reusing the
engine's gates — no second validator), the GraphSession/Op/replay per-op
surface, build-free unwired/vocabulary introspection, and the acceptance-1
replay-equals-GraphBuilder compile-identity test. The JSON op-list + CLI are
iteration 2. Eight RED-first tasks; struct literals + filter strings verified
against the current tree.
refs #157
Architect drift review of cycle 0087 (#155, the C24 blueprint-serialization-and-
loader first cut). What holds (confirmed against the diff): C17 / no-RustAst (the
format carries only type identity + name + bound params + topology; the build
closure is dropped and re-derived, no node logic in the data); invariant 9 /
domain-free engine (injected resolver, the closed match in aura-std, engine lib
deps aura-core + aura-analysis only — a compiled-in closed set, not a dynamic
registry); C9 round-trip / C23 bootstrap untouched (loader's terminal step is the
unchanged Composite::new -> bootstrap_with_params; validation deferred to the
existing gate, not bypassed).
Resolution:
- fix (ledger): C24 Status refreshed from "unbuilt" to "first cut shipped"
with a cycle-0087 realization note; C9's round-trips-both-ways refinement
marked realised. The ledger no longer contradicts the code.
- backlog (debt-med): the hand-written std_vocabulary match has no guard test
that fails when a new zero-arg aura-std node lacks an arm — fails safe today
(clean UnknownNodeType, never silent-wrong). Filed as #160.
- carry-on (scaling): construction-arg builders + sinks excluded, so no real
harness round-trips yet; harness retirement blocks on the construction +
project-as-crate layers — already tracked #156/#157/#159.
No architect-sweep / regression script is declared in the project facts, so the
suite is the gate: cargo test --workspace 748 passed (737 -> 748 = the 11 new
tests); clippy --all-targets -D warnings clean.
Ephemeral cycle artifacts removed (lifecycle convention): docs/specs/0087-*,
docs/plans/0087-*.
Five tasks for #155: serde derives on the serialized plain types; the closed
aura-std std_vocabulary resolver (22 zero-arg builders); the DTO layer +
canonical serializer + format_version envelope; the resolver-injected loader +
typed LoadError; and the round-trip tests (canonical golden, named failures,
bit-identical run vs Rust twin, idempotence, recursion).
refs #155
Architect drift review (8d04a84..HEAD): clean, no drift/debt.
What holds (verified against code, not asserted):
- C10 cost contract preserved: the non-R-harness guard reads the *resolved*
harness, so a `run` cost flag on sma/macd (incl. the implicit default) is
exit-2 fail-loud, never a silent no-op; parse_nonneg_rate names the flag;
the eight stage1-r cost goldens are byte-unchanged.
- The three edited realization notes are grounded: C12 Arc-sharing →
aura-ingest/src/lib.rs:316; aura-std "~30 modules" → 30 node files;
C15 Session emits only bars_since_open, matching the quoted source wording.
- project-layout.md rewrite complete: no residual exposure/realistic-broker.
Non-actionable scaling note (architect): the guard hardcodes Stage1R as the
sole R-harness, coupled to the "stage1-r only" note text — three sites move
together if a second R-harness ever lands; not in plausible next scope.
Regression gate: cargo test --workspace exit 0 (48 binaries, 737 passed, 0
failed); cargo clippy --workspace --all-targets -- -D warnings exit 0. No
baseline moved → no ratify needed. cycle 0086 tidy (clean).
Ephemeral spec/plan (docs/specs/0086, docs/plans/0086) removed per the
ephemeral-artifact convention.
Four tasks from spec 0086: (1) named non-negativity diagnostic via a
parse_nonneg_rate helper + perturbed-test fix; (2) non-R-harness guard
(the spec_gap, reject/exit-2); (3) COST_FLAGS_NOTE appended to the usage
+ --help surfaces; (4) the C10 ledger note + full-suite/clippy gate.
Confined to crates/aura-cli; the eight stage1-r cost goldens stay byte-green.
refs #153
Cycle 5 of milestone #148 (per-cycle-held accrual + CarryCost). Architect drift
review over 39f9387..f5e00a9: status clean, no code drift.
What holds (architect, evidence-of-review):
- C11 byte-identity: the AtClose eval arm is the pre-cycle-5 tokens verbatim
(if closed { per } / if open { per }, the per + cum lines unchanged), so the
cycle-0083/0084 net_expectancy_r goldens (-614.3134020253314, -615.0304388396047)
stay byte-identical and the AtClose unit regressions are untouched.
- Accrual sound, no double-count: aura-analysis (summarize_r) is genuinely unchanged.
During a hold the carry lives only in open_cost_in_r (cum=0); at close it moves to
cum while open_cost->0 (open/closed mutually exclusive per cycle), so net_r_equity
subtracts cum+open singly. summarize_r reads the close-row dumped total + the
window-end accrued-so-far — one charge per trade, acc reset proven. The 3-field
cost record's semantics generalize cleanly to accrual.
- C9/C16/C23: the diff touches only aura-std + aura-cli; aura-engine stays
domain-free. CarryCost is a CostNode factor, CostRunner a plain Node, composed via
cost_graph/CostSum. label() carries its param. All three run_stage1_r call sites
threaded; the negative-rate guard is symmetric with the sibling cost flags.
Resolved this commit (the cycle-close ledger sync):
- C10 realization note (cycle 0085) added under docs/design/INDEX.md — C10's
"per-cycle-held factors accrue over the hold" clause is now first realized (the
prior 0084 note covered the cost-graph composite-builder).
Regression gate: cargo test --workspace (0 failures), cargo build --workspace, cargo
clippy --workspace --all-targets -- -D warnings clean — the architect is the primary
gate (no dedicated regression script). Ephemera (spec 0085 + plan 0085) git rm'd.
Milestone "Cost-model graph (in R)" remains OPEN.
refs #148
Parent spec docs/specs/0085 (19ba1ec). 4 tasks: (1) ChargeMode + the PerHeldCycle
accrual branch on the shared CostRunner (AtClose arm kept verbatim for byte-identity)
+ 2 RED B-proof unit tests; (2) the CarryCost node (ConstantCost twin, PerHeldCycle)
+ lib.rs registration; (3) the --carry-per-cycle CLI flag threaded through every site
(incl. the easy-to-miss main.rs:4446 bin unit-test call site); (4) two capture-then-pin
net_expectancy_r goldens + the net_r_equity-bleeds-over-the-hold integration B-proof.
summarize_r and the CLI net_eq wiring are UNCHANGED; the cycle-0083/0084 goldens are
the byte-identity regression net.
refs #148
Cycle 4 of milestone #148 (cost-graph composite-builder). Architect drift review
over fc52b4f..d5c44dd: drift_found, every item dispositioned.
What holds (architect, evidence-of-review): C16/C9 — cost_graph lives in
aura-composites, the factors in aura-std, aura-engine stays domain-free; the
composite is ordinary downstream nodes. C11 behaviour-preservation is structural,
not just asserted — the composite inlines to the same flat fan-in as the deleted
CLI block (identical node set/order, cost[k].field slot map, geometry fan, net_eq
terms/signs, cost_rec cols), so the cycle-0083 net_expectancy_r goldens stay
byte-identical. C23 — role/port names non-load-bearing; 4 fixtures pin the role-set
+ output triple.
Resolved this commit:
- [high] ledger C10: the cycle-0083 note's "Still deferred (decision E)" is removed
(E shipped this cycle) and a cycle-0084 realization note added.
- [medium] cost_graph .leak() provenance (aura-composites/src/lib.rs): the
"risk_executor precedent" was imprecise — that .leak() lives in risk_executor's
TEST (one-shot, leak-safe), not its production builder. Doc corrected: the leak is
fine for one-shot run-path construction but must be interned (the COL_PORTS
production pattern) before cost reaches the sweep path.
- [low] cli_run.rs golden docstring cited the deleted `slot * COST_WIDTH + f` CLI
wiring; updated to the cost_graph composite's per-node cost[k].<port> wiring.
Deferred (tracked, not pending) -> #152:
- [medium] the cost[k].<port> index-namespacing restated across CostSum / cost_graph
/ the CLI (a build-validated lockstep — a divergent name fails loudly at g.build(),
NOT the silent positional kind 0083 collapsed), AND the per-build .leak() that
becomes an allocation regression on the per-member sweep path. Both are harmless on
the current run-only cost path; the proper fix is one sweep-safe single-source
cost-port-name contract (interned), best built with the deferred sweep-cost cycle.
Regression gate: cargo test --workspace (0 failures), clippy --workspace --all-targets
-- -D warnings clean, cargo doc clean — the architect is the primary gate (no dedicated
regression script). Ephemera (spec 0084 + plan 0084) git rm'd.
Milestone "Cost-model graph (in R)" remains OPEN.
refs #148
Two tasks: (1) the cost_graph(Vec<PrimitiveBuilder>) -> Composite builder in
aura-composites + the GEOMETRY_WIDTH re-export from aura-std + two unit tests
pinning the exposed input-role set and the 3-field output; (2) the aura-cli
stage1_r_graph rewire onto cost_graph, deleting MAX_RUN_COST_NODES and
COST_SUM_PORTS. Runtime port names .leak()'d (the risk_executor precedent).
Behaviour-preserving: the cycle-3 net_expectancy_r goldens are the regression net.
refs #148
Architect drift review over 6c7f5dd..HEAD. No regression scripts in this project
→ the architect is the sole gate; verdict: shipped code byte-clean.
What holds (verified against the diff):
- C9 — a CostRunner<F> is a plain downstream Node; the two cost nodes are thin
factors wired through the same cost_node_builder. No runtime sub-object.
- C18 / byte-identity — the numerator/latched token form is preserved verbatim;
the two new CLI goldens pin exact net_expectancy_r and pass; the no-cost golden
is untouched.
- C10 co-temporality + C23 + invariant-4 — the gate-on-PM-geometry-only rule
(cold factor input → 0 cost, row still emits) is now centralized once in the
runner; name() dropped cleanly (label() remains the non-load-bearing symbol);
the 3-field triple is a single source (COST_FIELD_NAMES) read by both producers
+ CostSum + the CLI — the cycle-0082 by-convention lockstep is structurally gone.
Resolution:
- [fix] docs/design/INDEX.md C10 — added the cycle-0083 realization note (each
prior cost cycle got one; the deferred general CostNode trait is now shipped and
the lockstep eliminated). Ledger deferred-work tracking re-synced.
- [fix] crates/aura-std/src/lib.rs:5 — module doc now names the CostNode/CostRunner
authoring surface.
- [carry-on, low debt] vol_slippage_cost.rs still declares its extra-input port
twice (the cost_node_builder arg and the trait extra_inputs()); a clean unifier
needs design thought (builder() is static, no factor instance) and is not worth
forcing at cycle close. Documented here; agreement rests on the helper + a test +
the harness debug-assert.
Cycle 0083 ephemera removed (docs/specs/0083 + docs/plans/0083).
Verified: cargo build/test --workspace clean (0 failures), clippy -D warnings
clean, cargo doc -p aura-std clean (CostNode/CostRunner intra-doc links resolve).
refs #148
Cycle 0082 (cost-graph composition, cycle 2) closes drift-clean against C10. The
architect review confirms the cycle is fundamentally sound:
What holds: VolSlippageCost + CostSum are ordinary aura-std downstream nodes
(C9/C8), cost stays out of aura-engine; the vol proxy is a trailing realized range
(C2, no look-ahead); feed-forward, no equity feedback (C1); the co-temporality
contract (gate cost nodes on PM geometry only, 0-cost on a cold state input) is
consistent with C1/C2/C9 and the cycle-1 positional join, and charging 0 during
warm-up is honest (no estimate yet, not a fabricated guess). The no-cost C18 golden
is byte-identical.
Drift resolved at close:
- [medium -> fixed] docs/design/INDEX.md (C10): added the cycle-0082 realization
note. The load-bearing co-temporality contract (generalizes to all future cost
factors) lived only in code comments + spec 0082; the ledger is now its durable
home once the spec is removed.
- [low -> fixed] crates/aura-cli/src/main.rs: --cost-per-trade now rejects negatives
at parse, symmetric with --slip-vol-mult (it previously deferred to the node
assert's panic). Run-path tests + the no-cost golden stay green.
Carry-on (documented deferrals, not this cycle's debt to fix):
- The 3-field cost triple {cost_in_r, cum_cost_in_r, open_cost_in_r} is restated
by-convention across ConstantCost, VolSlippageCost, and CostSum (compiler-unlinked
lockstep) — to be unified by the general CostNode trait, now justified by two
concrete nodes (#148).
- SLIP_VOL_LENGTH=5 is sized to warm within the synthetic smoke fixture; documented
in the const doc (on real M1 data any reasonable window warms).
- A future per-cycle-held accrual (carry/funding) accrues over holding duration,
which will force a summarize_r fold change and stress the positional seam — flagged
for that deferred cycle.
Regression gate green and unchanged: full workspace suite 0-fail, clippy --workspace
--all-targets -D warnings clean. No baseline moved -> no ratify.
Spec + plan ephemera removed (git rm docs/specs/0082, docs/plans/0082).
refs #148
Cycle 2 of the "Cost-model graph (in R)" milestone (#148): the milestone's real
architectural claim — the cost graph composes. Two cost nodes now sum into one
net-R curve while summarize_r and the net_r_equity tap stay structurally
unchanged.
- VolSlippageCost (aura-std): a second, STATE-DEPENDENT cost node; per-trade
charge = slip_vol_mult * volatility / |entry-stop|, in R. The vol is an
independent short-horizon realized range (SLIP_VOL_LENGTH=5, distinct from the
stop's EWMA-3) — scaling slippage by the stop's own vol would collapse cost-in-R
to a constant (indistinguishable from ConstantCost).
- CostSum (aura-std): the cost-graph OUTPUT node — sums N cost nodes' 3-field
cost-in-R records per-field into one aggregate. summarize_r and net_r_equity
read the aggregate (one home for cost; n=1 is the identity, so the cost path is
uniform). A future CostNode trait (deferred) will unify the cost-triple the two
producer nodes currently restate by-convention.
- Run path: --cost-per-trade and --slip-vol-mult combine, their costs summing into
the net-R curve; a hoisted vol proxy (RollingMax-RollingMin) keeps the single
feed. Run-path-scoped; sweep/walkforward/mc pass None.
Co-temporality contract (the load-bearing design decision; corrected from the
signed spec after the implement-loop correctly BLOCKED Task 3 on it). summarize_r
positional-joins cost[i] <-> record[i], so the cost stream must be co-temporal
1:1 with the PM record. A cost node is therefore gated ONLY by the PM geometry
(closed/open/entry/stop); a not-yet-warm state input (the vol proxy warms later
than PM) contributes 0 cost that cycle rather than withholding and desyncing the
stream. This makes co-temporality structural + warmup-independent, preserves the
C18 golden, and generalizes to any future cost factor. The rejected alternative
(a key-join in summarize_r) would have moved the golden and pushed cost-graph
logic into the post-run fold. Recorded on #148.
Tests: VolSlippageCost + CostSum unit sets (incl. the co-temporal-zero-during-
warmup case); the CLI composition run (both flags -> net_both < net_flat,
net_r_equity persisted); node-level EXACT additive composition (net_both ==
net_flat + net_vol - gross over the real nodes), the aggregate net_r_equity ==
post-run net total, and CostSum(1) identity. Full workspace suite green; clippy
-D warnings clean; the no-cost C18 golden byte-identical (the regression floor).
Deferred (later cycles of this milestone): the general CostNode trait + cost-graph
composite-builder (now justified by two concrete nodes), the conviction-weighting
R-aggregation axis, and cost on the reduce-mode sweep path. Spec + plan amended to
the corrected contract; both are cycle ephemera (git rm at cycle close).
refs #148
Task-by-task plan for spec 0082: the VolSlippageCost node (Task 1) and the
CostSum aggregator (Task 2) in aura-std; the run-path wiring as one compile-gate
task (Task 3) — stage1_r_graph cost-param widening + vol-proxy hoist + the
CostSum-aggregated cost block + the --slip-vol-mult thread-through across all
call sites, with a CLI composition test and the no-cost golden floor; and the
node-level exact-sum composition tests (Task 4). RED-first per task. The
&'static str CostSum port names are interned (COST_SUM_PORTS, mirroring
COL_PORTS); summarize_r is unchanged (it folds the CostSum aggregate).
refs #148
Cycle 0081 (cost-model graph, cycle 1) closes drift-clean against C10: the
architect review confirmed ConstantCost + the net-R seam realize the contract
at its floor (C9 cost node; net_r_equity a C8/C18 sink; R-pure; one home for
cost, subsuming the retired scalar round_trip_cost; pure feed-forward C1), and
the no-cost baseline is byte-identical (C18 golden held). Regression gate green
and unchanged: full workspace suite 0-fail, clippy --workspace --all-targets
-D warnings clean. No baseline moved -> no ratify.
Ledger sync (docs/design/INDEX.md): added the C10 cycle-0081 realization note
(ConstantCost node + net_r_equity seam shipped; scalar round_trip_cost retired;
run-path-scoped; later-cycle deferrals named).
Drift swept (cycle-adjacent + cheap one-liners):
- crates/aura-analysis/src/lib.rs net_expectancy_r doc: the removed in-fold
mechanic (mean(R - round_trip_cost/latched_dist)) -> the cost-stream fold.
- crates/aura-std/src/lib.rs module doc: "realistic broker profiles" (retired
by #116) -> the legacy SimBroker pip yardstick + cost-model nodes.
Backlogged (pre-existing, broader, predates this cycle): the
docs/project-layout.md backtest worked example is stale on #117 (exposure->bias)
and #116 (realistic broker); a proper rewrite is filed as #151, not folded here.
Architect-accepted: the #[allow(dead_code)] on r_col::ENTRY_PRICE/STOP_PRICE
(their production reader legitimately removed when summarize_r stopped recovering
latched_dist; still the layout contract + exercised by test fixtures).
Spec + plan ephemera removed (git rm docs/specs/0081, docs/plans/0081).
refs #148
Task-by-task plan for spec 0081: the ConstantCost node (aura-std), the
summarize_r scalar->cost-stream change (the workspace-wide call-site
migration as one compile-gate task), and the run-path wiring (net_r_equity
tap + --cost-per-trade) — RED-first per task. Scoped to the run path
(non-reduce); sweep/walkforward/mc pass None this cycle.
refs #148
Architect drift review (d50a482..feat): drift_found — documentation only,
NO contract violation. C1/C9/C10/C23 verified preserved against the diff:
`generalization` is a pure deterministic fold (registry-side, C9; R-only,
C10); the sole `instrument = Some` production site is `run_generalize`, every
other manifest constructor threads `None` + `skip_serializing_if`, so
sweep/mc/walkforward/standalone manifest bytes are byte-identical (C23); the
compat read-mirror was threaded in lockstep.
Drift fixed in this commit (ledger sync, docs/design/INDEX.md):
- The inferential-honesty thread read "now two of three pieces built" / "#146
remains the last open piece" — false now that #146 landed. Updated to record
the inferential half as structurally complete (all three built, cycle 0078)
+ the #146 realization, including the aggregator/validator-vs-selector
distinction (#146 is a recomputable aggregate, not a FamilySelection
annotation).
- C18 realization block: added the cycle-0078 note — the comparison axis (C12)
realized as FamilyKind::CrossInstrument + the first-class RunManifest.instrument
lineage field.
Regression: no regression scripts configured (project facts name only
Build/Test/Lint/Doc); architect is the gate. cargo test --workspace green
(0 failed) and cargo clippy --workspace --all-targets -D warnings clean,
orchestrator-verified.
Ephemera removed per the project lifecycle convention: docs/specs/0078-* and
docs/plans/0078-* (git rm). Durable rationale lifted to the ledger above.
refs #146
Three tasks for #146: (1) RunManifest.instrument serde-widened field +
compat-mirror lockstep + thread all in-workspace literals + back-compat tests;
(2) aura-registry FamilyKind::CrossInstrument + the R-only generalization
reduction (worst-case floor + sign-agreement + breakdown) + check_r_metric +
two RegistryError variants; (3) aura-cli generalize subcommand (single-cell
stage1-r candidate x instrument list), data-free arity/metric refusals, a
gated-skip cross-instrument E2E.
fieldtests/ confirmed outside the workspace compile set; FamilyKind has no
exhaustive match (serde-derive); only RegistryError's Display match is a gate.
refs #146
Architect drift review over 9c6b9c7..cb32658 returned drift_found (3 items);
all resolved here. What holds (architect): C23 default-argmax byte-identical,
C9 separation (selector in aura-registry, walk_forward selection-agnostic),
C1/C2 (plateau pure/deterministic/in-sample), one higher_is_better direction
source.
Resolutions:
- [medium] Backfilled the pre-0077 FamilySelection legacy-load fixture
(report.rs family_selection_loads_a_pre_0077_legacy_line). The feat commit
and the struct doc-comment claimed "a legacy line still loads (C14/C18)" as
landed, but no test pinned the field-level mapping: bare deflation scalars ->
Some(...), absent plateau keys -> None. families.jsonl/runs.jsonl are
append-only, so a winner stamped pre-0077 must read back; now pinned.
- [low] Synced the ledger's inferential-validation open thread
(docs/design/INDEX.md): #145 plateau-over-peak landed (cycle 0077), selection
is now a pluggable objective (bare argmax -> trials-deflated -> plateau) on
the manifest carrier; only #146 (cross-instrument generalization) remains of
the milestone's three pieces.
- [medium-high] Removed the cycle ephemera (git rm docs/specs/0077-*,
docs/plans/0077-*) per the cycle-close convention.
Regression: full workspace suite green and clippy --all-targets -D warnings
clean (verified at feat-review time). No baseline scripts configured; the test
+ clippy gates are the regression gate. Cycle 0077 tidy (clean) — drift-clean,
not a milestone close (the milestone fieldtest is a separate deliberate gate).
Executable plan for cycle 0077 (#145), decomposed into 5 tasks with the
compile-gates sequenced:
1. Reshape FamilySelection/SelectionMode across 3 crates (mechanical,
byte-preserving): deflation fields -> Option, add PlateauMean/PlateauWorst
+ neighbourhood_score/n_neighbours; thread optimize_deflated + all tests +
the runs_family display (argmax bytes unchanged).
2. GridSpace::axis_lens() + SweepBinder::sweep_with_lattice (sweep delegates,
every existing .sweep() caller byte-unchanged).
3. optimize_plateau + PlateauMode + closed_neighbourhood (mixed-radix grid
neighbourhood, argmax of the smoothed surface) + a higher_is_better refactor
so direction lives in one place.
4. CLI --select parse + Selection threading + sweep-entry Option<lattice>
tuples + select_winner (the RandomSpace-refuse guard) + walkforward_family
dispatch; all signature-change callers threaded before the build gate.
5. runs-family plateau E2E golden.
Two plan-time forks were derived and recorded on #145 (comment 1974): the
lattice surfaces at the engine terminal (only the post-resolve_axes GridSpace
holds param_space order), and the RandomSpace-refuse is a structural guard
unit-tested at select_winner (walkforward has no --random producer to E2E).
refs #145
Architect drift review (c192dfd..a295905): drift_found, medium/low only — no
ledger or hot-path contract crossed. C23-additive, C1-deterministic, C14/C18
back-compat all verified green (full workspace suite + clippy). No regression
scripts configured (test+clippy are the gate).
Resolution:
- [medium] three spec-promised optimize_deflated tests were missing (the
centring control, the all-noise high-p companion, the C2 IS-only read) — the
centring was unprotected ("removing it would pass every test"). Plus an
unguarded dispersion-floor sign assumption. FIXED in 0076.tidy (ecc9541).
- [low, RATIFY] the ledger's "Open architectural threads" inferential entry was
stale on one fact (it described optimize as having no trials penalty). Synced:
it now records that #144's trials-deflation landed this cycle (additive
optimize_deflated, winner unchanged — C23; optimize/rank_by stay bare argmax),
that #139's per-candidate OOS bootstrap landed in 0075, and that #145/#146
remain open. This ratifies the cycle-0076 intent; the gap description is
preserved for the still-open default-ranker path.
Deferred (spec 0076 Out of scope, not drift): n_eff effective-trials advisory,
reload-time recompute of the R-arm statistic, deflated-score re-ranking, CLI
flags for the resampling config.
Ephemeral spec + plan (docs/specs/0076-*, docs/plans/0076-*) removed per the
cycle-close convention. refs #144
Architect drift review (c99e7b8..2e77ab1) against the design ledger +
CLAUDE.md invariants: drift-clean, debt only — no contract or spec
violation. Verified intact: C18 wire shape (trade_rs is #[serde(skip)] +
excluded from the hand-written PartialEq; runs.jsonl/families.jsonl bytes
and digests unmoved; mc_r_bootstrap is a printed line, never a record),
C1 determinism (seeded r_bootstrap + disjoint walkforward windows, both
pinned by byte-identical-rerun e2e tests), C7 frictionless Stage-1
(round_trip_cost stays 0.0), C8/C12 streaming reduction (IS sweep folds
O(trades)/member, OOS run non-reduce). The verbatim summarize_r /
r_metrics_from_rs float duplication is guarded by the cross-reducer
equality test — sound.
Tidy applied this close:
- doc-link drift: the new E[R] notation in r_bootstrap / RBootstrap /
run_mc_r_bootstrap doc-comments was parsed by rustdoc as an intra-doc
link `[R]` (4 warnings). Wrapped in backticks; doc build now clean.
- coverage micro-gap [low, architect]: added a tripwire asserting a
populated trade_rs is absent from the serialized JSON (the serde(skip)
C18-preservation property had no direct test — only Vec::new() was
serialized before).
Carry-on (benign debt, not fixed): the mc usage literal carries a `usage:`
prefix the sibling sweep/walkforward usages omit — required because the
new `["mc", rest @ ..]` arm now handles the `--real` rejection and the
preserved golden asserts stderr.contains("usage"); churning the golden to
drop the prefix is not worth it.
Removed the cycle's ephemeral spec + plans (docs/specs/0075,
docs/plans/0075, docs/plans/0076) per the lifecycle rule.
Verified: cargo test --workspace 610 passed / 0 failed, clippy -D warnings
clean, cargo doc --no-deps clean.
closes#139
Iteration 2 of cycle 0075: the engine primitive r_bootstrap (moving-block
bootstrap over a flat R series, reusing MetricStats/SplitMix64); the CLI
parse_mc_args/McArgs split (synthetic seed-resweep preserved byte-for-byte;
the --strategy stage1-r real-R path reuses iter-1's walkforward_family +
RMetrics.trade_rs); run_mc_r_bootstrap prints one mc_r_bootstrap line. The
mc real-R path accepts only --strategy stage1-r, so a bare --real stays a
usage error (mc_rejects_real_flag_with_usage_exit_2 preserved).
refs #139
Architect audit: drift-clean. The ledger and source now point at the recorded
geometry sidecar; no live reference to the removed authored floor survives in
code or any live contract. Refuse-don't-guess preserved.
Recorded debt (non-blocking, accepted):
- fieldtests/milestone-runway references the removed instrument_spec; a frozen
non-workspace snapshot, left untouched per the tracked-fieldtests convention.
- cli_run.rs test fn names retain unspecced/vetted vocabulary (plan prescribed
substring-only edits); cosmetic.
#124 stays open for the deferred override/floor tiers the Stage-2 broker needs.
Drops the ephemeral cycle spec + plan (rationale lifted to the ledger).
Cycle-close audit: drift-clean on all load-bearing invariants (C7/C8/C15 hold; geometry stays non-scalar metadata, the Source seam still carries only (Timestamp, Scalar); scope boundary held — no resolver, quote_currency still &'static str, both #124's).
Tidy: completed the VETTED_SYMBOLS consolidation the feat commit over-claimed — migrated the two remaining inline vetted-symbol arrays in the crate-internal unit tests (instrument_spec_pip_value_matches_contract_times_pip, instrument_spec_ids_are_distinct) to the const, so #140 now extends one list.
Ledger: lifted this cycle's durable rationale into the C15 realization note (docs/design/INDEX.md) — the floor now carries tick_size/digits, and the recorded-metadata tier-2 source (instrument_geometry over symbol_meta -> neutral InstrumentGeometry, cross-checked against the authored floor) now exists at the ingestion edge; the tier-composing resolver remains #124.
Drop the ephemeral cycle spec + plan (docs/specs, docs/plans) per the lifecycle convention; durable rationale now in the ledger + the #143 thread.
refs #143
Three tasks at the aura-ingest edge: (1) re-export InstrumentGeometry + a thin instrument_geometry accessor over symbol_meta; (2) two additive InstrumentSpec fields tick_size/digits (compile-gated literal update); (3) a real-data cross-check of the authored floor vs provider geometry, iterating the vetted set.
refs #143
The EWMA Bollinger-band mean-reversion fade is refuted: no cross-index
generalization (FRA40 leans positive, GER40 negative — two correlated indices
disagreeing in sign), no OOS-significant cell on either index, and its lone
IS-significant cell is consistent with multiple-testing noise (full verdict on
#137). The machinery (--strategy stage1-meanrev, the composed EWMA Bollinger
band, zero new nodes) is permanent and kept; only the per-cycle spec/plan are
dropped per the ephemeral-artifact lifecycle convention.
refs #137
The Donchian channel-breakout Stage-1 R candidate is refuted: no cross-index
generalization, violent IS->OOS sign flips at long channels, no significant
positive cell (full verdict recorded on #137). The breakout machinery
(RollingMax / RollingMin nodes, --strategy stage1-breakout) is permanent and
kept; only the per-cycle spec/plan are dropped per the ephemeral-artifact
lifecycle convention.
refs #137
Implementation plan for the Donchian breakout candidate (parent spec
docs/specs/0071-stage1-breakout.md). Four dependency-ordered tasks: RollingMax and
RollingMin (monotonic-deque sliding extrema, mirroring the Sma/Delay node shape), a
C2-causality + ±1-latch composition test, and the CLI breakout strategy
(stage1_breakout_graph + manual-grid sweep family + --strategy/--channel wiring).
refs #137
Cycle 0070 (streaming sink reductions, #138) close. Durable rationale lifted to
the ledger: C8 now records the end-of-stream `finalize` lifecycle (the second node
phase beside `eval`), its `Harness::run` topo-order epilogue, and its C1/C7/C8
reconciliation — with the open `Recorder`->`Probe` / per-cycle-allocation question
(#77) cross-referenced, since `finalize` is the "non-channel exit" that issue's
accumulate-then-read option named as missing. The per-cycle spec and plan are
git-rm'd (ephemeral, valid only for their cycle).
Audit (architect) found no invariant breakage; noted debt, left as-is: the
two-mode `stage1_r_graph` (reduce vs raw sink wiring) rests on the CLI-seam
equivalence test rather than structural unification, and `SeriesReducer.last_ts`
carries the last *warm* cycle's ts (latent only if `--trace` ever folds).
refs #138
Architect audit clean (no drift): the derive is the faithful C10 book
first-difference — Close uses the stored book volume (the actual book), never an
exposure delta (the exact inversion of the abandoned 0064 exposure-integral);
post-run reduction, no in-graph node (C14), positional type-erased Scalar reads
(C7), each event's event_ts is its own cycle (C2), the >1-event-per-instant
reversal case is why it is derived not per-eval (C8/C10); aura-engine -> aura-core
only (instrument_id a caller scalar, no InstrumentSpec import).
- Ledger C10: add a "Realization (cycle 0068, #115)" note — derive_position_events
as the first difference of the executed book, the post-reframe replacement for
the rolled-back 0064 derive; fixed-fractional / currency / equity-feedback
sizing and the realistic brokers stay #116.
- Remove the ephemeral spec + plan (cycle closed; rationale in the ledger + git
history).
Accepted low debt (architect [low]): the stop-then-same-cycle-reopen producer path
emits the same closed&&open shape as a bias-flip reversal and the derive handles it
correctly (it keys on closed/open/direction/size, not exit_reason; unit-covered via
the reversal test), but is not separately asserted end-to-end. Cosmetic; the derive
is producer-agnostic.
refs #115
Three tasks for spec 0068: (1) derive_position_events + r_col DIRECTION/SIZE
consts + crate-root re-export + report.rs unit tests (reversal, normal lifecycle,
short, window-end open, empty, monotonic position_id); (2) stage1_r_e2e.rs
lockstep-guard direction pin + an agreement E2E folding both summarize_r and
derive_position_events over one recorded ledger; (3) full workspace
build/test/clippy verification. Purely additive — no existing output touched.
refs #115
Architect audit clean (no drift, no debt): raw sqn verified bit-identical,
C18 serde back-compat + C4 SoA seam + C1 determinism + Part-B symmetry all hold.
- Ledger C10: add a "Realization (cycle 0067, #130 + #135)" note — SQN100 as
the turnover-robust opt-in rank key (raw sqn / default ranker byte-unchanged,
serde(default) for back-compat), and per-member --trace now symmetric across
all three sweep strategies via the shared persist_traces_r.
- Glossary: R-metrics list gains sqn_normalized; the SQN entry documents the
SQN100 variant (was "deferred #130").
- Remove the ephemeral spec + plan (cycle closed; rationale lives in the ledger
and git history).
refs #130, refs #135
5-task plan for the boss-signed spec docs/specs/0067-r-sweep-followups.md.
Task 1 adds RMetrics.sqn_normalized (+ SQN_CAP + summarize_r compute) and
threads all four RMetrics struct literals (compile-gate). Task 2 adds the
Metric::SqnNormalized rank key. Task 3 re-baselines the 0066 single-run
golden (the r: block gains the field). Task 4 wires --trace for the stage1-r
sweep (invert the refusal test → persist member dirs via persist_traces_r,
drop the run_sweep guard). Task 5 is the full-workspace gate.
Sequencing pins the golden re-pin and the unfiltered suite after Task 1.
refs #130, refs #135
Cycle 0066 (#133) closed. The close audit (architect) found the family ratified against C12 axis-2 (rank-by-metric over the C18 family store) and the C10 R framing, with one [high] gap (swept-member manifest omitted the fixed R-defining params) fixed forward in 499121e.
- Ledger: a C10 realization note records the durable rationale -- SQN as the single-number sweep objective, the signal-only grid (the stop defines R, so varying it breaks cross-member SQN comparability -- the SQN100 #130 motivation), the R-metric rank vocabulary, and the manifest-completeness fix.
- Glossary: new 'R metrics' and 'SQN' entries.
- The ephemeral spec + plan are removed; the ledger + git history are the durable record.
Follow-ups filed: #135 (per-member --trace for the stage1-r sweep). refs #133
Parent spec docs/specs/0066-r-sweep-rank.md (#133). Four tasks: golden characterization of the stage1-r single run (byte-preservation guard); extract stage1_r_graph helper (float fast/slow for the sweep, single run binds Some(2)/Some(4)); metric_cmp learns sqn/expectancy_r/net_expectancy_r (None sorts worst); stage1_r_sweep_family + --strategy stage1-r + rank-by-sqn integration test.
refs #133
The 'R-based signal quality (Stage 1)' milestone is complete and ratified
(iter-1/2/3 + the corrective primitives mini, the tiny-pip fix, the metric rename;
end-to-end fieldtest green). Closing the cycle:
- Milestone container + issues #119/#126/#127/#128/#129 closed on the tracker.
- The ephemeral per-cycle spec (0065) and plans (0065-0069) are git-rm'd per the
cycle-close convention; the durable rationale lives in the design ledger (the C10
cycle-0065 realization note) plus git history.
Follow-ons tracked: #130 (n-normalized SQN), #131 (CLI UX), #132 (harness polish),
#133 (R-sweep + rank-by-sqn), #134 (strategy-output param-namespace rename).
refs #117
The deferred rename of the strategy-output residue (the typed exposure_sign_flips
metric with serde back-compat, the registry rank vocab, the exposure_scale manifest
label, the .named("exposure") Bias instances), keeping SimBroker's pre-reframe
exposure concept and the on-disk exposure tap label (scope fork on #117).
refs #126#117
Executable plan for iteration 3 of cycle 0065 - make the Stage-1 R layer
operable from the command line. Three tasks:
- Task 1: promote vol_stop + risk_executor + a StopRule axis from test
fixtures to public aura-engine composite-builders (aura-std moves to a
normal dep; the two fixtures rewired to call them; a Vol-backed RED test
added).
- Task 2: the stage1_r_blueprint dual-tap harness (one bias fanned into both
SimBroker and the RiskExecutor) + run_stage1_r folding summarize_r into
RunMetrics.r + persist_traces_r (a separate 3-tap helper that leaves the
seven pip callers byte-unchanged).
- Task 3: a parse_run_args tokenizer + --harness selector + run_dispatch,
replacing the run literal-slice arms; binary-driven selector / flag-
composition / r_equity-round-trip tests.
Recon: two plan-recon agents (aura-cli surface, aura-engine promotion).
Verified before handoff by a 3-critic adversarial pass (API-fidelity,
plan-discipline, behavioral-correctness): discipline and behavior SOUND, one
API fix applied (tempdir -> the existing temp_cwd helper, no tempfile dep).
refs #129#117
Iteration-2 plan for cycle 0065 (Stage-1 R signal quality). Sub-splits the
spec's iteration 2: this plan is the node + metric layer; the CLI/recording
surface (#129) becomes a separate iteration 3.
Five tasks, sequenced so each signature change threads all its callers before
its build gate, and the two signature changes land before the composite that
consumes both:
1. PositionManagement gains a 4th `size` input (col 10, from the Sizer); R
stays size-INVARIANT (RED test pins it). Threads the PM unit tests + the
stage1_r_e2e direct-eval column setups.
2. Sizer node (aura-std): `size = risk_budget / stop_distance`, flat-1R; the
Stage-2 fixed-fractional seam slots in unchanged.
3. summarize_r enrichment: SQN, conviction terciles, net-of-cost; gains a
`round_trip_cost` param (reads dense cols 6/7/9). Threads report.rs + the
E2E callers and extends the cross-crate layout guard.
4. RunMetrics.r: Option<RMetrics> with serde(default, skip_serializing_if) for
legacy runs.jsonl back-compat. Threads every RunMetrics literal (report.rs,
aura-registry, aura-engine/mc).
5. RiskExecutor composite (aura-engine integration-test fixture, sibling of
vol_stop_composite): FixedStop -> Sizer -> PositionManagement behind open
bias+price roles, price fanned to both; bias produced in-graph (single
source, no stale-price two-cycle merge). Veto is a documented seam, not a
node. E2E equivalence + R-invariance under risk_budget.
refs #117
The two genuinely-missing arithmetic primitives (Mul = two-stream f64 product,
Sqrt = one-input f64 root, negatives clamped to 0). They are the building blocks
for the volatility stop as a composition (rolling EWMA stddev), replacing the
fused VolStop node. Also corrects plan 0066 Task 3 (the VolStop removal must
migrate its stage1_r_e2e.rs caller — a false premise the implementer caught).
refs #117#119
VolStop was a design error (a fused node justified by a missing primitive). A
node is a primitive only if not DAG-expressible from other primitives; a missing
primitive is added, not fused away. Adds Mul + Sqrt primitives, removes the fused
VolStop, expresses the vol stop as a composition (rolling EWMA stddev = k *
Sqrt(Ema(Mul(d,d), length))). Spec 0065 b gets a correction note; full record on #117.
refs #117#119