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
Cycle 0066, reference issue #133. Settled design (deferred from 0065): make SQN
the single-number objective for ranking a Stage-1 sweep family by R signal
quality.
Two halves:
- aura-registry: metric_cmp learns sqn / expectancy_r / net_expectancy_r (all
higher-is-better, reaching into RunReport.metrics.r); a member with r:None sorts
to the worst position. No persistence change (the family store already carries r).
- aura-cli: --strategy stage1-r sweeps the stage1-r harness over a fast×slow signal
grid (stop & sizing fixed — risk_budget is R-invariant, bias.scale is sign-only
for flat-1R, both degenerate axes; the stop defines the R unit so varying it
breaks cross-member SQN comparability — see the #133 decision log). The stage1-r
topology is extracted into a shared helper so the single run keeps its identical
binding (output unchanged by construction) and only the sweep floats fast/slow.
Signed under /boss via the grounding-check PASS (the autonomous signature). The
first grounding pass BLOCKed a false claim that the stage1-r single-run output was
already byte-pinned; the spec was revised so a golden characterization test is
added against current HEAD before the refactor (verifying byte-preservation rather
than assuming it), and re-grounded to PASS.
refs #133#117
Complete the deferred rename tail from cycle 0065's #126 (which renamed only the
typed metric, keeping the param namespace uniformly "exposure" so the single-run
rename would not smuggle in a ~30-site sweep-pinned change). Now renamed together
as one consistent unit, all driven by the Bias node's instance name:
- Bias::builder().named("exposure") -> .named("bias") (the harness builders +
the engine fixtures in test_fixtures.rs / blueprint.rs);
- the derived knob path exposure.scale -> bias.scale (Composite::param_space
derives the knob from the node name) -- the sweep .axis/.range bindings and
.with() points (blueprint.rs, main.rs), the walkforward ParamSpecs
(walkforward.rs), the member_key dir names, and the JSON byte-pins in
cli_run.rs / report.rs / main.rs tests;
- the exposure_scale manifest param label -> bias_scale (the single-run manifest
builders + the streaming_seam / real_bars fixtures).
The rename is surgical: the three targets (named("exposure"), exposure.scale,
exposure_scale) are syntactically distinct from the deliberately-kept "exposure"
forms, which are untouched -- SimBroker's pre-reframe exposure input slot +
prev_exposure + the exposure-integral; the LongOnly / gate / latch ports named
"exposure"; and the on-disk "exposure" tap label (the recorded bias series that
feeds `chart --tap exposure`, decoupled from the node name via
ColumnarTrace::from_rows("exposure", ...)).
No on-disk back-compat break: the knob path is a runtime param address, and
recorded params in old runs.jsonl / families.jsonl are inert data strings (a
pre-existing recorded "exposure.scale" still loads, it is just data).
INDEX.md cycle-0065 realization note amended: the param namespace is recorded as
the now-completed tail; the SimBroker slot + the on-disk tap label remain the
deliberate permanent keeps (#117), and exposure_sign_flips stays a serde alias.
Verified: cargo build --workspace --all-targets clean; clippy --all-targets
-D warnings clean; full suite 514 passed / 0 failed (source + byte-pins renamed
together); live `aura run` emits "bias_scale", `aura sweep` emits "bias.scale".
closes#134
refs #126#117
The --macd flag was a back-compat alias for --harness macd, added in cycle 0065
iter-3 while the uniform `--harness <name>` selector was introduced. With that
selector in place the alias is pure redundancy, so drop it: --harness <name> is
now the sole way to pick a built-in harness.
Removed from parse_run_args: the macd_flag accumulator, its match arm, and the
(harness, macd_flag) conflict resolution -- harness selection collapses to
`harness.unwrap_or(HarnessKind::Sma)`. Both usage strings drop `[--macd]`; the
parse_run_args doc and the parse_real_args note no longer cite the flag.
The MACD harness itself is untouched: run_macd, the macd() composite, and
`--harness macd` all stay. Tests updated -- the alias test becomes a positive
`--harness macd -> Macd` test plus an assertion that `--macd` is now rejected as
an unknown token; the "repeated --macd" edge is dropped (the flag is gone, and
repeated-flag strictness is still covered by --harness/--trace).
INDEX.md: the two realization notes that documented `--macd` as a live run form
updated (`aura run [--real ...]`; `run --harness macd`). The historical
graph-viewer retirement note and the frozen fieldtest capture are left as the
record of their time.
Verified: clippy --all-targets -D warnings clean; full suite 513 passed / 0
failed (assertions rewritten in place, no test count change); live smoke --
`aura run --harness macd` emits a RunReport, `aura run --macd` exits with the
updated usage.
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
Architect drift review of cycle 0065 (Stage-1 R: the exposure->bias rename, the
stop-rule + vol_stop, PositionManagement's dense R-record, the Sizer, summarize_r,
the public RiskExecutor, and the CLI surface): code is drift-clean - C10 fidelity
holds (bias->stop->Sizer->PositionManagement, flat-1R feed-forward, R stop-defined
and size-invariant, guarded by the cross-crate layout lockstep test), C9/C23
acyclic, the --harness selector is a compile-time match (no runtime registry/DSL,
C17). The milestone fieldtest is green after the tiny-pip tolerance fix (2ee0d74).
Lifted to the ledger (docs/design/INDEX.md):
- A C10 realization note for cycle 0065 recording the built Stage-1 R layer (the
chain, the public RiskExecutor + StopRule axis, the CLI surface, the scale-robust
guard, the aura-engine->aura-std normal dep) and that Stage 2
(currency/compounding/realistic brokers) stays the deferred downstream layer.
- Amended the C10 contract's "pending Stage-1 implementation" line (it landed).
Fixed stale prose introduced by iter-3's dependency-tier change: report.rs and
position_management.rs comments cited "aura-std is only a dev-dependency" as the
rationale for the by-convention dense-record layout contract; iter-3 made it a
normal dependency, so that rationale was false. Reworded to the real,
dep-tier-independent reason - the record crosses the crate boundary as a
type-erased Scalar vector (C4 SoA), read positionally, guarded by stage1_r_e2e.rs.
Carry-on filed as follow-ons (not actioned): the exposure->bias rename tail (the
serde-stable exposure_sign_flips key + slot/param names - commented on #126, the
recommended next iteration); CLI UX friction (#131); stage1-r harness cosmetic
smells (#132); R-sweep families + rank-by-sqn (#133).
This is a drift-clean cycle-close audit, NOT a milestone-container close: the
ephemeral spec/plans stay (spec 0065's change (a) still scopes the deferred rename
tail) and the milestone close stays a deliberate act for the user.
cargo build/test --workspace green; clippy --workspace --all-targets -D warnings clean.
refs #117#126
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
Amend the cycle-0065 spec with the "Iteration 3 - the CLI surface" design:
make the Stage-1 R layer operable from the command line (the research loop's
primary verb, ergonomic for Claude to drive), splitting the CLI/recording
surface out of the originally-lumped iter-2.
Design (forks derived under /boss, user-delegated "du entscheidest das Design",
recorded on #117):
- Promote vol_stop + risk_executor from test fixtures to public aura-engine
composite-builders; the embedded stop generalizes to a StopRule{Fixed,Vol}
enum (a C11 structural axis), vol_stop the volatility-defined default.
- aura run --harness <name>: a compile-time selector (sma|macd|stage1-r) over
Rust-authored built-ins - running, not wiring (C9/C17 intact: no runtime
registry, no DSL). Replaces the run literal-slice arms with a parse_run_args
tokenizer so --harness/--real/--trace compose orthogonally; --macd kept as an
alias.
- The stage1-r harness fans one bias into both SimBroker (pip) and the
RiskExecutor (R), so one RunReport carries both yardsticks honestly; the run
path folds summarize_r -> RunMetrics.r (additive, skip_serializing_if keeps
pip-only/legacy JSON byte-unchanged), round_trip_cost=0.0 (Stage-1 is
frictionless; a --cost knob is a follow-on).
- An r_equity tap (LinComb of cum_realized_r+unrealized_r) persists via an
extended persist_traces and renders through the existing aura chart --tap -
no new viewer code.
Scope line: "operable from the CLI" = run+inspect a Rust-authored harness (the
#109 (a) reading the contracts settle), not authoring topology in the CLI; the
broad #109 meta-level stays a separate future milestone. Deferred follow-ons:
R-sweep families + rank-by-sqn, rich R-record charting, the bias_sign_flips
metric rename (never carried out in iter-0; field is still exposure_sign_flips).
Verified before signing: grounding-check PASS (all substrate + post-patch
current-code claims ratified by green tests) - the autonomous /boss signature;
plus an advisory 5-lens spec-skeptic panel (criterion/invariants/scope SOUND;
ambiguity + plan-readiness BLOCKs resolved inline: the argv tokenizer, the
3-tap persist change, the round_trip_cost value, the dual-tap arg provenance),
re-grounded after the patch.
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
Stage-1 "R-based signal quality" cycle spec (milestone #119/#126/#127/#128/#129,
contract C10). Signal quality measured in R on a strategy's unsized bias stream,
feed-forward (no equity feedback): bias -> stop-rule -> position-management ->
per-trade R-outcomes -> summarize_r fold -> E[R]/SQN.
Design adversarially hardened (12-juror refute panel; decisions logged on #117):
- R is stop-defined and LATCHED at entry (frozen R-denominator, never re-read).
- Stop-outs are NOT capped at -1R (honest loss tail; gap-through -> R < -1).
- Fills one-cycle-lagged (SimBroker no-look-ahead discipline; RED test mandatory).
- First stop is volatility-scaled (VolStop = k * EMA(|d price|)), not constant
(a constant makes R just rescaled pips).
- position-management emits a dense per-cycle R-record (trade ledger + R-equity +
window-end handling), tapped by a Recorder, folded post-run by summarize_r
(a post-run fold, NOT an in-graph node).
- Sizer = load-bearing flat-1R seam; R computed size-invariantly. Veto = doc seam,
not a runtime node (DCE deletes an identity).
- exposure -> bias rename lands first (compiler-driven).
Grounding-check PASS (11 assumptions ratified by green tests; auto-signed under /boss).
refs #117
Adopt the R-reframe ratified in #117: the strategy's native unit is risk
(R), not pips/dollars, and its primary output is a directional bias.
- exposure -> bias: the primary output is an UNSIZED direction + conviction
`f64 in [-1,+1]`; sizing and the protective stop leave the strategy.
- Signal quality is measured in R (Stage 1): an R-evaluator integrates the
per-trade R-outcomes of a flat-1R RiskExecutor into R-expectancy. R is
defined by the stop, account-/instrument-agnostic; pips retired as the unit.
Flat-1R needs no equity, so Stage 1 is feed-forward (no cycle).
- Risk-based execution is a decoupled layer: a RiskExecutor composite
(stop-rule -> Sizer -> Veto -> position-management) per symbol, nested in a
Broker/Account composite; account mode (netting/hedging) = composition
constraint. "Sizer" is not "risk-manager" (that names the Veto layer).
- Currency P&L is Stage 2 (fixed-fractional, compounding). The only feedback
(equity -> Sizer) is cut by a z^-1 register on the fill edge (mark-to-market
stays a same-cycle price read), encapsulated in the executor; flat-1R vs
compounding is a structural axis (the explicit register is mandatory because
C23 reorders the flat graph).
- Position-event table stays the decoupled Stage-2 audit layer = first
difference of the book (deal = target - book - in_flight); the flawed 0064
exposure-integral derive is abandoned.
Touches: ledger C10 + CLAUDE.md domain invariant #7 + glossary (adds bias, R,
R-evaluator, RiskExecutor, Sizer, veto, Stage 1/2; revises broker, exposure
stream, position table, sim-optimal broker, strategy, ...). Also fixes
cross-file drift surfaced by adversarial review (C20 guarantee + front-matter
provenance still claimed "exposure stream"; cross-refs corrected to
C9/C19/C20/C23). Industry-grounded against LEAN / nautilus_trader / backtrader
/ QSTrader / vectorbt / zipline.
refs #117
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
The broker milestone's (C10 A-side) foundation: two pure value-type
deliverables, no broker and no derivation yet.
- #113: extend InstrumentSpec with deploy-grade fields (instrument_id,
contract_size, pip_value_per_lot, min_lot, lot_step, quote_currency) +
populate the vetted table for the five instruments; refuse-don't-guess
arm stays. Permanent authored floor of the override hierarchy (#124).
- #114: PositionAction { Buy, Sell, Close } (closed enum, serde-encoded as
i64) + PositionEvent row in aura-engine, faithful to the C10 column spec
(no open_ts, unsigned volume, direction is the action).
Signed under /boss on a grounding-check PASS (all current-state assumptions
ratified by green tests; the two new types are greenfield, expected).
Derived fork decisions (quote_currency &'static str; action enum encoded as
i64 0/1/2; stable instrument_id + overridable vetted values) recorded on #113.
refs #113#114
The cut-2 amendment described decimate as a pure min/max transform; #111 made the
per-bucket reduction tap-aware (mean for the bounded exposure, min/max for equity).
Keep the always-loaded design memory accurate; note #112 (bars/OHLC rendering) and
#110 as the remaining deferred refinements.
refs #111#112
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
Served-page hardening for the families-comparison chart, bundling two issues that
share one code locus (the aura-cli render path) and one purpose (C22/C14: make the
#107 view openable + legible on real multi-year families):
- #108 — serve-time min-max decimation as a pure ChartData->ChartData transform in
emit_chart (both single-run and family paths), bounding the served page to a few
thousand points regardless of the underlying M1 point count; full data stays on
disk; the WFO null-fill page collapses for free. Engine/registry untouched.
- #102 — a ChartMeta threaded from RunManifest into window.AURA_TRACES, rendered by
a new pure buildHeader in chart-viewer.js (headless .mjs guarded), showing
name/window/broker/commit/taps (+ member count for a family).
Signed under /boss on the Step-5 grounding-check PASS (10/10 load-bearing
assumptions ratified by green tests).
refs #108
refs #102
Add an "Open architectural threads" entry that ties together aura's differentiator
(C21): the composable-orchestration rebuild (sweep/MC/walk-forward as composable
tools, not hard-wired CLI verbs) + the project-as-crate authoring layer (aura new /
experiment-builder API / Aura.toml / cdylib loading, C16/C17). Records the
load-bearing open fork — "driven via the CLI" = running a Rust-authored experiment
(compatible with C16/C17/C22) vs wiring nodes through the CLI itself (a deliberate
amendment to C17/C22/C9) — to be resolved in the brainstorm before any cycle.
Keeps the meta-level in focus in the always-loaded design memory; #109 is its
tracker home. No design decided here (the fork is recorded, not resolved).
refs #109
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
A read-side cycle: `aura chart <family>` overlays one tap (default equity) of all
members of a sweep / MC / walk-forward family in one self-contained uPlot page,
consistent across kinds via the existing union-ts spine. The view consumes a
"set of runs to compare" (a family is its first producer) — the first step toward
the programmable analysis meta-level (C21), without rebuilding the orchestration
axes. aura-registry gains name_kind / read_family / ensure_name_free (a write-guard
making name resolution a total function); aura-cli gains the comparison ChartData
builder + emit_chart branch + --tap. aura-engine untouched (C9/C14).
Brainstorm-ratified, grounding-check PASS (11/11 current-behaviour assumptions
ratified by green tests). Signed under /boss on the grounding PASS.
refs #107
The built-in family grid was calibrated for the synthetic demo streams (18/60
bars), where trend SMA 2-5 / MACD 2-4-3 are the only lengths that warm. Over real
M1 data those are noise — ~9000 exposure sign-flips per month, a strategy trading
the bid-ask wiggle, not a trend.
DataSource::strategy_lengths() makes the grid data-kind-dependent (like
wf_window_sizes): synthetic keeps {2,3}x{4,5} + MACD 2/4/3 (byte-unchanged); real
uses {50,100}x{200,400} trend SMAs + standard 12/26/9 MACD. Threaded through
sweep_family + sweep_over (the walk-forward in-sample sweep). Over real EURUSD the
monthly flip count drops from ~9000 to ~130-310 — a genuine trend cross.
This is a demo-strategy calibration patch (ledger C22 amendment notes it as such);
the real answer is project-authored strategies owning their own grid (C9), deferred
to the project-env work.
Verified: cargo test -p aura-cli (all green, synthetic byte-unchanged),
clippy -D warnings clean; real sweep probe shows ~130-310 flips/month.
refs #106
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
Opt-in `--real <SYMBOL> [--from <ms>] [--to <ms>]` for `aura sweep` and
`aura walkforward`, mirroring `aura run --real`: each family member streams real
M1 close bars from the local data-server archive instead of the synthetic stream.
MC is excluded — its seed varies a synthetic price-walk realization, undefined
over real data (one realization -> identical members; a real MC needs a
bootstrap-resampling axis, its own cycle).
Engine, ingest, and registry untouched: a CLI-side `DataSource` provider replaces
the hardcoded `VecSource`. `M1FieldSource` already impls `Source`; `WindowRoller`
already rolls over epoch-unit timestamps.
Boss-signed: Step-5 grounding-check PASS — all 8 load-bearing current-behaviour
assumptions ratified by named, currently-green tests.
refs #106
Cycle-close tidy for the generic portable sweep member-key + bool-param demo
strategy (spec/plan 0059, reference issue #105, implementations 27f850d + 0b73a75).
Architect drift review (range 1d6fafb..HEAD): clean — no drift, no debt.
- C1 (determinism): varying_axes + member_key are pure functions of the grid
point, no schedule state; the engine carries no trace state (consistent with
the #104 design + the C22/#101 ledger note).
- C7/C8/C9: LongOnly is a clean one-in/one-out f64 node, None until warmed (C8
filter), the first bool *param* through the already-ratified Cell::bool()
path; momentum is an ordinary composite of existing nodes; brokers stay
downstream (C10). C18/C21/C22 upheld.
- The engine accessor exposes the binder's OWN axis-cardinality knowledge (it
holds the value-lists), not a presentation concern — formatting stays in the
CLI. The hand-rolled fnv1a64 mirrors the ledger-blessed SplitMix64 precedent
(harness.rs): tiny, dependency-free, bit-stable-on-purpose (std DefaultHasher
is unstable across releases; on-disk-name stability is the per-case C16
reason). LongOnly is a genuine universal aura-std block (long-only is
asset-agnostic). The ledger amendment matches the code.
Regression: the project declares no dedicated regression command; the gate is
the architect review plus the full suite, verified green at 0b73a75 (cargo test
--workspace, clippy --all-targets -D warnings).
Spec docs/specs/0059 and plan docs/plans/0059 retired (git rm) per the ephemeral
active-cycle artefact lifecycle; the durable rationale (the portable member-key
convention) lives in the ledger amendment (docs/design/INDEX.md C22/#101 note)
landed in 0b73a75.
closes#105
Proves the #105 generic portable member key end-to-end: a demo strategy whose
params have nothing in common with the SMA-cross demo, swept by the same
machinery, with a bool axis surfacing — conformant — in the member dir names.
- momentum strategy: price -> Ema(length:i64) -> Sub(price-ema) ->
Exposure(scale:f64) -> LongOnly(enabled:bool) -> SimBroker. Three swept params
of three kinds incl. a bool; the exposure sink taps the post-gate exposure so
the bool's effect is in the trace.
- aura sweep gains --strategy <sma|momentum> via a pure, unit-tested
parse_sweep_args (mirroring parse_real_args); default = SMA-cross, so the
existing bare / --name / --trace forms are unchanged.
- `aura sweep --strategy momentum --trace mom` persists 8 member dirs named e.g.
ema.length-5_exposure.scale-0.5_longonly.enabled-true — the bool in the dir
name, every name matching [A-Za-z0-9._-], each chartable.
- ledger (docs/design/INDEX.md): the C22/#101 member-key note's sweep clause
amended to the generalised portable form (MC seed{N} / walk-forward oos{ns}
unchanged).
Self-verified: cargo build --workspace, cargo test --workspace (all green incl.
momentum_param_space_is_ema_exposure_longonly, the 8-point determinism test,
the parse_sweep_args grammar test, and the momentum_sweep_trace integration test
asserting 8 portable bool-bearing dirs + a chartable member), cargo clippy
--workspace --all-targets -D warnings.
refs #105
Generalises the family-member trace key (#105 foot-gun): derive it from the
axes that actually vary (not two hardcoded axis names), and render it as a
filesystem-conformant directory name on every major OS — charset [A-Za-z0-9._-],
case-less values (no case-insensitive-FS collision), length-bounded with an
FNV-1a fallback for the unbounded-grid edge.
Adds the first bool *param* node (LongOnly) and a momentum demo strategy
(Ema -> Sub -> Exposure -> LongOnly -> SimBroker) swept via a new
`aura sweep --strategy <sma|momentum>` selector — the empirical proof the
generic key works for a strategy whose params (incl. a bool) differ entirely
from the SMA-cross demo.
Boss-signed on the Step-5 grounding-check PASS (an independent fresh-context
agent): all 9 load-bearing current-behaviour assumptions ratified by green
tests; the end-to-end bool-param sweep path is correctly scoped as new
behaviour proven by new tests, not assumed. Workspace type-checks clean.
refs #105
Cycle-close tidy for family-member trace persistence (spec/plan 0058,
reference issue #104, implementation d3cb5f8).
Architect drift review (range 06fdafa..d3cb5f8): drift_found, low-grade
only — no contract violated. C1 (determinism), C7 (SoA), C8 (sinks),
C18/C21 (registry/families) all upheld; the opt-in --trace path is
genuinely byte-neutral. Two items, both resolved here:
- [high] Ledger gap: the C22/#101 disk-trace note recorded only the
single-run runs/traces/<name>/ layout. This cycle establishes a new,
load-bearing on-disk convention (per-member nested standalone run-dirs
runs/traces/<name>/<member_key>/) that the deferred family-comparison
view will build on. FIXED: amended the C22/#101 realization note in
docs/design/INDEX.md to record the layout, the content-derived
deterministic member keys, and the parallel-safe lock-free write.
- [medium] sweep_member_key hard-codes two grid axes; collision-free only
over today's built-in grid, a latent foot-gun if the grid varies an
unlisted axis. Not a current defect (one grid, covered, fail-loud on a
missing listed axis). CARRY-ON: filed #105 (idea) for generalised key
derivation when the grid generalises.
Regression: the project declares no dedicated regression command; the
gate is the architect review plus the full suite, verified green at
d3cb5f8 (cargo test --workspace, clippy --all-targets -D warnings).
Spec docs/specs/0058 and plan docs/plans/0058 retired (git rm) per the
ephemeral active-cycle artefact lifecycle; durable rationale lifted to
the ledger amendment above.
refs #104
Three tasks (MC, sweep, walk-forward) wiring per-member trace persistence
into the family closures + a full-suite/lint gate. Each task threads its
builder signature and every caller together so the workspace compiles
green per task.
refs #104
Persist each family member's equity/exposure streams to disk (opt-in
--trace on sweep|mc|walkforward), mirroring the single-run trace path, so
the C21 family-comparison view has per-member data and any single member
is chartable today. Write side only; the comparison view, decimation,
and a binary trace container are deferred.
Autonomously signed under /boss on the Step-5 grounding-check PASS.
refs #104
Architect drift review over 5bff7e0..HEAD: clean, no drift, no debt. C14/C7
firewall intact (main.rs byte-unchanged → build_chart_data still returns
ChartData{xs,series}, the injected window.AURA_TRACES payload shape untouched;
the ordinal index spine is derived client-side). C22 holds — the
ordinal/continuous toggle + wheel-zoom/drag-pan/dblclick-reset are view
affordances over a recorded trace (read-only setScale on the x range), not a
scene editor. The #102 manifest-header gap is neither closed nor regressed,
still tracked.
Regression gate: cargo test --workspace green (incl. the four chart guards +
render inline tests), clippy --all-targets -D warnings clean; aura has no
separate regression script, so the suite + architect are the gates. cycle
clean.
Spec/plan 0057 retired per the ephemeral-artifact lifecycle (durable record:
the feature commit 45cc1c4, the #103 decision-log comments, and git history).
refs #103
Tier-1 comfort pass for the served trace chart (#103): an ordinal x-axis
default (collapses non-trading gaps) with a one-click continuous toggle, plus
wheel-zoom / drag-pan / dblclick-reset, a value-readout legend, and panel
cursor-sync. Confined to the read/render side (chart-viewer.js + render.rs
CHART_HEAD); the Rust serve contract is unchanged.
Boss-signed: grounding-check PASS (five current-behaviour assumptions ratified
by green node guards + render.rs inline tests). Derived-fork decision log in
the #103 comments.
refs #103
Cycle-close audit for the trace-charts visual face (#101, shipped across
8bb5256 persist + 15ee6d5 serve). Architect drift review (13941a2..HEAD)
+ the regression gate (cargo build/test/clippy --workspace, all exit 0,
orchestrator-verified).
What holds (carry-on): C14 clean — aura-engine/aura-core carry zero
UI/HTML/uPlot knowledge; ColumnarTrace does struct->encoding only, file
I/O in aura-registry, rendering in aura-cli. C1/C3 clean — persistence
and serve-time alignment are post-run pure reductions (join_on_ts at
serve time only, never in-graph). C7 clean — on-disk f64 columns +
kinds-tagged base types, the documented coercion honest, no 5th scalar.
Resolutions:
- [fix] Added the C22 realization note now that the web-from-disk seam
shipped (the amendment 3b56efb had deferred it to "when the seam
ships").
- [ratify] The served page injects the chart SERIES but drops the run
manifest (no run-context header) — a deliberate, defensible naive-viewer
scope call (the manifest is on disk in index.json; a header matters most
for the deferred families/comparison work, C21). The deviation from spec
0056 §1/§4 landed unflagged in 15ee6d5; it is now flagged here and
tracked as a follow-up. refs #102
- [tidy] Retired this cycle's ephemera (spec 0056, plans 0055/0056) and
the stale debris from the prior Runway close (spec 0055-fieldtest) per
the ephemeral-artifact convention; the durable record is the ledger +
git history.
Cycle drift-clean (modulo the ratified, tracked manifest-header gap).
refs #101
Iteration-1 (persist half) plan for spec 0056: ColumnarTrace (aura-engine), TraceStore (aura-registry), and the shared persist_traces helper threaded into all three run forms. RED-first; Task 3 folds all nine signature-change callers in before the build gate (per plan-recon's compile-gate warning). Serve/chart half deferred to iteration 2.
refs #101
First cut of aura's visual face (issue #101; the web-from-disk pivot
ratified into C14/C22 this session, commit 3b56efb): tap arbitrary
recorder streams from a run, persist them to disk as columnar (SoA)
JSON, and serve them as a self-contained uPlot HTML chart — feeds
overlaid on a shared timestamp axis, or timestamp-aligned in stacked
panels. `aura run [--macd] [--trace <name>]` and `aura run --real <SYM>
... [--trace <name>]` persist; `aura chart <name> [--panels]` serves.
Both modes share one synthetic-union-spine join_on_ts alignment.
Signed via the specify auto-sign gate: the user is away under an
explicit "work fully autonomously, document decisions" mandate, so no
manual signature was available. All objective gates green (precondition
clean, self-review clean, grounding-check PASS), and a unanimous 5-lens
adversarial spec-skeptic panel (criterion / grounding / scope-fork /
ambiguity / plan-readiness all SOUND).
The panel earned its keep — two self-correction rounds to unanimity:
- Round 0 caught (a) panels shipped NOT timestamp-aligned, contradicting
the user's verbatim "aligned nach Timestamps in Panels" — corrected to
conform to issue #101 Fork A; (b) the USAGE advertised `--macd --trace`
with no dispatch arm — corrected to an orthogonal `--trace` composing
with every run form via a shared persist helper.
- Round 1 caught the union-spine -> join_on_ts mapping under-specified
(which tap is the spine?) — corrected with an explicit 3-step
synthetic-empty-spine mechanism (no privileged tap, no points dropped),
plus a to_rows uniformly-f64 clarification.
The two delegated naive-viewer decisions (per-series y-scale, union
spine) are documented with provenance on issue #101.
refs #101
The visual face pivots from the ledger's egui-native, in-process
zero-copy direction to a web frontend served from disk-persisted
recorder traces: the engine writes recorded traces to disk, a browser
charts them. Settled in an in-context design discussion (provenance in
issue #101): raw per-tap trace persistence + serve-time join_on_ts
alignment + a static self-contained HTML chart (uPlot). The engine
stays headless (C14) — arguably more strictly, since a browser reading
a serialized file is further from the hot path than egui reaching into
the live SoA columns. Amends the C14 visual-face note and the open
"Playground & World UI surface" thread; the C22 realization note lands
when the seam ships.
refs #101
Milestone-close fieldtest for "Runway — real-data ergonomics & honesty
hardening". Four curated end-to-end scenarios derived top-down from the
milestone promise, run as a downstream consumer against real GER40/EURUSD M1
bars (public interface only; no crates/*/src read):
1. per-instrument pip honesty (#22) — GER40 index pip 1.0 AND EURUSD forex
pip 0.0001 both honest end-to-end; AAPL.US/FOOBAR un-vetted refused
exit 2, no stdout leak
2. real GER40 M1 open via open_ohlc from aura-ingest ALONE (#80/#81/#92) —
no data-server dep, 53173 real bars, C4 O/H/L/C order, ts-window inverse
3. multi-tap ts-join (#93) — two taps at different cadences, 27744 rows,
0 by-ts mismatches; warm-up None rows where a positional zip would corrupt
4. run-registry coherence (#73/#82) — list/rank retired exit 2, families/
family live, two-store Registry read-back + rustdoc
Findings: 4 working, 1 friction, 1 spec_gap.
- friction: Cell exposes only from_i64/from_f64/... while the side-by-side
Scalar is a tagged enum with public I64(..)/F64(..) variants. The natural
param-authoring entry point is Scalar (Cell is the hot-path buffer carrier),
so the wrong reach is a self-correcting compile snag — ergonomic only.
Filed as a follow-up idea.
- spec_gap: unknown family id exits 0 empty — ratified into the C18 note in
the preceding commit (treat-as-empty contract).
Gate verdict: GREEN. All seven axes mapped to a covering scenario and exercised
on real bars; both finding classifications and the one material coverage gap
were adversarially re-verified. That gap — #22's FX-vetted pip face, untested by
the original scenario set — was probed (EURUSD -> sim-optimal(pip_size=0.0001),
FX-scaled, not index-mis-scaled) and folded into scenario 1, so the pip promise
is demonstrated on both positive faces. Every scenario re-run independently on
HEAD before commit.
The Runway milestone fieldtest surfaced a spec_gap: `aura runs family <id>`
with an unknown-but-well-formed id exits 0 with empty output, and neither the
ledger nor the glossary constrained that case. The behaviour is already the
documented, tested CLI contract (treat-as-empty, mirroring Registry::load's
missing-store = Ok(empty)); this lifts that contract to the durable C18 note
so a consumer reasoning from the spec can derive it, and records that tightening
to a non-zero "no such family" exit (typo-safety) stays an available future UX
choice rather than a current contract.
Ratifies the spec_gap from docs/specs/0055-fieldtest-runway-real-data-seam.md.
The milestone-close architect flagged that the runs-retire note over-claimed
"retained because used": after dropping runs list/rank, Registry::append/load (the
flat-store half) have no in-tree caller — only rank_by/optimize keep live
consumers. Note now distinguishes the live half from the public-but-uncalled half
(a latent dead-code surface for a later sweep). Doc-only.
Since cycle 0045 the flat runs.jsonl store has had no producer (sweep/mc/
walkforward persist to the family store; `aura run` does not persist), so
`aura runs list` / `runs rank` read a store nothing populates — a live dead-end
surface, the honesty gap the Runway milestone closes.
Resolve the C18 deferred fork (INDEX.md) as (b) RETIRE: drop the two CLI commands
+ their dispatch arms, usage fragments, and the now-unused load_runs_or_exit.
Families (sweep/mc/walkforward, C21) subsume standalone over-time comparison. The
aura-registry flat lib API (append/load/rank_by/optimize) is RETAINED — optimize
backs walk-forward's in-sample step, rank_by backs `runs family ... rank`.
`runs families` / `runs family` are untouched.
Decision recorded on #73 (user-directed (b), 2026-06-18). Cosmetic sub-item
(json! family-wrapper -> to_json() stdout key-order unification) deferred to a
follow-up: json! routes the embedded report through serde_json::Value, which
re-alphabetizes keys, so it needs manual JSON construction, not a trivial swap.
RED-first: the retire test asserted `runs list`/`rank` now exit 2 (was exit 0).
Verified: cargo build --workspace, clippy --all-targets -D warnings, and
cargo test --workspace all green.
closes#73
Audit (architect drift review + cargo test --workspace) clean: code matches the
spec, the engine stayed domain-free (no instrument identity in Ctx / the hot
path), InstrumentSpec sits beside the hot path per C7/C15. No regression scripts
configured (no-op gate); the full suite is green.
Ratify: the architect flagged one ledger-realization gap — C10/C15 described
per-instrument pip as standing design intent but carried no realization note for
the now-shipped channel. Added dated realization notes to C10 (the per-instrument
pip channel + the refuse-don't-guess honesty rule) and C15 (instrument specs as
metadata, first realized by InstrumentSpec/instrument_spec).
Retire the ephemeral cycle artefacts (spec 0054, plan 0054) per the active-cycle
lifecycle. Deferred follow-up: #98 (route the runnable GER40 examples through the
lookup).
refs #22