diff --git a/docs/design/contracts/c27-declared-taps.md b/docs/design/contracts/c27-declared-taps.md index dee625f..e3c34ec 100644 --- a/docs/design/contracts/c27-declared-taps.md +++ b/docs/design/contracts/c27-declared-taps.md @@ -84,11 +84,11 @@ consumer (`aura-runner::tap_recorder::TapRecorder`) holds the trace store's streaming writer in-graph — `initialize` opens (deferred acquisition), `eval` appends `(Timestamp, Cell)` (zero per-cycle heap, #77), `finalize` reports exactly one terminal outcome; fold consumers (`aura-std::TapFold`) land one -summary row, stamped with the source value's own timestamp for `first`/`last` -(they pin a single source instant) and with the finalize timestamp for the -accumulator folds (`count`/`sum`/`mean`/`min`/`max` summarise a range and have -no single source instant; `min`/`max` deliberately do not carry the extremum's -timestamp — ratified as-is, #335); live closures run inline +summary row, emitted at finalize and stamped with the instant of the last +contributing (warm) value — `first` alone pins the first contributing +instant; `min`/`max` deliberately do not carry the extremum's timestamp (a +whole-window row privileges no interior instant) — ratified as-is, #335; +live closures run inline (`aura-std::TapLive`). The sweep/reduce path never calls `bind_tap`. diff --git a/docs/glossary.md b/docs/glossary.md index 686729c..a095317 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -327,7 +327,7 @@ A named recorded stream produced by a recording `sink` — the addressable label Since C27 (#282) the word also names a second, author-facing sense: a **declared tap** — a `Composite.taps` entry `Tap { name, from: {node, field} }` a hand-authored blueprint declares on an interior output wire, the output-side twin of an `input_role`. It is a pure declaration (no channel endpoint); the harness binds it run-mode-aware (a single `aura run` constructs a recorder at each and persists the series through the trace store; a sweep leaves it unbound and inert). This is an OPEN, per-blueprint author-declared name — distinct from the CLOSED campaign `persist_taps` vocabulary above, which selects among fixed observables of the standard R-harness. Both senses land as `ColumnarTrace`s in the same trace store; the closed vocabulary is what a `campaign document` selects, the declared tap is what a blueprint author names. -Since #283 what CONSUMES a declared tap is itself declared per run by a **tap plan**: a subscription is either `Named { label, params }` — resolved against a layered **fold registry** whose core vocabulary is `record | count | sum | mean | min | max | first | last`, each entry carrying a doc line (the help surface and the roster-enumerating refusal) and a scalar-typed param schema (all core entries param-less; growth is a new Rust entry per C25, and higher layers register entries without touching the core) — or `Live(closure)`, the single non-data variant (an in-process consumer with consumer-owned loss policy). `record` streams the full series to the trace store at constant memory (no buffer-then-drain); folds keep an O(1) accumulator and land one summary row at finalize. Both declared-tap entry points are arms of the single verb `aura run` (`aura measure` is the post-hoc IC analysis over already-persisted traces and constructs no tap plan); `aura run` subscribes every declared tap to `record` by default, and its repeatable `--tap TAP=FOLD` selector (#310) replaces that default with an explicit plan — only listed taps are bound, unlisted taps stay unbound/inert. A fold's one summary row is stamped with the source value's own timestamp for `first`/`last` (they pin a single source instant) and with the finalize timestamp for the accumulator folds (`count | sum | mean | min | max` summarise a range; `min`/`max` deliberately do not carry the extremum's instant — ratified #335). +Since #283 what CONSUMES a declared tap is itself declared per run by a **tap plan**: a subscription is either `Named { label, params }` — resolved against a layered **fold registry** whose core vocabulary is `record | count | sum | mean | min | max | first | last`, each entry carrying a doc line (the help surface and the roster-enumerating refusal) and a scalar-typed param schema (all core entries param-less; growth is a new Rust entry per C25, and higher layers register entries without touching the core) — or `Live(closure)`, the single non-data variant (an in-process consumer with consumer-owned loss policy). `record` streams the full series to the trace store at constant memory (no buffer-then-drain); folds keep an O(1) accumulator and land one summary row at finalize. Both declared-tap entry points are arms of the single verb `aura run` (`aura measure` is the post-hoc IC analysis over already-persisted traces and constructs no tap plan); `aura run` subscribes every declared tap to `record` by default, and its repeatable `--tap TAP=FOLD` selector (#310) replaces that default with an explicit plan — only listed taps are bound, unlisted taps stay unbound/inert. A fold's one summary row is emitted at finalize and stamped with the instant of the last contributing (warm) value — `first` alone pins the first contributing instant, and `min`/`max` deliberately do not carry the extremum's instant (ratified #335). ### topology hash **Avoid:** —