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
Cycle-close tidy for broker-foundation (InstrumentSpec deploy metadata #113 +
PositionEvent schema #114).
Architect drift review (3638d48..HEAD): code is drift-clean. PositionEvent matches
the C10 column spec field-for-field (no open_ts, unsigned volume, direction-is-action,
bare-i64 action); the engine run-loop is untouched (C14); InstrumentSpec stays Copy
metadata at the ingestion edge (C7/C15); no instrument identity reaches the hot path.
The only drift was stale ledger prose, fixed here:
- C10 realization note: added a cycle-0063 entry recording that the position-event
*schema* landed (PositionAction/PositionEvent), while derivation (#115) and the
realistic broker nodes (#116) remain the deferred decoupled layer.
- C15 realization note: replaced "minimal today (pip only)" with the six-field
deploy-grade floor and the #124 currency-type forward note (quote_currency is
&'static str; the #124 resolver chooses how its runtime tier carries currency).
Regression (verbatim): cargo test --workspace = 458 passed / 0 failed (exit 0);
cargo clippy --workspace --all-targets -- -D warnings = clean (exit 0).
Carry-on (not actioned, justified): the inline reversal test is a shape-pin only —
the behaviour test arrives with #115's derive, and the E2E twin already exercises the
reversal wire shape. The quote_currency &'static str / #124 resolver concern is logged
on #124 as a deliberate deferred design choice.
This is drift-clean, NOT a milestone close — the realistic-broker milestone needs its
end-to-end fieldtest green, which depends on #115/#116/#120-123 still to land.
Removed the ephemeral cycle artifacts (spec + plan) per the lifecycle convention.
Three tasks. Task 1 (#113, compile-atomic): RED-rewrite the lookup test to the
six-field shape + invariant/uniqueness tests, then extend InstrumentSpec and
populate the vetted table for the five instruments (refuse arm stays). Task 2
(#114, greenfield): RED the round-trip / try_from-Err / serde-bare-int / reversal
tests, then add PositionAction (serde-as-i64) + PositionEvent in report.rs and
re-export from the crate root. Task 3: workspace test + clippy gate.
Recon-grounded line anchors; the redundant std::convert::TryFrom import dropped
(2021 prelude). INDEX.md realization-note drift (C10/C15 "minimal today") deferred
to the cycle-close audit, not folded here (code-only scope).
refs #113#114
Cycle-close tidy for visual-world-cut-2 (decimation #108 + run-context header #102).
Architect drift review (53eeba5..HEAD): the only drift was a STALE LEDGER — the C22
section still listed #102 (run-context header) and #108 (decimation) as deferred/open
after they shipped in 476342d. Resolved in this commit:
- the #101 first-cut note no longer claims "not yet a run-context header";
- a new "served-page hardening — cut 2" amendment records #102 (ChartMeta +
buildHeader, family window = span across members) and #108 (the pure decimate
min-max transform) as landed, both CLI-side (C14);
- the "Open architectural threads" list drops the now-landed run-context header.
Substantive gates (self-verified): C14 honoured — all decimation/header/pixel logic
is in aura-cli (render.rs/main.rs/chart-viewer.js); the only engine touch in range is
the one-line #100 cell.rs doc. C1 preserved — decimate is pure, deterministic
bucketing over the sorted-deduped spine, no-op under budget, monotonic spine (pinned
by a unit test). Regression: cargo test --workspace = 446 passed / 0 failed; cargo
clippy --workspace --all-targets -D warnings clean. No separate baseline script.
Residual debt filed as #110 (idea): the decimation budget is a fixed const (no
--width flag), and the min-then-max sub-pixel ordering is a real ts-displacement in
the non-default continuous x-mode. Both are local aura-cli refinements, neither a bug.
Ephemeral spec/plan removed at cycle close (docs/specs/0062, docs/plans/0062).
Cycle 0062 tidy: drift-clean after this ledger amendment.
Three tasks on the aura-cli render path + a workspace gate:
- Task 1 (#102, compile-atomic): ChartMeta + ChartData.meta, built from RunManifest
in build_chart_data/build_comparison_chart_data (gain a `name` param), every call
site threaded (emit_chart + 3 comparison unit tests + the render test helper), the
manifest re-injected into window.AURA_TRACES, the negative render pin flipped.
- Task 2 (#102): #ctx CHART_HEAD slot + a pure buildHeader in chart-viewer.js with a
node-driven headless guard pair (chart_viewer_header.{mjs,rs}).
- Task 3 (#108): a pure decimate(ChartData, buckets) min-max transform applied in
emit_chart on both paths; engine + registry untouched (C14).
- Task 4: cargo test --workspace + clippy -D warnings.
refs #108
refs #102
Architect drift review over 99fd32b..HEAD (the housekeeping commits #99/#98 plus
the 0061 cycle): code drift-clean. Engine untouched (aura-engine + aura-core diff
empty — C9/C14); C21 realized faithfully (the comparison view consumes a set of
runs, a family is the first producer, no orchestration-axis rebuild); C18/C10
refuse-don't-guess honoured (every new error path exits 2, never panics; all six
tracing entry points guarded before persist, so name resolution is total). The only
finding was a ledger-realization gap, lifted in this commit.
Ledger (docs/design/INDEX.md): added a C22 amendment recording the
families-comparison view as realized (#107) — aura chart <family> overlays one tap
across a family's members on a shared y-scale, union-ts spine giving one mechanism /
three correct readings, the write-guard totalising name resolution; reconciled the
two stale "families-comparison ... remain open" lines (the #104 note and the
open-threads list) and named the deferred follow-ons (#102 run-context header, #47
multi-column tap selection, the orchestration-composability rebuild).
Regression: cargo test --workspace green (no failures), clippy --workspace
--all-targets -D warnings exit 0, cargo build --workspace clean — verified by the
orchestrator before close. No baseline to update (aura's regression gate is the
gated determinism suite, which is part of the workspace tests).
Retire the cycle's ephemeral spec + plan (0061). refs #107
Three tasks: (1) aura-registry — NameKind/FamilyMember/WriteKind, name_kind,
read_family, ensure_name_free + a NameTaken error variant; (2) aura-cli — the
comparison ChartData builder (shared y-scale, union-ts spine), filter_to_tap,
parse_chart_args, the emit_chart name-kind branch, the --tap flag, USAGE; (3)
aura-cli — the write-guard calls in the six tracing fns + collision tests. Each
task RED-first with per-crate gates; workspace test + clippy at the close.
refs #107
Architect drift review (b92aab7..HEAD): the cycle is contract-clean — C9 (engine
untouched, whole change CLI-side), C6/C1 (real bars streamed from the pre-recorded
archive, real sweep byte-deterministic), C10 (refuse-don't-guess shared by run
--real and the family path), C12 (MC-exclusion fenced: mc --real exits 2). One
medium ledger-gap, now closed; one low item ratified as carry-on.
- Ledger: docs/design/INDEX.md C22 gains a "real-data family source" amendment
(#106) recording the opt-in real-data axis on sweep/walkforward families, the
DataSource provider, the MC exclusion (Fork A), and the oos{ns} key widening.
This was the only drift — a documentation gap, not code drift.
- Ratified carry-on [low]: the real walk-forward member key oos{from.0} is now an
epoch-ns integer; portable and collision-free, covered in practice by the
walkforward_real test (>=2 distinct oos<ns> dirs) and the 9-window E2E probe.
No explicit ns-uniqueness assertion beyond starts_with("oos") — acceptable; a
dedicated pin is not worth an iteration.
- Retire ephemeral spec/plan 0060 (git rm) per the cycle-artifact lifecycle; the
durable record is this ledger amendment + the git history.
No regression scripts configured (architect is the gate). Full workspace test +
clippy -D warnings green at close.
refs #106
Five compile-gated tasks for spec 0060: (1) additive DataSource/DataChoice
provider + ns roller constants, (2) pip-parametrize the two blueprints + thread
all callers, (3) thread &DataSource into the five family builders + run_sweep/
run_walkforward (dispatch passes Synthetic), (4) --real parser grammar +
build-or-refuse dispatch + USAGE, (5) gated real-path integration tests + full
suite + clippy. Each task threads its signature change with all callers so
`cargo build -p aura-cli --all-targets` is green per task; the byte-unchanged
synthetic path is the regression guard.
refs #106