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.
96 lines
6.3 KiB
Markdown
96 lines
6.3 KiB
Markdown
# C20 — Strategy ↔ harness; the harness is the root sim graph
|
||
|
||
**Guarantee.** A **strategy** is a reusable composite-node blueprint (C9): broker-,
|
||
data-, and viz-independent, with inputs declared as named **roles** (symbol-agnostic
|
||
where possible) and the **bias** stream (C10) as output. A **harness** (the
|
||
experimental setup) is the **root sim graph** — sources bound to the strategy's
|
||
input roles + the strategy + attached broker node(s) + sinks — and is itself
|
||
produced by the bootstrap (C19). A harness *instance* is C1's disjoint unit (the
|
||
root scope). The harness has **two kinds of parameterization**: **structural axes**
|
||
(which strategy, which instrument(s), which broker(s), which window, which **risk
|
||
regime**) whose variation selects *different* instances — the **experiment matrix**
|
||
(the risk regime is the fourth axis, #210, carried as `CampaignDoc.risk`;
|
||
kept-separate, compared-not-selected, see C10) — and **tuning params** (the
|
||
strategy's numeric params) swept *within* a fixed structure (Fork A). The same
|
||
strategy blueprint is reused across backtest, sweep, visual workspaces, and the
|
||
frozen live bot — each a different harness. **Both strategy and harness/experiment
|
||
are authored in Rust** via builder APIs (C17); the experiment matrix is ordinary
|
||
Rust control flow (loops/conditionals), not a config schema. Ontologically, a node
|
||
(incl. a strategy composite) is an **open** fragment — free input roles + ≤1 output
|
||
(C8/C9) — that does not run alone; a **harness is the closed root graph**: a
|
||
strategy with its input roles bound to sources and its output terminated in
|
||
broker/sink nodes, under a clock. A harness is therefore **not a node** (no free
|
||
inputs, no output; it does not fit `eval`) — it is the *closure that runs*, C1's
|
||
disjoint unit / the root scope. Harnesses do not nest as nodes; the World (C21)
|
||
orchestrates them as objects.
|
||
|
||
**Forbids.** Embedding data sources / brokers / sinks inside a strategy; a
|
||
declarative experiment mini-DSL (logic is Rust — C17); modelling the harness as a
|
||
node (it is the closed root scope, not an open composable node). The mini-DSL
|
||
prohibition is scoped by the #188 role-model pass: it forbids an **open,
|
||
logic-bearing** experiment language (the RustAst trap), **not** the closed-vocabulary
|
||
**campaign document** (C25/C18) that carries persisted experiment intent — data
|
||
windows × strategy ids × param axes × process ref, under the total, declarative P1
|
||
construct tier (bounded axes, gates, ladders; no variables, no general recursion, no
|
||
unbounded iteration — invariant 5's no-free-feedback move applied one level up;
|
||
#188/#189). A *generator* that enumerates structural variants may still be
|
||
plain Rust; what it yields, and what a campaign declares, is data. Genuinely new
|
||
logic (metrics, analysis blocks) escalates to a new Rust block, never to a freetext
|
||
hole in the artifact.
|
||
|
||
**Why.** Reusability needs the strategy to be a context-free blueprint that many
|
||
harnesses embed. Modelling the harness as a root graph keeps it within the one
|
||
Node/graph abstraction (C9) and makes "10 strategies in one environment" and "one
|
||
strategy × N instruments" plain nested loops over the structural axes. Rust
|
||
authoring (not config) preserves full programmatic power — conditional/adaptive
|
||
matrices, generated axes, custom wiring — and avoids re-introducing the DSL trap
|
||
C17 rejects.
|
||
|
||
## Current state
|
||
|
||
**The shippable form is the `Composite` blueprint.** A **hand-wired `FlatGraph` is
|
||
not a shippable strategy** — it carries no `param_space()`, so the World families
|
||
(sweep / walk_forward / compare, C21) cannot consume it without a hand re-author.
|
||
The **canonical shippable form is the `Composite` blueprint** (the authoring source
|
||
level, C9/C19); the `FlatGraph` is only its compiled substrate (C23). This is
|
||
concrete in the GER40 session-breakout example (`ger40_breakout_blueprint`,
|
||
`crates/aura-ingest/examples/shared/breakout_real.rs`), whose `param_space()` is
|
||
exactly its tuning knobs and whose **bar period is a construction argument** binding
|
||
Resample + Session together — a structural matrix axis (C12: a different period is a
|
||
*different strategy*, not a sweep point), never a `param_space` entry, so a sweep
|
||
cannot desync the two clocks. Structural constants (e.g. a `delay.lag`, C8) are
|
||
bound out of the space.
|
||
|
||
**Experiment-matrix members are topology-data.** The "ordinary Rust control flow"
|
||
clause holds for the **generator** — the loop / conditional that *enumerates*
|
||
structural variants may stay Rust (C17). But each **member** it yields is a
|
||
**topology-data value** (C24), not a hand-coded blueprint nor engine-baked source: a
|
||
structural axis selects among *data* blueprints the World constructs, mutates, and
|
||
serializes, which is what makes structural variation first-class and searchable
|
||
rather than a hand-enumerated menu. Persisted experiment *intent* is the campaign
|
||
document (C25/C18).
|
||
|
||
**Pre-C24 scaffolding retired.** The pre-C24 scaffolding — `HarnessKind` and the
|
||
per-strategy `*_sweep_family` functions — is **gone**. The family builders are now
|
||
generic and blueprint-driven: `blueprint_sweep_family`, `blueprint_walkforward_family`,
|
||
`blueprint_mc_family` (and `blueprint_sweep_over`) in
|
||
`crates/aura-runner/src/family.rs`. The R-evaluator scaffold `wrap_r`
|
||
(defined in `crates/aura-runner/src/member.rs`; imported and called from
|
||
`runner.rs`) survives; its last hard data weld — the
|
||
hard-wired `price`←close role and the `M1Field::Close`-only open sites — is retired
|
||
(a strategy's input roles now bind archive columns by name, C26), and `wrap_r`'s
|
||
remaining R-scaffolding retirement is tracked at #159.
|
||
|
||
## See also
|
||
- [C9](c09-fractal-composition.md) — the strategy as a composite blueprint.
|
||
- [C10](c10-bias-r-cost.md) — the bias output and the risk-regime axis.
|
||
- [C17](c17-authoring-surface.md) — Rust authoring and the DSL prohibition.
|
||
- [C19](c19-bootstrap.md) — the bootstrap that produces the harness.
|
||
- [C21](c21-world.md) — the World orchestrates harnesses as objects.
|
||
- [C23](c23-graph-compilation.md) — the `FlatGraph` compiled substrate.
|
||
- [C24](c24-blueprint-data.md) — experiment-matrix members as topology data.
|
||
- [C25](c25-role-model.md), [C18](c18-registry.md) — the campaign document / run registry.
|
||
- [C26](c26-input-binding.md) — roles bind archive columns by name.
|
||
|
||
> History: [c20-strategy-harness.history.md](c20-strategy-harness.history.md)
|