diff --git a/docs/specs/0016-param-set-injection.md b/docs/specs/0016-param-set-injection.md index 1cd55d9..4cae3e0 100644 --- a/docs/specs/0016-param-set-injection.md +++ b/docs/specs/0016-param-set-injection.md @@ -62,13 +62,17 @@ lowering/wiring is unchanged in structure. bound values, so the `aura graph` *blueprint view* (`render_blueprint`, pre-inline cluster boxes) can no longer label a leaf `SMA(2)` — there is no `2` until a vector is injected. The view instead renders the **param-generic** label from -`LeafFactory::label()`: the node type plus its tunable knob *names*, e.g. -`SMA(length)`, `Exposure(scale)`, bare `SimBroker`. Both SMAs of a cross render -identically as `SMA(length)` (they are the same recipe; their distinct values live -in the vector, and the graph's edges still distinguish them positionally). The -*compiled view* is unaffected: it renders post-build flat nodes via the unchanged -`Node::label()`, so a bound `SMA(2)` still shows there. This is the correct C22 -reading — structure (param-generic) before a run, values (bound) after. +`LeafFactory::label()`: the **bare node type**, e.g. `SMA`, `Exposure`, `SimBroker`. +Both SMAs of a cross render identically as `[SMA]` (they are the same recipe; their +distinct values live in the vector, and the graph's edges still distinguish them +positionally). The tunable knobs are surfaced by `param_space()`, not in the graph. +The label is the bare type — not `SMA(length)` — because the `ascii-dag` renderer +writes a label verbatim on one line (no multi-line) and overlaps two wide sibling +boxes inside a cluster subgraph; a knob suffix garbles the view, and domain labels +grow unboundedly wide. The *compiled view* is unaffected: it renders post-build flat +nodes via the unchanged `Node::label()`, so a bound `SMA(2)` still shows there. This +is the correct C22 reading — structure (param-generic) before a run, values (bound) +after. **Vestigial pre-build interface, removed.** `Composite::schema()` and the private `BlueprintNode::schema()` derive a blueprint item's interface from its interior @@ -168,16 +172,14 @@ impl LeafFactory { pub fn params(&self) -> &[ParamSpec] { &self.params } pub fn build(&self, p: &[Scalar]) -> Box { (self.build)(p) } /// The param-generic render label for the blueprint view (C22 "structure - /// before"): the node type plus its tunable param *names* — no values, a - /// value-empty recipe has none — e.g. `SMA(length)`, `LinComb(weights[0], - /// weights[1])`, or bare `SimBroker` when paramless. + /// before"): just the node type, e.g. `SMA`. A value-empty recipe has no + /// values to show; the tunable knobs are surfaced by `Blueprint::param_space`, + /// not in the graph. The label is the bare type because the `ascii-dag` + /// renderer writes a label verbatim on one line (no wrapping / multi-line) and + /// overlaps two wide sibling boxes inside a cluster subgraph — a knob suffix + /// (`SMA(length)`) garbles the view, and domain labels grow unboundedly wide. pub fn label(&self) -> String { - if self.params.is_empty() { - self.name.to_string() - } else { - let knobs: Vec<&str> = self.params.iter().map(|p| p.name.as_str()).collect(); - format!("{}({})", self.name, knobs.join(", ")) - } + self.name.to_string() } } ``` @@ -247,7 +249,7 @@ pub enum CompileError { | Crate / file | Change | |---|---| -| `crates/aura-core/src/node.rs` | New `LeafFactory { name, params, build }` (+ `new`/`params`/`build`/`label`). `label()` renders the param-generic blueprint-view label from `name` + param knob names. `Node` trait unchanged — construction lives in the closure, not a new trait method. | +| `crates/aura-core/src/node.rs` | New `LeafFactory { name, params, build }` (+ `new`/`params`/`build`/`label`). `label()` renders the bare node type for the blueprint view (the ascii-dag renderer cannot render wide cluster-sibling labels, so no knob suffix). `Node` trait unchanged — construction lives in the closure, not a new trait method. | | `crates/aura-core/src/scalar.rs` | New value accessors `Scalar::as_i64(self) -> Option` and `as_f64(self) -> Option` (mirroring `Scalar::kind`), used by the build closures to read the kind-checked slice. | | `crates/aura-core/src/lib.rs` | Re-export `LeafFactory`. | | `crates/aura-std/src/*.rs` | Each node gains `fn factory() -> LeafFactory`. With params: `Sma` (`length:I64`), `Exposure` (`scale:F64`), `LinComb::factory(arity)` declares `arity` × `weights[i]:F64` (the arity is topology — fixed per blueprint, C19 — taken as a factory arg; only the weight *values* are injected). Paramless: `Sub`, `Add`, `SimBroker`, `Recorder` (`params: vec![]`; their `build` closures forward the non-param construction args these nodes already take, e.g. the `Recorder` channel — captured by the closure). | @@ -319,10 +321,10 @@ not the node (C20, established at #30's close), and full domain validation is - **Paramless harness.** `bootstrap_with_params(vec![])` on a paramless blueprint bootstraps and runs; a non-empty vector against it returns `ParamArity`. - **Blueprint-view render (C22).** `render_blueprint` on a value-empty harness - renders param-generic labels (`SMA(length)`, `Exposure(scale)`, bare `SimBroker`); - the compiled view, run on built flat nodes, still renders valued labels - (`SMA(2)`). The `aura graph` golden tests are re-expressed accordingly - (blueprint-view goldens become param-generic; compiled-view goldens unchanged). + renders bare-type labels (`[SMA]`, `[Exposure]`, `[SimBroker]`); the compiled + view, run on built flat nodes, still renders valued labels (`SMA(2)`). The `aura + graph` golden tests are re-expressed accordingly (blueprint-view goldens become + bare-type; compiled-view goldens unchanged). ## Acceptance criteria