@plurnk/plurnk-service 1.19.3 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/.env.defaults +6 -5
  2. package/SPEC.md +177 -111
  3. package/dist/build-info.json +1 -1
  4. package/dist/core/AdmittedTurnExecutor.d.ts +2 -2
  5. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  6. package/dist/core/AdmittedTurnExecutor.js +12 -16
  7. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  8. package/dist/core/BareBatchRunner.d.ts +5 -1
  9. package/dist/core/BareBatchRunner.d.ts.map +1 -1
  10. package/dist/core/BareBatchRunner.js +86 -50
  11. package/dist/core/BareBatchRunner.js.map +1 -1
  12. package/dist/core/Dispatcher.d.ts +2 -2
  13. package/dist/core/Dispatcher.d.ts.map +1 -1
  14. package/dist/core/Dispatcher.js +23 -57
  15. package/dist/core/Dispatcher.js.map +1 -1
  16. package/dist/core/Dispatcher.sql +7 -0
  17. package/dist/core/LogBody.js +2 -2
  18. package/dist/core/LogBody.js.map +1 -1
  19. package/dist/core/LogEntryProjection.d.ts.map +1 -1
  20. package/dist/core/LogEntryProjection.js +0 -4
  21. package/dist/core/LogEntryProjection.js.map +1 -1
  22. package/dist/core/LoopDriver.d.ts.map +1 -1
  23. package/dist/core/LoopDriver.js +17 -4
  24. package/dist/core/LoopDriver.js.map +1 -1
  25. package/dist/core/PacketBuilder.d.ts.map +1 -1
  26. package/dist/core/PacketBuilder.js +3 -2
  27. package/dist/core/PacketBuilder.js.map +1 -1
  28. package/dist/core/PacketBuilder.sql +5 -0
  29. package/dist/core/ProviderRecovery.d.ts +9 -0
  30. package/dist/core/ProviderRecovery.d.ts.map +1 -0
  31. package/dist/core/ProviderRecovery.js +22 -0
  32. package/dist/core/ProviderRecovery.js.map +1 -0
  33. package/dist/core/ServiceTeardown.d.ts +1 -1
  34. package/dist/core/ServiceTeardown.d.ts.map +1 -1
  35. package/dist/core/ServiceTeardown.js +4 -2
  36. package/dist/core/ServiceTeardown.js.map +1 -1
  37. package/dist/core/StrikeRail.d.ts +3 -0
  38. package/dist/core/StrikeRail.d.ts.map +1 -1
  39. package/dist/core/StrikeRail.js +16 -1
  40. package/dist/core/StrikeRail.js.map +1 -1
  41. package/dist/core/TurnDispositionHandler.d.ts +3 -2
  42. package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
  43. package/dist/core/TurnDispositionHandler.js +48 -15
  44. package/dist/core/TurnDispositionHandler.js.map +1 -1
  45. package/dist/core/TurnMaterialization.d.ts.map +1 -1
  46. package/dist/core/TurnMaterialization.js +7 -1
  47. package/dist/core/TurnMaterialization.js.map +1 -1
  48. package/dist/core/TurnOps.d.ts.map +1 -1
  49. package/dist/core/TurnOps.js +4 -0
  50. package/dist/core/TurnOps.js.map +1 -1
  51. package/dist/core/TurnRunner.d.ts +0 -4
  52. package/dist/core/TurnRunner.d.ts.map +1 -1
  53. package/dist/core/TurnRunner.js +32 -100
  54. package/dist/core/TurnRunner.js.map +1 -1
  55. package/dist/core/TurnSources.sql +1 -1
  56. package/dist/core/ambient.sql +2 -2
  57. package/dist/core/packet-wire.d.ts.map +1 -1
  58. package/dist/core/packet-wire.js +67 -47
  59. package/dist/core/packet-wire.js.map +1 -1
  60. package/dist/core/results.d.ts +1 -0
  61. package/dist/core/results.d.ts.map +1 -1
  62. package/dist/core/results.js +7 -0
  63. package/dist/core/results.js.map +1 -1
  64. package/dist/core/turn-scheduler.js +1 -1
  65. package/dist/core/turn-scheduler.js.map +1 -1
  66. package/dist/core/unconcluded-emission.d.ts +7 -0
  67. package/dist/core/unconcluded-emission.d.ts.map +1 -0
  68. package/dist/core/unconcluded-emission.js +11 -0
  69. package/dist/core/unconcluded-emission.js.map +1 -0
  70. package/dist/core/unconcluded-emission.sql +14 -0
  71. package/dist/schemes/Log.d.ts.map +1 -1
  72. package/dist/schemes/Log.js +1 -0
  73. package/dist/schemes/Log.js.map +1 -1
  74. package/dist/server/Retention.d.ts.map +1 -1
  75. package/dist/server/Retention.js +2 -0
  76. package/dist/server/Retention.js.map +1 -1
  77. package/dist/server/Retention.sql +5 -0
  78. package/dist/server/logEntry.sql +2 -2
  79. package/dist/service.d.ts.map +1 -1
  80. package/dist/service.js +4 -1
  81. package/dist/service.js.map +1 -1
  82. package/migrations/006_log.sql +10 -4
  83. package/package.json +161 -163
package/SPEC.md CHANGED
@@ -527,8 +527,9 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
527
527
  parent as an `_plurnk` READ of `ops://<name>/<sequence>` ({§loop-answer}), not a message,
528
528
  and that row carries what the child said.
529
529
  The occurrence retains that loop's exact terminal result; the READ uses ordinary
530
- bounded projection. Its body, when present, is initially visible. Replies are
531
- independent deliveries ({§message-reply-delivery}), never copied into this outcome. Failures and
530
+ bounded projection of {§loop-answer}. The original delegated answer reaches the
531
+ parent here, not as a duplicate reply ({§message-reply-delivery}); other message
532
+ replies remain independent deliveries. Failures and
532
533
  cancellations retain their exact status, Problem, and visible explanation,
533
534
  including a spawn that fails before its first turn. Observation and wake-up
534
535
  follow {§env-delta-child-termination}; a later child loop cannot replace the
@@ -1023,7 +1024,7 @@ boundary.
1023
1024
  - §worker-lifecycle-wake-liveness **A stream conclusion always reaches its worker.** The stream first persists its terminal state. A worker **blocked on a 202 wait** for that stream ({§wait-obligation-matrix}) then **awakens that loop in place** — the blocked loop *is* the continuation, so there is no fresh loop and no summary-as-prompt fiction. An already-active worker needs no injected prompt or second wake because its next packet reads the durable terminal state. A concluded worker receives no synthetic loop from ambient stream closure. The result remains available in the stream's own state under every case.
1024
1025
  - §worker-lifecycle-child-wake **Each child task completion notifies its parent.** Terminal-task publication, including failure and cancellation of a parked task, notifies the direct parent without injecting a prompt. Other unfinished tasks or streams in that child remain independent obligations; they cannot suppress notification. The parent's eligible waits requeue in place under {§loop-wake-identity} and the bounded {§worker-optimistic-settlement} opportunity. Durable revisioning covers completion-before-park and restart; drain teardown and whole-worker quiescence are not completion identities.
1025
1026
  - §worker-optimistic-settlement **Asynchronous settlement receives one bounded worker-local opportunity before model dispatch.** An initiating turn lets only the streams it started settle before program completion; separately, a stream conclusion, direct-child conclusion or addressed reply persists and publishes immediately but holds eligible parked loops' `202→100` requeues while another stream or direct child remains live. Both use `PLURNK_SERVICE_OPTIMISTIC_WAIT_MS`, shipped at five seconds; zero disables the opportunity. The wake hold ends as soon as no sibling obligation remains, never extends its original deadline, and coalesces arrivals within that window into at most one requeue per eligible loop. With no sibling obligation the wake is immediate; at the deadline, surviving work follows the ordinary monitored lifecycle. An arrival after provider dispatch begins retains its next wake, while poll, new-request and operator wakes never open this hold. Only packet/provider dispatch waits: durable state, client events, cancellation and the replying program do not. One redaction-safe span records elapsed time, quiescence versus deadline, and arrival count without entering the packet.
1026
- - §worker-lifecycle-idle-is-concluded **Idle is not unanswered.** An empty WAIT continues; an answered, observed program without held work concludes under {§wait-obligation-matrix}. A concluded worker retains durable history; a later addressed arrival starts a new loop.
1027
+ - §worker-lifecycle-idle-is-concluded **Idle is not unanswered.** An empty WAIT continues; an eligible final response with answered messages, observed results and no held work concludes under {§wait-obligation-matrix}. A concluded worker retains durable history; a later addressed arrival starts a new loop.
1027
1028
  - §worker-lifecycle-no-lost-loop **A loop is never stranded by a drain's exit.** A drain relinquishes its registry slot only after a lock-held re-claim confirms the queue is empty; a loop enqueued during that teardown is either re-claimed by the exiting drain or claimed by a fresh drain that a later inject starts. The relinquish and the start are serialized, so neither the lost-loop hang nor a transient double-drain can occur.
1028
1029
  - §worker-lifecycle-durable-disposition **Durable disposition wins cancellation races.** At a turn boundary, the engine reads the loop's durable status before interpreting a process-local abort. A committed `202` park survives a later daemon-shutdown signal; only a loop still durably running at `102` can be terminalized by that cancellation. Wake selection rechecks shutdown and worker cancellation before requeuing each parked loop.
1029
1030
  - §worker-lifecycle-restart-recovery **Restart is owner-loss reconciliation, not replay.** Before opening client transports, the service holds an exclusive database-adjacent daemon lock; a second live owner fails before touching SQLite, while a dead-PID crash claim is replaced atomically without a timeout lease. Boot preserves accepted `100` loops and restores their drains. A `102` loop belonged to a vanished drain/provider call, so it settles `500` with the interruption on its durable row—never replayed across an unknown effect boundary. Every pending physical provider request first settles as an error with absent usage and explicitly unknown cost; then its logical model call closes. Recovery never fabricates zero evidence. Every durable proposed operation likewise lost its process-local resolution waiter and settles as a visible `500 owner_vanished` occurrence rather than an unresolvable interrupt ({§proposal-list}). A pending client interaction also lost its exact awaiting operation, so boot removes the orphan instead of replaying work or inventing a response ({§client-interactions}). Every durable-open subscription belonged to a vanished callable: active channels become errored and its row closes `500`. A `202` continuation requeues on an unseen completion or when no live obligation remains. Otherwise it stays parked on surviving children; the drain restores inherited stream observation through the same guarded scheduler ({§worker-wait-timing}). Child terminalization wakes its parked parent on every outcome, including provider exceptions, cancellation, and restart interruption, recursively through the durable parent edges. These operations are idempotent, so an interrupted recovery safely repeats.
@@ -1100,11 +1101,18 @@ are excluded from results; the complete note body still distinguishes activity.
1100
1101
  irrelevant; operation and array order are preserved. Only the configured
1101
1102
  `MIN_CYCLES × MAX_CYCLE_PERIOD` history window is retained. Repeated addresses
1102
1103
  alone are not a cycle: changing inputs or observations distinguish activity.
1104
+ A turn that executed nothing has no activity to identify, so an empty turn's
1105
+ identity is its **text** ({§empty-turn}) — the same principle, applied to the only
1106
+ output it produced. Identifying it by its absent program instead makes every empty
1107
+ turn identical, and changing words then read as a repeating one.
1103
1108
  This is an exact-repetition backstop, not a semantic judgment of task progress;
1104
1109
  new asynchronous invocation identities do not prove repetition of their eventual
1105
1110
  effects. Ordinary contract strikes and operator budgets remain independent.
1106
1111
 
1107
- §provider-recovery **A recoverable provider failure never ends a loop.** When a model
1112
+ §provider-recovery **A recoverable provider failure never ends a loop.** An isolated BARE
1113
+ call ({§bare-inference}) takes the same recovery as the loop's own inference: each re-issue
1114
+ is its own model call on the ledger, and a spent window leaves the operation's result as the
1115
+ provider's exact failure. When a model
1108
1116
  call fails with a network failure, rate limit, deadline, or interrupted resource after
1109
1117
  the provider's own retries, the turn records the exact Problem as a `_plurnk` row,
1110
1118
  notices the client (`engine:provider` / `provider_unavailable`), waits with
@@ -1137,7 +1145,7 @@ The contracts, and the violation of each that strikes:
1137
1145
  | Contract | Violation that strikes |
1138
1146
  |---|---|
1139
1147
  | operation contract | a hard operation failure (status ≥ 400) in an admitted turn — soft statuses below excluded |
1140
- | review contract | none: answered work joins live obligations ({§completion-joins-live-work}) or continues to observe results ({§completion-defers-to-results}) |
1148
+ | review contract | none: an eligible final response joins live obligations ({§completion-joins-live-work}) or continues to observe results ({§completion-defers-to-results}) |
1141
1149
  | progress contract | a detected operation cycle (`MIN_CYCLES` × period), or an admitted turn with no operation ({§empty-turn}) |
1142
1150
  | frame contract | emission attempts exhausted with no admissible turn |
1143
1151
  | provider response contract | the provider returned an invalid response |
@@ -1156,6 +1164,17 @@ independent turn ceiling terminates at **429** ({§loop-terminals}). The streak
1156
1164
  and cycle verdict are absent from model packets; only the concrete occurrences
1157
1165
  in the table are shown. The streak never leaves the daemon.
1158
1166
 
1167
+ A crossing terminal names the source that struck the crossing turn — `repetition`,
1168
+ `no_operation`, then `operation` — in its detail, in that order when a turn matches more
1169
+ than one. The three are not interchangeable: a turn that authored no operation did not *fail*
1170
+ one, and reporting it as a failed turn misreads a model answering without the fence as a model
1171
+ whose operations broke. This is the crossing turn's source, not the streak's composition; the
1172
+ rail rules on the crossing and does not retain the kinds behind it. What the crossing turn
1173
+ actually said is cited, not discarded ({§terminal-evidence}). Naming the source is not the
1174
+ private accounting {§rail-accounting-private} withholds: the streak, the cycle verdict and
1175
+ attempt counts stay inside the daemon — this is the terminal telling the truth about its own
1176
+ cause, which the reader already sees the shape of.
1177
+
1159
1178
  §loop-rail-continuity Rail state belongs to the durable loop, not its execution
1160
1179
  segment. The strike streak and bounded cycle history survive driver cleanup and
1161
1180
  restart; curation of log evidence cannot alter them.
@@ -1204,7 +1223,21 @@ Three current entry points:
1204
1223
 
1205
1224
  ### §emission-admission Provider emission admission
1206
1225
 
1207
- A completed provider exchange is an **emission attempt**, not necessarily an engine turn. **The harness admits every program whose meaning it can determine, runs what it admitted, and reports — never refuses — what it could not read**; a refusal is for undecidable text alone. ANTLR admits at least one parsed source operation. WAIT is optional under {§turn-shape}; omission invents no operation, diagnostic, warning or strike; any number of WAITs are one park, scheduled last ({§disposition-anywhere}), and statements after them remain admitted in authored order. Bounded operation errors retain useful siblings and participate in the ordinary struck turn. An unfinished heading slot ({§unparsed-tail-boundary}) refuses only what follows it: the statements that closed before it run, and the loss is one more hard diagnostic — a failed row with the lexer's own reason; an exchange that lost its boundary before any statement closed has nothing admissible and is rejected. A missing closer never rejects ({§closer-fallback}). An exchange with no operation and no other hard error is not rejected: it is admitted as an empty turn ({§empty-turn}). Parser warnings remain admissible. `finish=length` is evidence of likely truncation, not an independent rejection rule. Provider-declared interruption never reaches admission ({§provider-interrupted-attempt}). Accepted source bytes and statement positions remain exact in response evidence and `turnOps`. Execution follows {§op-execution-order}.
1226
+ A completed provider exchange is an **emission attempt**, not necessarily an engine turn.
1227
+ The parser owns its boundaries; core admits determinate work and exposes its failures.
1228
+
1229
+ | Parsed response | Admission |
1230
+ |---|---|
1231
+ | Bounded program, including malformed operations | Admit valid operations and record parser failures; with no authored operation, apply {§empty-turn}. |
1232
+ | Outside response text | Keep it as the model's NOTE under {§response-text-note}; never deliver it or infer completion. |
1233
+ | Lost boundary after a closed operation | Admit the closed operations and record the boundary diagnostic under {§unparsed-tail-boundary}. |
1234
+ | Lost boundary before any closed operation | Reject the attempt; neither outside text nor a reasoning NOTE substitutes for a closed response operation. |
1235
+
1236
+ Warnings and closer recovery ({§closer-fallback}) do not reject. `finish=length`
1237
+ discloses truncation and precludes completion; it is not independently a rejection.
1238
+ Provider interruption is owned by {§provider-interrupted-attempt}. Accepted source
1239
+ and positions remain exact; execution follows {§op-execution-order}. WAIT remains
1240
+ optional, with no omission warning or invented operation ({§turn-shape}).
1208
1241
 
1209
1242
  §safe-uri-target-groups After source and authored-command admission, Core tolerates one target group on READ or KILL only when splitting its raw target at top-level comma or whitespace separators produces at least two members and every member independently parses as an explicit `scheme://` URI. Request-metadata blocks are opaque to this split. Each member becomes one ordinary statement with an independent dispatch outcome and log row, in authored member order at that operation's position under {§op-execution-order}. Otherwise the target remains exactly singular, including local filenames containing spaces or commas. The stored `turnOps` and authored command count remain unexpanded, and no other operation admits target groups.
1210
1243
 
@@ -1481,7 +1514,7 @@ Registration precedes loop affinity:
1481
1514
  | Registered but inactive under flag | The flag gate returns `403 scheme-unavailable`. |
1482
1515
  | Registered and active | Dispatch continues to the operation owner. |
1483
1516
 
1484
- - §op-execution-order **An admitted turn is an ordered program.** Model, client, and harness operations execute in authored order. Only WAIT is deferred until all other admitted operations settle or establish their explicitly asynchronous work ({§disposition-anywhere}). The complete program then settles under {§wait-obligation-matrix}, whether or not it contains WAIT; no completion operation or inventory is invented. Existing cycle, no-operation, and resource rails remain effective. An observation records the resource state at its execution point; the model sees that receipt in the next packet. Exact submitted source and actual operation outcomes remain durable. Earlier successful effects survive a later operation failure; a producer requesting fail-on-error stops before subsequent operations.
1517
+ - §op-execution-order **An admitted turn is an ordered program.** Model, client, and harness operations execute in authored order. WAIT and parameterless KILL are deferred until all other admitted operations settle or establish their explicitly asynchronous work ({§disposition-anywhere}). The complete program then settles under {§wait-obligation-matrix}, whether or not it contains a lifecycle request; no completion operation or inventory is invented. Existing cycle, no-operation, and resource rails remain effective. An observation records the resource state at its execution point; the model sees that receipt in the next packet. Exact submitted source and actual operation outcomes remain durable. Earlier successful effects survive a later operation failure; a producer requesting fail-on-error stops before subsequent operations.
1485
1518
 
1486
1519
  §bare-inference **BARE is isolated, synchronous retrieval over the durable child-provider policy.**
1487
1520
 
@@ -2074,7 +2107,7 @@ streaming are independent. No later turn automatically requests reasoning.
2074
2107
 
2075
2108
  AST: `{ op: "KILL", target, matcher: MatcherBody | null, lineMarker: TextLineMarker | null, body: null }` ({§kill-scope} and {§matcher-option} in the contracts SPEC own the grammar).
2076
2109
 
2077
- KILL deletes context from the **log** (`log:///`, {§packet}). Without a scope it retires the selected rows from the active projection ({§log-history-projection}). With a one-line or inclusive two-line scope it removes only that body's intersecting body-relative physical lines from the readable projection, and the row stays active. An anchor may be one published on that body or one returned by READing its `log:///` coordinate ({§line-anchors}); an anchor absent from the current body selects no line, as with an out-of-bounds numeric line. Scoped KILL is one-way: intervals accumulate, the durable body is untouched, and subsequent access follows {§log-readable-projection}. A scoped KILL on a bodyless row is a friendly 200 no-op with `matched` reported. A KILL that addresses no row is 404 on an exact coordinate and 204 on a sweep ({§log-curation-folder-idiom}). Selection composes target/glob with an optional heading pattern ({§log-curation-set-selection}); a targetless KILL is 400.
2110
+ KILL deletes context from the **log** (`log:///`, {§packet}). Without a scope it retires the selected rows from the active projection ({§log-history-projection}). With a one-line or inclusive two-line scope it removes only that body's intersecting body-relative physical lines from the readable projection, and the row stays active. An anchor may be one published on that body or one returned by READing its `log:///` coordinate ({§line-anchors}); an anchor absent from the current body selects no line, as with an out-of-bounds numeric line. Scoped KILL is one-way: intervals accumulate, the durable body is untouched, and subsequent access follows {§log-readable-projection}. A scoped KILL on a bodyless row is a friendly 200 no-op with `matched` reported. A KILL that addresses no row is 404 on an exact coordinate and 204 on a sweep ({§log-curation-folder-idiom}). Selection composes target/glob with an optional heading pattern ({§log-curation-set-selection}). Parameterless KILL instead requests completion ({§kill-conclusion}).
2078
2111
 
2079
2112
  A READ carrying active native media is atomic: any KILL scope is ignored and the entire observation is retired, including its native context contribution ({§packet-attachment-parts}). For a model turn, native activity is the attachment selection in its actual input packet; without a model packet, a native observation is atomic by default. Text-only observations in the same selection retain ordinary scoped behavior. Neither form deletes source data or forensic evidence.
2080
2113
 
@@ -2105,21 +2138,29 @@ type and projection facts under {§read-bytes}.
2105
2138
  The `## Log` section is a sequence of ordinary Markdown records separated by one blank line:
2106
2139
 
2107
2140
  ```text
2108
- ### log:///<loop>/<turn>/<item>/<leaf>
2109
- {"oneLine":"strict JSON metadata"}
2141
+ ### log:///<loop>/<turn>/<item>/<leaf> · <logTokens>
2142
+ OP (operands) <marks> [metadata] <!-- aside -->
2143
+ {"oneLine":"strict JSON result facts"}
2110
2144
  <coordinate-prefixed body lines when visible>
2111
2145
  ```
2112
2146
 
2113
- The H3 is the row's complete model-facing identity and canonical READ address; metadata never repeats that identity or its operation. The following line is one strict JSON object: addressed operands ({§log-address-metadata}) precede `aside`, then all remaining members use stable alphabetical order. Absent fields are not invented. Every physical body line retains its canonical numeric `N:` or anchored `@hash N:` coordinate, so source text cannot create a record boundary. The section contains records only, with no leading prose or enclosing fence.
2147
+ | Line | Content | Rule |
2148
+ |---|---|---|
2149
+ | H3 | The row's complete model-facing identity and canonical READ address, then ` · ` and its `logTokens` charge ({§packet-token-accounting}). | Always present; nothing else repeats the identity, the operation, or the charge. |
2150
+ | written | The request as the language writes it ({§heading-slot-order}): the operation or runtime, every operand in the packet's canonical spelling ({§log-address-metadata}), marks, metadata blocks, matcher, aside. No fence, no body. | Present for every operation and execution row; absent on `error` and `extension` rows. |
2151
+ | facts | One strict JSON object of result facts in stable alphabetical order. | Present only when a fact exists; it never re-encodes the written line. |
2152
+ | body | Coordinate-prefixed lines. | Present when the row is visible. |
2153
+
2154
+ The written line is the model's own request, so a matcher such as `/\bhello\b/i` returns exactly as it was written, never JSON-quoted. Absent fields are not invented. Every physical body line retains its canonical numeric `N:` or anchored `@hash N:` coordinate, so source text cannot create a record boundary. The section contains records only, with no leading prose or enclosing fence.
2114
2155
 
2115
2156
  §log-address-metadata **Addresses name their relationship, not the row's producer.**
2116
2157
 
2117
- | Metadata | Meaning | Order |
2158
+ | Spelling | Meaning | Where |
2118
2159
  |---|---|---|
2119
- | `path` | The operation's addressed operand, matching `OP (path)`: read resource, mutation subject, message recipient, or executor operand. Explicit and automatic READs use the same field. Pathless operations omit it. | First |
2120
- | `from`, `to` | COPY/MOVE's two operand selections, each retaining its optional scope; neither replaces actor attribution or is repeated as `path`. | First, in that order |
2121
- | `stream` | An executor invocation's separately created output address, never a READ's alternative spelling of `path`. | Remaining facts |
2122
- | `resource` | A distinct returned resource under {§operation-resource-receipt}. | Remaining facts |
2160
+ | `OP (path)` | The operation's addressed operand: read resource, mutation subject, message recipient, or executor operand. Explicit and automatic READs are written identically. Pathless operations are written bare. | Written line |
2161
+ | `COPY (from) <marks> (to) <marks>` | COPY/MOVE's two operand selections, each retaining its optional scope; neither replaces actor attribution. | Written line |
2162
+ | `stream` | An executor invocation's separately created output address, never a READ's alternative spelling of its operand. | Facts |
2163
+ | `resource` | A distinct returned resource under {§operation-resource-receipt}. | Facts |
2123
2164
 
2124
2165
  Nested mutation effects and delivered attachments name their resource with `path`.
2125
2166
  These packet spellings do not rename the submitted AST, durable operation results,
@@ -2186,7 +2227,7 @@ Field absence carries defaults: `origin` is omitted for the owning model, `sourc
2186
2227
  records the exact READ coordinates sent without controlling retention. Missing immutable bytes are an
2187
2228
  internal integrity failure, never silently dropped content. No ejection message or permanent teaching is
2188
2229
  added. These stable curation weights are not provider-token measurements ({§tokenomics-render-weight-budget}).
2189
- - §packet-token-accounting Every row reports one `logTokens` charge: its complete materialized H3, metadata, visible body, and selected native attachment. The completed record is measured to a fixed point, including the accounting field itself. No `tokensBody`, `tokensMetadata`, or `tokensActive` field is serialized. Hidden text is not charged; metadata-only rows still have a reclaimable charge. Source/FIND-item `tokens` measure source content, not the observation's context footprint. A FIND's nonzero `itemsTokenTotal` weighs the complete matched set; a nonzero `returnedItemsTokenTotal` appears only when the returned page differs. All use stable curation weights, not provider tokens or dollars. Native component accounting follows {§packet-attachment-parts}; ordinary addressability and truthful errors follow {§log-wire-format}.
2230
+ - §packet-token-accounting Every row reports one `logTokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, written request, facts, visible body, and selected native attachment. The completed record is measured to a fixed point, including the accounting field itself. No `tokensBody`, `tokensMetadata`, or `tokensActive` field is serialized. Hidden text is not charged; metadata-only rows still have a reclaimable charge. Source/FIND-item `tokens` measure source content, not the observation's context footprint. A FIND's nonzero `itemsTokenTotal` weighs the complete matched set; a nonzero `returnedItemsTokenTotal` appears only when the returned page differs. All use stable curation weights, not provider tokens or dollars. Native component accounting follows {§packet-attachment-parts}; ordinary addressability and truthful errors follow {§log-wire-format}.
2190
2231
 
2191
2232
  ### §retrieval-packet-metadata READ/FIND packet metadata
2192
2233
 
@@ -2250,7 +2291,7 @@ single line past the end, a reversed range, empty content, a command's log row
2250
2291
  §rejected-emission-entry A rejected provider response is not `turnOps`: it never became an admitted turn program. The one bounded invalid-emission recovery item under {§emission-admission} has `attrs.kind="emissionAttempt"`, `origin="model"`, the canonical model-facing `/attempt` leaf, and the exact latest rejected response. The packet does not duplicate that identity as `kind` metadata. It is born durably body-suppressed and projected visibly only in the informed recovery packet; every other rejected attempt remains forensic-only.
2251
2292
 
2252
2293
  - §log-coordinate-hierarchy **Log coordinates are a hierarchical prefix; the trailing slash is optional** — a coordinate is `loop/turn/sequence`, and a PARTIAL coordinate selects its descendants: `log:///1` = loop 1's rows, `log:///1/2` = turn 1/2's rows, `log:///1/2/3` = the one row. A full coordinate is always three parts, so a one- or two-part path is unambiguously a prefix — the trailing slash is an optional alias (`log:///1/2` ≡ `log:///1/2/`), uniform with ```` ```READ (worker:///docs/) ````. A complete `[start-end]` segment in any numeric coordinate slot selects that inclusive decimal interval; brackets elsewhere retain ordinary path-glob meaning. Every rendered row appends one canonical model-facing leaf: the native operation name or invoked executor name, `/attempt` for a rejected emission. An executor leaf is derived from the durable submitted statement (its `runtime`), never an internal dispatch type or the current tool registry. Digits and punctuation in executor names remain part of the leaf. The leaf names identity rather than adding a resource level. Exact consumers tolerate the unsuffixed three-part shorthand; when supplied, the case-insensitive leaf is authoritative and a disagreement resolves 404. READ anchors use the canonical suffixed identity even when addressed by shorthand. Typed entry materialization therefore resolves as `/READ` while retaining its durable `EDIT` event ({§exec-entry-sink}). `log:///1/2/*` still selects the turn's item rows, while `log:///**/READ`, `log:///**/python3`, and `log:///**/attempt` deliberately filter canonical leaves. Executor outputs instead use workspace-wide claims such as `sh:///ab3d5678#stdout` ({§execution-output-identity}); their source operation has log coordinates, but resource lifetime and identity are independent of that observation. Error pointers, Problem instances, source attribution, and search use this same identity; client stream coordinates retain the numeric triple. Within a turn, sequence is arrival order. Inbound SEND rows publish before the program runs ({§message-arrival}); a turn receiving messages holds the first at `log:///L/T/1/SEND`, followed by further arrivals oldest first, then the model's operations ({§packet-current-turn} names `L/T`).
2253
- - §log-curation-folder-idiom **Log curation speaks the folder idiom; a zero-match sweep is a no-op success** — KILL takes a concrete coordinate or a path-glob, and a **trailing slash or a partial coordinate means "the contents"** ({§log-coordinate-hierarchy}), like a folder-scoped FIND: ```` ```KILL (log:///1/2) <1,-1> ```` suppresses turn 1/2's bodies. A **well-formed selection that matches nothing is 204 with `matched: 0`**; a successful sweep's rx carries `matched: N`. A targetless KILL is 400.
2294
+ - §log-curation-folder-idiom **Log curation speaks the folder idiom; a zero-match sweep is a no-op success** — KILL takes a concrete coordinate or a path-glob, and a **trailing slash or a partial coordinate means "the contents"** ({§log-coordinate-hierarchy}), like a folder-scoped FIND: ```` ```KILL (log:///1/2) <1,-1> ```` suppresses turn 1/2's bodies. A **well-formed selection that matches nothing is 204 with `matched: 0`**; a successful sweep's rx carries `matched: N`. Parameterless KILL instead requests completion ({§kill-conclusion}).
2254
2295
  - §log-curation-set-selection **Row selection and body scope are independent** — target/glob and an optional heading pattern (```` ```KILL (log:///**) [{"pattern": "~stale"}] ````, every dialect a FIND over rows accepts) compose by intersection into the affected row set. An optional `<L>` or `<SL,EL>` then intersects each selected canonical body; it never paginates or changes the selected set. Thus ```` ```KILL (log:///**/READ) <17,-1> ```` may change long READs and no-op on short ones while reporting every selected row in `matched`.
2255
2296
 
2256
2297
  §log-kill-meta-operation **A log KILL changes working context, never the underlying resources or execution history.** Receipt visibility depends on the target and result, not the producer, attribution, or age of the turn:
@@ -2559,7 +2600,7 @@ Log history preserved — `log_entries` stores path tuple as text, not FK to `en
2559
2600
  SEND AST: `{ op: "SEND", target: ParsedPath | null, body: SendBody | null, metadata, lineMarker }`.
2560
2601
 
2561
2602
  - **Message:** SEND delivers to an actor, endpoint or exact message address. Targetless SEND answers observed Open Messages.
2562
- - **Workflow:** WAIT yields; successful reply delivery and settled work permit completion at the end of the whole program. NOTE retains memory.
2603
+ - **Workflow:** WAIT yields. Parameterless KILL requests successful completion ({§kill-conclusion}). NOTE retains memory.
2563
2604
 
2564
2605
  §worker-obligations A worker holds its unresolved children and open non-detached
2565
2606
  streams (`worker_obligations`); `loop_obligations` names them per loop. The
@@ -2573,17 +2614,20 @@ same durable liveness.
2573
2614
  | Worker or loop already cancelled/terminal | Preserve that result. |
2574
2615
  | Administrative program | Finish its transaction without adjudicating another model loop's work. |
2575
2616
  | New unpublished message | Continue; publish it in the next packet. |
2576
- | Live work and either WAIT or no unanswered messages | Park the same loop; message arrival, child or stream settlement, or stream cadence wakes it. |
2577
- | WAIT without live work | Continue; never invent a future wake. |
2617
+ | Fresh operation/parser failure, without an authored WAIT | Continue before any automatic parking. |
2618
+ | Neither an authored WAIT nor an eligible completion request ({§kill-conclusion}) | Continue, regardless of earlier replies or live work. |
2619
+ | Live work and either WAIT or an eligible completion request | Park the same loop; message arrival, child or stream settlement, or stream cadence wakes it. No final-answer body is delivered while joining. |
2620
+ | WAIT without live work | Continue; never invent a future wake. The first such WAIT is an honest yield and its row says only `Nothing is in flight. Continuing.`; a second in the same loop is the model waiting on a wake nothing can send, so its own row instead names what WAIT is for and what to reach for — `WAIT doesn't wait unless there's a child worker or stream to wait on. Use schedule for specific timing decisions.` The correction rides the operation's own result, which is the surface the model is certain to read (operator, 2026-09-22). |
2578
2621
  | Unanswered messages | Continue. |
2579
2622
  | Unobserved operation results, failures, child results or stream conclusions | Continue; the next packet presents them. |
2580
- | No outstanding messages, live work or unobserved results | Conclude successfully, without a synthetic operation. |
2623
+ | Eligible completion request with no outstanding messages, live work or unobserved results | Conclude successfully. |
2581
2624
 
2582
- An empty emission is handled by {§empty-turn}, not this completion rule. Ordinary strikes,
2583
- cycles and execution limits remain independent. NOTE and successful KILL do not themselves
2584
- require another observation turn. Failed KILL and every other operational result do.
2625
+ An empty emission is handled by {§empty-turn}. Ordinary strikes, cycles and
2626
+ execution limits remain independent. NOTE and successful targeted KILL do not themselves
2627
+ require another observation turn, but neither requests completion. Failed KILL
2628
+ and every other operational result require observation.
2585
2629
 
2586
- §loop-response-messages **A response is a recorded delivery.** A successful SEND reply records
2630
+ §loop-response-messages **A response is a recorded delivery.** A successful SEND reply or admitted final KILL answer records
2587
2631
  the exact message addresses it answers. All replies remain independently recoverable in
2588
2632
  message history, in execution order, regardless of producer. An actor-addressed SEND that
2589
2633
  does not answer a message, WAIT, NOTE, asides, inherited rows and ambient observations are
@@ -2598,7 +2642,7 @@ conclusion carries its execution outcome under {§send-undelivered-child-term},
2598
2642
  | `NULL` | The model's own terminal or an engine verdict whose exact result already carries the story. | No authorship marker. |
2599
2643
  | `cancel` | The structured scope was explicitly cancelled, through the client or worker KILL ({§methods-loop-cancel}). | COLLECT and the termination delta prepend a cancellation marker to the exact Problem's presentation, so cancellation cannot masquerade as a deliverable. The model's prior log rows remain untouched. |
2600
2644
 
2601
- The engine's failure terminals — **500** (strike threshold) and **508** (cycle), {§engine-rails} — are never the model's to pick; they are the engine ruling the loop failed. The model answers, waits or cancels its scope; the engine derives the lifecycle outcome from that state.
2645
+ The engine's failure terminals — **500** (strike threshold) and **508** (cycle), {§engine-rails} — are never the model's to pick; they are the engine ruling the loop failed. The model answers, waits or cancels its scope; the engine derives the lifecycle outcome from that state. The ruling never softens, and it never destroys the evidence: every terminal cites what the model last left unconcluded ({§terminal-evidence}).
2602
2646
 
2603
2647
  Disposition outcomes follow {§wait-obligation-matrix},
2604
2648
  {§completion-joins-live-work}, and {§completion-defers-to-results}. Strike
@@ -2615,47 +2659,77 @@ accounting and model-visible failure evidence remain separately owned by
2615
2659
  answers its ordinary factual 501 without grafting a guessed recovery onto it.
2616
2660
  - §send-response-receipt **A reply records exactly which messages it answers.** A successful
2617
2661
  reply carries `answers`, the immutable message addresses it answered, not recipient actors. Targetless SEND
2618
- answers this loop's published, unanswered messages, oldest first. SEND to an exact message
2662
+ answers this loop's published, unanswered messages, oldest first. When none remain,
2663
+ a nonempty targetless SEND replies to the loop's original published message, so a
2664
+ follow-up can revise its answer. A targetless SEND with no body content or attachments
2665
+ delivers nothing, carries no `answers`, and cannot erase an earlier reply. An accepted
2666
+ parameterless KILL answer uses the same reply routing and empty-body rules. SEND to an exact message
2619
2667
  address answers only that message; SEND to an actor endpoint remains ordinary communication
2620
2668
  and answers no assignment implicitly. An unpublished arrival cannot be answered by the
2621
2669
  targetless shorthand. Failed delivery answers nothing. Reply accounting reads executed
2622
2670
  delivery evidence, never log visibility or the mere existence of a later SEND.
2623
- - §prose-conclusion **A markdown answer is the answer, and concluding is deliberate.** An admitted
2624
- response concludes only when it is wrapped whole in one `markdown` or `md` fence — the form
2625
- `plurnk.md` teaches — and has no operation, attempts none ({§operation-attempt}), was not cut at
2626
- the output allowance, is not empty, and says something outside its quotations ({§quotation}: a
2627
- reply that is nothing but quoted material is a misfenced program) (operator, 2026-09-18, #761;
2628
- fence required 2026-09-21). A response that merely failed to yield an operation is NOT an answer:
2629
- it is non-responsive and falls to {§empty-turn}, taking one strike while the loop continues. That
2630
- asymmetry is the point — a mis-fenced operation costs a turn, never the run, because a weak model
2631
- under pressure fences badly and a whole rollout must not end on a typo. An offset operation fence
2632
- is one of those quotations and disqualifies nothing: `plurnk.md` tells the model to offset an
2633
- example it does not intend to execute (operator, 2026-09-21). The engine
2634
- admits it as a targetless SEND whose body is the trimmed content, positioned on line 1. It
2635
- answers the open messages, reaches clients and a parent exactly as a SEND does, and meets the
2636
- completion barrier as a SEND does ({§completion-joins-live-work},
2637
- {§completion-defers-to-results}). Reasoning NOTEs ride with it. The model is taught
2638
- "respond without performing any OPs" and is never taught the SEND. A reply wrapped whole in one
2639
- `markdown` or `md` fence is delivered as that fence's content ({§quotation}). Its row is stored as the
2640
- SEND that delivers it (reply accounting, delivery and clients read SEND rows) but carries
2641
- `attrs.answer = "prose"` and `resource: ops://<worker>/<loop>`, and is addressed and rendered
2642
- under the leaf `answer` (`log:///1/2/2/answer`), never as a SEND the model did not write.
2671
+ - §kill-conclusion **Successful completion requires an explicit parameterless KILL.** The response
2672
+ contains exactly one KILL without a target, scope, matcher or metadata, no hard
2673
+ parse error or lost boundary, and was not cut at the provider's output allowance.
2674
+ The operation limit must admit the entire program.
2675
+ SEND, NOTE (outside text included, {§response-text-note}) and log-targeted KILL may
2676
+ accompany it; every other operation requires continuation. This tolerance is unadvertised:
2677
+ model teaching requests KILL alone. Reasoning-side NOTEs remain ordinary notes.
2678
+ An aside is allowed. After the program settles, {§wait-obligation-matrix} admits the
2679
+ completion or returns a non-striking continuation/parking receipt explaining the
2680
+ outstanding condition. Valid sibling operations always execute. Only an admitted
2681
+ KILL delivers its literal body through {§send-response-receipt}; a deferred body
2682
+ remains forensic evidence, never a stored draft to replay automatically. An empty
2683
+ KILL concludes without repeating an already-delivered answer, but cannot abandon an
2684
+ unanswered message. SEND, NOTE and targeted KILL never request successful
2685
+ completion. New arrivals still guard the terminal transition atomically
2686
+ ({§completion-defers-to-messages}); an arrival concurrent with an accepted reply
2687
+ remains unanswered and keeps the loop running. No implicit successful exit exists.
2688
+ - §response-text-note **Text outside the operations is the model's NOTE, never delivered.** Each
2689
+ span {§response-text} supplies becomes an ordinary NOTE in source order, unmarked, so the
2690
+ model's own log files its self-narration where it belongs. It is not an authored operation:
2691
+ {§empty-turn} still strikes a turn that holds only text, and the exact emission is retained.
2692
+ Delivered as a SEND, the text read as an answer and confirmed that speaking outside operations
2693
+ works; reported as a count of invalid characters, it sent a model to repair its prose into
2694
+ live operations (`demo-show-dont-run-qdN9u2` executed the KILL it meant to show). A NOTE
2695
+ neither delivers nor concludes (operator, 2026-09-22). This is the far end of the teaching
2696
+ scale: text outside every operation breaks the first rule of `plurnk.md` — *"YOU MUST ONLY
2697
+ use valid Plurnk OPs"* — and takes the largest reinterpretation, while a
2698
+ departure as small as a missing closer is read as meant ({§closer-fallback}).
2643
2699
  - §loop-answer **A loop's address is what it said.** READ `ops://<worker>/<loop>` resolves to
2644
- the latest reply the loop gave to the message that started it: a prose conclusion's text or
2645
- the body of a SEND that targeted that message. A running loop without one is 425; a loop that
2646
- ended without one is its terminal problem (404 when it ended 2xx). `ops://<worker>/<loop>/<turn>`
2647
- remains that turn's emission. A concluded child's `loop_termination` row to its parent carries
2648
- `answer: ops://<child>/<loop>` beside its status. Witness: `test/intg/loop-answer.test.ts`.
2649
- - §empty-turn **A response with no operation that is not an answer is a turn, not a retry.**
2650
- When the parser finds no operation and no other hard error, and the response is not an
2651
- answer under {§prose-conclusion} — an operation attempt, prose cut at the output allowance,
2652
- or an empty response — it is admitted as an empty turn (operator, 2026-09-12): its text and
2653
- reasoning are stored like any turn's (`ops://<worker>/`, `reasoning://<worker>/`), the model's own message
2654
- stays in the next packet's history, that packet carries one `turn_no_operations` notice and
2655
- any {§bare-heading-advisory} notices, the turn continues at 102, and the strike rail counts
2656
- one progress-contract strike, so a model that only talks strikes out at the ordinary
2657
- threshold instead of being resampled three times on an identical packet. Its fingerprint is
2658
- the empty program, so repeated empty turns also trip cycle detection.
2700
+ the latest reply the loop gave to the message that started it: the body of a SEND
2701
+ or accepted final KILL that answered that message. A running loop without one is 425; a loop that
2702
+ ended without one is its terminal problem (404 when it ended 2xx) — and that problem cites what
2703
+ the model last left unconcluded, so the loop's own address never reports silence from a loop that
2704
+ spoke ({§terminal-evidence}). `ops://<worker>/<loop>/<turn>`
2705
+ remains that turn's emission. A concluded child's `loop_termination` row to its parent
2706
+ READs this same loop resource. Witness: `test/intg/loop-answer.test.ts`.
2707
+ - §empty-turn **No authored response operation is a recoverable turn, never completion.**
2708
+ Count parsed response operations before outside-text and reasoning NOTEs join them;
2709
+ neither enters the count. When none exist and no boundary was lost, retain the turn and its raw
2710
+ sources and count one progress-contract strike, whether or not the turn carried text
2711
+ ({§response-text-note}). The strike sends no notice of its own; the threshold terminal is
2712
+ where it becomes visible, and it says why ({§engine-rails}). An empty turn uses its exact
2713
+ text as the cycle fingerprint ({§engine-cycle-evidence});
2714
+ different empty programs are not a repeated cycle merely because neither contained
2715
+ operations. Lost-boundary handling remains {§unparsed-tail-boundary}; no confirmation
2716
+ token or private retry is invented here.
2717
+ - §terminal-evidence **A terminal rules the loop over; it does not decide the model said nothing.**
2718
+ Every engine terminal — strike threshold (500), cycle (508), turn ceiling (429), loop timeout
2719
+ (504), provider unavailable ({§provider-recovery}) — keeps its status and its authorship: the
2720
+ engine ruled, the model did not conclude, and no terminal is ever softened into a 200 the model
2721
+ never declared. What a terminal may not do is discard the last thing the model said. When the
2722
+ loop's last inference turn performed no authored operation in either response or
2723
+ reasoning and kept text, its Problem Details
2724
+ carries the extension member `unconcluded`, the
2725
+ `ops://<worker>/<loop>/<turn>` address of that emission. It is a citation, never the bytes
2726
+ ({§turn-ops-entry}: the reader READs the source, and an emission of any length never rides
2727
+ wholesale into a parent's packet). The member is named for what it is — an emission left
2728
+ unconcluded — and never `answer`: the harness cannot warrant that text is complete or final,
2729
+ because it did not conclude under {§kill-conclusion}. Earlier deliveries remain delivered;
2730
+ the citation neither sends them again nor destroys them. A terminal whose last inference
2731
+ turn performed authored operations carries no `unconcluded`: an absent member is not an
2732
+ empty one. Attachment is owned by the one terminal seam.
2659
2733
  - §metadata-ignored **Options a scheme does not take are dropped, not refused.** A READ, FIND,
2660
2734
  EDIT or KILL carrying `[metadata]` for a scheme whose manifest takes none runs without it,
2661
2735
  and the packet carries one `metadata_ignored` notice naming the scheme (operator,
@@ -2663,40 +2737,26 @@ accounting and model-visible failure evidence remain separately owned by
2663
2737
  path; it is lifted into the matcher at parse time ({§matcher-option}). SEND recipients,
2664
2738
  executions, WORK and FORK own their input and receive it whole ({§send-resource-attachments},
2665
2739
  {§env-option}); a key they do not take is their own 400.
2666
- - §send-looks-like-operation **A reply never begins with an operation heading.** When a model's
2667
- untargeted SEND has, as its first non-blank line, a line that parses alone as one clean
2668
- heading naming an operation this worker could perform — a Plurnk operation, or a registered
2669
- executor or MCP service — dispatch refuses it 400 `send-looks-like-operation`, naming the
2670
- `heading`, and delivers nothing. Since the fences chapter's unlabeled-fence SEND was retired
2671
- ({§interstitial-fence}), this guards only an explicit `SEND` block; a heading written outside
2672
- any fence is prose with the parser's own advisory ({§bare-heading-advisory}), and an emission
2673
- made only of such lines is an empty turn carrying those advisories ({§empty-turn}). This is
2674
- admission, not promotion: the line is never run as the operation it resembles, and the neutral
2675
- recovery says only where each intent belongs (an operation on the fence line, a quoted example
2676
- inside a delimited SEND body). A first line that does not parse alone (prose after the word), a
2677
- name no registry knows, or an inner fence is an ordinary reply; so is a heading whose
2678
- only irregularity is a multi-word sigil-less matcher after the path (`READ (belfry.md)
2679
- returned nothing because the file is empty.`), which {§naked-pattern} would otherwise lift
2680
- as a literal — on a reply's first line that is prose. Origin: the 2026-09-11 dogfood,
2681
- where four operations on the line after their fences were delivered as four 200 replies and the
2682
- loop then parked fifteen minutes on receipts that could never arrive.
2683
2740
  - §send-idle-turn **NOTE is memory, not a yield.** NOTE does not imply parking.
2684
- With unanswered messages it continues; after replies and observation it may be the only
2685
- operation in the program that concludes. Repetition remains subject to {§engine-cycle-evidence}.
2741
+ A NOTE-only response does not request completion, even after every message is answered.
2742
+ Repetition remains subject to {§engine-cycle-evidence}.
2686
2743
  - §send-premature-terminate **Completion follows observation.** Every fired operation except
2687
2744
  SEND, NOTE, WAIT and successful KILL requires a subsequent packet. This barrier uses durable
2688
2745
  executed evidence, not curated rows. Fast completion, an empty result or curation cannot
2689
2746
  erase it. New arrivals are protected by {§completion-defers-to-messages}; no terminal verb
2690
2747
  or prose overrides this rule.
2691
- - §completion-joins-live-work **Answered work still joins its live obligations.** Once all
2692
- observed messages are answered, live children, non-detached streams park the same loop
2693
- as WAIT does. Each ordinary wake presents the newly settled state; completion is evaluated
2694
- again after the next program. KILL owns cancellation; a reply never cancels work implicitly.
2748
+ - §completion-joins-live-work **A completion request joins its live obligations.** An eligible
2749
+ parameterless KILL parks on live children or
2750
+ non-detached streams, as WAIT does. Ordinary programs continue regardless of earlier
2751
+ replies. Each wake presents the newly settled state; the next program expresses its
2752
+ own disposition. Only targeted KILL owns cancellation; parameterless KILL never
2753
+ cancels work and delivers no final answer while joining.
2695
2754
  - §completion-defers-to-results **Results keep the loop running until observed.** Same-turn
2696
2755
  operations and failures, plus undelivered child or stream conclusions, require the next
2697
- packet. This is ordinary continuation, not a strike or a synthetic refusal receipt.
2698
- The already-delivered answer remains delivered. If observation warrants no further work
2699
- or revision, a NOTE or curation-only program can conclude without repeating the answer.
2756
+ packet. This is ordinary continuation, not a strike. A premature parameterless KILL
2757
+ receives a factual continuation receipt without delivering its body. Earlier SEND
2758
+ replies remain delivered. If observation warrants no further work or revision, a
2759
+ lone empty parameterless KILL requests completion without repeating an earlier answer.
2700
2760
  - §send-administrative-terminal **Administrative programs close their own transaction.**
2701
2761
  Their caller closes the administrative loop after execution; no terminal operation is
2702
2762
  manufactured. Initialization runs in the model loop without concluding it.
@@ -2951,14 +3011,14 @@ two states and no others:
2951
3011
  | state | what the model receives |
2952
3012
  |---|---|
2953
3013
  | active | nothing in the Log. The `## Delegation` stream pointer names the stream with each channel's size and its growth since the last packet ({§child-orientation}); the model READs any range it wants, and every READ of a stream channel carries `terminal: false` while it runs and `terminal: true` once it has concluded, so an empty page is never mistaken for a finished command that printed nothing (operator, 2026-09-13). |
2954
- | terminal | ONE `origin=_plurnk` READ at the execution's channel address, born visible, that is exactly a markerless READ of the channel — its bounded first page ({§read-selection-projection}, the whole channel when it fits, the channel's own mimetype), the `range` or `region`, terminal status and Problem, `terminal: true`, and any producer-supplied integer `exitCode`. The packet identifies the read resource with `path`, exactly as an explicit READ does ({§log-address-metadata}). |
3014
+ | terminal | ONE `origin=_plurnk` READ at the execution's channel address, born visible, that is exactly a markerless READ of the channel — its bounded first page ({§read-selection-projection}, the whole channel when it fits, the channel's own mimetype), the `range` or `region`, terminal status and Problem, `terminal: true`, and any producer-supplied integer `exitCode`. The packet writes the read resource as its operand, exactly as an explicit READ does ({§log-address-metadata}). |
2955
3015
 
2956
3016
  §stream-observation-result **One liveness fact.** The durable READ result owns
2957
3017
  `terminal`, derived from its selected channel's state, for explicit and automatic
2958
3018
  observations alike, independently of mimetype: `active` gives false, `closed` or
2959
3019
  `errored` gives true, and `static` has no streaming liveness field. Packet
2960
- projection preserves that Boolean and any included
2961
- integer `exitCode`, even for an empty body. An automatic observation's atomic
3020
+ projection preserves that Boolean, any included
3021
+ integer `exitCode`, and a producer's `page` receipt ({§executor-page-receipt}), even for an empty body. An automatic observation's atomic
2962
3022
  publication transition consumes the same result flag; private log attributes
2963
3023
  retain only the publication offset, not a second liveness value.
2964
3024
 
@@ -3334,10 +3394,10 @@ No generator. SQLite-optimal: STRICT (3.37+), `INTEGER PRIMARY KEY` aliasing, ex
3334
3394
  | §db-process-triggers Processes beside their owners | A trigger that writes rows — a cascade, a capture, an ambient event, a publication cursor, a landed curation — is a process, not shape. It is declared as an `-- INIT: <trigger name>` block in the `.sql` file beside the statements that fire it (`ambient.sql` for the ambient feed, `LoopLifecycle.sql`, `Turn.sql`, `Engine.sql` for model calls, `_entry-crud.sql`, `Log.sql`, `ChannelWrite.sql`), as `DROP TRIGGER IF EXISTS` then `CREATE TRIGGER`, so the definition is current on every open of a database whose shape is current. `MIGRATE` always precedes `INIT` and `INIT` runs on the writer only, so a process may reference any table regardless of file order and never runs on the read pool. `test/intg/schema-composition.test.ts` fails on a baseline trigger that writes, an `INIT` trigger that only guards, a block not named after its trigger or not dropping first, and a live trigger set that differs from the declared set after a first and a second open. |
3335
3395
  | §db-fk-indexes Foreign-key check paths | Every foreign-key column a delete, cascade, or parent replacement can check carries an index (partial where the column is nullable), and no registry statement's plan scans a growing table: `test/intg/schema-query-plans.test.ts` runs `EXPLAIN QUERY PLAN` over every `-- PREP` statement against the baseline and fails on a `SCAN` of a growing table, except statements that read a whole table by design (digest, startup recovery, whole-workspace listings, scheduled-loop claims). An index claim is a plan, never a grep of index names. |
3336
3396
  | §db-index-owners Every index has an owner | An explicit index earns its place one of three ways: a registry statement's plan uses it, its leading column is a foreign key whose check it serves, or it enforces uniqueness. The same test fails on any other index, naming it: an index nobody reads is a write on every insert. Duplicates of a `UNIQUE` constraint's own index and sort-only indexes no plan selects were removed on this rule; a column no statement reads (`symbol_refs.col`, `ambient_events.created_at`) is not stored. |
3337
- | §db-maintenance-optimize Statistics at shutdown | The daemon's last database step before the caller closes SQLite is `PRAGMA optimize` on the writer (`maintenance_optimize`), so `sqlite_stat1` reflects tables the connection planned against, bounded by SQLite's own analysis limit; a failure there is a reported shutdown error, never silent. Retention runs before it under the operator's policy ({§retention-policy}); no explicit checkpoint and no periodic `ANALYZE` run. |
3397
+ | §db-maintenance-optimize Statistics at shutdown | The daemon's last database step before the caller closes SQLite is `PRAGMA optimize` on the writer (`maintenance_optimize`), so `sqlite_stat1` reflects tables the connection planned against, bounded by SQLite's own analysis limit; a failure there is a reported shutdown error, never silent. Retention runs before it under the operator's policy ({§retention-policy}) and ends with a WAL truncation ({§db-space-reclamation}); no periodic `ANALYZE` runs. |
3338
3398
  | §db-space-reclamation The daemon keeps its own file healthy | `PLURNK_SERVICE_AUTO_VACUUM` (`incremental`, the default, or `none`) names the mode the daemon keeps its file in. At start, before any drain, a database in another mode is converted (set the mode, one `VACUUM`, which rewrites the file and needs free disk about its size) and the journal says so with page counts before and after. Under `incremental`, every retention pass ends by stepping `PRAGMA incremental_vacuum` to completion once free pages reach `PLURNK_SERVICE_RECLAIM_MIN_FREE_BYTES` (0, the default, = every pass), and reports `reclaimedPages`; below the floor, free pages stay for SQLite to reuse. Under `none` the file never shrinks and freed pages are reused. No operator step is involved beyond the knobs. The WAL stays bounded by SQLite's automatic checkpoint (#764). |
3339
3399
  | §content-store Every body is stored once | `contents` holds each settled body once, addressed by its SHA-256, however many channels, workspaces, forks or derivations carry it; rows are immutable. `entry_channel_rows` points a settled channel at its body and keeps an active stream's body as a private buffer until it settles, when it is interned. Every reader and writer uses the `entry_channels` view, whose `INSTEAD OF` triggers intern bodies, refuse a bound `content_hash` that is not the content's, and write each column group only when it changed, so a search attachment is never a representation write. SQLite counts no changes for a view, so a write that must know whether its channel exists returns the channel's name; an outer join cannot flatten the view, so the two statements that need one read `entry_channel_rows` and `contents` directly. `derivation_fts` is an external-content index over `derivation_texts` (a derivation joined to its body); `derivations.content_id` names the indexed text, and the triggers in `_entry-fts.sql` move the index with it and forget it on delete. A body no channel holds and no derivation indexes is collected by retention under `PLURNK_SERVICE_COLLECT_CONTENTS` (1). Witnesses: `test/intg/retention.test.ts`, `test/intg/entries.test.ts`, `test/intg/fulltext-index.test.ts`. |
3340
- | §retention-policy Retention is the operator's policy; information is kept by default | `Retention` (`src/server/Retention.ts`, statements in `Retention.sql`) reads ten knobs from `.env.defaults` once at daemon construction (the two storage knobs are {§db-space-reclamation}) and runs four set statements in dependency order — on `PLURNK_SERVICE_RETENTION_INTERVAL_MS` cadence while the daemon runs (0 = shutdown only) and once more at shutdown before `PRAGMA optimize`. `PLURNK_SERVICE_RETAIN_PACKET_TURNS` (-1 = every packet) and `PLURNK_SERVICE_RETAIN_PACKET_MS` (-1 = no age limit) retire a completed turn's packet composition (`turn_sections`, {§packet-items}) once it is beyond the newest N packet-bearing turns of its loop or older than the age; the turn, its bag, its log rows and its accounting stay, and an open turn is never retired. `PLURNK_SERVICE_COLLECT_PACKET_ITEMS` (1) collects items no composition references. `PLURNK_SERVICE_COLLECT_CONTENTS` (1) collects stored bodies nothing holds ({§content-store}), after the collectors that release them. `PLURNK_SERVICE_COLLECT_DERIVATIONS` (1) collects derivations no channel, turn source, or log row cites — superseded editions — with their symbols (cascade) and their full-text shadow (`derivations_delete_fts`, a process trigger beside the FTS statements, on every delete path). `PLURNK_SERVICE_RETAIN_RESPONSE_TURNS` (-1) and `PLURNK_SERVICE_RETAIN_RESPONSE_MS` (-1) retire a settled call's response body (`model_call_responses`) once it is beyond the newest N body-bearing calls of its loop or its turn is older than the age; the call's identity, failure, capacity, admission and accounting stay, and the digest renders such a call request-only. Under the shipped defaults nothing that is information leaves; only what no row references. A malformed knob refuses daemon construction. Witness: `test/intg/retention.test.ts`. |
3400
+ | §retention-policy Retention is the operator's policy; information is kept by default | `Retention` (`src/server/Retention.ts`, statements in `Retention.sql`) reads ten knobs from `.env.defaults` once at daemon construction (the two storage knobs are {§db-space-reclamation}) and runs four set statements in dependency order — on `PLURNK_SERVICE_RETENTION_INTERVAL_MS` cadence while the daemon runs (0 = shutdown only) and once more at shutdown before `PRAGMA optimize`. `PLURNK_SERVICE_RETAIN_PACKET_TURNS` (-1 = every packet) and `PLURNK_SERVICE_RETAIN_PACKET_MS` (thirty days; -1 = no age limit) retire a completed turn's packet composition (`turn_sections`, {§packet-items}) once it is beyond the newest N packet-bearing turns of its loop or older than the age; the turn, its bag, its log rows and its accounting stay, and an open turn is never retired. `PLURNK_SERVICE_COLLECT_PACKET_ITEMS` (1) collects items no composition references. `PLURNK_SERVICE_COLLECT_CONTENTS` (1) collects stored bodies nothing holds ({§content-store}), after the collectors that release them. `PLURNK_SERVICE_COLLECT_DERIVATIONS` (1) collects derivations no channel, turn source, or log row cites — superseded editions — with their symbols (cascade) and their full-text shadow (`derivations_delete_fts`, a process trigger beside the FTS statements, on every delete path). `PLURNK_SERVICE_RETAIN_RESPONSE_TURNS` (-1) and `PLURNK_SERVICE_RETAIN_RESPONSE_MS` (thirty days) retire a settled call's response body (`model_call_responses`) once it is beyond the newest N body-bearing calls of its loop or its turn is older than the age; the call's identity, failure, capacity, admission and accounting stay, and the digest renders such a call request-only. Under the shipped defaults the durable record is kept forever, while packets and response bodies — transient evidence — are collected after thirty days, so a daemon left running for months stops growing (#788). A malformed knob refuses daemon construction. Witness: `test/intg/retention.test.ts`. |
3341
3401
 
3342
3402
  - DDL = storage truth; JSON Schemas = wire truth. They are allowed to differ where ergonomics demand.
3343
3403
  - §entry-identity-no-null **Identity components are never NULL.** `(workspace_id, scheme, authority, pathname)` is a unique key. `workspace_id` references the workspace directly with cascading deletion. Namespace schemes use empty authority; resource schemes retain their canonical authority. File members use nonempty `scheme="file"` and render as bare paths. Registration refuses `storedScheme: null`.
@@ -3750,7 +3810,10 @@ The database may be released only after the final settlement barrier resolves.
3750
3810
  (`PLURNK_SERVICE_STOP_TIMEOUT_MS`, default 30000): past the deadline each wait
3751
3811
  is abandoned with a named error instead of hanging the daemon on a child that
3752
3812
  never closes. A wedged child costs a forced shutdown; it must never cost an
3753
- unbounded one.
3813
+ unbounded one. When the teardown settles, success or failure, the process ends
3814
+ itself: `0` after a clean teardown, `1` after a reported one. A handle an abandoned
3815
+ wait left alive never keeps a stopped daemon running; the supervisor's kill is a
3816
+ backstop, not the exit.
3754
3817
 
3755
3818
  ```mermaid
3756
3819
  flowchart LR
@@ -4487,7 +4550,7 @@ flowchart TD
4487
4550
  | Status | Outcome |
4488
4551
  |---|---|
4489
4552
  | 100 / 102 | Queued / running |
4490
- | 202 | WAIT or answered work joining a live obligation ({§wait-obligation-matrix}, {§worker-wait-timing}) |
4553
+ | 202 | WAIT or an eligible final response joining a live obligation ({§wait-obligation-matrix}, {§worker-wait-timing}) |
4491
4554
  | 200 | Messages answered, results observed, held work settled |
4492
4555
  | 499 | Worker-scope or client cancellation |
4493
4556
  | 429 | Turn allowance exhausted |
@@ -4496,7 +4559,9 @@ flowchart TD
4496
4559
  | 504 | Loop timeout or exec-timeout restamp |
4497
4560
 
4498
4561
  An empty WAIT continues at 102. The exact terminal result retains its Problem;
4499
- status classes are not catch-all replacements for that evidence.
4562
+ status classes are not catch-all replacements for that evidence. No failing status
4563
+ here is ever softened because the model wrote something the harness could not read;
4564
+ every one of them cites it instead ({§terminal-evidence}).
4500
4565
 
4501
4566
  ### §env-delta The environment delta: what changed since the model last looked
4502
4567
 
@@ -4549,8 +4614,8 @@ ordinary operation evidence still reaches that child's direct parent.
4549
4614
 
4550
4615
  | Producer / event | Durable occurrence | Observer projection |
4551
4616
  | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
4552
- | §env-delta-child-activity Direct-child activity | Child-authored final EDIT, COPY, MOVE, SEND, executor invocation, WORK, FORK, and non-log KILL receipts, including failures. `_plurnk` initialization, maintenance, and operation turns stay with the worker. A reply already delivered to the parent uses its reply occurrence instead ({§message-reply-delivery}). | Direct parent only; one exact attributed row born body-suppressed. Incoming message projections ({§message-arrival}), NOTE, READ (including executor-output READs), FIND, BARE, WAIT, and log KILL never create activity occurrences. Provider reasoning, calls, rejected emissions, and turn sources do not cross automatically. |
4553
- | §env-delta-child-termination Direct-child termination | The child's exact terminal loop result, except loops containing only `_plurnk` operation or maintenance turns. A conclusion before the first turn still reports, including failed spawns. `source` names the actor; the READ target selects its exact loop result ({§worker-loop-result}). | Direct parent only; an ordinary bounded READ projection of the retained occurrence, never a fresh lookup of the child's latest loop. The outcome's own body is visible within the ordinary READ bound; replies are separate messages and are never copied or deduplicated by content ({§worker-scheme-collect}). Excluded administrative loops create no pending child-result edge. |
4617
+ | §env-delta-child-activity Direct-child activity | Child-authored final EDIT, COPY, MOVE, SEND, executor invocation, WORK, FORK, and targeted non-log KILL receipts, including failures. `_plurnk` initialization, maintenance, and operation turns stay with the worker. A reply already delivered to the parent uses its reply occurrence instead ({§message-reply-delivery}). | Direct parent only; one exact attributed row born body-suppressed. Incoming message projections ({§message-arrival}), successful targetless SEND without delivery ({§send-response-receipt}), NOTE, READ (including executor-output READs), FIND, BARE, WAIT, parameterless KILL, and log KILL never create activity occurrences. Provider reasoning, calls, rejected emissions, and turn sources do not cross automatically. |
4618
+ | §env-delta-child-termination Direct-child termination | The child's exact terminal loop result, except loops containing only `_plurnk` operation or maintenance turns. A conclusion before the first turn still reports, including failed spawns. `source` names the actor; the READ selects the exact loop ({§loop-answer}). | Direct parent only; bounded, initially visible READ under {§worker-scheme-collect}, never the child's potentially newer loop. Excluded administrative loops create no pending child-result edge. |
4554
4619
  | §env-delta-commons-mutation Commons mutation | One successful resolved operation whose landed effects touch `worker:///...`. | Every existing worker; one body-suppressed row per observer, deduplicated with any lineage audience. |
4555
4620
  | §env-delta-filesystem-narration Project-file divergence | Runtime-owned reconciliation evidence remains in the runtime actor's own log. | No ambient observer row. Current content remains addressable and stale hash edits reject at their owned boundary. |
4556
4621
  | §env-delta-entry-materialization Executor `entry()` sink | The runtime records typed materialization evidence under its owning actor. | No ambient observer row unless the resulting operation itself is direct-child activity or a commons mutation ({§exec-entry-sink}). |
@@ -4718,7 +4783,7 @@ Retired terms stay retired: the lexicon guard rejects `thinking`, the unqualifie
4718
4783
  | inbound `SEND` from outside the workspace | budgeted head under {§message-projection} |
4719
4784
  | structured `EDIT` receipt or textual `COPY`/`MOVE` effects | complete receipt-owned join context |
4720
4785
  | every other nonempty body | head bounded independently by `PLURNK_SERVICE_PREVIEW_LINES` and `PLURNK_SERVICE_PREVIEW_CHARS` |
4721
- | bodyless row | metadata only; no coordinate lines; `logTokens` includes any selected native part |
4786
+ | bodyless row | heading, written request, and any facts; no coordinate lines; `logTokens` includes any selected native part |
4722
4787
 
4723
4788
  §markerless-first-page **Every markerless retrieval takes the same implicit marker.** A marker's
4724
4789
  unit is whatever its projection counts, so `PLURNK_SERVICE_PREVIEW_LINES` is the first page of
@@ -4743,8 +4808,8 @@ READ and FIND own their range or pagination before packet rendering; the packet
4743
4808
 
4744
4809
  Every accepted message enters its recipient loop's inbox in arrival order, with its selected
4745
4810
  paths, and publishes exactly once at the next turn boundary. **Open Messages** lists the
4746
- unanswered messages by their immutable source address (`path`) and optional causal `source`,
4747
- not a log coordinate. Each arrival receipt's `resource` names that same retained source.
4811
+ unanswered messages by their immutable source address (`path`) and their sender — a causal
4812
+ `source`, or `"origin": "user"` for the operator's own ({§message-causal-source}) — not a log coordinate. Each arrival receipt's `resource` names that same retained source.
4748
4813
  Trusted protocol modules supply message addresses in their own scheme;
4749
4814
  native arrivals use `message://<recipient>/<opaque-id>`, separate from the worker's
4750
4815
  actor and scratch addresses. Ordinary worker scratch remains writable. Source bodies
@@ -4758,15 +4823,17 @@ another admission is a 409 conflict, not a second message or an implicit content
4758
4823
  | Audience | Delivery | Effect |
4759
4824
  |---|---|---|
4760
4825
  | Assigned worker | Its conversation, even when another actor answered | Visible reply; wakes eligible parked work without a new Open Message or loop. |
4761
- | Original native sender | That worker, if distinct from the assigned worker | The same reply, through the same wake and observation path. |
4826
+ | Original native sender | That worker, if distinct from the assigned worker; original delegated-task answers use {§worker-scheme-collect} instead | Other replies use the same wake and observation path. |
4762
4827
  | Exterior sender | The assigned conversation's protocol adapter | The adapter delivers the answer through its standard message channel. |
4763
4828
  | Replying actor | Its own executed SEND | No duplicate ambient occurrence. |
4764
4829
 
4765
4830
  The successful SEND and its addressed occurrences commit together. Reply occurrences use
4766
4831
  the ordinary durable ambient cursor and wake revision; curation cannot revoke delivery or
4767
4832
  replay it. An addressed reply replaces the same parent's generic activity observation.
4768
- Child completion is a separate READ of its execution outcome; replies are not outcome bodies.
4769
- The complete outcome remains available at its {§worker-loop-result} address.
4833
+ The child's reply to its original parent-delegated message reaches that parent once,
4834
+ through the conclusion READ under {§worker-scheme-collect}; it is not a separate reply
4835
+ occurrence. Other replies remain ordinary messages. The exact loop remains addressable
4836
+ under {§loop-answer}.
4770
4837
  Unobserved replies prevent conclusion just as unobserved child results do. All operation
4771
4838
  producers notify the same settlement path after durable execution; reply wake-up shares
4772
4839
  {§worker-optimistic-settlement}, without delaying the replying program.
@@ -4780,7 +4847,7 @@ additional alias. Answering either reaches the same message. Origin (operator, 2
4780
4847
  packet showed a 77-character `agui://anonymous/threads/…/messages/<uuid>` twice per open message,
4781
4848
  while the docs taught the short form.
4782
4849
 
4783
- §message-causal-source **Message authorship and delivery are distinct facts.** The harness publishes every arrival row; the row's `source` carries the canonical address of the causal actor. Native WORK, FORK, and directed worker SEND derive `worker://<sender>` from the authenticated sender worker ID. A trusted exterior adapter supplies its own canonical actor address through {§methods-loop-run}: the AG-UI bridge names the client's message under `agui://` ({§agui-run-source}), the inbound A2A adapter under `a2a://`. An absent source means the owning worker itself. Attribution persists with the message through the inbox, parking, orphan recovery, restart, and later log projection; model syntax cannot author it. The wire renders the row's `source` and omits its `origin`, which is constant for every arrival; the Open Messages pointer carries the same source ({§message-arrival}) — except where the source is the transport that minted this very message, which says nothing the address does not ({§message-short-identity}).
4850
+ §message-causal-source **Message authorship and delivery are distinct facts.** The harness publishes every arrival row; the row's `source` carries the canonical address of the causal actor. Native WORK, FORK, and directed worker SEND derive `worker://<sender>` from the authenticated sender worker ID. A trusted exterior adapter supplies its own canonical actor address through {§methods-loop-run}: the AG-UI bridge names the client's message under `agui://` ({§agui-run-source}), the inbound A2A adapter under `a2a://`. An absent source is the operator. Attribution persists with the message through the inbox, parking, orphan recovery, restart, and later log projection; model syntax cannot author it. The wire renders the row's `source` in place of its `origin`, which is constant for every arrival, except where the source is the transport that minted this very message, which says nothing the address does not ({§message-short-identity}). The operator's message is then the one arrival with no sender to show, so it renders `"origin": "user"`: left bare, it read as the model's own SEND, and a model that had finished the work could no longer find the request it was answering (operator, 2026-09-22). The Open Messages pointer carries the same attribution ({§message-arrival}).
4784
4851
 
4785
4852
  §message-projection **Message storage is unbounded by model context; automatic materialization is not.** Core persists every accepted message completely before packet assembly. The selected provider's derived `inputCapacity` and the alias-resolved percentage from `PLURNK_SERVICE_PROMPT_PROJECTION` derive one aggregate curation-weight allowance for the visible bodies of arrivals other than a peer worker's — every `source` that is not a `worker://` address, the loop's own assignment included. Complete bodies render when their aggregate weight fits. Otherwise all such visible rows share the allowance: full bodies consume only their required share, unused shares are redistributed, and partial bodies render the largest leading complete-line region that fits their share or an exact character-bound prefix when the first physical line alone is larger. The sum of their rendered body weights never exceeds the allowance. Every partial body carries `preview` under {§packet-extent-metadata}. The row remains complete and READable by coordinate; its `log:///` body additionally obeys deliberate curation under {§log-readable-projection}. A peer worker's message takes the ordinary bounds. When provider input capacity is unknown the percentage is underivable, so arrival rows retain the ordinary bounded projection rather than inventing capacity. This policy never rejects, summarizes, or discards a message because it exceeds a context window.
4786
4853
 
@@ -5388,8 +5455,8 @@ only when its content is already source-numbered, such as an effect receipt.
5388
5455
  An EDIT or scoped entry KILL log row renders its bounded effect receipt (`rx.receipt`) as row
5389
5456
  metadata and join context, not its input statement. Proposal-gated file EDITs
5390
5457
  compute the accepted receipt from what actually lands. Environment-delta EDITs
5391
- render their resulting `rx.span`. COPY/MOVE rows render compact ordered
5392
- `from` and `to` selections ({§log-address-metadata}), compact ordered `effects` metadata, and
5458
+ render their resulting `rx.span`. COPY/MOVE rows write both operand
5459
+ selections ({§log-address-metadata}), render compact ordered `effects` metadata, and
5393
5460
  any scoped textual receipt contexts under their `log:///` address, never under
5394
5461
  one operand's resource address. All generated bodies remain under
5395
5462
  {§body-projection}. {§edit-result-render}
@@ -5483,7 +5550,6 @@ database is a benchmark artifact like any other: the lane's run directory lives
5483
5550
  checkout holds source only — never run output. `test:intg` stamps `PLURNK_TEST_RUN` once and every
5484
5551
  test process inherits it, so one suite's databases land in one directory without a pretest step, a
5485
5552
  marker file or a sweep; an unstamped invocation is not a special case with its own rules, it is
5486
- simply an unstamped run with its own directory. Nothing counts, reuses, moves, hides or
5487
- conditionally clears an artifact, so a failed suite's evidence is exactly where the run reported
5488
- it. A cross-package test may reuse Core's migration fixture only by passing a path inside the
5553
+ simply an unstamped run with its own directory. A stamped run that passes is reclaimed when it
5554
+ exits; a failed suite's evidence is never touched and stays exactly where the run reported it. A cross-package test may reuse Core's migration fixture only by passing a path inside the
5489
5555
  caller's own run directory.