docs(C8): state output:vec![] as the sink declaration + eval return-width contract
Closes the spec_gap from the cycle-0006 fieldtest
(docs/specs/fieldtest-0006-substrate.md): the public surface never stated that
an empty `output` is THE pure-consumer (sink) declaration, nor defined what a
`Some` return paired with an empty output means.
The behaviour was already principled and defended in the engine — this only
documents it (no code change):
- `output: vec![]` is the pure-consumer declaration; there is no separate
Sink type/trait/marker.
- `eval` must return a row whose width equals `schema.output.len()`, so a pure
consumer returns `None` or a zero-width `Some(&[])`; the run loop
debug-asserts the width (harness.rs).
- field-wise wiring resolves `Edge::from_field` against the producer's output
at bootstrap, so no edge can bind a field of a zero-output node (it fails
with `BadIndex`) — a sink is structurally unwireable as an in-graph
producer; its only output is the out-of-graph side effect.
Ledger C8 gains an "Encoding & return contract" clause; aura-core node.rs
rustdoc (module, NodeSchema, Node trait) updated from the pre-0006 "1..K,
producer or transformer" wording to the three-role (producer/consumer/both)
contract.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -215,7 +215,15 @@ the record to a destination it holds as a field (a channel, a chart handle) —
|
||||
**out-of-graph side effect**. There is no `Sink` type, trait, or engine flag: a
|
||||
node that only records returns `None` (pure consumer), and a node may record
|
||||
**and** return an output the engine forwards in the same `eval` (the "both"
|
||||
case). In-graph routing stays engine-owned data (the edge table); the escape out
|
||||
case). **Encoding & return contract.** A pure consumer declares `output: vec![]`
|
||||
— the empty record *is* the sink declaration; there is no separate type, trait,
|
||||
or marker. Its `eval` returns `None` or a zero-width `Some(&[])`, and the run
|
||||
loop debug-asserts the returned row's width equals the declared output width
|
||||
(`row.len() == schema.output.len()`). Field-wise wiring resolves
|
||||
`Edge::from_field` against the producer's `output` at bootstrap, so no edge can
|
||||
bind a field of a zero-output node — it fails with `BadIndex` — making a sink
|
||||
structurally unwireable as an in-graph producer; its only output is the
|
||||
out-of-graph side effect. In-graph routing stays engine-owned data (the edge table); the escape out
|
||||
of the graph is the node's own side effect — and that boundary is the
|
||||
determinism / graph-as-data boundary (C1/C7).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user