feat(aura-core): name input ports
PortSpec gains a non-load-bearing `name: String`, so an input port is named just as FieldSpec.name (output) and ParamSpec.name (param) already are — input ports were the lone unnamed member of the node signature. Identity stays positional by slot (C23); the name is render/debug only, never read by bootstrap or the run loop. PortSpec drops Copy (String is not Copy), exactly as ParamSpec already does. - Every aura-std node names its input slots: SMA/EMA "series", Sub/Add "lhs"/"rhs", Exposure "signal", SimBroker "exposure"/"price" (the slots become self-documenting), LinComb "term[i]" and Recorder "col[i]" generated in their build loops (mirroring LinComb's existing weights[i] param loop). - derive_signature carries a composite's Role.name into the derived input port (it was dropped before — the output side already carried FieldSpec.name), so the graph model is homogeneously named at both levels. - model_to_json (port_json + the composite-header inputs in scope_json) emits the name as a third tuple element: ["f64","any","exposure"]. The byte golden was re-captured (machine bytes) and its substring twins updated; the model is now fully named across inputs/outputs/params. - All 16 PortSpec construction sites threaded in one compile-gate change; test fixtures carry fixture names. C8 realization note added to the design ledger. Why name-only, no validation: the name is a pure debug symbol. Wire-by-name was rejected (it would be a C23 contract change). Bootstrap slot-wiring validation (which would close #21's same-kind swap footgun) is deferred to its own cycle — a name alone does not catch the swap; it makes the slots self-documenting and gives a future validation something to check against. Verified: cargo test --workspace 168 green; clippy --all-targets -D warnings clean; cargo build --workspace clean. Read-only render path (C9), no serde (C14), scalar kinds unchanged (C4). closes #50 refs #21 refs #51
This commit is contained in:
@@ -294,6 +294,18 @@ primitive returns its recipe's schema; a composite *derives* it from the interio
|
||||
role kinds in, re-exported field kinds out, aggregated params), so "every node has a
|
||||
signature in the blueprint" holds for composites too.
|
||||
|
||||
**Realization (cycle 0027 — name input ports, refs #21/#51).** `PortSpec` now
|
||||
carries a `name: String` (it drops `Copy`, like `ParamSpec`), so an input port is
|
||||
named just as `FieldSpec.name` (output) and `ParamSpec.name` (param) already are.
|
||||
The name is **non-load-bearing** (C23): wiring stays positional by slot, bootstrap
|
||||
and the run loop never read it; it exists for tracing / graph rendering (#13). Leaf
|
||||
primitives declare their slot names (`SimBroker`'s `exposure`/`price`, etc.);
|
||||
`derive_signature` carries a composite's `Role.name` into the derived input port,
|
||||
so the graph model (`model_to_json`) is homogeneously named across inputs, outputs,
|
||||
and params and across both graph levels. This does **not** close #21 (a swapped
|
||||
same-kind wiring is still only kind-checked) — it makes those slots
|
||||
self-documenting; a name-consuming validation is its own future cycle.
|
||||
|
||||
### C9 — Fractal, acyclic composition
|
||||
**Guarantee.** A composite is itself a `Node` that wires a sub-graph and exposes
|
||||
one output; signal, combined signal, and (with execution) strategy are all the
|
||||
|
||||
Reference in New Issue
Block a user