The amend chose `SMA(length)` (type + knob names) for the param-generic blueprint
view. Implementation surfaced that the ascii-dag 0.9.1 renderer writes a label
verbatim on one line (no multi-line — `render/ascii.rs::write_node` brackets the
raw string) and its Sugiyama subgraph layout overlaps two wide sibling boxes inside
a cluster (`[SMA(length[SMA(length)]`). Width is auto-computed but the cluster
packing does not honor it; the only spacing knob (`node_spacing`) is on the
deprecated config path, global, and width-independent — no robust option, and
domain labels grow unboundedly wide (`LinComb(weights[0], weights[1])`, deep
path-qualified names). Horizontal mode is already rejected (collapses fan-outs).
So `LeafFactory::label()` renders the bare node type (`SMA`). The tunable knobs are
surfaced by `param_space()`, not in the graph; the compiled view still labels built
nodes valued (`SMA(2)`) via `Node::label`. Correct C22 reading either way —
structure (now: type-only) before, values after.
refs #31
Plan-recon surfaced two surfaces the first draft under-scoped; resolved here after
a user design decision on the render form.
- Blueprint rendering (C22): a value-empty blueprint has no bound values, so the
`aura graph` blueprint view can no longer label a leaf `SMA(2)`. LeafFactory gains
`name` + `label()`, and the blueprint view renders the param-generic form
`SMA(length)` (type + tunable knob names, no values), chosen over a bare `SMA` to
surface the knobs the milestone is about. The compiled view (post-build flat
nodes) is unchanged — it still labels valued. Correct C22 reading: structure
before, values after.
- Vestigial pre-build interface removed: `Composite::schema` / `BlueprintNode::schema`
derive an item interface from built interior leaves; a value-empty leaf has none,
and both methods have no live caller (compile resolves every interface structurally
on the built flat nodes). Removed with their unit test. This is why the factory
carries no io skeleton — the build-then-wire decision stands, no schema duplication.
- OQ3: the swapped-sample mis-wiring moves from the builder args to the injected
vector; its observability moves to the compiled view (the blueprint view is
param-generic and identical for both orderings).
Grounding-check re-run: PASS (LeafFactory::label internally consistent; the
no-live-caller claim for the removed methods verified; blueprint-view vs
compiled-view goldens correctly partitioned).
refs #31
Cycle B of milestone "The World — parameter-space & sweep". A blueprint's tunable
values are injected at bootstrap rather than baked into the builder: a leaf becomes
a param-generic recipe (LeafFactory: params -> sized node), and a new build-then-
wire compile path binds a positional Scalar vector slot-by-slot against
param_space(), building each node through its own constructor.
Ratified design (brainstorm): value-empty B over mutate-in-place and over the
default-bearing variant. The value lives only in the injected vector (no baked
default), so the blueprint stays a pure param-generic recipe (C19); injected
values flow through the single new() sizing/validation gate; and because
compile_with_params consumes the vector in the same depth-first order param_space()
reports, the two share one traversal — subsuming #34's dual-traversal drift hazard.
Scope: one vector -> one instance; LeafFactory in aura-core; bootstrap_with_params/
compile_with_params; CompileError::{ParamKindMismatch, ParamArity}; Scalar::as_i64/
as_f64 accessors; fixtures/CLI/bit-identity re-expressed against the vector.
Deferred: sweep enumeration (#32), domain validation (#32/C20), single-run
authoring convenience (#35).
Gates: grounding-check PASS (8 current-behaviour assumptions ratified against green
tests; the sole BLOCK — a missing Scalar value accessor — resolved by adding it as
in-scope surface). Parse gate a no-op (profile declares no spec_validation).
refs #31