@plurnk/plurnk-service 3.0.0 → 3.1.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 (156) hide show
  1. package/.env.defaults +16 -4
  2. package/INSTALL.md +18 -0
  3. package/README.md +3 -0
  4. package/SPEC.md +355 -187
  5. package/dist/build-info.json +1 -1
  6. package/dist/completions/_plurnk-service +13 -0
  7. package/dist/completions/plurnk-service.bash +19 -0
  8. package/dist/completions/plurnk-service.fish +93 -0
  9. package/dist/core/AdmittedTurnExecutor.d.ts +2 -2
  10. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  11. package/dist/core/AdmittedTurnExecutor.js +16 -24
  12. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  13. package/dist/core/BudgetReadout.d.ts +7 -2
  14. package/dist/core/BudgetReadout.d.ts.map +1 -1
  15. package/dist/core/BudgetReadout.js +36 -5
  16. package/dist/core/BudgetReadout.js.map +1 -1
  17. package/dist/core/Dispatcher.d.ts +2 -2
  18. package/dist/core/Dispatcher.d.ts.map +1 -1
  19. package/dist/core/Dispatcher.js +43 -39
  20. package/dist/core/Dispatcher.js.map +1 -1
  21. package/dist/core/Engine.d.ts.map +1 -1
  22. package/dist/core/Engine.js +1 -4
  23. package/dist/core/Engine.js.map +1 -1
  24. package/dist/core/EnvFlags.js +1 -1
  25. package/dist/core/EnvFlags.js.map +1 -1
  26. package/dist/core/FabricatedLog.d.ts +1 -0
  27. package/dist/core/FabricatedLog.d.ts.map +1 -1
  28. package/dist/core/FabricatedLog.js +8 -0
  29. package/dist/core/FabricatedLog.js.map +1 -1
  30. package/dist/core/KillHandler.d.ts.map +1 -1
  31. package/dist/core/KillHandler.js +2 -0
  32. package/dist/core/KillHandler.js.map +1 -1
  33. package/dist/core/LiveSubscription.d.ts.map +1 -1
  34. package/dist/core/LiveSubscription.js +14 -2
  35. package/dist/core/LiveSubscription.js.map +1 -1
  36. package/dist/core/LiveSubscriptions.d.ts +3 -1
  37. package/dist/core/LiveSubscriptions.d.ts.map +1 -1
  38. package/dist/core/LiveSubscriptions.js +16 -1
  39. package/dist/core/LiveSubscriptions.js.map +1 -1
  40. package/dist/core/LogBody.d.ts.map +1 -1
  41. package/dist/core/LogBody.js +3 -1
  42. package/dist/core/LogBody.js.map +1 -1
  43. package/dist/core/LoopDriver.d.ts.map +1 -1
  44. package/dist/core/LoopDriver.js +3 -0
  45. package/dist/core/LoopDriver.js.map +1 -1
  46. package/dist/core/LoopLifecycle.sql +1 -0
  47. package/dist/core/MessageResources.sql +31 -0
  48. package/dist/core/PacketBuilder.d.ts +2 -2
  49. package/dist/core/PacketBuilder.d.ts.map +1 -1
  50. package/dist/core/PacketBuilder.js +123 -51
  51. package/dist/core/PacketBuilder.js.map +1 -1
  52. package/dist/core/PacketBuilder.sql +13 -14
  53. package/dist/core/ReplyMetadata.d.ts +10 -0
  54. package/dist/core/ReplyMetadata.d.ts.map +1 -0
  55. package/dist/core/ReplyMetadata.js +20 -0
  56. package/dist/core/ReplyMetadata.js.map +1 -0
  57. package/dist/core/ServiceHelp.d.ts +6 -0
  58. package/dist/core/ServiceHelp.d.ts.map +1 -0
  59. package/dist/core/ServiceHelp.js +35 -0
  60. package/dist/core/ServiceHelp.js.map +1 -0
  61. package/dist/core/StoredPacket.d.ts +1 -0
  62. package/dist/core/StoredPacket.d.ts.map +1 -1
  63. package/dist/core/StoredPacket.js +4 -1
  64. package/dist/core/StoredPacket.js.map +1 -1
  65. package/dist/core/StrikeRail.d.ts.map +1 -1
  66. package/dist/core/StrikeRail.js +2 -2
  67. package/dist/core/StrikeRail.js.map +1 -1
  68. package/dist/core/TokenCalibration.d.ts +2 -2
  69. package/dist/core/TokenCalibration.d.ts.map +1 -1
  70. package/dist/core/TokenCalibration.js +12 -16
  71. package/dist/core/TokenCalibration.js.map +1 -1
  72. package/dist/core/TokenCalibration.sql +29 -6
  73. package/dist/core/TurnDispositionHandler.d.ts +1 -2
  74. package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
  75. package/dist/core/TurnDispositionHandler.js +30 -26
  76. package/dist/core/TurnDispositionHandler.js.map +1 -1
  77. package/dist/core/TurnMaterialization.d.ts.map +1 -1
  78. package/dist/core/TurnMaterialization.js +11 -1
  79. package/dist/core/TurnMaterialization.js.map +1 -1
  80. package/dist/core/TurnOps.d.ts +5 -1
  81. package/dist/core/TurnOps.d.ts.map +1 -1
  82. package/dist/core/TurnOps.js +29 -2
  83. package/dist/core/TurnOps.js.map +1 -1
  84. package/dist/core/TurnRunner.d.ts.map +1 -1
  85. package/dist/core/TurnRunner.js +119 -55
  86. package/dist/core/TurnRunner.js.map +1 -1
  87. package/dist/core/TurnSources.sql +2 -2
  88. package/dist/core/packet-wire.d.ts +7 -1
  89. package/dist/core/packet-wire.d.ts.map +1 -1
  90. package/dist/core/packet-wire.js +87 -27
  91. package/dist/core/packet-wire.js.map +1 -1
  92. package/dist/core/recap-lines.d.ts +4 -0
  93. package/dist/core/recap-lines.d.ts.map +1 -0
  94. package/dist/core/recap-lines.js +11 -0
  95. package/dist/core/recap-lines.js.map +1 -0
  96. package/dist/core/sql-functions.d.ts +2 -0
  97. package/dist/core/sql-functions.d.ts.map +1 -0
  98. package/dist/core/sql-functions.js +5 -0
  99. package/dist/core/sql-functions.js.map +1 -0
  100. package/dist/core/turn-scheduler.d.ts.map +1 -1
  101. package/dist/core/turn-scheduler.js +1 -1
  102. package/dist/core/turn-scheduler.js.map +1 -1
  103. package/dist/evidence/EvidenceReader.d.ts.map +1 -1
  104. package/dist/evidence/EvidenceReader.js +15 -2
  105. package/dist/evidence/EvidenceReader.js.map +1 -1
  106. package/dist/evidence/digest.sql +1 -0
  107. package/dist/man/plurnk-service.1 +488 -0
  108. package/dist/schemes/Env.d.ts +26 -0
  109. package/dist/schemes/Env.d.ts.map +1 -0
  110. package/dist/schemes/Env.js +133 -0
  111. package/dist/schemes/Env.js.map +1 -0
  112. package/dist/schemes/Exec.d.ts.map +1 -1
  113. package/dist/schemes/Exec.js +15 -15
  114. package/dist/schemes/Exec.js.map +1 -1
  115. package/dist/schemes/ExecOutputScheme.d.ts +3 -2
  116. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  117. package/dist/schemes/ExecOutputScheme.js +9 -0
  118. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  119. package/dist/schemes/Log.d.ts.map +1 -1
  120. package/dist/schemes/Log.js +33 -10
  121. package/dist/schemes/Log.js.map +1 -1
  122. package/dist/schemes/Log.sql +9 -0
  123. package/dist/schemes/_entry-find.d.ts +1 -1
  124. package/dist/schemes/_entry-find.d.ts.map +1 -1
  125. package/dist/schemes/_entry-find.js +16 -9
  126. package/dist/schemes/_entry-find.js.map +1 -1
  127. package/dist/schemes/_entry-manifest.js +3 -3
  128. package/dist/schemes/_entry-manifest.js.map +1 -1
  129. package/dist/schemes/exec-abort.js +2 -2
  130. package/dist/schemes/exec-abort.js.map +1 -1
  131. package/dist/server/Daemon.d.ts +1 -0
  132. package/dist/server/Daemon.d.ts.map +1 -1
  133. package/dist/server/Daemon.js +6 -1
  134. package/dist/server/Daemon.js.map +1 -1
  135. package/dist/server/DrainSupervisor.d.ts +1 -0
  136. package/dist/server/DrainSupervisor.d.ts.map +1 -1
  137. package/dist/server/DrainSupervisor.js +4 -1
  138. package/dist/server/DrainSupervisor.js.map +1 -1
  139. package/dist/server/EnvFunctionality.d.ts +4 -2
  140. package/dist/server/EnvFunctionality.d.ts.map +1 -1
  141. package/dist/server/EnvFunctionality.js +4 -1
  142. package/dist/server/EnvFunctionality.js.map +1 -1
  143. package/dist/server/client-input.d.ts.map +1 -1
  144. package/dist/server/client-input.js +12 -3
  145. package/dist/server/client-input.js.map +1 -1
  146. package/dist/server/drain.sql +10 -9
  147. package/dist/service.d.ts.map +1 -1
  148. package/dist/service.js +5 -31
  149. package/dist/service.js.map +1 -1
  150. package/docs/env.md +22 -0
  151. package/migrations/018_worker_owners.sql +1 -0
  152. package/migrations/019_interactive_owners.sql +1 -0
  153. package/migrations/020_log_projection.sql +1 -0
  154. package/migrations/021_packet_roles.sql +86 -0
  155. package/migrations/022_message_completion.sql +24 -0
  156. package/package.json +16 -14
package/SPEC.md CHANGED
@@ -388,13 +388,14 @@ Maintenance turns create neither lineage nor commons broadcasts. Their loops are
388
388
 
389
389
  §actor-boundary-catalog-preview **Catalog preview.** `PLURNK_SERVICE_FILES_ITEMS`
390
390
  foists turn-0 discovery into the worker's first turn, so a worker opens with a
391
- navigable map instead of blank. Its baseline bodyless FIND surveys follow this
392
- order; unregistered schemes contribute no survey, and workspace capabilities may
391
+ navigable map instead of blank. Its baseline surveys follow this
392
+ order: one READ of the program itself, then bodyless FINDs; unregistered schemes contribute no survey, and workspace capabilities may
393
393
  narrow or omit the reference catalogs under {§capability-admission}.
394
394
 
395
- | Surface | FIND target | Scope / aside |
395
+ | Surface | Target | Scope / aside |
396
396
  | --- | --- | --- |
397
- | Agent Skills | `skill://*/SKILL.md` | `<1,-1>`; {§skills-resources} |
397
+ | This program | READ `ops://<worker>/<loop>/1` | `this program`; the log carries one program verbatim, and every `ops://` turn is shown readable ({§turn-source-resources}) |
398
+ | Agent Skills | FIND `skill://*/SKILL.md` | `<1,-1>`; {§skills-resources} |
398
399
  | Plurnk references: executors, schemes, family managers | `worker:///_plurnk/plurnk/*.md` | `<1,-1>` |
399
400
  | Enabled tools | `worker:///_plurnk/tools/*.md` | `<1,-1>`; configured expansions follow under {§tools-resource-materialization} |
400
401
  | Enabled agents | `worker:///_plurnk/a2a/*.md` | `<1,-1>`; {§a2a-catalog} |
@@ -421,7 +422,7 @@ direct-entry-plus-directory count; `-1` enables the ordinary markerless page;
421
422
  unset / `0` disables previews. `log://` is absent because the current worker's
422
423
  log already renders in present mode.
423
424
 
424
- §worker-initialization-entry **Model-worker initialization is a real `_plurnk` operation turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its program — the READ/FIND surveys, nothing else — is recorded as the turn's `ops://` source and executed through {§op-execution-order} exactly as a model's program is; it authors no reasoning and reads none back. No emission row is fabricated ({§emission-row}): the first request sees the surveys' ordinary results, never an assistant-content copy of the program. The initial message arrives as an inbound SEND in the first model turn ({§message-arrival}); initialization never READs it, and neither initialization nor later turns manufacture a task inventory. Every orienting row is structurally classified `_plurnk` and `init`. The namespace surveys and their asides follow {§actor-boundary-catalog-preview}.
425
+ §worker-initialization-entry **Model-worker initialization is a real `_plurnk` operation turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its program — the READ/FIND surveys, led by one NOTE when the surveys run — is recorded as the turn's `ops://` source and executed through {§op-execution-order} exactly as a model's program is; it authors no reasoning and reads none back. The NOTE keeps the example turn within the card's NOTE-per-turn teaching and reads, exactly, `Surveyed tooling, documentation, extended context, and project root.` No emission row is fabricated ({§emission-row}): the first request sees the NOTE and the surveys' ordinary results, never an assistant-content copy of the program. The initial message arrives as an inbound SEND in the first model turn ({§message-arrival}); initialization never READs it, and neither initialization nor later turns manufacture a task inventory. Every orienting row is structurally classified `_plurnk` and `init`. The namespace surveys and their asides follow {§actor-boundary-catalog-preview}.
425
426
 
426
427
  Incoming messages publish once as inbound SEND rows in the first model turn
427
428
  ({§message-arrival}); initialization neither READs nor archives them. The turn
@@ -621,7 +622,7 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
621
622
  holds under the teaching's own word for handing work out: `## Delegation` is
622
623
  one JSON object, `{"workers": [...], "streams": [...]}`, its unconcluded child
623
624
  workers and its open streams as `{status, path}` pointers (the same shape as
624
- the errors section), just above it. Body-suppressed child activity is durable
625
+ the errors section). Body-suppressed child activity is durable
625
626
  history; this section is the current inventory that keeps an active obligation
626
627
  visible even when no new activity arrived. Each open stream pointer carries
627
628
  elapsed runtime, output inactivity, and its channels' sizes and growth since
@@ -649,7 +650,7 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
649
650
  `## Worker` identity block carries `"parent": "worker://<name>"`, or
650
651
  `"parent": null` at a root, so a worker never infers its rank from silence.
651
652
  - §packet-current-turn **The packet says who and which turn, below the log.** The
652
- `## Worker` block is the first section after the log, carrying
653
+ `## Worker` block, in the status clump below the log ({§packet-cache-monotone}), carries
653
654
  `{"path": "worker://<name>", "parent": <address or null>, "loop": L, "turn": T}`: the actor,
654
655
  whose child it is, and the coordinate this packet's response becomes, so `reasoning://<worker>/L/T`
655
656
  and `ops://<worker>/L/T` are the model's own and `log:///L/T/*` its rows; a model never infers the
@@ -885,7 +886,7 @@ all use that one definition.
885
886
 
886
887
  With live work—an open stream or a live child worker—the loop parks until an
887
888
  ordinary wake or its maximum wait elapses. `PLURNK_SERVICE_WAIT_SEC` supplies the
888
- bound; `WAIT <seconds>` overrides that one park ({§send-wait-scope}). The wake time
889
+ bound; `WAIT [seconds]` overrides that one park ({§send-wait-scope}). The wake time
889
890
  commits atomically with the wait revision, rounded up to the next millisecond.
890
891
  Expiry queues the same loop through normal worker/provider admission; it never
891
892
  cancels work or fabricates a result.
@@ -974,7 +975,7 @@ never replay interrupted effects to reconstruct time. Future messages use
974
975
  the separate schedule contract ({§schedule-delivery}).
975
976
 
976
977
  §worker-message-admission **Recipient selection and admission are one decision.**
977
- An arrival to a worker selects its running loop, otherwise its oldest parked
978
+ An unaddressed arrival to a worker selects its running loop, otherwise its oldest parked
978
979
  loop, otherwise a new queued loop. Compatibility is checked against the exact
979
980
  loop that receives the message; the writer does not reselect another recipient.
980
981
  The worker's admission lock covers selection, compatibility, message admission,
@@ -989,6 +990,15 @@ atomically; no drain may claim partially configured work.
989
990
  | Cancelled as part of the worker scope | Preserve the frame as evidence; never promote it into executable work, including after restart. |
990
991
  | Explicit new arrival after cancellation | Admit under ordinary current worker policy; never revive a terminal loop. |
991
992
 
993
+ §loop-addressed-admission **An explicit Loop recipient never falls back to new work.**
994
+ `runLoop` may name `loopId` alongside its owning `workerId`. Selection requires that
995
+ exact Loop to belong to the Worker and remain queued, running or parked. The inbox
996
+ insert atomically requires the recipient to remain unfinished; completion winning
997
+ that race leaves the message unadmitted. Missing, foreign or terminal recipients
998
+ produce `409 daemon/admission/loop-not-open`, without creating another Loop or
999
+ delivering to a different one. Compatibility checks and wake behavior are the same
1000
+ as ordinary Worker delivery. This is address selection, not a lifecycle policy.
1001
+
992
1002
  §stream-catalog-lifecycle Streams are independently durable subscriptions owned by a worker. Payload and
993
1003
  lifecycle are orthogonal: zero bytes is a valid payload for both success and
994
1004
  failure, while the closed subscription and its status are the terminal fact.
@@ -1094,8 +1104,8 @@ whose obligations settled during reconciliation is requeued in place so it can
1094
1104
  observe their terminal results. No effect is replayed across an unknown
1095
1105
  boundary.
1096
1106
 
1097
- - §worker-lifecycle-single-drain **One drain advances a worker.** At most one drain is registered for a worker at any instant: a `runLoop` request or wake on a worker with a live drain folds in (active→next-turn) or enqueues a loop that drain claims, never a second parallel drain. A drain's start and its empty-queue teardown relinquish the worker under one per-worker lock, so the teardown's re-claim cannot race a concurrent start into a double-drain. Fresh-loop sequence allocation and insertion are one mutation under that same lock; concurrent accepted prompts remain distinct ordered queue items.
1098
- - §worker-lifecycle-total-reap **Cancellation is recursive and reaps every held stream.** `loop.cancel` and worker `KILL` terminalize every unresolved loop in the cancelled worker subtree and iterate each worker's durable open-subscription rows, invoking each exact callable owner from the process-local live registry. The durable rows answer *what is held*; the live registry answers *how this process tears it down*; the abort signal is a fast-path optimization. There is no implicit detachment. Shutdown reaps process-local streams while preserving parked work under {§worker-lifecycle-durable-disposition}. Before shutdown awaits drains, it cancels every process-local proposal waiter through {§proposal-cancel-aborts} with outcome `daemon_stopping`, so a stopped-world dispatch cannot hold teardown open. A stream that is running, mid-spawn (its row written before it is killable), or spawned after the cancel is reaped alike. The teardown abort is bounded: the executor sends a polite signal then SIGKILL after a consumer-set grace (`PLURNK_SERVICE_EXEC_KILL_GRACE_MS`). A model ```` ```KILL [code] ```` on one live stream instead delivers exactly that signal once (bare KILL uses the executor's SIGHUP default; ```` ```KILL [9] ```` uses SIGKILL).
1107
+ - §worker-lifecycle-single-drain **One drain advances a worker.** At most one drain is registered for a worker at any instant: a `runLoop` request or wake on a worker with a live drain folds in (active→next-turn) or enqueues a loop that drain claims, never a second parallel drain. A drain's start and its empty-queue teardown relinquish the worker under one per-worker lock, so the teardown's re-claim cannot race a concurrent start into a double-drain. Fresh-loop sequence allocation and insertion are one mutation under that same lock; fresh loops receive distinct increasing sequence numbers. Recipient selection follows {§worker-message-admission}, not whether callers started concurrently.
1108
+ - §worker-lifecycle-total-reap **Cancellation is recursive and reaps every held stream.** `loop.cancel` and worker `KILL` terminalize every unresolved loop in the cancelled worker subtree and iterate each worker's durable open-subscription rows, invoking each exact callable owner from the process-local live registry. The durable rows answer *what is held*; the live registry answers *how this process tears it down*; the abort signal is a fast-path optimization. There is no implicit detachment. Shutdown reaps process-local streams while preserving parked work under {§worker-lifecycle-durable-disposition}. Before shutdown awaits drains, it cancels every process-local proposal waiter through {§proposal-cancel-aborts} with outcome `daemon_stopping`, so a stopped-world dispatch cannot hold teardown open. A stream that is running, mid-spawn (its row written before it is killable), or spawned after the cancel is reaped alike. The teardown abort is bounded: the executor sends a polite signal then SIGKILL after a consumer-set grace (`PLURNK_SERVICE_EXEC_KILL_GRACE_MS`). A model ```` ```KILL (sh:///stream) [code] ```` on one live stream instead delivers exactly that signal once (without a signal override it uses the executor's SIGHUP default; `[9]` uses SIGKILL).
1099
1109
  - §worker-lifecycle-exec-epoch-bound **A stream's kill binds to the scope it captured at spawn.** A stream captures the worker's cancellation scope as it registers and wires its kill to it, re-checking `aborted` AFTER wiring — no check-then-listen gap can drop an abort that lands mid-registration. Because the scope is replaced only once aborted, a captured-then-replaced scope is necessarily already aborted, so replacement never strands a live stream.
1100
1110
  - §worker-lifecycle-no-resurrection **Cancelled work does not revive its scope.** A cancelled worker cannot be woken by its torn-down streams, stale timers, or cancelled unpublished messages. The evidence remains readable. A `499` result from cancelling only one stream is still a completion owed to a live waiting worker: result status is not proof of worker cancellation. Only an explicit new arrival admits new work after scope cancellation; terminal loops themselves remain immutable.
1101
1111
  - §worker-cancel-trigger **A cancellation is one bound statement.** `lifecycle_cancel_workers` writes the causal cutoff and the cancellation Problem onto every worker of the scope; `workers_cancel_live_loops` (an `INIT` process trigger beside the lifecycle statements, {§db-process-triggers}) retires each worker's live loops inside that statement — 499, waits cleared, message evidence left unchanged, the Problem instanced `loop://<worker>/<sequence>`, `terminated_by = 'cancel'` — so cutoff and cancellation cannot land apart and no value is string-interpolated. Execution consumption is measured by the process-local monotonic timers ({§loop-execution-allowance}) and lands first through `lifecycle_checkpoint_executions`; a wall clock cannot stand in for it, so the timer stays outside the database by design.
@@ -1112,7 +1122,7 @@ boundary.
1112
1122
  - §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. An already-active worker's next packet reads the durable terminal state. Ambient stream closure starts no loop for a concluded worker. The result remains available in the stream's own state under every case.
1113
1123
  - §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.
1114
1124
  - §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.
1115
- - §worker-lifecycle-idle-is-concluded **Idle is not completion.** An empty WAIT continues; an eligible parameterless KILL with observed arrivals and results and no held work concludes under {§wait-obligation-matrix}, with or without an answer body. A concluded worker retains durable history; a later addressed arrival starts a new loop.
1125
+ - §worker-lifecycle-idle-is-concluded **Idle is not completion.** A loop concludes only under {§loop-completion}; an unanswered message remains an obligation even when nothing is running. A concluded worker retains durable history; a later addressed arrival starts a new loop.
1116
1126
  - §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.
1117
1127
  - §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.
1118
1128
  - §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.
@@ -1190,7 +1200,7 @@ These are the complete strike sources:
1190
1200
  |---------------------|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|
1191
1201
  | Hard result | An admitted non-execution operation or bounded parse-error status is `>= 400`, except the soft set `404`, `409`, `416`, `425`, `501`, in a turn where no operation succeeded ({§strike-progress-immunity}). | The originating failure row. |
1192
1202
  | Cycle | The executed operations and their observed results repeat under {§engine-cycle-evidence}. | None; cycle detection itself is private engine accounting. |
1193
- | Empty turn | An admitted turn with no authored response operation ({§empty-turn}). | The turn's `422` error row. |
1203
+ | Empty turn | An operation-free turn with unresolved messages or incomplete emission evidence ({§empty-turn}). | The turn's `422` error row. |
1194
1204
 
1195
1205
  Execution results remain exact model-visible evidence but are always soft: an
1196
1206
  executor error is not a PLURNK contract violation. Cycle detection remains an
@@ -1250,7 +1260,7 @@ failures keep their exact rows, but the turn counts as progress — it earns no
1250
1260
  and clears the streak. A successful operation is any admitted operation that acts on the
1251
1261
  task — executions included — whose result status is `< 400`. Operations that steer the
1252
1262
  loop never qualify: NOTE (it cannot fail; reasoning NOTEs are filed as NOTEs, and outside
1253
- text is no operation at all, {§outside-text}), WAIT, a parameterless KILL and a targetless SEND; a turn
1263
+ text is no operation at all, {§outside-text}), WAIT and a targetless SEND; a turn
1254
1264
  of failures beside a WAIT still strikes. The cycle source is not exempted: a repeating
1255
1265
  turn's operations succeed by construction, and the backstop exists to catch exactly
1256
1266
  that ({§engine-cycle-evidence}).
@@ -1354,7 +1364,7 @@ The parser owns its boundaries; core admits determinate work and exposes its fai
1354
1364
  | Lost boundary before any closed operation | Reject the attempt; outside text is no substitute for a closed operational statement. An admitted reasoning operation is one ({§reasoning-operations}). |
1355
1365
  | Outside text carrying a log-entry heading, other than an emission row's | Reject the attempt ({§fabricated-log-entry}). |
1356
1366
 
1357
- §fabricated-log-entry **Only the harness writes the log.** A line of outside response text that begins with a log-entry heading, `### log:///<loop>/<turn>/<sequence>/` ({§log-wire-format}), is the model continuing the packet's transcript instead of answering it: it writes the receipts it expects and then acts on them. The attempt is rejected under {§invalid-emission-attempts}, so neither that text nor any operation beside it runs or is stored as outside text ({§outside-text}), and its one diagnostic, at the heading's line, reads `` `### log:///2/1/5/READ` is a log entry, and only the harness writes the log. `` Text inside an operation body is not examined, so a SEND or KILL may quote a receipt. A heading whose leaf is `emission` is exempt: it names the worker's own source ({§emission-row}), and repeating it invents no receipt, so the attempt is admitted and the heading stays outside text, counted by the digest as an echo. In 10,486 recorded emissions, 101 carried such a heading in outside text, every one a fabrication: 85 of 1,675 from deepseek-flash, 81 of them opening with one, and 16 from glm-5.3-flash, deepseek-v4-pro and qwen3.8-flash, which appended an invented `## Log` after their own operations.
1367
+ §fabricated-log-entry **Only the harness writes the log.** A line of outside response text that begins with a log-entry heading, `### log:///<loop>/<turn>/<sequence>/` ({§log-wire-format}), is the model continuing the packet's transcript instead of answering it: it writes the receipts it expects and then acts on them. The attempt is rejected under {§invalid-emission-attempts}, so neither that text nor any operation beside it runs or is stored as outside text ({§outside-text}), and its one diagnostic, at the heading's line, reads `` `### log:///2/1/5/READ` is a log entry, and only the harness writes the log. `` Text inside an operation body is not examined, so a SEND or KILL may quote a receipt. A heading whose leaf is `emission` is exempt: it names the worker's own source ({§emission-row}), and repeating it invents no receipt, so the attempt is admitted and the heading is dropped from the text beside the operations ({§outside-text}), counted by the digest as an echo. In 10,486 recorded emissions, 101 carried such a heading in outside text, every one a fabrication: 85 of 1,675 from deepseek-flash, 81 of them opening with one, and 16 from glm-5.3-flash, deepseek-v4-pro and qwen3.8-flash, which appended an invented `## Log` after their own operations.
1358
1368
 
1359
1369
  Warnings and closer recovery ({§closer-fallback}) do not reject. `finish=length`
1360
1370
  discloses truncation and precludes completion; it is not independently a rejection.
@@ -1457,10 +1467,9 @@ unrelated suffixes.
1457
1467
  does nothing with it (#588).** `PLURNK_PROVIDERS_GBNF[_<alias>]` is a file
1458
1468
  path — absolute, `~`-relative, or relative to the daemon's working directory —
1459
1469
  whose text is read once per daemon and handed to the provider verbatim
1460
- ({§provider-grammar-transport}). The service ships no grammar profile: a bare
1461
- name with no path separator is refused with an error that says so, and an
1462
- unreadable file fails the constrained generation loudly; neither ever silently
1463
- becomes unconstrained. Nothing generates, validates, or grades a grammar, and
1470
+ ({§provider-grammar-transport}). A filename without a path separator is relative
1471
+ to the daemon's working directory too. An unreadable file fails the constrained
1472
+ generation; it never silently becomes unconstrained. Nothing generates, validates, or grades a grammar, and
1464
1473
  no effort is implied by one. The turn records transport as evidence:
1465
1474
  `railsAttached: "client"` when the provider reports it sent the grammar, or
1466
1475
  `"withheld"` when it reports it did not ({§provider-grammar-evidence}); there
@@ -1658,7 +1667,7 @@ Registration precedes loop affinity:
1658
1667
  | Registered but inactive under flag | The flag gate returns `403 scheme-unavailable`. |
1659
1668
  | Registered and active | Dispatch continues to the operation owner. |
1660
1669
 
1661
- - §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.
1670
+ - §op-execution-order **An admitted turn is an ordered program.** Model, client, and harness operations execute in authored order. 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 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.
1662
1671
 
1663
1672
  §bare-inference **BARE is isolated, synchronous retrieval over the durable child-provider policy.**
1664
1673
 
@@ -1953,7 +1962,7 @@ Client-interface target parameters carry fragments inline (`{ target: "sh:///a3b
1953
1962
  MOVE out of it are 400 `channel-derived`; COPY from it is an ordinary read. Binary sources
1954
1963
  keep {§membership-source-projection}, where the source is not text and the projection is the
1955
1964
  body; a fetched web page keeps its scheme's own two channels ({§html-materialization}).
1956
- - §channel-selection-visibility **Channel selection is decision-time information, not a guess** — every multi-channel resource presents its channels with extents wherever FIND presents the resource: broad results list each channel's path, projection `mimetype`, tokens, and lines (default channel first), and matcher locations name the channel their line coordinates address. A READ of a multi-channel resource names its other channels with their tokens in `channels`, keyed by the fragment the model appends (`{"#readable": 812}`), so first contact — a fetched page, a stream's stdout — carries the same choice without a listing; a single-channel resource names none. When the default channel is a readable projection of a differently typed source, it also names `sourceMimetype` once; this is representation evidence, not a different READ workflow. The packet never presents channels as equal and indistinguishable; extents derive from the stored channels by construction. Budget enforcement stays with {§context-fit} — this is information, not a second guard.
1965
+ - §channel-selection-visibility **Channel selection is decision-time information, not a guess** — every multi-channel resource presents its channels with extents wherever FIND presents the resource: broad results list each channel's path, projection `mimetype`, tokens, and lines (default channel first), and a matcher location names the channel its line coordinates address whenever that is not the resource's default channel. A READ of a multi-channel resource names its other channels with their tokens in `channels`, keyed by the fragment the model appends (`{"#readable": 812}`), so first contact — a fetched page, a stream's stdout — carries the same choice without a listing; a single-channel resource names none. When the default channel is a readable projection of a differently typed source, it also names `sourceMimetype` once; this is representation evidence, not a different READ workflow. The packet never presents channels as equal and indistinguishable; extents derive from the stored channels by construction. Budget enforcement stays with {§context-fit} — this is information, not a second guard.
1957
1966
 
1958
1967
  ### §channel-state Channel state — metadata, not gating
1959
1968
 
@@ -2267,7 +2276,7 @@ AST: `{ op: "KILL", target, matcher: MatcherBody | null, lineMarker: TextLineMar
2267
2276
 
2268
2277
  §log-kill-distillation **A log KILL may say what it keeps.** A body on a `log:///` KILL is the model's distillation of what the KILL retires. Whatever the kill's outcome, the body lands as the model's own NOTE row at the next sequence of the same turn — written after the kill's receipt, so it never falls inside the kill's own selection — carrying `attrs.distilled` with the KILL's target as written, so a distillation is distinguishable from a free NOTE while it renders, weighs and curates exactly as one; the dispatch reports two rows written. A kill that misses keeps its distillation beside its visible receipt: what the model wrote about its environment is recorded for the model to possess and retire, never dropped for where the kill aimed. A whitespace-only body is a plain KILL. The kill's own receipt stays hidden as any successful log KILL's does ({§context-verbs}).
2269
2278
 
2270
- 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. An emission row is curated whole ({§emission-row}): a scope covering every line retires it like an unscoped KILL; on its exact coordinate a narrower scope is 422 `emission-curated-whole`, whose recovery names both forms that retire it; a sweep leaves it intact. 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}).
2279
+ 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. An emission row is curated whole ({§emission-row}): the unscoped KILL retires it; a line scope on its exact coordinate addresses its legend and retires the NOTEs on the lines it selects, the row staying; on a row with no legend lines the scope is 422 `emission-curated-whole`, whose recovery names the unscoped KILL; a sweep leaves it intact. 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}).
2271
2280
 
2272
2281
  §log-scope-recovery A log-body scope follows the file slicer's range rule ({§range-starts-at-one} in the schemes SPEC): a range starting at 0 — `<0,-1>` included — is refused 416 `range-not-satisfiable` on every body, empty ones too, and never clamped; its detail is the slicer's own sentence, `Range <0,-1> starts at 0, which is not a line; lines are numbered from 1.`, and its recovery names the forms a log body takes — `Trim one line with <L> or lines L through M with <L,M>; KILL (log:///1/9/2/READ) with no scope retires the whole row.` — never the insert and append positions a body cannot take. Every other scope that names no line is 400 `curation-scope-invalid` with the same recovery: the forms that work on that row, never a rebuild of the written scope ({§diagnostic-observation}).
2273
2282
 
@@ -2277,7 +2286,7 @@ A READ carrying active native media is atomic: any KILL scope is ignored and the
2277
2286
 
2278
2287
  | Fact | Owner | Effect |
2279
2288
  | --- | --- | --- |
2280
- | Initial body suppression | Immutable event `initial_folded` | Packet presentation only; explicit retrieval can read an initially hidden body. An emission row remains folded; its program is separately eligible for {§previous-emission}. |
2289
+ | Initial body suppression | Immutable event `initial_folded` | Packet presentation only; explicit retrieval can read an initially hidden body. An emission row remains folded; its program is separately eligible for {§emission-history}. |
2281
2290
  | Deliberate scoped KILL | Current projection `folded`, initially empty | Packet, READ, FIND, COPY, and search omit those lines; later retrieval cannot undo trimming. |
2282
2291
 
2283
2292
  Packet display combines both masks. Other consumers use only deliberate trimming.
@@ -2315,7 +2324,7 @@ The `## Log` section is a sequence of ordinary Markdown records separated by one
2315
2324
  | facts | One strict JSON object in stable alphabetical order. | Present only when a fact exists. Asides, scopes, opaque invocation metadata and result facts belong here, not on the H3. |
2316
2325
  | body | Coordinate-prefixed lines. | Present when the row is visible. |
2317
2326
 
2318
- An emission row's body is not in its record ({§emission-row}); the optional previous program follows the user footer ({§previous-emission}). Patterns retain their literal spelling; a pattern containing a line break is JSON-quoted to keep the H3 on one physical line. Receipts are descriptive records, not reconstructed operation headings. 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.
2327
+ An emission row's body is not in its record ({§emission-row}); its eligible program follows it as a separate assistant message ({§emission-history}). Patterns retain their literal spelling; a pattern containing a line break is JSON-quoted to keep the H3 on one physical line. Receipts are descriptive records, not reconstructed operation headings. 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.
2319
2328
 
2320
2329
  §log-address-metadata **Addresses name their relationship, not the row's producer.**
2321
2330
 
@@ -2359,7 +2368,9 @@ cropping ({§packet-attachment-parts}).
2359
2368
 
2360
2369
  Retrieval results omit redundant requested coordinates; durable results and
2361
2370
  submitted programs retain them. Failed selections keep requested coordinates
2362
- and available extent in their owning Problem. Projection never parses its
2371
+ and available extent in their owning Problem; a channel READ that carries its
2372
+ execution's failure retrieved successfully and formats its extent like any
2373
+ other. Projection never parses its
2363
2374
  display strings to recover typed facts. A hidden body has no `preview`; a
2364
2375
  complete non-retrieval body retains `lines` where no other field supplies its
2365
2376
  navigable extent. None of these spellings changes acquisition, delivery,
@@ -2382,8 +2393,11 @@ Authored `metadata` retains its opaque ordered block strings under {§scheme-met
2382
2393
  byte sequence once; the result's `nativeContentHash`, enforced by the log's foreign key, identifies it.
2383
2394
  This is retained evidence, not a separate visibility or delivery lifecycle. Source mutation/deletion
2384
2395
  cannot change a retained observation. Explicit READ of its still-active log source can acquire the same media again.
2385
- Every compatible-model packet includes one file part per retained, admitted READ observation, after the
2386
- packet text, in observation order, each preceded by a text part that names the observation's log
2396
+ Every compatible-model packet includes one file part per retained, admitted READ observation, directly
2397
+ after the user section ending at that READ record, in observation order. The attachment retains that
2398
+ section's name in request evidence; later log records or emissions never move ahead of it. Packets
2399
+ stored without a section binding retain their recorded whole-log placement. Each file part is
2400
+ preceded by a text part that names the observation's log
2387
2401
  coordinate, source path and projection facts and states that the bytes are that READ's own, retained
2388
2402
  until its row is KILLed: an uncaptioned native part on the user turn reads as a fresh arrival (#899).
2389
2403
  Model-response settlement never consumes an observation. KILL follows
@@ -2397,7 +2411,7 @@ Authored `metadata` retains its opaque ordered block strings under {§scheme-met
2397
2411
  records the exact READ coordinates sent without controlling retention. Missing immutable bytes are an
2398
2412
  internal integrity failure, never silently dropped content. No ejection message or permanent teaching is
2399
2413
  added. These stable curation weights are not provider-token measurements ({§tokenomics-render-weight-budget}).
2400
- - §packet-token-accounting Every row reports one `tokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, facts, visible body and selected native attachment. The previous-emission section is charged separately as user-slot text ({§previous-emission}). The completed record is measured to a fixed point, including the accounting field itself. 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}.
2414
+ - §packet-token-accounting Every row reports one `tokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, facts, visible body and selected native attachment. The emission-history section is charged separately as assistant-message text ({§emission-history}). The completed record is measured to a fixed point, including the accounting field itself. 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}.
2401
2415
 
2402
2416
  ### §retrieval-packet-metadata READ/FIND packet metadata
2403
2417
 
@@ -2448,25 +2462,25 @@ single line past the end, a reversed range, empty content, a command's log row
2448
2462
  ### §emission-row The emission row
2449
2463
 
2450
2464
  Every admitted content emission is announced by one curatable row of its own turn.
2451
- The most recent eligible program supplies {§previous-emission}; older programs remain readable.
2465
+ Eligible programs supply {§emission-history}; every source remains readable regardless of replay.
2452
2466
 
2453
2467
  | Surface | Contract |
2454
2468
  |---|---|
2455
2469
  | When | An inference turn that admitted at least one content statement. Reasoning-only turns, including initialization ({§worker-initialization-entry}), a programmatic batch, an empty turn ({§empty-turn}), a client operation and a rejected attempt ({§rejected-emission-entry}) announce nothing. |
2456
2470
  | Place | After the turn's inputs (arrivals, deltas, open-path READs) and before its reasoning NOTEs and operations, written after the selection snapshot ({§turn-ops-selection-snapshot}): the emission sits between what the worker had seen and what it caused. |
2457
2471
  | Row | A `_plurnk` READ of the turn's own source, `ops://<worker>/L/T`, with `attrs.kind="emission"` and the canonical leaf `/emission`: `### log:///L/T/S/emission → ops://<worker>/L/T · N`. It renders its author, the turn's producer, as `origin`, so a model's row carries none. It is no operation: no receipt, tool call or strike, and outside the op mix. |
2458
- | Body | Frozen at announcement: the canonical rendering ({§statement-rendering}) of the admitted content statements, each whole in a closed fence. All heading operands, scopes, metadata, patterns and asides remain. Free text and unadmitted forms are absent; a recovered native call ({§native-tool-calls}) appears as the operation it was read as; an operation whose receipt failed stays. Reasoning operations retain their own source and normal receipts, never an assistant-content copy. No body text is inspected for nested operations. |
2459
- | Wire | The record appears in the log; its complete program is eligible for {§previous-emission}. No operation family or body is filtered. Dispatch and the immutable `ops://` source keep complete bodies ({§turn-source-resources}); an explicit READ returns them. |
2472
+ | Body | Frozen at announcement: the canonical rendering ({§statement-rendering}) of the admitted content statements, each whole in a closed fence, text beside them as the NOTEs it became ({§outside-text}). All heading operands, scopes, metadata, patterns and asides remain. Unadmitted forms are absent; a recovered native call ({§native-tool-calls}) appears as the operation it was read as; an operation whose receipt failed stays. Reasoning operations retain their own source and normal receipts, never an assistant-content copy. No body text is inspected for nested operations. |
2473
+ | Wire | The record appears in the log; its complete program supplies the readback projection in {§emission-history}. The frozen body and immutable `ops://` source keep every operation and body ({§turn-source-resources}); an explicit READ returns them. |
2460
2474
  | Stability | The projection is fixed from its first appearance, never aged or resized under budget pressure. Already frozen announcements and historical request captures are not rewritten. |
2461
- | Presentation | Born folded: the log record shows its header, never an assistant message. |
2462
- | Accounting | The row's `tokens` charges only its rendered record. The optional previous-emission section is measured once as user-slot text ({§packet-token-accounting}); replacing it never changes older row weights. An explicit source READ has its own ordinary charge. |
2463
- | Curation | Curated whole ({§log-kill-scope}): KILL retires it, and so does a scope covering every line (`<1,-1>`); on its exact coordinate a narrower scope is 422 `emission-curated-whole`, and a sweep whose scope would only trim it leaves it intact. |
2475
+ | Presentation | Born folded: the log record shows its header, never an assistant message. When its turn is replayed ({§emission-history}), the record's lines are the legend of that turn's NOTEs, one numbered line per NOTE with its `log:///` path and weight, and those NOTE rows render nowhere else. |
2476
+ | Accounting | The row's `tokens` charges only its rendered record, legend included. The optional emission-history section is measured once as assistant-message text ({§packet-token-accounting}); replacing it never changes older row weights. An explicit source READ has its own ordinary charge. |
2477
+ | Curation | Curated whole ({§log-kill-scope}): the unscoped KILL retires it. A line scope on its exact coordinate addresses the legend: the NOTEs on the selected lines retire and the row stays; on a row with no legend lines the scope is 422 `emission-curated-whole`, whose recovery names the unscoped KILL; a sweep whose scope would only trim it leaves it intact. |
2464
2478
  | Schema | Migration 12 admits `kind="emission"` only on this shape: one per turn, the turn's newest row when written, frozen, and curated whole; it backfills no announcement for earlier turns. FORK copies it with the inherited turns, still naming its writer. |
2465
2479
  | Echoes | A worker that repeats the heading in its own text is tolerated ({§fabricated-log-entry}); the digest counts the echoes. |
2466
2480
 
2467
2481
  ### §reasoning-row The reasoning row
2468
2482
 
2469
- The model's memory of its own reasoning, behind `PLURNK_SERVICE_REASONING_ROWS` (default `1`):
2483
+ The model's optional memory of its own reasoning, behind `PLURNK_SERVICE_REASONING_ROWS` (default `0`):
2470
2484
  when it is `1`, every model turn that reasoned lands its reasoning as one row of its
2471
2485
  own, `log:///<loop>/<turn>/<sequence>/reasoning → reasoning://<worker>/<loop>/<turn>`, the harness's
2472
2486
  READ of the turn's reasoning source, immediately before the turn's emission row (or its first
@@ -2477,10 +2491,10 @@ reads what the model thought and where its content program can be found
2477
2491
  | Concern | Rule |
2478
2492
  |---|---|
2479
2493
  | Room | Admission occurs after all mandatory turn rows, including the emission and diagnostics, using the remaining room under {§context-fit}. Its earlier chronological coordinate is reserved without inserting a placeholder; if it does not fit, that coordinate remains unused. Nothing else changes: no partial preview, refusal, or other row touched. Reasoning-only and empty model turns follow the same rule; content operations are not required. |
2480
- | Body | The model's own text when it fits the row's page — `PLURNK_SERVICE_REASONING_TRAILING_LINES` lines, unset meaning the shared `PLURNK_SERVICE_PREVIEW_LINES`, within `PLURNK_SERVICE_PREVIEW_CHARS` — and otherwise its **last page**. Keep complete final lines where possible; if the last line alone exceeds the character bound, select its suffix with the ordinary exact column scope. Unicode code points count once and CRLF is one indivisible separator, as in {§body-projection}. The statement carries the scope it took and the receipt its `range` ({§packet-extent-metadata}); the complete reasoning stays readable at its address by any scope ({§turn-source-resources}). |
2494
+ | Body | `PLURNK_SERVICE_REASONING_TRAILING_LINES=-1` selects the complete reasoning without either shared preview bound. A positive value selects that many trailing lines within `PLURNK_SERVICE_PREVIEW_CHARS`; unset/empty uses `PLURNK_SERVICE_PREVIEW_LINES`. Zero is invalid. Keep complete final lines where possible; if the last line alone exceeds the character bound, select its suffix with the ordinary exact column scope. Unicode code points count once and CRLF is one indivisible separator, as in {§body-projection}. The statement carries the scope it took and the receipt its `range` ({§packet-extent-metadata}); the complete reasoning stays readable at its address by any scope ({§turn-source-resources}). This setting does not change ordinary READ/FIND previews. |
2481
2495
  | Weight | Charged like any row, visible in the gauge and its `largest` ({§context-gauge}). |
2482
2496
  | Curation | The verbs alone: a KILL retires it like any row ({§context-verbs}); the daemon reorders nothing and un-bodies nothing on its account. |
2483
- | Absence | Means no room or no reasoning; the model tells them apart by reading `reasoning://` for the turn. |
2497
+ | Absence | Disabled, no room, or no reasoning. The setting does not affect reasoning-operation admission or the readable `reasoning://` source ({§reasoning-operations}, {§turn-source-resources}). |
2484
2498
 
2485
2499
  ### §turn-source-resources Immutable turn-source resources
2486
2500
 
@@ -2499,7 +2513,7 @@ reads what the model thought and where its content program can be found
2499
2513
 
2500
2514
  - §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, `/emission` for an admitted one's announcement ({§emission-row}). 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`, `log:///**/attempt`, and `log:///**/emission` 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 its emission's announcement, then the model's operations ({§packet-current-turn} names `L/T`).
2501
2515
  - §log-near-miss **A log miss beside rows that exist names them.** A READ, FIND or KILL of an exact coordinate that names no row carries a recovery from the worker's own active rows: the turn's rows carrying the leaf written come first, since the leaf is what the model asked for and the sequence its guess, followed by the row at that coordinate under its own leaf (`` Turn 1/44's reasoning is `log:///1/44/2/reasoning`; the entry at log:///1/44/1 is `log:///1/44/1/READ`. ``); with no row of that leaf, the row at the coordinate alone (`` The entry at log:///1/25/8 is `log:///1/25/8/sh`. ``), else the turn's rows, at most six named, else the loop's latest turn. A coordinate in a loop with no rows carries none. Recorded misses were near misses every time: a READ of `1/25/8/READ` when the row was `sh`, an EDIT one sequence off, and a KILL under the 413 that must curate (#1005).
2502
- - §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 and retires its emission ({§emission-row}). 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}).
2516
+ - §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 and retires its emission ({§emission-row}). A **well-formed selection that matches nothing is 204 with `matched: 0`**; a successful sweep's rx carries `matched: N`.
2503
2517
  - §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. An emission row is curated whole instead: the scope retires it when it covers every line and otherwise leaves it ({§emission-row}). Thus ```` ```KILL (log:///**/READ) <17,-1> ```` may change long READs and no-op on short ones while reporting every selected row in `matched`.
2504
2518
 
2505
2519
  §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:
@@ -2574,7 +2588,7 @@ per-operation projection on `rx`; the aggregate remains inside dispatch.
2574
2588
  | `unit`, `before`, `after` | `extent` | Whole-line batches use line counts. A batch containing any exact four-coordinate edit uses Unicode code-point counts. |
2575
2589
  | `parseIssues.before`, `parseIssues.after` | `parseIssues` as `before→after` | Parser-recovery counts for complete source and landed revisions; omitted when both are clean or either is unavailable. |
2576
2590
  | `effect.source`, `result` | `effect` as `<source> -> <result>` | Resolved scopes mapping the source snapshot into the landed body; the admitted marker stays in durable `requested` and `tx`. |
2577
- | `effect.removed`, `inserted` | `change` | Removed and inserted counts in the receipt unit. |
2591
+ | `effect.removed`, `inserted` | `change` | Removed and inserted counts led by the receipt unit, as `extent` is: `lines -7 +7`. |
2578
2592
  | `effect.removedText` | `removed` | {§edit-receipt-removed-text}: a pure deletion's removed text, its first `PLURNK_SERVICE_EDIT_RECEIPT_REMOVED_LINES` lines; absent when the edit inserted anything. |
2579
2593
  | `effect.context` | Canonical row body | Numbered physical lines at each landed boundary, bounded symmetrically by `PLURNK_SERVICE_EDIT_RECEIPT_CONTEXT_LINES`. A pattern batch's `last` context follows the first's when it differs, with no blank line between: every line of a row body carries its coordinate. |
2580
2594
  | `disposition`, `requested` | `disposition`, `requested` | A reviewer-replaced batch preserves the authored marker while stating that its attributed effect was superseded. |
@@ -2754,8 +2768,8 @@ Log history preserved — `log_entries` stores path tuple as text, not FK to `en
2754
2768
  with no addressable location is status 200 with `matchingPathCount: 1`,
2755
2769
  `matchLocationCount: 0`, and no fabricated row; a matcher selecting no
2756
2770
  resource is 204. A matcher-less broad empty catalog survey is status 200; an
2757
- absent exact resource is 404. Every entry-channel location names its `channel`
2758
- ({§channel-selection-visibility}); log rows carry none.
2771
+ absent exact resource is 404. Every entry-channel location in `results` names
2772
+ its `channel`; log rows carry none.
2759
2773
 
2760
2774
  Inside `FindResult`, `matchingPathCount` and `matchLocationCount` describe the
2761
2775
  complete selection before pagination; the packet curates those facts under
@@ -2774,9 +2788,11 @@ Log history preserved — `log_entries` stores path tuple as text, not FK to `en
2774
2788
  code points including a visible terminal ellipsis, so a row stays one line
2775
2789
  of orientation; an invocation-form witness — a summary that is one fenced
2776
2790
  operation, the shape a runtime's tool summary takes
2777
- ({§tools-resource-materialization}) — is shown whole, every tool named,
2778
- because the discovery row exists so the model can invoke without a READ and
2779
- a menu that is cut is no menu. Absent metadata is omitted.
2791
+ ({§tools-resource-materialization}), kept on one summary line by writing each
2792
+ newline as `\n` — is shown whole, every tool named and its newlines restored
2793
+ so the row's JSON escapes each once, because the discovery row exists so the
2794
+ model can invoke without a READ and a menu that is cut is no menu. Absent
2795
+ metadata is omitted.
2780
2796
 
2781
2797
  Resource-level `stream` and broad-match
2782
2798
  `matchLocationCount` live only on `[0]`. A single-channel resource is therefore
@@ -2794,11 +2810,15 @@ Log history preserved — `log_entries` stores path tuple as text, not FK to `en
2794
2810
  rank for `~`full-text and candidate order otherwise; location order is dialect
2795
2811
  order and exact duplicates deduplicate. The intended drill-down is broad FIND
2796
2812
  to choose paths, exact-target FIND to choose locations, then exact READ.
2797
- `content` uses the shared generated-JSON projection and translates only this
2798
- final model-facing representation from `weight` to `tokens`
2799
- ({§json-result-rendering}), so universal packet numbering makes result
2800
- ordinal N addressable as line N, matching `<N>` pagination without a second
2801
- coordinate system. A returned page begins at `range.returned[0]`, and every
2813
+ `content` uses the shared generated-JSON projection ({§json-result-rendering}),
2814
+ so universal packet numbering makes result ordinal N addressable as line N,
2815
+ matching `<N>` pagination without a second coordinate system. It translates
2816
+ only this final model-facing representation: `weight` reads `tokens`, a
2817
+ `region` or `enclosingRegion` reads in the one scope notation `<SL,SC,EL,EC>`
2818
+ ({§packet-extent-metadata}), and a location names its `channel` only when that
2819
+ is not the resource's default channel ({§channel-selection-visibility}). A
2820
+ location therefore reads `{"region":"<48,1,48,25>","matched":"class BaseCrossValidator"}`.
2821
+ A returned page begins at `range.returned[0]`, and every
2802
2822
  page left-pads its ordinals to the decimal width of `range.total`; content
2803
2823
  therefore keeps one stable column across the complete result set. Pagination is the only FIND materialization bound; no
2804
2824
  hidden complete row or location collection is retained behind the public
@@ -2808,8 +2828,56 @@ Log history preserved — `log_entries` stores path tuple as text, not FK to `en
2808
2828
 
2809
2829
  SEND AST: `{ op: "SEND", target: ParsedPath | null, body: SendBody | null, metadata, lineMarker }`.
2810
2830
 
2811
- - **Message:** SEND delivers to an actor, endpoint or exact message address. Targetless SEND answers observed Open Messages.
2812
- - **Workflow:** WAIT yields. Parameterless KILL requests successful completion ({§kill-conclusion}). NOTE retains memory.
2831
+ - **Message:** SEND delivers to an actor, endpoint or exact message address. Targetless SEND selects the oldest published Open Message. Only explicit completion metadata resolves a message ({§message-completion}).
2832
+ - **Workflow:** WAIT yields. The loop concludes from resolved messages, settled work and observed results ({§loop-completion}). NOTE retains memory; KILL names something to cancel or curate.
2833
+
2834
+ §message-completion **Reply delivery and message completion are distinct.**
2835
+
2836
+ | Reply metadata | Delivery | Message obligation |
2837
+ |---|---|---|
2838
+ | No completion code | Deliver the authored text and attachments | Remains open |
2839
+ | `[200]` | Deliver the final answer | Completed |
2840
+ | `[499]` | Deliver the cancellation explanation | Cancelled; no worker or execution is cancelled implicitly |
2841
+
2842
+ The numeric modifier belongs to SEND's reply metadata, not its text scope. It
2843
+ composes with attachment metadata. Completion applies only to replies: an exact
2844
+ message address selects that message. Targetless SEND selects the oldest published
2845
+ Open Message in its loop at dispatch time. Progress leaves it open; `[200]` or
2846
+ `[499]` resolves it, so the next targetless SEND selects the next Open Message.
2847
+ With none open, a targetless SEND is speech to the loop's latest published message: it is
2848
+ delivered to that message's originating client and recorded in `answers`, and a completion
2849
+ code on it changes no outcome. Only a loop with no published message refuses it. It never
2850
+ broadcasts; a correction that changes an outcome names the message explicitly. Empty completion replies
2851
+ resolve their selected messages without inventing speech or erasing an earlier
2852
+ answer. An empty addressed progress reply adds no speech. Failed delivery resolves nothing.
2853
+ The latest explicit completion reply determines each message's outcome; ordinary
2854
+ progress replies never reopen a completed message. Curation changes neither
2855
+ delivery nor completion. Replies and ambient observations do not become requests.
2856
+
2857
+ Completion replies execute in authored order, including alongside mutations and
2858
+ other replies. Their bodies are delivered immediately, never held as drafts to
2859
+ replay. Later results can require further work or a corrected answer without
2860
+ retracting an earlier delivery. The message outcome is distinct from the SEND
2861
+ operation's delivery status and from the loop's execution outcome.
2862
+ After all obligations settle, the loop succeeds if any message completed; it is
2863
+ cancelled only when every message was cancelled. This does not invoke worker-tree
2864
+ cancellation. Engine failures retain their own outcomes.
2865
+
2866
+ §loop-completion **The loop concludes from discharged obligations, not a terminating operation.**
2867
+ A model loop is eligible only when all its messages have explicit completion
2868
+ replies, every held child and non-detached stream has settled, and every required
2869
+ result has crossed a packet boundary. New arrivals guard the terminal transition
2870
+ atomically. An operation-free turn creates no additional observation obligation;
2871
+ it is neither a completion command nor a separate acknowledgement mode. NOTE and
2872
+ successful curation retain the observation exemptions in {§send-premature-terminate}.
2873
+ With unresolved messages, no-operation recovery still applies. Malformed emissions,
2874
+ known output truncation, omitted operations and provider failures cannot conclude
2875
+ the loop by absence of operations. Administrative programs close only their own
2876
+ transaction.
2877
+
2878
+ When all messages are resolved but new results require another packet, the engine
2879
+ reports only: `All Open Messages resolved. Review new results; emit no OPs if finished.`
2880
+ The notice creates no state and does not demand another final reply.
2813
2881
 
2814
2882
  §worker-obligations A worker holds its unresolved children and open non-detached
2815
2883
  streams (`worker_obligations`); `loop_obligations` names them per loop. The
@@ -2823,19 +2891,19 @@ same durable liveness.
2823
2891
  | Worker or loop already cancelled/terminal | Preserve that result. |
2824
2892
  | Administrative program | Finish its transaction without adjudicating another model loop's work. |
2825
2893
  | New unpublished message | Continue; publish it in the next packet. |
2826
- | Fresh operation/parser failure, without an authored WAIT | Continue before any automatic parking. |
2827
- | Neither an authored WAIT nor an eligible completion request ({§kill-conclusion}) | Continue, regardless of earlier replies or live work. |
2828
- | Live work and either WAIT or an eligible completion request | Park the same loop; message arrival, child or stream settlement, or wait expiry wakes it ({§worker-wait-timing}). No final-answer body is delivered while joining. |
2829
- | WAIT without live work | Continue; never invent a future wake. Its row says only `Nothing is in flight. Continuing.`, however often the loop yields this way. |
2894
+ | Fresh operation/parser failure or incomplete emission, without an authored WAIT | Continue before any automatic parking. |
2895
+ | Authored WAIT and live work | Park the same loop; message arrival, child or stream settlement, or wait expiry wakes it ({§worker-wait-timing}). |
2896
+ | Fresh failure or incomplete emission after an empty WAIT | Continue; the WAIT cannot conceal the failure. |
2897
+ | Any unresolved message | Continue; an operation-free turn receives {§empty-turn} recovery. |
2830
2898
  | Unobserved operation results, failures, child results or stream conclusions | Continue; the next packet presents them. |
2831
- | Eligible completion request with no unpublished arrivals, live work or unobserved results | Conclude successfully, whether or not it delivers an answer. |
2899
+ | All messages resolved and results observed, live work remains | Join that work with the configured bounded park. Replies remain delivered. |
2900
+ | All messages resolved, results observed, no live work | Conclude with the aggregate message outcome ({§message-completion}). |
2832
2901
 
2833
2902
  An empty emission is handled by {§empty-turn}. Ordinary strikes, cycles and
2834
- execution limits remain independent. NOTE and successful targeted KILL do not themselves
2835
- require another observation turn, but neither requests completion. Failed KILL
2836
- and every other operational result require observation.
2903
+ execution limits remain independent. Observation exemptions follow
2904
+ {§send-premature-terminate}; they never resolve a message implicitly.
2837
2905
 
2838
- §loop-response-messages **A response is a recorded delivery.** A successful SEND reply or admitted final KILL answer records
2906
+ §loop-response-messages **A response is a recorded delivery.** A successful SEND reply records
2839
2907
  the exact message addresses it answers. All replies remain independently recoverable in
2840
2908
  message history, in execution order, regardless of producer. An actor-addressed SEND that
2841
2909
  does not answer a message, WAIT, NOTE, asides, inherited rows and ambient observations are
@@ -2862,69 +2930,52 @@ accounting and model-visible failure evidence remain separately owned by
2862
2930
  or a scheme that implements SEND (an `https://` POST). A SEND to a scheme the model may not write (the
2863
2931
  log) is refused 400 `send-target-not-a-recipient`, never the unrelated writer
2864
2932
  rule. The detail states only that the addressed scheme is not a recipient;
2865
- neutral recovery distinguishes targetless replies from directed SEND without
2866
- guessing which one was intended. A scheme that does not implement SEND
2933
+ recovery names valid recipients without guessing which was intended.
2934
+ A scheme that does not implement SEND
2867
2935
  answers its ordinary factual 501 without grafting a guessed recovery onto it.
2868
2936
  - §send-response-receipt **A reply records exactly which messages it answers.** A successful
2869
- reply carries `answers`, the immutable message addresses it answered, not recipient actors. Targetless SEND
2870
- answers this loop's published, unanswered messages, oldest first. When none remain,
2871
- a nonempty targetless SEND replies to the loop's original published message, so a
2872
- follow-up can revise its answer. A targetless SEND with no body content or attachments
2873
- delivers nothing, carries no `answers`, and cannot erase an earlier reply. An accepted
2874
- parameterless KILL answer uses the same reply routing and empty-body rules. SEND to an exact message
2937
+ reply carries `answers`, the immutable message addresses it answered, not recipient actors.
2938
+ Targetless replies select the oldest published Open Message or, with none open, the
2939
+ loop's latest published message as speech only ({§message-completion}); they never broadcast.
2940
+ Empty completion replies still name their messages. SEND to an exact message
2875
2941
  address answers only that message; SEND to an actor endpoint remains ordinary communication
2876
2942
  and answers no assignment implicitly. An unpublished arrival cannot be answered by the
2877
2943
  targetless shorthand. Failed delivery answers nothing. Reply accounting reads executed
2878
2944
  delivery evidence, never log visibility or the mere existence of a later SEND.
2879
- - §kill-conclusion **Successful completion requires an explicit parameterless KILL.** The response
2880
- contains exactly one KILL without a target, scope, matcher or metadata, no hard
2881
- parse error or lost boundary, and was not cut at the provider's output allowance.
2882
- The operation limit must admit the entire program.
2883
- The parser retains everything after that KILL heading as its answer region
2884
- ({§terminal-kill}); apparent operations there are body text, not siblings.
2885
- SEND, NOTE and log-targeted KILL may accompany it, as may outside text ({§outside-text});
2886
- every other operation requires continuation. This tolerance is unadvertised:
2887
- model teaching requests KILL alone. Reasoning-side NOTEs remain ordinary notes.
2888
- An aside is allowed. After the program settles, {§wait-obligation-matrix} admits the
2889
- completion or returns a non-striking continuation/parking receipt explaining the
2890
- outstanding condition. Valid sibling operations always execute. Only an admitted
2891
- KILL delivers its literal body through {§send-response-receipt}; a deferred body
2892
- remains forensic evidence, never a stored draft to replay automatically. An empty
2893
- KILL concludes silently even when an observed message has no delivered answer. It neither
2894
- invents delivery nor replaces an earlier answer; immutable input and reply history remain intact.
2895
- SEND, NOTE and targeted KILL never request successful
2896
- completion. New arrivals still guard the terminal transition atomically
2897
- ({§completion-defers-to-messages}); an unobserved arrival concurrent with completion
2898
- keeps the loop running. No implicit successful exit exists.
2899
- - §outside-text **Text outside the operations is the turn's `outside` source: stored, weighed, never a row.**
2900
- The spans {§response-text} supplies are stored verbatim as one immutable `outside` turn source
2901
- per admitted emission, in source order joined by a blank line ({§turn-source-resources}); no
2902
- operation is minted for them, a repetitive or length-cut response stays one source, and nothing
2903
- filters what is stored. The model hears only the weight: the next packet's Notices section
2904
- carries `outside_text: N tokens emitted outside OPs. Discarded.`, N by {§tokenomics-agnostic-ruler};
2905
- the text itself never enters a packet, not even inside its turn's emission ({§emission-row}), is never delivered and never concludes.
2906
- {§empty-turn} still strikes a turn that holds only text, with unchanged
2907
- reply accounting and completion rules. A log-entry heading in
2945
+ - §outside-text **Text outside the operations is annotation beside them, and an empty turn without them.**
2946
+ The spans {§response-text} supplies are read with the turn's fenced operations. Beside at least one
2947
+ fenced content operation, each span is one `NOTE` at its position: it joins the admitted program as the
2948
+ model's own NOTE, frozen in the emission ({§emission-row}), lands as a NOTE row, replays with its turn
2949
+ ({§emission-history}) and draws no notice; the card's annotation register is where such text belongs.
2950
+ With no fenced operation in the turn, no operation is minted: the spans are stored verbatim as one
2951
+ immutable `outside` turn source per admitted emission, in source order joined by a blank line
2952
+ ({§turn-source-resources}), a repetitive or length-cut response stays one source, nothing filters what
2953
+ is stored, and the turn is an empty turn ({§empty-turn}) whose error row is the one thing the model
2954
+ hears of it; the text never enters a packet, is never delivered and never concludes. A log-entry heading in
2908
2955
  outside text still rejects the attempt unless it echoes an emission row ({§fabricated-log-entry}); an unfenced operation line is
2909
- not response text ({§unfenced-operation}) and so never reaches the source. Clients receive the text once through
2956
+ not response text ({§unfenced-operation}) and so reaches neither home. Clients receive an outside source once through
2910
2957
  `outside/event` ({§notifications-outside-event}, {§agui-outside-text}); FORK snapshots the
2911
2958
  source with the turn's others; the digest names its weight. It has no address: there is no
2912
2959
  `outside://` scheme, and exact emissions remain at `ops://`. This is evidence, not an alternate
2913
2960
  authoring format: the `plurnk.md` requirement to use only valid Plurnk OPs remains, and
2914
2961
  {§response-text} alone owns which bytes are operations, quotations or outside text.
2915
2962
  - §loop-answer **A loop's address is what it said.** READ `ops://<worker>/<loop>` resolves to
2916
- the latest reply the loop gave to the message that started it: the body of a SEND
2917
- or accepted final KILL that answered that message. A failed terminal takes precedence over
2963
+ the latest nonempty reply the loop gave to the message that started it: the body of a SEND
2964
+ that answered that message. A failed terminal takes precedence over
2918
2965
  an earlier reply and retains its exact Problem, including {§terminal-evidence}. A running loop
2919
2966
  without a reply is 425; a concluded loop without one returns its terminal outcome, including
2920
2967
  successful silence. Completion never fabricates an answer or a missing-resource failure.
2921
2968
  `ops://<worker>/<loop>/<turn>`
2922
2969
  remains that turn's emission. A concluded child's `loop_termination` row to its parent
2923
2970
  READs this same loop resource. Witness: `test/intg/loop-answer.test.ts`.
2924
- - §empty-turn **No authored response operation is a recoverable turn, never completion.**
2971
+ - §empty-turn **No operations resolve no messages.**
2925
2972
  Count parsed content operations and admitted reasoning operations ({§reasoning-operations}), a NOTE in
2926
- either channel among them; outside text ({§outside-text}) never enters the count. When none exist and no boundary was lost, retain the turn
2927
- and its raw sources and count one progress-contract strike, whether or not the turn carried text. The strike sends no notice of its own: the turn records one `_plurnk`
2973
+ either channel among them; outside text ({§outside-text}) never enters the count. When none exist,
2974
+ no boundary was lost, and messages remain unresolved or the emission is known incomplete,
2975
+ retain the turn and its raw sources and count one progress-contract strike, whether or not
2976
+ the turn carried text. Once messages are resolved, an intact operation-free turn is adjudicated
2977
+ normally under {§loop-completion}; absence of operations is not a new lifecycle signal.
2978
+ The strike sends no notice of its own: the turn records one `_plurnk`
2928
2979
  error row, `422` `The turn performed no operation.`, which rides the next packet's errors like
2929
2980
  any failure ({§operation-result-uniform-error-channel}); the threshold terminal still says why ({§engine-rails}).
2930
2981
  An empty turn uses its exact text as the cycle fingerprint ({§engine-cycle-evidence});
@@ -2943,7 +2994,7 @@ accounting and model-visible failure evidence remain separately owned by
2943
2994
  ({§turn-ops-entry}: the reader READs the source, and an emission of any length never rides
2944
2995
  wholesale into a parent's packet). The member is named for what it is — an emission left
2945
2996
  unconcluded — and never `answer`: the harness cannot warrant that text is complete or final,
2946
- because it did not conclude under {§kill-conclusion}. Earlier deliveries remain delivered;
2997
+ because its obligations did not settle under {§loop-completion}. Earlier deliveries remain delivered;
2947
2998
  the citation neither sends them again nor destroys them. A terminal whose last inference
2948
2999
  turn performed authored operations carries no `unconcluded`: an absent member is not an
2949
3000
  empty one. Attachment is owned by the one terminal seam.
@@ -2955,25 +3006,22 @@ accounting and model-visible failure evidence remain separately owned by
2955
3006
  executions, WORK and FORK own their input and receive it whole ({§send-resource-attachments},
2956
3007
  {§env-option}); a key they do not take is their own 400.
2957
3008
  - §send-idle-turn **NOTE is memory, not a yield.** NOTE does not imply parking.
2958
- A NOTE-only response does not request completion, even after every message is answered.
3009
+ A NOTE-only response does not resolve a message or create an observation obligation.
3010
+ The ordinary obligation check still runs ({§loop-completion}).
2959
3011
  Repetition remains subject to {§engine-cycle-evidence}.
2960
3012
  - §send-premature-terminate **Completion follows observation.** Every fired operation except
2961
3013
  SEND, NOTE, WAIT and successful KILL requires a subsequent packet. This barrier uses durable
2962
3014
  executed evidence, not curated rows. Fast completion, an empty result or curation cannot
2963
3015
  erase it. New arrivals are protected by {§completion-defers-to-messages}; no terminal verb
2964
3016
  or prose overrides this rule.
2965
- - §completion-joins-live-work **A completion request joins its live obligations.** An eligible
2966
- parameterless KILL parks on live children or
2967
- non-detached streams, as WAIT does. Ordinary programs continue regardless of earlier
2968
- replies. Each wake presents the newly settled state; the next program expresses its
2969
- own disposition. Only targeted KILL owns cancellation; parameterless KILL never
2970
- cancels work and delivers no final answer while joining.
3017
+ - §completion-joins-live-work **Resolved messages do not abandon held work.** Once messages
3018
+ and observation obligations are resolved, the loop joins live children and non-detached
3019
+ streams through the existing bounded wait. Each wake presents newly settled state.
3020
+ Neither completion nor message cancellation cancels that work.
2971
3021
  - §completion-defers-to-results **Results keep the loop running until observed.** Same-turn
2972
3022
  operations and failures, plus undelivered child or stream conclusions, require the next
2973
- packet. This is ordinary continuation, not a strike. A premature parameterless KILL
2974
- receives a factual continuation receipt without delivering its body. Earlier SEND
2975
- replies remain delivered. If observation warrants no further work or revision, a
2976
- lone empty parameterless KILL requests completion without repeating an earlier answer.
3023
+ packet. This is ordinary continuation, not a strike. SEND replies remain delivered.
3024
+ If observation warrants no further work or revision, no additional operation is needed.
2977
3025
  - §send-administrative-terminal **Administrative programs close their own transaction.**
2978
3026
  Their caller closes the administrative loop after execution; no terminal operation is
2979
3027
  manufactured. Initialization runs in the model loop without concluding it.
@@ -2982,7 +3030,8 @@ accounting and model-visible failure evidence remain separately owned by
2982
3030
  observed only after crossing a packet boundary. WAIT parks only on
2983
3031
  live obligations. If work has completed but is unobserved, it continues
2984
3032
  directly to the next packet because the wake edge has already fired. A genuinely
2985
- empty wait also continues under {§wait-obligation-matrix}, never concluding implicitly.
3033
+ empty wait creates no future wake; ordinary obligation adjudication still applies
3034
+ under {§wait-obligation-matrix}.
2986
3035
 
2987
3036
  ### §exec-input SEND to a running execution
2988
3037
 
@@ -3052,8 +3101,9 @@ site.** A bare shell command whose program is the name of a tool published by
3052
3101
  another enabled runtime (`brave_web_search {…}` under the default shell) exits
3053
3102
  127; the stream's terminal receipt then says the program is a tool of that
3054
3103
  runtime, names the tool's own document, and carries `toolRuntimes` and `tool`;
3055
- it builds no invocation ({§diagnostic-observation}). The status stays the shell's 500, nothing is rerouted, and a program the
3056
- registry does not know keeps the plain exit-127 receipt.
3104
+ it builds no invocation ({§diagnostic-observation}). That receipt is core's `404 program-is-a-tool` with
3105
+ `exitCode: 127`: the named program did not run. Nothing is rerouted, and a program the
3106
+ registry does not know keeps the shell's own answer, a 200 receipt with `exitCode: 127`.
3057
3107
 
3058
3108
  | Declared target kind | Authored target | Canonical effect target | Executor realization |
3059
3109
  | -------------------- | --------------------------------------- | ----------------------- | --------------------------------------------------------- |
@@ -3267,8 +3317,8 @@ it: an immediate slot is `200 { outcome: "started" }`; delayed work is
3267
3317
  `202 { outcome: "queued", executionsAhead, concurrency }`, and the channel stays
3268
3318
  `active` in the existing live sense — output growth and terminal settlement are the
3269
3319
  current truth. Admission is FIFO within the workspace; queue residence does not consume
3270
- the execution timeout; a KILL while queued never invokes the executor and closes the
3271
- stream through the normal 499 path. The scheduler is the exec scheme's; the knob is the
3320
+ the execution timeout; a KILL while queued never invokes the executor and concludes the
3321
+ stream as any KILL does ({§stream-control}). The scheduler is the exec scheme's; the knob is the
3272
3322
  service's ({§operator-config}), fail-hard on any other value.
3273
3323
 
3274
3324
  §exec-stream-page **An unrequested delivery never exceeds the retrieval page.** The
@@ -3292,7 +3342,10 @@ channel that holds content, and an empty sibling channel is a fact on that row
3292
3342
  (`channels: {"#stderr": 0}`), never a row of its own; only a stream that printed
3293
3343
  nothing on any channel lands one bodyless conclusion row, on its default
3294
3344
  channel, whose terminal fact, causal execution link, and available exit code make
3295
- completion explicit without invented narration. A skipped channel's publication is still marked
3345
+ completion explicit without invented narration. A failed execution is one failure: its
3346
+ terminal status and Problem ride its default channel's row when that row landed, else its
3347
+ first, and its other rows are 200 reads of their channels, so it puts one pointer in Errors
3348
+ ({§operation-results}). A skipped channel's publication is still marked
3296
3349
  terminal, so the stream's termination is delivered and never left pending. KILL may curate
3297
3350
  that log row without rewinding the cursor or publishing the terminal result
3298
3351
  again; the exact terminal result and channel content remain READable at the
@@ -3549,6 +3602,7 @@ Model sees lifecycle events in the `log` section per turn.
3549
3602
 
3550
3603
  - **Cancel:** ```` ```KILL (https://feed.example/x) ```` — the service invokes the handle registered by `subscriptions.open()` and aborts the composed subscription signal.
3551
3604
  - **Kill:** ```` ```KILL (sh:///ab3d5678) ```` — the model terminates the addressed workspace stream. This is stream control, not a write: the output scheme's `writableBy` never gates it. A stream that already ended, killed or not, answers 200 with its recorded `terminalStatus`: the process is not running, which is what KILL asks for (#757); a stream that never existed answers 404 ({§runtime-resource-binding}). A queued execution ({§exec-concurrency}) is cancelled the same way and never enters its executor.
3605
+ - §stream-asked-stop **A stop that was asked for is no failure.** A stream stopped by a model KILL of either form from the worker that holds it concludes 200, with its `exitCode` when its producer reported one: the producer's 499 cancellation is replaced before the subscription settles, so the KILL's 200 receipt is the record and the conclusion row brings nothing into Errors ({§operation-results}). A cancellation its holder did not ask for — a peer's or a client's KILL, loop end, worker teardown, daemon stop — keeps its 499, and a lifetime keeps its 504.
3552
3606
  - **WebSocket write:** ```` ```EDIT (wss://feed/x) ```` or ```` ```SEND (wss://feed/x) ```` with a body sends one whole text frame through the active owner. Either write can follow the opening READ in the same turn under {§op-execution-order}.
3553
3607
  - **Other stream write:** ```` ```SEND (…) ```` remains scheme-defined, including exec stdin.
3554
3608
 
@@ -3577,7 +3631,7 @@ No generator. SQLite-optimal: STRICT (3.37+), `INTEGER PRIMARY KEY` aliasing, ex
3577
3631
  | Concern | Rule |
3578
3632
  |---|---|
3579
3633
  | §db-schema-baseline Baseline | Versions 1–8 of `migrations/` are the released baseline, as domain chapters — `001_workspaces`, `002_workers`, `003_loops`, `004_inference`, `005_entries`, `006_log`, `007_subscriptions`, `008_interactions` — each one `MIGRATE` block whose version is the file's numeric prefix. They create the shape 1.21.1 shipped: tables, indexes, views, the constraint triggers that are a table's invariants (guards that only `RAISE`), and a view's `INSTEAD OF` write path. No migration holds an `INIT` block or a trigger that writes a row. |
3580
- | §db-migrations Evolution | A released version is frozen: only its comments may change. Every shape change is one new file at the next version, applied by sqlrite above the database's `PRAGMA user_version`, ascending, each in its own transaction with its version bump. A fresh database takes the same path as an existing one. Each migration carries upgrade coverage: `test/intg/schema-baseline.test.ts` pins the released shape's fingerprint and migrates a released database, asserting its rows survive. A process trigger's change needs no migration: its `INIT` block re-declares it on the next open ({§db-process-triggers}). A table anything references cannot be rebuilt in a migration: foreign keys stay enforced inside the migration transaction, so the drop cascades through its children (`011_settled.sql`); such a table evolves by adding columns or redeclaring its guard triggers. Only an unreferenced table is rebuilt (`010_outside_text.sql`). |
3634
+ | §db-migrations Evolution | A released version is frozen: only its comments may change. Every shape change is one new file at the next version, applied by sqlrite above the database's `PRAGMA user_version`, ascending, each in its own transaction with its version bump. A fresh database takes the same path as an existing one. Each migration carries upgrade coverage: `test/intg/schema-baseline.test.ts` pins the released shape's fingerprint and migrates a released database, asserting its rows survive. A process trigger's change needs no migration: its `INIT` block re-declares it on the next open ({§db-process-triggers}). Foreign keys stay enforced. Prefer column changes or guard-trigger replacement; rebuilding a referenced table requires copying its complete referencing subgraph first and replacing children before parents, with retained-row and foreign-key coverage. Dropping a parent alone would cascade away its children. |
3581
3635
  | §validation-topology Where an invariant is enforced | The SQL core owns each invariant: a chapter's CHECK constraints and guard triggers are its one statement, and a rule two tables share is the same expression over each column (`entry_channel_producer_result_contract` and `subscriptions_result_contract_update` hold the settled-result rule as one text, `011_settled`). Contracts (JSON Schema) are enforced at the gates: a scheme's result entering core (`Results` in plurnk-schemes) and the wire leaving to clients (plurnk-agui's `Validator` calls). Everything between trusts core and the gates and carries no defensive re-validation: a result read back from a row is parsed, never re-asserted. Witness: `test/intg/validation-topology.test.ts` applies one corpus of settled results to the gate, to chapter 5 and to chapter 7 and asserts the three agree on every row. |
3582
3636
  | Open failure | A missing table or column after migration means the file's shape disagrees with its version: a database from a newer release, or one from an unreleased development build. The daemon refuses to open it and names both remedies. |
3583
3637
  | §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. |
@@ -3591,6 +3645,26 @@ No generator. SQLite-optimal: STRICT (3.37+), `INTEGER PRIMARY KEY` aliasing, ex
3591
3645
  - DDL = storage truth; JSON Schemas = wire truth. They are allowed to differ where ergonomics demand.
3592
3646
  - §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`.
3593
3647
 
3648
+ ### §db-query-report Workload query report
3649
+
3650
+ `report:sql <database.db> [specimens.json]` is an on-demand diagnostic, not a gate.
3651
+ It snapshots only the named database under {§share-snapshot}, registers the production
3652
+ SQL functions, and plans the source PREPs through SqlRite's own parser. It neither
3653
+ migrates nor runs application INIT blocks on that snapshot. Schema mismatch and query
3654
+ errors remain report failures, not empty successful results.
3655
+
3656
+ | Evidence | Meaning |
3657
+ |---|---|
3658
+ | `plans` | Unbound `EXPLAIN QUERY PLAN` rows for every effective PREP, including mutations; no mutation is executed. |
3659
+ | `scans` | Conservative hints: named table/view, indexed, virtual, or unresolved alias/intermediate. Raw details remain authoritative; a scan is not itself a defect. |
3660
+ | `measurements` | Only supplied `{statement, parameters}` specimens execute, with SQLite's query-only guard. Each retains its bound plan, row count, and one elapsed measurement; row bodies are not retained. |
3661
+
3662
+ Timings cover SQLite stepping and row conversion in the report process against the
3663
+ compacted private snapshot, not daemon IPC, application work, cold-cache latency, or a
3664
+ statistical distribution. No implicit workload discovery, synthetic corpus, automatic
3665
+ sampling, or performance threshold is applied. The report changes neither source data
3666
+ nor the existing query-plan gate.
3667
+
3594
3668
  ### §sql-ts-boundary SQL/TS responsibility boundary
3595
3669
 
3596
3670
  **Lives in SQL:**
@@ -3890,7 +3964,8 @@ Each knob's value lives on its panel and nowhere else (`plurnk-service config de
3890
3964
  | `PLURNK_SERVICE_PROVIDER_RECOVERY_BACKOFF` | First recovery delay (ms); doubles per failure up to `PLURNK_SERVICE_PROVIDER_RECOVERY_BACKOFF_MAX` ({§provider-recovery}). |
3891
3965
  | `PLURNK_SERVICE_MAX_STRIKES` | Consecutive turn-contract strike threshold ({§engine-rails}). |
3892
3966
  | `PLURNK_SERVICE_EMISSION_ATTEMPTS` | Completed provider responses allowed beneath one engine turn before frame admission is exhausted. Bounded interior operation errors are admitted without spending this budget. Exhaustion contributes one frame-contract strike under {§invalid-emission-attempts}. |
3893
- | `PLURNK_SERVICE_BUDGET_LARGEST_ITEMS` | How many of the heaviest retained log rows the gauge names ({§context-gauge}). |
3967
+ | `PLURNK_SERVICE_BUDGET_PRESSURE` | Budget percentage above which the gauge names its largest rows ({§context-gauge}) and a packet within its budget carries the `budget_pressure` notice ({§context-pressure-notice}); measured before adding either. |
3968
+ | `PLURNK_SERVICE_BUDGET_LARGEST_ITEMS` | How many of the heaviest retained log rows the pressured gauge names ({§context-gauge}). |
3894
3969
  | `PLURNK_SERVICE_LINE_ANCHOR_CONTEXT_LINES` | Minimum neighboring lines hashed on each side; repeated handles expand their context ({§line-anchor-disambiguation}). |
3895
3970
  | `PLURNK_SERVICE_EDIT_RECEIPT_CONTEXT_LINES` | Surrounding and landed lines shown at each EDIT result boundary ({§edit-result-receipt-projection}). |
3896
3971
  | `PLURNK_SERVICE_MIN_CYCLES` | Min repetitions before cycle detection fires ({§engine-rails}). |
@@ -3920,7 +3995,14 @@ Feature-flag bools use `process.env.X === "1"` exactly — never `=== "true"`.
3920
3995
 
3921
3996
  External extensions declare their own env vars in their own `.env.defaults`, assembled at boot ({§operator-config-env-defaults}).
3922
3997
 
3923
- §operator-config-cli-flags **Admin CLI flags derive only from the service package's `.env.defaults`.** Every `PLURNK_*` declared there becomes `--<kebab-cased-name>` (prefix stripped, lowercased, underscores → dashes). A comment immediately above the declaration becomes its `-h` description. Installed extension defaults join the environment floor and catalog but do not implicitly expand the service executable's flag surface.
3998
+ §operator-config-cli-flags **Admin CLI configuration flags derive from the service panel and the contracts-owned shared keys ({§operator-config-shared-keys}).** Each active `PLURNK_*` declaration becomes `--<kebab-cased-name>` (prefix stripped, lowercased, underscores → dashes). A comment immediately above the declaration becomes its `-h` description; undescribed flags still show their environment name and default. Installed extension defaults join the environment floor and catalog but do not implicitly expand the service executable's flag surface.
3999
+
4000
+ §service-posix-artifacts The service package ships `dist/man/plurnk-service.1`
4001
+ and Bash, Zsh and Fish scripts in `dist/completions/`, generated at build time
4002
+ from the same help and panel descriptors as the executable. Completion supplies
4003
+ command and long-option names plus ordinary filename completion; it does not
4004
+ start the service, inspect configuration values, or contact a provider. Installing
4005
+ the manual or enabling completion is explicit and documented in `INSTALL.md`.
3924
4006
 
3925
4007
  ### Loop limits
3926
4008
 
@@ -3972,7 +4054,7 @@ leak into another.
3972
4054
  workspace: a client tightens the runaway-op guard and never raises it past
3973
4055
  the operator's.
3974
4056
  - §operator-config-workspace-max-commands-floor The cap bounds *actions* only.
3975
- WAIT and parameterless KILL are never counted and always dispatch, so `0` is a valid
4057
+ WAIT is never counted and always dispatch, so `0` is a valid
3976
4058
  floor, admitting lifecycle intent with zero actions. Dropped actions still prevent
3977
4059
  successful completion under {§turn-disposition}.
3978
4060
  - §operator-config-workspace-git `settings.git` (`false`) **denies** git for the workspace (`PLURNK_SERVICE_GIT_ALLOWED` AND workspace) — the client opts its workspace out of git membership and working-tree status; it can never re-enable git past the operator's service-wide lockout.
@@ -4422,14 +4504,15 @@ core owns discovery roots.
4422
4504
 
4423
4505
  An adapter may expose a `scheme` facet beneath its family's runtime namespace
4424
4506
  ({§runtime-resource-binding}). A facet claims a path subtree and is the scheme's
4425
- whole live half there: READ and FIND preparation, FIND, SEND, WAIT and KILL are
4426
- its own wherever it implements them. A claimed KILL the facet does not implement
4507
+ whole live half there: READ and FIND preparation, FIND, EDIT, SEND, WAIT and KILL
4508
+ are its own wherever it implements them. A claimed KILL the facet does not implement
4427
4509
  is the ordinary entry KILL ({§stream-control}); an unclaimed coordinate keeps the
4428
4510
  stored-execution behaviour, SEND to a process included. Where its resources are
4429
4511
  not shaped like the executor's output, the facet states their representation —
4430
- resource authority, channels, the default channel — and that manifest governs
4431
- every claimed coordinate: its address, its fragmentless READ, the channel a
4432
- subscription publishes. An adapter states the `traits` of its runtime — `web`
4512
+ resource authority, channels, the default channel, who may write them — and that
4513
+ manifest governs every claimed coordinate: its address, its fragmentless READ, the
4514
+ channel a subscription publishes, the writer gate ({§scheme-surface}) an EDIT or a
4515
+ COPY into it passes. An adapter states the `traits` of its runtime — `web`
4433
4516
  for a family that reaches the network — so {§capability-admission} selects its
4434
4517
  manager and its resources alike.
4435
4518
 
@@ -4466,6 +4549,23 @@ door past the ceiling.
4466
4549
  The family publishes no process runtimes. Its values are read at the spawn that uses them,
4467
4550
  not from a live process or a cached worker environment.
4468
4551
 
4552
+ §env-scheme **The registry is an address space.** Every name in effect for a Worker's commands —
4553
+ the ambient names the ceiling admits, workspace defaults and the Worker's own entries, exactly
4554
+ what `list` projects — is a resource at `env:///NAME` whose body is the value, verbatim; a
4555
+ reserved or masked name is no resource. The family's manager exposes it as the facet of its own
4556
+ `env://` namespace ({§runtime-resource-binding}), read for the dispatching Worker: READ projects
4557
+ the value its commands receive now, FIND lists the names in effect and a pattern on it matches
4558
+ values, COPY carries a value out. The manager's own output streams, eight hexadecimal characters
4559
+ ({§execution-output-identity}), stay the executor's. A write is the Worker's own layer, never the
4560
+ workspace's or the operator's: EDIT sets the whole value through the family's `add` for the
4561
+ Worker, and KILL retires the name from the Worker's commands — `remove` for an entry the Worker
4562
+ owns, which restores an inherited value, `disable` for an inherited one, which keeps its
4563
+ definition. Admission is the family's ({§env-functionality}) and its refusal is the operation's
4564
+ result. A value has no lines: a line scope on EDIT or KILL is `value-whole` (400), and a pattern
4565
+ on EDIT is the dispatcher's refusal for any scheme without text scopes; a target that is not
4566
+ `env:///NAME` is `name-invalid` (400), or `target-required` (400) when absent; a name not in
4567
+ effect is `entry-not-found` (404) on READ and KILL alike.
4568
+
4469
4569
  §functionality-scope **A family declares its supported scopes.** Skills, MCP, members
4470
4570
  and outbound A2A describe what exists in a **workspace**: a capability, resident or installable,
4471
4571
  that every Worker there shares. Environment describes how one **Worker** works — context rather
@@ -4585,7 +4685,7 @@ Core's behavior behind them.
4585
4685
  | §methods-proposal-resolve Proposals | `resolveProposal(logEntryId, resolution, owner)` | Validates the workspace-scoped owner before delivering one accept, reject, or cancel decision. Unknown, mismatched, and already-resolved identities fail without consuming the gate; the adapter authenticates its owner identity. |
4586
4686
  | §client-interaction-list Client interactions | `pendingClientInteractions(workspaceId)` | Intersects durable interaction rows with their live operation waiters and returns the contracts-owned projection; a row alone is not a resumable interaction. |
4587
4687
  | §methods-client-interaction-resolve Client interactions | `resolveClientInteraction(interactionId, resolution, respondent, message?)` | Validates the recorded recipient before delivering one resolved payload or cancellation. Unknown, mismatched, and already-resolved identities fail before affecting an operation. |
4588
- | §methods-loop-run Loops | `runLoop({ workspaceId, workerId, prompt, source?, maxTurns?, openPaths?, selector?, childSelector? })` | Validates a model worker and persists the request with the effective turn ceiling, then returns an immediate status-100 acknowledgement with `loopId` and `action`. A trusted adapter may identify the prompt's causal actor with one canonical `source`; ordinary clients cannot author it through their protocol surface. Messages carry no approval authority. The exact terminal result arrives only through `loop/terminated`; parking and resuming do not replace the loop. |
4688
+ | §methods-loop-run Loops | `runLoop({ workspaceId, workerId, loopId?, prompt, source?, maxTurns?, openPaths?, selector?, childSelector? })` | Validates a model worker and persists the request with the effective turn ceiling, then returns an immediate status-100 acknowledgement with `loopId` and `action`. An explicit Loop recipient follows {§loop-addressed-admission}. A trusted adapter may identify the prompt's causal actor with one canonical `source`; ordinary clients cannot author it through their protocol surface. Messages carry no approval authority. The exact terminal result arrives only through `loop/terminated`; parking and resuming do not replace the loop. |
4589
4689
  | §methods-loop-cancel Loops | `cancelDrain(workerId, reason?)`; `cancelWorker({ workspaceId, workerId, reason? })` | `cancelDrain` begins durable structured cancellation and reports whether process-local work existed when called; queued or parked durable work is still terminalized when it is `false`. The ownership-bounded `cancelWorker` awaits that same tree cancellation and stream reap, so an exterior protocol can project the settled durable result without polling or fabricating state. |
4590
4690
  | §methods-op-mirror Client dispatch | `dispatchClientAction({ workspaceId, workerId, statements })` | Dispatches already-parsed grammar statements as one client action in one administrative loop in the client worker, executing in the workspace's Functionality ({§actor-boundary-attached-functionality}). Every statement is an ordered client/operation turn, and every committed `log/entry` is emitted before the action promise resolves; a proposal may keep its turn, loop, and action promise open until resolution. Core exposes no per-op method family. |
4591
4691
  | Client observation | `look({ workspaceId, workerId, statement, perspectiveWorkerId? })` | Runs an already-parsed READ through the full resolver in the workspace's Functionality without a log row. A non-READ statement is rejected ({§op-look}). |
@@ -4627,9 +4727,12 @@ the requested configuration normally.
4627
4727
 
4628
4728
  §methods-loop-run-open-paths **Workspace paths are core-owned context reads.**
4629
4729
  `openPaths` belongs to the message submitted by the client. The client
4630
- sends paths, never duplicated file bytes; core dispatches one ordinary
4730
+ sends local paths or scheme URIs, never duplicated resource bytes; core dispatches one ordinary
4631
4731
  `plurnk`-origin READ per path from inside the owning workspace, and successes
4632
4732
  and failures surface through the normal operation-result contract.
4733
+ Path spelling follows {§path-syntax}, including channel fragments and literal
4734
+ delimiters. Malformed URI syntax is rejected before message admission; a valid
4735
+ address whose resource is absent produces the ordinary READ failure.
4633
4736
 
4634
4737
  | `runLoop` disposition | Message and path behavior |
4635
4738
  |-----------------------|------------------------------------------------------------------------------------------------------|
@@ -4751,6 +4854,8 @@ packets or state snapshots.
4751
4854
 
4752
4855
  §worker-model-selection **Worker-owned model selection.** Every model worker
4753
4856
  owns one durable model, persisted as a nullable `model_routes` foreign key.
4857
+ Concurrent first selections of the same resolved tuple share one identity;
4858
+ an insertion conflict returns the existing route without changing its fields.
4754
4859
  The root conversation worker is seeded once — from an explicit selection, else
4755
4860
  the daemon default — and never re-seeded from a later default change. A
4756
4861
  deliberately modelless daemon leaves the worker unset and rejects model work
@@ -4924,35 +5029,54 @@ rendered or measured; {§context-fit} remains an engine-owned post-build rail.
4924
5029
 
4925
5030
  ```mermaid
4926
5031
  flowchart LR
4927
- defaults[Engine section drafts] --> transforms[Trusted scheme transforms<br/>and boundary validation]
4928
- transforms --> render[Render system and user slots]
5032
+ defaults[Engine sections<br/>log records interleaved with complete programs] --> transforms[Trusted scheme transforms<br/>and boundary validation]
5033
+ transforms --> render[Render ordered message roles]
4929
5034
  render --> measure[Budget substitution and<br/>core-owned measurement]
4930
5035
  measure --> rail[Engine budget admission and dispatch]
4931
5036
  ```
4932
5037
 
4933
5038
  ### §packet-wire-envelope The wire envelope
4934
5039
 
4935
- The packet reaches the provider as two messages. No emission is replayed under `assistant`.
5040
+ Sections retain their message roles and order. System sections form the leading system message;
5041
+ adjacent nonempty sections of the same remaining role form one message. With an eligible
5042
+ {§emission-history}, the default envelope is:
4936
5043
 
4937
5044
  | Message | Role | Content |
4938
5045
  |:--|:--|:--|
4939
5046
  | 1 | `system` | the system slot, as rendered |
4940
- | 2 | `user` | the user sections in {§packet-cache-monotone} order; native parts ({§packet-attachment-parts}) precede the optional final {§previous-emission} section |
5047
+ | 2 | `user` | initial retained log records through the first selected emission record |
5048
+ | 3… | alternating `assistant`, `user` | each selected complete content program, then the following log records through the next selected emission record; native parts remain beside their READ records ({§packet-attachment-parts}) |
5049
+ | last | `user` | remaining log records and the current-status footer, from Worker through Open Messages and optional Recap |
5050
+
5051
+ Without selected programs, the log and footer coalesce into one user message: system + user.
5052
+ Each program follows its own emission record and precedes its subsequent results.
5053
+ Log records retain their order; interpolation never groups or relocates their bodies.
5054
+ Stored sections retain their original roles and order: reading evidence
5055
+ never converts an earlier request into a different envelope.
4941
5056
 
4942
5057
  The digest's packet artifacts record the sections, and `.wire.json` reconstructs their text-message
4943
5058
  envelope ({§share-packet-names}); it is not a serialized HTTP capture.
4944
5059
 
4945
- ### §previous-emission Complete, optional continuity
5060
+ ### §emission-history The turn's NOTEs, in the model's voice
4946
5061
 
4947
5062
  | Concern | Contract |
4948
5063
  |---|---|
4949
- | Selection | Only the immediately preceding completed model inference turn in this loop. Its admitted content program must have no syntax errors and its emission row must remain active. Never search backward for an older eligible program. Runtime failures do not disqualify it. |
4950
- | Absence | No preceding model turn, rejected or syntactically partial emission, empty or reasoning-only turn, or retired emission row means no section. Initialization and other loops supply none. |
4951
- | Content | The frozen canonical admitted content program, whole: every body, NOTE, WAIT and reply retained. No placeholders, redaction, preview or nested-body interpretation. Reasoning operations remain in their own source and receipts. |
4952
- | Placement | `## Previous Emission`, singular, is the final user section and final transmission content, after native parts when present. Nothing follows it. It is replaced each turn, never inserted into the reusable log prefix. |
4953
- | Authority | Core attaches this section after trusted section transforms; the extension seam does not rewrite the frozen program. The active emission row owns its curation lifetime. |
4954
- | Capacity | At the hard context wall, omit the section whole before suppressing any result body or native part ({§context-own-rows-fit}). Omission lasts through rebuilds of that request; the next request decides afresh. No source, receipt, or stored historical packet is changed. |
4955
- | Accounting | Its text is charged once within the user slot; the emission row charges only its record. |
5064
+ | Choice | `PLURNK_SERVICE_EMISSION_HISTORY`: `none`, `latest`, or `all` (default). Reasoning return is independent ({§reasoning-row}). |
5065
+ | Selection | `latest` considers only the immediately preceding completed model inference turn in this loop, never falling back to an older eligible program. `all` considers every completed model inference turn in this loop, in ascending turn order. |
5066
+ | Eligibility | An admitted content program with no syntax errors and an active emission row. Rejected attempts, syntactically partial emissions, empty or reasoning-only turns, initialization and other loops supply none. Runtime failures do not disqualify an admitted program. |
5067
+ | Vocabulary | Executor identities come from that turn's admitted operation evidence ({§packet-stored-shape}), not the current registry. Disabling or removing a runtime never changes its admitted history. |
5068
+ | Content | A replayed turn is its NOTEs: every content NOTE the program admitted, whole and in program order, as the model wrote it, including a NOTE that stood outside its fence ({§outside-text}). Every other operation is omitted; its receipt in the log is its record, and the program stays readable at `ops://`. A NOTE whose log row has been retired is omitted from the replay from the next packet on, so one KILL retires the memory everywhere it shows. Selection uses parsed operations, never text inside their bodies. Join retained NOTEs within each program with one blank line. No placeholders, body redaction or preview. Reasoning operations remain in their own source and receipts. |
5069
+ | Legend | The emission row of a replayed turn carries no program preview: its body is the legend of that turn's replayed NOTEs, one numbered line per NOTE, `N:log:///<loop>/<turn>/<sequence>/NOTE · <weight>`, in log order ({§emission-row}). Those NOTE rows render nowhere else in the packet; their text is read in the replay and their handle in the legend. A line scope on the emission row retires the NOTEs on those lines; the unscoped KILL retires the row ({§log-kill-scope}). A NOTE of a turn that is not replayed — an earlier loop, a program omitted at the wall, a reasoning NOTE — renders as an ordinary row with its body. |
5070
+ | Placement | Interpolate each selected program immediately after its durable emission record, as an assistant message without a heading or wrapper. Split the user log at that record; following observations stay after the program. No history is collected at the end. With `none` or no retained NOTEs, no assistant section is added; filtering does not make `latest` fall back to an older turn. |
5071
+ | Authority | Core assembles the chronological sections before the trusted whole-list transform ({§packet-extension-transform}). Each active emission row owns its program's curation lifetime; retiring it removes only that program, never its immutable source. |
5072
+ | Capacity | At the hard context wall, omit the selected history whole before suppressing any result body or native part ({§context-own-rows-fit}). A turn whose replay is omitted is not replayed: its NOTE rows stand in the log as ordinary bodied rows, and the wall's shedding then treats them as any other. A NOTE's text is in the packet once, as replay or as row, never both. Omission lasts through rebuilds of that request; the next request decides afresh. No source, receipt, or stored historical packet is changed. |
5073
+ | Accounting | Each program is charged once as its assistant message; the emission row charges only its record, legend included. |
5074
+
5075
+ The initial user segment is `log`; later segments are `log/<first-record-coordinate>`.
5076
+ Programs are `emission-history/<emission-record-coordinate>`. These are durable, unique section
5077
+ names, not model-facing headings. Only the initial segment has the `Log` header. Section-family
5078
+ inspection joins segments in recorded order; wire projection uses their individual roles and
5079
+ positions. Stored packets retain the sections actually sent, including older packet layouts.
4956
5080
 
4957
5081
  ### §packet-cache-monotone Default order and cache locality
4958
5082
 
@@ -4963,26 +5087,31 @@ Conditional absence never reorders the surviving default sections.
4963
5087
  | 1 | system | `definition` | Framework definition; leads the most stable prefix. |
4964
5088
  | 2 | system | `system-policy` | Operator policy; empty content is omitted on the wire. |
4965
5089
  | 3 | system | `inject` | Present only when operator notes are configured. |
4966
- | 4 | user | `log` | Append-mostly model-visible history; the first user section, so the cached prefix ends inside it. |
4967
- | 5 | user | `worker` | `Worker`: `{"path": "worker://alice", "parent": <address or null>, "loop": L, "turn": T}`, the actor and the coordinate this packet's response becomes ({§packet-current-turn}). |
4968
- | 6 | user | `delegation` | `Delegation`: per-turn `{workers, streams}` pointers; always present, each list `[]` when empty ({§packet-empty-sections}). |
4969
- | 7 | user | `errors` | Per-turn failure pointers; empty content is omitted. |
4970
- | 8 | user | `notices` | Per-turn observations; empty content is omitted. |
4971
- | 9 | user | `git` | Per-turn workspace status; empty content is omitted. |
4972
- | 10 | user | `budget` | `Context Curation`; omitted when capacity is unknown. |
4973
- | 11 | user | `messages` | `Open Messages`: immutable message addresses and causal sources ({§message-arrival}). |
4974
- | 12 | user | `recap` | Optional authored operational recap. |
4975
- | 13 | user | `previous-emission` | Complete previous program, if eligible and within capacity ({§previous-emission}); always last. |
5090
+ | 4–5 | user / assistant | `log` and `emission-history` segments | Append-mostly chronological history: each selected program follows its emission record and precedes its results ({§emission-history}). |
5091
+ | 6 | user | `git` | Per-turn workspace status; empty content is omitted. |
5092
+ | 7 | user | `budget` | `Context Curation`; omitted when capacity is unknown. |
5093
+ | 8 | user | `worker` | `Worker`: `{"path": "worker://alice", "parent": <address or null>, "loop": L, "turn": T}`, the actor and the coordinate this packet's response becomes ({§packet-current-turn}). |
5094
+ | 9 | user | `delegation` | `Delegation`: per-turn `{workers, streams}` pointers; always present, each list `[]` when empty ({§packet-empty-sections}). |
5095
+ | 10 | user | `messages` | `Open Messages`: immutable message addresses and causal sources ({§message-arrival}). |
5096
+ | 11 | user | `notices` | Per-turn observations; empty content is omitted. |
5097
+ | 12 | user | `errors` | Per-turn failure pointers; empty content is omitted. |
5098
+ | 13 | user | `recap` | Optional authored operational recap. |
4976
5099
 
4977
5100
  The order favors prefix-cache locality where semantics permit: the definition
4978
5101
  and privileged policy lead operator notes, while the append-mostly
4979
- log leads the volatile user-status clump. The previous program follows that clump, so replacing it
4980
- does not rewrite the log prefix. Retiring an emission row breaks the prefix at its row like any
4981
- other curation. It does **not** claim that every system byte is
5102
+ log and interpolated programs lead the volatile user-status clump. That clump is never cached
5103
+ across turns, since the next turn's log grows into its place, so its order serves attention alone:
5104
+ it runs from ambient state (Git Status, Context, Worker, Delegation) to what the turn owes (Open
5105
+ Messages) to feedback on the last turn (Notices, then Errors), and closes with the Recap. The nearer
5106
+ the end, the more a section asks of this turn. With `all`, appending new
5107
+ observations and programs preserves the existing history's roles and text prefix; no old program
5108
+ moves past newly appended observations. Changing selection or curating a row may invalidate the
5109
+ prefix at the affected position. It does **not** claim that every system byte is
4982
5110
  immutable or that the complete packet is globally monotone in volatility:
4983
5111
  operator notes and policies can change. Trust is a separate
4984
5112
  admission rule. The system slot contains trusted control-plane material;
4985
- attacker-reachable content stays in the user slot.
5113
+ observations stay in the user role, and only the model's admitted content program is replayed
5114
+ under assistant authorship.
4986
5115
 
4987
5116
  ### §packet-extension-transform Trusted whole-list extension seam
4988
5117
 
@@ -4994,8 +5123,10 @@ Each initial or returned list passes the schemes-owned validator, including
4994
5123
  unique-name enforcement, before the next transformer or renderer. Each
4995
5124
  transformer may inspect the section content and add, remove, or reorder
4996
5125
  sections. It receives no separate engine, database, actor, or request context.
4997
- Core then attaches the optional frozen previous program ({§previous-emission}); transforms own
4998
- section drafts, not the worker's source evidence.
5126
+ The complete default list already includes the interpolated programs ({§emission-history}) and
5127
+ native READ boundaries. Transforms own section drafts, not the worker's immutable source evidence.
5128
+ Removing a section removes its native deliveries too; a retained native delivery requires its
5129
+ named section to remain user-authored. Core measures the transformed composition.
4999
5130
 
5000
5131
  This is strictly a trusted in-process seam, admitted through the common extension
5001
5132
  trust gate; an external client action cannot invoke it. Whole-list transformation is
@@ -5009,7 +5140,7 @@ time of measurement.
5009
5140
 
5010
5141
  | Fact | Owner and unit | Time | Contract |
5011
5142
  |:-----|:---------------|:-----|:---------|
5012
- | Core curation weight | `contentWeight = ceil(chars/2)` over channel content, canonical log bodies, rendered packet slots (including the optional previous emission) | Write/build | Stable, model-independent measure; never a tokenizer claim. The model meets it as `tokens`. |
5143
+ | Core curation weight | `contentWeight = ceil(chars/2)` over channel content, canonical log bodies, and each rendered message (including the optional emission history) | Write/build | Stable, model-independent measure; never a tokenizer claim. The model meets it as `tokens`. |
5013
5144
  | §tokenomics-context-envelope-admission Provider input capacity | Provider model limits, the configured output reservation and the output floor, in provider tokens | Before every logical request | The reservation `min(maxInputTokens, contextWindow − outputBudget)` sizes the room; the wall `min(maxInputTokens, contextWindow − outputFloor)` decides admission ({§provider-capacity-admission}). The provider alone measures the complete request and admits it — with the grant flexed when the prompt is over the reservation — defers it, or rejects it at the wall. |
5014
5145
  | Provider generation envelope | Provider response grant and optional reasoning subset, in provider tokens | Before every logical request | The reservation includes hidden reasoning; its strict reasoning subset is never additive. The response grant follows {§provider-flexed-allowance}. |
5015
5146
  | Provider usage and cost | Provider-reported input/output/cache/reasoning tokens and monetary evidence | After every physical request | Durable physical-request forensics under {§provider-usage}; never curation state or a preflight estimate. |
@@ -5019,7 +5150,7 @@ time of measurement.
5019
5150
  ```mermaid
5020
5151
  flowchart TD
5021
5152
  build["Build the packet at the budget"] --> wall{"Estimate over the wall?"}
5022
- wall -- yes --> shed["Shed: the previous program whole, then the newest rows bodiless"]
5153
+ wall -- yes --> shed["Shed: the emission history whole, then the newest rows bodiless"]
5023
5154
  shed --> wall
5024
5155
  wall -- no --> over{"Over budget, no row yet?"}
5025
5156
  over -- yes --> row["One over-budget row at the head of the turn"]
@@ -5030,17 +5161,18 @@ flowchart TD
5030
5161
  shed -. "nothing left to take" .-> overflow["window-overflow 413, no inference request"]
5031
5162
  ```
5032
5163
 
5033
- - §context-budget **One room.** The budget is the provider's input capacity through the current calibration, `floor(inputCapacity / factor)` ({§tokenomics-calibrated-readout}), and it bounds the whole packet — teaching, catalog, log and gauge together. Nothing on the service panel sizes a part of it: no projection share, no preview page, no pressure threshold. The budget follows the calibration both ways; a room that shrinks under the model is announced by the over-budget row ({§context-over-budget-row}), never hidden by keeping a larger figure.
5034
- - §context-gauge **One gauge.** Every packet carries one `## Context` section holding one JSON object: `tokens`, the packet's weight as rendered; `budget`, the room; and `largest`, the `PLURNK_SERVICE_BUDGET_LARGEST_ITEMS` heaviest retained log rows as `{path, tokens}` ranked by weight then path. Each log row heading carries its own `tokens`. The gauge is state: it never presents `budget − tokens` as response allowance, it carries no mandate, and it reads the same at one percent as at ninety-nine; over budget, `largest` is as complete as under it, since those rows are the handles the row asks the model to use ({§context-over-budget-row}).
5035
- - §context-fit **One rule: whole if it fits, otherwise as much as fits, then its size and address.** A result the model asked for — a READ without a scope, a FIND, an exec result delivered on close — arrives complete when its weight fits within `budget − tokens` as of that turn, less the room the turn still owes — one receipt's measured weight for each result still to land in it and the emission record that answers it, so that the receipts of a batch and the answer always fit. Otherwise the complete result stays where it was read from and the row is a `413` receipt naming the result's size, its weight, the remaining budget, and the two verbs: `READ` a range, or `KILL` first. A READ of lines carries, above its receipt, the longest prefix of those lines whose row fits that room — the lines with their anchors, the returned range closed on the last line delivered, and the receipt naming the lines delivered; a result whose first line does not fit, a FIND, a stream page and a byte view are bodiless receipts. An arrival the model did not ask for — an inbound `SEND`, a child's conclusion — takes the same bodiless receipt as a fact, not an error: its size and its address. Explicit scopes (`<a,b>`, a pattern, `<1,-1>`) are exact and take the same test. Result cuts are named where they happen: the first page of what came back unasked in size ({§markerless-first-page}) and the cut at the room in the receipt. The optional previous program is whole or absent ({§previous-emission}), never a cut.
5164
+ - §context-budget **One room.** The budget is the provider's input capacity through the loop's calibration, `floor(inputCapacity / factor)` ({§tokenomics-calibrated-readout}), and it bounds the whole packet — teaching, catalog, log and gauge together. Nothing on the service panel sizes a part of it: no projection share or preview page. When the loop's first response fixes its factor, the budget follows it either way; a room that shrinks under the model is announced by the over-budget row ({§context-over-budget-row}), never hidden by keeping a larger figure.
5165
+ - §context-gauge **One gauge.** Every packet carries one `## Context` section holding one JSON object: `tokens`, the packet's weight as rendered, and `budget`, the known room. Only when the packet without an inventory strictly exceeds `PLURNK_SERVICE_BUDGET_PRESSURE` of its budget does `largest` name the `PLURNK_SERVICE_BUDGET_LARGEST_ITEMS` heaviest retained log rows as `{path, tokens}`, ranked by weight then path. Unknown budget omits both `budget` and `largest`. The final `tokens` includes the inventory; over budget, its full configured count remains available for curation ({§context-over-budget-row}). Each log row heading carries its own `tokens`. The gauge is state: it never presents `budget − tokens` as response allowance and carries no mandate.
5166
+ - §context-pressure-notice **Pressure is one notice.** When the gauge names its inventory ({§context-gauge}) and the packet, with the notice in it, stays within its budget, the packet's notices section carries one `engine:context` notice `budget_pressure`, `level: warn`, whose directive is "YOU MUST NOT exceed budget." and whose message is "Context is at *N*% of budget." *N* is `floor(100 × tokens / budget)` over the gauge's final figures, so the share never disagrees with the gauge, and the notice carries no count of its own. It is decided and rendered with the packet it describes, recurs on every such packet, and is never buffered or sent to clients, which read their own pair ({§tokenomics-client-gauge}). An over-budget packet carries the row instead ({§context-over-budget-row}).
5167
+ - §context-fit **One rule: whole if it fits, otherwise as much as fits, then its size and address.** A result the model asked for — a READ without a scope, a FIND, an exec result delivered on close — arrives complete when its weight fits within `budget − tokens` as of that turn, less the room the turn still owes — one receipt's measured weight for each result still to land in it and the emission record that answers it, so that the receipts of a batch and the answer always fit. Otherwise the complete result stays where it was read from and the row is a `413` receipt naming the result's size, its weight, the remaining budget, and the two verbs: `READ` a range, or `KILL` first. A READ of lines carries, above its receipt, the longest prefix of those lines whose row fits that room — the lines with their anchors, the returned range closed on the last line delivered, and the receipt naming the lines delivered; a result whose first line does not fit, a FIND, a stream page and a byte view are bodiless receipts. An arrival the model did not ask for — an inbound `SEND`, a child's conclusion — takes the same bodiless receipt as a fact, not an error: its size and its address. Explicit scopes (`<a,b>`, a pattern, `<1,-1>`) are exact and take the same test. Result cuts are named where they happen: the first page of what came back unasked in size ({§markerless-first-page}) and the cut at the room in the receipt. The optional emission history is whole or absent ({§emission-history}), never a cut.
5036
5168
  - §context-verbs **The verbs are the curation.** `READ` with a range takes a piece of what did not fit ({§read-selection-projection}); `NOTE` keeps what the model learned; `KILL` retires rows, ranges and bodies ({§log-kill-scope}) and may carry what it keeps of them as its own NOTE ({§log-kill-distillation}). The daemon adds no other mechanism.
5037
5169
  - §context-over-budget-row **Over budget is a row and a request, not an ending.** A packet whose weight exceeds `budget` is still submitted when it fits the window ({§context-wall}), and it carries one `_plurnk` error row at the head of its turn, `engine/context/packet-exceeds-budget` 413: "Context exceeds budget. YOU MUST ONLY KILL, MOVE or NOTE this turn." The row is the mandate and carries no figure: the gauge is the one home for `tokens` and `budget` ({§context-gauge}), and it shows the packet over with the row in it. The row recurs on every packet that is over, and nothing is hidden to make the packet smaller; the response grant is the window's remainder above the provider's output floor ({§provider-output-floor}). The limit protects a loop; it never ends one.
5038
5170
  - §context-wall **Only the window ends a loop.** The wall is the provider's physical input limit: `maxInputTokens`, and the context window less the output floor ({§provider-output-floor}). A request over the wall sheds ({§context-own-rows-fit}) and is measured again ({§context-wall-measure}); a packet that cannot fit even as receipts ends its loop with the exact `engine/context/window-overflow` 413 Problem, and no inference request is made. An unknown window has no wall ({§tokenomics-window-unpollable-deliberate}).
5039
5171
  - §context-wall-measure **The wall measures the request that will be sent.** The estimate is the packet's weight through its calibration factor ({§tokenomics-calibrated-readout}) and is never assumed to overestimate. A packet that fits by the estimate is assessed by the provider as the exact wire request ({§provider-capacity-admission}): an admission sends it; an exact refusal is the wall's verdict, and the request sheds by the refusal's excess and is assessed again. A provider that can only estimate defers, and the upstream provider is then the capacity oracle: its refusal ends the loop with the provider's own 413.
5040
- - §context-own-rows-fit **The model's own rows take the same receipt.** When a request is over the wall by either measure ({§context-wall-measure}), its newest rows that still carry a body or a native part — NOTEs, receipts, delivered results, pictures — render bodiless in the fit rule's receipt shape, newest first and only as many as it takes for the request to fit: the heading, the facts, and `size`, the lines and tokens of what the row stood for. The optional previous program has already been omitted whole ({§previous-emission}); an emission record has no body to take. A row whose receipt would weigh no less than its body stays whole. Every body stays stored and readable at its address, the verbs restore the room ({§context-verbs}), and each packet decides afresh from its own newest rows. The daemon chooses nothing to summarize and hides nothing silently.
5172
+ - §context-own-rows-fit **The model's own rows take the same receipt.** When a request is over the wall by either measure ({§context-wall-measure}), its newest rows that still carry a body or a native part — NOTEs, receipts, delivered results, pictures — render bodiless in the fit rule's receipt shape, newest first and only as many as it takes for the request to fit: the heading, the facts, and `size`, the lines and tokens of what the row stood for. The optional emission history has already been omitted whole ({§emission-history}); an emission record has no body to take. A row whose receipt would weigh no less than its body stays whole. Every body stays stored and readable at its address, the verbs restore the room ({§context-verbs}), and each packet decides afresh from its own newest rows. The daemon chooses nothing to summarize and hides nothing silently.
5041
5173
  - §tokenomics-weight-stored-at-write **Curation weight, stored at write.** `entry_channels.weight` weighs the complete channel content. `log_entries.weight` weighs the complete canonical `LogBody` content before coordinate and packet presentation; persistence `tx`/`rx` envelopes contribute nothing merely by existing, and proposal settlement recomputes the value when the canonical result changes. Bodyless rows therefore weigh zero. The stored number is a stable content-depth measurement, not a provider-token prediction. `entry_channels.lines` is the channel's line count beside it, a stored generated column SQLite keeps on every write as the persisted mirror of {§logical-line-count} (a trailing newline terminates the last line; empty content has none), so a catalog lists extent without reading bodies.
5042
- - §tokenomics-render-weight-budget **Packet curation budget.** `tokens` measures the *complete assembled packet* after section transforms and readout substitution, its rendered slots (including {§previous-emission}) and native attachments; it is not a sum of stored row weights ({§tokenomics-weight-stored-at-write}). Core measures minimum-width probes, monotonically expands fields that do not fit, then right-aligns final values into those widths; final substitution is length-invariant and the displayed total equals the stored request weight. Receipt, FIND-item, pressure-inventory, total, and ceiling figures all use the same curation ruler. A `SUM` of stored content weights measures a different artifact and cannot substitute for packet render weight.
5043
- - §tokenomics-calibrated-readout **Convert capacity, never content costs.** Before packet assembly, Core obtains the answering model's last five settled emission responses pairing a measured packet weight with a provider-reported prompt count. The conversion factor is `sum(reported) / sum(weight)`; fewer than three samples use 1. `floor(inputCapacity / factor)` converts provider capacity into curation units, the budget ({§context-budget}); the same factor converts the packet's weight into the wall's estimate ({§context-wall-measure}). Zero means no whole curation unit fits; unknown input capacity remains `null`. The built packet captures this allowance and its factor once for its readout, pressure inventory, wall estimate, and persisted client gauge. Later responses cannot change that packet's allowance. Samples are model-keyed, not worker-local; a model with no samples starts at 1. Calibration never changes stored weights, rendered receipt costs, or the immutable request history ({§tokenomics-agnostic-ruler}).
5174
+ - §tokenomics-render-weight-budget **Packet curation budget.** `tokens` measures the *complete assembled packet* after section transforms and readout substitution, each rendered message (including {§emission-history}) and native attachments; it is not a sum of stored row weights ({§tokenomics-weight-stored-at-write}). Core measures minimum-width probes, monotonically expands fields that do not fit, then right-aligns final values into those widths; final substitution is length-invariant and the displayed total equals the stored request weight. Receipt, FIND-item, pressure-inventory, total, and ceiling figures all use the same curation ruler. A `SUM` of stored content weights measures a different artifact and cannot substitute for packet render weight.
5175
+ - §tokenomics-calibrated-readout **Convert capacity, never content costs; one factor per loop.** A sample is a settled emission response pairing its request's measured packet weight with the provider-reported prompt count, both positive. A loop's first sample from the answering model fixes the conversion factor `reported / weight` for the rest of that loop. Until then the loop's packets use that model's most recently fixed factor, from any loop or worker, and a model that has none uses 1. The budget therefore changes at most once in a loop, when its first response settles. `floor(inputCapacity / factor)` converts provider capacity into curation units, the budget ({§context-budget}); the same factor converts the packet's weight into the wall's estimate ({§context-wall-measure}). Zero means no whole curation unit fits; unknown input capacity remains `null`. The built packet captures this allowance and its factor once for its readout, pressure inventory, wall estimate, and persisted client gauge; later responses cannot change that packet's allowance. Calibration never changes stored weights, rendered receipt costs, or the immutable request history ({§tokenomics-agnostic-ruler}).
5044
5176
  - §tokenomics-window-partition **One capacity derivation; no service-side token budget.** The provider owns model limits, the configured output reservation, and each call's response grant. Its resolved `inputCapacity` supplies the physical denominator exposed to clients and the boundary conversion into curation units ({§tokenomics-calibrated-readout}). Core shapes context in curation units; provider request-shaped evidence alone admits or rejects physical I/O. Local and custom deployments tune context window, total output budget and optional reasoning subset at their owning layers.
5045
5177
  - §tokenomics-window-unpollable-deliberate **Unknown provider capacity stays unknown.** When the provider cannot derive `inputCapacity`, there is no budget: the gauge carries `tokens` alone, every result arrives whole, and the provider remains the capacity oracle ({§provider-capacity-admission}). Core never invents a stand-in.
5046
5178
 
@@ -5128,7 +5260,7 @@ ordinary operation evidence still reaches that child's direct parent.
5128
5260
 
5129
5261
  | Producer / event | Durable occurrence | Observer projection |
5130
5262
  | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
5131
- | §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. |
5263
+ | §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}), 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. |
5132
5264
  | §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. |
5133
5265
  | §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. |
5134
5266
  | §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. |
@@ -5159,7 +5291,7 @@ Stream progress remains owned by {§exec-stream}.
5159
5291
  ## §packet Packet shape
5160
5292
 
5161
5293
  §packet-markdown **The packet's Markdown projection (#626).** Core renders the transformed section list
5162
- into one system string and one user string. Within each slot, list order is
5294
+ into the ordered messages of {§packet-wire-envelope}. Within each message, section order is
5163
5295
  preserved. A nonempty section with a header renders as an H2 immediately followed
5164
5296
  by its JSON object/array content; non-JSON content has one blank line after the
5165
5297
  header. A null header renders only its content. Empty content is omitted, trailing
@@ -5180,16 +5312,16 @@ their boundaries ({§log-wire-format}).
5180
5312
  | `definition` | system | Bare `plurnk.md`; no wrapper heading | {§definition-table-projection} |
5181
5313
  | `system-policy` | system | Authored Markdown | {§policy-sections} |
5182
5314
  | `inject` | system | Authored Markdown | {§packet-inject} |
5183
- | `log` | user | Markdown H3 records with JSON metadata | {§log-wire-format} |
5315
+ | `log`, `log/<coordinate>` | user | Chronological Markdown H3 records with JSON metadata | {§log-wire-format} |
5184
5316
  | `worker` | user | JSON `path` with the literal Worker address, `parent` (address or `null`), `loop`, `turn` | {§packet-current-turn} |
5185
5317
  | `delegation` | user | JSON `{workers, streams}` | {§child-orientation} |
5186
5318
  | `errors` | user | JSON status/log-path pointers | {§operation-results} |
5187
- | `notices` | user | Terse observation bullets | {§notice-drain-on-read} |
5319
+ | `notices` | user | One alert callout per notice, directive first | {§notice-callout} |
5188
5320
  | `git` | user | Working-tree state in a NOTE blockquote | {§packet-cache-monotone} |
5189
5321
  | `budget` | user | JSON curation usage and ceiling | {§context-gauge} |
5190
5322
  | `messages` | user | JSON pointers to the loop's unanswered immutable messages, path and source | {§message-arrival} |
5191
5323
  | `recap` | user | Optional authored operational recap | {§recap} |
5192
- | `previous-emission` | user | Complete preceding content program, whole or absent; always last | {§previous-emission} |
5324
+ | `emission-history/<coordinate>` | assistant | Complete retained operations at their emission records; replay omitted whole at capacity | {§emission-history} |
5193
5325
 
5194
5326
  §packet-stored-shape **A model packet preserves the rendered request and, only
5195
5327
  when an emission is admitted, its response.** Core assembles and measures the
@@ -5202,7 +5334,7 @@ leaves the request-only record, while rejected exchanges remain in their
5202
5334
  | Turn state | `turns.packet` (the bag) + `turn_sections` rows |
5203
5335
  | ----------------------------- | ----------------------------------------------- |
5204
5336
  | No admitted model request (including initialization and local capacity rejection) | SQL `NULL`, no rows |
5205
- | Request assembled | `{ weight, attributions }` + the sections as items; the complete previous-emission section, or its empty content, is stored with the request ({§previous-emission}) |
5337
+ | Request assembled | `{ weight, attributions }` + the ordered sections as items; each selected program is stored at its emission boundary, with no empty placeholder ({§emission-history}) |
5206
5338
  | Response admitted | `{ weight, attributions, assistant, assistantRaw }` + the sections as items |
5207
5339
 
5208
5340
  §packet-items **Sections are rows over content-addressed items; the bag never holds them.**
@@ -5371,7 +5503,7 @@ retain distinct contracts and lifetimes.
5371
5503
  - **Self-explaining rows.** A problem `title` names the stable class and `detail` states the occurrence-specific cause. Producer-known operands belong in factual extensions. `stage` appears only when neighboring stages imply different recovery; `recovery` states one generally valid next action; `retryable` is true only when the producer recommends automatically retrying the identical request. Unknown recovery or retryability is omitted rather than guessed. General workflow teaching stays in the packet rather than being duplicated into every failure. The runtime-neutral writing contract is owned by `@plurnk/plurnk-contracts`.
5372
5504
  - **Exact Problems cross durable and external boundaries.** Scheme capabilities, proposal application, subscription conclusion, loop settlement, AG-UI, clients, digests, and benchmark records preserve the originating Problem object. The model packet alone derives `{§problem-projection}` without mutating that object. An adapter may add a missing durable `instance`, never replace an existing one; it must not rebuild failure truth from `status`, `detail`, `RUN_ERROR`, or a scheduler projection. A failed boundary without a valid Problem is a contract violation and fails hard.
5373
5505
  - **Caught diagnostics are bounded.** Core-owned Problems may include a bounded preview of a caught runtime diagnostic when it states the occurrence-specific cause. `PLURNK_SERVICE_ERROR_DETAIL_LIMIT` owns that model-facing character bound; complete errors remain in daemon diagnostics. Input validation and stable contract failures do not spend this allowance on implementation text.
5374
- - §notice-drain-on-read **Notices** - the few observations that are not log rows render one terse line under their distinct `## Notices` section, never a JSON dump. Packet rendering normalizes whitespace, bounds the producer message with the shared preview limits, and appends any typed position. The notice buffer drains on read; event Notices appear on at most one packet. Parking preserves pending notices for that loop's next packet; another loop cannot consume them. Terminal cleanup, including cancellation while parked, discards undelivered notices. This buffer is process-local, not restart-persistent. Stateful derivation progress and provider availability coalesce in the buffer, so clients observe every checkpoint live while a later model packet receives only the current state under ordinary level filtering.
5506
+ - §notice-drain-on-read **Notices** - the few observations that are not log rows render one callout each under their distinct `## Notices` section ({§notice-callout}), never a JSON dump. Packet rendering normalizes whitespace, bounds the producer message with the shared preview limits, and appends any typed position. The notice buffer drains on read; event Notices appear on at most one packet. Parking preserves pending notices for that loop's next packet; another loop cannot consume them. Terminal cleanup, including cancellation while parked, discards undelivered notices. This buffer is process-local, not restart-persistent. Stateful derivation progress and provider availability coalesce in the buffer, so clients observe every checkpoint live while a later model packet receives only the current state under ordinary level filtering.
5375
5507
  - §rail-accounting-private **Rail accounting is private.** Visibility is owned by {§engine-rails}: the model sees concrete failures from admitted turns, never rejected emissions, attempt counts, the strike streak, or cycle detection. Surfacing internal state creates a gamification surface where the model optimizes for engine metrics instead of the task.
5376
5508
 
5377
5509
  **The error rows (one channel) + the only non-log notices:**
@@ -5382,12 +5514,35 @@ retain distinct contracts and lifetimes.
5382
5514
  | provider input capacity | `op='error'`, origin `_plurnk`, source `provider`; exact provider-owned `capacity-exceeded` Problem Details | 413 |
5383
5515
  | max commands exceeded | `op='error'`, origin `_plurnk`, source `rail`; `engine/rail/max-commands-exceeded` Problem Details | 429 |
5384
5516
 
5385
- | notice `kind` | Source | Position |
5386
- |---|---|---|
5387
- | `output_unaccounted` | a provider whose billed output tokens exceed those its content and reasoning hold | content-offset at the end of the content |
5388
- | `parse_advisory` | grammar parser — recoverable near-miss which did not invalidate the parsed statements | content-offset into the model's emission |
5389
- | `search_progress` | repository materialization/indexing lifecycle ({§persistent-search-index}); structured phase, count, and percent; `level: info`, `warn` when a completed pass carries failed members ({§derivation-member-failure}), `error` on terminal failure | none |
5390
- | `git_inspection_refused` | engine membership — automatic Git inspection refused a supplied repository whose config declares a `filter.*` program ({§membership-git-hermetic}); names the key; `level: warn`, once per workspace until the key changes or clears | none |
5517
+ | notice `kind` | Source | Directive ({§notice-directive}) | Position |
5518
+ |---|---|---|---|
5519
+ | `output_unaccounted` | a provider whose billed output tokens exceed those its content and reasoning hold | none | content-offset at the end of the content |
5520
+ | `parse_advisory` | grammar parser — recoverable near-miss which did not invalidate the parsed statements | YOU SHOULD write the canonical form. | content-offset into the model's emission |
5521
+ | `search_progress` | repository materialization/indexing lifecycle ({§persistent-search-index}); structured phase, count, and percent; `level: info`, `warn` when a completed pass carries failed members ({§derivation-member-failure}), `error` on terminal failure | none | none |
5522
+ | `git_inspection_refused` | engine membership — automatic Git inspection refused a supplied repository whose config declares a `filter.*` program ({§membership-git-hermetic}); names the key; `level: warn`, once per workspace until the key changes or clears | none | none |
5523
+ | `continued_without_note` | engine turn — a continuing or parked model turn that admitted no NOTE ({§continued-without-note}); `level: warn` | YOU MUST use at least one NOTE per continuing turn. | none |
5524
+ | `budget_pressure` | engine context — a packet within its budget whose gauge is under pressure ({§context-pressure-notice}); `level: warn`; rendered with that packet, never buffered | YOU MUST NOT exceed budget. | none |
5525
+ | `outside_text` | engine turn — text the emission carried outside its operations, discarded ({§outside-text}); `level: warn` | YOU MUST NOT emit anything except whitespace between fenced operations. | none |
5526
+ | `invalid_emission` | engine grammar — a response rejected before dispatch; `level: error` | YOU MUST ONLY emit fenced operations; with the parameters, pattern, and terse aside on the fenced Operation line. | content-offset of the parser diagnostic, when it has one |
5527
+ | `output_truncated` | engine capacity or turn — an emission cut at the output allowance ({§output-allowance-notice}); `level: error` when the cut response was rejected, otherwise `warn` | YOU SHOULD emit fewer or shorter operations per turn. | none |
5528
+ | `provider_warning` | a provider warning: an SDK compatibility note, or native tool calls in a response that declared none; `level: warn` | YOU MUST NOT emit native tool calls. on the native tool calls; none on a compatibility note | none |
5529
+ | `provider_retry` | a provider stream that failed after output began and was answered by a complete retry; `level: warn` | none | none |
5530
+ | `provider_unavailable` | engine provider — a provider failure retried within its recovery budget | none | none |
5531
+ | `path_normalized` | file scheme — a path resolved to its canonical spelling; `level: warn` | YOU SHOULD address the resolved path. | none |
5532
+ | `read_fanout_bounded` | engine dispatcher — a READ whose glob matched more paths than it read; `level: warn` | YOU SHOULD narrow the glob, or FIND first. | none |
5533
+ | `parse_issues_unavailable` | engine mimetype — parser recovery evidence unavailable for a mimetype; `level: warn` | none | none |
5534
+ | `metadata_ignored` | engine dispatcher — `[metadata]` on an operation whose scheme takes none, run without it; `level: warn` | YOU SHOULD NOT write [metadata] on an operation that takes none. | none |
5535
+ | `scope_normalized` | engine slicer — a scope normalized to its canonical form; `level: warn` | YOU SHOULD write the normalized scope. | none |
5536
+ | `edit_merged` | engine slicer — an EDIT resolution rule applied to a batch ({§edit-batch-merges}); `level: warn` | YOU SHOULD verify the merged EDIT before building on it. | none |
5537
+
5538
+ §continued-without-note **A continuing turn that lapsed from the per-turn rule is told so.** The card's rule is one line, `YOU MUST emit at least one NOTE operation with a complete status summary and at least one other operation per turn.`, and the daemon's directive quotes it. When a model turn settles at 102 or 202, so the loop continues past it or parks on it, and it admitted no NOTE in its program or from its reasoning ({§reasoning-operations}), the next packet carries one `engine:turn` notice, `continued_without_note`, `level: warn`, with that directive and the message `The turn continued without a NOTE.`; when its program was NOTEs and nothing else, the next packet carries `noted_without_operation`, the same directive and the message `The turn carried NOTEs and no other operation.` Each is a notice, never a failure: it mints no row, never counts toward the strike rail, and never ends or alters a loop. A turn that concludes its loop, an empty turn, which carries its own no-operation row, and every non-model turn take none.
5539
+
5540
+ §notice-callout **A notice speaks in the card's callout form.** Each renders as one alert callout, its level choosing the callout: `> [!CAUTION]` for `error`, `> [!WARNING]` for `warn`, and `> [!NOTE]` for `info`, which no model packet carries. Inside it stand the directive ({§notice-directive}), then the message, any typed position as `@ line:column`, and the kind in brackets; a blank line separates consecutive callouts:
5541
+
5542
+ ```text
5543
+ > [!WARNING]
5544
+ > YOU MUST use at least one NOTE per continuing turn. The turn continued without a NOTE. [continued_without_note]
5545
+ ```
5391
5546
 
5392
5547
  §notice-level **Severity on the wire (`level`, required).** Every `Notice` carries `level: "error" | "warn" | "info"`, set by the **producer** at the emit site. The level is client presentation, not operation status: even an `error` notice cannot terminalize work or substitute for a durable Problem. A forwarded `output_unaccounted` is `warn`; ordinary lifecycle and progress notices are `info`. Clients color straight off `level` without interpreting the open `kind` vocabulary.
5393
5548
 
@@ -5428,7 +5583,7 @@ USD and token totals with separately named known subtotals across every physical
5428
5583
  calls included. It is the shared exact derivation from the ledger, never a second
5429
5584
  stored fact, so a live watcher accrues running loop cost per turn (#465).
5430
5585
 
5431
- §notice-content-offset-pointer **Content-offset position.** A non-fatal diagnosis on an accepted emission (for example `output_unaccounted` or `parse_advisory`) carries `position: { type: "content-offset", line, column }` into the model's exact `ops://<worker>/<loop>/<turn>` source; the optional previous-emission section shows a canonical program ({§previous-emission}), so the position names a line of the source, which READ of its address shows. A bounded hard parse error becomes a durable failed operation whose Problem Details preserve its line, column, source, and parser-owned diagnostic. Hard errors that make the frame untrustworthy remain only with their rejected forensic attempt.
5586
+ §notice-content-offset-pointer **Content-offset position.** A non-fatal diagnosis on an accepted emission (for example `output_unaccounted` or `parse_advisory`) carries `position: { type: "content-offset", line, column }` into the model's exact `ops://<worker>/<loop>/<turn>` source; the optional emission-history section shows a canonical program ({§emission-history}), so the position names a line of the source, which READ of its address shows. A bounded hard parse error becomes a durable failed operation whose Problem Details preserve its line, column, source, and parser-owned diagnostic. Hard errors that make the frame untrustworthy remain only with their rejected forensic attempt.
5432
5587
  Reasoning normalization notices use source `grammar:reasoning` and omit the
5433
5588
  content-offset position: reasoning coordinates do not address the content source.
5434
5589
 
@@ -5646,6 +5801,13 @@ one dormant authored source. A failed read fails packet assembly with its cause.
5646
5801
  The footer is one projection path and one authored source, not a second language
5647
5802
  contract.
5648
5803
 
5804
+ §recap-lines The operator's recap lines lead the footer: every non-empty
5805
+ `PLURNK_SERVICE_RECAP_LINE_<alias>`, in alias order, renders as one callout ahead of the recap
5806
+ source, `> [!IMPORTANT]` for a `YOU MUST` line and `> [!TIP]` for `YOU SHOULD` and `YOU MAY`. A line
5807
+ that does not open with `YOU MUST`, `YOU MUST NOT`, `YOU MUST ONLY`, `YOU SHOULD`, `YOU SHOULD NOT` or
5808
+ `YOU MAY` is a configuration error naming its key, and an empty value turns a shipped line off. The
5809
+ shipped `recap.md` stays empty: it is the extension contract's source, not a home for core's lines.
5810
+
5649
5811
  ## Matcher selection and text regions
5650
5812
 
5651
5813
  Matchers select resources and report evidence; text scopes independently
@@ -5971,8 +6133,10 @@ database is a benchmark artifact like any other: the lane's run directory lives
5971
6133
  checkout holds source only — never run output. `test:intg` stamps `PLURNK_TEST_RUN` once and every
5972
6134
  test process inherits it, so one suite's databases land in one directory without a pretest step, a
5973
6135
  marker file or a sweep; an unstamped invocation is not a special case with its own rules, it is
5974
- simply an unstamped run with its own directory. A stamped run that passes is reclaimed when it
5975
- 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
6136
+ simply an unstamped run with its own directory. A lane whose suite boots Core through Core's test
6137
+ harness also exports `PLURNK_TEST_LANE`, its own lane name, so the daemon it boots writes into that
6138
+ lane's run directory and the lane's reclaim takes all of it; an unnamed run is Core's. A stamped run
6139
+ that passes is reclaimed when it 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
5976
6140
  caller's own run directory.
5977
6141
 
5978
6142
  §fs-world-state **The world-state harness — coverage that closes the class.** Op-outcome tests check what an op returned; the harness checks the resulting world. `WorldState.check(db)` asserts, pure-db and read-only: identity uniqueness in practice (no tuple holds two rows), the canonical fixpoint on every file-class key, channel orphan-freedom, the closed admission set (every file row's origin is Git or constraint), and sig-coherence. Generated-pick incorporation and lifecycle require filesystem/Git evidence and are covered by the composed creation matrix rather than a false pure-database proxy. The harness runs as a lifecycle-test epilogue and at every soak turn boundary, where the delta half applies: an idle turn grows the entries table by ZERO. A violation names its law and its row.
@@ -5999,6 +6163,7 @@ Every Problem code core mints is named here under its family ({§problem-error-c
5999
6163
  | `capability-denied` | 403 | Capability '*route*' is denied by *scope* policy. |
6000
6164
  | `spawn-prompt-empty` | 422 | *OP* has no prompt text. Recovery: Write the prompt on the lines beneath the *OP* fence line. A prompt resource that is empty with no body says so: *OP* has no prompt text: the resource is empty and there is no body. Recovery: Write the prompt on the lines beneath the *OP* fence line, or name a resource that holds it. |
6001
6165
  | `message-not-found` | 404 | No accepted message exists at *address*. |
6166
+ | `send-target-required` | 400 | SEND has no recipient and its loop has no published message. Recovery: Name a recipient address. |
6002
6167
  | `edit-collision` | 409 | EDIT collided with the current resource state ({§edit-collision}). Recovery: *n* of *m* edits applied. READ the target for current coordinates. |
6003
6168
  | `edit-target-required` | 400 | A line-anchored EDIT requires a target resource. Recovery: Provide the target that rendered the line anchor. |
6004
6169
  | `kill-target-required` | 400 | KILL requires a target path. |
@@ -6011,7 +6176,7 @@ Every Problem code core mints is named here under its family ({§problem-error-c
6011
6176
  | `metadata-unsupported` | 400 | *OP* takes only the env option; '*key*' is not one. |
6012
6177
  | `worker-name-conflict` | 409 | Worker '*name*' already exists in this workspace. |
6013
6178
  | `no-operation` | 422 | The turn performed no operation ({§empty-turn}). |
6014
- | `send-target-not-a-recipient` | 400 | The addressed scheme is not a SEND recipient. Recovery: A targetless SEND answers the open messages; a directed SEND requires a recipient that implements SEND. |
6179
+ | `send-target-not-a-recipient` | 400 | The addressed scheme is not a SEND recipient. Recovery: Name a message address or a recipient that implements SEND. |
6015
6180
 
6016
6181
  §unregistered-scheme-recovery **An unregistered scheme's refusal names what does exist.** Its recovery
6017
6182
  lists the schemes the workspace registers, and rebuilds the address into nothing else
@@ -6106,15 +6271,18 @@ lists the schemes the workspace registers, and rebuilds the address into nothing
6106
6271
  | sentence | arises when |
6107
6272
  |---|---|
6108
6273
  | Nothing is in flight. Continuing. | a WAIT (or a premature terminal) with no live work ({§wait-obligation-matrix}) |
6109
- | Completion deferred. Conclude with KILL alone. | a concluding KILL that carries other operations ({§kill-conclusion}) |
6274
+ | All Open Messages resolved. Review new results; emit no OPs if finished. | resolved messages with unobserved results ({§loop-completion}) |
6110
6275
  | Context exceeds budget. YOU MUST ONLY KILL, MOVE or NOTE this turn. | the over-budget row ({§context-over-budget-row}) |
6276
+ | YOU MUST NOT exceed budget. Context is at *N*% of budget. | a packet within its budget under pressure ({§context-pressure-notice}) |
6277
+ | YOU MUST use at least one NOTE per continuing turn. The turn continued without a NOTE. | a continuing or parked model turn without a NOTE ({§continued-without-note}) |
6278
+ | Each directive in the notice table | a notice of the model's own output ({§notice-directive}) |
6111
6279
  | Context window overflow: the packet cannot fit the model's window even as receipts. | the wall ({§context-wall}) |
6112
6280
  | No recipient implements the requested interaction. | The worker's owner is not interactive or does not declare the required client tool ({§client-interaction-routing}). |
6113
6281
  | Nobody is present to answer. Decide from what you already have, or conclude stating what you could not resolve. | dispatch of an interaction tool the worker's owner would not receive ({§owner-interaction-ring}) |
6114
6282
  | Worker name '*name*' must match `[A-Za-z0-9][A-Za-z0-9_-]{0,62}`. Recovery: Use 1–63 ASCII letters, digits, '_' or '-', starting with a letter or digit. | an invalid worker name |
6115
6283
  | Provide the client identifier. / Provide an absolute project path. / Use a positive integer limit. / prompt is not a non-empty string. | client input validation on the daemon's methods |
6116
6284
  | The stream was cancelled by KILL. | a stream terminal after KILL |
6117
- | '*program*' exited with code *n*. | an execution's non-zero exit |
6285
+ | '*runtime*' exited with code 127; `*program*` is a registered tool of `*owner*`. | a tool run as a shell command ({§exec-tool-fall-through}) |
6118
6286
  | '*path*' is a directory, not a file; READ reads one file. Recovery: `FIND (_path_/)` lists its files. | READ of a directory |
6119
6287
  | The execution at ops://*worker*/*loop* has not concluded. | a bare READ of a running worker's result (425) |
6120
6288
  | The child provider failed. | a child's provider failure read back by its parent |