03285d1b47
Milestone-scope fieldtest (closing functional gate) for "The World —
parameter-space & sweep" (issues #30-#36). Three curated end-to-end scenarios
derived top-down from the milestone promise, driven from the public interface
only (ledger + specs + rustdoc; no crates/*/src read), built and run from HEAD
via a downstream consumer crate.
Delivery verdict: GREEN. The milestone delivers its promise.
- mw_1 single run bound by name: .with("sma_cross.fast", 2).bootstrap() binds
and runs (12 equity rows); diagnostics precise and knob-named (UnknownKnob /
AmbiguousKnob / KindMismatch).
- mw_2 named-axis sweep + compare: .axis(..).sweep(run) yields a 4-member,
ordered (odometer), disjoint, non-constant SweepFamily; ranking from public
fields. CLI (aura sweep / aura runs rank) delivers the same with no Rust.
- mw_3 structural-constant negative space (deliberate): SMA2-entry's
definitional `2` has no honest expression today -> grounds #55. Out of
milestone scope; not a blocker.
Findings: 0 bugs, 2 working, 3 friction, 1 spec_gap. Verified independently
(re-ran all three from HEAD; confirmed a plain SMA-cross emits sma_cross.length
twice and the shipped CLI sample carries the fast/slow ParamAlias overlays).
Friction (routed to the forward queue, none blocks the gate):
- the promised sma_cross.fast/.slow names are not free — they require
author-added ParamAlias overlays, doubly mandatory because the canonical
2-SMA cross also will not bootstrap without them (IndistinguishableFanIn);
- the sweep closure drops back to positional bind + manual name re-zip.
spec_gap -> #55: the wished-for structural-constant consumer code is recorded
in mw_3 as #55's acceptance evidence.
This commit is the milestone fieldtest itself; it closes no issue. Closing the
tracker milestone stays a deliberate manual act on this green gate.
31 lines
1.6 KiB
Plaintext
31 lines
1.6 KiB
Plaintext
AVENUE (a) — param_space() of the SMA2-entry strategy:
|
|
sma2_entry.bias : I64
|
|
sma2_entry.slow : I64
|
|
scale : F64
|
|
|
|
>> The DEFINITIONAL SMA(2) length surfaces as `sma2_entry.bias` — an OPEN
|
|
>> knob, indistinguishable from the genuinely-tunable `sma2_entry.slow`.
|
|
>> A sweep `.axis("sma2_entry.bias", [2, 5, 10])` would enumerate DEFORMED
|
|
>> strategies (SMA-5-entry, SMA-10-entry) as valid family members.
|
|
>> param_space() declares a degree of freedom the strategy's definition
|
|
>> forbids. (C20: structural axes are NOT sweep params — but nothing here
|
|
>> distinguishes the two.) NOTE: the alias `bias` was FORCED on this knob
|
|
>> just to clear C9 IndistinguishableFanIn — so the surface makes me NAME
|
|
>> the constant as if it were tunable.
|
|
|
|
(avenue (a) runs: 12 recorded rows — it WORKS, but the 2 is fungible)
|
|
|
|
AVENUE (b) — capture the 2 as a construction constant (SimBroker pattern):
|
|
SimBroker::builder(1e-4) bakes pip_size OUTSIDE param_space (it is C10/C15
|
|
metadata — the broker declares NO param). The SMA2-entry author wants the
|
|
SAME for the length: a value baked at build, never a knob.
|
|
|
|
>> WALL: `Sma::builder()` takes no length arg (length is always a param),
|
|
>> and `Sma::new(2)` returns a built `Sma`, not a `PrimitiveBuilder` /
|
|
>> `BlueprintNode` — a blueprint holds value-empty RECIPES, not built nodes.
|
|
>> There is no `Sma::builder_with(2)` analogous to `SimBroker::builder(pip)`.
|
|
>> The construction-constant escape hatch exists for SimBroker (its builder
|
|
>> TAKES the constant) but is UNREACHABLE for a stock indicator node.
|
|
|
|
OK: scenario 3 recorded both wrong avenues + the wished-for code (grounds #55).
|