audit(0070): cycle close — lift finalize lifecycle to ledger C8, drop ephemera
Cycle 0070 (streaming sink reductions, #138) close. Durable rationale lifted to the ledger: C8 now records the end-of-stream `finalize` lifecycle (the second node phase beside `eval`), its `Harness::run` topo-order epilogue, and its C1/C7/C8 reconciliation — with the open `Recorder`->`Probe` / per-cycle-allocation question (#77) cross-referenced, since `finalize` is the "non-channel exit" that issue's accumulate-then-read option named as missing. The per-cycle spec and plan are git-rm'd (ephemeral, valid only for their cycle). Audit (architect) found no invariant breakage; noted debt, left as-is: the two-mode `stage1_r_graph` (reduce vs raw sink wiring) rests on the CLI-seam equivalence test rather than structural unification, and `SeriesReducer.last_ts` carries the last *warm* cycle's ts (latent only if `--trace` ever folds). refs #138
This commit is contained in:
@@ -275,6 +275,26 @@ out-of-graph side effect. In-graph routing stays engine-owned data (the edge tab
|
||||
of the graph is the node's own side effect — and that boundary is the
|
||||
determinism / graph-as-data boundary (C1/C7).
|
||||
|
||||
**Refinement (cycle 0070 — end-of-stream `finalize` lifecycle, 2026-06-25).** The
|
||||
node contract gains a second lifecycle phase beside `eval`: `finalize(&mut self)`,
|
||||
a **default-no-op** trait method the engine calls **once per node, in topological
|
||||
order, after the source loop drains** (the `Harness::run` epilogue). It lets a sink
|
||||
**fold online** — accumulate per `eval` into O(trades)/O(1) owned state and flush
|
||||
one compact summary at stream end — instead of pushing a record every fired cycle
|
||||
into an unbounded channel that buffers O(cycles) rows until the run ends (the
|
||||
retention BLOCKER #138 hit: a full-history Stage-1 sweep held ~2 GiB/member over
|
||||
~5.5M one-minute bars). C1/C7/C8 are preserved: `finalize` runs once *after* the
|
||||
deterministic event loop, adding no within-sim concurrency (C1); a folding sink
|
||||
holds only owned accumulator state, no interior mutability (C7); it still declares
|
||||
`output: vec![]` and its flush is the same out-of-graph side effect (C8) — one
|
||||
summary row, not a per-cycle stream. Realized by `GatedRecorder` (emits only gated
|
||||
rows + the genuine final row) and `SeriesReducer` (folds one column, emits one
|
||||
summary row), aura-std siblings of the per-cycle `Recorder`, which survives for the
|
||||
live / `--trace` / test-tap path. The recording sink's *own* per-cycle allocation
|
||||
(the `Recorder`→`Probe` rename + its accumulate-vs-stream choice, #77) stays open;
|
||||
`finalize` is the "non-channel exit from the graph" that issue's
|
||||
accumulate-then-read option named as missing.
|
||||
|
||||
**Refinement (Construction-layer milestone — render labels, 2026-06-05).** A node
|
||||
additionally exposes `label() -> String`, a **single-line, non-load-bearing**
|
||||
render symbol: a default trait method the run loop never calls (wiring is by
|
||||
|
||||
Reference in New Issue
Block a user