Orientation · Volume 03
Volume 03 — The Wave Log: Envelope, Ordering, Persistence
CURRENTsnapshot of 14 July 20265 min read← Volume 02 — Machine Model and the Architectural Register FileVolume 04 — Tuple Reference →
Reading aids · CoAgnes LabNot part of the specification; where they differ, the volume governs.
At a glance
- The envelope: every entry of the log is a wave tuple —
offset,kind,key,payload— treated as immutable once committed, its offset assigned by the engine alone; the current machine dispatches exactly four kinds. §1§2 - Ordering and correlation: the log is totally ordered by
offset, but causality is carried in payloads — correlation identities,triggeredBy,emittedBy— and consumers MUST rely on happens-before edges, never on adjacency. §3§4 - Keys, the attribution lanes: the
keyfield partitions winding — one clew per key — without partitioning the log; topology registrations usekey: null, lane-less and machine-wide. §5 - The persisted wire format: a UTF-8 JSON-Lines file, one tuple per line in offset order, offsets dense from 0; replay is reading, and feeding a log back into a live engine as continuation is not part of this specification. §6
- Quiescence and growth: the machine's global states — quiescent, settled, settled unfinished — and the log's known pressure points, fixed so that no implementer designs against a hidden assumption. §7§8
Where it sits
- Read after
- Volume 01 — OverviewVolume 02 — Machine Model and the Architectural Register File
- Read next
- Volume 04 — Tuple Reference
- Requirements
- 15 sentences with MUST, SHOULD or MAY — the list
- At work
- 5 of its sections seen in a real run of the machine, each linked under its heading
- Across the set
- every volume's questionsthe machine in figures
Questions this volume answers
- Who assigns a tuple's offset, and can it ever change? §1
- Can a new protocol add an envelope kind? §2
- Must an answer stand next to its cause on the log? §3
- How does an answer find the intention it answers? §4
- What does a key partition — the log, or the winding? §5
- Can a persisted log be fed back into a live engine? §6
- What is the difference between quiescent and settled? §7
- What makes the log grow, and where is retention handled? §8
The wave logWave logThe ordered, append-only history of committed wave tuples. The single source of truth; entries are never rewritten, only appended. aka append-log. (Vol. 03)Volume 15 — Terminology is the machine's memory, instruction stream, and audit trail at once. This volume specifies the tupleWave tupleAn immutable record in the wave log: offset, kind, key, payload. The unit of fact. aka tuple. (Vol. 03 §1)Volume 15 — Terminology envelope, the ordering guarantees, the attributionAttribution, reachability, terminationThe three load-bearing obligations of the decoupled model. (Vol. 01 §7)Volume 15 — Terminology lanes, the correlation discipline, and the persisted wire format. Compatibility between differing Nest implementations is defined first of all at this surface.
§1. The envelope
Seen at work Fragment 1 · Record #0 enters the log
Every entry of the log is a wave tupleWave tupleAn immutable record in the wave log: offset, kind, key, payload. The unit of fact. aka tuple. (Vol. 03 §1)Volume 15 — Terminology:
| Field | Type | Semantics |
|---|---|---|
offset | non-negative integer | The tuple's position in the log, assigned by the engine at append. Dense: the first tuple has offset 0 and each append increments by exactly 1. Never reused, never rewritten. |
kind | string | The envelope kind, selecting the payload contract. The current closed set is in §2. |
key | string or null | The attribution lane (§5). null for lane-less records (topology registrations). |
payload | kind-specific record | Immutable content. For domain.fact, an open {factType, data} shape (Vol. 04). |
An emissionEmissionA wave tuple without its offset — the form in which content is handed to the engine; the engine assigns the offset at append. (Vol. 03 §1)Volume 15 — Terminology is a tuple without offset — the form in which processors, controllersOutput controllerA receiver of committed tuples facing outward: it claims tuples by kind/fact type and discharges them to the external world exactly once per runtime. It neither judges nor integrates — a third station beside the activation knot and the bind descriptor, standing outside the propagation cycle on its own cursor. aka effector, egress handler. (Vol. 07 §2–3)Volume 15 — Terminology, and shells hand content to the engine. Rules:
- Emissions MUST NOT contain offsets; the engine alone assigns them.
- A committed tuple and everything reachable from its payload MUST be treated as immutable. Implementations SHOULD enforce this (deep-freeze, persistent structures, or discipline plus tests).
- Payloads MUST be JSON-representable values: no functions, no cycles, no non-finite numbers, no
undefinedinside records. (This is what makes §6 and the digest rules of Vol. 12 §7 possible.)
§2. Envelope kinds
Seen at work Fragment 1 · #0 · a listener is described
The current machine dispatches exactly four kinds:
| Kind | Committed by | Payload | Reference |
|---|---|---|---|
sys.knot.defined | loader, or a delegated emit template | {id, strategy, config, emittedBy?} | Vol. 04 §2.1 |
sys.descriptor.defined | loader, or a delegated emit template | {id, subscribesTo?, actionConfig?, operator?, emittedBy?} | Vol. 04 §2.2 |
sys.knot.ready | topology (readiness reification) | {knotId, understanding} | Vol. 04 §2.3 |
domain.fact | inputs, knots, binds, controllers, shells | {factType, data} — the open fact shape carrying every protocol of Vol. 04 §3–5 | Vol. 04 §3 |
The kind set is part of the invariant core's stability surface: adding a kind is a core widening under the discipline of Vol. 11 §2. Protocol growth happens inside domain.fact via factType namespaces instead (this is how the proposed Cell lifecycle stays on existing rails, Vol. 12 §5).
§3. Ordering and happens-before
Seen at work Fragment 2 · The world answers
- The log is totally ordered by
offset; every processor and every membraneMembraneThe boundary where the wave meets the world: output controllers face outward, ingress faces inward. (Vol. 07)Volume 15 — Terminology sweep observes tuplesWave tupleAn immutable record in the wave log:offset,kind,key,payload. The unit of fact. aka tuple. (Vol. 03 §1)Volume 15 — Terminology in exactly this order. - EmissionsEmissionA wave tuple without its
offset— the form in which content is handed to the engine; the engine assigns the offset at append. (Vol. 03 §1)Volume 15 — Terminology returned by oneapplycall are appended as a contiguous batch in returned order (Vol. 02 §7). - Asynchronous dischargesDischargeThe asynchronous execution of an external effect for one claimed tuple, resolving with the world's answers as emissions. (Vol. 07 §2)Volume 15 — Terminology re-enter as seeds of a later engine run; between two causally ordered tuples, unrelated tuples MAY therefore appear. Consumers MUST rely on happens-before edges, never on adjacency. (The Cell extension states its lifecycle partial order in exactly these terms, Vol. 12 §5.6.)
- Causality is carried in payloads — correlation identitiesCorrelation identityThe uid joining an intention with its answers (
<ownerId>#<n>), plus theemittedByprovenance stamp on sown emissions. (Vol. 03 §4)Volume 15 — Terminology (§4),triggeredBy,emittedBy— not in envelope fields.
§4. Correlation identities
Seen at work Fragment 1 · #4 · the note is released
Interaction with the world is asynchronous; the log keeps cause and answer joined through correlation identitiesCorrelation identityThe uid joining an intention with its answers (<ownerId>#<n>), plus the emittedBy provenance stamp on sown emissions. (Vol. 03 §4)Volume 15 — Terminology in payloads:
| Identity | Format | Minted by | Joins |
|---|---|---|---|
| winding uid | <knotId>#<n>, n from WIND.CTR | semantic knot | inference.request ↔ inference.response / inference.reasoning / inference.failed |
| service uid | <bindId>#<n>, n from INTENT.CTR | operator bind | service.request ↔ delegated publication / service.reasoning / service.failed |
| provenance stamp | emittedBy: <service uid> | delegated emit instantiation | sown records and head facts ↔ the sowing intention |
Rules:
- A uid MUST uniquely identify its intention among the owner's unanswered intentions; serviceServiceThe function evaluated over the bound scope to produce the integration. Its kind (model instruction, deterministic function, other) is an assembly property. aka service function. (Vol. 06 §3, Vol. 08 §5)Volume 15 — Terminology uids are unique per machine instance, windingWindThe act of integrating a matched tuple into the knot's wound state. Deterministic winding completes locally; semantic winding unfolds through the world — the knot projects a winding intention and later winds the returned integration. (Vol. 05 §1, §5)Volume 15 — Terminology uids per accumulation episode of the clewClewOne per-key executor instance of a registered knot definition; parallel keys wind independent clews. (Vol. 05 §2)Volume 15 — Terminology (exact semantics: Vol. 02 §4.7).
- An answer MUST carry the uid of its intention verbatim; a knotActivation knotAn accumulating unit that matches wave tuples, winds them, and tests readiness; it accumulates understanding. When ready, it activates bind descriptors. Its minimal form is a single condition matcher — a degenerate configuration of the same accumulator, not a different kind. aka knot, clew (for the per-key instance see clew). (Vol. 05)Volume 15 — Terminology MUST ignore correlated answers whose uid does not match its in-flight register.
- The
emittedBystamp makes the sowing thread explicit on the log rather than recoverable by adjacency; the topologyTopologyThe live set of registered activation knots and bind descriptors that the wave flows through. (Vol. 02 §5)Volume 15 — Terminology itself ignores the stamp. - Extensions defining new intention protocols MUST follow the same shape: mint at projection, echo in every answer, one terminal answer per intention (cf. the consumed-correlation rules of Vol. 12 §5).
§5. Keys: attribution lanes
Seen at work Fragment 1 · #0 · a listener is described
The key field partitions windingWindThe act of integrating a matched tuple into the knot's wound state. Deterministic winding completes locally; semantic winding unfolds through the world — the knot projects a winding intention and later winds the returned integration. (Vol. 05 §1, §5)Volume 15 — Terminology without partitioning the log:
- Every registered knotActivation knotAn accumulating unit that matches wave tuples, winds them, and tests readiness; it accumulates understanding. When ready, it activates bind descriptors. Its minimal form is a single condition matcher — a degenerate configuration of the same accumulator, not a different kind. aka knot, clew (for the per-key instance see clew). (Vol. 05)Volume 15 — Terminology winds one clewClewOne per-key executor instance of a registered knot definition; parallel keys wind independent clews. (Vol. 05 §2)Volume 15 — Terminology per key (Vol. 02 §4.2); facts on parallel keys accumulate independent understanding.
- A readinessReadinessThe state an activation knot reaches when its accumulated understanding satisfies its test; readiness is what activates bind descriptors. Readiness is reified: the topology commits it as a tuple carrying the understanding snapshot. (Vol. 02 §5, Vol. 04 §2.3)Volume 15 — Terminology tupleWave tupleAn immutable record in the wave log:
offset,kind,key,payload. The unit of fact. aka tuple. (Vol. 03 §1)Volume 15 — Terminology carries the key of the fact that completed the clew; an operator bindOperator bindThe full bind form: activation + demands + gates + a service crossing the membrane. (Vol. 06 §3)Volume 15 — Terminology maintains one rendezvousRendezvousOne key lane's gathering state of an operator bind: activation flag, scope, one-shot projection latch. (Vol. 02 §4.5, Vol. 06 §4)Volume 15 — Terminology per key (Vol. 06 §4). - Winding and service intentionsService intentionThe machine-complete
service.requestan operator bind projects: instruction, scope, schema, emit declaration. (Vol. 04 §5.1)Volume 15 — Terminology are projected on the key of their cause, and controllersOutput controllerA receiver of committed tuples facing outward: it claims tuples by kind/fact type and discharges them to the external world exactly once per runtime. It neither judges nor integrates — a third station beside the activation knot and the bind descriptor, standing outside the propagation cycle on its own cursor. aka effector, egress handler. (Vol. 07 §2–3)Volume 15 — Terminology MUST answer on the same key. - TopologyTopologyThe live set of registered activation knots and bind descriptors that the wave flows through. (Vol. 02 §5)Volume 15 — Terminology registrations use
key: null; they are lane-less and machine-wide. - A shell chooses keys at ingressIngressThe inward half of the membrane: the edge through which external events — the world's answers among them — are committed to the wave log as fact tuples. (Vol. 07 §6)Volume 15 — Terminology (a session id, a case id). Keys are opaque to the machine; no format is imposed.
Branches and ledgers (DECLARED). The authoring format reserves named lanes of a richer kind — branches (planes of breadth) and ledgers (levels of depth) with declared isolation. They are parsed, validated, and rejected if used beyond main (Vol. 09 §4); the runtime does not yet enforce them. AttributionAttribution, reachability, terminationThe three load-bearing obligations of the decoupled model. (Vol. 01 §7)Volume 15 — Terminology today is carried by keys, uids, and stamps alone — which bounds the machine to figures whose lanes those can express (Vol. 11 §4.3).
§6. Persisted wire format (JSONL)
A persisted run is a UTF-8 JSON-Lines file: exactly one tupleWave tupleAn immutable record in the wave log: offset, kind, key, payload. The unit of fact. aka tuple. (Vol. 03 §1)Volume 15 — Terminology per line, in offset order, each line a JSON object with the four envelope fields. The reference serialisation writes fields in the order kind, key, payload, offset; consumers MUST NOT depend on field order, only on names.
{"kind":"sys.knot.defined","key":null,"payload":{"id":"intent.understanding","strategy":"semantic_evaluator","config":{"wind":{"collect":[{"as":"user_messages","match_type":"chat.message.received","reduce":"append","field":"message"}]},"condition":{"evaluate_understanding":true,"questions":["…","…"],"threshold_grade":0.8}}},"offset":0}
{"kind":"sys.descriptor.defined","key":null,"payload":{"id":"action.notify.business.analyst","subscribesTo":"intent.understanding","actionConfig":{"writes":"intent.understanding.ready"}},"offset":1}
{"kind":"domain.fact","key":"nest-1","payload":{"factType":"chat.message.received","data":{"message":"…"}},"offset":2}
{"kind":"sys.knot.ready","key":"nest-1","payload":{"knotId":"intent.understanding","understanding":{"state":"…","grade":0.9}},"offset":3}
{"kind":"domain.fact","key":"nest-1","payload":{"factType":"intent.understanding.ready","data":{"triggeredBy":["intent.understanding"],"understanding":{"state":"…","grade":0.9}}},"offset":4}Rules:
- The JSONL line format MUST be identical across shells of one implementation (the reference CLI log tail and the Nest Studio run store are line-identical by test; refimpl 08 §1, §2.3).
- Offsets in a persisted log MUST be dense from 0; a reader MAY verify and MUST NOT renumber.
- A run metadata sidecar MAY accompany the log; the reference shape is
{id, pipelineRef, pipelineId, key, startedAt, finishedAt?, status: 'running'|'settled'|'defect', defect?, tuples, failures, unanswered}. Sidecars are derived convenience, never a second truth:failurescounts committed*.failedfacts;unansweredcounts intentions without a correlated answer on the log. - Replay is reading: feeding a persisted log to derivations (digests, UI) MUST reproduce their outputs. Feeding it back into a live engine as continuation is NOT part of this specification (open decision, Vol. 11 §6).
§7. Quiescence and the two cursors
Two independent cursors read the one log (Vol. 02 §4): the engine's propagation cursor and the membraneMembraneThe boundary where the wave meets the world: output controllers face outward, ingress faces inward. (Vol. 07)Volume 15 — Terminology's sweep cursor. From them the machine's global states are defined:
- QuiescentQuiescentThe engine cursor has consumed the whole log and produced nothing further. (Vol. 03 §7)Volume 15 — Terminology:
ENGINE.CURSOR = |LOG|— propagation has consumed every committed tupleWave tupleAn immutable record in the wave log:offset,kind,key,payload. The unit of fact. aka tuple. (Vol. 03 §1)Volume 15 — Terminology and produced nothing further. - SettledSettledQuiescent with no discharge in flight. (Vol. 03 §7)Volume 15 — Terminology: quiescent and
DISCHARGE.TABLEempty — additionally no external answer is pending. The settleSettleThe runtime algorithm alternating propagation with membrane discharges until the machine settles. (Vol. 08 §3)Volume 15 — Terminology algorithm (Vol. 08 §3) returns only here. - Settled unfinishedSettled unfinishedSettled while a derivation shows an open path — unanswered intentions, a stalled clew, an open rendezvous. An honest terminal state, never masked. (Vol. 08 §7)Volume 15 — Terminology: settled, while a derivation of the log shows an open path — a stalled clewClewOne per-key executor instance of a registered knot definition; parallel keys wind independent clews. (Vol. 05 §2)Volume 15 — Terminology (budget exhausted below threshold), an unanswered intention, an operator bindOperator bindThe full bind form: activation + demands + gates + a service crossing the membrane. (Vol. 06 §3)Volume 15 — Terminology with an incomplete rendezvousRendezvousOne key lane's gathering state of an operator bind: activation flag, scope, one-shot projection latch. (Vol. 02 §4.5, Vol. 06 §4)Volume 15 — Terminology. This is a visible, honest terminal state, not an error (Vol. 08 §7).
§8. Growth characteristics
Append-only history trades space for truth. Current known pressure points, fixed here so no implementer designs against a hidden assumption:
- repeated readinessReadinessThe state an activation knot reaches when its accumulated understanding satisfies its test; readiness is what activates bind descriptors. Readiness is reified: the topology commits it as a tuple carrying the understanding snapshot. (Vol. 02 §5, Vol. 04 §2.3)Volume 15 — Terminology under
reset: nevermultiplies snapshots; shells fold them at read time («×N» folding in the trace digest) until edge-triggered readiness and understanding-by-reference land (recorded future work, Vol. 11 §5); - embedded schemas and packages enlarge records in exchange for self-contained replay — deliberate;
- retention, archival, and content-addressed externalisation of large bodies are extension-level concerns (Vol. 12 §10, Vol. 13 §4); the log proper carries bounded content and immutable references.
Reading aids · CoAgnes LabNot part of the specification; where they differ, the volume governs.
Requirements in this volume
Every sentence of the volume with MUST, SHOULD or MAY, as it stands, with the section it stands in. These key words mark its conformance requirements; the rest of its text is descriptive (Vol. 00 §4).
- MUST NOTEmissions MUST NOT contain offsets; the engine alone assigns them.§1
- MUSTA committed tuple and everything reachable from its payload MUST be treated as immutable.§1
- SHOULDImplementations SHOULD enforce this (deep-freeze, persistent structures, or discipline plus tests).§1
- MUSTPayloads MUST be JSON-representable values: no functions, no cycles, no non-finite numbers, no
undefinedinside records.§1 - MAYAsynchronous discharges re-enter as seeds of a later engine run; between two causally ordered tuples, unrelated tuples MAY therefore appear.§3
- MUSTConsumers MUST rely on happens-before edges, never on adjacency. (The Cell extension states its lifecycle partial order in exactly these terms, Vol. 12 §5.6.)§3
- MUSTA uid MUST uniquely identify its intention among the owner's unanswered intentions; service uids are unique per machine instance, winding uids per accumulation episode of the clew (exact semantics: Vol. 02 §4.7).§4
- MUSTAn answer MUST carry the uid of its intention verbatim; a knot MUST ignore correlated answers whose uid does not match its in-flight register.§4
- MUSTExtensions defining new intention protocols MUST follow the same shape: mint at projection, echo in every answer, one terminal answer per intention (cf. the consumed-correlation rules of Vol. 12 §5).§4
- MUSTWinding and service intentions are projected on the key of their cause, and controllers MUST answer on the same key.§5
- MUST NOTThe reference serialisation writes fields in the order
kind,key,payload,offset; consumers MUST NOT depend on field order, only on names.§6 - MUSTThe JSONL line format MUST be identical across shells of one implementation (the reference CLI log tail and the Nest Studio run store are line-identical by test; refimpl 08 §1, §2.3).§6
- MUSTMAYMUST NOTOffsets in a persisted log MUST be dense from 0; a reader MAY verify and MUST NOT renumber.§6
- MAYA run metadata sidecar MAY accompany the log; the reference shape is
{id, pipelineRef, pipelineId, key, startedAt, finishedAt?, status: 'running'|'settled'|'defect', defect?, tuples, failures, unanswered}.§6 - MUSTReplay is reading: feeding a persisted log to derivations (digests, UI) MUST reproduce their outputs.§6