@plurnk/plurnk-service 1.22.0 → 1.24.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.
- package/.env.defaults +4 -0
- package/SPEC.md +293 -36
- package/dist/build-info.json +1 -1
- package/dist/content/body-preview.js +1 -1
- package/dist/content/body-preview.js.map +1 -1
- package/dist/content/edit-receipt.d.ts.map +1 -1
- package/dist/content/edit-receipt.js +3 -10
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/line-anchors.d.ts.map +1 -1
- package/dist/content/line-anchors.js +7 -9
- package/dist/content/line-anchors.js.map +1 -1
- package/dist/content/matcher.js +1 -1
- package/dist/content/matcher.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +3 -2
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
- package/dist/core/AdmittedTurnExecutor.js +16 -1
- package/dist/core/AdmittedTurnExecutor.js.map +1 -1
- package/dist/core/BudgetReadout.js +1 -1
- package/dist/core/BudgetReadout.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +13 -8
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +53 -17
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/EditMutations.js +2 -2
- package/dist/core/EditMutations.js.map +1 -1
- package/dist/core/Engine.d.ts +8 -19
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +22 -19
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +22 -0
- package/dist/core/ErrorDetail.d.ts +3 -4
- package/dist/core/ErrorDetail.d.ts.map +1 -1
- package/dist/core/ErrorDetail.js +3 -18
- package/dist/core/ErrorDetail.js.map +1 -1
- package/dist/core/ExecutorRegistry.js +1 -1
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/FabricatedLog.d.ts +2 -0
- package/dist/core/FabricatedLog.d.ts.map +1 -1
- package/dist/core/FabricatedLog.js +18 -7
- package/dist/core/FabricatedLog.js.map +1 -1
- package/dist/core/HostPaths.d.ts +1 -0
- package/dist/core/HostPaths.d.ts.map +1 -1
- package/dist/core/HostPaths.js +39 -13
- package/dist/core/HostPaths.js.map +1 -1
- package/dist/core/LogBody.d.ts.map +1 -1
- package/dist/core/LogBody.js +9 -8
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LogEntryProjection.d.ts +1 -0
- package/dist/core/LogEntryProjection.d.ts.map +1 -1
- package/dist/core/LogEntryProjection.js +10 -0
- package/dist/core/LogEntryProjection.js.map +1 -1
- package/dist/core/LoopDriver.js +1 -1
- package/dist/core/LoopDriver.js.map +1 -1
- package/dist/core/LoopPolicies.js +1 -1
- package/dist/core/LoopPolicies.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts +1 -0
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +23 -3
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/PacketBuilder.sql +3 -1
- package/dist/core/ProposalLifecycle.d.ts +9 -13
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +5 -7
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProviderRecovery.d.ts.map +1 -1
- package/dist/core/ProviderRecovery.js +2 -7
- package/dist/core/ProviderRecovery.js.map +1 -1
- package/dist/core/SchemeRegistry.d.ts +2 -1
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +10 -2
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +10 -10
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +31 -41
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/file-materialization.d.ts.map +1 -1
- package/dist/core/file-materialization.js +4 -3
- package/dist/core/file-materialization.js.map +1 -1
- package/dist/core/git-env.d.ts.map +1 -1
- package/dist/core/git-env.js +2 -7
- package/dist/core/git-env.js.map +1 -1
- package/dist/core/git-state.js +1 -1
- package/dist/core/git-state.js.map +1 -1
- package/dist/core/notifications.d.ts +17 -0
- package/dist/core/notifications.d.ts.map +1 -0
- package/dist/core/notifications.js +2 -0
- package/dist/core/notifications.js.map +1 -0
- package/dist/core/packet-inject.d.ts.map +1 -1
- package/dist/core/packet-inject.js +2 -3
- package/dist/core/packet-inject.js.map +1 -1
- package/dist/core/packet-wire.d.ts +10 -2
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +97 -22
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/teaching.js +1 -1
- package/dist/core/teaching.js.map +1 -1
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +19 -3
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/DigestRender.d.ts +3 -1
- package/dist/digest/DigestRender.d.ts.map +1 -1
- package/dist/digest/DigestRender.js +219 -1
- package/dist/digest/DigestRender.js.map +1 -1
- package/dist/digest/DigestRequiem.d.ts.map +1 -1
- package/dist/digest/DigestRequiem.js +12 -14
- package/dist/digest/DigestRequiem.js.map +1 -1
- package/dist/digest/digest-rows.d.ts +34 -0
- package/dist/digest/digest-rows.d.ts.map +1 -1
- package/dist/digest/digest-rows.js +1 -1
- package/dist/digest/digest-rows.js.map +1 -1
- package/dist/digest/digest.sql +26 -0
- package/dist/launch/Launch.d.ts +49 -0
- package/dist/launch/Launch.d.ts.map +1 -0
- package/dist/launch/Launch.js +179 -0
- package/dist/launch/Launch.js.map +1 -0
- package/dist/observe/spans.d.ts +1 -1
- package/dist/observe/spans.d.ts.map +1 -1
- package/dist/observe/spans.js +5 -64
- package/dist/observe/spans.js.map +1 -1
- package/dist/schemes/EffectPolicy.js +1 -1
- package/dist/schemes/EffectPolicy.js.map +1 -1
- package/dist/schemes/Exec.d.ts +2 -2
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +20 -16
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecutionInput.d.ts.map +1 -1
- package/dist/schemes/ExecutionInput.js +2 -5
- package/dist/schemes/ExecutionInput.js.map +1 -1
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +6 -1
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +25 -3
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +2 -6
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-manifest.js +1 -1
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_search-index.d.ts.map +1 -1
- package/dist/schemes/_search-index.js +2 -8
- package/dist/schemes/_search-index.js.map +1 -1
- package/dist/schemes/exec-abort.js +1 -1
- package/dist/schemes/exec-abort.js.map +1 -1
- package/dist/schemes/exec-lifetime.d.ts.map +1 -1
- package/dist/schemes/exec-lifetime.js +2 -1
- package/dist/schemes/exec-lifetime.js.map +1 -1
- package/dist/server/ClientReads.d.ts +1 -1
- package/dist/server/ClientReads.d.ts.map +1 -1
- package/dist/server/ClientReads.js +1 -1
- package/dist/server/ClientReads.js.map +1 -1
- package/dist/server/Daemon.d.ts +10 -7
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +12 -3
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +2 -63
- package/dist/server/DaemonModule.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +10 -1
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/EnvFunctionality.d.ts +2 -1
- package/dist/server/EnvFunctionality.d.ts.map +1 -1
- package/dist/server/EnvFunctionality.js.map +1 -1
- package/dist/server/Functionality.d.ts +2 -1
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts +2 -1
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +1 -1
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/SkillsFunctionality.d.ts +2 -1
- package/dist/server/SkillsFunctionality.d.ts.map +1 -1
- package/dist/server/SkillsFunctionality.js +1 -1
- package/dist/server/SkillsFunctionality.js.map +1 -1
- package/dist/server/WorkspaceResidency.d.ts +2 -1
- package/dist/server/WorkspaceResidency.d.ts.map +1 -1
- package/dist/server/WorkspaceResidency.js.map +1 -1
- package/dist/server/client-input.d.ts +1 -1
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +1 -0
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/envelope.d.ts +2 -9
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +2 -2
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +6 -3
- package/dist/server/logEntry.d.ts +1 -31
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/model-catalog.js +1 -1
- package/dist/server/model-catalog.js.map +1 -1
- package/dist/server/module-discovery.d.ts.map +1 -1
- package/dist/server/module-discovery.js +4 -22
- package/dist/server/module-discovery.js.map +1 -1
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +4 -1
- package/dist/service.js.map +1 -1
- package/docs/env.md +18 -0
- package/migrations/012_emission.sql +77 -0
- package/package.json +38 -34
- package/dist/core/Knob.d.ts +0 -9
- package/dist/core/Knob.d.ts.map +0 -1
- package/dist/core/Knob.js +0 -50
- package/dist/core/Knob.js.map +0 -1
package/SPEC.md
CHANGED
|
@@ -224,6 +224,32 @@ before provider or capability initialization can perform external work. Every
|
|
|
224
224
|
later startup failure closes resources in reverse ownership order while
|
|
225
225
|
preserving the originating failure: daemon, observability, database, listener.
|
|
226
226
|
|
|
227
|
+
§startup-readiness-line **Readiness is one stdout line.** After the client interface is mounted
|
|
228
|
+
the service prints exactly one line, `plurnk-service agui=<url> db=<json string> route=<json string>`:
|
|
229
|
+
the URL brackets an IPv6 host, and the database path and the route (the active model route or
|
|
230
|
+
`no model`) are JSON strings, so a path or route containing spaces is exact and a consumer parses
|
|
231
|
+
the URL as a URL and the strings as JSON; nothing else the service prints on stdout before it has
|
|
232
|
+
that prefix. Before the line the listener answers `503 service-starting`; after it,
|
|
233
|
+
`discover` is the identity check a launcher uses to tell this daemon from any other listener. A bind
|
|
234
|
+
failure is an exit with the originating address error and means *occupied*, not *foreign* — another
|
|
235
|
+
plurnk-service may be starting there, and only `discover` says which.
|
|
236
|
+
|
|
237
|
+
§daemon-launch **The service ships its own launcher; launchers own policy.** `@plurnk/plurnk-service/launch`
|
|
238
|
+
spawns a daemon argv with the caller's environment, an optional {§state-root}, host and port, and
|
|
239
|
+
resolves on the readiness line with the published address, database path, route and a `stop()` that
|
|
240
|
+
is SIGTERM, a stated grace, then SIGKILL, resolving when the process has ended. It holds no timing of
|
|
241
|
+
its own: the caller states the readiness timeout and the stop grace. A start that fails — spawn error,
|
|
242
|
+
exit before readiness, or timeout — is stopped and awaited before the failure is thrown with its kind
|
|
243
|
+
and both output streams; the helper never creates, keeps or removes state. A shared daemon survives
|
|
244
|
+
the launcher that started it (scheduled deliveries, other clients and inbound A2A depend on it); a
|
|
245
|
+
private daemon is its launcher's child and ends with it under managed shutdown. The launcher
|
|
246
|
+
spawns either: `lifetime: "private"` (the default) pipes both streams to the launcher; `lifetime:
|
|
247
|
+
"shared"` puts the daemon in its own process group with both streams appended to the caller's
|
|
248
|
+
`logFile`, reads readiness from that file, and releases the process once ready, so the launcher may
|
|
249
|
+
exit while the daemon runs on and no output accumulates in a launcher that has left; until
|
|
250
|
+
readiness the launcher owns it either way, and `stop()` ends it while the launcher lives. Shell and container
|
|
251
|
+
launchers consume the same contract by reading the line themselves.
|
|
252
|
+
|
|
227
253
|
## §actor-boundary Workers and workspace boundaries
|
|
228
254
|
|
|
229
255
|
```mermaid
|
|
@@ -352,7 +378,7 @@ direct-entry-plus-directory count; `-1` enables the ordinary markerless page;
|
|
|
352
378
|
unset / `0` disables previews. `log://` is absent because the current worker's
|
|
353
379
|
log already renders in present mode.
|
|
354
380
|
|
|
355
|
-
§worker-initialization-entry **Model-worker initialization is a real `_plurnk` turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its reasoning and program are stored before execution. NOTEs from its reasoning and program, the orienting READ/FIND surveys, and the reasoning
|
|
381
|
+
§worker-initialization-entry **Model-worker initialization is a real `_plurnk` turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its reasoning and program are stored before execution. NOTEs from its reasoning and program, the orienting READ/FIND surveys, and the reasoning READ in {§reasoning-initial-read} execute under {§op-execution-order}. Its program is announced at `log:///1/1/1/emission` ({§emission-row}) and supplies the worked example as the first request's assistant message ({§packet-wire-envelope}); no program READ, actionless source row or simulated READ is added. Every orienting row is structurally classified `_plurnk` and `init`. The namespace surveys and their asides follow {§actor-boundary-catalog-preview}.
|
|
356
382
|
|
|
357
383
|
Incoming messages publish once as inbound SEND rows in the first model turn
|
|
358
384
|
({§message-arrival}); initialization neither READs nor archives them. The turn
|
|
@@ -586,6 +612,8 @@ Worker control rides the daemon's inject seam (active→fold, idle→enqueue+dra
|
|
|
586
612
|
|
|
587
613
|
## §membership File membership and project roots
|
|
588
614
|
|
|
615
|
+
A file is a member of a workspace when Git tracks it or a members definition includes it and none excludes it; only members can be READ, found by FIND, or changed by EDIT, and every member path resolves under the project root.
|
|
616
|
+
|
|
589
617
|
The project-file path has two explicit reconciliation gates. Internal entries do
|
|
590
618
|
not participate in this disk loop.
|
|
591
619
|
|
|
@@ -1065,11 +1093,21 @@ append-only log high-water mark. Every log-targeted KILL in the program resolves
|
|
|
1065
1093
|
row membership at or below that same boundary, while prior curation effects still
|
|
1066
1094
|
compose normally. Message arrivals and other pre-program rows already present in the turn
|
|
1067
1095
|
remain selectable; preceding and later operation rows cannot be captured by
|
|
1068
|
-
their own program.
|
|
1096
|
+
their own program. The emission row ({§emission-row}) is written after the snapshot, so the
|
|
1097
|
+
program it announces cannot select it; a later program can. A directly dispatched
|
|
1069
1098
|
single operation captures the equivalent boundary before dispatch. This limits
|
|
1070
1099
|
only log-row selection: operation phasing and same-turn resource effects retain
|
|
1071
1100
|
their ordinary contracts.
|
|
1072
1101
|
|
|
1102
|
+
### §engine-notifications One bundle of daemon callbacks
|
|
1103
|
+
|
|
1104
|
+
The daemon's observation callbacks — stream, reasoning, outside-text and packet
|
|
1105
|
+
events, worker wake, inject and cancel, operation settlement, notices — are one
|
|
1106
|
+
declared bundle (`EngineNotifications`). The Engine receives them flat, carries
|
|
1107
|
+
them as one value, and every consumer reads the callbacks it uses from that
|
|
1108
|
+
value; adding one is a declaration and a use, never an edit to the constructors
|
|
1109
|
+
between. Scheme contexts still expose the specific callbacks a handler may call.
|
|
1110
|
+
|
|
1073
1111
|
### §engine-rails Engine rails
|
|
1074
1112
|
|
|
1075
1113
|
After each admitted turn, one inline verdict decides whether the loop continues.
|
|
@@ -1221,7 +1259,7 @@ Three current entry points:
|
|
|
1221
1259
|
|
|
1222
1260
|
### Engine → provider guarantees
|
|
1223
1261
|
|
|
1224
|
-
- `messages` is a complete prompt (the section list, pre-assembled into the
|
|
1262
|
+
- `messages` is a complete prompt (the section list, pre-assembled into the wire envelope, {§packet-wire-envelope}). Provider does not reorder.
|
|
1225
1263
|
- §provider-guarantees-signal-wired `signal` is wired to the worker's AbortController.
|
|
1226
1264
|
- §provider-guarantees-serial-attempts Emission attempts for one engine turn are serial. They reuse the exact messages, coordinates, generation limits, and strike state; two attempts for that turn never overlap.
|
|
1227
1265
|
- BARE calls admitted by one turn launch as one parallel batch; each call retains independent observer and failure state, and the engine awaits the complete batch before committing results in authored order ({§bare-inference}).
|
|
@@ -1240,10 +1278,10 @@ The parser owns its boundaries; core admits determinate work and exposes its fai
|
|
|
1240
1278
|
| Outside response text | Store it as the turn's `outside` source under {§outside-text}; never a row, never delivered, never completion. |
|
|
1241
1279
|
| Lost boundary after a closed operation | Admit the closed operations and record the boundary diagnostic under {§unparsed-tail-boundary}. |
|
|
1242
1280
|
| Lost boundary before any closed operation | Reject the attempt; neither outside text nor a reasoning NOTE substitutes for a closed response operation. |
|
|
1243
|
-
| Outside text carrying a log-entry heading | Reject the attempt ({§fabricated-log-entry}). |
|
|
1281
|
+
| Outside text carrying a log-entry heading, other than an emission row's | Reject the attempt ({§fabricated-log-entry}). |
|
|
1244
1282
|
| A response the provider stopped at a repeated line | Reject the attempt with the provider's sentence as its diagnostic ({§repetition-stop}); no provider recovery, notice, or problem row. |
|
|
1245
1283
|
|
|
1246
|
-
§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. Write the operation, then wait for its receipt. `` Text inside an operation body is not examined, so a SEND or KILL may quote a receipt. 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.
|
|
1284
|
+
§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. Write the operation, then wait for its receipt. `` 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: the transcript shows it before each of the worker's own emissions ({§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.
|
|
1247
1285
|
|
|
1248
1286
|
Warnings and closer recovery ({§closer-fallback}) do not reject. `finish=length`
|
|
1249
1287
|
discloses truncation and precludes completion; it is not independently a rejection.
|
|
@@ -1547,7 +1585,7 @@ Registration precedes loop affinity:
|
|
|
1547
1585
|
- §anchor-offset **An anchor offset is tolerated, never taught (#749).** A line mark may carry an offset from its anchor (`@abcde+1`, `@abcde-2`), and a bare `+N` after an anchor counts from that anchor (`<@abcde,+1>`). The anchor resolves as usual and the offset is added; a result before line 1 is an invalid mark, and past the end is the ordinary range refusal. Continuity and current-anchor preconditions check the anchor's own line. No teaching text, scope table or receipt mentions offsets; `plurnk.md` keeps its two anchor forms. A bare `+N` with no anchor before it is refused as before.
|
|
1548
1586
|
- §edit-batch **One compound operation may require atomic splices.** The scheme's `editBatch` primitive validates all supplied numeric edits against one snapshot and commits one revision or none. Core supplies one statement for an authored EDIT; same-resource MOVE can supply multiple splices as one operation. This primitive does not group separate authored operations. Its replacement, insertion, conflict, and receipt rules remain owned by the shared Slicer.
|
|
1549
1587
|
- §edit-batch-receipt **A refusal describes its own unapplied work.** An anchor collision lists every distinct unresolved anchor in that EDIT, including both range endpoints, in `unresolvedAnchors` (`anchor`, `kind: missing | ambiguous`, and matching `lines` when ambiguous). Missing is not proof of earlier validity or subsequent change. It carries `editCount: 1`, `applied: 0`, and recovery directing a READ for current coordinates; it makes no claim about other operations. A refused compound splice batch lists all conflicting pairs in `conflicts`, non-conflicting regions in `cleanRegions`, its first pair in `conflictingRegions`, and its own `editCount` and `applied: 0`.
|
|
1550
|
-
- §edit-batch-merges **Normalizations require evidence and a receipt.** An EDIT body carrying only this resource's published
|
|
1588
|
+
- §edit-batch-merges **Normalizations require evidence and a receipt.** An EDIT body carrying only this resource's published `L<@xxxxx>` prefixes (the number right-aligned) is stripped when those prefixes verify against current anchors or this worker's preserved READ receipts (`rendered-prefix-stripped`); otherwise it remains literal content (`rendered-prefix-unverified`). Within a single atomic splice batch, the Slicer can deduplicate identical regions/bodies, concatenate same-boundary insertions, assign a shared endpoint to the sole body reproducing that line, or relocate an inner change when its original content occurs exactly once in the outer body. An already-applied inner body can be dropped. Unevidenced overlap remains a collision. These batch resolutions never reinterpret separate authored EDITs. Applied normalizations carry their exact merge facts and a notice; receipts describe only the applied effects.
|
|
1551
1589
|
|
|
1552
1590
|
### Cross-scheme orchestration
|
|
1553
1591
|
|
|
@@ -1907,9 +1945,11 @@ anchors from the complete canonical selected channel before applying the
|
|
|
1907
1945
|
authored text slice; its durable result retains the canonical derivation
|
|
1908
1946
|
identity and anchors aligned with returned lines. Packet rendering right-aligns
|
|
1909
1947
|
`L` to the decimal width of the complete canonical selected channel's final
|
|
1910
|
-
addressable line and emits
|
|
1911
|
-
|
|
1912
|
-
|
|
1948
|
+
addressable line and emits `L<@xxxxx><content>` with `L` right-aligned to that
|
|
1949
|
+
width, the scope literal as the delimiter, the content beginning after `>`. The anchor
|
|
1950
|
+
stands against its own text and never opens the row after the previous line's text —
|
|
1951
|
+
the placement that reads correctly at long context on every model measured (#893); a
|
|
1952
|
+
source line therefore retains the same prefix across projections of one revision.
|
|
1913
1953
|
An explicit default-channel fragment and its fragmentless spelling share that
|
|
1914
1954
|
identity; a selected non-default channel retains its canonical `#channel`.
|
|
1915
1955
|
|
|
@@ -2134,7 +2174,7 @@ same transitions the dispatcher's atomic curation event makes, without the row.
|
|
|
2134
2174
|
The initialization turn records a short `_plurnk`-authored rationale containing
|
|
2135
2175
|
a fenced NOTE. The shared reasoning extractor ({§reasoning-notes}) executes that
|
|
2136
2176
|
NOTE through ordinary dispatch, creating its log item and immutable source.
|
|
2137
|
-
The program begins with its own NOTE and READs its reasoning
|
|
2177
|
+
The program begins with its own NOTE and READs its reasoning,
|
|
2138
2178
|
demonstrating both NOTE placements and their ordinary results. The initial message arrives separately as an
|
|
2139
2179
|
inbound SEND ({§message-arrival}). Neither initialization nor later turns
|
|
2140
2180
|
manufacture a task inventory.
|
|
@@ -2158,7 +2198,7 @@ a turn whose emission or reasoning carries a foreign tool-call grammar or leaked
|
|
|
2158
2198
|
|
|
2159
2199
|
AST: `{ op: "KILL", target, matcher: MatcherBody | null, lineMarker: TextLineMarker | null, body: null }` ({§kill-scope} and {§matcher-option} in the contracts SPEC own the grammar).
|
|
2160
2200
|
|
|
2161
|
-
KILL deletes context from the **log** (`log:///`, {§packet}). Without a scope it retires the selected rows from the active projection ({§log-history-projection}). With a one-line or inclusive two-line scope it removes only that body's intersecting body-relative physical lines from the readable projection, and the row stays active. An anchor may be one published on that body or one returned by READing its `log:///` coordinate ({§line-anchors}); an anchor absent from the current body selects no line, as with an out-of-bounds numeric line. Scoped KILL is one-way: intervals accumulate, the durable body is untouched, and subsequent access follows {§log-readable-projection}. A scoped KILL on a bodyless row is a friendly 200 no-op with `matched` reported. A KILL that addresses no row is 404 on an exact coordinate and 204 on a sweep ({§log-curation-folder-idiom}). Selection composes target/glob with an optional heading pattern ({§log-curation-set-selection}). Parameterless KILL instead requests completion ({§kill-conclusion}).
|
|
2201
|
+
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}).
|
|
2162
2202
|
|
|
2163
2203
|
§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 — `Write <1,-1> to trim every line of the body; KILL (log:///1/9/2/READ) with no scope retires the whole row.`, or `To trim lines 1 through M, write <1,M>; …` — never the insert and append positions a body cannot take. Every other scope that names no line is 400 `curation-scope-invalid` and likewise names the model's mistake in its coordinates and the forms that work on that row: `<0>` offers `<1>`; an end below 1 offers `<L,-1>`; a backward `<5,3>` offers `<3,5>`; anything else offers `<L>`, `<L,M>` and the unscoped row KILL.
|
|
2164
2204
|
|
|
@@ -2168,7 +2208,7 @@ A READ carrying active native media is atomic: any KILL scope is ignored and the
|
|
|
2168
2208
|
|
|
2169
2209
|
| Fact | Owner | Effect |
|
|
2170
2210
|
| --- | --- | --- |
|
|
2171
|
-
| Initial body suppression | Immutable event `initial_folded` | Packet presentation only; explicit retrieval can read an initially hidden body. |
|
|
2211
|
+
| Initial body suppression | Immutable event `initial_folded` | Packet presentation only; explicit retrieval can read an initially hidden body. An emission row's hidden body reaches the packet as its assistant message ({§emission-row}). |
|
|
2172
2212
|
| Deliberate scoped KILL | Current projection `folded`, initially empty | Packet, READ, FIND, COPY, and search omit those lines; later retrieval cannot undo trimming. |
|
|
2173
2213
|
|
|
2174
2214
|
Packet display combines both masks. Other consumers use only deliberate trimming.
|
|
@@ -2202,7 +2242,7 @@ The `## Log` section is a sequence of ordinary Markdown records separated by one
|
|
|
2202
2242
|
| 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. |
|
|
2203
2243
|
| body | Coordinate-prefixed lines. | Present when the row is visible. |
|
|
2204
2244
|
|
|
2205
|
-
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.
|
|
2245
|
+
An emission row's body is not in its record: it follows the record as the worker's assistant message ({§packet-wire-envelope}). 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.
|
|
2206
2246
|
|
|
2207
2247
|
§log-address-metadata **Addresses name their relationship, not the row's producer.**
|
|
2208
2248
|
|
|
@@ -2252,7 +2292,7 @@ complete non-retrieval body retains `lines` where no other field supplies its
|
|
|
2252
2292
|
navigable extent. None of these spellings changes acquisition, delivery,
|
|
2253
2293
|
curation, admission, or immutable evidence.
|
|
2254
2294
|
|
|
2255
|
-
Field absence carries defaults: `origin` is omitted for the owning model, `source` for the owning worker, and `status` for a routine 200. Dispositions always carry their lifecycle status, SEND its delivery status, KILL keeps an explicit 200, and every non-200 stays explicit. A present authored aside appears as `aside`. Every row's accounting follows {§packet-token-accounting}.
|
|
2295
|
+
Field absence carries defaults: `origin` is omitted for the owning model, `source` for the owning worker, and `status` for a routine 200. An emission row renders its author, the turn's producer, as its `origin` ({§emission-row}). Dispositions always carry their lifecycle status, SEND its delivery status, KILL keeps an explicit 200, and every non-200 stays explicit. A present authored aside appears as `aside`. Every row's accounting follows {§packet-token-accounting}.
|
|
2256
2296
|
|
|
2257
2297
|
Authored `metadata` retains its opaque ordered block strings under {§scheme-metadata-modifier}; COPY/MOVE pair them as `{from,to}`. Packet rendering does not interpret scheme options or discard malformed input from a failed operation.
|
|
2258
2298
|
|
|
@@ -2270,7 +2310,10 @@ Authored `metadata` retains its opaque ordered block strings under {§scheme-met
|
|
|
2270
2310
|
This is retained evidence, not a separate visibility or delivery lifecycle. Source mutation/deletion
|
|
2271
2311
|
cannot change a retained observation. Explicit READ of its still-active log source can acquire the same media again.
|
|
2272
2312
|
Every compatible-model packet includes one file part per retained, admitted READ observation, after the
|
|
2273
|
-
packet text, in observation order
|
|
2313
|
+
packet text, in observation order, each preceded by a text part that names the observation's log
|
|
2314
|
+
coordinate, source path and projection facts and states that the bytes are that READ's own, retained
|
|
2315
|
+
until its row is KILLed: an uncaptioned native part on the user turn reads as a fresh arrival (#899).
|
|
2316
|
+
Model-response settlement never consumes an observation. KILL follows
|
|
2274
2317
|
{§log-kill-scope}; forks inherit the snapshot and ordinary projection state independently. Output withholding
|
|
2275
2318
|
suppresses the complete native part under {§context-output-admission}. Unsupported routes receive only the
|
|
2276
2319
|
text projection and no native charge; switching back to a compatible route exposes still-retained media.
|
|
@@ -2281,7 +2324,7 @@ Authored `metadata` retains its opaque ordered block strings under {§scheme-met
|
|
|
2281
2324
|
records the exact READ coordinates sent without controlling retention. Missing immutable bytes are an
|
|
2282
2325
|
internal integrity failure, never silently dropped content. No ejection message or permanent teaching is
|
|
2283
2326
|
added. These stable curation weights are not provider-token measurements ({§tokenomics-render-weight-budget}).
|
|
2284
|
-
- §packet-token-accounting Every row reports one `logTokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, facts, visible body,
|
|
2327
|
+
- §packet-token-accounting Every row reports one `logTokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, facts, visible body, selected native attachment, and the emission it delivers outside its record ({§emission-row}). The completed record is measured to a fixed point, including the accounting field itself. No `tokensBody`, `tokensMetadata`, or `tokensActive` field is serialized. Hidden text is not charged; metadata-only rows still have a reclaimable charge. Source/FIND-item `tokens` measure source content, not the observation's context footprint. A FIND's nonzero `itemsTokenTotal` weighs the complete matched set; a nonzero `returnedItemsTokenTotal` appears only when the returned page differs. All use stable curation weights, not provider tokens or dollars. Native component accounting follows {§packet-attachment-parts}; ordinary addressability and truthful errors follow {§log-wire-format}.
|
|
2285
2328
|
|
|
2286
2329
|
### §retrieval-packet-metadata READ/FIND packet metadata
|
|
2287
2330
|
|
|
@@ -2327,14 +2370,32 @@ single line past the end, a reversed range, empty content, a command's log row
|
|
|
2327
2370
|
|
|
2328
2371
|
### §turn-ops-entry The admitted turn program
|
|
2329
2372
|
|
|
2330
|
-
§turn-ops-log-curation A source-backed turn preserves its **exact admitted Plurnk program**, including ignored interstitial text, before dispatch. `turn_sources` records that source once, separately from the curatable log and optional provider evidence. Retention does not manufacture a log row. Ordinary READ creates a receipt governed by {§log-readable-projection}; curation of
|
|
2373
|
+
§turn-ops-log-curation A source-backed turn preserves its **exact admitted Plurnk program**, including ignored interstitial text, before dispatch. `turn_sources` records that source once, separately from the curatable log and optional provider evidence. Retention does not manufacture a log row; the one row an admitted emission gains is its announcement ({§emission-row}). Ordinary READ creates a receipt governed by {§log-readable-projection}; curation of either never changes the source.
|
|
2374
|
+
|
|
2375
|
+
### §emission-row The emission row
|
|
2376
|
+
|
|
2377
|
+
Every admitted emission is announced by one row of its own turn, so the transcript carries the
|
|
2378
|
+
worker's emissions in chronological place ({§packet-wire-envelope}) and the worker curates them
|
|
2379
|
+
like any other row.
|
|
2380
|
+
|
|
2381
|
+
| Surface | Contract |
|
|
2382
|
+
|---|---|
|
|
2383
|
+
| When | An inference turn that admitted at least one statement from its provider content, and turn zero's survey ({§worker-initialization-entry}). A programmatic batch, an empty turn ({§empty-turn}), a client operation and a rejected attempt ({§rejected-emission-entry}) announce nothing. |
|
|
2384
|
+
| 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. |
|
|
2385
|
+
| 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. |
|
|
2386
|
+
| Body | Frozen: the canonical rendering ({§statement-rendering}) of every statement the parser admitted, in order. 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. Turn zero's is its survey as authored. `ops://` keeps the exact source ({§turn-source-resources}). |
|
|
2387
|
+
| Presentation | Born folded: the record shows its header, and its body follows the record as the worker's assistant message. |
|
|
2388
|
+
| Accounting | `logTokens` charges the record and the emission it delivers ({§packet-token-accounting}). |
|
|
2389
|
+
| 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. |
|
|
2390
|
+
| Schema | Migration 12 admits `kind="emission"` only on this shape: one per turn, the turn's newest row when written, frozen, and curated whole. A database from before version 12 keeps its rows and gains no announcement. FORK copies it with the inherited turns, still naming its writer. |
|
|
2391
|
+
| Echoes | A worker that repeats the heading in its own text is tolerated ({§fabricated-log-entry}); the digest counts the echoes. |
|
|
2331
2392
|
|
|
2332
2393
|
### §turn-source-resources Immutable turn-source resources
|
|
2333
2394
|
|
|
2334
2395
|
| Surface | Contract |
|
|
2335
2396
|
|---|---|
|
|
2336
2397
|
| Identity | `ops://<worker>/<loop>/<turn>`, `reasoning://<worker>/<loop>/<turn>`, and `note://<worker>/<loop>/<turn>/<item>` name a worker in the current workspace and its durable coordinates. A note's item is its dispatched NOTE ordinal. The `outside` source ({§outside-text}) has no address: no `outside://` scheme exists, and it is reached only through `outside/event`, FORK and the digest. The worker authority is required and case-sensitive; userinfo, ports, and queries are invalid. Source identity never depends on the reading worker. `log:///` remains local; READ, FIND and KILL reject log authorities, userinfo, ports and queries with 400, never substitute the caller's log. |
|
|
2337
|
-
| Source | `ops` is exact admitted `text/vnd.plurnk
|
|
2398
|
+
| Source | `ops` is exact admitted `text/vnd.plurnk`, and its turn's emission row carries the canonical rendering ({§emission-row}); `reasoning` is `text/plain` containing the selected original provider reasoning or a non-model producer's authored rationale. Producer identity comes from the owning turn; a harness rationale is not provider evidence. The turn decides existence and the source decides content: a turn that exists but has no source of that kind reads as the ordinary empty resource (204, empty body), never a fabricated one; a worker or turn that does not exist is 404. |
|
|
2338
2399
|
| Notes | Each dispatched NOTE stores its exact literal body as an immutable `text/plain` source and returns its worker-qualified address. There may be multiple notes in a turn, from reasoning, content, or another producer. A missing note is 404, not an empty invented note. Sharing its URI uses ordinary SEND; the receiver deliberately READs it. NOTE itself sends no ambient update. |
|
|
2339
2400
|
| Retention | One ops source, one reasoning source and one outside source per turn; one note source per NOTE ordinal. An optional inference-call link records provenance. Source removal follows deletion of its owning turn, never log curation. |
|
|
2340
2401
|
| Operations | Ordinary scoped READ, FIND, content search and COPY from any named worker's source within the workspace. FIND accepts authority and path patterns, retaining complete worker-qualified identities in results and folder selectors. READ returns data and never executes it. Sources are read-only for every actor and have no edit hashes. |
|
|
@@ -2342,11 +2403,11 @@ single line past the end, a reversed range, empty content, a command's log row
|
|
|
2342
2403
|
| FORK | Sources copy with the inherited turns at identical loop/turn/item coordinates under the fork's own authority. Bytes and embedded source references are preserved verbatim; an explicit reference still names its original worker. Branch receipt curation is independent; neither branch can rewrite source evidence. |
|
|
2343
2404
|
| Forensics | Digest assistant artifacts read source directly, independently of receipt presence or curation. Original provider responses retain all attempts and opaque fields separately. |
|
|
2344
2405
|
|
|
2345
|
-
§rejected-emission-entry A rejected provider response is not `turnOps`: it never became an admitted turn program. The one bounded invalid-emission recovery item under {§emission-admission} has `attrs.kind="emissionAttempt"`, `origin="model"`, the canonical model-facing `/attempt` leaf, and the exact latest rejected response. The packet does not duplicate that identity as `kind` metadata. It is born durably body-suppressed and projected visibly only in the informed recovery packet; every other rejected attempt remains forensic-only.
|
|
2406
|
+
§rejected-emission-entry A rejected provider response is not `turnOps`: it never became an admitted turn program, and no emission row announces it ({§emission-row}). The one bounded invalid-emission recovery item under {§emission-admission} has `attrs.kind="emissionAttempt"`, `origin="model"`, the canonical model-facing `/attempt` leaf, and the exact latest rejected response. The packet does not duplicate that identity as `kind` metadata. It is born durably body-suppressed and projected visibly only in the informed recovery packet; every other rejected attempt remains forensic-only.
|
|
2346
2407
|
|
|
2347
|
-
- §log-coordinate-hierarchy **Log coordinates are a hierarchical prefix; the trailing slash is optional** — a coordinate is `loop/turn/sequence`, and a PARTIAL coordinate selects its descendants: `log:///1` = loop 1's rows, `log:///1/2` = turn 1/2's rows, `log:///1/2/3` = the one row. A full coordinate is always three parts, so a one- or two-part path is unambiguously a prefix — the trailing slash is an optional alias (`log:///1/2` ≡ `log:///1/2/`), uniform with ```` ```READ (worker:///docs/) ````. A complete `[start-end]` segment in any numeric coordinate slot selects that inclusive decimal interval; brackets elsewhere retain ordinary path-glob meaning. Every rendered row appends one canonical model-facing leaf: the native operation name or invoked executor name, `/attempt` for a rejected emission. An executor leaf is derived from the durable submitted statement (its `runtime`), never an internal dispatch type or the current tool registry. Digits and punctuation in executor names remain part of the leaf. The leaf names identity rather than adding a resource level. Exact consumers tolerate the unsuffixed three-part shorthand; when supplied, the case-insensitive leaf is authoritative and a disagreement resolves 404. READ anchors use the canonical suffixed identity even when addressed by shorthand. Typed entry materialization therefore resolves as `/READ` while retaining its durable `EDIT` event ({§exec-entry-sink}). `log:///1/2/*` still selects the turn's item rows, while `log:///**/READ`, `log:///**/python3`, and `log:///**/
|
|
2348
|
-
- §log-curation-folder-idiom **Log curation speaks the folder idiom; a zero-match sweep is a no-op success** — KILL takes a concrete coordinate or a path-glob, and a **trailing slash or a partial coordinate means "the contents"** ({§log-coordinate-hierarchy}), like a folder-scoped FIND: ```` ```KILL (log:///1/2) <1,-1> ```` suppresses turn 1/2's bodies. A **well-formed selection that matches nothing is 204 with `matched: 0`**; a successful sweep's rx carries `matched: N`. Parameterless KILL instead requests completion ({§kill-conclusion}).
|
|
2349
|
-
- §log-curation-set-selection **Row selection and body scope are independent** — target/glob and an optional heading pattern (```` ```KILL (log:///**) [{"pattern": "~stale"}] ````, every dialect a FIND over rows accepts) compose by intersection into the affected row set. An optional `<L>` or `<SL,EL>` then intersects each selected canonical body; it never paginates or changes the selected set. Thus ```` ```KILL (log:///**/READ) <17,-1> ```` may change long READs and no-op on short ones while reporting every selected row in `matched`.
|
|
2408
|
+
- §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`).
|
|
2409
|
+
- §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}).
|
|
2410
|
+
- §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`.
|
|
2350
2411
|
|
|
2351
2412
|
§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:
|
|
2352
2413
|
|
|
@@ -2422,7 +2483,7 @@ per-operation projection on `rx`; the aggregate remains inside dispatch.
|
|
|
2422
2483
|
| `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`. |
|
|
2423
2484
|
| `effect.removed`, `inserted` | `change` | Removed and inserted counts in the receipt unit. |
|
|
2424
2485
|
| `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. |
|
|
2425
|
-
| `effect.context` | Canonical row body | Numbered physical lines at each landed boundary, bounded symmetrically by `PLURNK_SERVICE_EDIT_RECEIPT_CONTEXT_LINES`.
|
|
2486
|
+
| `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. |
|
|
2426
2487
|
| `disposition`, `requested` | `disposition`, `requested` | A reviewer-replaced batch preserves the authored marker while stating that its attributed effect was superseded. |
|
|
2427
2488
|
| `replacement` | `replacement`, `change`, canonical proposal-owner body | The one whole-resource effect actually applied by the reviewer replacement; never duplicated across authored rows. |
|
|
2428
2489
|
|
|
@@ -2747,10 +2808,10 @@ accounting and model-visible failure evidence remain separately owned by
|
|
|
2747
2808
|
operation is minted for them, a repetitive or length-cut response stays one source, and nothing
|
|
2748
2809
|
filters what is stored. The model hears only the weight: the next packet's Notices section
|
|
2749
2810
|
carries `outside_text: N tokens emitted outside OPs. Discarded.`, N by {§tokenomics-agnostic-ruler};
|
|
2750
|
-
the text itself never enters a packet, is never delivered and never concludes.
|
|
2811
|
+
the text itself never enters a packet, not even inside its turn's emission ({§emission-row}), is never delivered and never concludes.
|
|
2751
2812
|
{§empty-turn} still strikes a turn that holds only text, with unchanged reasoning recovery
|
|
2752
2813
|
({§reasoning-empty-turn-read}), reply accounting and completion rules. A log-entry heading in
|
|
2753
|
-
outside text still rejects the attempt ({§fabricated-log-entry}); an unfenced operation line is
|
|
2814
|
+
outside text still rejects the attempt unless it echoes an emission row ({§fabricated-log-entry}); an unfenced operation line is
|
|
2754
2815
|
not response text ({§unfenced-operation}) and so never reaches the source; `KnownToxins` guards
|
|
2755
2816
|
only the read-back ({§reasoning-empty-turn-read}). Clients receive the text once through
|
|
2756
2817
|
`outside/event` ({§notifications-outside-event}, {§agui-outside-text}); FORK snapshots the
|
|
@@ -2870,7 +2931,9 @@ anything spawns — a file is the script; a directory is refused `400 target-not
|
|
|
2870
2931
|
pointing at `[{"cwd": "…"}]`; an absent path is refused `400 target-not-found`, giving the
|
|
2871
2932
|
applicable accepted form without inferring what the model meant. When the target is a
|
|
2872
2933
|
registered tool of another executor, recovery gives that tool's exact bracketed
|
|
2873
|
-
invocation;
|
|
2934
|
+
invocation; when it names another available executor (`sh (python3)` over a Python body, #895),
|
|
2935
|
+
recovery names that executor's fence — `` `python3` is its own executor; use that name on the
|
|
2936
|
+
opening fence and put the program in the body. ``; otherwise it points at an existing script or a bare shell-command body. A non-file resource
|
|
2874
2937
|
target that cannot be read keeps the owning READ's failure identity (#163) and states
|
|
2875
2938
|
the slot contract in its recovery — the resource is the program and the body its stdin;
|
|
2876
2939
|
a command belongs beneath a targetless heading — without guessing which was meant (#425). The started receipt always
|
|
@@ -3002,7 +3065,8 @@ Per-tool programs such as `go`, `cargo`, `make`, and `npm` do not earn executor
|
|
|
3002
3065
|
|
|
3003
3066
|
§exec-lifetime **How long a spawn may live is the fence's metadata, one field.**
|
|
3004
3067
|
`[{"lifetime": …}]` takes a duration (`30s`, `30m`, `2h`), or one of three words;
|
|
3005
|
-
absent is `loop`.
|
|
3068
|
+
absent is `loop`. The key is one of the service's reserved metadata keys, withheld
|
|
3069
|
+
from every owner by the framework ({§service-metadata-keys}). An execution takes no scope: a numeric coordinate on an
|
|
3006
3070
|
executor target is refused `scope-unsupported` (400), naming the field.
|
|
3007
3071
|
|
|
3008
3072
|
| `lifetime` | The spawn |
|
|
@@ -3217,7 +3281,7 @@ body prefixes.
|
|
|
3217
3281
|
wholesale ({§log-sensitive-request-evidence}); the spawn's record names each such value's
|
|
3218
3282
|
provenance as the modifier's.
|
|
3219
3283
|
- §exec-hold-until-concluded **The turn-hold exception** — for runtimes in `PLURNK_SERVICE_EXEC_HOLD` (a decision-table env), an in-flight stream **pauses the cycle**: the next packet does not assemble until the stream concludes, so the model never burns a turn asking "are we there yet" about a result the engine controls end-to-end. This exception is limited to seconds-bounded runtimes whose final result the engine controls end-to-end. Bounded by `PLURNK_SERVICE_EXEC_HOLD_MS` and **fail-open**: at the cap the standard cycle resumes untouched (waits, wakes, polls). Zero grammar or teaching surface — the model emits an executor fence, optionally followed by WAIT; the wake-shaped world simply arrives one packet sooner. It extends selected runtimes beyond the ordinary {§worker-optimistic-settlement} cap before the next packet assembles. A bare entry holds ALL of a runtime's spawns; a `<runtime>:<effect>` suffix (`github:read`) holds only that effect-class — an MCP server is one runtime whose tools split (a `read` `get_issue` is instant; a `host` `run_migration` is a slow mutation), so an operator opts the known-fast read-class in without parking on the mutation. Conservative stays default: an arbitrary third-party server's latency never parks the engine unless a suffix opts a class in.
|
|
3220
|
-
- §exec-entry-sink **The entry() sink** implements {§executor-entry-sink} over ordinary scheme-owned entries. Core owns allocation, materialization, and persistence; executors receive only the returned resource address.
|
|
3284
|
+
- §exec-entry-sink **The entry() sink** implements {§executor-entry-sink} over ordinary scheme-owned entries. Core owns allocation, materialization, and persistence; executors receive only the returned resource address. Web acquisition and materialization are the `https` handler's {§web-materialization-contract}, reached through the scheme registry; core names no leaf package.
|
|
3221
3285
|
|
|
3222
3286
|
| Input / effect | Consumer behavior |
|
|
3223
3287
|
| --- | --- |
|
|
@@ -3626,6 +3690,14 @@ and is ignored rather than resolved against the working directory.
|
|
|
3626
3690
|
| Reproducible cache | `$XDG_CACHE_HOME` (default `~/.cache`) | Reserved; no directory is created without an owned artifact. |
|
|
3627
3691
|
| Shared global Agent Skills | User home | `.agents/skills/<name>/SKILL.md` |
|
|
3628
3692
|
|
|
3693
|
+
§state-root **A private daemon has one root.** `PLURNK_SERVICE_STATE_ROOT` (absolute; a leading
|
|
3694
|
+
`~/` expands; a relative value fails hard by name) replaces the data, state, cache and runtime homes
|
|
3695
|
+
with `<root>/data`, `<root>/state`, `<root>/cache` and `<root>/runtime`, the database with them
|
|
3696
|
+
(`PLURNK_SERVICE_DB_PATH` still names the database exactly). Configuration stays where the cascade
|
|
3697
|
+
reads it and the shared Agent Skills root stays under the user's home: a state root separates what
|
|
3698
|
+
the daemon *writes*, not what the operator supplies, and is no execution sandbox. What a launcher
|
|
3699
|
+
keeps or removes under a root after the daemon stops is that launcher's retention decision.
|
|
3700
|
+
|
|
3629
3701
|
The service creates only a directory required by the current command. A newly
|
|
3630
3702
|
created configuration or data directory uses mode `0700`; a newly seeded
|
|
3631
3703
|
secret-bearing `.env` uses `0600`. Existing user-owned permissions are not
|
|
@@ -4048,7 +4120,12 @@ actions from model operations where the family contract requires it
|
|
|
4048
4120
|
outcomes, and a snapshot with `commit`/`abort`. Successful publication commits;
|
|
4049
4121
|
failure aborts; cooling tears down. Protocol continuations remain ordinary
|
|
4050
4122
|
module actions. Optional `forget` releases an installed or provisioned
|
|
4051
|
-
definition before removal; failure rejects removal ({§skills-remove}).
|
|
4123
|
+
definition before removal; failure rejects removal ({§skills-remove}). The
|
|
4124
|
+
seam's shapes — the identity a verb acts under, its options, definition
|
|
4125
|
+
sources, outcomes, preparation, the prepared result and the family handle —
|
|
4126
|
+
are declared once in `plurnk-contracts` and imported by core and every
|
|
4127
|
+
module; core adds only its own face of the seam, the runtime registration a
|
|
4128
|
+
resident family prepares and the scheme facet it may expose.
|
|
4052
4129
|
|
|
4053
4130
|
An adapter may expose a `scheme` facet beneath its family's runtime namespace
|
|
4054
4131
|
({§runtime-resource-binding}). A facet claims a path subtree and is the scheme's
|
|
@@ -4224,11 +4301,12 @@ Core's behavior behind them.
|
|
|
4224
4301
|
| §methods-conversation-worker Workspace lifecycle | `createConversationWorker({ workspaceId, name? })` | Creates a distinct model-origin root worker with empty history: a fresh conversation over the same world, not a fork or the stable default. |
|
|
4225
4302
|
| Workspace lifecycle | `forkWorker({ workspaceId, workerId, name? })` | Creates a child worker that branches the source worker's history while sharing workspace state. |
|
|
4226
4303
|
| §methods-workspace-rename Workspace metadata | `renameWorkspace(workspaceId, name)` | Changes only the world's unique mutable name; workers, log, and membership remain intact. |
|
|
4227
|
-
| §methods-workspace-prompts Workspace metadata | `listPrompts(workspaceId, limit?)` | Returns nonempty loop-seed prompts
|
|
4304
|
+
| §methods-workspace-prompts Workspace metadata | `listPrompts(workspaceId, limit?, workerId?)` | Returns nonempty loop-seed prompts a client addressed to the workspace's model workers, newest-first; `workerId` narrows to one worker. Authorship is the seed message's address ({§message-arrival}): a worker-issued seed (WORK, FORK, SEND to a worker) has none and is never history, whichever worker it seeded; a client prompt at a forked conversation worker is. An omitted limit is `PLURNK_SERVICE_PROMPTS_PAGE`. |
|
|
4228
4305
|
| Workspace metadata | `listWorkspaces()`, `workspaceDerivationStatus(...)` | Reads current workspace identity and derivation progress. |
|
|
4229
4306
|
| §methods-worker-read Worker topology | `readWorker({ workspaceId, identity })` | Ownership-bounds an exact id-or-name lookup and returns one durable Worker projection or `null` under {§application-worker-observation}. Supplying both identities or neither is invalid. |
|
|
4230
4307
|
| §methods-worker-list Worker topology | `listWorkers(workspaceId, query?)` | Returns the workspace's durable Worker projections under {§application-worker-observation}. The origin filter is exact; an explicitly present `parentWorkerId` filters roots (`null`) or one immediate parent (id), while omission returns every lineage position. Each projection carries `kind` (`conversation`, `fork` for a child with a fork boundary, `work` for any other child) and `lifecycle`, the representative work loop's status through {§loop-lifecycle-vocabulary} (`idle` with no work loop), so a directory row shows the same lifecycle glyph the bound worker's own status gauge shows; clients infer neither (#523). |
|
|
4231
4308
|
| §methods-worker-loops Loop lifecycle | `listWorkerLoops({ workspaceId, workerId })` | Ownership-checks the Worker and returns its Loops in sequence order under {§application-loop-observation}, including the validated exact terminal result when one exists. It performs no scheduling or event replay. |
|
|
4309
|
+
| §methods-worker-descendants Descendant spend | `descendantAccounting({ workspaceId, workerId, loopId })` | Ownership-checks the Worker and returns the {§provider-accounting} projection of every settled request on a loop that a descendant of the Worker (`parent_worker_id`, to any depth) ran after `loopId` — this delegation's spend, the same tree the turn cap counts ({§turn-cap-counts-the-tree}). The Worker's own loop is never included: its accounting stays {§notifications-loop-terminated}'s. `loopId: null` is the empty projection, explicit zero. Derived from the request ledger on every read ({§tokenomics-provider-usage}); no rollup, no second store. |
|
|
4232
4310
|
| Extension actions | `listModuleActions()`, `invokeModuleAction(name, params, context)` | Lists setup-registered `{ name, scope, inputSchema, outputSchema }` descriptors in sorted order. Invocation requires a context matching the registered scope; missing names, forged scope, and missing workspace identity fail before the owner runs. Handler values remain opaque to core. |
|
|
4233
4311
|
|
|
4234
4312
|
§methods-loop-run-fold-consistency **A folded prompt cannot silently reconfigure
|
|
@@ -4533,6 +4611,25 @@ flowchart LR
|
|
|
4533
4611
|
measure --> rail[Engine budget admission and dispatch]
|
|
4534
4612
|
```
|
|
4535
4613
|
|
|
4614
|
+
### §packet-wire-envelope The wire envelope
|
|
4615
|
+
|
|
4616
|
+
The packet reaches the provider as a transcript, under the roles the model was tuned on, its bytes unchanged:
|
|
4617
|
+
|
|
4618
|
+
| Message | Role | Content |
|
|
4619
|
+
|:--|:--|:--|
|
|
4620
|
+
| 1 | `system` | the system slot, as rendered |
|
|
4621
|
+
| 2, 4, … | `user` | the user slot's text up to and including the next placed emission row's record ({§emission-row}); the first opens with `## Log` |
|
|
4622
|
+
| 3, 5, … | `assistant` | that row's emission, as the worker's own message |
|
|
4623
|
+
| last | `user` | the records after the last placed emission, then the remaining user sections in {§packet-cache-monotone} order; native parts ride here ({§packet-attachment-parts}) |
|
|
4624
|
+
|
|
4625
|
+
Only role boundaries are added: joined by blank lines, the user messages are the user slot's
|
|
4626
|
+
bytes, in record order. An emission is placed exactly when its row is present in the final log
|
|
4627
|
+
section, so curation governs the transcript: a KILLed emission row, or one a trusted transform
|
|
4628
|
+
removed ({§packet-plugin-transform}), takes its emission with it, and a log without emission rows
|
|
4629
|
+
is one user message. The Worker block and the status clump always follow the log, so a request
|
|
4630
|
+
never ends on an emission, and the projection refuses one that would. The digest's packet
|
|
4631
|
+
artifacts record the sections, and `.wire.json` the messages ({§share-packet-names}).
|
|
4632
|
+
|
|
4536
4633
|
### §packet-cache-monotone Default order and cache locality
|
|
4537
4634
|
|
|
4538
4635
|
Conditional absence never reorders the surviving default sections.
|
|
@@ -4554,7 +4651,9 @@ Conditional absence never reorders the surviving default sections.
|
|
|
4554
4651
|
|
|
4555
4652
|
The order favors prefix-cache locality where semantics permit: the definition
|
|
4556
4653
|
and privileged policy lead operator notes, while the append-mostly
|
|
4557
|
-
log leads the volatile user-status clump.
|
|
4654
|
+
log leads the volatile user-status clump. An emission sits at the row that announces it
|
|
4655
|
+
({§packet-wire-envelope}), so the reusable prefix runs through every retained emission, and
|
|
4656
|
+
retiring one breaks the prefix at its row like any other curation. It does **not** claim that every system byte is
|
|
4558
4657
|
immutable or that the complete packet is globally monotone in volatility:
|
|
4559
4658
|
operator notes and policies can change. Trust is a separate
|
|
4560
4659
|
admission rule. The system slot contains trusted control-plane material;
|
|
@@ -4570,6 +4669,8 @@ Each initial or returned list passes the schemes-owned validator, including
|
|
|
4570
4669
|
unique-name enforcement, before the next transformer or renderer. Each
|
|
4571
4670
|
transformer may inspect the section content and add, remove, or reorder
|
|
4572
4671
|
sections. It receives no separate engine, database, actor, or request context.
|
|
4672
|
+
Emission placement reads the final log section, so a transform that removes an
|
|
4673
|
+
emission row's record removes its emission from the transcript ({§packet-wire-envelope}).
|
|
4573
4674
|
|
|
4574
4675
|
This is strictly a trusted in-process seam, admitted through the common plugin
|
|
4575
4676
|
trust gate; an external client action cannot invoke it. Whole-list transformation is
|
|
@@ -4583,13 +4684,13 @@ time of measurement.
|
|
|
4583
4684
|
|
|
4584
4685
|
| Fact | Owner and unit | Time | Contract |
|
|
4585
4686
|
|:-----|:---------------|:-----|:---------|
|
|
4586
|
-
| Core curation weight | `contentWeight = ceil(chars/2)` over channel content, canonical log bodies,
|
|
4687
|
+
| Core curation weight | `contentWeight = ceil(chars/2)` over channel content, canonical log bodies, rendered packet slots, and placed emissions | Write/build | Stable, model-independent pressure and curation savings; never a tokenizer claim. |
|
|
4587
4688
|
| §tokenomics-context-envelope-admission Provider input capacity | Provider model limits and configured output reservation, in provider tokens | Before every logical request | `min(maxInputTokens, contextWindow - outputBudget)` over the known terms. The provider alone measures the complete request and admits, defers, or rejects it. |
|
|
4588
4689
|
| 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}. |
|
|
4589
4690
|
| 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. |
|
|
4590
4691
|
|
|
4591
4692
|
- §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.
|
|
4592
|
-
- §tokenomics-render-weight-budget **Packet curation budget.** `logTokensTotal` measures the *complete assembled packet* after section transforms and readout substitution; it is not a sum of log-row `logTokens` fields. 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.
|
|
4693
|
+
- §tokenomics-render-weight-budget **Packet curation budget.** `logTokensTotal` measures the *complete assembled packet* after section transforms and readout substitution, its rendered slots and the emissions it places ({§emission-row}); it is not a sum of log-row `logTokens` fields. 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.
|
|
4593
4694
|
- §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. `logTokensMax = floor(inputCapacity / factor)` converts provider capacity into curation units. Zero means no whole curation unit fits; unknown input capacity remains `null`. The built packet captures this allowance once for its readout, pressure inventory, overflow admission, 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}).
|
|
4594
4695
|
- §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. `PLURNK_SERVICE_PROMPT_BUDGET`, `PLURNK_SERVICE_SAFETY`, and the additive reasoning/completion reserve knobs are retired; local and custom deployments tune context window, total output budget, optional reasoning subset, and prompt-projection percentage at their owning layers.
|
|
4595
4696
|
- §tokenomics-prompt-projection-share **Prompt projection is stable packet policy.**
|
|
@@ -4795,7 +4896,7 @@ leaves the request-only record, while rejected exchanges remain in their
|
|
|
4795
4896
|
| Turn state | `turns.packet` (the bag) + `turn_sections` rows |
|
|
4796
4897
|
| ----------------------------- | ----------------------------------------------- |
|
|
4797
4898
|
| No admitted model request (including initialization and local capacity rejection) | SQL `NULL`, no rows |
|
|
4798
|
-
| Request assembled | `{ weight, attributions }` + the sections as items |
|
|
4899
|
+
| Request assembled | `{ weight, attributions }` + the sections as items; the emissions it placed stay in their rows ({§emission-row}) |
|
|
4799
4900
|
| Response admitted | `{ weight, attributions, assistant, assistantRaw }` + the sections as items |
|
|
4800
4901
|
|
|
4801
4902
|
§packet-items **Sections are rows over content-addressed items; the bag never holds them.**
|
|
@@ -4851,6 +4952,7 @@ consumer reconstructs a name. A name that cannot be a file name, or two turns sh
|
|
|
4851
4952
|
|----------|--------------|-----------|
|
|
4852
4953
|
| `<stem>.assistant.md` | The turn has an `ops` source | Exact `turn_sources.content`, independent of log rows |
|
|
4853
4954
|
| `<stem>.system.md`, `<stem>.user.md` | The turn stored a provider request | Stored text sections projected through `PacketWire`; native parts are not Markdown |
|
|
4955
|
+
| `<stem>.wire.json` | The turn stored a provider request | The request's text messages in order, its worker's emission rows placed ({§packet-wire-envelope}); `<stem>.wire.invalid.json` names a stored log that cannot be projected |
|
|
4854
4956
|
| `digest.json` turn `attachments` | Every turn | Stored native attachment descriptors; `[]` means a request without attachments, `null` means no valid stored request. Selection is not proof of provider acceptance. |
|
|
4855
4957
|
| `<stem>.assistantRaw.json` | The request has an admitted provider response | Stored opaque provider response |
|
|
4856
4958
|
| `<stem>.response.md`, attempt artifacts | The request received no admitted response | Stored request and attempt state |
|
|
@@ -5041,6 +5143,8 @@ retain distinct contracts and lifetimes.
|
|
|
5041
5143
|
|
|
5042
5144
|
§notice-event-notify **Client surface.** Engine Notices broadcast live via the `notice/event` notification — `{ workerId, loopId, notice: { source, kind, level, message?, position?, …kind-specific } }` per the grammar's `Notice` schema — the moment they land. A loop Notice names its owning Worker; workspace derivation progress alone carries `workerId=null, loopId=0`. AG-UI projects the same observation as the custom `plurnk.notice` event. Failures do not broadcast on this surface: they are log rows, and the client reads them through `log.read` / the `log/entry` notification, the durable log.
|
|
5043
5145
|
|
|
5146
|
+
§loop-status-notice **The drain beats the loop's lifecycle on the notice channel.** When the drain claims a loop to run it broadcasts `notice/event` `{ workerId, loopId, notice: { source: "engine:lifecycle", kind: "loop_status", level: "info", status: 102 } }`, and when it leaves a loop parked ({§loop-wake-identity}) the same with `status: 202`; a wake that the drain claims again is another `102`. The beat is transient: broadcast to the workspace like any notice ({§notice-event-notify}), never a log row, never in a packet. Terminals stay `loop/terminated`'s; a client that reads the beat has the running/parked edges a parked delegation otherwise never publishes.
|
|
5147
|
+
|
|
5044
5148
|
§share **A share is the database's record, ready to send.** `plurnk-service share [<file.db>] [<folder>]`, and `npm run share` from a checkout, take a consistent copy of the database (`VACUUM INTO`; a live database is never read in place), and write its digest into `<folder>`, an ordinary folder the user archives or attaches however they like. Without a database the service's own is shared. Nothing is overwritten: a folder that exists and is not empty is refused, and a caller reusing a place removes it first. The share is the user's bug report and our dogfood, benchmark and forensics artifact alike.
|
|
5045
5149
|
|
|
5046
5150
|
§share-snapshot **A database is copied by SQLite, never by the filesystem.** `Share.snapshot(dbPath, copy)`, exported as `@plurnk/plurnk-service/share` with `Share.write`, is the one consistent copy: a byte copy of a WAL-mode database drops every committed page still in its `-wal` file. A harness that keeps the database beside its digest takes it through `snapshot`; an existing `copy` is refused.
|
|
@@ -5068,7 +5172,11 @@ retain distinct contracts and lifetimes.
|
|
|
5068
5172
|
|
|
5069
5173
|
§digest-wire-line **Wire health aggregated.** Each worker summary renders a `Wire:` line — total physical provider requests, error-outcome count, and the error percentage when nonzero. Provider-level failures are absorbed by retries below the packet stream, so without this aggregate a rate-limit storm is invisible in every summary while the model's experience stays clean.
|
|
5070
5174
|
|
|
5071
|
-
§digest-
|
|
5175
|
+
§digest-cache-ledger **Cacheable versus cached, per request.** For every physical provider request the digest computes its cacheable prefix: the longest common prefix, in characters, between the prompt its turn stored (the request's messages in order, each role above its content — the messages `.wire.json` carries) and the prompt of the previous provider request in the same loop, taken as that prefix's share of the whole prompt in the packet's own token estimate ({§tokenomics-agnostic-ruler}) and applied to the provider's reported input count, so `cacheableTokens` sits in the same units as the cache read beside it; a loop's first request has 0, and a request whose turn stores no valid packet or whose provider reported no input count has none. Beside it sit the provider's reported cache read as `cachedTokens` (`provider_requests.usage_input_cache_read`) and `inputTokens` (`usage_input`). `digest.json` carries the three on every provider-request row; an inference turn line carries `cache=<cached>/<cacheable>` summed over the turn's requests; each workspace heading is followed by `Cache: <cached> of <cacheable> cacheable tokens reported (<pct>%) over <n> requests`. A provider that reported no cache field at all (null, not 0) renders `?` on the turn line and is counted apart on the workspace line (`· <k> unreported (cached=?)`), outside both sums and the percentage; a request without a stored packet or without a reported input count is likewise counted apart. The prefix measures what the daemon kept identical between consecutive requests; it is no claim about the provider's tokenization or cache-block alignment, so a provider that under-caches an identical prefix reads as such, apart from a prefix the daemon itself broke.
|
|
5176
|
+
|
|
5177
|
+
§digest-edit-census **Every model EDIT by the form it authored, how it landed, and whether it came back.** For each worker the digest reads every model-authored EDIT row and classifies the form from the row's stored marker and the durable statement's pattern: `hash` (one anchor), `line` (one line number), `range` (two marks), `insert` (the zero-width `<L,1,L,1>` form, {§zero-width-column-one-insert}), `column` (any other four-mark region), `prepend` / `append` (`<0>` / `<-1>`), `offset` (a tolerated anchor offset, {§anchor-offset}), `pattern` (a selection matcher), `whole` (no marker: a creation when it lands 201). It counts the EDITs, those refused (status ≥ 400), and the *revisits*: an EDIT of a path the same worker had edited within its previous two model turns — the shape of a repair without the claim of one. Each worker summary renders `EDITs: <n> · <form>=<count>… · refused=<k> · revisits=<r>` (`(no edits)` for none); `digest.json` carries the census as `edit_census` on every worker and stamps every EDIT log entry with its `edit_form` and `edit_revisit`. A form is a fact about what was written, never about intent; the bench sheet reads the counts as friction and leaves the judgement to the reader.
|
|
5178
|
+
|
|
5179
|
+
§digest-forensic-fidelity **Forensic fidelity and cardinality.** The digest's machine-readable JSON preserves every log event with its initial and current projection, causal `source`, and structured `attrs`; every exact log-KILL target effect; the exact Problem on every failed row; each loop's exact terminal result, settlement time, scheduled due time, recurring interval, and recurrence lineage; and every ordered physical provider request. Programs still produce chronological `assistant.md` artifacts after every READ receipt is KILLed; source is independent of log curation. Each worker summary's `Emissions:` line counts its announced emission rows, those the worker KILLed, and the headings it echoed ({§emission-row}); the op mix leaves the announcements out. Each stored packet validates independently: one malformed historical packet remains exact raw evidence with its complete validation error chain and never prevents healthy turns from being projected. Accounting on broader rows is the shared exact derivation from that ledger, never a second stored fact. A worker's Cost line names how many settled requests carry no usage at all (errored or aborted exchanges) — their server-side spend is unrecorded rather than silently priced as zero. The reasoning chronology distinguishes readable reasoning content from provider-reported reasoning usage: when tokens were reported but no readable content was returned, it states both facts instead of implying that no reasoning occurred. The human Markdown waterfall shows a present causal source and may preview only the Problem detail because it remains a triage projection, not the machine record. Targets reconstruct the model-visible address, including hostname, port, serialized query, and fragment; an authority-bearing URL must never degrade from `https://host/path` to `https:///path`, and durable resource coordinates render back to their authority form. Its human Markdown waterfall groups identical per-turn op outcomes and typed `entry_materialized` narrations, reporting the exact count and sequence span (`xN (seq A-B)`). Grouping keys include source and the complete target, so distinct causes, authorities, or channels never collapse. Thus amplification is conspicuous without making the diagnostic artifact itself pathological; valid packet files remain byte-identical records of what the model saw.
|
|
5072
5180
|
|
|
5073
5181
|
Unrecognized actionless log rows are retained and labelled as such, not
|
|
5074
5182
|
interpreted as executable turnOps or allowed to prevent the remaining digest.
|
|
@@ -5110,7 +5218,7 @@ USD, and token totals across every physical exchange the turn paid for, failed
|
|
|
5110
5218
|
calls included. It is the shared exact derivation from the ledger, never a second
|
|
5111
5219
|
stored fact, so a live watcher accrues running loop cost per turn (#465).
|
|
5112
5220
|
|
|
5113
|
-
§notice-content-offset-pointer **Content-offset position.** A non-fatal diagnosis on an accepted emission (for example `grammar_unenforced` or `parse_advisory`) carries `position: { type: "content-offset", line, column }` into the model's exact `ops://<worker>/<loop>/<turn>` source. 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.
|
|
5221
|
+
§notice-content-offset-pointer **Content-offset position.** A non-fatal diagnosis on an accepted emission (for example `grammar_unenforced` or `parse_advisory`) carries `position: { type: "content-offset", line, column }` into the model's exact `ops://<worker>/<loop>/<turn>` source; the transcript shows that turn's canonical emission instead ({§emission-row}), 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.
|
|
5114
5222
|
|
|
5115
5223
|
### Executable tool resources
|
|
5116
5224
|
|
|
@@ -5687,3 +5795,152 @@ exits; a failed suite's evidence is never touched and stays exactly where the ru
|
|
|
5687
5795
|
caller's own run directory.
|
|
5688
5796
|
|
|
5689
5797
|
§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.
|
|
5798
|
+
|
|
5799
|
+
## Problem codes and pinned wording
|
|
5800
|
+
|
|
5801
|
+
Every Problem code core mints is named here under its family ({§problem-error-carrier} carries it); the root lint (`scripts/problem-codes.mjs`) refuses a code no owning SPEC names.
|
|
5802
|
+
|
|
5803
|
+
§problems-dispatch **Dispatch Problems.** Every code this family mints, its status, and the sentence that is its contract (placeholders in *italics* are filled at emission; a fixed recovery follows its detail).
|
|
5804
|
+
|
|
5805
|
+
| code | status | contract |
|
|
5806
|
+
|---|---:|---|
|
|
5807
|
+
| `target-required` | 400 | *OP* requires a target path. Recovery: Write the target in parentheses on the opening fence line: `OP (path)`. |
|
|
5808
|
+
| `scheme-not-found` | 501 | Scheme '*name*' is not registered. |
|
|
5809
|
+
| `scheme-metadata-unsupported` | 400 | *OP* on '*scheme*' does not accept the [metadata] modifier. |
|
|
5810
|
+
| `operation-not-implemented` | 501 | Scheme '*name*' does not implement *OP* (or exec). |
|
|
5811
|
+
| `entry-read-not-implemented` | 501 | The '*scheme*' scheme does not provide entry reads. |
|
|
5812
|
+
| `entry-write-not-implemented` | 501 | The '*scheme*' scheme does not provide entry writes. |
|
|
5813
|
+
| `entry-delete-not-implemented` | 501 | The '*scheme*' scheme does not provide entry deletion. |
|
|
5814
|
+
| `channel-delete-not-implemented` | 501 | The '*scheme*' scheme does not provide channel deletion. |
|
|
5815
|
+
| `scheme-handler-threw` | 500 | The '*scheme*' scheme did not produce a result for *OP*. |
|
|
5816
|
+
| `exec-source-not-data` | 501 | Scheme '*name*' is not a data source for an execution. |
|
|
5817
|
+
| `writer-forbidden` | 403 | Writer '*origin*' cannot modify scheme '*name*'. |
|
|
5818
|
+
| `capability-denied` | 403 | Capability '*route*' is denied by *scope* policy. |
|
|
5819
|
+
| `spawn-prompt-empty` | 422 | *OP* has no prompt text: the resource is empty and there is no body. |
|
|
5820
|
+
| `message-not-found` | 404 | No accepted message exists at *address*. |
|
|
5821
|
+
| `edit-collision` | 409 | EDIT collided with the current resource state ({§edit-collision}). Recovery: *n* of *m* edits applied. READ the target for current coordinates. |
|
|
5822
|
+
| `edit-target-required` | 400 | A line-anchored EDIT requires a target resource. Recovery: Provide the target that rendered the line anchor. |
|
|
5823
|
+
| `kill-target-required` | 400 | KILL requires a target path. |
|
|
5824
|
+
| `kill-target-scheme-required` | 400 | KILL target requires a scheme. |
|
|
5825
|
+
| `worker-not-found` | 404 | Worker '*name*' does not exist in this workspace. |
|
|
5826
|
+
| `entry-operation-unsupported` | 400 | KILL requires an entry-bearing target; '*scheme*' does not provide one. |
|
|
5827
|
+
| `resource-scheme-required` | 400 | Resource selection requires an address. |
|
|
5828
|
+
| `channel-required` | 400 | The '*scheme*' scheme has no default channel. Recovery: Address a named channel with a URI fragment. |
|
|
5829
|
+
| `binary-source-unsupported` | 415 | Channel #*name* is binary and its scheme keeps no bytes to transfer. |
|
|
5830
|
+
| `metadata-unsupported` | 400 | *OP* takes only the env option; '*key*' is not one. |
|
|
5831
|
+
| `worker-name-conflict` | 409 | Worker '*name*' already exists in this workspace. Recovery: To give '*name*' more work, write `SEND (worker://_name_)` with the task as the body; to start another worker, choose a name no worker holds. |
|
|
5832
|
+
| `no-operation` | 422 | The turn performed no operation ({§empty-turn}). |
|
|
5833
|
+
| `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. |
|
|
5834
|
+
|
|
5835
|
+
§problems-content **Content and transfer Problems.** Every code this family mints, its status, and the sentence that is its contract (placeholders in *italics* are filled at emission; a fixed recovery follows its detail).
|
|
5836
|
+
|
|
5837
|
+
| code | status | contract |
|
|
5838
|
+
|---|---:|---|
|
|
5839
|
+
| `handler-crashed` | 415 | The *mimetype* content handler failed on *key*: *cause*. |
|
|
5840
|
+
| `line-anchor-unsupported` | 400 | The byte view of *target* publishes no anchors. Recovery: Use byte coordinates: `<first,last>`. |
|
|
5841
|
+
| `line-anchor-invalid` | 400 | A line anchor in the marker is malformed or names no current line ({§line-anchors}). |
|
|
5842
|
+
| `channel-not-found` | 404 | The addressed channel does not exist at *target*. Recovery: Use one of the available channels: #*a*, #*b*. |
|
|
5843
|
+
| `binary-read-unsupported` | 415 | The representation at *target* is binary and cannot be rendered. |
|
|
5844
|
+
| `pattern-unapplicable` | 422 | The pattern could not be applied to *target*. |
|
|
5845
|
+
| `move-region-overlap` | 409 | MOVE cannot insert a whole channel into itself and then remove that channel. |
|
|
5846
|
+
| `mimetype-mismatch` | 415 | COPY or MOVE cannot write '*source-mimetype*' into a '*destination-mimetype*' channel. |
|
|
5847
|
+
| `binary-region-unsupported` | 415 | Channel #*name* is binary and cannot receive a textual region. |
|
|
5848
|
+
| `copy-destination-exists` | 409 | COPY or MOVE destination *address* already contains different content. |
|
|
5849
|
+
| `proposal-apply-missing` | 500 | The source scheme accepted its MOVE proposal without applying the source mutation. |
|
|
5850
|
+
| `line-anchor-collision` | 409 | READ coordinates collided with current content at *target*. |
|
|
5851
|
+
|
|
5852
|
+
§problems-file **File scheme Problems.** Every code this family mints, its status, and the sentence that is its contract (placeholders in *italics* are filled at emission; a fixed recovery follows its detail).
|
|
5853
|
+
|
|
5854
|
+
| code | status | contract |
|
|
5855
|
+
|---|---:|---|
|
|
5856
|
+
| `edit-empty` | 400 | EDIT requires at least one statement. Recovery: Provide an EDIT statement. |
|
|
5857
|
+
| `edit-batch-mismatch` | 400 | The EDIT batch spans multiple resources. Recovery: Submit a separate EDIT batch for each resource. |
|
|
5858
|
+
| `line-marker-required` | 400 | EDIT of an existing file requires a line marker ({§edit-marker-required-on-existing}). Recovery: Name the lines to replace with `<@hash>` or `<@start,@end>` from a READ of the file; `<L,1,L,1>` inserts before line L, and `<1,-1>` replaces the whole file. |
|
|
5859
|
+
| `creation-batch-conflict` | 409 | Multiple EDIT operations attempted to create the same file. Recovery: Create the file with one EDIT before applying additional edits. |
|
|
5860
|
+
| `member-read-only` | 403 | The mounted member '*path*' is read-only. |
|
|
5861
|
+
| `project-root-required` | 400 | The workspace has no project root, so it cannot write files. |
|
|
5862
|
+
| `path-names-no-file` | 403 | The spelling '*path*' does not name a file: it is empty, or it names a directory. |
|
|
5863
|
+
| `path-occupied-by-nonmember` | 403 | A non-member file already occupies '*path*'. Recovery: Choose an unoccupied member path. |
|
|
5864
|
+
| `path-outside-workspace` | 403 | A symlink on '*path*' resolves outside the namespace. |
|
|
5865
|
+
| `binary-write-unsupported` | 415 | A text EDIT cannot author binary '*mimetype*'; COPY or MOVE the bytes instead. |
|
|
5866
|
+
| `file-create-excluded` | 403 | A members exclusion (`!_glob_`) covers '*path*'. Recovery: Remove or disable the excluding members definition, or choose another path. |
|
|
5867
|
+
| `file-create-gitignored` | 403 | Active Git policy ignores '*path*', and no members definition includes it. Recovery: Choose a Git-admitted path or add a members definition that includes it. |
|
|
5868
|
+
| `file-materialization-limit` | 413 | The file exceeds the materialization byte limit and is not read into the workspace. |
|
|
5869
|
+
| `entry-not-found` | 404 | No member of this workspace is at '*path*'. Recovery: Check the path with FIND. EDIT creates files; `members (add)` admits existing files with a `{"glob": "<path>"}` body. |
|
|
5870
|
+
|
|
5871
|
+
§problems-exec **Execution Problems.** Every code this family mints, its status, and the sentence that is its contract (placeholders in *italics* are filled at emission; a fixed recovery follows its detail).
|
|
5872
|
+
|
|
5873
|
+
| code | status | contract |
|
|
5874
|
+
|---|---:|---|
|
|
5875
|
+
| `invalid-input-target` | 400 | SEND input addresses an execution, without a channel or scope. |
|
|
5876
|
+
| `input-unavailable` | 409 | This execution's input receiver is no longer enabled. |
|
|
5877
|
+
| `stream-not-found` | 404 | No execution exists at the requested address. |
|
|
5878
|
+
| `input-closed` | 410 | Execution input is closed. |
|
|
5879
|
+
|
|
5880
|
+
§problems-entries **Entry scheme Problems (log, worker, entries).** Every code this family mints, its status, and the sentence that is its contract (placeholders in *italics* are filled at emission; a fixed recovery follows its detail).
|
|
5881
|
+
|
|
5882
|
+
| code | status | contract |
|
|
5883
|
+
|---|---:|---|
|
|
5884
|
+
| `read-target-required` | 400 | READ requires a log coordinate. Recovery: Provide one exact log coordinate. |
|
|
5885
|
+
| `coordinate-malformed` | 400 | The log coordinate '*path*' is malformed. Recovery: Use one exact loop/turn/sequence coordinate. |
|
|
5886
|
+
| `worker-target-required` | 400 | EDIT requires a worker:// target. Recovery: Provide the worker target. |
|
|
5887
|
+
| `binary-edit-unsupported` | 415 | The #*channel* channel is binary and cannot be edited. |
|
|
5888
|
+
| `message-not-implemented` | 501 | SEND does not deliver messages to *scheme* entries. Recovery: To reply, SEND to an Open Message address or omit the target. `SEND (worker://<name>)` sends a new message. |
|
|
5889
|
+
| `worker-entity-not-editable` | 400 | A worker entity is not an editable entry. Recovery: EDIT requires an entry path, such as worker:///example.md. |
|
|
5890
|
+
| `message-empty` | 400 | SEND has no message text or attachments. |
|
|
5891
|
+
| `scope-unsupported` | 400 | A worker SEND takes no scope. |
|
|
5892
|
+
|
|
5893
|
+
§problems-functionality **Server and Functionality Problems.** Every code this family mints, its status, and the sentence that is its contract (placeholders in *italics* are filled at emission; a fixed recovery follows its detail).
|
|
5894
|
+
|
|
5895
|
+
| code | status | contract |
|
|
5896
|
+
|---|---:|---|
|
|
5897
|
+
| `service-starting` | 503 | The PLURNK service owns this listener but has not admitted its client interface yet. |
|
|
5898
|
+
| `configuration-unsupported` | 400 | Environment discovery reads this installation's declared configuration; client configuration contributes nothing. |
|
|
5899
|
+
| `name-reserved` | 400 | '*alias*' is plurnk's own: PLURNK_* configuration and provider credential names never reach a subprocess. |
|
|
5900
|
+
| `value-invalid` | 400 | '*alias*' needs a string value. |
|
|
5901
|
+
| `env-invalid` | 400 | `env` must be an object of string values; '*name*' is not a name a shell can export. |
|
|
5902
|
+
| `query-required` | 400 | discover takes a path or a glob. Recovery: Supply `{ "query": "<path or glob>" }`. |
|
|
5903
|
+
| `headless` | 409 | The workspace has no project root, so there are no file members. Recovery: Open the workspace on a project root. |
|
|
5904
|
+
| `definition-invalid` | 400 | A members definition is { glob }: a gitignore-style pattern, `!glob` to exclude; a skill definition names an installable skill. |
|
|
5905
|
+
| `model-scope` | 403 | The model may not change membership here: the members scope is none. Recovery: `git add` the file so git tracks it, or ask the operator to add it (/members add) or raise PLURNK_SERVICE_MEMBERS_MODEL_SCOPE. |
|
|
5906
|
+
| `registry-unreachable` | 502 | Skills registry *url* could not be reached. |
|
|
5907
|
+
| `registry-rejected` | 502 | Skills registry *url* answered *status*. |
|
|
5908
|
+
| `registry-invalid` | 502 | Skills registry *url* returned no skills array. |
|
|
5909
|
+
| `discover-failed` | 502 | Agent Skills source '*source*' could not be listed: *cause*. |
|
|
5910
|
+
| `alias-mismatch` | 400 | Alias '*alias*' must equal the skill name '*name*'. |
|
|
5911
|
+
| `scope-not-installable` | 400 | Service-provided skills can be enabled or disabled; adding a skill requires project or global scope. Recovery: Add it with scope "global" or open a workspace rooted in a project. |
|
|
5912
|
+
| `source-required` | 400 | Adding '*alias*' requires the standard installer source that provides it. |
|
|
5913
|
+
| `uninstall-failed` | 502 | Agent Skill '*name*' could not be removed from its *scope* root: *cause*. |
|
|
5914
|
+
| `workspace-not-found` | 404 | Workspace *id* does not exist. |
|
|
5915
|
+
| `state-not-json` | 400 | Worker module state is not JSON-serializable. |
|
|
5916
|
+
| `workspace-busy` | 409 | Workspace *id* is running an operation or another capability change. Recovery: Settle the current operation and retry the capability change. |
|
|
5917
|
+
| `not-configured` | 503 | No provider is configured for this worker. |
|
|
5918
|
+
| `model-worker-required` | 404 | No model worker exists for prompt injection (or to fork). |
|
|
5919
|
+
| `name-conflict` | 409 | The worker name is taken. Recovery: Choose another worker name. |
|
|
5920
|
+
| `offset-channel-required` | 400 | Recovery: Select the channel to read from the offset. |
|
|
5921
|
+
| `target-invalid` | 400 | Recovery: Use a scheme://path target. |
|
|
5922
|
+
| `proposal-not-pending` | 409 | Recovery: Refresh pending proposals before resolving one. |
|
|
5923
|
+
| `loop-policy-invalid` | 400 | An unattended loop cannot hold a proposal for review: nobody is present to answer. Recovery: State proposals accept or reject, or attend the loop. |
|
|
5924
|
+
| `scope-cancelled` | 499 | The worker scope was cancelled: *reason*. |
|
|
5925
|
+
| `range-not-satisfiable` | 416 | `Range <0,-1>` starts at 0, which is not a line; lines are numbered from 1. Recovery: Write `<1,-1>` to trim every line of the body; `KILL (log:///…/READ)` with no scope retires the item. |
|
|
5926
|
+
| `registry-not-configured` | 501 | Skills registry search is disabled; PLURNK_SERVICE_SKILLS_REGISTRY_URL is empty. |
|
|
5927
|
+
| `install-failed` | 502 | Agent Skill '*name*' could not be installed from '*source*': *cause* (or the installer reported it but its SKILL.md does not exist). |
|
|
5928
|
+
| `skill-missing` | 404 | Agent Skill '*alias*' is not installed under its *scope* root, or is not provided by this service. |
|
|
5929
|
+
| `skill-invalid` | 422 | Agent Skill '*alias*' is not a valid standard skill: *cause*. |
|
|
5930
|
+
|
|
5931
|
+
§pinned-wording-core **Pinned wording.** Verbatim sentences tests pin: each is contract, and a change here is a change of contract.
|
|
5932
|
+
|
|
5933
|
+
| sentence | arises when |
|
|
5934
|
+
|---|---|
|
|
5935
|
+
| Nothing is in flight. Continuing. | a WAIT (or a premature terminal) with no live work ({§wait-obligation-matrix}) |
|
|
5936
|
+
| Completion deferred. Conclude with KILL alone. | a concluding KILL that carries other operations ({§kill-conclusion}) |
|
|
5937
|
+
| Context Token Budget Overflow: logTokensTotal exceeds logTokensMax; retained context cannot be admitted. | output admission over the retained-context ceiling |
|
|
5938
|
+
| This run is unattended: nobody is present to answer. | a capability that needs a present operator in an unattended loop ({§loop-attendance}) |
|
|
5939
|
+
| 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 |
|
|
5940
|
+
| 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 |
|
|
5941
|
+
| The stream was cancelled by KILL. | a stream terminal after KILL |
|
|
5942
|
+
| '*program*' exited with code *n*. | an execution's non-zero exit |
|
|
5943
|
+
| '*path*' is a directory, not a file; READ reads one file. Recovery: List its files with `FIND (_path_/)`, then READ one by its path. | READ of a directory |
|
|
5944
|
+
| The execution at ops://*worker*/*loop* has not concluded. | a bare READ of a running worker's result (425) |
|
|
5945
|
+
| The child provider failed. | a child's provider failure read back by its parent |
|
|
5946
|
+
| '*path*' exists on disk but is not a member of this workspace. Recovery: Admit it with `members (add)` and a `{"glob": "<path>"}` body. | a non-member on disk at the addressed path |
|