@plurnk/plurnk-service 3.3.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.defaults +4 -4
- package/INSTALL.md +6 -0
- package/README.md +2 -2
- package/SPEC.md +408 -179
- package/dist/build-info.json +1 -1
- package/dist/completions/_plurnk-service +1 -1
- package/dist/completions/plurnk-service.bash +1 -1
- package/dist/completions/plurnk-service.fish +2 -0
- package/dist/content/read-projector.js +1 -1
- package/dist/content/read-projector.js.map +1 -1
- package/dist/core/AdministrativeLoop.d.ts +1 -1
- package/dist/core/AdministrativeLoop.d.ts.map +1 -1
- package/dist/core/AdministrativeLoop.js +4 -1
- package/dist/core/AdministrativeLoop.js.map +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts +3 -1
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
- package/dist/core/AdmittedTurnExecutor.js +12 -0
- package/dist/core/AdmittedTurnExecutor.js.map +1 -1
- package/dist/core/BareBatchRunner.js +2 -1
- package/dist/core/BareBatchRunner.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +10 -0
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +10 -0
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +14 -2
- package/dist/core/ClientInteractions.d.ts.map +1 -1
- package/dist/core/ClientInteractions.js +2 -1
- package/dist/core/ClientInteractions.js.map +1 -1
- package/dist/core/CoreSchemeServices.d.ts.map +1 -1
- package/dist/core/CoreSchemeServices.js +5 -0
- package/dist/core/CoreSchemeServices.js.map +1 -1
- package/dist/core/DataStatementRunner.js +4 -6
- package/dist/core/DataStatementRunner.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +4 -7
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +48 -68
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/Dispatcher.sql +2 -2
- package/dist/core/EditMutations.js +1 -0
- package/dist/core/EditMutations.js.map +1 -1
- package/dist/core/Engine.d.ts +8 -14
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +22 -24
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Engine.sql +6 -6
- package/dist/core/ExecutorRegistry.d.ts +0 -5
- package/dist/core/ExecutorRegistry.d.ts.map +1 -1
- package/dist/core/ExecutorRegistry.js +10 -18
- package/dist/core/ExecutorRegistry.js.map +1 -1
- package/dist/core/FileAddress.js +1 -1
- package/dist/core/FileAddress.js.map +1 -1
- package/dist/core/FilePublication.js +10 -74
- package/dist/core/FilePublication.js.map +1 -1
- package/dist/core/FileSnapshot.js +36 -100
- package/dist/core/FileSnapshot.js.map +1 -1
- package/dist/core/HostPaths.d.ts +1 -0
- package/dist/core/HostPaths.d.ts.map +1 -1
- package/dist/core/HostPaths.js +11 -1
- package/dist/core/HostPaths.js.map +1 -1
- package/dist/core/KillHandler.js +3 -1
- package/dist/core/KillHandler.js.map +1 -1
- package/dist/core/LiveSubscription.js +1 -1
- package/dist/core/LiveSubscription.js.map +1 -1
- package/dist/core/LogBody.js +1 -1
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LogWriter.d.ts +4 -2
- package/dist/core/LogWriter.d.ts.map +1 -1
- package/dist/core/LogWriter.js +8 -4
- package/dist/core/LogWriter.js.map +1 -1
- package/dist/core/LoopDriver.d.ts +3 -3
- package/dist/core/LoopDriver.d.ts.map +1 -1
- package/dist/core/LoopDriver.js +15 -13
- package/dist/core/LoopDriver.js.map +1 -1
- package/dist/core/LoopLifecycle.d.ts +5 -0
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +14 -1
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +8 -0
- package/dist/core/MembershipMaterialization.js +2 -2
- package/dist/core/MembershipMaterialization.js.map +1 -1
- package/dist/core/MessageResources.d.ts +3 -0
- package/dist/core/MessageResources.d.ts.map +1 -1
- package/dist/core/MessageResources.js +15 -1
- package/dist/core/MessageResources.js.map +1 -1
- package/dist/core/OperationHistory.d.ts +18 -0
- package/dist/core/OperationHistory.d.ts.map +1 -0
- package/dist/core/OperationHistory.js +55 -0
- package/dist/core/OperationHistory.js.map +1 -0
- package/dist/core/OperatorConfig.d.ts +1 -2
- package/dist/core/OperatorConfig.d.ts.map +1 -1
- package/dist/core/OperatorConfig.js +26 -92
- package/dist/core/OperatorConfig.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +22 -56
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/PacketBuilder.sql +7 -8
- package/dist/core/ProblemLog.d.ts +1 -0
- package/dist/core/ProblemLog.d.ts.map +1 -1
- package/dist/core/ProblemLog.js +2 -2
- package/dist/core/ProblemLog.js.map +1 -1
- package/dist/core/ProposalLifecycle.d.ts.map +1 -1
- package/dist/core/ProposalLifecycle.js +13 -8
- package/dist/core/ProposalLifecycle.js.map +1 -1
- package/dist/core/ProposalPolicies.d.ts +4 -1
- package/dist/core/ProposalPolicies.d.ts.map +1 -1
- package/dist/core/ProposalPolicies.js +5 -2
- package/dist/core/ProposalPolicies.js.map +1 -1
- package/dist/core/ResourceMutations.js +2 -0
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.js +1 -1
- package/dist/core/ResourceSelector.js.map +1 -1
- package/dist/core/SchemeRegistry.js +1 -1
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/ServiceHelp.js +1 -1
- package/dist/core/ServiceHelp.js.map +1 -1
- package/dist/core/ServiceTeardown.js +9 -12
- package/dist/core/ServiceTeardown.js.map +1 -1
- package/dist/core/StrikeRail.d.ts +2 -1
- package/dist/core/StrikeRail.d.ts.map +1 -1
- package/dist/core/StrikeRail.js +11 -6
- package/dist/core/StrikeRail.js.map +1 -1
- package/dist/core/TerminalResult.js +1 -1
- package/dist/core/TerminalResult.js.map +1 -1
- package/dist/core/TurnDispositionHandler.js +3 -2
- package/dist/core/TurnDispositionHandler.js.map +1 -1
- package/dist/core/TurnMaterialization.js +6 -4
- package/dist/core/TurnMaterialization.js.map +1 -1
- package/dist/core/TurnMaterialization.sql +1 -1
- package/dist/core/TurnOps.d.ts +0 -3
- package/dist/core/TurnOps.d.ts.map +1 -1
- package/dist/core/TurnOps.js +1 -27
- package/dist/core/TurnOps.js.map +1 -1
- package/dist/core/TurnRunner.d.ts +4 -2
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +61 -61
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/WorkerControlHandler.d.ts +2 -0
- package/dist/core/WorkerControlHandler.d.ts.map +1 -1
- package/dist/core/WorkerControlHandler.js +48 -16
- package/dist/core/WorkerControlHandler.js.map +1 -1
- package/dist/core/WorkerName.d.ts +0 -4
- package/dist/core/WorkerName.d.ts.map +1 -1
- package/dist/core/WorkerName.js +5 -30
- package/dist/core/WorkerName.js.map +1 -1
- package/dist/core/WorkerName.sql +4 -20
- package/dist/core/WorkerOwners.d.ts +1 -0
- package/dist/core/WorkerOwners.d.ts.map +1 -1
- package/dist/core/WorkerOwners.js +6 -0
- package/dist/core/WorkerOwners.js.map +1 -1
- package/dist/core/WorkerOwners.sql +7 -0
- package/dist/core/WorkspaceGate.d.ts +3 -1
- package/dist/core/WorkspaceGate.d.ts.map +1 -1
- package/dist/core/WorkspaceGate.js +59 -10
- package/dist/core/WorkspaceGate.js.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.d.ts +2 -0
- package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
- package/dist/core/caps/SchemeCtxImpl.js +12 -0
- package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
- package/dist/core/env-catalog.js +1 -1
- package/dist/core/env-catalog.js.map +1 -1
- package/dist/core/fork.js +1 -1
- package/dist/core/fork.js.map +1 -1
- package/dist/core/fork.sql +5 -4
- package/dist/core/mutation-types.js +4 -1
- package/dist/core/mutation-types.js.map +1 -1
- package/dist/core/namespace.js +1 -1
- package/dist/core/namespace.js.map +1 -1
- package/dist/core/packet-wire.d.ts +7 -5
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +38 -20
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/scheme-types.d.ts +4 -0
- package/dist/core/scheme-types.d.ts.map +1 -1
- package/dist/core/turn-signals.d.ts +4 -0
- package/dist/core/turn-signals.d.ts.map +1 -1
- package/dist/core/turn-signals.js +1 -0
- package/dist/core/turn-signals.js.map +1 -1
- package/dist/core/workspace-settings.js +1 -1
- package/dist/core/workspace-settings.js.map +1 -1
- package/dist/evidence/EvidenceReader.js +5 -5
- package/dist/evidence/EvidenceReader.js.map +1 -1
- package/dist/man/plurnk-service.1 +27 -6
- package/dist/schemes/Env.d.ts +7 -3
- package/dist/schemes/Env.d.ts.map +1 -1
- package/dist/schemes/Env.js +12 -6
- package/dist/schemes/Env.js.map +1 -1
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +33 -25
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/ExecOutputScheme.js +3 -3
- package/dist/schemes/ExecOutputScheme.js.map +1 -1
- package/dist/schemes/ExecutionInput.js +1 -1
- package/dist/schemes/ExecutionInput.js.map +1 -1
- package/dist/schemes/File.js +15 -18
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +21 -36
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/Log.sql +0 -9
- package/dist/schemes/ResourceTreeScheme.js +2 -5
- package/dist/schemes/ResourceTreeScheme.js.map +1 -1
- package/dist/schemes/TurnSource.js +1 -1
- package/dist/schemes/TurnSource.js.map +1 -1
- package/dist/schemes/Worker.d.ts.map +1 -1
- package/dist/schemes/Worker.js +10 -3
- package/dist/schemes/Worker.js.map +1 -1
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js +2 -4
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-crud.sql +5 -3
- package/dist/schemes/_entry-find.js +3 -3
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +3 -3
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-manifest.sql +2 -0
- package/dist/schemes/_entry-ops.js +1 -1
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_entry-send.js +1 -1
- package/dist/schemes/_entry-send.js.map +1 -1
- package/dist/server/ClientReads.d.ts +1 -0
- package/dist/server/ClientReads.d.ts.map +1 -1
- package/dist/server/ClientReads.js +7 -2
- package/dist/server/ClientReads.js.map +1 -1
- package/dist/server/Credentials.d.ts +48 -0
- package/dist/server/Credentials.d.ts.map +1 -0
- package/dist/server/Credentials.js +203 -0
- package/dist/server/Credentials.js.map +1 -0
- package/dist/server/Daemon.d.ts +40 -41
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +272 -206
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +5 -2
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +27 -31
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/EnvFunctionality.d.ts.map +1 -1
- package/dist/server/EnvFunctionality.js +2 -1
- package/dist/server/EnvFunctionality.js.map +1 -1
- package/dist/server/Functionality.d.ts +4 -2
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js +110 -51
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/FunctionalityManager.js +1 -1
- package/dist/server/FunctionalityManager.js.map +1 -1
- package/dist/server/HttpListener.d.ts +1 -1
- package/dist/server/HttpListener.d.ts.map +1 -1
- package/dist/server/HttpListener.js.map +1 -1
- package/dist/server/MembersFunctionality.d.ts.map +1 -1
- package/dist/server/MembersFunctionality.js +4 -2
- package/dist/server/MembersFunctionality.js.map +1 -1
- package/dist/server/ModuleHost.d.ts +2 -1
- package/dist/server/ModuleHost.d.ts.map +1 -1
- package/dist/server/PlurnkSkill.js +4 -7
- package/dist/server/PlurnkSkill.js.map +1 -1
- package/dist/server/Rollback.js +1 -1
- package/dist/server/Rollback.js.map +1 -1
- package/dist/server/WorkerModelResolver.js +1 -0
- package/dist/server/WorkerModelResolver.js.map +1 -1
- package/dist/server/WorkerReferences.d.ts +14 -0
- package/dist/server/WorkerReferences.d.ts.map +1 -0
- package/dist/server/WorkerReferences.js +24 -0
- package/dist/server/WorkerReferences.js.map +1 -0
- package/dist/server/WorkerReferences.sql +31 -0
- package/dist/server/WorkspaceCapabilities.d.ts +2 -0
- package/dist/server/WorkspaceCapabilities.d.ts.map +1 -1
- package/dist/server/WorkspaceCapabilities.js +35 -18
- package/dist/server/WorkspaceCapabilities.js.map +1 -1
- package/dist/server/WorkspacePlugins.js +1 -0
- package/dist/server/WorkspacePlugins.js.map +1 -1
- package/dist/server/WorkspaceResidency.d.ts +3 -1
- package/dist/server/WorkspaceResidency.d.ts.map +1 -1
- package/dist/server/WorkspaceResidency.js +12 -5
- package/dist/server/WorkspaceResidency.js.map +1 -1
- package/dist/server/client-input.d.ts +2 -0
- package/dist/server/client-input.d.ts.map +1 -1
- package/dist/server/client-input.js +28 -0
- package/dist/server/client-input.js.map +1 -1
- package/dist/server/drain.sql +37 -40
- package/dist/server/envelope.d.ts +5 -9
- package/dist/server/envelope.d.ts.map +1 -1
- package/dist/server/envelope.js +21 -84
- package/dist/server/envelope.js.map +1 -1
- package/dist/server/envelope.sql +17 -17
- package/dist/server/lifecycle-recovery.sql +5 -15
- package/dist/server/logEntry.d.ts.map +1 -1
- package/dist/server/logEntry.js +6 -0
- package/dist/server/logEntry.js.map +1 -1
- package/dist/server/logEntry.sql +94 -6
- package/dist/server/module-discovery.d.ts +1 -1
- package/dist/server/module-discovery.d.ts.map +1 -1
- package/dist/server/module-discovery.js +1 -0
- package/dist/server/module-discovery.js.map +1 -1
- package/dist/server/seam-loop.sql +15 -7
- package/dist/server/seam-proposal-list.sql +10 -4
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +7 -1
- package/dist/service.js.map +1 -1
- package/docs/members.md +6 -4
- package/migrations/002_workers.sql +2 -2
- package/migrations/006_log.sql +1 -1
- package/migrations/018_worker_owners.sql +1 -1
- package/migrations/029_default_worker.sql +9 -0
- package/migrations/030_client_workers.sql +105 -0
- package/migrations/031_message_openers.sql +83 -0
- package/migrations/032_worker_references.sql +29 -0
- package/package.json +23 -22
- package/plurnk.nginx.conf +71 -0
- package/plurnk.service +2 -0
package/SPEC.md
CHANGED
|
@@ -40,11 +40,11 @@ Canonical meanings. When a doc, comment, test name, or commit message uses one o
|
|
|
40
40
|
|
|
41
41
|
```mermaid
|
|
42
42
|
flowchart LR
|
|
43
|
-
W["Workspace<br/>shared
|
|
43
|
+
W["Workspace<br/>shared resources and configuration"] --> K["Worker<br/>actor and history"]
|
|
44
44
|
K --> L["Loop<br/>queued-to-terminal work"]
|
|
45
45
|
L --> T["Turn<br/>one admitted scheduling unit"]
|
|
46
46
|
T --> O["Op<br/>one statement / action row"]
|
|
47
|
-
H["AG-UI thread<br/>
|
|
47
|
+
H["AG-UI thread<br/>names a worker"] -. resolves to .-> K
|
|
48
48
|
R["AG-UI Run<br/>client stream envelope"] -. binds to .-> L
|
|
49
49
|
R -. or executes .-> A["Management action<br/>no core loop required"]
|
|
50
50
|
```
|
|
@@ -52,7 +52,7 @@ flowchart LR
|
|
|
52
52
|
| Term | Layer | Meaning |
|
|
53
53
|
|-------------------|-----------------------|---------|
|
|
54
54
|
| **agent** | PLURNK | The plurnk runtime. Acts in-workspace as the `_plurnk` worker ({§actor-boundary} self-hosting), never a privileged singleton owning its own entries ({§entry-owner}, {§machine-processes}). |
|
|
55
|
-
| **workspace** | Core | Durable
|
|
55
|
+
| **workspace** | Core | Durable shared resources and configuration, with an optional project folder. Identity: `workspaces.id`; mutable label: unique `workspaces.name`. Persists across workers and process restarts. |
|
|
56
56
|
| **worker** | Core | Durable actor and history over one workspace. Owns its loops and log rows, may carry a `parent_worker_id`, and has one process-local cancellation scope while active. |
|
|
57
57
|
| **loop** | Core | Queued-to-terminal unit of model or client work within a worker. Status ∈ {100 pending · 102 running · 200 done · 202 waiting (blocked on a live obligation, {§send}) · 413 input-capacity failure · 429 model-turn ceiling · 499 cancelled · 500 failed · 504 execution timeout ({§operator-config-loop-timeout}) · 508 runaway}. Many loops may belong to one worker. |
|
|
58
58
|
| **turn** | Core | One durable, producer-neutral batch of ordered operations. A turn may be authored by a model, client, or `_plurnk`; only a model turn assembles a packet and owns an emission call. Many turns may belong to one loop. Identity: `(loop_id, sequence)`. |
|
|
@@ -62,7 +62,7 @@ flowchart LR
|
|
|
62
62
|
| **action** | Core | One executed op. Execution normally produces a `log_entries` row at `log:///<L>/<T>/<S>/<op>`; an engine rail may instead record an `op='error'` row ({§operation-results}). A source artifact carries no fabricated operation. |
|
|
63
63
|
| **dispatch** | Core | Routing a statement to its scheme's op handler. |
|
|
64
64
|
| **AG-UI Run** | AG-UI protocol | A client request/stream envelope identified by the client's `runId`. A message or resume AG-UI Run binds to one core loop; a management-action AG-UI Run may complete without creating a core loop. |
|
|
65
|
-
| **AG-UI thread** | AG-UI protocol |
|
|
65
|
+
| **AG-UI thread** | AG-UI protocol | Message history identity. Within an explicitly selected workspace, `threadId` resolves to one model worker. |
|
|
66
66
|
|
|
67
67
|
### Storage terms
|
|
68
68
|
|
|
@@ -202,7 +202,8 @@ early ownership introduces neither traffic nor a close/rebind race.
|
|
|
202
202
|
§http-host **The daemon opens exactly one transport.** Core binds the HTTP
|
|
203
203
|
listener on `PLURNK_HOST:PLURNK_PORT` and offers it to every exterior adapter as
|
|
204
204
|
`registerHttpRoute(prefix, handler)` and `httpAddress()` on the application port
|
|
205
|
-
({§application-port}).
|
|
205
|
+
({§application-port}). The listener is bound before any module sets up, so the setup seam
|
|
206
|
+
offers `httpAddress()` too ({§module-host-capabilities}). A prefix is an absolute pathname. Each request goes to the
|
|
206
207
|
longest mounted prefix; a prefix claims itself and the subtree beneath it, never
|
|
207
208
|
a longer sibling name; `/` is the root and receives whatever nothing more
|
|
208
209
|
specific claimed when a module mounts it. An admitted listener returns an HTTP
|
|
@@ -215,6 +216,67 @@ none opens a socket of its own. The standards
|
|
|
215
216
|
address by URL, never by port (#641): AG-UI mounts only `/agui`, A2A the
|
|
216
217
|
well-known card and its endpoint path, on the same address.
|
|
217
218
|
|
|
219
|
+
§http-request-origin **What the daemon advertises follows the address a caller used.** A request's
|
|
220
|
+
origin is the address its `Host` names, over http, or the listener's own for a request that names
|
|
221
|
+
none (`requestOrigin`). Every address the daemon advertises to a caller, the authority's issuer
|
|
222
|
+
({§agui-oauth-endpoints}) and the A2A card's endpoint, is its configured public origin or the origin
|
|
223
|
+
of the request that asked, so a daemon bound to every interface answers each caller at the address
|
|
224
|
+
that caller used; a module that asks with no request in hand, as one reading the issuer at its
|
|
225
|
+
start does, is answered with the configured origin or the listener's own. A configured origin is for
|
|
226
|
+
a front the daemon cannot see, such as a TLS proxy. No request is refused for the name it uses.
|
|
227
|
+
|
|
228
|
+
§credential-authority **The daemon is one credential authority.** Every credential presented
|
|
229
|
+
to its listener, whatever protocol is mounted there, was issued by the daemon's `credentials`
|
|
230
|
+
authority on the application port ({§application-port}): an opaque random token held in memory
|
|
231
|
+
with its kind (`access`, presented as a bearer; `refresh`, exchanged and never presented), its
|
|
232
|
+
subject, its client, its scopes, its family and its expiry. A restart revokes every credential.
|
|
233
|
+
Revocation is by family, so an access token and the refresh token that renews it fall together;
|
|
234
|
+
a refresh token is consumed once, and a second presentation revokes its family and says so. The
|
|
235
|
+
authority has no HTTP face and no policy of its own: the issuing module publishes the one face
|
|
236
|
+
(`publish({ issuer })`, at setup) that names where a request's caller obtains credentials
|
|
237
|
+
({§http-request-origin}) and answers from its publication, so any module may read the issuer from its own `start` on ({§module-phases}), an
|
|
238
|
+
exterior adapter
|
|
239
|
+
verifies through it ({§agui-http-authorization}), and the client protocol issues through it
|
|
240
|
+
({§agui-oauth}). The posture is the shared `PLURNK_AUTH` ({§operator-config-shared-keys}) and is
|
|
241
|
+
never inferred from what else is set. Under `1` the authority holds the operator's client secret,
|
|
242
|
+
`PLURNK_SECRET` when set, else one minted for this boot and written to the file `secret` beside the
|
|
243
|
+
database, 0600 and complete or absent, before any mount is admitted, where a tool running as the
|
|
244
|
+
operator reads it; a configured secret and a daemon that does not authenticate leave no such file. A
|
|
245
|
+
listening daemon under `1` refuses to start until a module publishes the face. Under `0` no
|
|
246
|
+
credential exists, no face is published and every mounted resource admits anonymously. Credentials
|
|
247
|
+
the daemon presents to others follow the remote party's declared scheme and are never minted here.
|
|
248
|
+
|
|
249
|
+
§credential-module-client **A module of this daemon is a confidential client by registration.** At
|
|
250
|
+
setup a module registers its own client on the authority, `registerClient({ id, redirectPaths, scopes, stylesheetPath })`:
|
|
251
|
+
an id of letters, digits, `.`, `_` or `-` other than `operator`, the absolute pathnames under its own
|
|
252
|
+
mounts it may be answered at, each as a URL carries it, with no query and no fragment, the scopes it
|
|
253
|
+
may ask for and, optionally, the pathname in the same form of a stylesheet under its own mounts,
|
|
254
|
+
which the issuing face links on the documents it serves that client's requests
|
|
255
|
+
({§agui-oauth-documents}). A module states no origin: it serves only on the daemon's one listener
|
|
256
|
+
({§http-host}), so its address is its path on the issuer, and registration needs nothing from the
|
|
257
|
+
listener, the issuer or another module. The issuing face answers the client at exactly the issuer
|
|
258
|
+
followed by a registered path ({§agui-oauth-endpoints}), and the module forms the same address from
|
|
259
|
+
`credentials.face().issuer()`, from its `start` on ({§credential-authority}). The authority mints the client's
|
|
260
|
+
secret for this boot, holds it in memory, answers it to the registrant and to nobody else, and
|
|
261
|
+
checks it in constant time (`authenticateClient`); `client(id)` tells any module the registration
|
|
262
|
+
without the secret. A second registration of one id and a malformed registration are faults and
|
|
263
|
+
register nothing. Nothing is configured, printed or persisted, so installing a module adds no
|
|
264
|
+
operator step. The issuing face authenticates such a client as it does any confidential one
|
|
265
|
+
({§agui-oauth-clients}). A module's own browser session is a credential of this authority too: a
|
|
266
|
+
`session` credential it issues in the family of the authorization grant it stands on, which is the
|
|
267
|
+
family of the browser's sign-in that authorized it ({§agui-oauth-session}), so revoking that family
|
|
268
|
+
from either side ends the module's session, its tokens and the browser's standing at the issuing
|
|
269
|
+
face together.
|
|
270
|
+
|
|
271
|
+
§credential-sessions **A browser sign-in is a family, and a subject's sign-ins are listed without a
|
|
272
|
+
token.** `sessions(subject)` answers every family of that subject that holds a live `session`
|
|
273
|
+
credential, oldest first: the family, which is the sign-in's handle and is never admitted as a
|
|
274
|
+
credential; the subject; when a credential was first issued into the family; when the last of its
|
|
275
|
+
session credentials expires; and the clients holding credentials in it. A grant with no session
|
|
276
|
+
credential, such as a client's `client_credentials` token or a consented client's code grant, is no
|
|
277
|
+
sign-in and is not listed. Revoking a listed family ({§credential-authority}) is signing that browser
|
|
278
|
+
out. Nothing records last activity or a device, and a restart ends every sign-in.
|
|
279
|
+
|
|
218
280
|
§startup-admission-order After listener ownership, database admission completes
|
|
219
281
|
before capability initialization can perform external work. Provider construction
|
|
220
282
|
and endpoint verification occur on worker selection or first use, never merely
|
|
@@ -262,7 +324,7 @@ not access to workspace resources ({§actor-boundary-no-mutex}).
|
|
|
262
324
|
| Root creation | Explicit owner, otherwise the runtime `_plurnk`. |
|
|
263
325
|
| WORK, FORK, or a fresh child | Inherit the parent's owner. |
|
|
264
326
|
| SEND, schedule occurrence, or other incoming message | Preserve the recipient's owner. |
|
|
265
|
-
| Explicit client control attachment | Claim a runtime-owned
|
|
327
|
+
| Explicit client control attachment | Claim a runtime-owned model worker and its runtime-owned descendants; never claim the runtime actor or replace another owner. |
|
|
266
328
|
| Observation or disconnect | No change. |
|
|
267
329
|
|
|
268
330
|
An owner declares its capability set: the client tool names it implements, and whether it
|
|
@@ -313,12 +375,12 @@ filter over workspace resources.
|
|
|
313
375
|
**attribution** — the delta's provenance ({§env-delta}) — and is never read to
|
|
314
376
|
filter a row.
|
|
315
377
|
|
|
316
|
-
§actor-boundary-attached-functionality **Attachment selects a
|
|
378
|
+
§actor-boundary-attached-functionality **Attachment selects a worker,
|
|
317
379
|
not an environment owner.** Client management commands mutate workspace
|
|
318
380
|
Functionality ({§module-workspace-capabilities}); runtimes, runtime
|
|
319
|
-
schemes, and tools resolve by `workspaceId`.
|
|
320
|
-
|
|
321
|
-
|
|
381
|
+
schemes, and tools resolve by `workspaceId`. A model's operations journal in its
|
|
382
|
+
worker, and a person's client operations in the workspace's runtime worker
|
|
383
|
+
({§connection-lifecycle}). Runtime and policy resolution require no second worker identity.
|
|
322
384
|
Attachment remains many-to-one and unrelated to parentage. Explicit control
|
|
323
385
|
attachment may claim approval ownership under {§worker-ownership}.
|
|
324
386
|
|
|
@@ -422,7 +484,7 @@ direct-entry-plus-directory count; `-1` enables the ordinary markerless page;
|
|
|
422
484
|
unset / `0` disables previews. `log://` is absent because the current worker's
|
|
423
485
|
log already renders in present mode.
|
|
424
486
|
|
|
425
|
-
§worker-initialization-entry **Model-worker initialization is a real `_plurnk` operation turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its program — the READ/FIND surveys,
|
|
487
|
+
§worker-initialization-entry **Model-worker initialization is a real `_plurnk` operation turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its program — the READ/FIND surveys, opened by one NOTE and closed by another when the surveys run — is recorded as the turn's `ops://` source and executed through {§op-execution-order} exactly as a model's program is; it authors no reasoning and reads none back. The two NOTEs show the card's NOTE practice in the example turn: the opening one carries the aside of the card's first NOTE example, `<!-- plan -->`, and is the worker's plan in numbered steps, each with its purpose: survey what exists, read the Open Message and restate what it asks for and what will show it is done, then do the work saving all new plans, findings and decisions in NOTEs for later turns; the closing one carries the aside of the card's last NOTE example, `<!-- next -->`, and reads `Read and resolve the Open Message.` No emission row is fabricated ({§emission-row}): the first request sees the NOTEs and the surveys' ordinary results, never an assistant-content copy of the program. The initial message arrives as an inbound SEND in the first model turn ({§message-arrival}); initialization never READs it, and neither initialization nor later turns manufacture a task inventory. Every orienting row is structurally classified `_plurnk` and `init`. The namespace surveys and their asides follow {§actor-boundary-catalog-preview}.
|
|
426
488
|
|
|
427
489
|
Incoming messages publish once as inbound SEND rows in the first model turn
|
|
428
490
|
({§message-arrival}); initialization neither READs nor archives them. The turn
|
|
@@ -481,8 +543,8 @@ for a loop, `(loop, sequence)` for a turn, `(turn, sequence)` for a log row —
|
|
|
481
543
|
outside the database, every copied row passes the same table triggers the original did, and a fork
|
|
482
544
|
either lands whole or not at all. Nothing else runs: `Fork.fork` is the claim.
|
|
483
545
|
|
|
484
|
-
§machine-processes-worker-is-its-log **A worker's
|
|
485
|
-
the shared
|
|
546
|
+
§machine-processes-worker-is-its-log **A worker's memory of
|
|
547
|
+
the shared workspace is its log, with no hidden per-worker snapshot beside it.**
|
|
486
548
|
A scoped KILL suppresses canonical body intervals on that worker's rows ({§log-kill-scope});
|
|
487
549
|
lineage activity and explicit commons broadcasts arrive as attributed log
|
|
488
550
|
entries ({§env-delta}). Named scratch and evidence follow {§machine-processes-entry-inheritance}. They are not an invisible mirror of shared state. Workspace
|
|
@@ -497,9 +559,9 @@ the parent after that boundary is sibling activity, not fork history. Global
|
|
|
497
559
|
commons broadcasts remain live after the fork because the branch is then an
|
|
498
560
|
existing workspace worker in its own right.
|
|
499
561
|
|
|
500
|
-
§machine-processes-model-worker-readable **Packet membership is per-worker, not an access policy.** A packet contains its worker's log plus explicitly delivered activity ({§actor-boundary}). `readLog({ workspaceId, workerId })` may inspect any worker belonging to that workspace, and `listWorkers` enumerates them. A client-interface module chooses its
|
|
562
|
+
§machine-processes-model-worker-readable **Packet membership is per-worker, not an access policy.** A packet contains its worker's log plus explicitly delivered activity ({§actor-boundary}). `readLog({ workspaceId, workerId })` may inspect any worker belonging to that workspace, and `listWorkers` enumerates them. A client-interface module chooses its worker binding. Inspection does not inject another log into a model's packet.
|
|
501
563
|
|
|
502
|
-
§machine-processes-worker-origin **A worker carries its actor.** Each worker records its `origin
|
|
564
|
+
§machine-processes-worker-origin **A worker carries its actor.** Each worker records its `origin`, set once at creation: `model` (a model's identity) or `_plurnk` (the workspace's runtime worker, where the daemon's own work and a person's client operations journal, {§connection-lifecycle}). Every worker WORK or FORK creates is a model worker: a model's is its child, and a person's operation starts a root worker or branches the worker it acts for ({§actor-boundary-client-operations}). `listWorkers` returns actor class without interpreting names; a retained worker's name is immutable ({§machine-processes-worker-is-its-log}).
|
|
503
565
|
|
|
504
566
|
§worker-provider-identity **A worker owns a durable provider identity distinct
|
|
505
567
|
from its database id.** Creation mints a globally unique, opaque 128-bit value;
|
|
@@ -508,7 +570,7 @@ emission ({§provider-cache-identity}). Database ids remain the internal relatio
|
|
|
508
570
|
client coordinate. BARE calls use isolated per-call provider identities rather
|
|
509
571
|
than either worker value.
|
|
510
572
|
|
|
511
|
-
§machine-processes-fork-shares-
|
|
573
|
+
§machine-processes-fork-shares-workspace **A fork copies history and named
|
|
512
574
|
scratch while sharing the workspace.** It is a new worker in the
|
|
513
575
|
same workspace (`workers.parent_worker_id`, {§lifecycle-terms}); project files,
|
|
514
576
|
shared entries, and membership remain live and uncopied.
|
|
@@ -523,9 +585,10 @@ or membership overlay requires a new workspace.
|
|
|
523
585
|
§worker-authority-carving **Authority is a literal namespace, not a principal.** `worker:///notes.md` is shared scratch; `worker://alice/draft.md` is named scratch. Both belong directly to the workspace ({§entry-owner}). Entry addresses require no namesake Worker row and survive its deletion; only pathless worker controls resolve an actor. The caller never alters an address, and `~` has no alias semantics.
|
|
524
586
|
|
|
525
587
|
§worker-name-minting **URI ingestion is permissive; worker minting is not.**
|
|
526
|
-
Every model
|
|
588
|
+
Every model worker-creation door applies the contracts-owned
|
|
527
589
|
`WORKER_NAME` predicate ({§worker-name}) through one core admission path. Generic URL parsing
|
|
528
|
-
continues to decompose other authorities without treating them as mintable
|
|
590
|
+
continues to decompose other authorities without treating them as mintable, and an exact read by
|
|
591
|
+
name ({§methods-worker-read}) is no creation door: it resolves `_plurnk` like any listed name.
|
|
529
592
|
|
|
530
593
|
| Candidate | Minting result |
|
|
531
594
|
| ---------------------------------------------- | --------------------------------------------------------------------- |
|
|
@@ -566,7 +629,7 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
|
|
|
566
629
|
| `READ` | existing literal name | Collect the named worker's deliverable. |
|
|
567
630
|
| `KILL` | existing literal name | Terminate the named worker or caller. |
|
|
568
631
|
|
|
569
|
-
- §worker-scheme-spawn **Spawn** — ```` ```WORK (worker://<name>)? ```` with a task body creates a new child worker (empty log) and starts it with that task on its first loop. WORK/FORK are the worker-creation verbs: EDIT is file/entry only, so EDIT on the bare worker entity is a **400** steering to WORK/FORK — the entity is not an entry. Names remain unique within a workspace for the lifetime of retained Worker rows, including after termination. A WORK whose name a worker already holds is the voice door ({§worker-scheme-irc}): its body is delivered to that worker as a message, nothing is created, the receipt names the worker and `delivered: message`, and an `env` option is refused by name since a message takes none. A FORK whose name a worker holds is `409 worker-name-conflict` whose recovery names the working forms, WORK or `SEND (worker://<name>)` to message the live worker, or a name no worker holds to branch; concurrent claims cannot redirect a published address or expose a raw uniqueness failure.
|
|
632
|
+
- §worker-scheme-spawn **Spawn** — ```` ```WORK (worker://<name>)? ```` with a task body creates a new child worker (empty log) and starts it with that task on its first loop; a person's operation starts a root worker that person owns instead ({§actor-boundary-client-operations}). WORK/FORK are the worker-creation verbs: EDIT is file/entry only, so EDIT on the bare worker entity is a **400** steering to WORK/FORK — the entity is not an entry. Names remain unique within a workspace for the lifetime of retained Worker rows, including after termination. A WORK whose name a worker already holds is the voice door ({§worker-scheme-irc}): its body is delivered to that worker as a message, nothing is created, the receipt names the worker and `delivered: message`, and an `env` option is refused by name since a message takes none. A FORK whose name a worker holds is `409 worker-name-conflict` whose recovery names the working forms, WORK or `SEND (worker://<name>)` to message the live worker, or a name no worker holds to branch; concurrent claims cannot redirect a published address or expose a raw uniqueness failure.
|
|
570
633
|
- §worker-spawn-prompt-resource **The spawn slot is overloaded by scheme.** A `worker://` path is
|
|
571
634
|
the child's address and keeps the address rules ({§worker-control-addressing}). A path of any
|
|
572
635
|
other scheme is the child's prompt resource: it is read whole (`<1,-1>`) under the caller's read capabilities, composed with
|
|
@@ -580,7 +643,8 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
|
|
|
580
643
|
- §worker-scheme-fork **Fork** — ```` ```FORK (worker://<name>)? ```` with a task body branches the
|
|
581
644
|
current worker into a **named** child: its log is deep-copied
|
|
582
645
|
({§machine-processes-fork-copies-the-log}), which continues with `task`; the
|
|
583
|
-
|
|
646
|
+
workspace is shared, never copied ({§machine-processes-fork-shares-workspace}). A
|
|
647
|
+
person's operation branches the worker it acts for ({§actor-boundary-client-operations}).
|
|
584
648
|
WORK and FORK are distinct verbs — WORK spawns a fresh worker, FORK branches
|
|
585
649
|
the log. Both report the resulting `worker://name` address in receipt
|
|
586
650
|
metadata `worker`, whether named explicitly or allocated automatically.
|
|
@@ -618,9 +682,8 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
|
|
|
618
682
|
A failure reports its problem even when the loop answered earlier: the failure is the news.
|
|
619
683
|
READs and completion observations use the same resolution, representation and projector.
|
|
620
684
|
- §child-orientation **Child orientation.** Beyond the conclusion delta, every
|
|
621
|
-
turn the packet's status clump surfaces the
|
|
622
|
-
|
|
623
|
-
one JSON object, `{"workers": [...], "streams": [...], "messages": [...]}`, its
|
|
685
|
+
turn the packet's status clump surfaces the work this worker currently holds
|
|
686
|
+
open, beside the messages it owes: `## Open Work` is one JSON object, `{"workers": [...], "streams": [...], "messages": [...]}`, its
|
|
624
687
|
unconcluded child workers, its open streams and the messages it sent that await
|
|
625
688
|
completion ({§worker-obligations}) as `{status, path}` pointers (the same shape as
|
|
626
689
|
the errors section); a message pointer carries the recipient loop's status. Body-suppressed child activity is durable
|
|
@@ -643,7 +706,7 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
|
|
|
643
706
|
Workspace schedules are not held work: an occurrence arrives as a message
|
|
644
707
|
({§schedule-delivery}).
|
|
645
708
|
- §packet-empty-sections **Emptiness is stated where the model decides on it.**
|
|
646
|
-
`##
|
|
709
|
+
`## Open Work` renders every turn, each of its lists `[]` when empty: the
|
|
647
710
|
model decides whether to wait or complete on exactly these facts, so their
|
|
648
711
|
emptiness is stated rather than inferred from a missing heading. This is the
|
|
649
712
|
deliberate exception to the wire rule that empty content is absent; errors,
|
|
@@ -867,7 +930,7 @@ pass.
|
|
|
867
930
|
|
|
868
931
|
§membership-git-flags **Permission flags.** Service-wide Git admission comes from {§operator-config-git-ceiling}. `PLURNK_SERVICE_GIT_AUTO=1` includes the repository containing `project_root`; `=0` disables automatic Git membership, leaving member definitions as the only membership source. `ALLOWED` gates `AUTO`.
|
|
869
932
|
|
|
870
|
-
**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
|
|
933
|
+
**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 workspace would require Plurnk-owned topology, synchronization, and model teaching that Git already solves cleanly by treating them as separate workspaces.
|
|
871
934
|
|
|
872
935
|
**Schema.** The version-1 baseline stores the normalized {§inference-ledger},
|
|
873
936
|
its model-response evidence, emission admission, and cardinal
|
|
@@ -1144,7 +1207,7 @@ boundary.
|
|
|
1144
1207
|
- §worker-lifecycle-idle-is-concluded **Idle is not completion.** A loop concludes only under {§loop-completion}; an unanswered message remains an obligation even when nothing is running. A concluded worker retains durable history; a later addressed arrival starts a new loop.
|
|
1145
1208
|
- §worker-lifecycle-no-lost-loop **A loop is never stranded by a drain's exit.** A drain relinquishes its registry slot only after a lock-held re-claim confirms the queue is empty; a loop enqueued during that teardown is either re-claimed by the exiting drain or claimed by a fresh drain that a later inject starts. The relinquish and the start are serialized, so neither the lost-loop hang nor a transient double-drain can occur.
|
|
1146
1209
|
- §worker-lifecycle-durable-disposition **Durable disposition wins cancellation races.** At a turn boundary, the engine reads the loop's durable status before interpreting a process-local abort. A committed `202` park survives a later daemon-shutdown signal; only a loop still durably running at `102` can be terminalized by that cancellation. Wake selection rechecks shutdown and worker cancellation before requeuing each parked loop.
|
|
1147
|
-
- §worker-lifecycle-restart-recovery **Restart is owner-loss reconciliation, not replay.** Before opening client transports, the service holds an exclusive database-adjacent daemon lock; a second live owner fails before touching SQLite, while a dead-PID crash claim is replaced atomically without a timeout lease. Boot preserves accepted `100` loops and restores their drains. A `102` loop belonged to a vanished drain/provider call, so it settles `500` with the interruption on its durable row—never replayed across an unknown effect boundary. Every pending physical provider request first settles as an error with absent usage and explicitly unknown cost; then its logical model call closes. Recovery never fabricates zero evidence. Every durable proposed operation likewise lost its process-local resolution waiter and settles as a visible `500 owner_vanished` occurrence rather than an unresolvable interrupt ({§proposal-list}). A pending client interaction also lost its exact awaiting operation, so boot removes the orphan instead of replaying work or inventing a response ({§client-interactions}). Every durable-open subscription belonged to a vanished callable: active channels become errored and its row closes `500`. A `202` continuation requeues on an unseen completion or when no live obligation remains. Otherwise it stays parked on surviving children; the drain restores inherited stream observation through the same guarded scheduler ({§worker-wait-timing}). Child terminalization wakes its parked parent on every outcome, including provider exceptions, cancellation, and restart interruption, recursively through the durable parent edges. These operations are idempotent, so an interrupted recovery safely repeats.
|
|
1210
|
+
- §worker-lifecycle-restart-recovery **Restart is owner-loss reconciliation, not replay.** Before opening client transports, the service holds an exclusive database-adjacent daemon lock; a second live owner fails before touching SQLite, while a dead-PID crash claim is replaced atomically without a timeout lease. Database-only owner-loss settlement commits atomically before drains or process-local observation resume; a failed settlement leaves no partial transitions. Boot preserves accepted `100` loops and restores their drains. A `102` loop belonged to a vanished drain/provider call, so it settles `500` with the interruption on its durable row—never replayed across an unknown effect boundary. Every pending physical provider request first settles as an error with absent usage and explicitly unknown cost; then its logical model call closes. Recovery never fabricates zero evidence. Every durable proposed operation likewise lost its process-local resolution waiter and settles as a visible `500 owner_vanished` occurrence rather than an unresolvable interrupt ({§proposal-list}). A pending client interaction also lost its exact awaiting operation, so boot removes the orphan instead of replaying work or inventing a response ({§client-interactions}). Every durable-open subscription belonged to a vanished callable: active channels become errored and its row closes `500`. A `202` continuation requeues on an unseen completion or when no live obligation remains. Otherwise it stays parked on surviving children or unanswered inter-worker messages; the drain restores inherited stream observation through the same guarded scheduler ({§worker-wait-timing}). Child terminalization wakes its parked parent on every outcome, including provider exceptions, cancellation, and restart interruption, recursively through the durable parent edges. These operations are idempotent, so an interrupted recovery safely repeats.
|
|
1148
1211
|
|
|
1149
1212
|
---
|
|
1150
1213
|
|
|
@@ -1241,7 +1304,9 @@ alone are not a cycle: changing inputs or observations distinguish activity.
|
|
|
1241
1304
|
A turn that executed nothing has no activity to identify, so an empty turn's
|
|
1242
1305
|
identity is its **text** ({§empty-turn}) — the same principle, applied to the only
|
|
1243
1306
|
output it produced. Identifying it by its absent program instead makes every empty
|
|
1244
|
-
turn identical, and changing words then read as a repeating one.
|
|
1307
|
+
turn identical, and changing words then read as a repeating one. A turn whose final emission the
|
|
1308
|
+
output allowance cut has no identity: the engine's ceiling, not the model, ended its output, so it
|
|
1309
|
+
is no repetition evidence and closes the window ({§loop-rail-continuity}).
|
|
1245
1310
|
This is an exact-repetition backstop, not a semantic judgment of task progress;
|
|
1246
1311
|
new asynchronous invocation identities do not prove repetition of their eventual
|
|
1247
1312
|
effects. Ordinary contract strikes and operator budgets remain independent.
|
|
@@ -1312,12 +1377,13 @@ independent turn ceiling terminates at **429** ({§loop-terminals}). The streak
|
|
|
1312
1377
|
and cycle verdict are absent from model packets; only the concrete occurrences
|
|
1313
1378
|
in the table are shown. The streak never leaves the daemon.
|
|
1314
1379
|
|
|
1315
|
-
A crossing terminal names the source that struck the crossing turn — `
|
|
1316
|
-
`no_operation`, then `operation` — in its detail, in that order when a turn matches
|
|
1317
|
-
than one. The three are not interchangeable: a turn that authored no operation did not *fail*
|
|
1380
|
+
A crossing terminal names the source that struck the crossing turn — `output_allowance`,
|
|
1381
|
+
`repetition`, `no_operation`, then `operation` — in its detail, in that order when a turn matches
|
|
1382
|
+
more than one. The three are not interchangeable: a turn that authored no operation did not *fail*
|
|
1318
1383
|
one, and reporting it as a failed turn misreads a model answering without the fence as a model
|
|
1319
1384
|
whose operations broke. A cycle of empty turns names repeated responses without operations,
|
|
1320
|
-
not repeated operations or results.
|
|
1385
|
+
not repeated operations or results. A turn whose final emission the output allowance cut names
|
|
1386
|
+
the allowance and its grant ({§output-allowance-notice}), whatever else it struck on. This is the crossing turn's source, not the streak's composition; the
|
|
1321
1387
|
rail rules on the crossing and does not retain the kinds behind it. What the crossing turn
|
|
1322
1388
|
actually said is cited, not discarded ({§terminal-evidence}). Naming the source is not the
|
|
1323
1389
|
private accounting {§rail-accounting-private} withholds: the streak, the cycle verdict and
|
|
@@ -1333,6 +1399,7 @@ restart; curation of log evidence cannot alter them.
|
|
|
1333
1399
|
| Assessed turn with a violation | Increment once. | Include its exact activity. |
|
|
1334
1400
|
| Clean assessed turn | Reset to zero. | Include its exact activity. |
|
|
1335
1401
|
| Actual park, including an immediate wake/reclaim in the same drain | Preserve the assessed streak. | Close the window; the next turn starts a new one. |
|
|
1402
|
+
| Assessed turn whose final emission the output allowance cut | As any assessed turn. | Exclude it and close the window; the next turn starts a new one. |
|
|
1336
1403
|
| Recoverable provider outage | No assessment; preserve the streak. | Preserve until an actual park. |
|
|
1337
1404
|
| New loop | Start at zero. | Start empty. |
|
|
1338
1405
|
|
|
@@ -1414,7 +1481,9 @@ completion before the model sees them in the next packet.
|
|
|
1414
1481
|
WAIT without a live obligation continues to those results.
|
|
1415
1482
|
This is operation recovery, not provider
|
|
1416
1483
|
resampling. A malformed statement's Problem records the factual
|
|
1417
|
-
`siblingsRetained: true` extension
|
|
1484
|
+
`siblingsRetained: true` extension, and its row's `attrs` record the statement the parser refused,
|
|
1485
|
+
its `attempt` ({§parse-attempt}), outside the row's body and weight, so the packet shows the model
|
|
1486
|
+
nothing new.
|
|
1418
1487
|
|
|
1419
1488
|
§invalid-emission-attempts Each exhausted emission-attempt budget contributes
|
|
1420
1489
|
one frame-contract strike to the same streak as other contract violations
|
|
@@ -1658,7 +1727,7 @@ Every fact names the canonical key, never the host root or an echo of the
|
|
|
1658
1727
|
model's spelling. These classes let a caller distinguish a wrong address, an
|
|
1659
1728
|
invalid range, read-only authority, and occupied hidden state without guessing.
|
|
1660
1729
|
|
|
1661
|
-
§membership-read-refusal **A file miss speaks of membership, never of the disk.** A file is read only as a member, so every `file` miss — READ, FIND of an exact path, KILL, a pattern EDIT's source, a COPY or MOVE source — is 404 `entry-not-found`, `No member of this workspace is at '<key>'.`, its target rendered as the reusable member address ({§fs-answer-in-canon}, {§file-url}). Recovery offers listing with FIND, creation with EDIT, and admission with `members (add)` as alternatives and presumes none ({§diagnostic-observation}): `` FIND lists paths. EDIT creates files; `members (add)` admits existing files with a `{"
|
|
1730
|
+
§membership-read-refusal **A file miss speaks of membership, never of the disk.** A file is read only as a member, so every `file` miss — READ, FIND of an exact path, KILL, a pattern EDIT's source, a COPY or MOVE source — is 404 `entry-not-found`, `No member of this workspace is at '<key>'.`, its target rendered as the reusable member address ({§fs-answer-in-canon}, {§file-url}). Recovery offers listing with FIND, creation with EDIT, and admission with `members (add)` as alternatives and presumes none ({§diagnostic-observation}): `` FIND lists paths. EDIT creates files; `members (add)` admits existing files with a `{"files": ["<path>"]}` body. `` The sentence is about the address and is true whether or not a file is there: it neither claims absence nor hints at presence. Beyond the root the engine does not look at the disk at all, so two reads of `../` paths differ only in the name they echo, and their recovery speaks of the address too, true under every members scope: `'<key>' is outside the project root: only a members definition under the operator's namespace scope admits it.` Inside the root occupancy is not secret ({§fs-write-nonmember}), so an exact-path READ of a path that exists on disk but is not a member says so instead — 404 `entry-not-member`, `'<key>' exists on disk but is not a member of this workspace.`, with admission-only recovery; a path the repository ignores, which no model definition admits, carries the members discovery verdict instead: `The repository ignores it: a client or operator members definition can include it, a model definition cannot.` Occupancy may surface there; content never does ({§membership}).
|
|
1662
1731
|
|
|
1663
1732
|
§file-directory-target **A directory is named as a directory.** Inside the root, a READ (or other exact-path read), KILL or EDIT whose target is a directory on disk — with or without a trailing slash — is refused `path-is-directory`, never as a missing or non-member file: READ and KILL answer 404, EDIT 403. The detail is `'<key>' is a directory, not a file; <OP> reads/removes/writes one file.`; a READ or KILL carries the listing as its recovery, `` `FIND (<key>/)` lists its files. ``, and an EDIT carries none. Beyond the root the disk stays dark and {§membership-read-refusal} holds unchanged.
|
|
1664
1733
|
|
|
@@ -1683,6 +1752,9 @@ cross-scheme SQL transaction. Core's create-only publication claims the same
|
|
|
1683
1752
|
identity atomically: an existing identity returns 409 without changing its
|
|
1684
1753
|
metadata or channels.
|
|
1685
1754
|
|
|
1755
|
+
Removing a channel preserves its siblings. Pruning the resulting entry requires
|
|
1756
|
+
it to be empty at the deletion boundary, not merely at an earlier observation.
|
|
1757
|
+
|
|
1686
1758
|
### Op methods
|
|
1687
1759
|
|
|
1688
1760
|
§op-methods-op-dispatch Engine operation ownership follows the public scheme contract:
|
|
@@ -1700,7 +1772,7 @@ Registration precedes loop affinity:
|
|
|
1700
1772
|
| Registered but inactive under flag | The flag gate returns `403 scheme-unavailable`. |
|
|
1701
1773
|
| Registered and active | Dispatch continues to the operation owner. |
|
|
1702
1774
|
|
|
1703
|
-
- §op-execution-order **An admitted turn is an ordered program.** Model, client, and harness operations execute in authored order. WAIT is deferred until all other admitted operations settle or establish their explicitly asynchronous work ({§disposition-anywhere}). The complete program then settles under {§wait-obligation-matrix}, whether or not it contains a lifecycle request; no completion operation or inventory is invented. Existing cycle, no-operation, and resource rails remain effective. An observation records the resource state at its execution point; the model sees that receipt in the next packet. Exact submitted source and actual operation outcomes remain durable. Earlier successful effects survive a later operation failure; a producer requesting fail-on-error stops before subsequent operations.
|
|
1775
|
+
- §op-execution-order **An admitted turn is an ordered program.** Model, client, and harness operations execute in authored order. WAIT is deferred until all other admitted operations settle or establish their explicitly asynchronous work ({§disposition-anywhere}). The complete program then settles under {§wait-obligation-matrix}, whether or not it contains a lifecycle request; no completion operation or inventory is invented. Existing cycle, no-operation, and resource rails remain effective. An observation records the resource state at its execution point; the model sees that receipt in the next packet. Exact submitted source and actual operation outcomes remain durable. Earlier successful effects survive a later operation failure; a producer requesting fail-on-error stops before subsequent operations. Cancellation stops before the next resolved operation, including remaining glob targets, while preserving already-settled effects, receipts, source, and provider accounting.
|
|
1704
1776
|
|
|
1705
1777
|
§bare-inference **BARE is isolated, synchronous retrieval over the durable child-provider policy.**
|
|
1706
1778
|
|
|
@@ -1714,7 +1786,7 @@ Registration precedes loop affinity:
|
|
|
1714
1786
|
| Failure | A source/admission/provider failure affects its own operation, not successful siblings. Accounting or persistence failure is internal and fails hard. |
|
|
1715
1787
|
| Observation | Responses are unseen retrieval work; completion follows {§send-premature-terminate}. |
|
|
1716
1788
|
|
|
1717
|
-
- §op-synchronous **Decisive operations settle before the next operation.** The dispatcher awaits each operation and its proposal resolution. Work remains in flight only when the operation's contract deliberately creates concurrency: FORK, WORK,
|
|
1789
|
+
- §op-synchronous **Decisive operations settle before the next operation.** The dispatcher awaits each operation and its proposal resolution, including subsystem commands ({§functionality-model-mutation}). Work remains in flight only when the operation's contract deliberately creates concurrency: FORK, WORK, external execution, and streaming READ after acquisition. Such a READ first establishes its durable subscription and returns `102`; a later operation may address that live owner. Dispatching an external execution before KILL does not wait for the process to finish using a resource. KILL of a worker synchronously ends its live loops before disposition checks the pending set; physical scope cleanup remains asynchronous.
|
|
1718
1790
|
- §edit-execution **One resolved EDIT target is one mutation.** Each EDIT resolves against current resource state when dispatch reaches it, owns its proposal when gated, and records its own resulting revision. No later EDIT is prepared or applied in advance. Numeric scopes address current coordinates; an earlier EDIT may change what those numbers select. Rejection applies only to that operation, not its successful siblings.
|
|
1719
1791
|
- §edit-anchor-continuity **Own EDITs preserve untouched hash targets within one program.** Core carries an anchor through exact, successfully applied EDIT splices when its line survives unchanged, even if its ordinal or neighborhood changes. Scoped entry KILL uses the same deletion path. Target-line replacement or deletion invalidates that binding. Continuity is private to the admitted program and canonical resource/channel; it is not a new published anchor format. The complete normalized line content must match the expected result of the preceding recorded EDIT, otherwise retained bindings are discarded and ordinary current-state validation applies. Reviewer replacement and results without an applied EDIT receipt do not carry bindings forward. A retained binding resolves alone: a twin neighbourhood this program's own splice created elsewhere does not make the carried anchor ambiguous, and an anchor the program never bound resolves against current state. Normalization is the same line-content representation used by READ and line hashing; file-write revision checks remain independent. No approximate text matching is used. Lowered coordinates retain a current-anchor precondition at the mutation owner; ambiguous matches and concurrent changes remain collisions.
|
|
1720
1792
|
- §anchor-offset **An anchor offset is tolerated, never taught (#749).** A line mark may carry an offset from its anchor (`@abcde+1`, `@abcde-2`), and a bare `+N` after an anchor counts from that anchor (`<@abcde,+1>`). The anchor resolves as usual and the offset is added; a result before line 1 is an invalid mark, and past the end is the ordinary range refusal. Continuity and current-anchor preconditions check the anchor's own line. `plurnk.md` keeps its two anchor forms. Numeric relative endpoints normalize under {§scope-range-recovery}; a reversed range produced by anchor resolution is never reinterpreted as a count.
|
|
@@ -2114,7 +2186,7 @@ source line therefore retains the same prefix across projections of one revision
|
|
|
2114
2186
|
An explicit default-channel fragment and its fragmentless spelling share that
|
|
2115
2187
|
identity; a selected non-default channel retains its canonical `#channel`.
|
|
2116
2188
|
|
|
2117
|
-
For READ
|
|
2189
|
+
For READ and COPY/MOVE source or destination selection, core resolves every
|
|
2118
2190
|
anchor against the addressed current complete content before applying the
|
|
2119
2191
|
ordinary numeric text-coordinate contract. Exactly one current match lowers to
|
|
2120
2192
|
its numeric line; zero or multiple matches return 409 `line-anchor-collision`,
|
|
@@ -2337,7 +2409,7 @@ AST: `{ op: "KILL", target, matcher: MatcherBody | null, lineMarker: TextLineMar
|
|
|
2337
2409
|
|
|
2338
2410
|
§log-kill-distillation **A log KILL may say what it keeps.** A body on a `log:///` KILL is the model's distillation of what the KILL retires. Whatever the kill's outcome, the body lands as the model's own NOTE row at the next sequence of the same turn — written after the kill's receipt, so it never falls inside the kill's own selection — carrying `attrs.distilled` with the KILL's target as written, so a distillation is distinguishable from a free NOTE while it renders, weighs and curates exactly as one; the dispatch reports two rows written. A kill that misses keeps its distillation beside its visible receipt: what the model wrote about its environment is recorded for the model to possess and retire, never dropped for where the kill aimed. A whitespace-only body is a plain KILL. The kill's own receipt stays hidden as any successful log KILL's does ({§context-verbs}).
|
|
2339
2411
|
|
|
2340
|
-
KILL deletes context from the **log** (`log:///`, {§packet}). Without a scope it retires the selected rows from the active projection ({§log-history-projection}). With a one-line or inclusive two-line scope it removes only that body's intersecting body-relative physical lines from the readable projection, and the row stays active. An anchor may be one published on that body or one returned by READing its `log:///` coordinate ({§line-anchors}); an anchor absent from the current body selects no line, as with an out-of-bounds numeric line. Scoped KILL is one-way: intervals accumulate, the durable body is untouched, and subsequent access follows {§log-readable-projection}. A scoped KILL on a bodyless row is a friendly 200 no-op with `matched` reported. An emission row is curated whole ({§emission-row}): the unscoped KILL retires it; a line scope on its exact coordinate
|
|
2412
|
+
KILL deletes context from the **log** (`log:///`, {§packet}). Without a scope it retires the selected rows from the active projection ({§log-history-projection}). With a one-line or inclusive two-line scope it removes only that body's intersecting body-relative physical lines from the readable projection, and the row stays active. An anchor may be one published on that body or one returned by READing its `log:///` coordinate ({§line-anchors}); an anchor absent from the current body selects no line, as with an out-of-bounds numeric line. Scoped KILL is one-way: intervals accumulate, the durable body is untouched, and subsequent access follows {§log-readable-projection}. A scoped KILL on a bodyless row is a friendly 200 no-op with `matched` reported. An emission row is curated whole ({§emission-row}): the unscoped KILL retires it; a line scope on its exact coordinate is 422 `emission-curated-whole`, whose recovery names the unscoped KILL; a sweep leaves it intact. A KILL that addresses no row is 404 on an exact coordinate and 204 on a sweep ({§log-curation-folder-idiom}). Selection composes target/glob with an optional heading pattern ({§log-curation-set-selection}).
|
|
2341
2413
|
|
|
2342
2414
|
§log-target-tolerances **The log target reader accepts four near-misses of the taught form and reads each as the one target it can only have meant.** The card teaches `KILL (log:///1/[1-7]/*/{READ,emission})`; none of the following is taught, and no diagnostic text accompanies any of them. A `|` between complete KILL targets, each a coordinate, prefix or glob ({§log-coordinate-hierarchy}) written bare or as a full `log:///` address, is their union: `log:///1/25/2/EDIT|log:///1/24/3/EDIT` retires both rows; a piece that is none of those refuses the whole target, 400 `kill-failed`, naming the piece; a list that selects nothing is the sweep's 204 unless every piece is an exact coordinate, when it is the exact miss's 404. `|` is not a character of a coordinate, and file paths, where it is one, are untouched. For KILL and FIND alike: a bracketed comma list in a numeric slot is a set, `log:///1/[19,24]/**/sh` reading as `log:///1/{19,24}/**/sh`, since a character class can never match a turn number; a non-numeric literal in a numeric slot, after at least one numeric slot, is the leaf with the missing slots `*`, `log:///1/*/READ` reading as `log:///1/*/*/READ`; and `*` segments between the sequence and the leaf are dropped, `log:///1/3/3/*/READ` reading as `log:///1/3/3/READ`, since no coordinate holds a segment there.
|
|
2343
2415
|
|
|
@@ -2389,7 +2461,7 @@ The `## Log` section is a sequence of ordinary Markdown records separated by one
|
|
|
2389
2461
|
| facts | One strict JSON object in stable alphabetical order. | Present only when a fact exists. Asides, scopes, opaque invocation metadata and result facts belong here, not on the H3. |
|
|
2390
2462
|
| body | Coordinate-prefixed lines. | Present when the row is visible. |
|
|
2391
2463
|
|
|
2392
|
-
An emission row's body is not in its record ({§emission-row}); its eligible
|
|
2464
|
+
An emission row's body is not in its record ({§emission-row}); its eligible operations precede their receipts as assistant messages ({§emission-history}). Paired receipts omit duplicated request information under {§paired-receipt}. Patterns retain their literal spelling; a pattern containing a line break is JSON-quoted to keep the H3 on one physical line. Receipts are descriptive records, not reconstructed operation headings. Absent fields are not invented. Every physical body line retains its canonical numeric `N:` or anchored `@hash N:` coordinate, so source text cannot create a record boundary. The section contains records only, with no leading prose or enclosing fence.
|
|
2393
2465
|
|
|
2394
2466
|
§log-mutation-patch **A settled file mutation's row keeps what it did.** When an accepted EDIT,
|
|
2395
2467
|
COPY, MOVE or KILL writes or removes a text member, the file scheme appends the unified diff of
|
|
@@ -2402,14 +2474,14 @@ nothing is reconstructed for them: such a row has no `patch` channel, and whatev
|
|
|
2402
2474
|
rollback included, fails by name rather than inventing one.
|
|
2403
2475
|
|
|
2404
2476
|
§rollback **Rollback reverses a worker's settled file mutations, latest first, through ordinary
|
|
2405
|
-
operations.** `rollback({ workspaceId, workerId,
|
|
2477
|
+
operations.** `rollback({ workspaceId, workerId, actor, to })` (`workspace.rollback { to,
|
|
2406
2478
|
workerId? }` for a client) names a log coordinate of `workerId`, `<loop>/<turn>/<item>`; the state
|
|
2407
2479
|
after that item is what remains. Every settled EDIT, COPY, MOVE or KILL row after it, latest first,
|
|
2408
|
-
has its patch ({§log-mutation-patch}) reversed against the file as it is now and written back
|
|
2409
|
-
operation of
|
|
2410
|
-
`EDIT <1,-1>`, a removed file as a creating `EDIT`, a created file as `KILL`. Each reversal is a
|
|
2411
|
-
|
|
2412
|
-
|
|
2480
|
+
has its patch ({§log-mutation-patch}) reversed against the file as it is now and written back within
|
|
2481
|
+
one client operation of `actor` ({§connection-lifecycle}), that person's decision already: a rewrite
|
|
2482
|
+
as `EDIT <1,-1>`, a removed file as a creating `EDIT`, a created file as `KILL`. Each reversal is a
|
|
2483
|
+
row and a patch of its own, so a rollback is inspectable afterwards and reversible by the same
|
|
2484
|
+
means. The report (`RollbackReport`) lists what was restored, the rows skipped because they
|
|
2413
2485
|
kept no patch or were reversed already (the file is in the state before that mutation, as an earlier
|
|
2414
2486
|
rollback left it), and where it stopped: `drift`, the file no longer holds what that mutation wrote,
|
|
2415
2487
|
leaves that file and everything earlier untouched; `refused` carries the reversing operation's
|
|
@@ -2467,9 +2539,9 @@ complete non-retrieval body retains `lines` where no other field supplies its
|
|
|
2467
2539
|
navigable extent. None of these spellings changes acquisition, delivery,
|
|
2468
2540
|
curation, admission, or immutable evidence.
|
|
2469
2541
|
|
|
2470
|
-
Field absence carries defaults: `origin` is omitted for the owning model, `source` for the owning worker, and `status` for a routine 200. An emission row renders its author, the turn's producer, as its `origin` ({§emission-row}).
|
|
2542
|
+
Field absence carries defaults: `origin` is omitted for the owning model, `source` for the owning worker, and `status` for a routine 200, regardless of operation. Every non-200 stays explicit. This presentation rule does not alter message completion, durable results or protocol responses. An emission row renders its author, the turn's producer, as its `origin` ({§emission-row}). A present authored aside appears as `aside`. Every row's accounting follows {§packet-token-accounting}.
|
|
2471
2543
|
|
|
2472
|
-
Authored `metadata` retains its opaque ordered block strings under {§scheme-metadata-modifier}; COPY/MOVE pair them as `{from,to}`. Packet rendering does not interpret scheme options or discard malformed input from a failed operation.
|
|
2544
|
+
Authored `metadata` retains its opaque ordered block strings under {§scheme-metadata-modifier}, as stored under {§log-sensitive-request-evidence}; COPY/MOVE pair them as `{from,to}`. Packet rendering does not interpret scheme options or discard malformed input from a failed operation.
|
|
2473
2545
|
|
|
2474
2546
|
- §operation-resource-receipt A result's nonempty `resource` address remains visible in receipt metadata when distinct from its `path` and `stream`. It identifies returned material without replacing the addressed operand or injecting that material into context; ordinary READ acquires it.
|
|
2475
2547
|
- §packet-attachment-parts A successful READ of an attachable resource carries projection facts with its
|
|
@@ -2502,7 +2574,7 @@ Authored `metadata` retains its opaque ordered block strings under {§scheme-met
|
|
|
2502
2574
|
records the exact READ coordinates sent without controlling retention. Missing immutable bytes are an
|
|
2503
2575
|
internal integrity failure, never silently dropped content. No ejection message or permanent teaching is
|
|
2504
2576
|
added. These stable curation weights are not provider-token measurements ({§tokenomics-render-weight-budget}).
|
|
2505
|
-
- §packet-token-accounting Every row reports one `tokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, facts, visible body
|
|
2577
|
+
- §packet-token-accounting Every row reports one `tokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, facts, visible body, selected native attachment and any assistant operation owned by that receipt ({§paired-receipt}). Packet accounting measures each actual message once. The completed record is measured to a fixed point, including the accounting field itself. Hidden text is not charged; metadata-only rows still have a reclaimable charge. Source/FIND-item `tokens` measure source content, not the observation's context footprint. A FIND's nonzero `itemsTokenTotal` weighs the complete matched set; a nonzero `returnedItemsTokenTotal` appears only when the returned page differs. All use stable curation weights, not provider tokens or dollars. Native component accounting follows {§packet-attachment-parts}; ordinary addressability and truthful errors follow {§log-wire-format}.
|
|
2506
2578
|
|
|
2507
2579
|
### §retrieval-packet-metadata READ/FIND packet metadata
|
|
2508
2580
|
|
|
@@ -2563,9 +2635,9 @@ Eligible programs supply {§emission-history}; every source remains readable reg
|
|
|
2563
2635
|
| Body | Frozen at announcement: the canonical rendering ({§statement-rendering}) of the admitted content statements, each whole in a closed fence, text beside them as the NOTEs it became ({§outside-text}). All heading operands, scopes, metadata, patterns and asides remain. Unadmitted forms are absent; a recovered native call ({§native-tool-calls}) appears as the operation it was read as; an operation whose receipt failed stays. Reasoning operations retain their own source and normal receipts, never an assistant-content copy. No body text is inspected for nested operations. |
|
|
2564
2636
|
| Wire | The record appears in the log; its complete program supplies the readback projection in {§emission-history}. The frozen body and immutable `ops://` source keep every operation and body ({§turn-source-resources}); an explicit READ returns them. |
|
|
2565
2637
|
| Stability | The projection is fixed from its first appearance, never aged or resized under budget pressure. Already frozen announcements and historical request captures are not rewritten. |
|
|
2566
|
-
| Presentation | Born folded:
|
|
2567
|
-
| Accounting | The row's `tokens` charges only its
|
|
2568
|
-
| Curation | Curated whole ({§log-kill-scope}):
|
|
2638
|
+
| Presentation | Born folded: its log record shows its header. Its operations replay together before their receipts under {§emission-history}; NOTE has its ordinary receipt coordinate, not a legend entry. |
|
|
2639
|
+
| Accounting | The row's `tokens` charges only its own record. Each operation's first surviving receipt owns its replay charge ({§paired-receipt}). An explicit source READ has its own ordinary charge. |
|
|
2640
|
+
| Curation | Curated whole ({§log-kill-scope}): an unscoped KILL retires it. A line scope on its exact coordinate is 422 `emission-curated-whole`, whose recovery names the unscoped KILL; a sweep whose scope would only trim it leaves it intact. |
|
|
2569
2641
|
| Schema | Migration 12 admits `kind="emission"` only on this shape: one per turn, the turn's newest row when written, frozen, and curated whole; it backfills no announcement for earlier turns. FORK copies it with the inherited turns, still naming its writer. |
|
|
2570
2642
|
| Echoes | A worker that repeats the heading in its own text is tolerated ({§fabricated-log-entry}); the digest counts the echoes. |
|
|
2571
2643
|
|
|
@@ -3011,7 +3083,12 @@ The notice creates no state and does not demand another final reply.
|
|
|
3011
3083
|
§worker-obligations A worker holds its unresolved children, its open non-detached
|
|
3012
3084
|
streams, and the messages it sent to other workers that await completion while the
|
|
3013
3085
|
recipient's loop is live (`worker_obligations`); `loop_obligations` names them per
|
|
3014
|
-
loop.
|
|
3086
|
+
loop. Each obligation records the operation that opened it, by identity: a stream its
|
|
3087
|
+
execution ({§subscriptions-causal-resource}), a message the SEND, WORK or FORK that sent it,
|
|
3088
|
+
by the row that operation writes; a child's loop is opened by its first message's. The
|
|
3089
|
+
opening row names what it opened: an execution's `attrs.stream`, a message's `attrs.message`
|
|
3090
|
+
(its durable address). A message holds, and its reply reaches, the worker whose own operation
|
|
3091
|
+
sent it; a message a person, a client or the daemon sends opens no worker's obligation. The packet's Open Work list, WAIT, completion and drain wake settlement use
|
|
3015
3092
|
that same durable liveness: a worker that messaged another worker parks on an
|
|
3016
3093
|
authored WAIT until the completion arrives ({§message-completion}), and with no WAIT
|
|
3017
3094
|
joins that work with the bounded park rather than concluding idle.
|
|
@@ -3119,7 +3196,7 @@ accounting and model-visible failure evidence remain separately owned by
|
|
|
3119
3196
|
The strike sends no notice of its own: the turn records one `_plurnk`
|
|
3120
3197
|
error row, `422` `The turn performed no operation.`, which rides the next packet's errors like
|
|
3121
3198
|
any failure ({§operation-result-uniform-error-channel}); the threshold terminal still says why ({§engine-rails}).
|
|
3122
|
-
An empty turn uses its exact text as the cycle fingerprint ({§engine-cycle-evidence});
|
|
3199
|
+
An empty turn the output allowance did not cut uses its exact text as the cycle fingerprint ({§engine-cycle-evidence});
|
|
3123
3200
|
different empty programs are not a repeated cycle merely because neither contained
|
|
3124
3201
|
operations. Lost-boundary handling remains {§unparsed-tail-boundary}; no confirmation
|
|
3125
3202
|
token or private retry is invented here.
|
|
@@ -3325,8 +3402,12 @@ unchanged for proposal policy, application, stream registration, and
|
|
|
3325
3402
|
effect-qualified hold policy. The post-acceptance materialization path never
|
|
3326
3403
|
triggers reclassification.
|
|
3327
3404
|
|
|
3328
|
-
§exec-registry-resolves The
|
|
3329
|
-
the workspace snapshot.
|
|
3405
|
+
§exec-registry-resolves The execution's `runtime` selects an executor from
|
|
3406
|
+
the workspace snapshot at its dispatch point. Explicit invocations parse without requiring
|
|
3407
|
+
registration ({§executor-heading}); a preceding accepted subsystem command may publish the
|
|
3408
|
+
name they invoke in that same program ({§functionality-model-mutation}). A failed or rejected
|
|
3409
|
+
command grants nothing; subsequent invocations resolve the unchanged snapshot, unless the
|
|
3410
|
+
producer requested fail-on-error and stopped the program. Installed siblings form the immutable base:
|
|
3330
3411
|
they are discovered and probed at startup, and availability is cached.
|
|
3331
3412
|
Workspace Functionality providers may atomically overlay additional names under
|
|
3332
3413
|
{§module-workspace-capabilities}; a name has one owner within a workspace, while
|
|
@@ -3362,7 +3443,7 @@ execution is refused `scope-unsupported` (400).
|
|
|
3362
3443
|
| `lifetime` | The spawn |
|
|
3363
3444
|
| ------------ | --------- |
|
|
3364
3445
|
| a duration | Aborted at the deadline — a bounded reap, polite signal then SIGKILL after `PLURNK_SERVICE_EXEC_KILL_GRACE_MS` — and the stream is stamped **504** `execution-timeout`, distinct from a deliberate kill (499) or a clean exit (200): `` Execution of '*runtime*' outlived its *lifetime* lifetime. `` |
|
|
3365
|
-
| `loop` (absent) | Loop-life bounded: reaped on every loop terminal except 202, the background-stream behavior. |
|
|
3446
|
+
| `loop` (absent) | Loop-life bounded: reaped on every loop terminal except 202, the background-stream behavior. A person's client operation answers once its command starts, so its execution belongs to the operation instead: it outlives the operation loop's 200 and is reaped when that operation is cancelled or the daemon stops ({§connection-lifecycle}). |
|
|
3366
3447
|
| `turn` | Reaped at the worker's next pre-turn via the registry abort, before the turn's own spawns, so it never survives into the subsequent turn; its terminal output surfaces born visible like any close ({§exec-stream}). |
|
|
3367
3448
|
| `detached` | Outlives its loop's terminal, 200 included. It never binds to the loop's teardown and is nobody's obligation — completion is not gated by it, WAIT does not park on it, optimistic settlement looks past it — and it ends only by KILL, the worker's total reap, or daemon shutdown; its late conclusion surfaces without opening a loop. |
|
|
3368
3449
|
|
|
@@ -3408,18 +3489,53 @@ lifecycle teardown still reaps its work. No new delegation semantics follow.
|
|
|
3408
3489
|
|
|
3409
3490
|
§worker-auto-name **Automatic names are eight random lowercase hexadecimal
|
|
3410
3491
|
characters**, e.g. `worker://ab3d5678`; a colliding draw is retried. All unnamed
|
|
3411
|
-
workers use this allocator, including WORK, FORK, clients, and
|
|
3492
|
+
workers use this allocator, including WORK, FORK, clients, and model workers.
|
|
3412
3493
|
Names encode neither machine identity nor topology or role; those remain
|
|
3413
3494
|
separate durable fields.
|
|
3414
3495
|
Automatic names never reuse an existing literal. Name selection and worker
|
|
3415
3496
|
creation share one atomic claim: concurrent allocations receive distinct
|
|
3416
|
-
addresses
|
|
3417
|
-
worker. Generated addresses appear in ordinary operation receipts and child
|
|
3497
|
+
addresses. Generated addresses appear in ordinary operation receipts and child
|
|
3418
3498
|
inventory; allocation never rewrites the submitted operation's target.
|
|
3419
3499
|
|
|
3420
|
-
§workspace-
|
|
3421
|
-
|
|
3422
|
-
|
|
3500
|
+
§workspace-name **A workspace's name is an opaque handle; its identity is its id; its folder is a
|
|
3501
|
+
separate fact.** A name is a unique non-empty string compared by exact bytes, the same comparison for
|
|
3502
|
+
creation, rename and lookup; nothing in it is normalized or decoded, and it authorizes
|
|
3503
|
+
nothing: only `projectRoot` selects a folder, and a workspace may have none. Admission, at creation
|
|
3504
|
+
and rename, refuses these spellings as `name-invalid` (400):
|
|
3505
|
+
|
|
3506
|
+
- ASCII decimal digits alone (`[0-9]+`, including zero and leading zeroes): reserved for workspace IDs.
|
|
3507
|
+
- Text that is not well-formed Unicode: an unpaired surrogate has no encoding.
|
|
3508
|
+
- A slash-delimited segment exactly `.` or `..`: a URL parser resolves it away, encoded or not.
|
|
3509
|
+
|
|
3510
|
+
None is repaired or resolved. Every other spelling
|
|
3511
|
+
is admitted as written: spaces, Unicode, `~`, `@`, `%` and a literal `%2E%2E`, query and fragment
|
|
3512
|
+
punctuation, and a dot within a segment (`.config`, `file.txt`, `...`). A refused rename changes
|
|
3513
|
+
nothing. Admission governs new names only: a workspace already carrying a refused spelling keeps it,
|
|
3514
|
+
its id, its folder and its workers, stays listed and attachable, and is renamed like any other. Rename
|
|
3515
|
+
({§methods-workspace-rename}) changes the name alone; {§methods-workspace-attach} selects an existing workspace. With a project
|
|
3516
|
+
root and no name, `workspace.create` names the workspace after the root, the root's path with the daemon's
|
|
3517
|
+
home abbreviated to `~` (`~` for the home itself, the absolute path outside it), and selects the
|
|
3518
|
+
workspace of that name when one exists instead of creating a second, so two default launches on the
|
|
3519
|
+
same project and daemon share one workspace and a concurrent pair resolves to one. The root is resolved
|
|
3520
|
+
before it is named, so a root spelled with `.` or `..` components derives the name of the folder it
|
|
3521
|
+
reaches and no default is ever refused; a root that is not well-formed Unicode is
|
|
3522
|
+
`project-root-invalid` (400), since it names no folder. The default is a
|
|
3523
|
+
convention, not a mapping: a renamed workspace is not re-selected by its old default, and a workspace may
|
|
3524
|
+
carry any name over any folder. An explicit name that exists is `409 name-conflict`, never a
|
|
3525
|
+
selection.
|
|
3526
|
+
|
|
3527
|
+
§workspace-label **A folder's display spelling is the daemon's.** Wherever the application port
|
|
3528
|
+
returns a workspace's folder it returns its label beside it: `projectLabel` on a client envelope and
|
|
3529
|
+
the `workspace/created` notice, `project_label` on a `listWorkspaces` row. The label is the folder as
|
|
3530
|
+
a default name spells it: the daemon's home is `~`, a path beneath it `~/<rest>`, and any other path,
|
|
3531
|
+
one that merely shares the home's prefix included, its absolute spelling. A workspace without a
|
|
3532
|
+
folder has a null label. It is derived from the folder on every read and never stored, and it never
|
|
3533
|
+
rewrites a name, so a client compares a workspace's name with its label by equality and derives
|
|
3534
|
+
neither from its own home.
|
|
3535
|
+
|
|
3536
|
+
§workspace-auto-name **A workspace with neither name nor project root gets five alphanumeric characters, at least one a letter.** Such a `workspace.create` draws uniformly from the {§line-anchors} alphabet `0-9A-Za-z` using a cryptographic source, redrawing digit-only names and collisions. No prefix, timestamp, or origin marker: a name never encodes where a workspace came from.
|
|
3537
|
+
|
|
3538
|
+
§exec-readpure-ungated A `read` runtime (observes external state, e.g. search) or `pure` runtime (no observable effect, e.g. `:memory:` sqlite) is side-effect-free → **auto-run**: no proposal, no human gate, no notification. Core persists the prepared operation before applying it; that write-ahead staging has no resolution waiter and therefore cannot enter proposal discovery ({§proposal-list}). Admission does not determine settlement: external executions background and stream, while subsystem commands settle under {§functionality-model-mutation}. Both expose output through ordinary environment observation ({§exec-stream}), not a second inline body path.
|
|
3423
3539
|
|
|
3424
3540
|
§effect-policy-tunable **Effect admission is one knob per effect.**
|
|
3425
3541
|
`PLURNK_SERVICE_EFFECT_HOST`, `PLURNK_SERVICE_EFFECT_READ` and
|
|
@@ -3435,7 +3551,7 @@ two states and no others:
|
|
|
3435
3551
|
|
|
3436
3552
|
| state | what the model receives |
|
|
3437
3553
|
|---|---|
|
|
3438
|
-
| active | nothing in the Log. The `##
|
|
3554
|
+
| active | nothing in the Log. The `## Open Work` stream pointer reports timing and channel activity ({§child-orientation}); the model READs any range it wants, and every READ of a stream channel carries `terminal: false` while it runs and `terminal: true` once it has concluded, so an empty page is never mistaken for a finished command that printed nothing. |
|
|
3439
3555
|
| terminal | ONE `origin=_plurnk` READ at the execution's channel address, born visible, that is exactly a markerless READ of the channel — its bounded first page ({§read-selection-projection}, the whole channel when it fits, the channel's own mimetype), the `range` or `region`, terminal status and Problem, `terminal: true`, and any producer-supplied integer `exitCode`. The packet writes the read resource as its operand, exactly as an explicit READ does ({§log-address-metadata}). |
|
|
3440
3556
|
|
|
3441
3557
|
§stream-observation-result **One liveness fact.** The durable READ result owns
|
|
@@ -3450,7 +3566,7 @@ publishes only once subscription settlement has installed its terminal result;
|
|
|
3450
3566
|
until then the stream is still in flight and publishes on the turn after it settles.
|
|
3451
3567
|
|
|
3452
3568
|
§exec-concurrency **Bounded admission per workspace (#389).** At most
|
|
3453
|
-
`PLURNK_SERVICE_EXEC_CONCURRENCY` executions run at once in one workspace (`-1`
|
|
3569
|
+
`PLURNK_SERVICE_EXEC_CONCURRENCY` external executions run at once in one workspace (`-1`
|
|
3454
3570
|
unbounded); the scope is the workspace, so neither delegation nor later turns
|
|
3455
3571
|
bypass it and no other workspace can starve it. Every admitted execution still creates its
|
|
3456
3572
|
entry, channels, and open subscription before its receipt returns, so queued work is
|
|
@@ -3462,7 +3578,8 @@ it: an immediate slot is `200 { outcome: "started" }`; delayed work is
|
|
|
3462
3578
|
current truth. Admission is FIFO within the workspace; queue residence does not consume
|
|
3463
3579
|
the execution timeout; a KILL while queued never invokes the executor and concludes the
|
|
3464
3580
|
stream as any KILL does ({§stream-control}). The scheduler is the exec scheme's; the knob is the
|
|
3465
|
-
service's ({§operator-config}), fail-hard on any other value.
|
|
3581
|
+
service's ({§operator-config}), fail-hard on any other value. Ordered subsystem
|
|
3582
|
+
commands use {§functionality-model-mutation}, not this background-work queue.
|
|
3466
3583
|
|
|
3467
3584
|
§exec-stream-page **An unrequested delivery never exceeds the retrieval page.** The
|
|
3468
3585
|
terminal observation is the same page a markerless READ returns, whatever the
|
|
@@ -3477,7 +3594,7 @@ records stop at the last complete line that fits, or at an exact Unicode region
|
|
|
3477
3594
|
when even the first line exceeds the character bound. Explicit READ scopes stay exact.
|
|
3478
3595
|
|
|
3479
3596
|
The durable per-subscription, per-channel cursor records the size last reported
|
|
3480
|
-
to the model — by the
|
|
3597
|
+
to the model — by the Open Work stream pointer while active, by the terminal
|
|
3481
3598
|
observation at close — so the pointer can state growth and no partial document
|
|
3482
3599
|
or record ever reaches the model. The terminal observation and its cursor
|
|
3483
3600
|
transition commit atomically. A concluded stream lands one conclusion row per
|
|
@@ -3621,6 +3738,9 @@ Core derives the contracts-owned `ProposalProjection` from the durable proposed
|
|
|
3621
3738
|
| Projection field | Durable authority |
|
|
3622
3739
|
| --------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
3623
3740
|
| identity | proposed log row `id`, `worker_id`, `loop_id`, `turn_id`, and validated `op` |
|
|
3741
|
+
| `worker` | the worker's name ({§worker-name}) |
|
|
3742
|
+
| `coordinate` | the row's log coordinate `L/T/S` ({§methods-log-coordinate}) |
|
|
3743
|
+
| `expiresAt` | when the operator's decision deadline cancels the proposal ({§proposal-timeout-cancels}); absent for an untimed wait |
|
|
3624
3744
|
| `target` | canonical `{ scheme, authority, pathname }` from `attrs.proposalTarget` for staged COPY/MOVE, otherwise the log row target |
|
|
3625
3745
|
| `body` | proposed operation result `rx.body`; absent means the empty review body |
|
|
3626
3746
|
| `attrs` | proposed log row `attrs` object |
|
|
@@ -3674,6 +3794,7 @@ operation, message sender, or attrs.
|
|
|
3674
3794
|
| Runtime bookkeeping | reject, `runtime_bookkeeping` |
|
|
3675
3795
|
| Server `accept` | accept |
|
|
3676
3796
|
| Server `reject` | reject, `policy_veto` |
|
|
3797
|
+
| Server `review`, a person's client operation ({§connection-lifecycle}) | accept, `client_operation` |
|
|
3677
3798
|
| Server `review`, owner implements `request_approval` | review |
|
|
3678
3799
|
| Server `review`, owner has no reviewer | reject, `no_review_channel` |
|
|
3679
3800
|
|
|
@@ -3681,8 +3802,9 @@ Core selects the disposition once for the pending gate. Its live event and
|
|
|
3681
3802
|
reconnect projection use that same decision. Automatic settlement precedes
|
|
3682
3803
|
observational notification; an observer failure cannot change authority or orphan
|
|
3683
3804
|
a waiter. Invalid configuration is diagnosed at the proposal boundary without
|
|
3684
|
-
substituting authority ({§configuration-repair-path}).
|
|
3685
|
-
|
|
3805
|
+
substituting authority ({§configuration-repair-path}). A person's client operation is
|
|
3806
|
+
already that person's decision, so review never routes it; the server's `accept` and
|
|
3807
|
+
`reject` still apply.
|
|
3686
3808
|
|
|
3687
3809
|
§runtime-bookkeeping-policy Runtime bookkeeping cannot acquire new authority.
|
|
3688
3810
|
Generated reference publication and audit narration have no reviewer and do not
|
|
@@ -4126,6 +4248,13 @@ systemd user unit. Installation and enablement are explicit operator actions;
|
|
|
4126
4248
|
package installation performs neither. The template documents executable-path
|
|
4127
4249
|
and environment adjustments instead of introducing a service-management command.
|
|
4128
4250
|
|
|
4251
|
+
§nginx-example The service package ships `plurnk.nginx.conf`, an example nginx front, beside
|
|
4252
|
+
the unit and under the same terms. Hardening belongs there, not in the daemon: TLS, security
|
|
4253
|
+
headers, sign-in throttling by real client address and an optional network allow-list. The
|
|
4254
|
+
daemon answers every caller at the address it used ({§http-request-origin}); behind TLS it is
|
|
4255
|
+
told the public origin (`PLURNK_AGUI_ISSUER`, and `PLURNK_A2A_ENDPOINT_URL` when it exposes A2A),
|
|
4256
|
+
which it cannot see.
|
|
4257
|
+
|
|
4129
4258
|
Model selection uses one selector vocabulary in `ProviderRegistry` ({§provider-instantiation}). `PLURNK_MODEL_<alias>=<provider>/<model-id>` optionally declares a friendly route and tuning scope; `PLURNK_MODEL=<selector>` selects either that alias or an exact provider/model route. `PLURNK_MODEL_CHILD=<selector>` uses the same vocabulary for the default child provider; unset means inherit the spawning loop's provider. Operator selections and alias declarations live in `.env`, not `.env.defaults`.
|
|
4130
4259
|
|
|
4131
4260
|
Each knob's value lives on its panel and nowhere else (`plurnk-service config defaults` prints them all); this table says what the service's knobs mean.
|
|
@@ -4135,7 +4264,7 @@ Each knob's value lives on its panel and nowhere else (`plurnk-service config de
|
|
|
4135
4264
|
| `PLURNK_SERVICE_DB_PATH` | SQLite file path; an explicit non-empty value overrides the derived default. |
|
|
4136
4265
|
| `PLURNK_SERVICE_SQLITE_SYNCHRONOUS` | Connection-time WAL durability: `OFF`, `NORMAL`, `FULL` or `EXTRA` ({§db-durability}). |
|
|
4137
4266
|
| `PLURNK_SERVICE_SHARE_FOLDER` | Parent of the shares written when no folder is named ({§share-folder}); empty is `$XDG_STATE_HOME/plurnk/shares`. |
|
|
4138
|
-
| §operator-config-shared-keys `PLURNK_HOST`, `PLURNK_PORT` | The daemon-owned listener's bind address and TCP port; modules mount their paths on that one listener ({§http-host}). **A key the daemon and its clients both read has a shared owner**: `@plurnk/plurnk-contracts` declares these
|
|
4267
|
+
| §operator-config-shared-keys `PLURNK_HOST`, `PLURNK_PORT`, `PLURNK_AUTH`, `PLURNK_SECRET`, `PLURNK_PASS` | The daemon-owned listener's bind address and TCP port; modules mount their paths on that one listener ({§http-host}). The daemon's authentication posture, the operator's client secret and the operator's browser sign-in ({§credential-authority}, {§agui-oauth}). **A key the daemon and its clients both read has a shared owner**: `@plurnk/plurnk-contracts` declares these, and the optional `PLURNK_AGUI_URL`, on its own panel, the one package every side depends on. The daemon folds it like any installed member's, a client folds it beneath its own, and so neither holds the other's default. The service's `--host`, `--port`, `--auth`, `--user` and `--pass` flags are generated from that panel. |
|
|
4139
4268
|
| §operator-config-git-ceiling `PLURNK_SERVICE_GIT_ALLOWED` | Hard service ceiling: only `1` admits Git membership and status; every other value denies them. |
|
|
4140
4269
|
| §operator-config-file-create-scope `PLURNK_SERVICE_FILE_CREATE_SCOPE` | Hard file-creation ceiling: `none < root < namespace`. `none` denies new filesystem files, `root` admits only paths inside `project_root`, and `namespace` also admits canonical outside-root paths. Existing-member writes are unaffected. |
|
|
4141
4270
|
| `PLURNK_SERVICE_FILE_MATERIALIZE_MAX_BYTES` | Byte ceiling in `1..104857600` for one workspace-file snapshot ({§membership-materialization-limit}). |
|
|
@@ -4322,7 +4451,7 @@ flowchart LR
|
|
|
4322
4451
|
release --> warm["Bounded warm grace / idle LRU"]
|
|
4323
4452
|
warm -->|new demand| lease
|
|
4324
4453
|
warm -->|idle bound| cool["Deactivate providers;<br/>withdraw runtime projections"]
|
|
4325
|
-
interface -->|
|
|
4454
|
+
interface -->|daemon call| calls
|
|
4326
4455
|
calls --> core["Core state and orchestration"]
|
|
4327
4456
|
core --> events["subscribeToEvents<br/>(workspaceId, event, payload)"]
|
|
4328
4457
|
events --> interface
|
|
@@ -4336,7 +4465,8 @@ modules in registration order. The daemon's listener is bound before durable adm
|
|
|
4336
4465
|
({§module-http-mounts}). Persisted workspaces with
|
|
4337
4466
|
no durable work stay passive until first demand; activation publishes their
|
|
4338
4467
|
complete capabilities and documentation before the demanding operation
|
|
4339
|
-
proceeds.
|
|
4468
|
+
proceeds. An owner's arrival is such a demand ({§methods-workspace-activate}), so a first prompt
|
|
4469
|
+
waits only for what remains of it. `setup` is the readiness boundary for every capability registered
|
|
4340
4470
|
with Core: recovery may demand a workspace provider before `start`. Requests on
|
|
4341
4471
|
the listener remain unavailable until it is admitted; a module opens any other exterior
|
|
4342
4472
|
ingress only after recovery. No
|
|
@@ -4377,11 +4507,12 @@ An invalid module object, factory result or lifecycle member is an implementatio
|
|
|
4377
4507
|
not configuration, and fails loudly. What a module contributes registers through its owning public
|
|
4378
4508
|
interfaces and is released during {§module-lifecycle} resource teardown.
|
|
4379
4509
|
|
|
4380
|
-
§module-shutdown-order `Daemon.stop()` first rejects new capability demand
|
|
4510
|
+
§module-shutdown-order `Daemon.stop()` first rejects new capability demand, cancels preparation
|
|
4511
|
+
under {§functionality-preparation-cancellation}, and
|
|
4381
4512
|
aborts proposals, branches, derivations, and worker scopes. It begins module
|
|
4382
4513
|
`stop()` calls in reverse registration order without serially awaiting them,
|
|
4383
4514
|
so every producer is asked to stop even if another stalls. Core settles drains,
|
|
4384
|
-
capability publications, module producers, streaming producers, derivations,
|
|
4515
|
+
whole workspace activation and cooling transitions, capability publications, module producers, streaming producers, derivations,
|
|
4385
4516
|
mimetypes, schemes, and the final worker-settlement barrier while observers
|
|
4386
4517
|
remain subscribed. Only then does it begin and join module `close()` calls in
|
|
4387
4518
|
reverse order. Failures do not skip later phases and join one shutdown aggregate.
|
|
@@ -4392,6 +4523,9 @@ After asynchronous selection, the supervisor rechecks shutdown before creating
|
|
|
4392
4523
|
a drain or installing a timer; parked-loop wake mutations also recheck worker
|
|
4393
4524
|
cancellation under {§worker-lifecycle-durable-disposition}.
|
|
4394
4525
|
The database remains available through observer closure and final maintenance.
|
|
4526
|
+
Residency transitions are retained from stop admission through settlement, including failed
|
|
4527
|
+
transitions; one failure does not stop the join of other workspaces. Expected preparation
|
|
4528
|
+
cancellation is not a shutdown failure; genuine preparation and cleanup failures are.
|
|
4395
4529
|
The shared deadline bounds every phase, including observer delivery; forced
|
|
4396
4530
|
shutdown may therefore lose notifications and reports the unfinished phase.
|
|
4397
4531
|
|
|
@@ -4412,7 +4546,8 @@ flowchart LR
|
|
|
4412
4546
|
stop[Begin stop] --> abort[Abort core producers]
|
|
4413
4547
|
stop --> moduleStop[Begin reverse module stop]
|
|
4414
4548
|
abort --> drains[Settle worker drains]
|
|
4415
|
-
drains -->
|
|
4549
|
+
drains --> residency[Join workspace transitions<br/>and capability publications]
|
|
4550
|
+
residency --> joined[Settle module producers]
|
|
4416
4551
|
moduleStop --> joined
|
|
4417
4552
|
joined --> producers[Settle streaming producers]
|
|
4418
4553
|
producers --> resources[Dispose derivations,<br/>mimetypes, and schemes]
|
|
@@ -4429,6 +4564,8 @@ published module contract.
|
|
|
4429
4564
|
|
|
4430
4565
|
| Setup function | Contract |
|
|
4431
4566
|
|---|---|
|
|
4567
|
+
| `credentials` | The {§credential-authority} on the setup seam: the issuing module publishes its face (`publish({ issuer })`) before any module starts, and every module may `verify` through it. |
|
|
4568
|
+
| `httpAddress()` | The address of the listener the host bound before any module set up ({§http-host}), as on the application port: the issuing module derives its issuer from it at setup, so the face it publishes answers from publication. |
|
|
4432
4569
|
| `registerRuntimes([{ decl, executor, availability, scheme? }, ...])` | Validates the complete canonical tag set under {§executor-runtime-declaration}, then publishes every process-wide executor and optional claimed scheme facet atomically. |
|
|
4433
4570
|
| §module-workspace-provider `registerWorkspaceCapabilityProvider(namespaceOwner, provider)` | Registers one extension-unique Functionality provider. `activate({ workspaceId, retain })` reconstructs the workspace snapshot; idempotent `deactivate({ workspaceId })` releases process resources. Core coalesces demand and supplies residency leases for work that outlives its caller. |
|
|
4434
4571
|
| §module-workspace-state `readWorkspaceModuleState(workspaceId, namespaceOwner)` | Reads one nullable JSON state value per workspace and provider. Core owns storage and lifecycle; the provider owns its schema. Store symbolic credential references, not copied secrets. A worker-scoped family's coordinator reads and replaces the same shape per worker in `worker_module_state` ({§functionality-scope}). |
|
|
@@ -4471,7 +4608,10 @@ Settling the coordinator includes accepted refreshes waiting for that gate,
|
|
|
4471
4608
|
not only work already inside a family lane.
|
|
4472
4609
|
Explicit client mutations use `try` and fail 409 before effects while the workspace is held.
|
|
4473
4610
|
Refused mutations reserve no queue position; a client retry is a new admission.
|
|
4474
|
-
An accepted
|
|
4611
|
+
An accepted operation mutation uses `wait`: its turn yields the shared lease
|
|
4612
|
+
at that operation, awaits exclusive publication, and reacquires its lease before
|
|
4613
|
+
dispatching the next operation. Concurrent publishers yield independently; no
|
|
4614
|
+
publisher waits while retaining the shared lease it needs released. Activation and turn-admission refresh use `none` inside
|
|
4475
4615
|
their already-held demand boundary. Providers reject replacement while active
|
|
4476
4616
|
requests, input exchanges, or Tasks depend on the old snapshot; infrastructure
|
|
4477
4617
|
watches may be replaced. These are concurrency constraints, not creator privileges.
|
|
@@ -4493,8 +4633,11 @@ bound. Concurrent demand coalesces; cooling never closes a leased connection.
|
|
|
4493
4633
|
|
|
4494
4634
|
Cooling withdraws live capability and releases process resources at the
|
|
4495
4635
|
workspace boundary. Durable configuration, history, and saved entries remain.
|
|
4496
|
-
New demand reconstructs the one shared snapshot. Shutdown cancels warm timers
|
|
4497
|
-
and
|
|
4636
|
+
New demand reconstructs the one shared snapshot. Shutdown cancels warm timers and preparation,
|
|
4637
|
+
refuses new leases before database access, and joins whole activation and cooling transitions
|
|
4638
|
+
before releasing resources. An interrupted acquisition rejects with `AbortError`, never a usable
|
|
4639
|
+
lease. Cooling and activation cleanup remain joined, not cancelled.
|
|
4640
|
+
Cooling failures are reported; demand awaiting that transition receives its failure, not a lease.
|
|
4498
4641
|
|
|
4499
4642
|
§module-workspace-residency-facet **Residency is the workspace's; processes are
|
|
4500
4643
|
one family's facet.** The workspace is the lease unit, and every family's
|
|
@@ -4673,7 +4816,7 @@ state without demand; `workspace/preparation` broadcasts
|
|
|
4673
4816
|
| Boundary | Visible state |
|
|
4674
4817
|
|---|---|
|
|
4675
4818
|
| Preparation begins | Family, `phase: preparing`, `alias: null`, UTC `since` |
|
|
4676
|
-
| Adapter
|
|
4819
|
+
| Adapter reports the aliases it is preparing | One activity per alias, each keeping the `since` it began; an alias leaves when a later report omits it, so aliases prepared at once are listed together |
|
|
4677
4820
|
| Prepared candidate enters publication | `phase: publishing`, `alias: null` |
|
|
4678
4821
|
| Commit, rejection, or rollback settles | Family removed; empty array means no preparation |
|
|
4679
4822
|
|
|
@@ -4784,7 +4927,8 @@ reserved or masked name is no resource. The family's manager exposes it as the f
|
|
|
4784
4927
|
the value its commands receive now, FIND lists the names in effect and a pattern on it matches
|
|
4785
4928
|
values, COPY carries a value out. The manager's own output streams, eight hexadecimal characters
|
|
4786
4929
|
({§execution-output-identity}), stay the executor's. A write is the Worker's own layer, never the
|
|
4787
|
-
workspace's or the operator's
|
|
4930
|
+
workspace's or the operator's (the runtime worker keeps none, so a person's write is the workspace's,
|
|
4931
|
+
{§actor-boundary-client-operations}): EDIT sets the whole value through the family's `replace` for the
|
|
4788
4932
|
Worker, and KILL retires the name from the Worker's commands — `remove` for an entry the Worker
|
|
4789
4933
|
owns, which restores an inherited value, `disable` for an inherited one, which keeps its
|
|
4790
4934
|
definition. Admission is the family's ({§env-functionality}) and its refusal is the operation's
|
|
@@ -4796,7 +4940,9 @@ effect is `entry-not-found` (404) on READ and KILL alike.
|
|
|
4796
4940
|
§functionality-scope **A family declares its supported scopes.** Skills, MCP, members
|
|
4797
4941
|
and outbound A2A describe what exists in a **workspace**: a capability, resident or installable,
|
|
4798
4942
|
that every Worker there shares. Environment describes how one **Worker** works — context rather
|
|
4799
|
-
than capability — with worker overrides above workspace defaults.
|
|
4943
|
+
than capability — with worker overrides above workspace defaults. A context family's definitions are read where they
|
|
4944
|
+
are used, so a change at either scope holds nothing resident and takes no workspace exclusivity: it serializes on
|
|
4945
|
+
the family's lane. The adapter declares
|
|
4800
4946
|
`scopes` (absent means `["workspace"]`; the first is the model default), and the
|
|
4801
4947
|
coordinator keys durable state and the locally-owned `origin`
|
|
4802
4948
|
by it: a workspace-scoped family's own entries carry origin `workspace`, a worker-scoped
|
|
@@ -4883,20 +5029,27 @@ A family that ships no file has a header-only document. Registration also
|
|
|
4883
5029
|
validates the adapter's taught `add` example against the `add` input schema it
|
|
4884
5030
|
teaches, so a wrong example fails boot rather than the model.
|
|
4885
5031
|
|
|
4886
|
-
§functionality-model-mutation **
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
5032
|
+
§functionality-model-mutation **Subsystem commands settle in authored order.**
|
|
5033
|
+
Every manager verb, including inspection, completes before dispatch proceeds;
|
|
5034
|
+
later operations observe earlier successful configuration changes. These
|
|
5035
|
+
core-owned commands use ordinary proposals and durable execution outputs, but
|
|
5036
|
+
not the background-execution slot pool. Preparation and publication share the
|
|
5037
|
+
family's serialized lane. Resident publication uses the lease handoff in
|
|
5038
|
+
{§module-workspace-quiescence}; context-only families retain their existing
|
|
5039
|
+
scope-local serialization. The invoking operation and its output remain pending
|
|
5040
|
+
until settlement; they never acknowledge merely starting a future commit.
|
|
4890
5041
|
It then reports `active`, `unavailable`, or `authorization-required`, or the exact
|
|
4891
5042
|
publication failure. Resource readiness is not execution liveness: a mutation's
|
|
4892
5043
|
`202 authorization-required` body remains exact, while the finished manager
|
|
4893
5044
|
execution closes with `200`. It does not wait for sign-in. A preparation failure may publish enabled-but-unavailable
|
|
4894
|
-
state for other mutations, but `replace` rejects it ({§functionality-replacement}); a publication failure never reports a successful mutation.
|
|
4895
|
-
waiting, and result observation use the ordinary execution lifecycle, without a
|
|
5045
|
+
state for other mutations, but `replace` rejects it ({§functionality-replacement}); a publication failure never reports a successful mutation. Result observation uses the ordinary execution lifecycle, without a
|
|
4896
5046
|
separate deferred-commit queue. An explicit client action publishes now, rejects
|
|
4897
5047
|
a failed preparation, and fails 409 while the workspace is held
|
|
4898
5048
|
({§module-workspace-quiescence}). Rejecting a proposal prepares, persists, and
|
|
4899
|
-
publishes nothing.
|
|
5049
|
+
publishes nothing. Cancellation removes queued publication and aborts preparation
|
|
5050
|
+
before publication; an already-started atomic publication is joined, never
|
|
5051
|
+
abandoned partway through. Shell commands, remote tools, WORK/FORK and streaming
|
|
5052
|
+
READ retain their deliberately asynchronous contracts ({§op-synchronous}).
|
|
4900
5053
|
|
|
4901
5054
|
## §methods Application interface
|
|
4902
5055
|
|
|
@@ -4908,35 +5061,36 @@ Core's behavior behind them.
|
|
|
4908
5061
|
| Area | Function | Core contract |
|
|
4909
5062
|
|---------------------------------------------------|----------|---------------|
|
|
4910
5063
|
| §methods-event-subscribe Events | `subscribeToEvents(handler) -> unsubscribe` | Subscribes to the raw event source in {§notifications}. A subscriber failure is logged and cannot re-enter engine control flow. |
|
|
5064
|
+
| §methods-credentials Credentials | `credentials` | The {§credential-authority}: `issue`, `verify`, `consume`, `revokeFamily`, `onRevoked` and the sign-ins of a subject by `sessions` ({§credential-sessions}), and a module's own client by `registerClient`, `client` and `authenticateClient` ({§credential-module-client}); one in-memory authority per daemon, offered to every module on the seam. |
|
|
4911
5065
|
| §proposal-list Proposals | `pendingProposals(workspaceId)` | Intersects durable proposed rows with the lifecycle owner's live resolution waiters, then returns their validated {§proposal-projection}; persistence alone cannot advertise an unresolvable client interrupt. |
|
|
4912
5066
|
| §methods-proposal-resolve Proposals | `resolveProposal(logEntryId, resolution, owner)` | Validates the workspace-scoped owner before delivering one accept, reject, or cancel decision. Unknown, mismatched, and already-resolved identities fail without consuming the gate; the adapter authenticates its owner identity. |
|
|
4913
5067
|
| §client-interaction-list Client interactions | `pendingClientInteractions(workspaceId)` | Intersects durable interaction rows with their live operation waiters and returns the contracts-owned projection; a row alone is not a resumable interaction. |
|
|
4914
5068
|
| §methods-client-interaction-resolve Client interactions | `resolveClientInteraction(interactionId, resolution, respondent, message?)` | Validates the recorded recipient before delivering one resolved payload or cancellation. Unknown, mismatched, and already-resolved identities fail before affecting an operation. |
|
|
4915
5069
|
| §methods-loop-run Loops | `runLoop({ workspaceId, workerId, loopId?, prompt, source?, maxTurns?, openPaths?, selector?, childSelector? })` | Validates a model worker and persists the request with the effective turn ceiling, then returns an immediate status-100 acknowledgement with `loopId` and `action`. An explicit Loop recipient follows {§loop-addressed-admission}. A trusted adapter may identify the prompt's causal actor with one canonical `source`; ordinary clients cannot author it through their protocol surface. Messages carry no approval authority. The exact terminal result arrives only through `loop/terminated`; parking and resuming do not replace the loop. |
|
|
4916
|
-
| §
|
|
4917
|
-
| §methods-
|
|
4918
|
-
| Client
|
|
4919
|
-
| §methods-log-read Reads | `readLog({ workspaceId, workerId, ...coordinate })` | Ownership-checks the worker, then reads by ids, recency, or the complete `loopSeq`/`turnSeq`/`sequence` display coordinate. An omitted `limit` is `PLURNK_SERVICE_LOG_READ_PAGE`, and any `limit` is capped at `PLURNK_SERVICE_LOG_READ_MAX`. |
|
|
5070
|
+
| §message-idempotency Message admission | `messageAdmission({ workspaceId, address, body })` | A client message's address is its idempotency key ({§message-source-scheme}): `new` when nothing is accepted there, `accepted` when the same body is, so a repeat attaches to what the message started instead of admitting it twice; another body under an accepted address is refused, 422 `message-address-reused`, creating nothing. `runLoop` refuses every repeat it is handed: other words 422 `message-address-reused`, the same words 409 `message-already-accepted`, a duplicate racing the original. |
|
|
5071
|
+
| §methods-loop-cancel Loops | `cancelDrain(workerId, reason?)`; `cancelWorker({ workspaceId, workerId, reason? })`; `cancelLoop({ workspaceId, loopId, reason? })` | `cancelDrain` begins durable structured cancellation and reports whether process-local work existed when called; queued or parked durable work is still terminalized when it is `false`. The ownership-bounded `cancelWorker` awaits that same tree cancellation and stream reap, so an exterior protocol can project the settled durable result without polling or fabricating state. `cancelLoop` cancels exactly one client operation ({§connection-lifecycle}): its dispatch while that runs, and every attached execution its rows started that still runs, then reports whether any of it was running; nothing else in the runtime worker shares its scope. |
|
|
5072
|
+
| §methods-op-mirror Client dispatch | `dispatchClientAction({ workspaceId, actor, contextWorkerId?, statements, onLoop? })` | Dispatches already-parsed grammar statements as one client operation of `actor` ({§connection-lifecycle}), in the workspace's Functionality ({§actor-boundary-attached-functionality}), reading `log:///` in `contextWorkerId`'s log ({§actor-boundary-client-operations}). `onLoop` hears the operation's loop before any statement runs. Every statement is an ordered client/operation turn, and every committed `log/entry` is emitted before the promise resolves. Core exposes no per-op method family. |
|
|
5073
|
+
| §methods-log-read Reads | `readLog({ workspaceId, workerId, ...coordinate })` | Ownership-checks the worker, then reads by ids, recency, or the complete `loopSeq`/`turnSeq`/`sequence` display coordinate, newest first. `sinceId` keeps rows after an id and `beforeId` rows before one, so a reader pages back through the whole log one page at a time. An omitted `limit` is `PLURNK_SERVICE_LOG_READ_PAGE`, and any `limit` is capped at `PLURNK_SERVICE_LOG_READ_MAX`. |
|
|
4920
5074
|
| §methods-entry-read Reads | `readEntry({ workspaceId, workerId, target, channel?, offset? })` | Resolves the selector from that worker's perspective and returns {§entry-read-result}, either complete or as one channel suffix, without creating action evidence. |
|
|
4921
5075
|
| Providers | `listProviders()` | Lists configured aliases with provider/model identity, active state, and the effective provider-derived `inputCapacity` when known. |
|
|
4922
5076
|
| Model catalog | `listModels(query)` | Returns one validated bounded {§model-catalog-wire} page under {§model-catalog}; performs no provider request or selection. |
|
|
4923
5077
|
| Client capabilities | `listClientDisplayCapabilities()` | Composes sorted scheme declarations ({§manifest-client-display}) followed by sorted MIME declarations ({§mimetype-client-display}) into the validated shared wire ({§client-display-capabilities}). The internal `exec` operation handler is excluded; its addressable runtime-tag scheme faces remain included. |
|
|
4924
|
-
| §methods-workspace-create Workspace lifecycle | `createWorkspace({ name?, projectRoot?, settings? })` | Validates `settings` through {§operator-config-workspace-settings}, creates the
|
|
4925
|
-
| §methods-workspace-attach Workspace lifecycle | `attachWorkspace({ workspaceId
|
|
4926
|
-
| §methods-
|
|
4927
|
-
| §methods-
|
|
5078
|
+
| §methods-workspace-create Workspace lifecycle | `createWorkspace({ name?, projectRoot?, settings? })` | Validates `settings` through {§operator-config-workspace-settings}, creates the workspace and returns its client envelope, minting no worker, and emits global `workspace/created`; with a project root and no name it names and selects the workspace under {§workspace-name}, emitting `workspace/created` only for a workspace it created. Creation and attachment are passive: neither starts derivation nor activates workspace Functionality. `projectRoot` is established here or the workspace remains headless. |
|
|
5079
|
+
| §methods-workspace-attach Workspace lifecycle | `attachWorkspace({ workspaceId } \| { name } \| { projectRoot })` | Exactly one selector returns an existing workspace's client envelope, minting and activating nothing. Names are literal lookups, including previously admitted names. An absolute project root selects its folder-derived default name ({§workspace-name}), not a workspace by its stored folder. An absent target is `404 workspace-not-found`; ambiguous or absent selectors are `400 identity-invalid`. It retains no caller or transport binding state. |
|
|
5080
|
+
| §methods-workspace-activate Workspace lifecycle | `activateWorkspace({ workspaceId })` | Makes the demand a turn makes, without a turn: a cold workspace activates and publishes its complete capabilities; a concurrent demand shares that one activation; it resolves once the workspace is active and leaves it warm under `PLURNK_SERVICE_WORKSPACE_WARM_MS`. Creation and attachment stay passive; an owner's arrival calls it ({§agui-owner-activation}). |
|
|
5081
|
+
| §methods-worker-create Workspace lifecycle | `createWorker({ workspaceId, name?, parentWorkerId?, owner? })` | Creates a distinct model-origin worker with empty history. A root may name a registered owner; a child names its parent and inherits ownership. Supplying both parent and owner is invalid ({§worker-owner-creation}). |
|
|
4928
5082
|
| Worker ownership | `registerWorkerOwner(workspaceId, { address, tools, interactive })` | Declares or replaces an owner's supported client-tool names and whether a person attends it, in that workspace; `_plurnk` is reserved. |
|
|
4929
5083
|
| Worker ownership | `claimWorkerOwner({ workspaceId, workerId, owner })` | Claims only runtime-owned work under {§worker-ownership}, returning its effective owner. The owner must already be registered. |
|
|
4930
5084
|
| Runtime actor | `ensureRuntimeWorker(workspaceId)` | Returns the workspace's `_plurnk` actor, creating it if absent; it always retains runtime ownership. |
|
|
4931
|
-
| Workspace lifecycle | `forkWorker({ workspaceId, workerId, name? })` | Creates a child worker that branches the source worker's history while sharing workspace state. |
|
|
4932
|
-
| §methods-workspace-rename Workspace metadata | `renameWorkspace(workspaceId, name)` | Changes only the
|
|
4933
|
-
| §methods-workspace-rollback Workspace files | `rollback({ workspaceId, workerId,
|
|
4934
|
-
| §methods-workspace-prompts Workspace metadata | `listPrompts(workspaceId, limit?, workerId?)` | Returns nonempty loop-seed prompts a client addressed to the workspace's model workers, newest-first; `workerId` narrows to one worker. Authorship is the seed message's address ({§message-arrival}): a worker-issued seed (WORK, FORK, SEND to a worker) has none and is never history, whichever worker it seeded; a client prompt at a forked
|
|
4935
|
-
| Workspace metadata | `listWorkspaces()`, `workspaceDerivationStatus(...)` | Reads current workspace identity and derivation progress. |
|
|
4936
|
-
| §methods-worker-read Worker topology | `readWorker({ workspaceId, identity })` | Ownership-bounds an exact id-or-name lookup and returns one durable Worker projection or `null` under {§application-worker-observation}. Supplying both identities or neither is invalid. |
|
|
4937
|
-
| §methods-worker-list Worker topology | `listWorkers(workspaceId, query?)` | Returns the workspace's durable Worker projections under {§application-worker-observation}. The origin filter is exact; an explicitly present `parentWorkerId` filters roots (`null`) or one immediate parent (id), while omission returns every lineage position. Each projection carries `kind` (`
|
|
4938
|
-
| §methods-worker-loops Loop lifecycle | `listWorkerLoops({ workspaceId, workerId })` | Ownership-checks the Worker and returns its Loops in sequence order under {§application-loop-observation}, including the validated exact terminal result when one exists. It performs no scheduling or event replay. |
|
|
4939
|
-
| §methods-worker-
|
|
5085
|
+
| Workspace lifecycle | `forkWorker({ workspaceId, workerId, name? })` | Creates a child worker that branches the source worker's history while sharing workspace state. The source is a model worker, else `409 model-worker-required` ({§machine-processes-worker-origin}). |
|
|
5086
|
+
| §methods-workspace-rename Workspace metadata | `renameWorkspace(workspaceId, name)` | Changes only the workspace's unique mutable name, under the admission of {§workspace-name}; workers, log, and membership remain intact, and a refused name changes nothing. |
|
|
5087
|
+
| §methods-workspace-rollback Workspace files | `rollback({ workspaceId, workerId, actor, to })` | Reverses `workerId`'s settled file mutations after its coordinate `to` as one client operation of `actor` ({§rollback}, {§connection-lifecycle}); answers a `RollbackReport`. |
|
|
5088
|
+
| §methods-workspace-prompts Workspace metadata | `listPrompts(workspaceId, limit?, workerId?)` | Returns nonempty loop-seed prompts a client addressed to the workspace's model workers, newest-first; `workerId` narrows to one worker. Authorship is the seed message's address ({§message-arrival}): a worker-issued seed (WORK, FORK, SEND to a worker) has none and is never history, whichever worker it seeded; a client prompt at a forked model worker is. An omitted limit is `PLURNK_SERVICE_PROMPTS_PAGE`. |
|
|
5089
|
+
| Workspace metadata | `listWorkspaces()`, `workspaceDerivationStatus(...)` | Reads current workspace identity, with each folder and its label ({§workspace-label}), and derivation progress. |
|
|
5090
|
+
| §methods-worker-read Worker topology | `readWorker({ workspaceId, identity })` | Ownership-bounds an exact id-or-name lookup and returns one durable Worker projection or `null` under {§application-worker-observation}. Supplying both identities or neither is invalid. Any non-empty name is looked up, the runtime worker's `_plurnk` included: the lookup is no minting door ({§worker-name-minting}). |
|
|
5091
|
+
| §methods-worker-list Worker topology | `listWorkers(workspaceId, query?)` | Returns the workspace's durable Worker projections under {§application-worker-observation}. The origin filter is exact; an explicitly present `parentWorkerId` filters roots (`null`) or one immediate parent (id), while omission returns every lineage position. Each projection carries `kind` (`root` for a worker with no parent, `fork` for a child with a fork boundary, `work` for any other child) and `lifecycle`, the representative work loop's status through {§loop-lifecycle-vocabulary} (`idle` with no work loop), so a directory row shows the same lifecycle glyph the bound worker's own status gauge shows; clients infer neither (#523). |
|
|
5092
|
+
| §methods-worker-loops Loop lifecycle | `listWorkerLoops({ workspaceId, workerId })` | Ownership-checks the Worker and returns its Loops in sequence order under {§application-loop-observation}, including the validated exact terminal result when one exists, and each Loop's `invocation`: `{ workerId, address }`, the Worker and the log address ({§methods-invocation}) of the operation that sent the Loop's first message ({§worker-obligations}), or null when a person, a client, a peer or the daemon sent it. It performs no scheduling or event replay. |
|
|
5093
|
+
| §methods-worker-accounting Worker spend | `workerAccounting({ workspaceId, workerId })` | Ownership-checks the Worker and returns the {§provider-accounting} projection of every settled request on any loop the Worker or a descendant of it (`parent_worker_id`, to any depth) ran, since the Worker began: its own spend and its delegations', the same tree the turn cap counts ({§turn-cap-counts-the-tree}). Nothing spent is explicit zero. One loop's own accounting stays {§notifications-loop-terminated}'s. Derived from the request ledger on every read ({§tokenomics-provider-usage}); no rollup, no second store. |
|
|
4940
5094
|
| Extension actions | `listModuleActions()`, `invokeModuleAction(name, params, context)` | Lists setup-registered `{ name, scope, inputSchema, outputSchema }` descriptors in sorted order. Invocation requires a context matching the registered scope; missing names, forged scope, and missing workspace identity fail before the owner runs. Handler values remain opaque to core. |
|
|
4941
5095
|
|
|
4942
5096
|
§methods-loop-run-fold-consistency **A folded prompt cannot silently reconfigure
|
|
@@ -4972,19 +5126,17 @@ If an unpublished message is promoted into subsequent work under
|
|
|
4972
5126
|
{§message-loop-containment}, its selected paths travel with it.
|
|
4973
5127
|
|
|
4974
5128
|
§methods-rebind **Binding belongs to the client-interface module.** Core's
|
|
4975
|
-
workspace lifecycle calls return exactly the workspace
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
§
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
name lies outside `WORKER_NAME`), insert a non-mintable spelling, or make the
|
|
4987
|
-
client registry diverge from model worker control.
|
|
5129
|
+
workspace lifecycle calls return exactly the workspace (`workspaceId`,
|
|
5130
|
+
`workspaceName`, `projectRoot`, `projectLabel`); they carry no worker, bound-worker
|
|
5131
|
+
or operation-loop binding. Core retains no connection, thread, or current-workspace
|
|
5132
|
+
mapping. A module may replace its own binding with a later create or attach result
|
|
5133
|
+
without requiring a new transport; it resolves the bound worker separately, while
|
|
5134
|
+
each client operation allocates its own administrative loop under {§connection-lifecycle}.
|
|
5135
|
+
|
|
5136
|
+
§methods-worker-name-admission **Worker-name admission.** Worker
|
|
5137
|
+
creation and fork apply {§worker-name-minting} before lookup or creation. A client therefore cannot forge or resume the runtime actor (its
|
|
5138
|
+
name lies outside `WORKER_NAME`) or create a worker under a spelling model worker control
|
|
5139
|
+
could not mint.
|
|
4988
5140
|
|
|
4989
5141
|
§capability-admission **One admission path owns external authority.** Core
|
|
4990
5142
|
derives one or more `CapabilityDescriptor` demands from each routed statement,
|
|
@@ -5021,7 +5173,7 @@ resolver.** Workspace capability actions return the contracts-owned
|
|
|
5021
5173
|
their normalized effective intersection. The same resolver governs dispatch
|
|
5022
5174
|
and packet shaping. Replacement preserves unrelated workspace settings. Before their next operation
|
|
5023
5175
|
or observation, existing workers reconcile generated references against it. It requires no selected
|
|
5024
|
-
|
|
5176
|
+
bound worker and returns the complete fresh projection.
|
|
5025
5177
|
|
|
5026
5178
|
§question-tool **The native request-user-input tool.** Core registers one
|
|
5027
5179
|
in-process `question` runtime at boot and offers it only to a worker whose owner
|
|
@@ -5084,7 +5236,7 @@ packets or state snapshots.
|
|
|
5084
5236
|
owns one durable model, persisted as a nullable `model_routes` foreign key.
|
|
5085
5237
|
Concurrent first selections of the same resolved tuple share one identity;
|
|
5086
5238
|
an insertion conflict returns the existing route without changing its fields.
|
|
5087
|
-
|
|
5239
|
+
A root model worker is seeded once — from an explicit selection, else
|
|
5088
5240
|
the daemon default — and never re-seeded from a later default change. A
|
|
5089
5241
|
deliberately modelless daemon leaves the worker unset and rejects model work
|
|
5090
5242
|
until an explicit selection. Starting a loop snapshots the worker's resolved
|
|
@@ -5093,7 +5245,7 @@ continue from the loop snapshot and never re-resolve through the alias
|
|
|
5093
5245
|
cascade. A WORK/FORK child copies the spawning loop's effective spawn model
|
|
5094
5246
|
(spawn override ?? model) onto the new worker by value at creation; it retains
|
|
5095
5247
|
no live link and begins with no override, so a later parent change affects
|
|
5096
|
-
only that worker's future loops and descendants.
|
|
5248
|
+
only that worker's future loops and descendants. The runtime worker and other
|
|
5097
5249
|
Plurnk-owned bookkeeping workers run no model loops and own no model
|
|
5098
5250
|
selection; the model, spawn-override, and effort controls refuse them with
|
|
5099
5251
|
`409 model-worker-required` before any policy row is initialized or written. An explicit model, spawn-override, or effort change while
|
|
@@ -5175,26 +5327,40 @@ beside database ids, so a client can render and resolve the logical `L/T/S`
|
|
|
5175
5327
|
coordinate without fetching all rows and matching locally.
|
|
5176
5328
|
|
|
5177
5329
|
§methods-log-entry-wire **Log entry wire fidelity.** `readLog` and `log/entry`
|
|
5178
|
-
preserve causal `source` and
|
|
5330
|
+
preserve causal `source` and the row's lifecycle `state` (`proposed` while a proposal awaits its
|
|
5331
|
+
decision, then `resolved`, `failed` or `cancelled`), and parse the row's JSON `attrs` into structured data.
|
|
5179
5332
|
Client interfaces do not reconstruct these fields from operation or origin.
|
|
5180
5333
|
|
|
5181
5334
|
§methods-readable-reasoning **Readable provider reasoning remains derived
|
|
5182
|
-
provider evidence.** On
|
|
5183
|
-
project
|
|
5184
|
-
`reasoning` field
|
|
5335
|
+
provider evidence.** On a turn's first model operation row, `readLog` and `log/entry`
|
|
5336
|
+
project the turn's nonempty admitted `packet.assistant.reasoning` as the optional
|
|
5337
|
+
`reasoning` field, from the row's first announcement; no other row repeats it. Beside it,
|
|
5338
|
+
`reasoning_model_call_id` and `reasoning_request_sequence` name the request that streamed it (the
|
|
5339
|
+
turn's accepted model call and that call's response request), so a client can match the reasoning it
|
|
5340
|
+
watched stream; history a FORK inherited was streamed by no request of this worker and names none. The durable packet remains the sole stored representation;
|
|
5185
5341
|
core does not copy readable reasoning into log attributes or bodies. A turn
|
|
5186
5342
|
without readable reasoning omits the field.
|
|
5187
5343
|
|
|
5188
|
-
§
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5344
|
+
§methods-invocation **A row that discharges an obligation names the operation that opened it.** `readLog`
|
|
5345
|
+
and `log/entry` project `invocation`, the log address of that operation ({§worker-obligations}), on every
|
|
5346
|
+
row that discharges one, so a client pairs the answer with its call without matching addresses:
|
|
5347
|
+
|
|
5348
|
+
| Discharging row | Its invocation |
|
|
5349
|
+
|---|---|
|
|
5350
|
+
| A stream observation ({§exec-stream}) | The execution, as its subscription recorded it ({§subscriptions-causal-resource}) |
|
|
5351
|
+
| A child's conclusion ({§env-delta-child-termination}) | The operation that sent the first message of the concluded loop |
|
|
5352
|
+
| A completion reply delivered to the sender ({§message-reply-delivery}), including {§message-abandonment} | The operation that sent the message it completed |
|
|
5353
|
+
|
|
5354
|
+
Each is derived from what the row records: the publication it advanced, or the occurrence it materialized.
|
|
5355
|
+
A message names an invocation only to the worker whose operation sent it; history a FORK inherited names the
|
|
5356
|
+
same invocation as its original, at the same coordinate. The row's own `source` keeps its attribution meaning
|
|
5357
|
+
({§env-delta-attribution}). An obligation whose opener was not recorded, and every other row, omits the field.
|
|
5358
|
+
|
|
5359
|
+
§methods-answering **A reply names the operation that sent the message it answers.** `readLog` and `log/entry`
|
|
5360
|
+
project `answering` on a reply delivered to the worker whose operation sent the message ({§message-reply-delivery}):
|
|
5361
|
+
that operation's log address, whether the reply completes the message or reports progress. A completion reply
|
|
5362
|
+
names the same address as its `invocation`. A reply to a message this worker did not send, such as another actor
|
|
5363
|
+
answering a message in this worker's inbox, omits the field, as does every other row.
|
|
5198
5364
|
|
|
5199
5365
|
### §notifications Core events
|
|
5200
5366
|
|
|
@@ -5202,13 +5368,13 @@ adding a loop to it. LOOK text anchors resolve through the same
|
|
|
5202
5368
|
|--------------------------------------------------------------|---------|------------|
|
|
5203
5369
|
| §notifications-operation-event `operation/event` | `ApplicationOperationEvent`: `{ workerId, loopId, turnId, sequence, origin, projectRoot, statement, phase, result? }` | One admitted dispatch starts before capability/proposal admission and settles after its durable receipt(s). Only the settled phase has `result`, the exact returned operation result. Resource fan-out is one dispatch ({§bulk-resource-targeting}); BARE starts before prompt preparation and settles after ordered receipt persistence. Automatic stream observations and log writes are not dispatches. An asynchronous executor's successful dispatch does not assert process exit. An internal exception that prevents settlement has no invented result event. |
|
|
5204
5370
|
| §notifications-log-entry-notify `log/entry` | `{ entry: LogEntry }` | A non-proposed `log_entries` row is committed, or a proposed row reaches terminal settlement under {§proposal-proposed-hidden}. Delivery completes before a later event may terminate the owning Loop. |
|
|
5205
|
-
| §notifications-loop-terminated `loop/terminated` | `{ workerId, loopId, result, hitMaxTurns, turnIds, usage: { accounting, curationWeight, curationBudget, contextTokens, contextCapacity, meta }, attributions }` | One loop reaches a terminal state. `result` is the exact universal operation result, including its RFC 9457 Problem Details on failure. `accounting` is the loop's contracts-owned {§provider-accounting}; the two curation facts and two physical-context facts follow {§tokenomics-client-gauge}; `meta` is that turn's opaque provider bag. `attributions` is the sorted union of exact provider-request evidence ({§attribution}), separate from accounting. Worker and loop are an inseparable owning coordinate. |
|
|
5371
|
+
| §notifications-loop-terminated `loop/terminated` | `{ workerId, loopId, result, hitMaxTurns, turnIds, usage: { accounting, curationWeight, curationBudget, contextTokens, contextCapacity, meta }, attributions, terminatedAt }` | One loop reaches a terminal state. `terminatedAt` is the loop's own stamp in Unix milliseconds, the one a projection reads ({§application-loop-observation}). `result` is the exact universal operation result, including its RFC 9457 Problem Details on failure. `accounting` is the loop's contracts-owned {§provider-accounting}; the two curation facts and two physical-context facts follow {§tokenomics-client-gauge}; `meta` is that turn's opaque provider bag. `attributions` is the sorted union of exact provider-request evidence ({§attribution}), separate from accounting. Worker and loop are an inseparable owning coordinate. |
|
|
5206
5372
|
| §notifications-loop-packet `loop/packet` | `{ workerId, loopId, packetCount }` | One provider packet becomes durable. `packetCount` is the exact count of packet-bearing turns in that Loop; packetless producer turns and physical provider retries never contribute. |
|
|
5207
5373
|
| §notifications-loop-proposal `loop/proposal` | contracts-owned `ProposalProjection` | Dispatch pauses on a durable 202 proposal. `disposition` is the sole authority for whether a client presents review UI; live and reconnect share {§proposal-projection}. |
|
|
5208
5374
|
| §notifications-loop-interaction `loop/interaction` | contracts-owned `ClientInteractionProjection` | An operation is paused on client input. Live delivery and reconnect discovery share {§client-interactions}; workspace scope remains the event envelope. |
|
|
5209
5375
|
| §notifications-workspace-created `workspace/created` | `{ id, name, projectRoot }` | A workspace is created. This is the only current global event. |
|
|
5210
5376
|
| `workspace/preparation` | `{ workspaceId, preparation: FunctionalityPreparationActivity[] }` | Workspace capability preparation changes; snapshot and clearing semantics follow {§functionality-preparation-visibility}. |
|
|
5211
|
-
| §notifications-stream-event-on-channel-change `stream/event` | `{ entryId, workerId, target, channel, state, contentLength, mimetype?, loop_seq?, turn_seq?, sequence? }` | Channel content grows or channel state transitions. `workerId` is the initiating actor used for
|
|
5377
|
+
| §notifications-stream-event-on-channel-change `stream/event` | `{ entryId, workerId, target, channel, state, contentLength, mimetype?, loop_seq?, turn_seq?, sequence? }` | Channel content grows or channel state transitions. `workerId` is the initiating actor used for routing to the bound worker, never entry ownership or access control. `target` is the canonical resource URI. Optional numeric coordinates identify the causal log item, independently of that URI. Core-managed channel writes include the current stored `mimetype`, which may change per call ({§channel-mimetype}); the generic extension notification capability does not require it. It carries metadata, not content; consumers read bytes by canonical workspace address. |
|
|
5212
5378
|
| §notifications-stream-concluded `stream/concluded` | `{ entryId, workerId, target, subscriptionId, scheme, result, summary, wakeAction, loop_seq?, turn_seq?, sequence? }` | A subscription closes. `workerId` identifies the initiating actor; `target` is the canonical resource URI. Optional numeric fields identify the causal log item, never parsed from `target`. Exact result truth is preserved. `wakeAction` reports `wake-pending` before settlement, `no-op-active-loop` when work is already executing, `no-loop`, or `skipped-aborted`/`skipped-cancelled` for an aborted worker scope. A pending wake predicts neither execution nor recipient count; subsequent ordinary loop events report actual progress and completion. |
|
|
5213
5379
|
| §notifications-notice-event `notice/event` | `{ workerId, loopId, notice: Notice }` | A transient observation or progress notice occurs. `workerId` owns loop activity; only workspace derivation progress uses `null` with `loopId=0`. It cannot alter durable history, scheduling, recovery, or model-visible failure truth. |
|
|
5214
5380
|
| §notifications-outside-event `outside/event` | `{ workerId, loopId, turnId, coordinate, text, tokens }` | An admitted emission carried text outside every operation ({§outside-text}): once per admitted emission, the exact stored text, its packet weight, and the turn's `<worker>-<loop>-<turn>` coordinate. It is transient presentation evidence; the turn's `outside` source remains the durable authority. |
|
|
@@ -5231,21 +5397,66 @@ the authoritative scope and is `null` only for a global event. Core does not
|
|
|
5231
5397
|
mutate each payload to repeat it. A transport module stamps that scope onto any
|
|
5232
5398
|
outward envelope that requires it and owns workspace fan-out.
|
|
5233
5399
|
|
|
5234
|
-
### §
|
|
5400
|
+
### §worker-external-reference External worker references
|
|
5401
|
+
|
|
5402
|
+
An adapter's `(namespace, reference)` identifies one durable model worker. Both strings are opaque
|
|
5403
|
+
to core; protocol syntax belongs to the adapter. `readWorkerReference` returns its workspace and
|
|
5404
|
+
worker IDs or null, without creating anything. `ensureWorkerReference` returns the same identity,
|
|
5405
|
+
atomically creating an ordinary folderless workspace and root model worker if absent. Names follow
|
|
5406
|
+
{§workspace-auto-name} and {§worker-auto-name}; no owner is claimed and no work starts.
|
|
5235
5407
|
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
one
|
|
5241
|
-
|
|
5242
|
-
interrupt/resume, but those records preserve durable evidence rather than
|
|
5243
|
-
defining the public client lifecycle. Multiple client actors have distinct workers.
|
|
5408
|
+
The association is immutable while its worker exists. Concurrent allocation creates exactly one
|
|
5409
|
+
workspace, worker and association; failure leaves none. Renaming a workspace, changing approval
|
|
5410
|
+
ownership, reconnecting or restarting does not change the association. Worker deletion removes it
|
|
5411
|
+
through its foreign key. Namespaces isolate adapter identities, not authorization: the daemon
|
|
5412
|
+
remains one trust domain. `listWorkerReferences` inspects one namespace's references to a worker,
|
|
5413
|
+
bounded by its workspace. New workspace creation emits the ordinary `workspace/created` event.
|
|
5244
5414
|
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5415
|
+
### §connection-lifecycle Client operations
|
|
5416
|
+
|
|
5417
|
+
A worker is a model's identity. A person's client operations (an execution, typed
|
|
5418
|
+
statements, a rollback's compensations) are the workspace's, so each journals in the
|
|
5419
|
+
workspace's runtime worker `_plurnk`, created when absent, and executes in the workspace's
|
|
5420
|
+
Functionality ({§actor-boundary-attached-functionality}). Binding a workspace mints nothing.
|
|
5421
|
+
|
|
5422
|
+
| | A model worker | A client operation in `_plurnk` |
|
|
5423
|
+
|---|---|---|
|
|
5424
|
+
| Who acted | the worker | the person its loop names ({§actor-boundary-client-operations}) |
|
|
5425
|
+
| Who answers its proposals | the worker's owner reviews them | nobody: it is that person's decision already ({§proposal-disposition}) |
|
|
5426
|
+
| Who answers its clarifications | its owner, while it can ({§client-interaction-routing}) | nobody: the runtime's owner receives no client tool, so an interaction the operation needs fails at once as unsupported |
|
|
5427
|
+
| What is cancelled and observed together | the worker's loops | the operation's own administrative loop |
|
|
5428
|
+
| What its `env:///` means | its own layer, above the workspace's | the workspace's layer; `_plurnk` keeps none ({§env-scheme}) |
|
|
5429
|
+
| Whose voice its messages carry | its own | the person's, as a thread message's is |
|
|
5430
|
+
| Whose log its log addresses and FORK mean | its own | the worker the person acts for: read and branched, never curated |
|
|
5431
|
+
| What its WORK starts | its own child | a root worker the person owns |
|
|
5432
|
+
|
|
5433
|
+
One client operation owns one administrative loop, and its statements become ordered
|
|
5434
|
+
`client` operation turns inside it. The loop carries its own cancellation scope, and
|
|
5435
|
+
nothing else in `_plurnk` (another person's operation, the daemon's narration, a hosted A2A
|
|
5436
|
+
task) shares it. `cancelLoop` cancels that operation alone: a dispatch still running
|
|
5437
|
+
ends `operation-cancelled`, as does its loop, and every attached execution its rows started
|
|
5438
|
+
that still runs is reaped ({§worker-lifecycle-total-reap}), its stream concluding aborted even
|
|
5439
|
+
after the loop settled. A detached execution is nobody's obligation, and `cancelLoop` leaves it
|
|
5440
|
+
running. Shutdown cancels every operation the same way.
|
|
5441
|
+
|
|
5442
|
+
`runLoop` targets a model worker with `origin="model"`. A packet renders only that
|
|
5443
|
+
worker's private log, so a client operation's rows are structurally absent from every
|
|
5444
|
+
model's packet ({§actor-boundary-isolation}); a person reaches a model through a message.
|
|
5445
|
+
|
|
5446
|
+
§actor-boundary-client-operations **A client operation acts on workspace resources, attributes messages
|
|
5447
|
+
to its person, and reads a log in the context of one worker.** Its loop's `promptSource`
|
|
5448
|
+
({§methods-worker-loops}) is the acting person's canonical address, the form arrivals use
|
|
5449
|
+
({§message-causal-source}); the daemon's own loops in `_plurnk` have none. Its rows are acts, not arrivals:
|
|
5450
|
+
they keep writer `origin: "client"`, so a person never writes as the runtime
|
|
5451
|
+
({§scheme-surface-writableby-403}), and `source` null, so a person's SEND replies and completes as any
|
|
5452
|
+
author's does. Acting for no worker, an operation names no log: `log:///` is 404 `log-unaddressed` and
|
|
5453
|
+
FORK is 404 `fork-unaddressed`.
|
|
5454
|
+
|
|
5455
|
+
| Frame | Covers | So |
|
|
5456
|
+
|---|---|---|
|
|
5457
|
+
| Workspace resources | files, executions, Functionality, `env:///` | `_plurnk` keeps no layer of its own, so a person's `env:///` reads and writes the workspace's ({§env-scheme}) |
|
|
5458
|
+
| The person's voice | messages and delegated prompts | a message the operation delivers (SEND, or WORK to a worker that exists) arrives from the person, as a thread message does; WORK to a new worker starts a root model worker the person owns, its first prompt from them |
|
|
5459
|
+
| The worker it acts for | `log:///`, and the log FORK branches | READ and FIND answer from that worker's log as it reads it; FORK branches it as `forkWorker` does, its task from the person; curating the log is a client write it refuses ({§scheme-surface-writableby-403}) |
|
|
5249
5460
|
|
|
5250
5461
|
---
|
|
5251
5462
|
|
|
@@ -5272,12 +5483,12 @@ adjacent nonempty sections of the same remaining role form one message. With an
|
|
|
5272
5483
|
| Message | Role | Content |
|
|
5273
5484
|
|:--|:--|:--|
|
|
5274
5485
|
| 1 | `system` | the system slot, as rendered |
|
|
5275
|
-
| 2 | `user` | initial retained log records
|
|
5276
|
-
| 3… | alternating `assistant`, `user` |
|
|
5486
|
+
| 2 | `user` | initial retained log records, up to the first replayed turn's first surviving receipt |
|
|
5487
|
+
| 3… | alternating `assistant`, `user` | a replayed turn's operations, then that turn's receipts and the records that follow, up to the next replayed turn; native parts remain beside their READ records ({§packet-attachment-parts}) |
|
|
5277
5488
|
| last | `user` | remaining log records and the current-status footer, from Worker through Open Messages and optional Recap |
|
|
5278
5489
|
|
|
5279
5490
|
Without selected programs, the log and footer coalesce into one user message: system + user.
|
|
5280
|
-
Each
|
|
5491
|
+
Each turn's operations precede its first surviving receipt.
|
|
5281
5492
|
Log records retain their order; interpolation never groups or relocates their bodies.
|
|
5282
5493
|
Stored sections retain their original roles and order: reading evidence
|
|
5283
5494
|
never converts an earlier request into a different envelope.
|
|
@@ -5285,7 +5496,7 @@ never converts an earlier request into a different envelope.
|
|
|
5285
5496
|
The digest's packet artifacts record the sections, and `.wire.json` reconstructs their text-message
|
|
5286
5497
|
envelope ({§share-packet-names}); it is not a serialized HTTP capture.
|
|
5287
5498
|
|
|
5288
|
-
### §emission-history
|
|
5499
|
+
### §emission-history A turn's operations, then its results
|
|
5289
5500
|
|
|
5290
5501
|
| Concern | Contract |
|
|
5291
5502
|
|---|---|
|
|
@@ -5293,15 +5504,27 @@ envelope ({§share-packet-names}); it is not a serialized HTTP capture.
|
|
|
5293
5504
|
| Selection | `latest` considers only the immediately preceding completed model inference turn in this loop, never falling back to an older eligible program. `all` considers every completed model inference turn in this loop, in ascending turn order. |
|
|
5294
5505
|
| Eligibility | An admitted content program with no syntax errors and an active emission row. Rejected attempts, syntactically partial emissions, empty or reasoning-only turns, initialization and other loops supply none. Runtime failures do not disqualify an admitted program. |
|
|
5295
5506
|
| Vocabulary | Executor identities come from that turn's admitted operation evidence ({§packet-stored-shape}), not the current registry. Disabling or removing a runtime never changes its admitted history. |
|
|
5296
|
-
|
|
|
5297
|
-
|
|
|
5298
|
-
| Placement |
|
|
5299
|
-
|
|
|
5300
|
-
|
|
|
5301
|
-
|
|
|
5507
|
+
| Association | Each dispatched content operation records its ordinal in the turn's frozen canonical program. Resource fan-out retains that ordinal on every concrete receipt. Reasoning operations, arrivals and runtime observations have no content ordinal. Never infer association from matching bodies, paths, or row proximity; older rows without this provenance remain self-describing. |
|
|
5508
|
+
| Content | Replay each associated canonical operation, including its complete body, in its own closed fence; a turn's fences are separated by one blank line. No placeholders, body redaction, preview, or inspection of body text for nested operations. A log-curation KILL's distilled body belongs to its independent NOTE, not to its replay. Reasoning operations remain in their own source and receipts. |
|
|
5509
|
+
| Placement | Put one assistant message holding the turn's surviving operations, in program order, immediately before the turn's first surviving receipt; that turn's receipts, fan-out included, and the records between them follow together in the user role, so the model sees each past response as the batch it wrote. Preserve receipt chronology and concrete fan-out targets. No history is collected at the end. `none` adds no assistant section; filtering never makes `latest` fall back. |
|
|
5510
|
+
| Curation | A retired operation row loses its replay; retiring one fan-out receipt leaves the operation with its surviving receipts. A body-trimmed authored row is not replayed: its ordinary receipt shows the remaining body. Retiring the emission row removes that turn's replay, not its operation results or immutable source. No legend or separate NOTE-curation path exists. |
|
|
5511
|
+
| Authority | Core assembles these chronological sections before the trusted whole-list transform ({§packet-extension-transform}); this is presentation of admitted work, not additional execution or inference. |
|
|
5512
|
+
| Capacity | At the hard context wall, omit the selected history whole before suppressing result bodies or native parts ({§context-own-rows-fit}). Unpaired receipts regain their ordinary request facts and authored bodies. Omission lasts through rebuilds of that request; the next request decides afresh. No source, receipt, or stored historical packet changes. |
|
|
5513
|
+
| Accounting | The first paired receipt's displayed curation weight includes its assistant operation once. Packet accounting measures each actual message once. The emission row charges only its own record. |
|
|
5514
|
+
|
|
5515
|
+
§paired-receipt A paired receipt reports execution information, not a second copy of its request.
|
|
5516
|
+
|
|
5517
|
+
| Information | Paired receipt | Unpaired receipt / explicit log READ |
|
|
5518
|
+
|---|---|---|
|
|
5519
|
+
| Authored body | Lives in the complete assistant operation only | Ordinary body projection |
|
|
5520
|
+
| Authored aside, scope, metadata, pattern and addressed path | Supplied by the operation | Self-describing request facts |
|
|
5521
|
+
| Resolved targets that differ from the request, including fan-out and COPY/MOVE glob operands | Retained on each concrete receipt | Retained |
|
|
5522
|
+
| Retrieval and tool output, landed edit windows, errors, result extents, stream/resource identities and statuses | Retained | Retained |
|
|
5523
|
+
|
|
5524
|
+
Suppression is packet-local. Durable requests, results, exact source and recorded historical packets remain complete.
|
|
5302
5525
|
|
|
5303
5526
|
The initial user segment is `log`; later segments are `log/<first-record-coordinate>`.
|
|
5304
|
-
|
|
5527
|
+
Operations are `emission-history/<first-surviving-receipt-coordinate>`. These are durable, unique section
|
|
5305
5528
|
names, not model-facing headings. Only the initial segment has the `Log` header. Section-family
|
|
5306
5529
|
inspection joins segments in recorded order; wire projection uses their individual roles and
|
|
5307
5530
|
positions. Stored packets retain the sections actually sent, including older packet layouts.
|
|
@@ -5315,11 +5538,11 @@ Conditional absence never reorders the surviving default sections.
|
|
|
5315
5538
|
| 1 | system | `definition` | Framework definition; leads the most stable prefix. |
|
|
5316
5539
|
| 2 | system | `system-policy` | Operator policy; empty content is omitted on the wire. |
|
|
5317
5540
|
| 3 | system | `inject` | Present only when operator notes are configured. |
|
|
5318
|
-
| 4–5 | user / assistant | `log` and `emission-history` segments | Append-mostly chronological history: each
|
|
5541
|
+
| 4–5 | user / assistant | `log` and `emission-history` segments | Append-mostly chronological history: each replayed turn's operations immediately precede that turn's results ({§emission-history}). |
|
|
5319
5542
|
| 6 | user | `git` | Per-turn workspace status; empty content is omitted. |
|
|
5320
5543
|
| 7 | user | `budget` | `Context Curation`; omitted when capacity is unknown. |
|
|
5321
5544
|
| 8 | user | `worker` | `Worker`: `{"path": "worker://alice", "parent": <address or null>, "loop": L, "turn": T}`, the actor and the coordinate this packet's response becomes ({§packet-current-turn}). |
|
|
5322
|
-
| 9 | user | `
|
|
5545
|
+
| 9 | user | `work` | `Open Work`: per-turn `{workers, streams, messages}` pointers; always present, each list `[]` when empty ({§packet-empty-sections}). |
|
|
5323
5546
|
| 10 | user | `messages` | `Open Messages`: immutable message addresses and causal sources ({§message-arrival}). |
|
|
5324
5547
|
| 11 | user | `notices` | Per-turn observations; empty content is omitted. |
|
|
5325
5548
|
| 12 | user | `errors` | Per-turn failure pointers; empty content is omitted. |
|
|
@@ -5329,7 +5552,7 @@ The order favors prefix-cache locality where semantics permit: the definition
|
|
|
5329
5552
|
and privileged policy lead operator notes, while the append-mostly
|
|
5330
5553
|
log and interpolated programs lead the volatile user-status clump. That clump is never cached
|
|
5331
5554
|
across turns, since the next turn's log grows into its place, so its order serves attention alone:
|
|
5332
|
-
it runs from ambient state (Git Status, Context, Worker,
|
|
5555
|
+
it runs from ambient state (Git Status, Context, Worker, Open Work) to what the turn owes (Open
|
|
5333
5556
|
Messages) to feedback on the last turn (Notices, then Errors), and closes with the Recap. The nearer
|
|
5334
5557
|
the end, the more a section asks of this turn. With `all`, appending new
|
|
5335
5558
|
observations and programs preserves the existing history's roles and text prefix; no old program
|
|
@@ -5454,7 +5677,7 @@ flowchart LR
|
|
|
5454
5677
|
log --> packet["Packet lists coordinate;<br/>READ recalls exact body"]
|
|
5455
5678
|
```
|
|
5456
5679
|
|
|
5457
|
-
§env-delta-log-pull **Pull the event record, never a
|
|
5680
|
+
§env-delta-log-pull **Pull the event record, never a workspace snapshot.** At
|
|
5458
5681
|
pre-turn, a worker materializes only occurrences whose structural audience
|
|
5459
5682
|
includes that worker. The set is exhaustive, unranked, and exactly once; the
|
|
5460
5683
|
engine makes no relevance decision. Each copied event retains the operation,
|
|
@@ -5648,9 +5871,9 @@ another admission is a 409 conflict, not a second message or an implicit content
|
|
|
5648
5871
|
|
|
5649
5872
|
| Audience | Delivery | Effect |
|
|
5650
5873
|
|---|---|---|
|
|
5651
|
-
| Assigned worker | Its
|
|
5874
|
+
| Assigned worker | Its own log, even when another actor answered | Visible reply; wakes eligible parked work without a new Open Message or loop. |
|
|
5652
5875
|
| Original native sender | That worker, if distinct from the assigned worker; original delegated-task answers use {§worker-scheme-collect} instead | Other replies use the same wake and observation path. |
|
|
5653
|
-
| Exterior sender | The assigned
|
|
5876
|
+
| Exterior sender | The assigned worker's protocol adapter | The adapter delivers the answer through its standard message channel. |
|
|
5654
5877
|
| Replying actor | Its own executed SEND | No duplicate ambient occurrence. |
|
|
5655
5878
|
|
|
5656
5879
|
The successful SEND and its addressed occurrences commit together. Reply occurrences use
|
|
@@ -5681,7 +5904,9 @@ published, oldest first, and stamps each with the row it became. Ordinal 1 is th
|
|
|
5681
5904
|
own assignment and shares the loop's fate: a loop that fails before its first turn does
|
|
5682
5905
|
not replay it. Every other still-unpublished message at conclusion moves into one
|
|
5683
5906
|
source-keyed recovery loop, renumbered from its first, whose headline it becomes; that loop's first turn publishes the complete
|
|
5684
|
-
ordered set exactly once.
|
|
5907
|
+
ordered set exactly once. The recovery loop retains the source loop's model routes,
|
|
5908
|
+
effort, and call ceiling; message bodies and attribution are preserved directly from
|
|
5909
|
+
their durable rows. Recovery retries complete the same queued loop and never
|
|
5685
5910
|
mint duplicate work. Output withholding preserves readable arrival rows; explicit
|
|
5686
5911
|
KILL follows the ordinary log contract.
|
|
5687
5912
|
|
|
@@ -5747,9 +5972,8 @@ retain distinct contracts and lifetimes.
|
|
|
5747
5972
|
| `parse_advisory` | grammar parser — recoverable near-miss which did not invalidate the parsed statements | YOU SHOULD write the canonical form. | content-offset into the model's emission |
|
|
5748
5973
|
| `search_progress` | repository materialization/indexing lifecycle ({§persistent-search-index}); structured phase, count, and percent; `level: info`, `warn` when a completed pass carries failed members ({§derivation-member-failure}), `error` on terminal failure | none | none |
|
|
5749
5974
|
| `git_inspection_refused` | engine membership — automatic Git inspection refused a supplied repository whose config declares a `filter.*` program ({§membership-git-hermetic}); names the key; `level: warn`, once per workspace until the key changes or clears | none | none |
|
|
5750
|
-
| `continued_without_note` | engine turn — a continuing or parked model turn that admitted no NOTE ({§continued-without-note}); `level: warn` | YOU MUST record at least one NOTE along with other operations. | none |
|
|
5751
5975
|
| `outside_text` | engine turn — text the emission carried outside its operations, discarded ({§outside-text}); `level: warn` | YOU MUST NOT emit anything except whitespace between fenced operations. | none |
|
|
5752
|
-
| `invalid_emission` | engine grammar — a response rejected before dispatch; `level: error` | YOU MUST ONLY emit fenced
|
|
5976
|
+
| `invalid_emission` | engine grammar — a response rejected before dispatch; `level: error` | YOU MUST ONLY emit fenced operation batches; with the parameters, pattern, and terse aside on the fenced operation line. | content-offset of the parser diagnostic, when it has one |
|
|
5753
5977
|
| `output_truncated` | engine capacity or turn — an emission cut at the output allowance ({§output-allowance-notice}); `level: error` when the cut response was rejected, otherwise `warn` | YOU SHOULD emit fewer or shorter operations per turn. | none |
|
|
5754
5978
|
| `provider_warning` | a provider warning: an SDK compatibility note, or native tool calls in a response that declared none; `level: warn` | YOU MUST NOT emit native tool calls. on the native tool calls; none on a compatibility note | none |
|
|
5755
5979
|
| `provider_retry` | a provider stream that failed after output began and was answered by a complete retry; `level: warn` | none | none |
|
|
@@ -5761,13 +5985,11 @@ retain distinct contracts and lifetimes.
|
|
|
5761
5985
|
| `scope_normalized` | engine slicer — a scope normalized to its canonical form; `level: warn` | YOU SHOULD write the normalized scope. | none |
|
|
5762
5986
|
| `edit_merged` | engine slicer — an EDIT resolution rule applied to a batch ({§edit-batch-merges}); `level: warn` | YOU SHOULD verify the merged EDIT before building on it. | none |
|
|
5763
5987
|
|
|
5764
|
-
§continued-without-note **A continuing turn that lapsed from the per-turn rule is told so.** The card's rule is one line, `YOU MUST record at least one NOTE along with other operations.`, and the daemon's directive quotes it. When a model turn settles at 102 or 202, so the loop continues past it or parks on it, and it admitted no NOTE in its program or from its reasoning ({§reasoning-operations}), the next packet carries one `engine:turn` notice, `continued_without_note`, `level: warn`, with that directive and the message `The turn continued without a NOTE.`; when its program was NOTEs and nothing else, the next packet carries `noted_without_operation`, the same directive and the message `The turn carried NOTEs and no other operation.` Each is a notice, never a failure: it mints no row, never counts toward the strike rail, and never ends or alters a loop. A turn that concludes its loop, an empty turn, which carries its own no-operation row, and every non-model turn take none.
|
|
5765
|
-
|
|
5766
5988
|
§notice-callout **A notice speaks in the card's callout form.** Each renders as one alert callout, its level choosing the callout: `> [!CAUTION]` for `error`, `> [!WARNING]` for `warn`, and `> [!NOTE]` for `info`, which no model packet carries. Inside it stand the directive ({§notice-directive}), then the message, any typed position as `@ line:column`, and the kind in brackets; a blank line separates consecutive callouts:
|
|
5767
5989
|
|
|
5768
5990
|
```text
|
|
5769
5991
|
> [!WARNING]
|
|
5770
|
-
> YOU
|
|
5992
|
+
> YOU SHOULD write the normalized scope. Scope <0,120> was normalized to <1,120>. [scope_normalized]
|
|
5771
5993
|
```
|
|
5772
5994
|
|
|
5773
5995
|
§notice-level **Severity on the wire (`level`, required).** Every `Notice` carries `level: "error" | "warn" | "info"`, set by the **producer** at the emit site. The level is client presentation, not operation status: even an `error` notice cannot terminalize work or substitute for a durable Problem. A forwarded `output_unaccounted` is `warn`; ordinary lifecycle and progress notices are `info`. Clients color straight off `level` without interpreting the open `kind` vocabulary.
|
|
@@ -5777,7 +5999,10 @@ retain distinct contracts and lifetimes.
|
|
|
5777
5999
|
§notice-event-notify **Client surface.** Engine Notices broadcast live via the `notice/event` notification — `{ workerId, loopId, notice: { source, kind, level, message?, position?, …kind-specific } }` per the grammar's `Notice` schema — the moment they land. A loop Notice names its owning Worker; workspace derivation progress alone carries `workerId=null, loopId=0`. AG-UI projects the same observation as the custom `plurnk.notice` event. Failures do not broadcast on this surface: they are log rows, and the client reads them through `log.read` / the `log/entry` notification, the durable log.
|
|
5778
6000
|
|
|
5779
6001
|
§loop-status-notice **The drain publishes lifecycle and its observation deadline together.**
|
|
5780
|
-
`notice/event` carries `{ workerId, loopId, notice: { source: "engine:lifecycle", kind: "loop_status", level: "info", status, waitUntil } }
|
|
6002
|
+
`notice/event` carries `{ workerId, loopId, notice: { source: "engine:lifecycle", kind: "loop_status", level: "info", status, waitUntil, packetCount, claimedAt } }`:
|
|
6003
|
+
with its status, every beat carries its loop's packet count and claim stamp (Unix milliseconds, `null`
|
|
6004
|
+
before the first claim), the ones a projection reads ({§application-loop-observation}), so a client
|
|
6005
|
+
updates the loop's identity, count and stamp together.
|
|
5781
6006
|
|
|
5782
6007
|
| Edge | `status` | `waitUntil` |
|
|
5783
6008
|
|---|---|---|
|
|
@@ -5799,7 +6024,7 @@ the same deadline through {§application-loop-observation}, not a restarted cloc
|
|
|
5799
6024
|
|
|
5800
6025
|
§candidate-pinned-runtime **Candidate runtime stays pinned.** At launch, after its optional build, the candidate copies every workspace's package projection (`files`) into `<state>/runtime`, links third-party dependencies, and resolves `@plurnk/*` to those copies. Its daemon and its digest export both run from that copy, never the shared checkout, so neither source edits nor a concurrent candidate's or developer's rebuild after launch changes the code a run finishes on. The copy is removed once the digest is written.
|
|
5801
6026
|
|
|
5802
|
-
§output-allowance-notice **The output allowance is not disclosed; a ceiling cut names its cause.** The packet's budget section carries the curation state and no response allowance: a model does not plan in tokens and no harness tells it its output ceiling, so the number is a fact without a use (#826). Overflow tolerance (#482) is likewise never advertised; a cut's notice names the true per-call grant from the response's own capacity record. When a provider finish is `length`, the engine emits an `output_truncated` notice (source `engine:capacity`) naming the allowance — the fact alone, never advice on what to do about it — on every path — railed or not — and the rails verdict never blames the model
|
|
6027
|
+
§output-allowance-notice **The output allowance is not disclosed; a ceiling cut names its cause.** The packet's budget section carries the curation state and no response allowance: a model does not plan in tokens and no harness tells it its output ceiling, so the number is a fact without a use (#826). Overflow tolerance (#482) is likewise never advertised; a cut's notice names the true per-call grant from the response's own capacity record. When a provider finish is `length`, the engine emits an `output_truncated` notice (source `engine:capacity`) naming the allowance — the fact alone, never advice on what to do about it — on every path — railed or not — and the rails verdict never blames the model for a cut the engine's own ceiling made: a cut turn is no repetition evidence ({§engine-cycle-evidence}), and a strike threshold crossed on one names the allowance ({§engine-rails}). The same precedence governs a cut so deep no operation parses: the rejection notice names the truncation as the cause, not the parser's symptom, overriding {§invalid-emission-attempts}'s parser diagnostic for `length` finishes.
|
|
5803
6028
|
|
|
5804
6029
|
§turn-lifecycle **Turn-lifecycle liveness.** Provider generation is the long, opaque window in a turn — one or more same-packet emission attempts may occur before the first committed op. A static client screen there is indistinguishable from a hang. The engine brackets the complete attempt window with two `notice/event` notices (`source: "engine:turn"`, `level: "info"`): `turn_awaiting_model` before the first call and `turn_generated` when an emission is accepted or the attempt budget is exhausted. The completion beat carries the spend ({§turn-accounting-notice}). Rejected content never rides the notice channel. Both are suppressed on an aborted loop and broadcast to the workspace like any notice ({§notice-event-notify}).
|
|
5805
6030
|
|
|
@@ -6389,7 +6614,7 @@ llama-server rails, the upstream A2A TCK and the client's real-model TUI tier ar
|
|
|
6389
6614
|
run wherever their requirements hold. `tier:history` ledgers every census under the home: per
|
|
6390
6615
|
specimen, its verdicts over runs and its last reason.
|
|
6391
6616
|
|
|
6392
|
-
§fs-
|
|
6617
|
+
§fs-resource-state **The resource-state harness — coverage that closes the class.** Op-outcome tests check what an op returned; the harness checks the resulting resource state. `ResourceState.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.
|
|
6393
6618
|
|
|
6394
6619
|
## Problem codes and pinned wording
|
|
6395
6620
|
|
|
@@ -6428,6 +6653,7 @@ Every Problem code core mints is named here under its family ({§problem-error-c
|
|
|
6428
6653
|
| `channel-required` | 400 | The '*scheme*' scheme has no default channel. Recovery: Address a named channel with a URI fragment. |
|
|
6429
6654
|
| `binary-source-unsupported` | 415 | Channel #*name* is binary and its scheme keeps no bytes to transfer. |
|
|
6430
6655
|
| `metadata-unsupported` | 400 | *OP* takes only the env option; '*key*' is not one. A WORK to a held name with env: WORK to the existing worker '*name*' carries env; a message takes none. |
|
|
6656
|
+
| `fork-unaddressed` | 404 | This client operation acts for no worker, so FORK has no log to branch ({§actor-boundary-client-operations}). |
|
|
6431
6657
|
| `worker-name-conflict` | 409 | Worker '*name*' already exists in this workspace. Recovery: WORK or SEND (worker://*name*) delivers a message to the live worker; FORK with a name no worker holds. ({§worker-scheme-spawn}) |
|
|
6432
6658
|
| `no-operation` | 422 | The turn performed no operation ({§empty-turn}). |
|
|
6433
6659
|
| `send-target-not-a-recipient` | 400 | The addressed scheme is not a SEND recipient. Recovery: Name a message address or a recipient that implements SEND. |
|
|
@@ -6491,7 +6717,7 @@ lists the schemes the workspace registers, and rebuilds the address into nothing
|
|
|
6491
6717
|
| `file-create-excluded` | 403 | A members exclusion (`!_glob_`) covers '*path*'. Recovery: Remove or disable the excluding members definition, or choose another path. |
|
|
6492
6718
|
| `file-create-gitignored` | 403 | Active Git policy ignores '*path*', and no members definition includes it. Recovery: Choose a Git-admitted path or add a members definition that includes it. |
|
|
6493
6719
|
| `file-materialization-limit` | 413 | The file exceeds the materialization byte limit and is not read into the workspace. |
|
|
6494
|
-
| `entry-not-found` | 404 | No member of this workspace is at '*path*'. Recovery: FIND lists paths. EDIT creates files; `members (add)` admits existing files with a `{"
|
|
6720
|
+
| `entry-not-found` | 404 | No member of this workspace is at '*path*'. Recovery: FIND lists paths. EDIT creates files; `members (add)` admits existing files with a `{"files": ["<path>"]}` body. A path beyond the root recovers instead to: '*path*' is outside the project root: only a members definition under the operator's namespace scope admits it. |
|
|
6495
6721
|
| `body-channel-required` | 400 | A file write requires a body channel. |
|
|
6496
6722
|
| `write-failed` | 500 | Publication or its settlement failed; the result distinguishes an unpublished write from an already-published one. |
|
|
6497
6723
|
| `creation-rollback-failed` | 500 | Incorporating a newly created file failed, and rollback was incomplete. |
|
|
@@ -6527,6 +6753,7 @@ lists the schemes the workspace registers, and rebuilds the address into nothing
|
|
|
6527
6753
|
|---|---:|---|
|
|
6528
6754
|
| `read-target-required` | 400 | READ requires a log coordinate. Recovery: Provide one exact log coordinate. |
|
|
6529
6755
|
| `coordinate-malformed` | 400 | The log coordinate '*path*' is malformed. Recovery: Use one exact loop/turn/sequence coordinate. |
|
|
6756
|
+
| `log-unaddressed` | 404 | This client operation acts for no worker, so `log:///` names no log ({§actor-boundary-client-operations}). |
|
|
6530
6757
|
| `kill-failed` | 400 | The log target '*path*' is malformed. (A glob the matcher cannot read: The log glob '*glob*' is malformed.) Recovery: the {§log-target-shape} sentence. |
|
|
6531
6758
|
| `curation-failed` | 400 | A scoped KILL's selection could not be read: the same sentences and recovery as `kill-failed`. |
|
|
6532
6759
|
| `worker-target-required` | 400 | EDIT requires a worker:// target. Recovery: Provide the worker target. |
|
|
@@ -6537,7 +6764,7 @@ lists the schemes the workspace registers, and rebuilds the address into nothing
|
|
|
6537
6764
|
| `scope-unsupported` | 400 | A worker SEND takes no scope. |
|
|
6538
6765
|
| `control-address-invalid` | 400 | The operation requires an authority-only worker control address. |
|
|
6539
6766
|
| `named-worker-required` | 400 | A worker deliverable READ requires a named worker. |
|
|
6540
|
-
| `emission-curated-whole` | 422 | An emission
|
|
6767
|
+
| `emission-curated-whole` | 422 | An emission source announcement must be curated whole, without a line scope. |
|
|
6541
6768
|
| `entry-exists` | 409 | An entry already exists at the addressed resource. |
|
|
6542
6769
|
| `invalid-expression` | 400 | The full-text or graph matcher expression is invalid. |
|
|
6543
6770
|
| `delete-target-required` | 400 | KILL requires a target path. |
|
|
@@ -6547,14 +6774,16 @@ lists the schemes the workspace registers, and rebuilds the address into nothing
|
|
|
6547
6774
|
| code | status | condition |
|
|
6548
6775
|
|---|---:|---|
|
|
6549
6776
|
| `interaction-not-pending` | 409 | The requested client interaction is not pending. |
|
|
6550
|
-
| `interaction-unsupported` | 501 | No recipient implements the requested tool for this
|
|
6777
|
+
| `interaction-unsupported` | 501 | No recipient implements the requested tool for this worker. |
|
|
6551
6778
|
| `recipient-mismatch` | 403 | Only the interaction's recipient may answer it. |
|
|
6552
6779
|
| `interaction-response-invalid` | 400 | The response does not satisfy the pending interaction's schema. |
|
|
6553
6780
|
| `invalid-body` | 400 | A question body is not JSON, or lacks its nonempty message or requested schema. |
|
|
6554
6781
|
| `offset-invalid` | 400 | An entry offset is not a nonnegative safe integer. |
|
|
6555
6782
|
| `userinfo-not-allowed` | 400 | An entry target URL contains userinfo. |
|
|
6556
6783
|
| `action-threw` | 500 | The client action failed outside its operation result contract. |
|
|
6784
|
+
| `operation-cancelled` | 499 | The client operation was cancelled: *reason*. Its loop settles with this result ({§connection-lifecycle}). |
|
|
6557
6785
|
| `message-already-accepted` | 409 | The message address was already accepted in this workspace. |
|
|
6786
|
+
| `message-address-reused` | 422 | The message address was already accepted in this workspace with other words. |
|
|
6558
6787
|
| `source-not-running` | 409 | The originating task is not running; no message was admitted. |
|
|
6559
6788
|
| `loop-not-open` | 409 | The named loop is not an unfinished recipient of the worker; no message was admitted. |
|
|
6560
6789
|
|
|
@@ -6601,17 +6830,17 @@ lists the schemes the workspace registers, and rebuilds the address into nothing
|
|
|
6601
6830
|
| Nothing is in flight. Continuing. | a WAIT (or a premature terminal) with no live work ({§wait-obligation-matrix}) |
|
|
6602
6831
|
| All Open Messages resolved. Review new results; emit no OPs if finished. | resolved messages with unobserved results ({§loop-completion}) |
|
|
6603
6832
|
| Context exceeds budget. YOU MUST ONLY KILL, MOVE or NOTE this turn. | the over-budget row ({§context-over-budget-row}) |
|
|
6604
|
-
| YOU MUST record at least one NOTE along with other operations. The turn continued without a NOTE. | a continuing or parked model turn without a NOTE ({§continued-without-note}) |
|
|
6605
6833
|
| Each directive in the notice table | a notice of the model's own output ({§notice-directive}) |
|
|
6606
6834
|
| Context window overflow: the packet cannot fit the model's window even as receipts. | the wall ({§context-wall}) |
|
|
6607
6835
|
| No recipient implements the requested interaction. | The worker's owner is not interactive or does not declare the required client tool ({§client-interaction-routing}). |
|
|
6608
6836
|
| Nobody is present to answer. Decide from what you already have, or conclude stating what you could not resolve. | dispatch of an interaction tool the worker's owner would not receive ({§owner-interaction-ring}) |
|
|
6609
6837
|
| Worker name '*name*' must match `[A-Za-z0-9][A-Za-z0-9_-]{0,62}`. Recovery: Use 1–63 ASCII letters, digits, '_' or '-', starting with a letter or digit. | an invalid worker name |
|
|
6610
6838
|
| Provide the client identifier. / Provide an absolute project path. / Use a positive integer limit. / prompt is not a non-empty string. | client input validation on the daemon's methods |
|
|
6839
|
+
| name '*name*' has the path segment '*segment*'. Recovery: Provide a name with no '.' or '..' between its slashes; a dot within a segment is ordinary. / name is not well-formed Unicode: it holds an unpaired surrogate. | a workspace name refused at creation or rename ({§workspace-name}) |
|
|
6611
6840
|
| The stream was cancelled by KILL. | a stream terminal after KILL |
|
|
6612
6841
|
| '*runtime*' exited with code 127; `*program*` is a registered tool of `*owner*`. | a tool run as a shell command ({§exec-tool-fall-through}) |
|
|
6613
6842
|
| '*path*' is a directory, not a file; READ reads one file. Recovery: `FIND (_path_/)` lists its files. | READ of a directory |
|
|
6614
6843
|
| The execution at ops://*worker*/*loop* has not concluded. | a bare READ of a running worker's result (425) |
|
|
6615
6844
|
| The child provider failed. | a child's provider failure read back by its parent |
|
|
6616
|
-
| '*path*' exists on disk but is not a member of this workspace. Recovery: Admit it with `members (add)` and a `{"
|
|
6845
|
+
| '*path*' exists on disk but is not a member of this workspace. Recovery: Admit it with `members (add)` and a `{"files": ["<path>"]}` body. | a non-member on disk at the addressed path |
|
|
6617
6846
|
| '*path*' exists on disk but is not a member of this workspace. Recovery: The repository ignores it: a client or operator members definition can include it, a model definition cannot. | a non-member the repository ignores ({§membership-read-refusal}) |
|