Add single-run authoring convenience for param-bearing harnesses #35

Closed
opened 2026-06-07 18:50:00 +02:00 by Brummel · 1 comment
Owner

Part of milestone "The World — parameter-space & sweep". Deferred at the cycle-B (#31) design as a deliberate scope cut. refs #31.

Cycle #31 makes a blueprint value-empty: a node's tunable value lives only in the injected param-set vector, never baked into the builder (Sma::factory() declares the knob; Sma::new(2) no longer sits in a blueprint leaf). This keeps the blueprint a pure param-generic recipe (C19) — the load-bearing line the #31 design chose to keep clean.

The cost lands on the single-run path. A one-off backtest must now supply its point explicitly as a positional vector against param_space() order:

let bp    = sma_cross_harness();        // Sma::factory(), Exposure::factory(), …
let space = bp.param_space();           // [length:I64, length:I64, scale:F64]
let inst  = bp.bootstrap_with_params(vec![I64(2), I64(4), F64(0.5)])?;
//          └─ the author must order the vector by hand to match param_space()

For a sweep (#32) this is correct — the value comes from the run, not the author. For a single manual run it is verbose and order-fragile.

Direction: a thin authoring convenience that restores single-run ergonomics without reintroducing a default value into the blueprint (which the #31 design rejected). Candidate shapes, none chosen:

  • a named-param binding ({"length": 2, "scale": 0.5}) lowered to the positional vector via param_space(), so the author addresses knobs by name and the order-fragility disappears;
  • a builder that pairs a factory with a chosen value at the call site for a one-off instance, kept outside the blueprint's param-generic identity.

context: not blocking — bootstrap_with_params is the honest primitive and ships in #31; this is ergonomics atop it. Belongs after the sweep (#32) clarifies how a run supplies vectors, so the convenience matches that surface.

Part of milestone "The World — parameter-space & sweep". Deferred at the cycle-B (#31) design as a deliberate scope cut. refs #31. Cycle #31 makes a blueprint value-empty: a node's tunable value lives only in the injected param-set vector, never baked into the builder (`Sma::factory()` declares the knob; `Sma::new(2)` no longer sits in a blueprint leaf). This keeps the blueprint a pure param-generic recipe (C19) — the load-bearing line the #31 design chose to keep clean. The cost lands on the single-run path. A one-off backtest must now supply its point explicitly as a positional vector against `param_space()` order: ```rust let bp = sma_cross_harness(); // Sma::factory(), Exposure::factory(), … let space = bp.param_space(); // [length:I64, length:I64, scale:F64] let inst = bp.bootstrap_with_params(vec![I64(2), I64(4), F64(0.5)])?; // └─ the author must order the vector by hand to match param_space() ``` For a sweep (#32) this is correct — the value comes from the run, not the author. For a single manual run it is verbose and order-fragile. Direction: a thin authoring convenience that restores single-run ergonomics **without** reintroducing a default value into the blueprint (which the #31 design rejected). Candidate shapes, none chosen: - a named-param binding (`{"length": 2, "scale": 0.5}`) lowered to the positional vector via `param_space()`, so the author addresses knobs by name and the order-fragility disappears; - a builder that pairs a factory with a chosen value at the call site for a one-off instance, kept outside the blueprint's param-generic identity. context: not blocking — `bootstrap_with_params` is the honest primitive and ships in #31; this is ergonomics atop it. Belongs after the sweep (#32) clarifies how a run supplies vectors, so the convenience matches that surface.
Brummel added this to the The World — parameter-space & sweep milestone 2026-06-07 18:50:00 +02:00
Brummel added the idea label 2026-06-07 18:50:00 +02:00
Author
Owner

Scope narrowed (design discussion after #33): #35 is the named-binding convenience on the injected-vector side only — addressing param_space knobs by name ({"length": 2} lowered to the positional vector via param_space()) instead of by position. Pure ergonomics over #31's vector; the value still lives in the vector and stays sweepable.

The second candidate in the original body — "a builder that pairs a factory with a chosen value … kept outside the blueprint's param-generic identity" — is a different axis: a structural blueprint constant, a value NOT in param_space at all (variation deforms the strategy rather than moving it to another valid point). That is orthogonal to named-binding and is now tracked separately in #55. Dropping it from #35's scope so the two axes don't blur.

Scope narrowed (design discussion after #33): #35 is the **named-binding convenience on the injected-vector side only** — addressing param_space knobs by name (`{"length": 2}` lowered to the positional vector via `param_space()`) instead of by position. Pure ergonomics over #31's vector; the value still lives in the vector and stays sweepable. The second candidate in the original body — "a builder that pairs a factory with a chosen value … kept outside the blueprint's param-generic identity" — is a *different* axis: a **structural blueprint constant**, a value NOT in param_space at all (variation deforms the strategy rather than moving it to another valid point). That is orthogonal to named-binding and is now tracked separately in #55. Dropping it from #35's scope so the two axes don't blur.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Brummel/Aura#35