@plurnk/plurnk-service 1.14.2 → 1.15.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/SPEC.md +177 -135
- package/dist/build-info.json +1 -1
- package/dist/content/byte-view.d.ts +14 -0
- package/dist/content/byte-view.d.ts.map +1 -0
- package/dist/content/byte-view.js +33 -0
- package/dist/content/byte-view.js.map +1 -0
- package/dist/content/edit-receipt.d.ts.map +1 -1
- package/dist/content/edit-receipt.js +12 -1
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/line-marker.d.ts +2 -1
- package/dist/content/line-marker.d.ts.map +1 -1
- package/dist/content/line-marker.js +1 -0
- package/dist/content/line-marker.js.map +1 -1
- package/dist/content/matcher.d.ts +1 -0
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +1 -0
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/read-projector.d.ts +4 -1
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +80 -3
- package/dist/content/read-projector.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +43 -0
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -0
- package/dist/core/AdmittedTurnExecutor.js +245 -0
- package/dist/core/AdmittedTurnExecutor.js.map +1 -0
- package/dist/core/BareBatchRunner.d.ts +26 -0
- package/dist/core/BareBatchRunner.d.ts.map +1 -0
- package/dist/core/BareBatchRunner.js +104 -0
- package/dist/core/BareBatchRunner.js.map +1 -0
- package/dist/core/BudgetReadout.d.ts +1 -1
- package/dist/core/BudgetReadout.d.ts.map +1 -1
- package/dist/core/BudgetReadout.js +19 -10
- package/dist/core/BudgetReadout.js.map +1 -1
- package/dist/core/CapabilityResolver.d.ts +2 -1
- package/dist/core/CapabilityResolver.d.ts.map +1 -1
- package/dist/core/CapabilityResolver.js +8 -9
- package/dist/core/CapabilityResolver.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +1 -1
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/DataStatementRunner.d.ts +35 -0
- package/dist/core/DataStatementRunner.d.ts.map +1 -0
- package/dist/core/DataStatementRunner.js +252 -0
- package/dist/core/DataStatementRunner.js.map +1 -0
- package/dist/core/Dispatcher.d.ts +8 -3
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +88 -738
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/EditMutations.d.ts +39 -0
- package/dist/core/EditMutations.d.ts.map +1 -0
- package/dist/core/EditMutations.js +418 -0
- package/dist/core/EditMutations.js.map +1 -0
- package/dist/core/Engine.d.ts +2 -23
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +18 -240
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +22 -15
- package/dist/core/KillHandler.d.ts +32 -0
- package/dist/core/KillHandler.d.ts.map +1 -0
- package/dist/core/KillHandler.js +179 -0
- package/dist/core/KillHandler.js.map +1 -0
- package/dist/core/LogVisibility.d.ts +1 -1
- package/dist/core/LogVisibility.d.ts.map +1 -1
- package/dist/core/LogVisibility.js +3 -4
- package/dist/core/LogVisibility.js.map +1 -1
- package/dist/core/LogWriter.d.ts +42 -0
- package/dist/core/LogWriter.d.ts.map +1 -0
- package/dist/core/LogWriter.js +136 -0
- package/dist/core/LogWriter.js.map +1 -0
- package/dist/core/LoopDriver.d.ts +46 -0
- package/dist/core/LoopDriver.d.ts.map +1 -0
- package/dist/core/LoopDriver.js +263 -0
- package/dist/core/LoopDriver.js.map +1 -0
- package/dist/core/LoopLifecycle.d.ts +2 -1
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/MembershipMaterialization.d.ts +7 -0
- package/dist/core/MembershipMaterialization.d.ts.map +1 -0
- package/dist/core/MembershipMaterialization.js +283 -0
- package/dist/core/MembershipMaterialization.js.map +1 -0
- package/dist/core/MutationEffects.d.ts +29 -0
- package/dist/core/MutationEffects.d.ts.map +1 -0
- package/dist/core/MutationEffects.js +318 -0
- package/dist/core/MutationEffects.js.map +1 -0
- package/dist/core/OverflowTurn.d.ts +4 -4
- package/dist/core/OverflowTurn.d.ts.map +1 -1
- package/dist/core/OverflowTurn.js +6 -7
- package/dist/core/OverflowTurn.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +28 -5
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/ResourceMutations.d.ts +12 -36
- package/dist/core/ResourceMutations.d.ts.map +1 -1
- package/dist/core/ResourceMutations.js +27 -1351
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.d.ts +21 -0
- package/dist/core/ResourceSelector.d.ts.map +1 -0
- package/dist/core/ResourceSelector.js +204 -0
- package/dist/core/ResourceSelector.js.map +1 -0
- package/dist/core/ResourceTransfers.d.ts +55 -0
- package/dist/core/ResourceTransfers.d.ts.map +1 -0
- package/dist/core/ResourceTransfers.js +460 -0
- package/dist/core/ResourceTransfers.js.map +1 -0
- package/dist/core/SchemeRegistry.js +2 -2
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/SendBroadcastHandler.d.ts +40 -0
- package/dist/core/SendBroadcastHandler.d.ts.map +1 -0
- package/dist/core/SendBroadcastHandler.js +159 -0
- package/dist/core/SendBroadcastHandler.js.map +1 -0
- package/dist/core/StoredPacket.d.ts +11 -0
- package/dist/core/StoredPacket.d.ts.map +1 -1
- package/dist/core/StoredPacket.js +22 -1
- package/dist/core/StoredPacket.js.map +1 -1
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +19 -9
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/TokenCalibration.d.ts +16 -0
- package/dist/core/TokenCalibration.d.ts.map +1 -0
- package/dist/core/TokenCalibration.js +35 -0
- package/dist/core/TokenCalibration.js.map +1 -0
- package/dist/core/ToolResources.d.ts.map +1 -1
- package/dist/core/ToolResources.js +15 -12
- package/dist/core/ToolResources.js.map +1 -1
- package/dist/core/TurnMaterialization.d.ts +37 -0
- package/dist/core/TurnMaterialization.d.ts.map +1 -0
- package/dist/core/TurnMaterialization.js +307 -0
- package/dist/core/TurnMaterialization.js.map +1 -0
- package/dist/core/TurnOps.d.ts.map +1 -1
- package/dist/core/TurnOps.js +4 -6
- package/dist/core/TurnOps.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +15 -27
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +73 -667
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/WorkerControlHandler.d.ts +15 -0
- package/dist/core/WorkerControlHandler.d.ts.map +1 -0
- package/dist/core/WorkerControlHandler.js +89 -0
- package/dist/core/WorkerControlHandler.js.map +1 -0
- package/dist/core/attachments.d.ts +14 -0
- package/dist/core/attachments.d.ts.map +1 -0
- package/dist/core/attachments.js +18 -0
- package/dist/core/attachments.js.map +1 -0
- package/dist/core/git-membership.d.ts +15 -0
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +4 -273
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/git-state.d.ts +2 -1
- package/dist/core/git-state.d.ts.map +1 -1
- package/dist/core/mutation-types.d.ts +101 -0
- package/dist/core/mutation-types.d.ts.map +1 -0
- package/dist/core/mutation-types.js +2 -0
- package/dist/core/mutation-types.js.map +1 -0
- package/dist/core/operation-target-groups.js +1 -1
- package/dist/core/operation-target-groups.js.map +1 -1
- package/dist/core/packet-wire.d.ts +7 -6
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +57 -6
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/plurnk-uri.d.ts +0 -1
- package/dist/core/plurnk-uri.d.ts.map +1 -1
- package/dist/core/plurnk-uri.js +1 -1
- package/dist/core/plurnk-uri.js.map +1 -1
- package/dist/core/statement-primary.d.ts +4 -0
- package/dist/core/statement-primary.d.ts.map +1 -0
- package/dist/core/statement-primary.js +3 -0
- package/dist/core/statement-primary.js.map +1 -0
- package/dist/core/teaching-corpus.d.ts +0 -1
- package/dist/core/teaching-corpus.d.ts.map +1 -1
- package/dist/core/teaching-corpus.js +0 -9
- package/dist/core/teaching-corpus.js.map +1 -1
- package/dist/core/turn-scheduler.js +3 -3
- package/dist/core/turn-scheduler.js.map +1 -1
- package/dist/core/turn-signals.d.ts +15 -0
- package/dist/core/turn-signals.d.ts.map +1 -0
- package/dist/core/turn-signals.js +19 -0
- package/dist/core/turn-signals.js.map +1 -0
- package/dist/core/worker-settings.d.ts +0 -1
- package/dist/core/worker-settings.d.ts.map +1 -1
- package/dist/core/worker-settings.js +1 -1
- package/dist/core/worker-settings.js.map +1 -1
- package/dist/digest/Digest.d.ts +3 -16
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +10 -958
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/DigestRender.d.ts +12 -0
- package/dist/digest/DigestRender.d.ts.map +1 -0
- package/dist/digest/DigestRender.js +644 -0
- package/dist/digest/DigestRender.js.map +1 -0
- package/dist/digest/DigestRequiem.d.ts +13 -0
- package/dist/digest/DigestRequiem.d.ts.map +1 -0
- package/dist/digest/DigestRequiem.js +332 -0
- package/dist/digest/DigestRequiem.js.map +1 -0
- package/dist/digest/digest-rows.d.ts +306 -0
- package/dist/digest/digest-rows.d.ts.map +1 -0
- package/dist/digest/digest-rows.js +2 -0
- package/dist/digest/digest-rows.js.map +1 -0
- package/dist/observe/api.d.ts +0 -2
- package/dist/observe/api.d.ts.map +1 -1
- package/dist/observe/api.js +2 -2
- package/dist/observe/api.js.map +1 -1
- package/dist/observe/metrics.d.ts +0 -1
- package/dist/observe/metrics.d.ts.map +1 -1
- package/dist/observe/metrics.js +0 -1
- package/dist/observe/metrics.js.map +1 -1
- package/dist/schemes/Exec.d.ts +4 -1
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +90 -45
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.d.ts +2 -1
- package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +3 -3
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/File.d.ts +4 -1
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +70 -4
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts +4 -5
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +20 -98
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +0 -12
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts +0 -1
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-find.d.ts +4 -2
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +68 -10
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-manifest.d.ts +1 -2
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.d.ts +2 -1
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +12 -2
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-semantic.d.ts +1 -0
- package/dist/schemes/_entry-semantic.d.ts.map +1 -1
- package/dist/schemes/_entry-semantic.js +3 -0
- package/dist/schemes/_entry-semantic.js.map +1 -1
- package/dist/schemes/_entry-semantic.sql +2 -2
- package/dist/schemes/_entry-send.d.ts +0 -1
- package/dist/schemes/_entry-send.d.ts.map +1 -1
- package/dist/schemes/_entry-send.js +5 -80
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/schemes/exec-runtime.d.ts +7 -0
- package/dist/schemes/exec-runtime.d.ts.map +1 -0
- package/dist/schemes/exec-runtime.js +2 -0
- package/dist/schemes/exec-runtime.js.map +1 -0
- package/dist/server/ClientReads.d.ts +34 -0
- package/dist/server/ClientReads.d.ts.map +1 -0
- package/dist/server/ClientReads.js +210 -0
- package/dist/server/ClientReads.js.map +1 -0
- package/dist/server/Daemon.d.ts +12 -22
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +31 -362
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DaemonModule.d.ts +6 -5
- package/dist/server/DaemonModule.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +3 -2
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +7 -3
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/Functionality.d.ts +0 -12
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/FunctionalityManager.d.ts +0 -1
- package/dist/server/FunctionalityManager.d.ts.map +1 -1
- package/dist/server/FunctionalityManager.js +2 -2
- package/dist/server/FunctionalityManager.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts +2 -13
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +4 -4
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/SkillsFunctionality.d.ts +1 -7
- package/dist/server/SkillsFunctionality.d.ts.map +1 -1
- package/dist/server/SkillsFunctionality.js +3 -3
- package/dist/server/SkillsFunctionality.js.map +1 -1
- package/dist/server/WorkerModelResolver.d.ts +17 -0
- package/dist/server/WorkerModelResolver.d.ts.map +1 -0
- package/dist/server/WorkerModelResolver.js +166 -0
- package/dist/server/WorkerModelResolver.js.map +1 -0
- package/dist/server/daemon-results.d.ts +5 -0
- package/dist/server/daemon-results.d.ts.map +1 -0
- package/dist/server/daemon-results.js +7 -0
- package/dist/server/daemon-results.js.map +1 -0
- package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
- package/dist/server/dispatch-as-plurnk.js +4 -6
- package/dist/server/dispatch-as-plurnk.js.map +1 -1
- package/dist/server/loopDocs.d.ts.map +1 -1
- package/dist/server/loopDocs.js +11 -2
- package/dist/server/loopDocs.js.map +1 -1
- package/migrations/001_schema.sql +21 -92
- package/package.json +30 -30
package/SPEC.md
CHANGED
|
@@ -131,7 +131,7 @@ scored. Every recovery checkpoint broadcasts live, while the model-facing Notice
|
|
|
131
131
|
retains only the current provider state; the next completed exchange notices
|
|
132
132
|
`provider_recovered`. Recovery is bounded by `PLURNK_SERVICE_PROVIDER_RECOVERY`; when it
|
|
133
133
|
is spent the turn completes as `202` and the loop parks exactly like a
|
|
134
|
-
`## SEND0
|
|
134
|
+
`## SEND0 (WAIT)` wait ({§worker-lifecycle-wake-requeue-not-terminal}), resuming on the
|
|
135
135
|
next prompt or wake with its log intact. Only a client cancel, the loop deadline
|
|
136
136
|
({§operator-config-loop-timeout}), or a non-recoverable provider Problem (refusal,
|
|
137
137
|
authorization, quota, an invalid response) settles a loop on a provider failure.
|
|
@@ -464,10 +464,10 @@ executors, schemes, and family managers (`## FIND0 [+init,+plurnk]
|
|
|
464
464
|
(worker://~/_plurnk/plurnk/*.md) <1,-1>`), enabled tools (`## FIND0 [+init,+tools]
|
|
465
465
|
(worker://~/_plurnk/tools/*.md) <1,-1>`), enabled agents (`## FIND0 [+init,+agents]
|
|
466
466
|
(worker://~/_plurnk/agents/*.md) <1,-1>`, {§a2a-agents-catalog}), enabled members
|
|
467
|
-
(`## FIND0
|
|
468
|
-
{§members-projection}), workspace files (`## FIND0
|
|
469
|
-
workspace entries (`## FIND0
|
|
470
|
-
private worker entries (`## FIND0
|
|
467
|
+
(`## FIND0 (worker://~/_plurnk/members/*.md) <1,-1>`,
|
|
468
|
+
{§members-projection}), workspace files (`## FIND0 (*) <!-- workspace files -->`),
|
|
469
|
+
workspace entries (`## FIND0 (worker:///*) <!-- workspace entries -->`), and
|
|
470
|
+
private worker entries (`## FIND0 (worker://~/*) <!-- private worker entries -->`).
|
|
471
471
|
Only those three namespace surveys carry annotations because the bare targets do not
|
|
472
472
|
name their surface; generated paths and classification tags already name every other
|
|
473
473
|
survey. Naming `~` private prevents a worker from offering its own `~` address to
|
|
@@ -491,7 +491,7 @@ direct-entry-plus-directory count; `-1` enables the ordinary markerless page;
|
|
|
491
491
|
unset / `0` disables previews. `log://` is absent because the current worker's
|
|
492
492
|
log already renders in present mode.
|
|
493
493
|
|
|
494
|
-
§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}. It preserves one
|
|
494
|
+
§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}. It preserves one visible exact `turnOps` item and dispatches the same source into ordinary PLAN, one archiving COPY, orienting READ/FIND, and terminal `SEND0 (NEXT)` rows (authored in their {§op-mode-phases} execution order). Every orienting row is structurally classified `_plurnk` and `init`; the archiving `COPY (prompt:///<loop>/1)` onto `worker://~/prompts.md <-1>` is classified `_plurnk` and `backup` — the worked COPY specimen, showing the private space as scratch, emitted whenever the loop publishes a prompt ({§prompt-entry}). The PLAN is the canonical {§plan-value} with two entries in order: the `memory` entry reads "Determinations and Decisions must be persisted as `memory` items.", then `Discover the tooling available and survey the workspace file root.` is `in_progress`; SEND hands off with `Next: Address the prompt.` The first model request occupies the following turn and therefore begins at database/log turn sequence 2; “turn zero” is the initialization phase's model-facing label, not a zero-based database coordinate. Client and `_plurnk` administrative workers execute operation turns and do not receive model initialization.
|
|
495
495
|
|
|
496
496
|
### §machine-processes The machine and its processes: workspace, worker, fork
|
|
497
497
|
|
|
@@ -534,7 +534,7 @@ terminal history.**
|
|
|
534
534
|
|
|
535
535
|
§machine-processes-worker-is-its-log **A worker's conversational memory of
|
|
536
536
|
the shared world is its log, with no hidden per-worker snapshot beside it.**
|
|
537
|
-
|
|
537
|
+
A scoped KILL folds canonical body intervals on that worker's rows ({§log-kill-scope});
|
|
538
538
|
lineage activity and explicit commons broadcasts arrive as attributed log
|
|
539
539
|
entries ({§env-delta}). Worker-owned entries include deliberate scratch and
|
|
540
540
|
other private resources; their manifest declares whether a FORK snapshots,
|
|
@@ -594,7 +594,7 @@ continues to decompose other authorities without treating them as mintable.
|
|
|
594
594
|
|
|
595
595
|
§worker-write-scoping **Writes are own-space-and-commons only**: a model writes `worker://~/` and `worker:///` — every ancestry-readable named authority is read-only to it (403), while an unreadable name remains 404 under {§worker-read-scope}. `owner_id` is engine-stamped from the dispatch context, never model-set. Nothing worker-authored can land under another principal. The entry-copy seam (COPY/MOVE) is pathname-keyed and addresses the commons; a space's content moves via READ + EDIT. The one exception inside a writable space is the generated subtree below.
|
|
596
596
|
|
|
597
|
-
§worker-generated-subtree **`_plurnk/` is Plurnk's generated subtree in every worker space.** Every Plurnk-generated per-Worker document lives under `worker://~/_plurnk/`: the project instructions (`_plurnk/agents.md`, with nested AGENTS.md files under `_plurnk/instructions/**` preserving their subtree paths — the standard's closest-file scope, materialized without any foisted READ or teaching), standard Agent Skills and Plurnk-generated references (`_plurnk/skills/**`), executable families (`_plurnk/tools/**`), and future family catalogs. The subtree is readable exactly like the rest of the space ({§worker-read-scope}) and writable only by the `_plurnk` writer tier: a model, client, or plugin EDIT, KILL, SEND 410, or COPY/MOVE destination whose pathname begins `/_plurnk/` is refused 403 `worker-generated-read-only`, in the commons as well as in own and named spaces. Its documents are materialized through ordinary `_plurnk` **maintenance** turns ({§actor-boundary-doc-injection}), so provenance is legible at the address and durable in the log — but a receipt answers an asker, and maintenance turns have none: their successful rows never render in the packet (failures remain visible), while READ over `log:///` recovers them exactly and the turn's self-
|
|
597
|
+
§worker-generated-subtree **`_plurnk/` is Plurnk's generated subtree in every worker space.** Every Plurnk-generated per-Worker document lives under `worker://~/_plurnk/`: the project instructions (`_plurnk/agents.md`, with nested AGENTS.md files under `_plurnk/instructions/**` preserving their subtree paths — the standard's closest-file scope, materialized without any foisted READ or teaching), standard Agent Skills and Plurnk-generated references (`_plurnk/skills/**`), executable families (`_plurnk/tools/**`), and future family catalogs. The subtree is readable exactly like the rest of the space ({§worker-read-scope}) and writable only by the `_plurnk` writer tier: a model, client, or plugin EDIT, KILL, SEND 410, or COPY/MOVE destination whose pathname begins `/_plurnk/` is refused 403 `worker-generated-read-only`, in the commons as well as in own and named spaces. Its documents are materialized through ordinary `_plurnk` **maintenance** turns ({§actor-boundary-doc-injection}), so provenance is legible at the address and durable in the log — but a receipt answers an asker, and maintenance turns have none: their successful rows never render in the packet (failures remain visible), while READ over `log:///` recovers them exactly and the turn's self-curation keeps client waterfalls tidy. On FORK the subtree is never byte-copied; the child rederives it from its inherited Functionality ({§machine-processes-entry-inheritance}). A runtime's `resourcesPath` is relative to this root ({§tools-resource-materialization}). No world-readable kernel authority exists; there is no `worker://plurnk/`.
|
|
598
598
|
|
|
599
599
|
§worker-control-addressing **Only an exact authority-only address selects worker
|
|
600
600
|
control.** Control is same-workspace only ({§actor-boundary}). Generic URI
|
|
@@ -639,18 +639,16 @@ literal `workers.name` value.
|
|
|
639
639
|
parent's private entries — its own space deep-copied with the owner
|
|
640
640
|
remapped (source → branch) — so the branch opens with the parent's notes and
|
|
641
641
|
diverges on its own edits: *fork = everything-in-common-but-name*.
|
|
642
|
-
- §worker-spawn-no-
|
|
643
|
-
removed outright (#396)
|
|
644
|
-
|
|
645
|
-
branches through ordinary EXEC git, taught by the git skill — never engine
|
|
646
|
-
machinery. No batch, branch, or child comes into being from a signalled spawn.
|
|
642
|
+
- §worker-spawn-no-branch **WORK and FORK take a worker path and a prompt, nothing else.** Branch
|
|
643
|
+
delegation was removed outright (#396). A model manages git branches through ordinary
|
|
644
|
+
EXEC git, taught by the git skill — never engine machinery.
|
|
647
645
|
- §worker-delegation-inherits-policy **Delegation cannot widen authority.** WORK and FORK copy the delegating actor's complete effective capability policy into the child's immutable `capability_bound`; later widening of any parent layer cannot enlarge that child. Every fresh delegated loop carries that complete effective attenuation and the delegating loop's proposal disposition, including a loop created by SEND to an idle Worker. SEND into an active or parked loop leaves that loop's immutable policy untouched. The bound is delegation authority captured by value, not a client binding or a live parent-policy link.
|
|
648
646
|
- §worker-lifecycle-wake-requeue-not-terminal **A wake re-queue is not a terminal.** A conclusion-wake resumes a 202-blocked loop by re-queueing it (202 → 100); when that lands while the loop's own live drain is between turns, the drain **re-claims and continues** (atomic 100 → 102; the injected prompt is already the next turn). The internal re-queue is never reported as an outward terminal.
|
|
649
647
|
|
|
650
648
|
- §worker-scheme-collect **Collect** — a worker's loop reaching a terminal status
|
|
651
649
|
surfaces to its direct parent as an ambient delta ({§env-delta}): a `SEND` from
|
|
652
650
|
`worker://<name>` carrying the loop's exact terminal operation result. A
|
|
653
|
-
**2xx deliverable is born
|
|
651
|
+
**2xx deliverable is born visible** (its body
|
|
654
652
|
materialized into the parent's packet, not hidden behind a fold): a child's
|
|
655
653
|
success must reach the parent open and awakening, never a bodyless row. An
|
|
656
654
|
non-2xx result surfaces folded; a failure retains its exact status and Problem. Every death-path is stamped uniformly —
|
|
@@ -673,10 +671,10 @@ machinery. No batch, branch, or child comes into being from a signalled spawn.
|
|
|
673
671
|
history; this clump is the current inventory that keeps an active obligation
|
|
674
672
|
visible even when no new activity arrived. Each open stream pointer carries
|
|
675
673
|
its channels' sizes and growth since the last packet (`* active
|
|
676
|
-
sh:///1/2/3 — stdout 340 lines (+2048 bytes)`) — the only thing the model
|
|
674
|
+
sh:///1/2/3/EXEC — stdout 340 lines (+2048 bytes)`) — the only thing the model
|
|
677
675
|
learns about a stream before it closes ({§exec-stream}). It is orienting state, never
|
|
678
676
|
advice: the model sees its live subtree (`* 102 worker://worker-x`, `* active
|
|
679
|
-
sh:///1/2/3`) and reasons for itself — READ/
|
|
677
|
+
sh:///1/2/3/EXEC`) and reasons for itself — READ/KILL via the path.
|
|
680
678
|
Empty sections are omitted, like errors.
|
|
681
679
|
|
|
682
680
|
Worker control rides the daemon's inject seam (active→fold, idle→enqueue+drain), so the handler creates/branches the worker and hands off; the daemon owns provider + system prompt. FORK/WORK carry the seed task in the body and are their own ops, dispatched to worker control — never the entry-copy path.
|
|
@@ -875,13 +873,13 @@ latest context gauge.
|
|
|
875
873
|
|
|
876
874
|
### §emission-admission Provider emission admission
|
|
877
875
|
|
|
878
|
-
A completed provider exchange is an **emission attempt**, not necessarily an engine turn. The provider transports and observes the model's bytes; ANTLR is the admission authority only after provider completion. Admission requires at least one parsed source operation, no `unparsedTail`, and a trustworthy effective envelope. Canonical source begins with PLAN and ends with a terminal SEND. If no valid leading PLAN or terminal SEND was parsed, the parser supplies
|
|
876
|
+
A completed provider exchange is an **emission attempt**, not necessarily an engine turn. The provider transports and observes the model's bytes; ANTLR is the admission authority only after provider completion. Admission requires at least one parsed source operation, no `unparsedTail`, and a trustworthy effective envelope. Canonical source begins with PLAN and ends with a terminal SEND. If no valid leading PLAN or terminal SEND was parsed, the parser supplies a bodyless `## SEND0 (NEXT)`, records its exact hard diagnostic, and Core admits the useful operations instead of resampling. Both diagnostics participate in one ordinary struck turn, never one strike apiece. An authored PLAN or terminal SEND remains a real boundary, so an error outside either authored edge, post-terminal content, a boundary-destroying tail, or no source operation rejects the entire exchange regardless of `finishReason`; no recovered prefix dispatches. Parser warnings remain admissible. `finish=length` is forensic evidence of likely truncation, not an independent rejection rule. A provider-declared resource interruption never reaches admission, even when its partial bytes form a complete-looking frame ({§provider-interrupted-attempt}). The accepted packet retains the provider's source bytes exactly in response evidence and `turnOps`; synthetic envelope statements exist only in the normalized operation program and its durable rows.
|
|
879
877
|
|
|
880
|
-
§safe-uri-target-groups After source and authored-command admission, Core tolerates one target group on READ
|
|
878
|
+
§safe-uri-target-groups After source and authored-command admission, Core tolerates one target group on READ or KILL only when splitting its raw target at top-level comma or whitespace separators produces at least two members and every member independently parses as an explicit `scheme://` URI. Request-metadata blocks are opaque to this split. Each member becomes one ordinary statement with an independent dispatch outcome and log row, in authored member order; scheduling may still move the complete operation class under {§op-mode-phases}. Otherwise the target remains exactly singular, including local filenames containing spaces or commas. The stored `turnOps` and authored command count remain unexpanded, and no other operation admits target groups.
|
|
881
879
|
|
|
882
880
|
Core retries a rejected emission against the exact same packet beneath the same engine turn, up to `PLURNK_SERVICE_EMISSION_ATTEMPTS`. Rejected bytes never dispatch or reach the engine strike rail. Before each `generate`, Core opens one durable logical `inference_calls` row with its `model_calls` specialization and emission-specific `turn_attempts` admission row. A call that ends without response evidence leaves that admission row unclassified (`accepted IS NULL`) and does not consume the emission-attempt ceiling. Beneath the logical call, every provider observer invocation opens one cardinal `provider_requests` occurrence immediately before physical I/O and settles it as response or error. Adapter retries and capacity failover append requests in issue order; a response-less failure therefore remains an accounted occurrence rather than disappearing. Normalized response evidence is durable before parser classification and does not duplicate the separately owned accounting. The accepted exchange alone extends `turns.packet` with response evidence; every physical request remains in turn and loop accounting, while the context gauge reads the latest settled emission request on the latest turn. Digest exposes rejected response evidence as `packetNNN.attemptNNN.rejected.*` and every physical request in its machine-readable ledger.
|
|
883
881
|
|
|
884
|
-
The first exhaustion in a consecutive sequence closes that unadmitted turn as a continue and opens exactly one ordinary recovery turn. Its packet projects the latest rejected response
|
|
882
|
+
The first exhaustion in a consecutive sequence closes that unadmitted turn as a continue and opens exactly one ordinary recovery turn. Its packet projects the latest rejected response visibly from a durably folded emission-attempt item under {§rejected-emission-entry} and carries one transient `invalid_emission` Notice: `Response rejected before dispatch; no operations were performed.` followed by `Parser: <the latest attempt's first diagnostic>` with its `content-offset` position — the model sees why, at which line, against its own projected text. The Notice states only observed admission facts; it does not classify the response as unrecoverable, infer why generation ended, or prescribe intent beyond the parser-owned diagnostic. Attempt count and rail state never become model-facing. The recovery turn has its own honestly stored packet and its configured private same-packet attempts. The packet-local projection never changes the row's curation state, so no later packet repeats the malformed body unless the model explicitly OPENs it. Admission clears the recovery state; exhausting the informed turn terminates instead of opening another.
|
|
885
883
|
|
|
886
884
|
An admitted program may contain bounded malformed statements or recovered
|
|
887
885
|
envelope defaults. Parsed operations still dispatch; each hard parser diagnostic
|
|
@@ -1137,6 +1135,8 @@ Every fact names the canonical key, never the host root or an echo of the
|
|
|
1137
1135
|
model's spelling. These classes let a caller distinguish a wrong address, an
|
|
1138
1136
|
invalid range, read-only authority, and occupied hidden state without guessing.
|
|
1139
1137
|
|
|
1138
|
+
§membership-read-refusal **A READ miss that is really a non-member is refused, not denied.** An exact-path READ of an in-root path that exists on disk but is not a member returns 404 `entry-not-member` — `'<key>' exists on disk but is not a member of this workspace.` — with a recovery naming the door (`## EXEC0 [members] (add)` with a `{"glob": "<path>"}` body); it never claims absence. Occupancy surfaces, content does not ({§membership}).
|
|
1139
|
+
|
|
1140
1140
|
§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.
|
|
1141
1141
|
|
|
1142
1142
|
### §scheme-manifest Manifest
|
|
@@ -1156,7 +1156,7 @@ There is no fictional cross-scheme SQL transaction.
|
|
|
1156
1156
|
§op-methods-op-dispatch Engine operation ownership follows the public scheme contract:
|
|
1157
1157
|
|
|
1158
1158
|
- EDIT resource batches dispatch through `editBatch`.
|
|
1159
|
-
-
|
|
1159
|
+
- A log KILL dispatches only to the core-owned log curation handler ({§log-kill-scope}); an entry scheme's `kill` method never sees a `log:///` target.
|
|
1160
1160
|
- Other delegated operations use the corresponding lowercase `SchemeHandler` method, with standard FIND supplied for a data scheme that omits a custom implementation.
|
|
1161
1161
|
- COPY and MOVE are engine-owned compositions over CRUD primitives ({§copy}/{§move}).
|
|
1162
1162
|
|
|
@@ -1168,9 +1168,9 @@ Registration precedes loop affinity:
|
|
|
1168
1168
|
| Registered but inactive under flag | The flag gate returns `403 scheme-unavailable`. |
|
|
1169
1169
|
| Registered and active | Dispatch continues to the operation owner. |
|
|
1170
1170
|
|
|
1171
|
-
- §op-mode-phases **A continuing turn executes in MODE phases.** A model turn describes intended effects and requested observations; it is not an imperative program whose later statements can consume invisible same-turn results. The engine therefore performs four stable phases: **Mutate** (`EDIT`, `COPY`, `MOVE`, `KILL
|
|
1171
|
+
- §op-mode-phases **A continuing turn executes in MODE phases.** A model turn describes intended effects and requested observations; it is not an imperative program whose later statements can consume invisible same-turn results. The engine therefore performs four stable phases: **Mutate** (`EDIT`, `COPY`, `MOVE`, `KILL`), **Observe** (`FIND`, `READ`, `BARE`), **Do** (all remaining non-terminal actions, including `EXEC`, `WORK`, `FORK`, and directed `SEND`), then **End** (the terminal `SEND`). `PLAN` remains the turn anchor and is recorded before those phases. Authored order is preserved within each phase. A result still lands in the next packet; phasing makes that result describe settled state instead of an accidental intermediate state.
|
|
1172
1172
|
|
|
1173
|
-
§bare-inference **BARE is isolated, synchronous retrieval over the durable child-provider policy.** Its body is the complete prompt and becomes the sole user message; Core supplies no PLURNK system packet, log context, tools, GBNF, parser, target, worker, or persistent child state. The selected provider is exactly the loop's WORK/FORK child provider, falling back to the parent provider when the durable policy is inherit. All BARE statements in one admitted turn receive logical model-call identities in authored order and launch concurrently under the loop cancellation signal. Core awaits the batch, isolates a provider failure to that operation, then records results and notifications in authored order regardless of completion order. Accounting or persistence failure is internal and fails hard. Each response is unseen retrieval work: the canonical
|
|
1173
|
+
§bare-inference **BARE is isolated, synchronous retrieval over the durable child-provider policy.** Its body is the complete prompt and becomes the sole user message; Core supplies no PLURNK system packet, log context, tools, GBNF, parser, target, worker, or persistent child state. The selected provider is exactly the loop's WORK/FORK child provider, falling back to the parent provider when the durable policy is inherit. All BARE statements in one admitted turn receive logical model-call identities in authored order and launch concurrently under the loop cancellation signal. Core awaits the batch, isolates a provider failure to that operation, then records results and notifications in authored order regardless of completion order. Accounting or persistence failure is internal and fails hard. Each response is unseen retrieval work: the canonical label is `## SEND0 (NEXT)`, and a same-turn `(TERM)` is refused until the next packet presents it.
|
|
1174
1174
|
|
|
1175
1175
|
- §op-synchronous **Decisive operations settle before the next scheduled operation.** The dispatcher `await`s every decisive operation. Work remains in flight only when the operation's contract deliberately creates concurrency: `FORK`, `WORK`, stream-producing `EXEC`, and a streaming `READ` after its scheme-specific acquisition boundary. Such a READ first establishes its durable subscription, returns `102`, and then retains only its `StreamSubscription`; a later scheduled operation may address that live owner. MODE changes scheduling, not completion semantics. This is why a same-turn KILL followed by SEND signal `200` concludes ({§send-premature-terminate}): KILL synchronously flips the worker's live loops terminal (`engine_terminate_worker_live_loops`) before the End phase judges the pending set, while the physical scope reap rides `cancelWorker` asynchronously and invisibly.
|
|
1176
1176
|
|
|
@@ -1204,12 +1204,12 @@ snapshot. Cross-resource MOVE is ordered destination-then-source and cannot be
|
|
|
1204
1204
|
globally atomic; if source removal fails after destination success, its Problem
|
|
1205
1205
|
Details state `destinationWritten: true` and identify the destination.
|
|
1206
1206
|
|
|
1207
|
-
### §send-dispatch SEND dispatch (
|
|
1208
|
-
|
|
1209
|
-
Directed SEND (non-null path) routes to scheme's `send`. Status = intent:
|
|
1207
|
+
### §send-dispatch SEND dispatch (a message to a recipient)
|
|
1210
1208
|
|
|
1211
|
-
|
|
1212
|
-
|
|
1209
|
+
A recipient SEND (non-null path, `status` null — {§send-label}) routes to the scheme's
|
|
1210
|
+
`send`: the body is the message — a WebSocket frame, exec stdin, an HTTP POST, an A2A
|
|
1211
|
+
message, a worker's next prompt. A label SEND never reaches a scheme: it concludes the
|
|
1212
|
+
turn ({§send}). Cancelling a stream and deleting an entry are KILL ({§stream}, {§move}).
|
|
1213
1213
|
|
|
1214
1214
|
- §log-uniform-query **Log speaks the universal query contract** — `## FIND0 (log://…)` works like every scheme's FIND. Candidates are worker rows scoped by the coordinate hierarchy ({§log-coordinate-hierarchy}) and projected exactly as READ shows them. Content dialects use `Matcher.matchCandidates`; `~semantic` and `&graph` use the same persistent derivation artifacts and candidate rankers as entries. Broad results are one-channel catalog groups whose `[0].path` is `log:///loop/turn/seq/OP`; exact matcher results are flat locations ({§find-result-projection}). A FIND signal classifies the FIND result row and never changes this candidate set ({§log-item-tags}). Log remains the core event ledger rather than duplicating rows into `entries`; its core-private storage adapter supplies one complete channel representation to the same READ projector. That adapter is not a plugin seam and grants no protocol scheme an alternate READ path.
|
|
1215
1215
|
- §find-source-agnostic **The content matcher is source-agnostic** — `Matcher.matchCandidates(body, candidates, mimetypes)` applies a content matcher (regex/jsonpath/xpath/glob) to candidates from ANY source, keyed by the caller's own identity (a pathname for entries, a `loop/turn/seq` coordinate for log). The matcher never cares what table the content came from, so FIND works uniformly across schemes by construction: `EntryFind` and `Log.find` run the one shared primitive rather than re-implementing it per scheme. Log stays its own event stream, but its rows are candidates the shared matcher covers like any entry's content.
|
|
@@ -1218,9 +1218,7 @@ Directed SEND (non-null path) routes to scheme's `send`. Status = intent:
|
|
|
1218
1218
|
|
|
1219
1219
|
- §matcher-selection-signal **Matching carries navigation evidence** - a matcher is a boolean resource predicate. Internally, each selected resource carries `matches: MatchEvidence[]`, where `MatchEvidence` is `{channel?,locator?,region?}`; `channel` names the entry channel the finding was located in and is absent for channel-less resources such as log rows, so line coordinates cannot be mis-attributed across channels of the same resource ({§channel-selection-visibility}). `locator` preserves a structural address without overloading the resource row's `path`; `region` is a complete four-coordinate `TextRegion` only when the finding maps honestly into the exact text the model can READ. Exact duplicate evidence deduplicates. Relation findings map their indexed source spans through the same readable text coordinate index. FIND alone decides whether that grouped selection projects as resource rows or flat locations ({§find-result-projection}); the engine never fabricates a region or guesses which surgical READ the model wants.
|
|
1220
1220
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
§send-dispatch-entry-schemes-501-on-non-410 Other status codes return 501 from entry-bearing schemes by default.
|
|
1221
|
+
§send-dispatch-entry-schemes-501 An entry-bearing scheme carries no messages: a recipient SEND aimed at one returns 501.
|
|
1224
1222
|
|
|
1225
1223
|
Null-path SEND is broadcast ({§send}), engine-handled.
|
|
1226
1224
|
|
|
@@ -1458,7 +1456,7 @@ A published default channel renders under the entry's ordinary fragmentless addr
|
|
|
1458
1456
|
|
|
1459
1457
|
### §no-visibility Entries carry no visibility
|
|
1460
1458
|
|
|
1461
|
-
Every entry is uniformly listed in the catalog (`## FIND0 (scheme:///**)`, {§packet}) and READable — entries have no per-worker open/folded state. Context curation is the model's, on the **log** (via
|
|
1459
|
+
Every entry is uniformly listed in the catalog (`## FIND0 (scheme:///**)`, {§packet}) and READable — entries have no per-worker open/folded state. Context curation is the model's, on the **log** (via KILL, {§log-kill-scope}), never on entries.
|
|
1462
1460
|
|
|
1463
1461
|
### §channel-mimetype Mimetype is a (scheme, channel) property — never a default
|
|
1464
1462
|
|
|
@@ -1480,8 +1478,8 @@ Rules:
|
|
|
1480
1478
|
| URI | Channel |
|
|
1481
1479
|
| ------------------------------------ | ------------------------------------ |
|
|
1482
1480
|
| `worker:///france/capital` | body (default) |
|
|
1483
|
-
| `sh:///1/1/2#stdout`
|
|
1484
|
-
| `sh:///1/1/2#stderr`
|
|
1481
|
+
| `sh:///1/1/2/EXEC#stdout` | stdout |
|
|
1482
|
+
| `sh:///1/1/2/EXEC#stderr` | stderr |
|
|
1485
1483
|
| `https://feed.example/y#body` | body |
|
|
1486
1484
|
| `log:///N/T/A` | (no channel concept; atomic log row) |
|
|
1487
1485
|
|
|
@@ -1490,7 +1488,7 @@ Op implications:
|
|
|
1490
1488
|
- EDIT to undeclared channel → 400; read-only channel → 405.
|
|
1491
1489
|
- COPY/MOVE source and destination fragments independently select channels.
|
|
1492
1490
|
|
|
1493
|
-
Client-interface target parameters carry fragments inline (`{ target: "sh:///1/1/2#stderr" }`).
|
|
1491
|
+
Client-interface target parameters carry fragments inline (`{ target: "sh:///1/1/2/EXEC#stderr" }`).
|
|
1494
1492
|
|
|
1495
1493
|
**Wire rendering: default channel is path-only.** A rendered target omits `#channel` when channel matches `defaultChannel`. Single-channel entries render path-only; multi-channel entries render the default path-only and only non-default carries `#name`.
|
|
1496
1494
|
|
|
@@ -1562,7 +1560,7 @@ AST: `{ op: "EDIT", target, body: string | null, signal: tags | null, lineMarker
|
|
|
1562
1560
|
- §edit-null-clears Writes the body; `body: null` clears it.
|
|
1563
1561
|
- §edit-status-201-200 Returns `{ status: 201, entryId }` for a new entry and
|
|
1564
1562
|
`{ status: 200, entryId }` for a content update.
|
|
1565
|
-
- §edit-noop-304 A write that changes nothing — identical content — returns `{ status: 304, entryId }`, mirroring
|
|
1563
|
+
- §edit-noop-304 A write that changes nothing — identical content — returns `{ status: 304, entryId }`, mirroring a scoped KILL's idempotence ({§log-kill-scope}). Its terse detail states the observed equality and the valid empty-body deletion shape; it never presumes that repetition or retrieval is the intended recovery. The operation's log classification remains independent ({§log-item-tags}).
|
|
1566
1564
|
- §edit-marker-required-on-existing **A markerless EDIT is CREATE-ONLY — there is no easy-clobber path on an existing entry.** A `<L>` marker scopes an EDIT to a range; without one, the body becomes the entry's WHOLE content — legitimate and required for a fresh entry (nothing exists to scope into), but on an EXISTING entry a missing marker is refused **400**, never a silent full replace. A deliberate full rewrite states that intent explicitly: `<1,-1>` resolves through the ordinary marker math to the same whole-content replacement, so the capability is available but cannot be selected by omission.
|
|
1567
1565
|
- §edit-line-anchors An anchored EDIT resolves under {§line-anchors} and carries
|
|
1568
1566
|
its endpoint checks as a core-private mutation precondition. Otherwise-valid
|
|
@@ -1600,52 +1598,76 @@ selection or fan-out path.
|
|
|
1600
1598
|
|
|
1601
1599
|
- §read-read-content Returns channel content and mimetype.
|
|
1602
1600
|
- §read-read-404 Returns 404 when the channel is absent.
|
|
1601
|
+
- §read-content-wins A channel that delivered content reads as that content (200); the
|
|
1602
|
+
producer's failure projects onto the READ only when there is nothing to read, so a
|
|
1603
|
+
failed command's stdout and stderr stay readable.
|
|
1603
1604
|
- §read-selection-projection READ applies `lineMarker` as text coordinates to one
|
|
1604
1605
|
exact target under {§read-exact-target}. Markerless READ synthesizes
|
|
1605
1606
|
`<1,16>`; `<1,-1>` explicitly selects all text. Successful positional reads
|
|
1606
1607
|
carry the compact requested/returned extent and available total
|
|
1607
1608
|
({§range-extent}). Anchors resolve under {§line-anchors} before selection. An
|
|
1608
1609
|
invalid text region is 416.
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1610
|
+
- §read-bytes A binary channel with no readable projection, and the `#bytes` view of
|
|
1611
|
+
any resource whose scheme supplies bytes, reads as the source bytes one hexadecimal
|
|
1612
|
+
octet per line: coordinate = line = byte, so `<a,b>` selects bytes, the markerless
|
|
1613
|
+
default is the same `<1,16>`, `<1,-1>` is the whole resource, and the extent carries
|
|
1614
|
+
`unit: "byte"`. The result keeps the source mimetype and names `projection: "hex"`;
|
|
1615
|
+
anchors do not exist there (400). Bytes are read from the source at READ time, sized
|
|
1616
|
+
then windowed, never stored: `file:` supplies them from the member on disk, and a
|
|
1617
|
+
scheme that keeps no bytes answers 501 `bytes-unavailable` for `#bytes` and 415 for a
|
|
1618
|
+
binary channel, as before. An EXEC whose target is a file member already runs the
|
|
1619
|
+
bytes on disk.
|
|
1620
|
+
- §find-bytes A FIND over a binary channel without a readable projection matches the
|
|
1621
|
+
source bytes one character each (Latin-1): a text pattern finds strings, `\xNN`
|
|
1622
|
+
escapes find byte sequences, and every hit is reported in byte coordinates that paste
|
|
1623
|
+
into a byte READ (`region` spans the hexadecimal lines of the matched bytes; `matched`
|
|
1624
|
+
is their hex). The load is bounded by the mimetypes binary input ceiling; a larger
|
|
1625
|
+
resource fails 413 `bytes-too-large` by name rather than being skipped.
|
|
1626
|
+
|
|
1627
|
+
§log-item-tags **Log items carry no model-authored classification.** The tag slot left the
|
|
1628
|
+
grammar with the signal slot ({§legacy-bracket-slot}); the `log_tags` primitive remains for
|
|
1629
|
+
engine policy's own diagnostic classifications, such as `overflow`, and is never a
|
|
1630
|
+
selector the model can address.
|
|
1625
1631
|
|
|
1626
1632
|
### §log-history-projection Durable history and active projection
|
|
1627
1633
|
|
|
1628
1634
|
| Layer | Owner | Curation contract |
|
|
1629
1635
|
|---|---|---|
|
|
1630
1636
|
| Durable event | `log_entries` | One chronological execution fact. Ordinary Plurnk operations never erase it; its original body and initial folded state remain available to the client journal, digest, and fork forensics. Containing turn, worker, or workspace teardown may cascade the history. |
|
|
1631
|
-
| Active projection | `log_entry_projections` | One current worker-facing state per event.
|
|
1637
|
+
| Active projection | `log_entry_projections` | One current worker-facing state per event. A scoped KILL changes folded body intervals while active. Log-KILL atomically changes active to inactive and cannot be reversed; inactive rows are absent from packet rendering, log READ/FIND, failure pointers, semantic discovery, token accounting, and later curation. |
|
|
1632
1638
|
|
|
1633
1639
|
The successful curation operation and every exact target transition are durable
|
|
1634
1640
|
in the same commit. KILL against another scheme retains that scheme's ordinary
|
|
1635
1641
|
resource or process semantics; this projection contract is specific to
|
|
1636
1642
|
`log:///`.
|
|
1637
1643
|
|
|
1638
|
-
### §
|
|
1644
|
+
### §log-kill-scope KILL on the log: whole items and scoped bodies
|
|
1639
1645
|
|
|
1640
|
-
AST: `{ op: "
|
|
1646
|
+
AST: `{ op: "KILL", target, body: MatcherBody | null, lineMarker: TextLineMarker | null }` ({§kill-scope} in the contracts SPEC owns the grammar).
|
|
1641
1647
|
|
|
1642
|
-
|
|
1648
|
+
KILL is the model's one context-curation verb on 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 folds only that body's intersecting body-relative physical lines away from the packet projection, and the row stays. An anchor may be one already published on that immutable body or one returned by READing its `log:///` coordinate ({§line-anchors}); a stale anchor is 412 and an unrelated one is 422. Scoped KILL is one-way: intervals accumulate under the one-way interval algebra and nothing reopens them — the durable body is untouched, and the model re-READs the source when it needs the text again. 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 matcher body ({§log-curation-set-selection}); a targetless KILL is 400.
|
|
1643
1649
|
|
|
1644
1650
|
### §jsonplurnk The Log's wire format
|
|
1645
1651
|
|
|
1646
|
-
The `## Log` section renders as a fixed three-backtick `jsonplurnk` fence - a JSON array of entry objects, otherwise-valid JSON with **exactly one** deviation: an open, nonempty `body` is a raw multiline string. Its opening JSON quote is followed by a physical newline, every visible content line retains its canonical numeric `N:` or anchored `@hash N:` coordinate, and its closing quote appears at column zero before either the object close or a following member. Source quotes, braces, fences, and headings cannot collide with either boundary because source text never occupies column zero after projection; source backticks therefore cannot form a CommonMark closing fence. The fixed opener keeps the packet prefix stable across content changes. The carve-out is localized to `body`, so the strip-parser recognizes `"body":"` followed by a newline, consumes one or more coordinate-prefixed lines, and replaces the raw multiline value with an escaped JSON string while preserving following members to recover strict JSON. The three body states are self-describing through field presence alone: a `body` field means open, `tokensBody` without `body` means folded (the value prices the
|
|
1647
|
-
|
|
1648
|
-
- §packet-
|
|
1652
|
+
The `## Log` section renders as a fixed three-backtick `jsonplurnk` fence - a JSON array of entry objects, otherwise-valid JSON with **exactly one** deviation: an open, nonempty `body` is a raw multiline string. Its opening JSON quote is followed by a physical newline, every visible content line retains its canonical numeric `N:` or anchored `@hash N:` coordinate, and its closing quote appears at column zero before either the object close or a following member. Source quotes, braces, fences, and headings cannot collide with either boundary because source text never occupies column zero after projection; source backticks therefore cannot form a CommonMark closing fence. The fixed opener keeps the packet prefix stable across content changes. The carve-out is localized to `body`, so the strip-parser recognizes `"body":"` followed by a newline, consumes one or more coordinate-prefixed lines, and replaces the raw multiline value with an escaped JSON string while preserving following members to recover strict JSON. The three body states are self-describing through field presence alone: a `body` field means open, `tokensBody` without `body` means folded (the value prices the visible body), and neither means no canonical body; no `display` label exists. Two defaults are likewise field absence: `origin` is omitted for the worker's own model authorship (exactly as `source` absence means the owning worker), and `status` is omitted for a routine 200 on an ordinary row. SEND always carries its submit code, KILL keeps an explicit 200 so destructive completion is decisive, and every non-200 stays explicit. A partially hidden open row also carries `"folded":["<scope>",...]`; coordinate gaps in its body make the omission explicit without renumbering later lines. `path` is the complete model-facing log identity: when a projected operation exists it ends in `/OP`, and no separate `op` field duplicates it. It leads each entry object; the remaining members follow in stable alphabetical order. A present authored operation annotation appears as `annotation`; its absence omits the field. Nonempty `tags` is the row's complete deduplicated, sorted folksonomy; an untagged row omits it. When an automatic bounded projection differs from the visibility-selected body, it appends `"chunk":"showing <selected> of <complete>"` after `body`; otherwise it omits `chunk`. Complete-line extents use inclusive two-coordinate line regions. A cut inside a line uses four-coordinate, start-inclusive and end-exclusive regions with 1-based Unicode code-point columns. The row's `path` remains the canonical READ target. The block is data only - no prose leads the fence. Every row's accounting: {§packet-token-accounting}.
|
|
1653
|
+
|
|
1654
|
+
- §packet-attachment-parts A READ of an attachable member carries its facts from the member's projection
|
|
1655
|
+
({§mimetype-projection-facts}): an image ({§mimetype-image}) as `image: { mimetype, width, height, bytes }`,
|
|
1656
|
+
a PDF ({§mimetype-pdf-facts}) as `document: { mimetype, pages, bytes }`. Its open row weighs the attachment
|
|
1657
|
+
(`tokensAttachment`, inside `tokensActive`) at `ceil(width × height / 750)` for a picture and
|
|
1658
|
+
`pages × 1500` for a document, and the packet lists it as an attachment of that kind. The kinds live in
|
|
1659
|
+
one table (`attachments.ts`): a kind exists only once a handler projects its facts and a scheme still holds
|
|
1660
|
+
its bytes. On a route whose provider declares the kind's modality ({§provider-input-modalities}) the wire
|
|
1661
|
+
form carries the user slot as parts, the text then one native part per accepted attachment read from the
|
|
1662
|
+
scheme's bytes at request time, a picture as an image part and a document as a file part; an attachment of
|
|
1663
|
+
a kind the route does not accept, and every attachment on a route that accepts none, reaches the model as
|
|
1664
|
+
its text projection alone. An attachment follows visibility exactly: a folded or killed row sends nothing.
|
|
1665
|
+
The weights are estimates; the provider's reported usage corrects the readout as it does for text.
|
|
1666
|
+
- §attachment-teaching The system slot teaches attachments only where they apply: an `Attachments` section,
|
|
1667
|
+
rendered between the definition and the policy, carries one `example`-fenced READ line per kind the
|
|
1668
|
+
route accepts and the daemon can attach, from the same table; a route that accepts no attachable kind has
|
|
1669
|
+
no section, so no model is told of a capability its route lacks (#497).
|
|
1670
|
+
- §packet-token-accounting Every row reports its real weight so the packet self-reconciles against the budget: `tokensBody` is the projected body's nonzero weight whenever a canonical body would render (never `0` — a priceless visible body is field absence), and `tokensActive` is the complete row's weight in the packet right now. The metadata share is derivable (`tokensActive − tokensBody` when open; `tokensActive` otherwise) and is never serialized — it feeds no curation decision. Thus a scoped KILL removes the rendered body's weight while a whole KILL removes `tokensActive`; on a folded row `tokensBody` previews the body share the fold reclaimed. The completed row, including its accounting field and framing, is measured to a fixed point. A FIND's nonzero `itemsTokenTotal` weighs the complete matched set; a nonzero `returnedItemsTokenTotal` appears only when the returned page has a different weight. These are curation weights, not dollars. The invariants bind regardless of shape ({§packet}): addressability (`path`/`target`/`#channel`/coordinate-prefixed bodies), weighability (per-item `tokens`), honesty (every 4xx/5xx row and the exact body state). {§jsonplurnk} {§packet-jsonplurnk-exception}
|
|
1649
1671
|
|
|
1650
1672
|
### §retrieval-packet-metadata READ/FIND packet metadata
|
|
1651
1673
|
|
|
@@ -1677,17 +1699,17 @@ ordinary bounded bodies expose their displayed and complete chunk extents there.
|
|
|
1677
1699
|
|
|
1678
1700
|
### §turn-ops-entry The admitted turn program
|
|
1679
1701
|
|
|
1680
|
-
§turn-ops-log-curation A source-backed turn preserves its **exact admitted Plurnk program** as an actionless log item in addition to the ordinary result row for every dispatched statement. `op` is null, `attrs.kind="turnOps"` identifies the durable type, `origin` is the turn producer, no target exists, `tx` is empty, and the source lives in `rx.content`, typed `text/vnd.plurnk`. Its canonical model-facing address appends the lowercase `/ops` leaf to its three-part coordinate. The packet does not duplicate that identity as `kind` metadata. It is line-numbered and READ/FIND/
|
|
1702
|
+
§turn-ops-log-curation A source-backed turn preserves its **exact admitted Plurnk program** as an actionless log item in addition to the ordinary result row for every dispatched statement. `op` is null, `attrs.kind="turnOps"` identifies the durable type, `origin` is the turn producer, no target exists, `tx` is empty, and the source lives in `rx.content`, typed `text/vnd.plurnk`. Its canonical model-facing address appends the lowercase `/ops` leaf to its three-part coordinate. The packet does not duplicate that identity as `kind` metadata. It is line-numbered and READ/FIND/KILL-able like any active log body. The worker-initialization `turnOps` is born visible because it is the worked orientation example; every other `turnOps`, including model inference and overflow recovery, is born FOLDED and remains available on demand. Log-KILL clears the `writableBy` gate for a model-authored item and retires only its active projection under {§log-history-projection}; the exact program remains forensic history. Log's handler surface keeps every other mutating op at 501. The shared executor writes exactly one after every admitted source-backed turn.
|
|
1681
1703
|
|
|
1682
|
-
§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
|
|
1704
|
+
§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 folded and projected visibly only in the informed recovery packet; every other rejected attempt remains forensic-only.
|
|
1683
1705
|
|
|
1684
|
-
- §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 `## READ0 (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: `/OP` for an operation, `/ops` for an admitted turn program, or `/attempt` for a rejected emission. 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. 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:///**/ops`, and `log:///**/attempt` deliberately filter canonical leaves.
|
|
1685
|
-
- §log-curation-folder-idiom **Log curation speaks the folder idiom; a zero-match sweep is a no-op success** —
|
|
1686
|
-
- §log-curation-set-selection **Row selection and body scope are independent** — target/glob
|
|
1706
|
+
- §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 `## READ0 (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: `/OP` for an operation, `/ops` for an admitted turn program, or `/attempt` for a rejected emission. 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. 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:///**/ops`, and `log:///**/attempt` deliberately filter canonical leaves. An EXEC's output stream lives at that same item address under its runtime tag — `sh:///1/2/3/EXEC#stdout` — so one `loop/turn/item/OP` schema addresses every item, log rows and streams alike.
|
|
1707
|
+
- §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: `## KILL0 (log:///1/2) <1,-1>` folds turn 1/2's bodies. A **well-formed selection that matches nothing is 204 with `matched: 0`**; a successful sweep's rx carries `matched: N`. A targetless KILL is 400.
|
|
1708
|
+
- §log-curation-set-selection **Row selection and body scope are independent** — target/glob and an optional body matcher 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 `## KILL0 (log:///**/READ) <17,-1>` may change long READs and no-op on short ones while reporting every selected row in `matched`.
|
|
1687
1709
|
|
|
1688
|
-
§
|
|
1710
|
+
§log-kill-meta-operation **A log KILL is a meta-operation — a log-curation directive, not a world action.** It changes log visibility, never the underlying resources. A **successful** log KILL **is recorded in the log** and **renders exactly once** — in the packet after its turn, as its path, target, and status — then dissolves from the projection ({§curation-receipt-dissolves}): the actor sees its `200` or `204` at the one moment it decides whether to conclude or repeat, and the row exists for forensics (a curation act with NO trace is how a weak model folding its own task frame stayed invisible until a database dig).
|
|
1689
1711
|
|
|
1690
|
-
§curation-receipt-dissolves **Successful log-curation receipts dissolve.** A model-authored
|
|
1712
|
+
§curation-receipt-dissolves **Successful log-curation receipts dissolve.** A model-authored KILL of a log item, whole or scoped, renders in exactly the packet immediately after its turn — path, target, and status, no body — and leaves the active projection once a later model turn has rows; history keeps the row, the exact active/folded transition for every target, and the authored `turnOps`. Nothing is left to curate: a receipt that dissolves is not a log item to sweep. A KILL of a log item retires the selected rows from the worker's active projection under {§log-history-projection}; it does not delete their execution history. The dissolving is **scoped to log targets**: a `KILL` of a `worker://` note, an `sh://` stream, or another stored artifact retains its scheme-owned world or process semantics and stays visible. A killed exact coordinate resolves 404 in ordinary log operations; a well-formed broad selection with no active matches remains the 204 no-op of {§log-curation-folder-idiom}, and that 204 renders once like any dissolving receipt. Failed KILLs render like every operation error and persist.
|
|
1691
1713
|
|
|
1692
1714
|
### §log-sensitive-request-evidence Durable request evidence
|
|
1693
1715
|
|
|
@@ -1773,7 +1795,7 @@ AST: `{ op: "FIND", target (scope), body: MatcherBody | null (predicate), signal
|
|
|
1773
1795
|
`(https, example.com, /page)`, never an empty-authority row at `/page`.
|
|
1774
1796
|
- §find-channel-selection The target selects a channel under {§channel-selection}. That channel controls candidate eligibility, every matcher dialect's content or derivation, match-evidence coordinates, and exact producer-result composition. A selected channel absent from an exact entry is 404; a broad scope simply excludes entries lacking it. Successful resource-mode results remain complete default-first channel groups, so sibling channels are navigable catalog metadata rather than additional matches.
|
|
1775
1797
|
- §find-glob-filter-on-content `body` matcher operates on the addressed entry channel (glob/regex/jsonpath/xpath), per `plurnk.md` "Pattern Filtering"; the path-glob lives in the (target), not the body.
|
|
1776
|
-
- §find-semantic-selection Every matcher operates only over the candidate set selected by `(target)`; relation matchers do not bypass that selection. Semantic ranking is exhaustive within that candidate set, then applies the ordinary FIND result scope. Markerless semantic FIND therefore uses the same `<1,16>` default as every other matcher. Integers retain FIND's positional contract: `<N>` selects result N and `<N,M>` selects the inclusive range. A leading decimal first applies a minimum cosine-similarity threshold; following integers select positions within that ranked threshold set. Thus `<0.7,10,20>` means threshold 0.7 followed by results 10 through 20, while `<0.7>` applies the threshold and the ordinary first-16 page.
|
|
1798
|
+
- §find-semantic-selection Every matcher operates only over the candidate set selected by `(target)`; relation matchers do not bypass that selection. Semantic ranking is exhaustive within that candidate set, then applies the ordinary FIND result scope. Markerless semantic FIND therefore uses the same `<1,16>` default as every other matcher. Integers retain FIND's positional contract: `<N>` selects result N and `<N,M>` selects the inclusive range. A leading decimal first applies a minimum cosine-similarity threshold; following integers select positions within that ranked threshold set. Thus `<0.7,10,20>` means threshold 0.7 followed by results 10 through 20, while `<0.7>` applies the threshold and the ordinary first-16 page. Each semantic match carries its best-chunk cosine as `score`, and each ranked resource row surfaces it as `similarity` (three decimals), so a ranked page states why it is ordered; the lexical fallback ranks by BM25 and carries neither.
|
|
1777
1799
|
- §find-scoped-isolation Workspace + scheme scoped — no cross-workspace/cross-scheme leakage.
|
|
1778
1800
|
- §find-result-projection **The authored target shape determines the result unit; result cardinality never changes it** ({§find-result-unit}). Returns `FindResult { status, content, mimetype, results, range, matchingPathCount, matchLocationCount, itemsWeightTotal, returnedItemsWeightTotal }`:
|
|
1779
1801
|
|
|
@@ -1847,9 +1869,9 @@ AST: `{ op: "SEND", target: ParsedPath | null, body: SendBody | null, signal: nu
|
|
|
1847
1869
|
|---|---|---|---|
|
|
1848
1870
|
| **102** continue | next turn | next turn | next turn |
|
|
1849
1871
|
| **200** done | **resolved** — terminal, loop ends | **refused** — Premature-Terminate (KILL to abandon, or wait) | **refused** — forced next turn to see the result |
|
|
1850
|
-
| **202** wait | **resolves like 200**, unless this turn successfully
|
|
1872
|
+
| **202** wait | **resolves like 200**, unless this turn successfully scoped a KILL — an empty wait is satisfied, while curation continues into the curated next packet | **block on the join** — the loop sleeps (`<T>`/`<-1>` bound it, `<P>` polls); its work's conclusion **reawakens the same loop**, prompt intact ({§worker-lifecycle-child-wake}, {§worker-lifecycle-wake-liveness}) | resolves next turn (≈ continue) |
|
|
1851
1873
|
|
|
1852
|
-
§wait-obligation-matrix **499** gives up regardless of obligations and cancels the unresolved descendant scope — the model's one self-decided failure ({§state-terms}). The surface is small on purpose. The **one** non-obvious cell is **200 with an obligation in flight** — a contradiction (you claimed done while you owe work), which the engine holds you to via Premature-Terminate below. A child join is bounded by the child's terminal transition; an external stream may carry an explicit `<T,P>` policy. A successful same-turn
|
|
1874
|
+
§wait-obligation-matrix **499** gives up regardless of obligations and cancels the unresolved descendant scope — the model's one self-decided failure ({§state-terms}). The surface is small on purpose. The **one** non-obvious cell is **200 with an obligation in flight** — a contradiction (you claimed done while you owe work), which the engine holds you to via Premature-Terminate below. A child join is bounded by the child's terminal transition; an external stream may carry an explicit `<T,P>` policy. A successful same-turn scoped KILL is synchronous housekeeping, so it does not block an explicit `200`; with `202`, it instead continues as `102` because its context effect is useful only in the curated next packet.
|
|
1853
1875
|
|
|
1854
1876
|
§loop-terminal-authorship **Terminal authorship is explicit when external.**
|
|
1855
1877
|
|
|
@@ -1878,19 +1900,18 @@ failure) do strike: six in a row is a degenerated run.
|
|
|
1878
1900
|
|
|
1879
1901
|
- §send-target-recipient **A SEND target is a recipient.** A model's directed SEND
|
|
1880
1902
|
addresses a worker (`## SEND0 (worker://<name>)`), an outbound agent (`a2a://`),
|
|
1881
|
-
or a scheme that implements SEND (an `https://` POST)
|
|
1882
|
-
resource to delete. A SEND to a scheme the model may not write (the prompt, the
|
|
1903
|
+
or a scheme that implements SEND (an `https://` POST). A SEND to a scheme the model may not write (the prompt, the
|
|
1883
1904
|
log) is refused 400 `send-target-not-a-recipient`, never the unrelated writer
|
|
1884
1905
|
rule. The detail states only that the addressed scheme is not a recipient;
|
|
1885
1906
|
neutral recovery distinguishes targetless replies from directed SEND without
|
|
1886
1907
|
guessing which one was intended. A scheme that does not implement SEND
|
|
1887
1908
|
answers its ordinary factual 501 without grafting a guessed recovery onto it.
|
|
1888
|
-
- §send-idle-turn **Idle turn** — a continuing turn (102) whose ops are only PLAN/SEND — no work op. The model continued with nothing to do. The steer, verbatim: *"If your work is done, conclude with `## SEND0
|
|
1909
|
+
- §send-idle-turn **Idle turn** — a continuing turn (102) whose ops are only PLAN/SEND — no work op. The model continued with nothing to do. The steer, verbatim: *"If your work is done, conclude with `## SEND0 (TERM)`. If you're waiting on a child or stream you spawned, use `## SEND0 (WAIT)` to block on it — a 202 with nothing to wait on simply concludes."* A successful same-turn scoped KILL is the exception: its `202` continues without a strike so the curated packet can support the next reasoning turn. **An empty `(NEXT)` while the worker holds a live stream or child is a mis-spelled wait, not idleness**: the engine parks the turn as `(WAIT)` — the same live-work predicate the `(TERM)` gate uses, so the shift never disagrees with the orientation the model reads — records the SEND as `202` with the correction in that row's annotation (a park drops transient notices; the row survives the wake); no strike. With nothing in flight the idle-turn 409 stands — it is the deterministic recovery for that case.
|
|
1889
1910
|
- §send-premature-terminate **Premature terminate — the pending set.**
|
|
1890
1911
|
A model's completion claim is gated by one rule: *nothing pending may be silently
|
|
1891
1912
|
discarded*. Pending work has two states: **live obligations** (open
|
|
1892
1913
|
streams/spawns and live child workers) and **completed-but-unobserved
|
|
1893
|
-
results** (same-turn READ/FIND
|
|
1914
|
+
results** (same-turn READ/FIND results, failed operations, failed
|
|
1894
1915
|
terminal stream output (close status ≥ 400) without a terminal foisted
|
|
1895
1916
|
READ, and child results queued for the next packet). A stream that closed
|
|
1896
1917
|
successfully is banked, not pending: its output stays in the Log and `[200]`
|
|
@@ -1902,7 +1923,7 @@ failure) do strike: six in a row is a degenerated run.
|
|
|
1902
1923
|
`streams`, `workers`, `receipts`, `failed-stream-results`, and
|
|
1903
1924
|
`worker-results`; it never embeds commands, stream handles, result bodies, or
|
|
1904
1925
|
a presumed recovery. The pending kind changes the factual Problem class, not
|
|
1905
|
-
rail accounting. `
|
|
1926
|
+
rail accounting. `(FAIL)` deliberately abandons regardless.
|
|
1906
1927
|
- §send-administrative-terminal **An administrative terminal closes its own
|
|
1907
1928
|
transaction.** A client, plugin, or `_plurnk` operation program runs in its
|
|
1908
1929
|
own administrative loop. Its SEND signal `200` concludes exactly that loop;
|
|
@@ -1912,7 +1933,7 @@ failure) do strike: six in a row is a degenerated run.
|
|
|
1912
1933
|
observed only after crossing a packet boundary. SEND signal `202` parks only on
|
|
1913
1934
|
live obligations. If work has completed but is unobserved, it continues
|
|
1914
1935
|
directly to the next packet because the wake edge has already fired; only a
|
|
1915
|
-
genuinely empty set with no successful same-turn
|
|
1936
|
+
genuinely empty set with no successful same-turn scoped KILL resolves immediately like `(TERM)`.
|
|
1916
1937
|
|
|
1917
1938
|
### §exec EXEC
|
|
1918
1939
|
|
|
@@ -1923,17 +1944,17 @@ resolves the runtime first, selects its static {§executor-invocation} or exact
|
|
|
1923
1944
|
{§executor-tool-registry} entry, and enforces that declaration before effect
|
|
1924
1945
|
admission. Core owns target
|
|
1925
1946
|
realization; neither filesystem type nor body presence may invent a target role
|
|
1926
|
-
the selected runtime did not declare.
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
script;
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
tool
|
|
1936
|
-
|
|
1947
|
+
the selected runtime did not declare. `cwd` is the workspace's `project_root`, where the File scheme writes — never the
|
|
1948
|
+
daemon's own cwd — unless the heading carries a `{cwd=<directory>}` block
|
|
1949
|
+
({§exec-executor-slot}): core resolves that directory against the project root, or the
|
|
1950
|
+
shell's own cwd when the workspace has none, and refuses `400 cwd-not-found` when it is
|
|
1951
|
+
not an existing directory; any other metadata block on a local program is refused
|
|
1952
|
+
`400 metadata-unsupported`. A `script`-kind target ({§executor-invocation}) is the program: core inspects it before
|
|
1953
|
+
anything spawns — a file is the script; a directory is refused `400 target-not-a-program`,
|
|
1954
|
+
pointing at `{cwd=…}`; an absent path is refused `400 target-not-found`, giving the
|
|
1955
|
+
applicable accepted form without inferring what the model meant. When the target is a
|
|
1956
|
+
registered tool of another executor, recovery gives that tool's exact bracketed
|
|
1957
|
+
invocation; otherwise it points at an existing script or a bare shell-command body. A non-file resource
|
|
1937
1958
|
target that cannot be read keeps the owning READ's failure identity (#163) and states
|
|
1938
1959
|
the slot contract in its recovery — the resource is the program and the body its stdin;
|
|
1939
1960
|
a command belongs beneath a targetless heading — without guessing which was meant (#425). The started receipt always
|
|
@@ -1941,11 +1962,9 @@ names the working directory only when it is not the project root, and then in th
|
|
|
1941
1962
|
model's own project-relative form ({§fs-namespace}: the root is the model's `/`, so it
|
|
1942
1963
|
is never rendered, and no receipt or Problem carries a host-absolute path — the
|
|
1943
1964
|
batch of 2026-08-29 showed the absolute `cwd` copied back into the target slot as
|
|
1944
|
-
`(cwd: /host/path)`). The EXEC `(path)` is
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
is taught as targetless bare `EXEC`; `[sh]` remains the explicit form, and an
|
|
1948
|
-
authored directory target remains an optional cwd override.
|
|
1965
|
+
`(cwd: /host/path)`). The EXEC `(path)` is a program — a script for an interpreter, a tool name for a tool
|
|
1966
|
+
family — and neither a command nor a working directory is ever a target. The default
|
|
1967
|
+
shell is taught as targetless bare `EXEC`; `[sh]` remains the explicit form.
|
|
1949
1968
|
|
|
1950
1969
|
| Declared target kind | Authored target | Canonical effect target | Executor realization |
|
|
1951
1970
|
| -------------------- | --------------------------------------- | ----------------------- | --------------------------------------------------------- |
|
|
@@ -2028,21 +2047,27 @@ dispatch admission, and pull-document materialization. Core performs no
|
|
|
2028
2047
|
protocol discovery while building a packet and has no alternate tool
|
|
2029
2048
|
catalogue.
|
|
2030
2049
|
|
|
2031
|
-
Per-tool programs such as `go`, `cargo`, `make`, and `npm` do not earn executor tags merely because they are executables; they are complete shell commands under `## EXEC0` or `## EXEC0
|
|
2050
|
+
Per-tool programs such as `go`, `cargo`, `make`, and `npm` do not earn executor tags merely because they are executables; they are complete shell commands under `## EXEC0` or `## EXEC0 (sh)`. Registered tags exist only for tools that own a distinct body, target, or output contract. {§exec-registry-resolves}
|
|
2032
2051
|
|
|
2033
2052
|
**Timeout and poll — `<T,P>` on the `<L>` slot (grammar 0.74.20).** EXEC
|
|
2034
2053
|
repurposes the line-marker slot as `<timeout, poll>` in **minutes** — agentic
|
|
2035
2054
|
latencies make a sub-minute horizon a trap — converted at the parse boundary to the
|
|
2036
|
-
catalog's internal `stream.seconds`. The
|
|
2055
|
+
catalog's internal `stream.seconds`. The `## SEND0 (WAIT) <T>` wait horizon is minutes too.
|
|
2037
2056
|
|
|
2038
2057
|
§exec-timeout `T` (`mark[0]`) caps the spawn's lifetime. At `T>0` the service
|
|
2039
2058
|
aborts it — a bounded reap, polite signal then SIGKILL after
|
|
2040
2059
|
`PLURNK_SERVICE_EXEC_KILL_GRACE_MS` — and stamps the stream **504**, distinct
|
|
2041
|
-
from a deliberate kill (499) or a clean exit (200).
|
|
2042
|
-
|
|
2060
|
+
from a deliberate kill (499) or a clean exit (200). Absent is unbounded but
|
|
2061
|
+
loop-life bounded — reaped on every loop terminal except 202 — the
|
|
2062
|
+
background-stream behavior. **`-1` is unbounded and detached**: the spawn
|
|
2063
|
+
outlives its loop's terminal, 200 included. It never binds to the loop's
|
|
2064
|
+
teardown and is nobody's obligation — a TERM is not gated by it, a WAIT does
|
|
2065
|
+
not park on it, optimistic settlement looks past it — and it ends only by KILL,
|
|
2066
|
+
the worker's total reap, or daemon shutdown; its late conclusion surfaces
|
|
2067
|
+
without opening a loop. **`0` is turn-scoped**:
|
|
2043
2068
|
the stream is reaped at the worker's next pre-turn via the registry abort,
|
|
2044
2069
|
before the turn's own spawns, so it never survives into the subsequent turn;
|
|
2045
|
-
its terminal output surfaces born
|
|
2070
|
+
its terminal output surfaces born visible like any close ({§exec-stream}).
|
|
2046
2071
|
|
|
2047
2072
|
§exec-poll `P` (`mark[1]`) is the **poll cadence**, stored on the subscription.
|
|
2048
2073
|
While the loop is blocked on a SEND signal `202` wait for that stream, the daemon arms
|
|
@@ -2102,7 +2127,7 @@ two states and no others:
|
|
|
2102
2127
|
| state | what the model receives |
|
|
2103
2128
|
|---|---|
|
|
2104
2129
|
| active | nothing in the Log. The `## Child Streams` pointer names the stream with each channel's size and its growth since the last packet ({§child-orientation}); the model READs any range it wants. |
|
|
2105
|
-
| terminal | ONE `origin=_plurnk` READ at `<runtime>:///<coord>#<channel>`, born
|
|
2130
|
+
| terminal | ONE `origin=_plurnk` READ at `<runtime>:///<coord>#<channel>`, born visible, that is exactly a markerless READ of the channel — its first page ({§read-selection-projection}: lines 1–16, the whole channel when it fits, the channel's own mimetype), the `range` extent, terminal status and Problem, `terminal: true`, any producer-supplied integer `exitCode`, and `source: log:///<coord>/EXEC` linking the causal invocation. The packet renders that address under `stream`, exactly as the invocation row links its output, never under `target`: a stream is observed, not a slot to author. |
|
|
2106
2131
|
|
|
2107
2132
|
§exec-concurrency **Bounded admission per workspace (#389).** At most
|
|
2108
2133
|
`PLURNK_SERVICE_EXEC_CONCURRENCY` executions run at once in one workspace (shipped `12`;
|
|
@@ -2133,7 +2158,7 @@ observation at close — so the pointer can state growth and no partial document
|
|
|
2133
2158
|
or record ever reaches the model. The terminal observation and its cursor
|
|
2134
2159
|
transition commit atomically; a terminal state with an empty channel still
|
|
2135
2160
|
produces one bodyless conclusion row whose terminal fact, causal EXEC link, and
|
|
2136
|
-
available exit code make completion explicit without invented narration.
|
|
2161
|
+
available exit code make completion explicit without invented narration. KILL may curate
|
|
2137
2162
|
that log row without rewinding the cursor or publishing the terminal result
|
|
2138
2163
|
again; the exact terminal result and channel content remain READable at the
|
|
2139
2164
|
stream address. Every READ then obeys {§body-projection} and therefore renders
|
|
@@ -2141,7 +2166,7 @@ its selected result complete. A stream that closes before a same-turn wait
|
|
|
2141
2166
|
remains pending until every selected channel's terminal READ crosses the next
|
|
2142
2167
|
packet boundary. The EXEC row separately records the authored invocation.
|
|
2143
2168
|
|
|
2144
|
-
`## KILL0 (<runtime>:///<loop>/<turn>/<seq
|
|
2169
|
+
`## KILL0 (<runtime>:///<loop>/<turn>/<seq>/EXEC)` cancels an active subprocess via
|
|
2145
2170
|
the subscription registry's stored controller. A terminal stream is immutable:
|
|
2146
2171
|
499 returns 410 (already killed), every other terminal status returns an RFC
|
|
2147
2172
|
9457 409 Problem carrying `terminalStatus`, and an unknown address returns 404.
|
|
@@ -2236,7 +2261,7 @@ settles it as interruption (`500`) and errors active channels before evaluating
|
|
|
2236
2261
|
loops ({§worker-lifecycle-restart-recovery}); it never reports cancellation (`499`) or
|
|
2237
2262
|
pretends to reconstruct an opaque plugin connection.
|
|
2238
2263
|
|
|
2239
|
-
§subscriptions-fold-keeps-subscription
|
|
2264
|
+
§subscriptions-fold-keeps-subscription A scoped KILL changes a log row's folded body intervals ({§log-kill-scope}), never the subscription registry. Curation of a streaming entry's log body leaves the live stream running: visibility is render-only, never cancellation.
|
|
2240
2265
|
|
|
2241
2266
|
### §chunk-accumulation Chunk accumulation
|
|
2242
2267
|
|
|
@@ -2254,9 +2279,9 @@ Model sees lifecycle events in the `log` section per turn.
|
|
|
2254
2279
|
|
|
2255
2280
|
### §stream-control Stream control and writes
|
|
2256
2281
|
|
|
2257
|
-
- **Cancel:** `##
|
|
2258
|
-
- **Kill:** `## KILL0 (sh:///1/2/3)` — the model terminates its own runtime stream. This is stream control, not a write: the output scheme's `writableBy` never gates it, `Exec.kill` scopes the address to the caller ({§stream-owner-scoped}), and a finished stream answers 410 under its own tag. A queued execution ({§exec-concurrency}) is cancelled the same way and never enters its executor.
|
|
2259
|
-
- **WebSocket write:** `## EDIT0 (wss://feed/x)` or `## SEND0
|
|
2282
|
+
- **Cancel:** `## KILL0 (https://feed.example/x)` — the service invokes the handle registered by `subscriptions.open()` and aborts the composed subscription signal.
|
|
2283
|
+
- **Kill:** `## KILL0 (sh:///1/2/3/EXEC)` — the model terminates its own runtime stream. This is stream control, not a write: the output scheme's `writableBy` never gates it, `Exec.kill` scopes the address to the caller ({§stream-owner-scoped}), and a finished stream answers 410 under its own tag. A queued execution ({§exec-concurrency}) is cancelled the same way and never enters its executor.
|
|
2284
|
+
- **WebSocket write:** `## EDIT0 (wss://feed/x)` or `## SEND0 (wss://feed/x)` with a body sends one whole text frame through the active owner. SEND can follow the opening READ in the same turn; EDIT runs before READ ({§op-mode-phases}) and therefore addresses an owner already open at turn start.
|
|
2260
2285
|
- **Other stream write:** `## SEND0 [200] (…)` remains scheme-defined, including exec stdin.
|
|
2261
2286
|
|
|
2262
2287
|
### §stream-constraints Engine constraints
|
|
@@ -2420,8 +2445,8 @@ service manifest edit.
|
|
|
2420
2445
|
|
|
2421
2446
|
- Channel state (`static`/`active`/`closed`/`errored`) — persisted channel metadata owned by core and exposed through the schemes capability contract ({§channel-state}).
|
|
2422
2447
|
- Backpressure caps — none ({§stream-constraints}).
|
|
2423
|
-
- Stream cancel —
|
|
2424
|
-
- Delete — `KILL` (entry-KILL, the canonical delete, {§move});
|
|
2448
|
+
- Stream cancel — `KILL` of the stream address ({§stream-control}).
|
|
2449
|
+
- Delete — `KILL` (entry-KILL, the canonical delete, {§move}); a scoped entry KILL deletes one span through the EDIT path ({§kill-scope-entry}).
|
|
2425
2450
|
- §loop-policy-effective-read Per-loop policy — `loops.policy` persists one complete immutable `LoopPolicy`; every runtime policy read validates that snapshot before use. Missing rows or invalid values fail with the owning loop coordinate and cause. Raw archival copies and forensic rendering do not interpret policy.
|
|
2426
2451
|
- Default-channel wire rendering — {§channel-selection}.
|
|
2427
2452
|
|
|
@@ -2960,8 +2985,8 @@ mutation of its source; resource-backed EXEC demands its runtime plus source
|
|
|
2960
2985
|
observation. Unknown schemes, runtimes,
|
|
2961
2986
|
and tools continue to their ordinary resolver so capability policy cannot turn
|
|
2962
2987
|
absence into a misleading restriction. The same resolver shapes generated
|
|
2963
|
-
resource examples, worker tool documents, and Turn0 surveys. PLAN,
|
|
2964
|
-
|
|
2988
|
+
resource examples, worker tool documents, and Turn0 surveys. PLAN, log KILL,
|
|
2989
|
+
and label or targetless SEND are log/program control rather than routed
|
|
2965
2990
|
external demands and therefore remain outside capability selectors.
|
|
2966
2991
|
|
|
2967
2992
|
§worker-settings **The worker carries its own behavioral rules.** The
|
|
@@ -3243,7 +3268,7 @@ time of measurement.
|
|
|
3243
3268
|
|
|
3244
3269
|
| Fact | Owner and unit | Time | Contract |
|
|
3245
3270
|
|:-----|:---------------|:-----|:---------|
|
|
3246
|
-
| Core curation weight | `contentWeight = ceil(chars/2)` over channel content, canonical log bodies, and rendered packet slots | Write/build | Stable, model-independent pressure and
|
|
3271
|
+
| Core curation weight | `contentWeight = ceil(chars/2)` over channel content, canonical log bodies, and rendered packet slots | Write/build | Stable, model-independent pressure and curation savings; never a tokenizer claim. |
|
|
3247
3272
|
| §tokenomics-context-envelope-admission Provider input capacity | Provider model limits and configured total output envelope, 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. |
|
|
3248
3273
|
| Provider generation envelope | Provider total output budget and optional reasoning subset, in provider tokens | Before every logical request | One total output budget includes hidden reasoning. A reasoning budget is a strict subset, never an additive reserve. |
|
|
3249
3274
|
| 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. |
|
|
@@ -3251,6 +3276,7 @@ time of measurement.
|
|
|
3251
3276
|
- §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.
|
|
3252
3277
|
- §tokenomics-render-weight-budget **Packet curation budget.** `tokensActiveTotal` measures the *complete assembled packet* after section transforms and readout substitution; it is not a sum of log-row `tokensActive` 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. `tokensActiveMax` is the provider-derived curation calibration. A `SUM` of stored content weights measures a different artifact and cannot substitute for packet render weight.
|
|
3253
3278
|
- §tokenomics-context-percent **Curation percent.** `tokensActiveTotal` carries packet weight as a percentage of `tokensActiveMax`. It reads the capacity already resolved by the provider; no extra provider call.
|
|
3279
|
+
- §tokenomics-calibrated-readout **The readout is calibrated to the answering model.** The model-independent ruler overstates what a tokenizer charges by a model-specific ratio (1.3–1.6× on Qwen3.8 packets, measured 2026-09-02, which fired the pressure mandate at half the real ceiling). Before rendering the readout, Core takes this model's last five settled emission responses that pair a measured packet weight with a provider-reported prompt count and scales `tokensActiveTotal`, its percent, the pressure-inventory figures, and the overflow admission by reported ÷ measured. Fewer than three samples leave the factor at 1. Samples are keyed by the model name the provider reports, so a model change starts from 1 again; stored weights and the client gauge stay in the model-independent ruler ({§tokenomics-agnostic-ruler}).
|
|
3254
3280
|
- §tokenomics-window-partition **One capacity derivation; no service-side token budget.** The provider owns model limits and the configured total output envelope. Its resolved `inputCapacity` is the numeric curation-budget calibration as well as the physical denominator exposed to clients. That reuse is policy, not a unit conversion: Core compares stable curation weight with it only to shape context, while provider request-shaped evidence alone admits or rejects 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.
|
|
3255
3281
|
- §tokenomics-prompt-projection-share **Prompt projection is stable packet policy.**
|
|
3256
3282
|
`PLURNK_SERVICE_PROMPT_PROJECTION` is a required alias-scoped percentage in
|
|
@@ -3266,10 +3292,10 @@ time of measurement.
|
|
|
3266
3292
|
- **Derivation is exhaustive and demand-led.** Explicit searchable-resource changes may start one coalesced warm. Passive creation and attachment do not. The first model turn starts or joins that warm; later turns derive intervening changes before dispatch. No model operation observes partial graph or vector coverage. A semantic query ranks every eligible candidate in scope, so lexical overlap never gates vector recall. With no embedder, readable-content FTS is the explicit keyword fallback. Progress notices make the wait visible; latency is never hidden by partial semantics. {§derivation-exhaustive}
|
|
3267
3293
|
- §membership-binary-sniff **Binary truth beats the label; no entry dominates the corpus.** A tracked member whose HEAD bytes contain NUL enters {§membership-source-projection} as `application/octet-stream` **regardless of what extension-based detection claims**; byte-level evidence outranks a default label. Every eligible text is tiled losslessly to the embedder window and every tile is embedded before its derivation attaches; semantic ranking max-pools the best chunk per candidate.
|
|
3268
3294
|
- §tokenomics-agnostic-ruler **One model-agnostic curation ruler.** The daemon runs workers on different models in one workspace concurrently, while catalog and log accounting are workspace-wide. `contentWeight = ceil(chars/2)` therefore gives one content one stable number without per-model workspace state or recount passes. It controls curation only; every provider call independently measures the complete request as well as it can.
|
|
3269
|
-
- §tokenomics-neutral-telemetry **Curation telemetry is state, not response allowance.** The model-facing `Context Token Budget` section begins with exactly two fields on separate lines: `tokensActiveTotal: N (P%)` and `tokensActiveMax: M`. It never presents their difference as free response tokens. The protocol definition directly requires
|
|
3270
|
-
- §tokenomics-pressure-inventory **Pressure identifies its reclaimable concentration.** When the ordinary two-field packet measurement reaches 80% of `tokensActiveMax`, the budget section may append `YOU MUST
|
|
3295
|
+
- §tokenomics-neutral-telemetry **Curation telemetry is state, not response allowance.** The model-facing `Context Token Budget` section begins with exactly two fields on separate lines: `tokensActiveTotal: N (P%)` and `tokensActiveMax: M`. It never presents their difference as free response tokens. The protocol definition directly requires KILL of irrelevant log items and ranges to keep the next packet within the maximum. Per-entry weights remain on log rows where they describe visible cost and curation savings. Generic packet composition and physical-token speculation are absent.
|
|
3296
|
+
- §tokenomics-pressure-inventory **Pressure identifies its reclaimable concentration.** When the ordinary two-field packet measurement reaches 80% of `tokensActiveMax`, the budget section may append `YOU MUST KILL superseded, stale, or irrelevant log items and ranges.` followed by `Largest Log Items`: at most five currently visible, addressed log bodies, ordered by `tokensActive` descending and then `log:///` path. Each item repeats only that row's `tokensBody` and `tokensActive`. Folded and bodyless rows cannot enter the list because a scoped KILL would reclaim no body from them. The largest prefix that fits may be shown; this conditional block never pushes an otherwise admissible packet over its maximum. Its own weight participates in the final fixed-point `tokensActiveTotal`.
|
|
3271
3297
|
- §tokenomics-content-hash-identity **Content identity, not per-tokenizer counts.** Static channel writes stamp `content_hash` (SHA-256) as stable content identity. `weight` is stored beside that content and is never keyed or recomputed by model.
|
|
3272
|
-
- §tokenomics-provider-usage **Provider accounting is physical-request evidence, not curation state.** Every issued physical request has one durable pre-I/O `provider_requests` identity beneath the normalized {§inference-ledger} and settles once as response or error. Each record preserves conventional {§provider-usage} quantities and required {§provider-cost} evidence; an unreported quantity remains absent, including on response-less failures, and is never replaced by zero. `model_calls` and `embedding_calls` own domain response/failure evidence, `turn_attempts` specialize emission admission, and `provider_requests` are the sole durable accounting representation. Emissions, BARE calls, embeddings, rejected responses, retries, failovers, and errors therefore remain cardinal and ordered. Turn, loop, worker, workspace, digest, and protocol accounting are derived from those records through the shared {§provider-accounting} projection; only emission calls contribute the latest-packet context gauge. The baseline stores no floating-point money, denormalized totals, or rollup triggers. A documented direct charge becomes `charged`; otherwise the provider may compute an exact-decimal USD `estimated` amount from complete usage and the exact model's Models.dev rates; insufficient evidence becomes `unknown`. Derived `costUsd` sums every USD-expressible request and is `null` only when no request is expressible; a response-less failure or an uncataloged model is skipped, never allowed to erase the expressible evidence. Each derived aggregate usage field independently sums its reported quantity, so heterogeneous detail coverage remains partial rather than becoming fictitiously complete. This is operational request accounting, not invoice reconciliation. Output and reasoning are quantities the model cannot
|
|
3298
|
+
- §tokenomics-provider-usage **Provider accounting is physical-request evidence, not curation state.** Every issued physical request has one durable pre-I/O `provider_requests` identity beneath the normalized {§inference-ledger} and settles once as response or error. Each record preserves conventional {§provider-usage} quantities and required {§provider-cost} evidence; an unreported quantity remains absent, including on response-less failures, and is never replaced by zero. `model_calls` and `embedding_calls` own domain response/failure evidence, `turn_attempts` specialize emission admission, and `provider_requests` are the sole durable accounting representation. Emissions, BARE calls, embeddings, rejected responses, retries, failovers, and errors therefore remain cardinal and ordered. Turn, loop, worker, workspace, digest, and protocol accounting are derived from those records through the shared {§provider-accounting} projection; only emission calls contribute the latest-packet context gauge. The baseline stores no floating-point money, denormalized totals, or rollup triggers. A documented direct charge becomes `charged`; otherwise the provider may compute an exact-decimal USD `estimated` amount from complete usage and the exact model's Models.dev rates; insufficient evidence becomes `unknown`. Derived `costUsd` sums every USD-expressible request and is `null` only when no request is expressible; a response-less failure or an uncataloged model is skipped, never allowed to erase the expressible evidence. Each derived aggregate usage field independently sums its reported quantity, so heterogeneous detail coverage remains partial rather than becoming fictitiously complete. This is operational request accounting, not invoice reconciliation. Output and reasoning are quantities the model cannot KILL, so they never alter the model-facing Budget ledger.
|
|
3273
3299
|
- §tokenomics-negative-pressure **Negative curation pressure is honest but never submitted.** The provisional readout may report `tokensActiveTotal` and its percentage above `tokensActiveMax`. Crossing the maximum diverts that would-be model turn into {§overflow-turn}; no over-ceiling packet reaches `provider.generate`. Automatic recovery does not create a strike or consume a model-turn allowance.
|
|
3274
3300
|
|
|
3275
3301
|
### §membership Workspace identity, membership, disk co-location
|
|
@@ -3361,7 +3387,7 @@ and never re-fetch a match.
|
|
|
3361
3387
|
- §membership-git-hermetic Native Git runs with ambient `GIT_*` and
|
|
3362
3388
|
global/system config scrubbed, so repository identity follows `project_root`,
|
|
3363
3389
|
never the daemon's launch environment.
|
|
3364
|
-
- §membership-edit-membership-gate **Membership-gated edits.** EDIT is bounded by membership exactly as READ is. An existing **member**'s baseline is its entry snapshot — the body channel the model READ, not a fresh disk read — so the diff is naive against the view the model saw, never empty (the write-side CAS, {§membership-edit-write-cas}, prevents the silent overwrite of out-of-band drift). An existing **non-member** is refused (403) *before* any read or write: the model never reads a file it can't see (no leak into the proposal) and never overwrites one (no wiping a gitignored `.env` it never added). A **new path** crosses the creation matrix in {§fs-write-surface}; proposal acceptance cannot bypass its scope, exclusion, or incorporation rules. Reaching past membership is `## EXEC0
|
|
3390
|
+
- §membership-edit-membership-gate **Membership-gated edits.** EDIT is bounded by membership exactly as READ is. An existing **member**'s baseline is its entry snapshot — the body channel the model READ, not a fresh disk read — so the diff is naive against the view the model saw, never empty (the write-side CAS, {§membership-edit-write-cas}, prevents the silent overwrite of out-of-band drift). An existing **non-member** is refused (403) *before* any read or write: the model never reads a file it can't see (no leak into the proposal) and never overwrites one (no wiping a gitignored `.env` it never added). A **new path** crosses the creation matrix in {§fs-write-surface}; proposal acceptance cannot bypass its scope, exclusion, or incorporation rules. Reaching past membership is `## EXEC0 (sh)`'s job, not the file scheme's.
|
|
3365
3391
|
- §membership-create-parents **Parent-complete creation.** An accepted File creation—whether authored as EDIT or as a COPY/MOVE destination—recursively creates missing parent directories before writing and registering the new member.
|
|
3366
3392
|
|
|
3367
3393
|
**The overlay — `include | exclude`.** `workspace_constraints` holds the `members` family's projected definitions and the engine's creation records ({§members-projection}). Resolved membership is `(project repository files ∪ include) − exclude`.
|
|
@@ -3438,7 +3464,7 @@ The CAS is the **hard backstop**, at the moment of writing, on every accept path
|
|
|
3438
3464
|
|
|
3439
3465
|
§membership-git-flags **Permission flags.** Service-wide Git admission comes from {§operator-config-git-ceiling}. `PLURNK_SERVICE_GIT_AUTO=1` (default) includes the repository containing `project_root`; `=0` disables automatic Git membership, leaving member definitions as the only membership source. `ALLOWED` gates `AUTO`.
|
|
3440
3466
|
|
|
3441
|
-
**Rationale.** Workspace is the right scope unit and the containing Git repository is its ordinary development boundary. Membership curation is tiered: Git bounds it by tracking, the client supersedes by overlay, and the model curates its render by READ/
|
|
3467
|
+
**Rationale.** Workspace is the right scope unit and the containing Git repository is its ordinary development boundary. Membership curation is tiered: Git bounds it by tracking, the client supersedes by overlay, and the model curates its render by READ/KILL. Supporting several independent repositories as one world would require Plurnk-owned topology, synchronization, and model teaching that Git already solves cleanly by treating them as separate workspaces.
|
|
3442
3468
|
|
|
3443
3469
|
**Schema.** The version-1 baseline stores the normalized {§inference-ledger},
|
|
3444
3470
|
its generation or embedding specialization, emission admission, and cardinal
|
|
@@ -3458,7 +3484,7 @@ flowchart TD
|
|
|
3458
3484
|
assemble["Assemble and measure<br/>candidate request"] --> budget{"Weight ≤ curation ceiling?"}
|
|
3459
3485
|
budget -->|yes| generate["Provider generate"]
|
|
3460
3486
|
budget -->|no| recover["Keep turn packetless<br/>reclassify as `_plurnk` overflow"]
|
|
3461
|
-
recover --> fold["Dispatch PLAN, whole-body
|
|
3487
|
+
recover --> fold["Dispatch PLAN, whole-body scoped KILL ops,<br/>and SEND through ordinary dispatch"]
|
|
3462
3488
|
fold --> verify{"Rebuilt request fits?"}
|
|
3463
3489
|
verify -->|yes| next["Next model turn"]
|
|
3464
3490
|
verify -->|no| stop["Terminal 413"]
|
|
@@ -3484,19 +3510,19 @@ at its first overflow because four embedding calls were counted as history). Pac
|
|
|
3484
3510
|
remain ordinary turn chronology but do not consume `maxTurns`, model-call,
|
|
3485
3511
|
emission-attempt, usage, or cost accounting.
|
|
3486
3512
|
|
|
3487
|
-
- §overflow-turn-script **Recovery is one ordinary admitted `_plurnk` program.** Its canonical {§plan-value} has one `medium`, `in_progress` entry whose content is `Automatically
|
|
3488
|
-
- §overflow-turn-curation **The preceding turn owns the pressure it introduced.** Core deterministically selects every body already created in the packetless candidate turn, every body created by the immediately preceding completed turn in that worker's chronology,
|
|
3489
|
-
- §overflow-turn-hard-413 **Recovery fails hard when the causal fold cannot fit.** After the ordinary
|
|
3513
|
+
- §overflow-turn-script **Recovery is one ordinary admitted `_plurnk` program.** Its canonical {§plan-value} has one `medium`, `in_progress` entry whose content is `Automatically KILL log bodies newly active at token-budget overflow.`, followed by every causal whole-body scoped KILL and terminal `## SEND0 (NEXT)` with body `Next: YOU MUST ONLY KILL superseded, stale, or irrelevant log content in bulk.` The final sentence requires the successor's substantive operations to be one dedicated, comprehensive bulk-curation program. Core authors this internal program with canonical PLAN and SEND framing. Its exact `turnOps` is born folded; successful KILL rows follow {§log-kill-meta-operation} and therefore remain durable but packet-suppressed. Every recovery row carries `_plurnk` and `overflow`; no model call, synthetic receipt, or parallel explanation exists.
|
|
3514
|
+
- §overflow-turn-curation **The preceding turn owns the pressure it introduced.** Core deterministically selects every body already created in the packetless candidate turn, every body created by the immediately preceding completed turn in that worker's chronology, Every selected body is KILLed whole (`<1,-1>`) through ordinary dispatch. Already-wholly-folded and bodyless rows require no operation. Core performs no relevance judgment, exempts no operation or resource kind, reconstructs no interval delta, re-runs no authored selector, and chooses no unrelated older history.
|
|
3515
|
+
- §overflow-turn-hard-413 **Recovery fails hard when the causal fold cannot fit.** After the ordinary scoped KILLs land, Core rebuilds and remeasures once. If the plan changes no visibility or the rebuilt request still exceeds the ceiling, the loop terminalizes with an exact `engine/context/token-budget-overflow` 413 Problem; Core neither submits excess bytes nor chooses unrelated older history. Separately, every `provider.generate` assesses physical capacity under {§provider-surface-capacity}. Core may retry a provider capacity rejection only after withholding automatic prompt-body projection when that changes the request. If it cannot produce changed bytes or the changed request is still rejected, the request-only model turn and provider-owned Problem terminalize at **413 Content Too Large**.
|
|
3490
3516
|
|
|
3491
3517
|
- §tokenomics-fetch-fits-free **A retrieval larger than the available packet room remains addressable.** Its complete row lands in the model turn that requested it. If the following candidate packet exceeds the curation ceiling, {§overflow-turn-curation} FOLDs the new body and classifies it `_plurnk` and `overflow`; the exact body remains durable and selectively re-OPENable.
|
|
3492
3518
|
|
|
3493
|
-
- §loop-terminals **Engine-imposed terminals are HTTP-precise** — the loop-status vocabulary, one meaning each: `200` concluded (the model's SEND signal `200`) · `499` model-abandoned (signal `499`, or a cancel) · `429` maxTurns exhausted · `413` token-ceiling recovery failure or provider input-capacity failure after changed-request recovery · `500` strike threshold or invalid-emission exhaustion (distinct Problem types; `508` when the crossing strike was a detected cycle) · `504` loop timeout / exec-timeout restamp · `202` the bounded wait — a loop blocked on a live obligation (the model's `## SEND0
|
|
3519
|
+
- §loop-terminals **Engine-imposed terminals are HTTP-precise** — the loop-status vocabulary, one meaning each: `200` concluded (the model's SEND signal `200`) · `499` model-abandoned (signal `499`, or a cancel) · `429` maxTurns exhausted · `413` token-ceiling recovery failure or provider input-capacity failure after changed-request recovery · `500` strike threshold or invalid-emission exhaustion (distinct Problem types; `508` when the crossing strike was a detected cycle) · `504` loop timeout / exec-timeout restamp · `202` the bounded wait — a loop blocked on a live obligation (the model's `## SEND0 (WAIT) <T,P>`, {§wait-obligation-matrix}); a wait on nothing resolves to `200` unless a successful same-turn scoped KILL requires the curated next packet · `100`/`102` queued/running. Never a catch-all, never a new value without changing the owning schema.
|
|
3494
3520
|
|
|
3495
3521
|
§overflow-turn-surface **The packet is the resulting state, not an account of it.**
|
|
3496
3522
|
The first request after recovery is assembled by the ordinary packet path from
|
|
3497
3523
|
the actual durable log after the recovery turn. It therefore carries the prior
|
|
3498
|
-
causal rows genuinely
|
|
3499
|
-
the recovery `turnOps` genuinely
|
|
3524
|
+
causal rows genuinely folded, the recovery PLAN and SEND genuinely visible, and
|
|
3525
|
+
the recovery `turnOps` genuinely folded. Successful recovery KILL receipts are
|
|
3500
3526
|
absent under the universal curation rule. No notice, reconstruction, auto-open,
|
|
3501
3527
|
or overflow-specific projection simulates what `_plurnk` did; OPENing the exact
|
|
3502
3528
|
`turnOps` reveals the program that did it. The model retains complete authority
|
|
@@ -3517,7 +3543,7 @@ flowchart LR
|
|
|
3517
3543
|
parent --> pull["Pre-turn lossless pull<br/>(cursor, captured high-water]"]
|
|
3518
3544
|
global --> pull
|
|
3519
3545
|
pull --> log["Observer's self-contained log<br/>origin=_plurnk"]
|
|
3520
|
-
log --> packet["Packet lists coordinate;<br/>
|
|
3546
|
+
log --> packet["Packet lists coordinate;<br/>READ recalls exact body"]
|
|
3521
3547
|
```
|
|
3522
3548
|
|
|
3523
3549
|
§env-delta-log-pull **Pull the event record, never a world snapshot.** At
|
|
@@ -3598,6 +3624,8 @@ flowchart LR
|
|
|
3598
3624
|
body --> recall["READ log:///…<br/>recalls canonical body"]
|
|
3599
3625
|
```
|
|
3600
3626
|
|
|
3627
|
+
§edit-receipt-removed-text **A pure deletion's receipt quotes what it removed.** An applied effect that inserted nothing and removed at least one line carries `removedText` — the removed text, first 40 lines — projected on the wire as `removed`; an effect that inserted anything carries no such field, its resulting context shows the change.
|
|
3628
|
+
|
|
3601
3629
|
§edit-receipt-anchored-context **An applied EDIT's resulting context carries anchors.** The bounded resulting context each effect renders (`PLURNK_SERVICE_EDIT_RECEIPT_CONTEXT_LINES` around and inside the landed region) is rendered exactly as a READ renders — `@xxxxx L:text`, hashed with the resource's READ identity ({§line-anchors}) — so the next batch cites the landed lines by anchor without a READ; both requiems of 2026-08-29 asked for this. A scheme that supplies no identity keeps the line-numbered form.
|
|
3602
3630
|
|
|
3603
3631
|
§edit-result-receipt-projection **EDIT projects the scheme-owned batch
|
|
@@ -3614,7 +3642,8 @@ the aggregate remains dispatch coordination state.
|
|
|
3614
3642
|
| `unit`, `before`, `after` | `extent` | Whole-line batches use line counts. A batch containing any exact four-coordinate edit uses Unicode code-point counts. |
|
|
3615
3643
|
| `parseIssues.before`, `parseIssues.after` | `parseIssues` as `before→after` | Parser-recovery counts for complete source and landed revisions; omitted when both are clean or either is unavailable. |
|
|
3616
3644
|
| `effect.requested`, `source`, `result` | `range` | The admitted marker and its normalized mapping from the common source snapshot into the landed body. |
|
|
3617
|
-
| `effect.removed`, `inserted` | `change` | Removed and inserted counts in the receipt unit.
|
|
3645
|
+
| `effect.removed`, `inserted` | `change` | Removed and inserted counts in the receipt unit. |
|
|
3646
|
+
| `effect.removedText` | `removed` | {§edit-receipt-removed-text}: a pure deletion's removed text, first 40 lines; absent when the edit inserted anything. |
|
|
3618
3647
|
| `effect.context` | Canonical row body | Numbered physical lines at each landed boundary, bounded symmetrically by `PLURNK_SERVICE_EDIT_RECEIPT_CONTEXT_LINES`. |
|
|
3619
3648
|
| `disposition`, `requested` | `disposition`, `requested` | A reviewer-replaced batch preserves the authored marker while stating that its attributed effect was superseded. |
|
|
3620
3649
|
| `replacement` | `replacement`, `change`, canonical proposal-owner body | The one whole-resource effect actually applied by the reviewer replacement; never duplicated across authored rows. |
|
|
@@ -3789,7 +3818,7 @@ evidence when a downstream standard cannot represent the complete list.
|
|
|
3789
3818
|
|
|
3790
3819
|
§body-projection **One full body, one packet projection.** Every durable log row has one canonical full body resolved from its stored tx/rx envelope by `LogBody`. READ and FIND over `log:///`, persistent search derivation, and packet rendering all consume that same meaning. Only packet rendering may project it:
|
|
3791
3820
|
|
|
3792
|
-
| row producer | ordinary
|
|
3821
|
+
| row producer | ordinary visible projection |
|
|
3793
3822
|
|---|---|
|
|
3794
3823
|
| any `READ` or `FIND` | complete selected operation result |
|
|
3795
3824
|
| any `PLAN` | complete canonical Plurnk Plan JSON {§plan-value} |
|
|
@@ -3798,13 +3827,13 @@ evidence when a downstream standard cannot represent the complete list.
|
|
|
3798
3827
|
| every other nonempty body | head bounded independently by `PLURNK_SERVICE_PREVIEW_LINES` and `PLURNK_SERVICE_PREVIEW_CHARS` |
|
|
3799
3828
|
| bodyless row | `"display":"none","body":""` |
|
|
3800
3829
|
|
|
3801
|
-
READ and FIND own their range or pagination before packet rendering; the packet never applies a second hidden substring bound to their selected result. PLAN is likewise complete while
|
|
3830
|
+
READ and FIND own their range or pagination before packet rendering; the packet never applies a second hidden substring bound to their selected result. PLAN is likewise complete while visible: it is the model's explicit persistent reasoning inventory, serialized once as compact JSON rather than clipped or reparsed from source text. Prompt rows follow their separate adaptive projection contract. Structured mutation contexts already carry the receipt-owned bound in {§edit-result-receipt-truth}, so packet rendering does not preview them again. Actionless source artifacts, SEND/WORK/FORK bodies, EXEC commands, environment-delta EDIT spans, and extension-produced bodies use the ordinary fixed bound. When a visible projection differs from its canonical body, `chunk` follows the displayed `body` with the exact selected and complete extents defined by {§jsonplurnk}; complete and FOLDED bodies omit it. `## READ0 (log:///<coordinate>/<OP>)` applies its default or explicit text range to the canonical body; the unsuffixed exact shorthand and authoritative suffix behavior are defined by {§log-coordinate-hierarchy}. `## FIND0 (log:///...)` and search match that same full body. A scoped KILL hides the ordinary projection without changing its bound. System/policy sections are not log bodies. Notices are transient non-log observations; they share the ordinary line/character bounds but have no durable body or recovery URI.
|
|
3802
3831
|
|
|
3803
|
-
§prompt-entry **Prompt as a first-class entry and log row.** Each prompt is stored once at `prompt:///<loop>/<N>` as an owner-keyed text/markdown entry — written before any turn of its loop executes, so the initialization COPY ({§worker-initialization-entry}) archives a real source — then published to its first model turn as one actionless lowercase `prompt` log row; that row, not the entry, records publication. No synthetic EDIT or READ operation is invented. The row is born
|
|
3832
|
+
§prompt-entry **Prompt as a first-class entry and log row.** Each prompt is stored once at `prompt:///<loop>/<N>` as an owner-keyed text/markdown entry — written before any turn of its loop executes, so the initialization COPY ({§worker-initialization-entry}) archives a real source — then published to its first model turn as one actionless lowercase `prompt` log row; that row, not the entry, records publication. No synthetic EDIT or READ operation is invented. The row is born visible and obeys {§body-projection}. The **Active User Prompts** section closes the user-slot status clump as a paths-only list (`* prompt:///<loop>/<N>`), so every frame remains directly READable even after its log row is folded or killed.
|
|
3804
3833
|
|
|
3805
3834
|
§prompt-causal-source **Prompt authorship and delivery are distinct facts.** The harness publishes every prompt row with `origin="_plurnk"`; the row's existing `source` carries the canonical address of a different causal actor. Native WORK, FORK, and directed worker SEND derive `worker://<sender>` from the authenticated sender worker ID. A trusted exterior adapter may supply its own canonical actor address through {§methods-loop-run}. An absent source means the owning worker itself. Attribution persists with the prompt frame through active delivery, parking, orphan recovery, restart, and later log projection; model syntax cannot author it.
|
|
3806
3835
|
|
|
3807
|
-
§prompt-projection **Prompt storage is unbounded by model context; automatic materialization is not.** Core persists every accepted prompt completely before packet assembly. The selected provider's derived `inputCapacity` and the alias-resolved percentage from `PLURNK_SERVICE_PROMPT_PROJECTION` derive one aggregate curation-weight allowance for
|
|
3836
|
+
§prompt-projection **Prompt storage is unbounded by model context; automatic materialization is not.** Core persists every accepted prompt completely before packet assembly. The selected provider's derived `inputCapacity` and the alias-resolved percentage from `PLURNK_SERVICE_PROMPT_PROJECTION` derive one aggregate curation-weight allowance for visible prompt bodies. Complete prompt bodies render when their aggregate weight fits. Otherwise all visible prompt rows share the allowance: full bodies consume only their required share, unused shares are redistributed, and partial bodies render the largest leading complete-line region that fits their share or an exact character-bound prefix when the first physical line alone is larger. The sum of their rendered body weights never exceeds the allowance. Every partial body carries its exact `chunk` after `body`; the canonical `prompt:///` entry and `log:///` body remain complete and READ/FIND-addressable. When provider input capacity is unknown the percentage is underivable, so prompt rows retain the ordinary bounded projection rather than inventing capacity. This policy never rejects, summarizes, or discards a prompt because it exceeds a context window.
|
|
3808
3837
|
|
|
3809
3838
|
§prompt-self-only The frame is self-only and owner-keyed:
|
|
3810
3839
|
`entries.owner_id` carries worker identity while the address carries only the
|
|
@@ -3901,7 +3930,7 @@ retain distinct contracts and lifetimes.
|
|
|
3901
3930
|
|
|
3902
3931
|
§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.
|
|
3903
3932
|
|
|
3904
|
-
§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`, tags, and structured `attrs`; every exact
|
|
3933
|
+
§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`, tags, and structured `attrs`; every exact log-KILL target effect; the exact Problem on every failed row; each loop's exact terminal result; and every ordered physical provider request. KILLed `turnOps` still produce their chronological `assistant.md` artifacts because curation cannot rewrite what a producer submitted. 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.
|
|
3905
3934
|
|
|
3906
3935
|
§digest-executor-evidence **A red command is work, not a defect.** Engine-materialized
|
|
3907
3936
|
completion rows for a failed command carry the executor's problem identity
|
|
@@ -3983,7 +4012,7 @@ worker's private entry space. Turn 0 surveys the families (`## FIND0 [+init,+too
|
|
|
3983
4012
|
(worker://~/_plurnk/tools/*.md)`, one row per
|
|
3984
4013
|
server carrying its summary) and, for each server named in
|
|
3985
4014
|
`PLURNK_MCP_EXPANDED`, adds one FIND over its family document matching the
|
|
3986
|
-
`## EXEC0` headings (`## FIND0
|
|
4015
|
+
`## EXEC0` headings (`## FIND0 (worker://~/_plurnk/tools/<server>.md)`
|
|
3987
4016
|
with `/^## EXEC0 .*\n.*$/m`), so turn 0 names every tool with its annotation and
|
|
3988
4017
|
signature — one row per tool, paged like every survey. No document is delivered
|
|
3989
4018
|
unasked.
|
|
@@ -4047,8 +4076,9 @@ its adapter owns protocol truth for standard Agent Skills and nothing else. A
|
|
|
4047
4076
|
definition is `SkillDefinition` — the standard skill `name`, the universal
|
|
4048
4077
|
root `scope` (`project` = `<projectRoot>/.agents/skills`, `global` =
|
|
4049
4078
|
`~/.agents/skills`), and for a Worker-installed skill the standard installer
|
|
4050
|
-
`source` that provides it. Plurnk
|
|
4051
|
-
|
|
4079
|
+
`source` that provides it. Plurnk seeds no universal root and mutates none
|
|
4080
|
+
absent an explicit `add`/`remove`; its one bundled skill document is never a
|
|
4081
|
+
root at all ({§git-skill}).
|
|
4052
4082
|
|
|
4053
4083
|
*Available definitions.* The filesystem is the only truth about installation:
|
|
4054
4084
|
every `<root>/<name>/SKILL.md` directory under the project then the global
|
|
@@ -4091,6 +4121,17 @@ preserved verbatim ({§functionality-documents}). They are discovered by the
|
|
|
4091
4121
|
turn-0 `+init,+skills` FIND survey; disabled and unavailable skills are
|
|
4092
4122
|
absent from model teaching.
|
|
4093
4123
|
|
|
4124
|
+
§git-skill **The git skill is a bundled document, surfaced where it applies.** `git.md`
|
|
4125
|
+
(the teaching corpus's `skillDocs.git`, shipped by `@plurnk/plurnk-meta`) is a knowledge
|
|
4126
|
+
document, not a tool: it teaches commits as the only shareable state, one branch-shaped child
|
|
4127
|
+
per checkout, worktrees for parallel children, deliberate merging, and the history a worker
|
|
4128
|
+
must not rewrite. The worker documentation reconciliation materializes it as the worker-private
|
|
4129
|
+
entry `worker://~/_plurnk/skills/git.md` when, and only when, the workspace's project root sits
|
|
4130
|
+
inside a git repository ({§membership}); it touches no universal skill root and installs
|
|
4131
|
+
nothing. The turn-0 survey `FIND (worker://~/_plurnk/skills/*.md)` therefore lists it, with
|
|
4132
|
+
its summary, exactly for the workspaces where it applies, and a plain-directory workspace never
|
|
4133
|
+
sees it.
|
|
4134
|
+
|
|
4094
4135
|
§skills-remove **`remove` uninstalls what the Worker installed.** Before the
|
|
4095
4136
|
coordinator forgets a Worker-origin skill definition the adapter removes that
|
|
4096
4137
|
skill from the definition's scope through the standard CLI (`remove <name>
|
|
@@ -4117,7 +4158,7 @@ section because they are language extensions rather than executable tools.
|
|
|
4117
4158
|
|
|
4118
4159
|
### §schemes user.schemes — the resource directory
|
|
4119
4160
|
|
|
4120
|
-
§schemes-directory A `## Resources` section renders in the system slot **after the policy sections** — a terse directory of the scheme families available to this worker, so the model knows what URI resources and operations exist before it acts. Each scheme that ships a `manifest.example` contributes one or more concise canonical ops (no scheme prefix; each example self-documents) into
|
|
4161
|
+
§schemes-directory A `## Resources` section renders in the system slot **after the policy sections** — a terse directory of the scheme families available to this worker, so the model knows what URI resources and operations exist before it acts. Each scheme that ships a `manifest.example` contributes one or more concise canonical ops (no scheme prefix; each example self-documents) into an `example` fence. Scheme example sets are separated by one blank line. The doc is NOT linked inline — it is materialized as the worker-private skill `worker://~/_plurnk/plurnk/<scheme>.md` and discovered via the turn-0 `## FIND0 (worker://~/_plurnk/plurnk/*.md)` survey ({§skills-functionality}), keeping the raw packet free of doc links. Meta-owned `worker` depth is required teaching ({§teaching-corpus}); a failed source read rejects materialization with its cause and never falls back. Other core and plugin schemes may supply optional `manifest.documentation`; absence contributes no pull doc. The verbose semantics live in that pull doc (materialized like any entry, READ on demand), not the hot path — terse pushes, depth pulls. A scheme with no example (provisional) is omitted; `PLURNK_SERVICE_DOCS_EXCLUDE` drops a named scheme's examples + doc. The directory includes only examples admitted by the effective worker-level capability layers, and Turn0 further narrows discovery through its loop policy using the same resolver ({§capability-admission}); the packet never baits an operation its own admission path will refuse. Materialized pull docs remain worker state, while their discoverability and execution remain policy-bound.
|
|
4121
4162
|
|
|
4122
4163
|
### §inject system.inject — the operator injection
|
|
4123
4164
|
|
|
@@ -4125,7 +4166,7 @@ section because they are language extensions rather than executable tools.
|
|
|
4125
4166
|
|
|
4126
4167
|
### §policy system.policy — the client's policy injection
|
|
4127
4168
|
|
|
4128
|
-
§policy-sections One section rides the system slot **after the definition and before capability teaching**: `## Policy` from `PLURNK_SERVICE_POLICY` (default `$XDG_CONFIG_HOME/plurnk/AGENTS.md`, {§host-path-layout}). Policy is the client's authoritative rules promoted into the privileged zone — NOT a curatable, foldable, READ-able entry; the model cannot
|
|
4169
|
+
§policy-sections One section rides the system slot **after the definition and before capability teaching**: `## Policy` from `PLURNK_SERVICE_POLICY` (default `$XDG_CONFIG_HOME/plurnk/AGENTS.md`, {§host-path-layout}). Policy is the client's authoritative rules promoted into the privileged zone — NOT a curatable, foldable, READ-able entry; the model cannot KILL it away. A default-absent path is silent (the section is omitted); an explicit override (env set) that fails to read fails the turn hard — a deliberate setting with a broken path is a misconfig, surfaced not hidden. Read per-turn so edits take effect live. The PROJECT `AGENTS.md` is local guidance, not policy: it rides turn 0 as the foisted `worker://~/_plurnk/agents.md` entry ({§turn0-agents-stunt}); all other reference material is skills under the worker's private skills tree ({§skills-functionality}).
|
|
4129
4170
|
|
|
4130
4171
|
On first run, and only when `$XDG_CONFIG_HOME/plurnk` itself is absent, the service seeds
|
|
4131
4172
|
`AGENTS.md` from `@plurnk/plurnk-meta/POLICY.md` ({§teaching-corpus}).
|
|
@@ -4380,10 +4421,11 @@ Carried from the contract walk; durable.
|
|
|
4380
4421
|
- **READ rx** prefixes every textual line under {§render-rule}; eligible
|
|
4381
4422
|
editable resources carry `@hash N:`, and all others carry `N:`.
|
|
4382
4423
|
- **FIND body matcher** applies to the addressed entry channel (all dialects), per-candidate via the in-tree `Matcher.matchAgainstContent` ({§matcher-dispatch}; status 200 = content hit → entry selected). The target scope and channel select candidates; the path-glob is the (target). FIND's signal classifies its own log item ({§log-item-tags}).
|
|
4383
|
-
- **
|
|
4384
|
-
- **SEND signal `410`** deletes as a side-effect (not the model idiom; {§move}): with `#fragment`, that channel only; without, the whole entry. **SEND signal `499`** resolves the durable open-subscription row and invokes that subscription's exact callable owner through the process-local live registry ({§subscriptions}).
|
|
4424
|
+
- **Scoped KILL** on the **log** (`log:///`) folds a body span away ({§log-kill-scope}); on an entry it deletes that span through the EDIT path ({§kill-scope-entry}). A whole-entry KILL deletes the entry, or one `#fragment` channel.
|
|
4385
4425
|
- **File scheme** detects with `Mimetypes.detect({ path })` and classifies with the same configured service ({§mimetype-classification-consumption}). Handler-declared binary sources materialize through {§membership-source-projection}; projected bodies are READ-able, while source-aware EDIT remains 415.
|
|
4386
4426
|
|
|
4387
|
-
### §
|
|
4427
|
+
### §kill-scope-entry Scoped KILL on an entry
|
|
4428
|
+
|
|
4429
|
+
A KILL with a text-coordinate scope aimed at an entry-bearing scheme deletes exactly that span: core prepares and dispatches it as an EDIT with an empty body over the same marker, so anchors resolve, proposals gate it, and the merge facts and receipt are the EDIT path's — while the log row records the model's KILL. `## EDIT0 (path) <scope>` with an empty body remains the same act spelled the other way; the teaching names KILL.
|
|
4388
4430
|
|
|
4389
|
-
|
|
4431
|
+
A body pattern on an entry KILL is refused (400 `kill-body-log-only`): body patterns select log items ({§log-kill-scope}), and a selector core does not apply is never silently dropped, so a scoped entry KILL can never widen to its whole span.
|