8688a60ded
The single-file ledger had grown to 2968 lines / ~42k tokens, mixing current design law with accreted history: 59 cycle-stamped realization blocks, 18 [HISTORY] passages, 22 supersession markers, and the C10 / C22 / C24 reframe sagas layered several supersessions deep. A code-grounding audit (31 agents, adversarially verified) confirmed 11 defects stated as current truth: stale crate homes from the C28 #288 roster split (cost nodes, PositionManagement, PositionEvent, Session), the renamed InputSpec->PortSpec, the pre-#241 project model in C16 and the open-threads section, a stale HarnessKind retirement deferral in C24, and three C28-internal inconsistencies. New shape, per the ailang precedent: - INDEX.md stays the sole addressable entry point: foundation, external components, a C-id-keyed contract map (one line per contract), and only the genuinely open architectural threads. - contracts/cNN-<slug>.md carries each contract's current truth only: Guarantee / Forbids / Why with ratified refinements integrated, plus a code-anchored Current state. All confirmed defects are fixed here; crate anchors were re-verified against the tree. - contracts/cNN-<slug>.history.md (18 sidecars) and INDEX.history.md preserve every superseded block verbatim, stamps and issue refs intact, under a frozen-record banner. Nothing was deleted: superseded design intent remains an addressable working-tree artifact, off the per-cycle audit walk. - Ledger discipline is now stated in INDEX.md: live files are edited in place at cycle close, superseded text moves verbatim to the sidecar, and a supersession marker in a live file is itself an audit finding. Every contract file was verified against its old text by an independent zero-loss pass (statement-by-statement) plus a code-accuracy spot check; C-ids and contract titles are unchanged, so existing C-id citations in code, tests, and issues resolve as before.
83 lines
4.9 KiB
Markdown
83 lines
4.9 KiB
Markdown
# C12 — The atomic sim unit and the four orchestration axes
|
||
|
||
**Guarantee.** The atomic unit is `(frozen topology + param-set + data-window +
|
||
RNG-seed) → deterministic run → metrics`. Parameters are typed, ranged, runtime
|
||
values injected at graph build — no recompile per param-set; the optimizer sees a
|
||
generic vector of typed ranges. A **bound blueprint param is that param's
|
||
default**: "open" means *must be bound by an axis*, "bound" means *default,
|
||
overridable by an axis*, so axis 1 (param-sweep) may name a bound param — the
|
||
family boundary re-opens it on the probe and on every member reload, and the axis
|
||
binds it per cell; `run`/`mc` still require every param resolved (a truly open
|
||
param refuses). Identity is untouched: `content_id_of`
|
||
(`crates/aura-research/src/lib.rs`) and `topology_hash`
|
||
(`crates/aura-cli/src/main.rs`) read the authored document, never a re-opened
|
||
probe, and each member manifest records its per-cell bindings (#246, ratified
|
||
2026-07-12; the restriction this amends — axes bind only open knobs — was an
|
||
implementation consequence of `bind()` shrinking the param surface, not a recorded
|
||
decision). Raw data is shared read-only across sims via `Arc<[T]>` (the
|
||
data-server is built for this). Four axes orchestrate the atomic unit:
|
||
(1) param-sweep (grid/random), (2) optimization (argmax metric), (3) walk-forward
|
||
(rolling in-sample optimize + out-of-sample test), (4) Monte-Carlo (N seeded
|
||
realizations perturbing input). **MC = sweep over seeds**; each realization is
|
||
itself deterministic given its seed.
|
||
|
||
**Forbids.** Baking a specific search strategy (Bayesian/genetic) into the
|
||
primitive — those are pluggable policies atop the atomic unit; recompiling on a
|
||
param change.
|
||
|
||
**Why.** A stable primitive + orchestration axes keeps "wahnsinnig schnell"
|
||
(embarrassingly parallel across the unit) cleanly separated from search policy.
|
||
Seed-as-input reconciles Monte-Carlo with C1. The "frozen topology" of the atomic
|
||
unit is one harness instance, selected by the harness's **structural axes** (C20);
|
||
the structural experiment matrix is the outer orchestration over this dimension,
|
||
the tuning sweep the inner (C19/C20).
|
||
|
||
## Current state
|
||
`Harness::run` is typed as a **producer seam** — the object-safe `Source` trait
|
||
(`peek`/`next`, plus `bounds` and a `resident_records()` residency probe;
|
||
`crates/aura-engine/src/harness.rs`) that the k-way merge drives (C3). Two source
|
||
shapes back it. The eager `load_m1_window`/`close_stream` path
|
||
(`crates/aura-ingest/src/lib.rs`), wrapped as `VecSource`, materializes a whole
|
||
stream and is retained for bounded loads. The streaming `M1FieldSource`
|
||
(`crates/aura-ingest/src/lib.rs`) pulls a data-server window lazily, borrowing one
|
||
`Arc<[M1Parsed]>` chunk per pull (zero-copy *within* a source) and decoding each
|
||
`Scalar` on demand, so its **source ring** is resident O(one chunk), not
|
||
O(window length) — `resident_records()` is a *per-source* bound, not
|
||
whole-process RSS.
|
||
|
||
Raw-data sharing is realized both within and across sims. The data-server's
|
||
`FileCache` retains each window's parsed chunks read-only for the pass, so process
|
||
residency is O(records-touched) — the **replay-many** sharing model, not a leak.
|
||
Across sims, the sweep / Monte-Carlo / walk-forward families (axes 2–4) build their
|
||
members over **one** shared `Arc<DataServer>` (one `FileCache`;
|
||
`crates/aura-ingest/src/lib.rs`), so a window is parsed once and every member's
|
||
`M1FieldSource` borrows the same cached `Arc<[M1Parsed]>` chunks. The single-pass
|
||
*parse* cost of a window is tracked as #95.
|
||
|
||
Axis 1 (param-sweep) is built. `GridSpace` enumerates a cartesian lattice over
|
||
discrete per-slot value-lists; `RandomSpace` draws `N` seeded points over typed
|
||
continuous `ParamRange`s (I64 inclusive `[lo,hi]`, F64 half-open `[lo,hi)`),
|
||
validated against the param-space before any run; a `ListSpace` enumerates an
|
||
explicit point list. All implement the `Space` trait the disjoint `sweep` /
|
||
`run_indexed` core is generic over (`crates/aura-engine/src/sweep.rs`), so every
|
||
enumeration runs through one execution path (C1: results in enumeration order, not
|
||
completion order). The other axes are realized as families over that core:
|
||
`walk_forward` + `WindowRoller` (`crates/aura-engine/src/walkforward.rs`) for the
|
||
rolling in-sample/out-of-sample split, `monte_carlo`
|
||
(`crates/aura-backtest/src/mc.rs`) for the seed sweep; optimization is argmax over
|
||
a sweep's metrics, a policy atop the core rather than a baked-in strategy. The
|
||
seeded sampler reuses the bit-stable `SplitMix64`
|
||
(`crates/aura-analysis/src/lib.rs`) as a **code-path-disjoint** instance from the
|
||
data-edge seed RNG (the source-seam firewall, #52/#71: they share only the `u64`
|
||
type, never a path).
|
||
|
||
## See also
|
||
- [C1](c01-determinism.md)
|
||
- [C11](c11-sources-record-replay.md)
|
||
- [C18](c18-registry.md)
|
||
- [C19](c19-bootstrap.md)
|
||
- [C20](c20-strategy-harness.md)
|
||
- [C23](c23-graph-compilation.md)
|
||
|
||
> History: [c12-atomic-sim-unit.history.md](c12-atomic-sim-unit.history.md)
|