@plurnk/plurnk-service 1.25.0 → 1.27.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 +3 -6
- package/SPEC.md +317 -151
- package/dist/build-info.json +1 -1
- package/dist/content/body-preview.d.ts +1 -0
- package/dist/content/body-preview.d.ts.map +1 -1
- package/dist/content/body-preview.js +7 -0
- package/dist/content/body-preview.js.map +1 -1
- package/dist/content/byte-view.d.ts +19 -2
- package/dist/content/byte-view.d.ts.map +1 -1
- package/dist/content/byte-view.js +67 -14
- package/dist/content/byte-view.js.map +1 -1
- package/dist/content/edit-receipt.js +1 -1
- package/dist/content/edit-receipt.js.map +1 -1
- package/dist/content/line-marker.js +1 -1
- package/dist/content/line-marker.js.map +1 -1
- package/dist/content/line-selection.d.ts +3 -1
- package/dist/content/line-selection.d.ts.map +1 -1
- package/dist/content/line-selection.js +27 -3
- package/dist/content/line-selection.js.map +1 -1
- package/dist/content/matcher.d.ts +9 -14
- package/dist/content/matcher.d.ts.map +1 -1
- package/dist/content/matcher.js +51 -45
- package/dist/content/matcher.js.map +1 -1
- package/dist/content/pattern-edits.d.ts +7 -26
- package/dist/content/pattern-edits.d.ts.map +1 -1
- package/dist/content/pattern-edits.js +54 -91
- package/dist/content/pattern-edits.js.map +1 -1
- package/dist/content/read-projector.d.ts +2 -1
- package/dist/content/read-projector.d.ts.map +1 -1
- package/dist/content/read-projector.js +58 -7
- package/dist/content/read-projector.js.map +1 -1
- package/dist/content/read-resolve.js +1 -1
- package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
- package/dist/core/AdmittedTurnExecutor.js +4 -3
- package/dist/core/AdmittedTurnExecutor.js.map +1 -1
- package/dist/core/ChannelWrite.d.ts +2 -3
- package/dist/core/ChannelWrite.d.ts.map +1 -1
- package/dist/core/ChannelWrite.js +21 -22
- package/dist/core/ChannelWrite.js.map +1 -1
- package/dist/core/ChannelWrite.sql +26 -0
- package/dist/core/DataStatementRunner.d.ts.map +1 -1
- package/dist/core/DataStatementRunner.js +1 -0
- package/dist/core/DataStatementRunner.js.map +1 -1
- package/dist/core/Dispatcher.d.ts +3 -3
- package/dist/core/Dispatcher.d.ts.map +1 -1
- package/dist/core/Dispatcher.js +53 -14
- package/dist/core/Dispatcher.js.map +1 -1
- package/dist/core/EditMutations.d.ts +5 -5
- package/dist/core/EditMutations.d.ts.map +1 -1
- package/dist/core/EditMutations.js +44 -50
- package/dist/core/EditMutations.js.map +1 -1
- package/dist/core/EditSequence.js +2 -2
- package/dist/core/EditSequence.js.map +1 -1
- package/dist/core/Engine.d.ts +1 -0
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js +3 -0
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/InferenceCall.js +2 -2
- package/dist/core/InferenceCall.js.map +1 -1
- package/dist/core/InferenceCall.sql +1 -0
- package/dist/core/LiveSubscription.d.ts +20 -0
- package/dist/core/LiveSubscription.d.ts.map +1 -0
- package/dist/core/LiveSubscription.js +68 -0
- package/dist/core/LiveSubscription.js.map +1 -0
- package/dist/core/LiveSubscriptions.d.ts +1 -0
- package/dist/core/LiveSubscriptions.d.ts.map +1 -1
- package/dist/core/LiveSubscriptions.js +8 -0
- package/dist/core/LiveSubscriptions.js.map +1 -1
- package/dist/core/LogBody.js +1 -1
- package/dist/core/LogBody.js.map +1 -1
- package/dist/core/LoopDriver.d.ts.map +1 -1
- package/dist/core/LoopDriver.js +5 -2
- package/dist/core/LoopDriver.js.map +1 -1
- package/dist/core/LoopLifecycle.d.ts +2 -2
- package/dist/core/LoopLifecycle.d.ts.map +1 -1
- package/dist/core/LoopLifecycle.js +2 -4
- package/dist/core/LoopLifecycle.js.map +1 -1
- package/dist/core/LoopLifecycle.sql +1 -6
- package/dist/core/MembershipMaterialization.js +1 -1
- package/dist/core/MembershipMaterialization.js.map +1 -1
- package/dist/core/MutationEffects.d.ts +1 -3
- package/dist/core/MutationEffects.d.ts.map +1 -1
- package/dist/core/MutationEffects.js +2 -1
- package/dist/core/MutationEffects.js.map +1 -1
- package/dist/core/PacketBuilder.d.ts.map +1 -1
- package/dist/core/PacketBuilder.js +17 -4
- package/dist/core/PacketBuilder.js.map +1 -1
- package/dist/core/PacketBuilder.sql +4 -5
- package/dist/core/PatternSelection.d.ts +5 -10
- package/dist/core/PatternSelection.d.ts.map +1 -1
- package/dist/core/PatternSelection.js +9 -16
- package/dist/core/PatternSelection.js.map +1 -1
- package/dist/core/ReasoningView.d.ts +1 -1
- package/dist/core/ReasoningView.d.ts.map +1 -1
- package/dist/core/ReasoningView.js +4 -5
- package/dist/core/ReasoningView.js.map +1 -1
- package/dist/core/ResourceMutations.d.ts +2 -4
- package/dist/core/ResourceMutations.d.ts.map +1 -1
- package/dist/core/ResourceMutations.js +2 -5
- package/dist/core/ResourceMutations.js.map +1 -1
- package/dist/core/ResourceSelector.d.ts +2 -2
- package/dist/core/ResourceSelector.d.ts.map +1 -1
- package/dist/core/ResourceSelector.js +64 -33
- package/dist/core/ResourceSelector.js.map +1 -1
- package/dist/core/ResourceTransfers.d.ts +2 -4
- package/dist/core/ResourceTransfers.d.ts.map +1 -1
- package/dist/core/ResourceTransfers.js +74 -50
- package/dist/core/ResourceTransfers.js.map +1 -1
- package/dist/core/SchemeRegistry.d.ts +1 -0
- package/dist/core/SchemeRegistry.d.ts.map +1 -1
- package/dist/core/SchemeRegistry.js +11 -9
- package/dist/core/SchemeRegistry.js.map +1 -1
- package/dist/core/ServiceTeardown.d.ts +3 -2
- package/dist/core/ServiceTeardown.d.ts.map +1 -1
- package/dist/core/ServiceTeardown.js +17 -8
- package/dist/core/ServiceTeardown.js.map +1 -1
- package/dist/core/StopDeadline.d.ts +5 -0
- package/dist/core/StopDeadline.d.ts.map +1 -0
- package/dist/core/StopDeadline.js +20 -0
- package/dist/core/StopDeadline.js.map +1 -0
- package/dist/core/ToolResources.d.ts.map +1 -1
- package/dist/core/ToolResources.js +11 -2
- package/dist/core/ToolResources.js.map +1 -1
- package/dist/core/Turn.d.ts +1 -1
- package/dist/core/Turn.d.ts.map +1 -1
- package/dist/core/Turn.js +2 -2
- package/dist/core/Turn.js.map +1 -1
- package/dist/core/Turn.sql +1 -1
- package/dist/core/TurnDispositionHandler.d.ts +4 -2
- package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
- package/dist/core/TurnDispositionHandler.js +24 -6
- package/dist/core/TurnDispositionHandler.js.map +1 -1
- package/dist/core/TurnRunner.d.ts.map +1 -1
- package/dist/core/TurnRunner.js +62 -49
- package/dist/core/TurnRunner.js.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
- package/dist/core/caps/DbSubscriptionCaps.js +13 -19
- package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
- package/dist/core/content-hash.d.ts +1 -1
- package/dist/core/content-hash.d.ts.map +1 -1
- package/dist/core/content-hash.js.map +1 -1
- package/dist/core/env-defaults.d.ts.map +1 -1
- package/dist/core/env-defaults.js +6 -2
- package/dist/core/env-defaults.js.map +1 -1
- package/dist/core/git-membership.d.ts.map +1 -1
- package/dist/core/git-membership.js +0 -3
- package/dist/core/git-membership.js.map +1 -1
- package/dist/core/mutation-types.d.ts +6 -4
- package/dist/core/mutation-types.d.ts.map +1 -1
- package/dist/core/namespace.d.ts +1 -0
- package/dist/core/namespace.d.ts.map +1 -1
- package/dist/core/namespace.js +21 -75
- package/dist/core/namespace.js.map +1 -1
- package/dist/core/notifications.d.ts +2 -0
- package/dist/core/notifications.d.ts.map +1 -1
- package/dist/core/packet-wire.d.ts.map +1 -1
- package/dist/core/packet-wire.js +31 -3
- package/dist/core/packet-wire.js.map +1 -1
- package/dist/core/provider-accounting.d.ts +1 -1
- package/dist/core/provider-accounting.d.ts.map +1 -1
- package/dist/core/provider-accounting.js +2 -1
- package/dist/core/provider-accounting.js.map +1 -1
- package/dist/digest/Digest.d.ts.map +1 -1
- package/dist/digest/Digest.js +1 -0
- package/dist/digest/Digest.js.map +1 -1
- package/dist/digest/DigestEvidence.d.ts +2 -0
- package/dist/digest/DigestEvidence.d.ts.map +1 -1
- package/dist/digest/DigestEvidence.js +14 -0
- package/dist/digest/DigestEvidence.js.map +1 -1
- package/dist/digest/DigestRender.d.ts +1 -0
- package/dist/digest/DigestRender.d.ts.map +1 -1
- package/dist/digest/DigestRender.js +41 -13
- package/dist/digest/DigestRender.js.map +1 -1
- package/dist/digest/DigestRequiem.js +4 -4
- package/dist/digest/DigestRequiem.js.map +1 -1
- package/dist/digest/digest-rows.d.ts +2 -0
- package/dist/digest/digest-rows.d.ts.map +1 -1
- package/dist/digest/digest.sql +9 -0
- package/dist/schemes/Exec.d.ts.map +1 -1
- package/dist/schemes/Exec.js +28 -27
- package/dist/schemes/Exec.js.map +1 -1
- package/dist/schemes/File.d.ts.map +1 -1
- package/dist/schemes/File.js +8 -15
- package/dist/schemes/File.js.map +1 -1
- package/dist/schemes/Log.d.ts.map +1 -1
- package/dist/schemes/Log.js +4 -17
- package/dist/schemes/Log.js.map +1 -1
- package/dist/schemes/TurnSource.js +2 -2
- package/dist/schemes/TurnSource.js.map +1 -1
- package/dist/schemes/_derivation-use.d.ts +7 -0
- package/dist/schemes/_derivation-use.d.ts.map +1 -0
- package/dist/schemes/_derivation-use.js +40 -0
- package/dist/schemes/_derivation-use.js.map +1 -0
- package/dist/schemes/_entry-crud.d.ts +6 -1
- package/dist/schemes/_entry-crud.d.ts.map +1 -1
- package/dist/schemes/_entry-crud.js.map +1 -1
- package/dist/schemes/_entry-find.d.ts +1 -0
- package/dist/schemes/_entry-find.d.ts.map +1 -1
- package/dist/schemes/_entry-find.js +17 -52
- package/dist/schemes/_entry-find.js.map +1 -1
- package/dist/schemes/_entry-find.sql +0 -11
- package/dist/schemes/_entry-fts.d.ts.map +1 -1
- package/dist/schemes/_entry-fts.js +9 -3
- package/dist/schemes/_entry-fts.js.map +1 -1
- package/dist/schemes/_entry-fts.sql +14 -8
- package/dist/schemes/_entry-graph.d.ts +5 -8
- package/dist/schemes/_entry-graph.d.ts.map +1 -1
- package/dist/schemes/_entry-graph.js +33 -72
- package/dist/schemes/_entry-graph.js.map +1 -1
- package/dist/schemes/_entry-graph.sql +30 -48
- package/dist/schemes/_entry-manifest.d.ts +5 -0
- package/dist/schemes/_entry-manifest.d.ts.map +1 -1
- package/dist/schemes/_entry-manifest.js +5 -0
- package/dist/schemes/_entry-manifest.js.map +1 -1
- package/dist/schemes/_entry-ops.d.ts +1 -1
- package/dist/schemes/_entry-ops.d.ts.map +1 -1
- package/dist/schemes/_entry-ops.js +4 -11
- package/dist/schemes/_entry-ops.js.map +1 -1
- package/dist/schemes/_path-scope.d.ts +2 -2
- package/dist/schemes/_path-scope.d.ts.map +1 -1
- package/dist/schemes/_path-scope.js +23 -2
- package/dist/schemes/_path-scope.js.map +1 -1
- package/dist/schemes/_search-index.d.ts +10 -0
- package/dist/schemes/_search-index.d.ts.map +1 -1
- package/dist/schemes/_search-index.js +33 -1
- package/dist/schemes/_search-index.js.map +1 -1
- package/dist/schemes/exec-lifetime.d.ts.map +1 -1
- package/dist/schemes/exec-lifetime.js +1 -2
- package/dist/schemes/exec-lifetime.js.map +1 -1
- package/dist/server/Daemon.d.ts +2 -1
- package/dist/server/Daemon.d.ts.map +1 -1
- package/dist/server/Daemon.js +21 -33
- package/dist/server/Daemon.js.map +1 -1
- package/dist/server/DrainSupervisor.d.ts +2 -1
- package/dist/server/DrainSupervisor.d.ts.map +1 -1
- package/dist/server/DrainSupervisor.js +37 -56
- package/dist/server/DrainSupervisor.js.map +1 -1
- package/dist/server/Functionality.d.ts +1 -1
- package/dist/server/Functionality.d.ts.map +1 -1
- package/dist/server/Functionality.js +24 -11
- package/dist/server/Functionality.js.map +1 -1
- package/dist/server/FunctionalityManager.js +2 -2
- package/dist/server/FunctionalityManager.js.map +1 -1
- package/dist/server/Retention.d.ts.map +1 -1
- package/dist/server/Retention.js +7 -3
- package/dist/server/Retention.js.map +1 -1
- package/dist/server/drain.sql +0 -6
- package/dist/server/seam-loop.sql +1 -1
- package/dist/service.js +1 -1
- package/dist/service.js.map +1 -1
- package/docs/env.md +4 -3
- package/migrations/013_graph_regions.sql +31 -0
- package/migrations/014_stream_timing.sql +3 -0
- package/migrations/015_request_evidence.sql +3 -0
- package/package.json +34 -34
- package/dist/server/exec-poll-backoff.d.ts +0 -2
- package/dist/server/exec-poll-backoff.d.ts.map +0 -1
- package/dist/server/exec-poll-backoff.js +0 -6
- package/dist/server/exec-poll-backoff.js.map +0 -1
package/SPEC.md
CHANGED
|
@@ -143,7 +143,7 @@ which depends on core semantic conventions v1.44.0: a CLIENT-kind
|
|
|
143
143
|
spelling, never its tuning alias; unmatched IDs are preserved, `other` for an
|
|
144
144
|
unregistered handle), and `gen_ai.request.model`;
|
|
145
145
|
on settlement it gains `gen_ai.usage.input_tokens` and
|
|
146
|
-
`gen_ai.usage.output_tokens` by
|
|
146
|
+
`gen_ai.usage.output_tokens` for quantities reported by every physical request in
|
|
147
147
|
validated accounting ({§tokenomics-provider-usage}), plus
|
|
148
148
|
`gen_ai.response.finish_reasons`; failures carry `error.type` as the class
|
|
149
149
|
name only. Plurnk custom attributes (attempt, kind, status, loop/turn ids)
|
|
@@ -382,7 +382,7 @@ direct-entry-plus-directory count; `-1` enables the ordinary markerless page;
|
|
|
382
382
|
unset / `0` disables previews. `log://` is absent because the current worker's
|
|
383
383
|
log already renders in present mode.
|
|
384
384
|
|
|
385
|
-
§worker-initialization-entry **Model-worker initialization is a real `_plurnk` turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its reasoning
|
|
385
|
+
§worker-initialization-entry **Model-worker initialization is a real reasoning-only `_plurnk` turn.** A model worker's first loop begins with one packetless `{ producer="_plurnk", kind="initialization" }` turn submitted through {§turn-ops-admission-path}. Its authored reasoning contains the orientation NOTE, READ/FIND surveys and its own reasoning READ ({§reasoning-initial-read}); it is stored before those operations execute through {§reasoning-operations} and {§op-execution-order}. No content program or emission row is fabricated ({§emission-row}). The first request sees ordinary results and the reasoning READ, not an assistant-content copy of the surveys. Every orienting row is structurally classified `_plurnk` and `init`. The namespace surveys and their asides follow {§actor-boundary-catalog-preview}.
|
|
386
386
|
|
|
387
387
|
Incoming messages publish once as inbound SEND rows in the first model turn
|
|
388
388
|
({§message-arrival}); initialization neither READs nor archives them. The turn
|
|
@@ -586,9 +586,17 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
|
|
|
586
586
|
the errors section), just above it. Body-suppressed child activity is durable
|
|
587
587
|
history; this section is the current inventory that keeps an active obligation
|
|
588
588
|
visible even when no new activity arrived. Each open stream pointer carries
|
|
589
|
-
its channels' sizes and growth since
|
|
590
|
-
|
|
591
|
-
|
|
589
|
+
elapsed runtime, output inactivity, and its channels' sizes and growth since
|
|
590
|
+
the last packet in `detail`
|
|
591
|
+
(`{"status":"active","path":"sh:///ab3d5678","detail":"elapsed 300s; output unchanged 120s; stdout 340 lines (+2048 bytes)"}`).
|
|
592
|
+
Both durations are whole seconds at packet assembly, floored and bounded
|
|
593
|
+
below by zero. Runtime starts at subscription opening. Output inactivity
|
|
594
|
+
starts there too, then resets atomically when any published channel's content
|
|
595
|
+
changes, including replacement or clearing. Identical writes, empty appends,
|
|
596
|
+
READs, publication acknowledgements, metadata, and channel-state changes do
|
|
597
|
+
not reset it. The clock is durable; an upgraded stream lacking that evidence
|
|
598
|
+
reports `output timing unknown` until its next content change, never a guessed
|
|
599
|
+
timestamp. These are observations, not new timeouts or wake conditions
|
|
592
600
|
({§exec-stream}). It is orienting state, never advice: the model sees its live
|
|
593
601
|
subtree (`{"status":102,"path":"worker://worker-x"}`) and reasons for itself —
|
|
594
602
|
READ, SEND, or KILL via the path.
|
|
@@ -736,7 +744,8 @@ identity, and terminal disposition without exposing raw bytes or a base64 lane.
|
|
|
736
744
|
| ---------------------------------- | ---------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
737
745
|
| Text | Verbatim Unicode under the detected textual mimetype | READ and EDIT use the snapshot. |
|
|
738
746
|
| Binary with readable projection | Derived Unicode as `text/markdown` | READ uses the projection; source-aware EDIT remains 415. |
|
|
739
|
-
| Binary without projection
|
|
747
|
+
| Binary without projection | Empty marker under the source binary mimetype | READ uses source bytes under {§read-bytes}; text EDIT remains 415. |
|
|
748
|
+
| Failed or oversized acquisition | Empty marker carrying the producer failure | The operation preserves that failure under {§membership-materialization-limit}. |
|
|
740
749
|
|
|
741
750
|
§membership-materialization-limit **A pathological member degrades, never the
|
|
742
751
|
workspace.** `PLURNK_SERVICE_FILE_MATERIALIZE_MAX_BYTES` is a required positive
|
|
@@ -836,19 +845,38 @@ all use that one definition.
|
|
|
836
845
|
|
|
837
846
|
### §worker-wait-timing Durable waits and wake ownership
|
|
838
847
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
848
|
+
With live work—an open stream or a live child worker—the loop parks until an
|
|
849
|
+
ordinary wake or its maximum wait elapses. `PLURNK_SERVICE_WAIT_SEC` supplies the
|
|
850
|
+
bound; `WAIT <seconds>` overrides that one park ({§send-wait-scope}). The wake time
|
|
851
|
+
commits atomically with the wait revision, rounded up to the next millisecond.
|
|
852
|
+
Expiry queues the same loop through normal worker/provider admission; it never
|
|
853
|
+
cancels work or fabricates a result.
|
|
854
|
+
|
|
855
|
+
With live work, each WAIT receipt exposes `waitSeconds`, the maximum accepted
|
|
856
|
+
for that operation. It is not elapsed time or a promised sleep: an ordinary wake
|
|
857
|
+
or a shorter sibling WAIT can resume the loop sooner. An idle WAIT has no bound.
|
|
858
|
+
Historical unbounded receipts do not acquire one during projection.
|
|
859
|
+
|
|
860
|
+
| Boundary | Outcome |
|
|
861
|
+
|---|---|
|
|
862
|
+
| Message or work settlement before expiry | Wake normally; retire the old timer. |
|
|
863
|
+
| Several WAITs | One park at the earliest requested bound; a bare WAIT requests the configured bound. |
|
|
864
|
+
| Zero bound | Continue at 102 without parking, a timer, cancellation, or a warning; a later WAIT chooses its own bound. |
|
|
865
|
+
| Eligible completion joining live work | Use the configured bound. |
|
|
866
|
+
| No live work | Continue immediately; do not arm a timer. |
|
|
867
|
+
| Later WAIT after any wake | New wait identity and bound; no inherited override or backoff. |
|
|
868
|
+
| Restart | Restore the durable due time; an overdue wait becomes runnable. |
|
|
869
|
+
| Cancellation or terminal loop | Late timers are inert. |
|
|
870
|
+
| Provider-recovery or client-review wait | Keep its owning recovery/admission semantics, not this observation bound. |
|
|
871
|
+
|
|
872
|
+
A wake preserves the loop's messages, generation policy, cumulative turn ceiling,
|
|
873
|
+
and execution allowance. Parked time does not consume that allowance. Scheduled
|
|
874
|
+
messages remain independent; WAIT neither creates one nor selects its waker.
|
|
847
875
|
|
|
848
876
|
```mermaid
|
|
849
877
|
stateDiagram-v2
|
|
850
878
|
Running --> Parked: atomically persist the wait identity
|
|
851
|
-
Parked --> Queued: arrival / completion /
|
|
879
|
+
Parked --> Queued: arrival / completion / wait expiry, guarded by wait identity
|
|
852
880
|
Parked --> Terminal: cancellation
|
|
853
881
|
Queued --> Running: same loop claimed by its worker's drain
|
|
854
882
|
```
|
|
@@ -964,7 +992,7 @@ completion. Closure is always a wake edge.
|
|
|
964
992
|
|
|
965
993
|
| §worker-lifecycle-poll-matrix stream | While open | On closure |
|
|
966
994
|
|------------------------------------------------|---|---|
|
|
967
|
-
| any lifetime but `turn` |
|
|
995
|
+
| any lifetime but `turn` | bounded wait expiry permits inspection ({§worker-wait-timing}) | resume once with terminal observation |
|
|
968
996
|
| `[{"lifetime":"turn"}]` | reap at the next pre-turn boundary | surface the terminal outcome |
|
|
969
997
|
|
|
970
998
|
The structured-concurrency sequence is identical whether a child performs an
|
|
@@ -980,7 +1008,7 @@ sequenceDiagram
|
|
|
980
1008
|
P->>P: WAIT parks on live child
|
|
981
1009
|
C->>S: execution opens subscription
|
|
982
1010
|
C->>C: WAIT parks on live stream
|
|
983
|
-
loop
|
|
1011
|
+
loop wait expiry or explicit arrival
|
|
984
1012
|
S-->>C: optional progress observation
|
|
985
1013
|
C->>C: continue or park
|
|
986
1014
|
end
|
|
@@ -1082,6 +1110,16 @@ plugin-authored operation turns; exposing that path must not introduce a
|
|
|
1082
1110
|
parallel record or lifecycle. Producer and kind never change. Process-restart
|
|
1083
1111
|
recovery completes any turn whose producer vanished.
|
|
1084
1112
|
|
|
1113
|
+
§turn-exception-outcome An exceptional inference exit completes every still-open
|
|
1114
|
+
turn it acquired, without overwriting completed turns or inventing provider evidence.
|
|
1115
|
+
The turn owner propagates the original exception unchanged.
|
|
1116
|
+
|
|
1117
|
+
| Exception cause | Turn status |
|
|
1118
|
+
|---|---|
|
|
1119
|
+
| The owning aborted signal's reason, directly or through an `Error.cause` chain | 499 for cancellation; 504 for the loop execution deadline. |
|
|
1120
|
+
| An unrelated exception, including an unrelated `AbortError` concurrent with cancellation | 500. An aborted signal alone does not prove causation. |
|
|
1121
|
+
| An `AggregateError` combining cancellation with other failures | 500; cancellation does not conceal another failure. |
|
|
1122
|
+
|
|
1085
1123
|
§turn-ops-admission-path **Source acquisition varies; admitted-turn execution does not.**
|
|
1086
1124
|
A provider response, deterministic `_plurnk` program, or future client/plugin
|
|
1087
1125
|
program crosses one admission boundary into the same executor. That executor
|
|
@@ -1218,7 +1256,8 @@ A crossing terminal names the source that struck the crossing turn — `repetiti
|
|
|
1218
1256
|
`no_operation`, then `operation` — in its detail, in that order when a turn matches more
|
|
1219
1257
|
than one. The three are not interchangeable: a turn that authored no operation did not *fail*
|
|
1220
1258
|
one, and reporting it as a failed turn misreads a model answering without the fence as a model
|
|
1221
|
-
whose operations broke.
|
|
1259
|
+
whose operations broke. A cycle of empty turns names repeated responses without operations,
|
|
1260
|
+
not repeated operations or results. This is the crossing turn's source, not the streak's composition; the
|
|
1222
1261
|
rail rules on the crossing and does not retain the kinds behind it. What the crossing turn
|
|
1223
1262
|
actually said is cited, not discarded ({§terminal-evidence}). Naming the source is not the
|
|
1224
1263
|
private accounting {§rail-accounting-private} withholds: the streak, the cycle verdict and
|
|
@@ -1281,9 +1320,8 @@ The parser owns its boundaries; core admits determinate work and exposes its fai
|
|
|
1281
1320
|
| Bounded program, including malformed operations | Admit valid operations and record parser failures; with no authored operation, apply {§empty-turn}. |
|
|
1282
1321
|
| Outside response text | Store it as the turn's `outside` source under {§outside-text}; never a row, never delivered, never completion. |
|
|
1283
1322
|
| Lost boundary after a closed operation | Admit the closed operations and record the boundary diagnostic under {§unparsed-tail-boundary}. |
|
|
1284
|
-
| Lost boundary before any closed operation | Reject the attempt; neither outside text nor a reasoning NOTE substitutes for a closed
|
|
1323
|
+
| Lost boundary before any closed operation | Reject the attempt; neither outside text nor a reasoning NOTE substitutes for a closed operational statement. Reasoning FIND/READ count as such statements ({§reasoning-operations}). |
|
|
1285
1324
|
| Outside text carrying a log-entry heading, other than an emission row's | Reject the attempt ({§fabricated-log-entry}). |
|
|
1286
|
-
| A response the provider stopped at a repeated line | Reject the attempt with the provider's sentence as its diagnostic ({§repetition-stop}); no provider recovery, notice, or problem row. |
|
|
1287
1325
|
|
|
1288
1326
|
§fabricated-log-entry **Only the harness writes the log.** A line of outside response text that begins with a log-entry heading, `### log:///<loop>/<turn>/<sequence>/` ({§log-wire-format}), is the model continuing the packet's transcript instead of answering it: it writes the receipts it expects and then acts on them. The attempt is rejected under {§invalid-emission-attempts}, so neither that text nor any operation beside it runs or is stored as outside text ({§outside-text}), and its one diagnostic, at the heading's line, reads `` `### log:///2/1/5/READ` is a log entry, and only the harness writes the log. Write the operation, then wait for its receipt. `` Text inside an operation body is not examined, so a SEND or KILL may quote a receipt. A heading whose leaf is `emission` is exempt: the transcript shows it before each of the worker's own emissions ({§emission-row}), and repeating it invents no receipt, so the attempt is admitted and the heading stays outside text, counted by the digest as an echo. In 10,486 recorded emissions, 101 carried such a heading in outside text, every one a fabrication: 85 of 1,675 from deepseek-flash, 81 of them opening with one, and 16 from glm-5.3-flash, deepseek-v4-pro and qwen3.8-flash, which appended an invented `## Log` after their own operations.
|
|
1289
1327
|
|
|
@@ -1464,9 +1502,23 @@ sequences; native messages and workspace outputs use opaque identifiers rather t
|
|
|
1464
1502
|
pretending to be turn coordinates. `worker://<name>` addresses the actor, not a
|
|
1465
1503
|
historical execution. No address grants ownership or access restrictions.
|
|
1466
1504
|
|
|
1467
|
-
§fs-namespace **
|
|
1505
|
+
§fs-namespace **Filesystem coordinates are ordinary paths; internal addresses are project-relative.** `project_root` is the base directory, not a replacement for the operating-system `/`. It is fixed at workspace creation; a headless workspace has no implicit filesystem base. Absolute paths and paths emitted by executors name the same filesystem locations as they do on the host. Resolution never grants membership or creation authority ({§fs-visibility-grantors}, {§fs-write-surface}); an outside-root member retains its `../`-prefixed key. Plurnk is not a sandbox: confinement belongs to the host.
|
|
1468
1506
|
|
|
1469
|
-
§fs-namei **
|
|
1507
|
+
§fs-namei **Resolve, then relativize, through one pathname resolver.** Resolve relative input against `project_root` and absolute input from the operating-system root, normalize lexical `.`/`..` segments, then translate the result to a `project_root`-relative key before storage, comparison or canonical rendering. Physical membership and symlink checks remain separate. No failed absolute lookup retries as a project-relative spelling.
|
|
1508
|
+
|
|
1509
|
+
| Input with `project_root=/work/project` | Canonical address |
|
|
1510
|
+
|---|---|
|
|
1511
|
+
| `src/x.md`, `./src/x.md`, `/work/project/src/x.md` | `src/x.md` |
|
|
1512
|
+
| `/src/x.md` | `../../src/x.md` |
|
|
1513
|
+
| `../policy.md`, `/work/policy.md` | `../policy.md` |
|
|
1514
|
+
| `.`, `/work/project/` | The project collection, not a file entry |
|
|
1515
|
+
| `/` | `../../`, the operating-system root collection |
|
|
1516
|
+
|
|
1517
|
+
At `project_root=/`, `/src/x.md` and `src/x.md` resolve to the same key. Without a project root, absolute paths cannot be translated; no process CWD or home directory is substituted.
|
|
1518
|
+
|
|
1519
|
+
Folders and globs select members in those same filesystem coordinates. Parent-directory selectors may include in-root and outside-root members; they never scan or admit unrelated disk contents. Catalog paths and grouped subtree selectors remain project-relative.
|
|
1520
|
+
|
|
1521
|
+
§file-path-normalization An authored model file operation using an absolute path receives a `scheme:file/path_normalized` warning Notice naming its project-relative address. COPY/MOVE cover each absolute operand. The Notice neither changes the operation result nor causes a strike, and does not repeat for automatic observations or already-relative paths. Root-mounted workspaces need no such notice. It never suggests that an unadmitted path has become a member.
|
|
1470
1522
|
|
|
1471
1523
|
§fs-canonical-name **One canonical name, storage ≡ wire: the git pathspec.** Member keys follow gitformat-index(5) verbatim (reference edition: git 2.47.3): relative to the workspace `project_root`, without leading slash, `/`-separated, no trailing slash or NUL. Directories are never entries and the root needs no name. When `project_root` is below the containing repository's top level, Git members above it naturally use the same `../`-prefixed CWD-relative names that `git ls-files` emits without `--full-name`; these are not outside-repository mounts. The database stores that root-relative key directly because workspace identity is rooted at the access point. Every model spelling canonicalizes before storage or comparison.
|
|
1472
1524
|
|
|
@@ -1588,7 +1640,7 @@ Registration precedes loop affinity:
|
|
|
1588
1640
|
- §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, a stream-producing 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 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.
|
|
1589
1641
|
- §edit-execution **One authored EDIT 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.
|
|
1590
1642
|
- §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.
|
|
1591
|
-
- §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.
|
|
1643
|
+
- §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.
|
|
1592
1644
|
- §edit-batch **One compound operation may require atomic splices.** The scheme's `editBatch` primitive validates all supplied numeric edits against one snapshot and commits one revision or none. Core supplies one statement for an authored EDIT; same-resource MOVE can supply multiple splices as one operation. This primitive does not group separate authored operations. Its replacement, insertion, conflict, and receipt rules remain owned by the shared Slicer.
|
|
1593
1645
|
- §edit-batch-receipt **A refusal describes its own unapplied work.** An anchor collision lists every distinct unresolved anchor in that EDIT, including both range endpoints, in `unresolvedAnchors` (`anchor`, `kind: missing | ambiguous`, and matching `lines` when ambiguous). Missing is not proof of earlier validity or subsequent change. It carries `editCount: 1`, `applied: 0`, and recovery directing a READ for current coordinates; it makes no claim about other operations. A refused compound splice batch lists all conflicting pairs in `conflicts`, non-conflicting regions in `cleanRegions`, its first pair in `conflictingRegions`, and its own `editCount` and `applied: 0`.
|
|
1594
1646
|
- §edit-batch-merges **Normalizations require evidence and a receipt.** An EDIT body carrying only this resource's published `L<@xxxxx>` prefixes (the number right-aligned) is stripped when those prefixes verify against current anchors or this worker's preserved READ receipts (`rendered-prefix-stripped`); otherwise it remains literal content (`rendered-prefix-unverified`). Within a single atomic splice batch, the Slicer can deduplicate identical regions/bodies, concatenate same-boundary insertions, assign a shared endpoint to the sole body reproducing that line, or relocate an inner change when its original content occurs exactly once in the outer body. An already-applied inner body can be dropped. Unevidenced overlap remains a collision. These batch resolutions never reinterpret separate authored EDITs. Applied normalizations carry their exact merge facts and a notice; receipts describe only the applied effects.
|
|
@@ -2010,24 +2062,24 @@ AST: `{ op: "EDIT", target, body: string | null, signal: tags | null, lineMarker
|
|
|
2010
2062
|
```` ```EDIT (path) [{"pattern": "/foo/"}] ```` reads the resource once under
|
|
2011
2063
|
the channel's own mimetype, matches, and expands into one atomic batch
|
|
2012
2064
|
({§edit-batch}) of four-coordinate splices, all relative to the same original
|
|
2013
|
-
content: a regex span is its
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2065
|
+
content under {§slice-semantics-compose-pattern}: a regex span is its match;
|
|
2066
|
+
a literal is each substring occurrence; a glob selects matching line content;
|
|
2067
|
+
a node dialect's span (`//` xpath, `$` jsonpath) is the selected node's source
|
|
2068
|
+
region, not its enclosing context, across as
|
|
2017
2069
|
many lines as the node spans, so ```` ```EDIT (books.xml) [{"pattern":
|
|
2018
2070
|
"//book[price > 35]"}] ```` replaces each such element and an empty body
|
|
2019
|
-
removes it.
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2071
|
+
removes it. FTS uses its located token/phrase occurrences; graph uses the
|
|
2072
|
+
definitions or references selected under {§graph-relations}. The body is
|
|
2073
|
+
literal replacement text, never a template; an absent body deletes only the
|
|
2074
|
+
spans. Regex anchors apply per line (`^`, `$`); matches may cross line breaks.
|
|
2075
|
+
A numeric scope admits only complete matches inside its resolved source
|
|
2076
|
+
region, including columns; `<0>` and `<-1>` name insertion positions and are refused
|
|
2024
2077
|
(400 `pattern-scope-invalid`). Every touched line's anchor guards the batch as a
|
|
2025
2078
|
precondition, so a same-turn change to one of them is the ordinary
|
|
2026
2079
|
{§edit-collision}. Zero matches change nothing: 204 with `matched: 0`, never a
|
|
2027
2080
|
clobber. The result is one operation receipt: `matched` spans, `receipt` for the
|
|
2028
2081
|
first splice ({§edit-result-receipt-projection}), and `last` beside it for the
|
|
2029
|
-
final one when there were several.
|
|
2030
|
-
name no spans: 400 `pattern-dialect-unsupported`. A scheme without textual EDIT scopes refuses the
|
|
2082
|
+
final one when there were several. A scheme without textual EDIT scopes refuses the
|
|
2031
2083
|
pattern before any read (400 `pattern-unsupported`). Same-turn anchor continuity
|
|
2032
2084
|
({§edit-anchor-continuity}) does not carry through a pattern batch; the next
|
|
2033
2085
|
anchored EDIT validates against current state.
|
|
@@ -2058,25 +2110,20 @@ READ is the one fan-out core performs ({§read-fan-out}).
|
|
|
2058
2110
|
- §log-range-miss-names-stream A 416 on a log execution item is the range twin of its channel miss ({§log-channel-miss-names-stream}): the coordinate addresses the row's invocation (its authored call body, often empty or one line) while the execution's output stays readable at the stream address the row records. When that stream link exists, the 416 gains it as `stream`, the detail appends where the command's streams live, and `recovery` is `READ <stream> for the command's stream`, whether the invocation's extent is empty or merely shorter than the range (#759). A 416 on a row with no recorded stream stays byte-identical to the generic slicer's.
|
|
2059
2111
|
- §read-pattern **A pattern selects the lines a READ renders.** With a heading
|
|
2060
2112
|
matcher ({§matcher-option} in the contracts SPEC) an exact-target READ stays a
|
|
2061
|
-
READ: the matcher runs over the channel's text
|
|
2062
|
-
each line, so `^` and `$` are the line's ends — and every line a match touches,
|
|
2113
|
+
READ: the matcher runs over the channel's complete text — a regex anchors
|
|
2114
|
+
each line, so `^` and `$` are the line's ends, while matches may span lines — and every line a match touches,
|
|
2063
2115
|
in source order, is the visible selection. The scope still bounds it: a scoped
|
|
2064
2116
|
READ renders exactly the selected lines the scope holds; a whole-resource one
|
|
2065
2117
|
pages through the selected lines under the ordinary preview bound, never showing
|
|
2066
2118
|
an unselected line. Selected lines keep their physical ordinals and their
|
|
2067
2119
|
ordinary anchors, so a pattern READ is a coordinate source for EDIT and KILL. The
|
|
2068
2120
|
result carries `matched`, the count of selected lines inside the scope. Zero
|
|
2069
|
-
matches is an empty read (204, `matched: 0`), never a failure.
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
matcher's own 415/400 ({§matcher-dispatch}).
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
matcher and says only FIND takes it, and its recovery gives both working forms with the
|
|
2076
|
-
model's own target: the FIND carrying that matcher, and the same operation with a text
|
|
2077
|
-
pattern built from the symbol or words it named (regex metacharacters escaped, words joined
|
|
2078
|
-
by `|`): `` Locate it with `FIND (django/urls/resolvers.py) &RoutePattern`, or select lines
|
|
2079
|
-
with a text pattern: `READ (django/urls/resolvers.py) /RoutePattern/`. ``
|
|
2121
|
+
matches is an empty read (204, `matched: 0`), never a failure. Full-text and
|
|
2122
|
+
graph matches project their located occurrences through the same line
|
|
2123
|
+
presentation. A matcher its mimetype cannot run answers the
|
|
2124
|
+
matcher's own 415/400 ({§matcher-dispatch}). A selected value with neither
|
|
2125
|
+
exact nor enclosing source coordinates answers 422 `pattern-source-unlocated`;
|
|
2126
|
+
READ does not substitute an unrelated ancestor or the whole resource.
|
|
2080
2127
|
- §read-fan-out **A READ over a glob reads every matching path.** `READ (pets_*.md)`
|
|
2081
2128
|
and `READ (pets_*.md) /dogs/i` keep their glob ({§read-find-normalization} in the
|
|
2082
2129
|
contracts SPEC) and dispatch fans them out: the ordinary FIND over the same
|
|
@@ -2095,8 +2142,24 @@ READ is the one fan-out core performs ({§read-fan-out}).
|
|
|
2095
2142
|
receipt on the authored glob (`matched: 0` when a pattern selected nothing); a
|
|
2096
2143
|
FIND failure is that failure on the authored glob. The FIND's resource page bounds
|
|
2097
2144
|
the fan-out: when more paths matched than were read, one `read_fanout_bounded`
|
|
2098
|
-
notice names both counts.
|
|
2099
|
-
|
|
2145
|
+
notice names both counts. Every dialect follows this same READ fan-out;
|
|
2146
|
+
none substitutes a FIND receipt for the requested content.
|
|
2147
|
+
|
|
2148
|
+
§read-pattern-evidence **Match regions survive line-oriented presentation.** A patterned
|
|
2149
|
+
READ retains `matches` ({§matcher-selection-signal}) for findings intersecting its
|
|
2150
|
+
returned text, in physical source coordinates. The body shows matching lines;
|
|
2151
|
+
its `range` describes that presentation, not the match boundaries. A match's
|
|
2152
|
+
region is never clipped into a different selection when a preview or authored
|
|
2153
|
+
READ scope shows only part of it. An empty read carries an empty match array.
|
|
2154
|
+
|
|
2155
|
+
The packet projects each visible match's `locator`, exact `region`, or
|
|
2156
|
+
explicitly enclosing `enclosingRegion`
|
|
2157
|
+
using {§packet-extent-metadata}, without duplicating matched body text. Log
|
|
2158
|
+
curation removes metadata for matches outside the retained body. Match metadata
|
|
2159
|
+
uses the ordinary preview allowance ({§body-projection}), keeping only complete
|
|
2160
|
+
items; `matchLocationCount` appears when that preview omits locations. Exact
|
|
2161
|
+
FIND pages the complete location set ({§find-result-projection}).
|
|
2162
|
+
|
|
2100
2163
|
- §read-bytes A binary channel, and the `#bytes` view of
|
|
2101
2164
|
any resource whose scheme supplies bytes, reads as the source bytes one hexadecimal
|
|
2102
2165
|
octet per line: coordinate = line = byte, so `<a,b>` selects bytes, the markerless
|
|
@@ -2116,34 +2179,24 @@ READ is the one fan-out core performs ({§read-fan-out}).
|
|
|
2116
2179
|
into a byte READ (`region` spans the hexadecimal lines of the matched bytes; `matched`
|
|
2117
2180
|
is their hex). The load is bounded by the mimetypes binary input ceiling; a larger
|
|
2118
2181
|
resource fails 413 `bytes-too-large` by name rather than being skipped.
|
|
2119
|
-
- §binary-parity
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
content
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
is not an empty success: its producer outcome remains authoritative for READ and transfer.
|
|
2138
|
-
This supersedes the older blanket refusal (#140)
|
|
2139
|
-
for both the file and the entry case. Native image/PDF/audio attachment facts come from the configured
|
|
2140
|
-
mimetype handler over original bytes, whether supplied by a file or stored channel
|
|
2141
|
-
({§packet-attachment-parts}); the hexadecimal view remains available. The exceptions are narrow and
|
|
2142
|
-
defined, each a clear receipt rather than a dead end: a binary region addressed by a **textual anchor**
|
|
2143
|
-
rather than a numeric byte coordinate has no meaning (416 — bytes are not lines), **authoring** binary
|
|
2144
|
-
content from a text EDIT body is impossible (a text emission cannot type bytes), and a scheme that keeps
|
|
2145
|
-
no bytes for a binary channel — no disk file, no stored content — has nothing to transfer and says so
|
|
2146
|
-
(415). None is the entry-storage dead end the older text named; that cell is filled.
|
|
2182
|
+
- §binary-parity Binary resources share ordinary existence, membership, FIND-by-path,
|
|
2183
|
+
deletion, and proposal rules. Files supply native bytes; DB-backed channels store
|
|
2184
|
+
them as base64 and recover the same bytes through their byte source. Empty binary
|
|
2185
|
+
content is zero bytes, never an unsupported format. Acquisition failure preserves
|
|
2186
|
+
its producer result and cannot become a successful empty transfer.
|
|
2187
|
+
|
|
2188
|
+
| Binary operation | Contract |
|
|
2189
|
+
| --- | --- |
|
|
2190
|
+
| READ / FIND | Hexadecimal byte projection and byte-pattern coordinates under {§read-bytes}/{§find-bytes}. Eligible image/PDF/audio attachments use original bytes independently ({§packet-attachment-parts}). |
|
|
2191
|
+
| Whole COPY / MOVE | Markerless or `<1,-1>` transfers the original bytes verbatim ({§move-canonical-whole-source}); MOVE deletes its source after the destination lands. |
|
|
2192
|
+
| Source range or pattern | `<a,b>` selects 1-indexed inclusive bytes. Patterns use {§find-bytes}; a source scope admits complete matches. Fragments concatenate without separators. MOVE removes exactly those bytes after destination success. |
|
|
2193
|
+
| Destination range | `<c,d>` replaces bytes c..d; `<c>` inserts before byte c, `<0>` prepends, and `<-1>` appends. All coordinates name the pre-mutation source. Other bytes remain unchanged. |
|
|
2194
|
+
| Same-channel MOVE | Destination insertion and source removal use one pre-mutation snapshot and one proposal-gated write. Overlapping selections refuse with 409 before writing. |
|
|
2195
|
+
| Deferred MOVE | The source byte snapshot is retained as a content-hash precondition; changed bytes refuse removal with 409 `edit-collision`. A landed destination remains reported under {§copy-move-observation}. |
|
|
2196
|
+
| Mutation result | Ordinary proposal gate and byte count; no fabricated text diff. |
|
|
2197
|
+
| Text anchor on a transfer | 416: native byte coordinates are numeric. |
|
|
2198
|
+
| Text EDIT of native bytes | 415: an EDIT body authors text, not native bytes. |
|
|
2199
|
+
| Binary channel without a byte source | 415, not an empty success. |
|
|
2147
2200
|
|
|
2148
2201
|
### §log-history-projection Durable history and active projection
|
|
2149
2202
|
|
|
@@ -2177,11 +2230,12 @@ same transitions the dispatcher's atomic curation event makes, without the row.
|
|
|
2177
2230
|
|
|
2178
2231
|
### §reasoning-initial-read Initial reasoning observation
|
|
2179
2232
|
|
|
2180
|
-
The initialization turn records
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2233
|
+
The initialization turn records its `_plurnk`-authored rationale and complete
|
|
2234
|
+
NOTE/FIND/READ program as one reasoning source before dispatch. The shared
|
|
2235
|
+
reasoning extractor ({§reasoning-operations}) admits every operation once, in
|
|
2236
|
+
source order. Its final READ observes that same reasoning source, including
|
|
2237
|
+
the READ itself; this is an ordinary read of already stored text, not recursion
|
|
2238
|
+
or a future-source subscription. The initial message arrives separately as an
|
|
2185
2239
|
inbound SEND ({§message-arrival}). Neither initialization nor later turns
|
|
2186
2240
|
manufacture a task inventory.
|
|
2187
2241
|
`PLURNK_REASONING_VIEW_LINES` (alias-scoped, default in `.env.defaults`) selects this one READ's
|
|
@@ -2190,13 +2244,14 @@ bounds it to the first N lines. Source retention, deliberate READs, and client
|
|
|
2190
2244
|
streaming are independent. The only other automatic reasoning READ follows an empty
|
|
2191
2245
|
turn ({§reasoning-empty-turn-read}).
|
|
2192
2246
|
|
|
2193
|
-
§reasoning-empty-turn-read **
|
|
2194
|
-
turn admitted under {§empty-turn}, one runtime turn of the same loop
|
|
2247
|
+
§reasoning-empty-turn-read **Operation-free reasoning is read back for recovery.** After a
|
|
2248
|
+
turn admitted under {§empty-turn} with no admitted reasoning operations, one runtime turn of the same loop
|
|
2195
2249
|
(`{ producer="_plurnk", kind="operation" }`) dispatches
|
|
2196
2250
|
`READ (reasoning://<worker>/<loop>/<turn>) <!-- turn N emitted no OP -->` over that turn's stored
|
|
2197
2251
|
reasoning source; its receipt renders in the next packet like any other log row.
|
|
2198
2252
|
`PLURNK_REASONING_EMPTY_TURN_LINES` (alias-scoped, default in `.env.defaults`) selects the scope on the same
|
|
2199
|
-
scale as `PLURNK_REASONING_VIEW_LINES`.
|
|
2253
|
+
scale as `PLURNK_REASONING_VIEW_LINES`. Any admitted reasoning NOTE, FIND or READ suppresses
|
|
2254
|
+
this recovery readback. No read follows a turn without reasoning, and none follows
|
|
2200
2255
|
a turn whose emission or reasoning carries a foreign tool-call grammar or leaked template token
|
|
2201
2256
|
(`KnownToxins` names them); the strike and its error row are unchanged.
|
|
2202
2257
|
|
|
@@ -2223,7 +2278,11 @@ Coordinates and anchors retain the original body's physical lines; selection occ
|
|
|
2223
2278
|
before omitted lines are removed, and sparse receipts retain their original line
|
|
2224
2279
|
ordinals. Automatic previews remain retrieval bounds, not deletions. COPY can read
|
|
2225
2280
|
an active log source under ordinary read authority, without minting log history;
|
|
2226
|
-
destinations
|
|
2281
|
+
entry destinations require independently writable storage; MOVE retires its
|
|
2282
|
+
source under {§move-decomposition}. A pattern spanning retained lines on either
|
|
2283
|
+
side of a curated gap maps to separate exact source regions, never to a bounding
|
|
2284
|
+
region that restores hidden lines. Concatenating those fragments reproduces only
|
|
2285
|
+
the matched readable text.
|
|
2227
2286
|
Trimming invalidates derived search attachments; an in-flight derivation attaches
|
|
2228
2287
|
only if its source projection is still current. Forks copy both projection facts;
|
|
2229
2288
|
forensics always retain the complete immutable body and curation history.
|
|
@@ -2344,7 +2403,7 @@ The packet projects one actionable owner for each retrieval fact:
|
|
|
2344
2403
|
| catalog/path FIND | `range` in resources | none | none |
|
|
2345
2404
|
| broad matcher FIND | `range` in resources | per-resource match-location counts; a resource with exactly one match also carries that match's `locator`/`region` | nonzero complete `matchLocationCount` |
|
|
2346
2405
|
| exact matcher FIND | `range` in match locations | each row's locator/region; a regex or glob row also carries `matched`, the matched text | none |
|
|
2347
|
-
| pattern READ ({§read-pattern}) | `range` over the physical lines |
|
|
2406
|
+
| pattern READ ({§read-pattern}) | `range` over the physical lines | selected lines with ordinals and anchors; precise `matches` under {§read-pattern-evidence} | heading pattern and selected-line `matched`; `matchLocationCount` only when the metadata preview omits locations |
|
|
2348
2407
|
|
|
2349
2408
|
Any row whose statement carried a heading pattern ({§matcher-option}) retains it
|
|
2350
2409
|
in its H3, and a pattern mutation ({§edit-pattern}, {§kill-pattern},
|
|
@@ -2376,7 +2435,7 @@ single line past the end, a reversed range, empty content, a command's log row
|
|
|
2376
2435
|
|
|
2377
2436
|
### §turn-ops-entry The admitted turn program
|
|
2378
2437
|
|
|
2379
|
-
§turn-ops-log-curation A source-backed turn preserves its **exact
|
|
2438
|
+
§turn-ops-log-curation A source-backed turn preserves its **exact content emission**, including ignored interstitial text, before dispatch. `turn_sources` records that source once, separately from reasoning, the curatable log and optional provider evidence. Retention does not manufacture a log row; the one row an admitted emission gains is its announcement ({§emission-row}). Ordinary READ creates a receipt governed by {§log-readable-projection}; curation of either never changes the source.
|
|
2380
2439
|
|
|
2381
2440
|
### §emission-row The emission row
|
|
2382
2441
|
|
|
@@ -2386,10 +2445,10 @@ like any other row.
|
|
|
2386
2445
|
|
|
2387
2446
|
| Surface | Contract |
|
|
2388
2447
|
|---|---|
|
|
2389
|
-
| When | An inference turn that admitted at least one statement
|
|
2448
|
+
| When | An inference turn that admitted at least one content statement. Reasoning-only turns, including initialization ({§worker-initialization-entry}), a programmatic batch, an empty turn ({§empty-turn}), a client operation and a rejected attempt ({§rejected-emission-entry}) announce nothing. |
|
|
2390
2449
|
| Place | After the turn's inputs (arrivals, deltas, open-path READs) and before its reasoning NOTEs and operations, written after the selection snapshot ({§turn-ops-selection-snapshot}): the emission sits between what the worker had seen and what it caused. |
|
|
2391
2450
|
| Row | A `_plurnk` READ of the turn's own source, `ops://<worker>/L/T`, with `attrs.kind="emission"` and the canonical leaf `/emission`: `### log:///L/T/S/emission → ops://<worker>/L/T · N`. It renders its author, the turn's producer, as `origin`, so a model's row carries none. It is no operation: no receipt, tool call or strike, and outside the op mix. |
|
|
2392
|
-
| Body | Frozen at announcement: the canonical rendering ({§statement-rendering}) of
|
|
2451
|
+
| Body | Frozen at announcement: the canonical rendering ({§statement-rendering}) of admitted content statements, each in a closed fence. Each body appears within the shared preview bound ({§body-projection}), `PLURNK_SERVICE_PREVIEW_LINES` and `PLURNK_SERVICE_PREVIEW_CHARS`. A longer body keeps its head, and its closing fence carries `<!-- Automatically truncated op body: READ (ops://<worker>/L/T) to retrieve in full -->`; nothing the harness writes enters a fence. Absent and empty bodies remain empty. All heading operands, scopes, metadata, patterns and asides remain. Free text and unadmitted forms are absent; a recovered native call ({§native-tool-calls}) appears as the operation it was read as; an operation whose receipt failed stays. Reasoning operations retain their own source and normal receipts, never an assistant-content copy. No body text is inspected for nested operations. |
|
|
2393
2452
|
| Sources and memory | Dispatch and immutable `ops://` sources retain complete bodies ({§turn-source-resources}); an explicit source READ returns them normally. The wire omits NOTE and WAIT blocks, whose own rows show them whole ({§body-projection}), so curating a NOTE row removes its text; an emission of only NOTE and WAIT delivers nothing, its row stands, and no assistant message follows it ({§packet-wire-envelope}); reasoning-only NOTEs never enter this projection. |
|
|
2394
2453
|
| 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. |
|
|
2395
2454
|
| Presentation | Born folded: the record shows its header, and its body follows the record as the worker's assistant message. |
|
|
@@ -2561,24 +2620,23 @@ Operand syntax: {§transfer-resource-selections}. Result projection: {§copy-mov
|
|
|
2561
2620
|
channel is 404. Entry sources follow {§membership-source-projection}; active
|
|
2562
2621
|
log sources follow {§log-readable-projection}. Binary sources transfer bytes
|
|
2563
2622
|
under {§binary-parity}; text anchors resolve under {§line-anchors}.
|
|
2564
|
-
- §copy-move-pattern **A source pattern selects
|
|
2623
|
+
- §copy-move-pattern **A source pattern selects exact source spans; a
|
|
2565
2624
|
destination is a place.** A source operand's heading pattern
|
|
2566
2625
|
(```` ```COPY (notes.md) [{"pattern": "TODO"}] (todos.md) <-1> ````) runs
|
|
2567
|
-
over the source
|
|
2568
|
-
the source shows ({§log-readable-projection})
|
|
2569
|
-
|
|
2570
|
-
|
|
2626
|
+
over the addressed source channel, bounded by the source scope and by what
|
|
2627
|
+
the source shows ({§log-readable-projection}). The selected fragments are
|
|
2628
|
+
concatenated verbatim in source order, without invented separators or
|
|
2629
|
+
enclosing line context ({§slice-semantics-compose-pattern}). The result
|
|
2630
|
+
reports `matched` spans. Zero
|
|
2571
2631
|
matches transfer nothing: 204 with `matched: 0`, and no destination is
|
|
2572
|
-
created. A MOVE
|
|
2573
|
-
path, one empty-body
|
|
2574
|
-
anchors ({§edit-pattern});
|
|
2632
|
+
created. A textual MOVE removes exactly those spans through the source's EDIT
|
|
2633
|
+
path, one empty-body exact splice per span in one batch guarded by their
|
|
2634
|
+
anchors ({§edit-pattern}); byte selections use {§binary-parity}. Within one channel the insertion and the removals
|
|
2575
2635
|
are one atomic batch, and a deferred MOVE ({§proposal}) retires the same
|
|
2576
|
-
|
|
2636
|
+
spans after acceptance. A curated source retires rows, not arbitrary text of its
|
|
2577
2637
|
projection, so a pattern MOVE from `log:///` is 400 `pattern-unsupported`
|
|
2578
|
-
(COPY
|
|
2579
|
-
|
|
2580
|
-
the destination is 400 `pattern-destination-unsupported`; resource-selecting
|
|
2581
|
-
dialects (`~`, `&`) are 400 `pattern-dialect-unsupported`.
|
|
2638
|
+
(COPY its selected text, then KILL its rows by pattern). A pattern on
|
|
2639
|
+
the destination is 400 `pattern-destination-unsupported`.
|
|
2582
2640
|
2. Resolve destination path, channel, and optional text scope. Source and
|
|
2583
2641
|
destination mimetypes must be compatible under {§mimetype-verbatim-transfer}
|
|
2584
2642
|
or the result is 415. Destination anchors
|
|
@@ -2741,7 +2799,7 @@ same durable liveness.
|
|
|
2741
2799
|
| New unpublished message | Continue; publish it in the next packet. |
|
|
2742
2800
|
| Fresh operation/parser failure, without an authored WAIT | Continue before any automatic parking. |
|
|
2743
2801
|
| Neither an authored WAIT nor an eligible completion request ({§kill-conclusion}) | Continue, regardless of earlier replies or live work. |
|
|
2744
|
-
| Live work and either WAIT or an eligible completion request | Park the same loop; message arrival, child or stream settlement, or
|
|
2802
|
+
| Live work and either WAIT or an eligible completion request | Park the same loop; message arrival, child or stream settlement, or wait expiry wakes it ({§worker-wait-timing}). No final-answer body is delivered while joining. |
|
|
2745
2803
|
| WAIT without live work | Continue; never invent a future wake. Its row says only `Nothing is in flight. Continuing.`, however often the loop yields this way. |
|
|
2746
2804
|
| Unobserved operation results, failures, child results or stream conclusions | Continue; the next packet presents them. |
|
|
2747
2805
|
| Eligible completion request with no unpublished arrivals, live work or unobserved results | Conclude successfully, whether or not it delivers an answer. |
|
|
@@ -2837,8 +2895,8 @@ accounting and model-visible failure evidence remain separately owned by
|
|
|
2837
2895
|
remains that turn's emission. A concluded child's `loop_termination` row to its parent
|
|
2838
2896
|
READs this same loop resource. Witness: `test/intg/loop-answer.test.ts`.
|
|
2839
2897
|
- §empty-turn **No authored response operation is a recoverable turn, never completion.**
|
|
2840
|
-
Count parsed
|
|
2841
|
-
text ({§outside-text}) enter the count. When none exist and no boundary was lost, retain the turn
|
|
2898
|
+
Count parsed content operations and reasoning FIND/READs ({§reasoning-operations}); neither
|
|
2899
|
+
reasoning NOTEs nor outside text ({§outside-text}) enter the count. When none exist and no boundary was lost, retain the turn
|
|
2842
2900
|
and its raw sources and count one progress-contract strike, whether or not the turn carried text. The strike sends no notice of its own: the turn records one `_plurnk`
|
|
2843
2901
|
error row, `422` `The turn performed no operation.`, which rides the next packet's errors like
|
|
2844
2902
|
any failure ({§operation-result-uniform-error-channel}), and its reasoning is read back to the
|
|
@@ -2947,8 +3005,9 @@ target that cannot be read keeps the owning READ's failure identity (#163) and s
|
|
|
2947
3005
|
the slot contract in its recovery — the resource is the program and the body its stdin;
|
|
2948
3006
|
a command belongs beneath a targetless heading — without guessing which was meant (#425). The started receipt always
|
|
2949
3007
|
names the working directory only when it is not the project root, and then in the
|
|
2950
|
-
|
|
2951
|
-
|
|
3008
|
+
project-relative form ({§fs-namespace}); the default directory is omitted rather
|
|
3009
|
+
than repeated in every receipt. Native file addresses resolve from that same project
|
|
3010
|
+
directory, while absolute input retains its filesystem meaning. The `(path)` is a program — a script for an interpreter, a tool name for a tool
|
|
2952
3011
|
family — and neither a command nor a working directory is ever a target. The default
|
|
2953
3012
|
shell is written as its own fence, ```` ```sh ````; no runtime-less form exists.
|
|
2954
3013
|
|
|
@@ -3087,14 +3146,10 @@ executor target is refused `scope-unsupported` (400), naming the field.
|
|
|
3087
3146
|
| `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}). |
|
|
3088
3147
|
| `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. |
|
|
3089
3148
|
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
the loop is active, because ambient stream deltas already surface progress.
|
|
3095
|
-
Closure is a wake edge regardless. Child-only joins never use this timer: child
|
|
3096
|
-
settlement is their durable wake edge. A recurring check on the calendar is a
|
|
3097
|
-
schedule targeting yourself ({§schedule-delivery}), not a loop that polls.
|
|
3149
|
+
Observation timing belongs to the bounded wait ({§worker-wait-timing}), separately
|
|
3150
|
+
from execution lifetime. Wait expiry permits inspection of still-running work;
|
|
3151
|
+
closure remains an independent wake edge. Active loops already receive ambient
|
|
3152
|
+
stream deltas. Calendar recurrence remains a schedule ({§schedule-delivery}).
|
|
3098
3153
|
|
|
3099
3154
|
§exec-host-proposes **Effect-gating.** Each executor — and each scheme operation that mutates something outside this process — declares an `effect` (`pure` | `read` | `host`); the service maps it to policy (`EffectPolicy`). The declarer states the FACT, the panel decides the POLICY, and one rule covers every operation: nothing that changes the world runs on nobody's authority. A `host` runtime (subprocess; file-backed sqlite) proposes under {§proposal}, and so does an outbound request that mutates a remote resource ({§http-outbound-proposes}). Once accepted, it spawns and writes channels at its workspace execution address ({§execution-output-identity}), returning `102 Processing`. Channel state transitions (`active` → `closed`/`errored`) drive subsequent observations ({§channel-state}).
|
|
3100
3155
|
|
|
@@ -3160,7 +3215,7 @@ two states and no others:
|
|
|
3160
3215
|
|
|
3161
3216
|
| state | what the model receives |
|
|
3162
3217
|
|---|---|
|
|
3163
|
-
| active | nothing in the Log. The `## Delegation` stream pointer
|
|
3218
|
+
| active | nothing in the Log. The `## Delegation` 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. |
|
|
3164
3219
|
| 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}). |
|
|
3165
3220
|
|
|
3166
3221
|
§stream-observation-result **One liveness fact.** The durable READ result owns
|
|
@@ -3308,7 +3363,7 @@ body prefixes.
|
|
|
3308
3363
|
|
|
3309
3364
|
## §proposal Proposals and client interactions
|
|
3310
3365
|
|
|
3311
|
-
§proposal-202-pauses A side-effecting op does not execute on dispatch — it **proposes**. The scheme returns **202** (an execution on a `host` runtime {§exec}, an EDIT to a member file {§membership}); the engine writes the log row `state='proposed'`, registers a waiter keyed by `logEntryId`, and **pauses `dispatch`** awaiting a resolution. The provider exchange and emitted operation are already durable, while the turn remains open until dispatch settles; {§engine-rails} therefore sees the *resolved* status, never the provisional 202.
|
|
3366
|
+
§proposal-202-pauses A side-effecting op does not execute on dispatch — it **proposes**. The scheme returns **202** (an execution on a `host` runtime {§exec}, an EDIT to a member file {§membership}); the engine writes the log row `state='proposed'`, registers a waiter keyed by `logEntryId`, and **pauses `dispatch`** awaiting a resolution. The provider exchange and emitted operation are already durable, while the turn remains open until dispatch settles; {§engine-rails} therefore sees the *resolved* status, never the provisional 202. Acceptance runs the scheme's effect and settles with its result ({§proposal-accept-applies}).
|
|
3312
3367
|
|
|
3313
3368
|
**Resolution arrives through one lifecycle:**
|
|
3314
3369
|
|
|
@@ -3320,7 +3375,7 @@ body prefixes.
|
|
|
3320
3375
|
|
|
3321
3376
|
| decision | state | `status_rx` | default outcome | effect |
|
|
3322
3377
|
|---------------------------------|---|---|---|---|
|
|
3323
|
-
| §proposal-accept-applies accept | `resolved` | 200 | — | runs the scheme's **`applyResolution`** — the real side effect (disk write, exec spawn). An unavailable handler returns `410 handler-unavailable`, never success. A failing apply (≥400)
|
|
3378
|
+
| §proposal-accept-applies accept | `resolved`, or `failed` when application fails | applied result's status, otherwise 200 | — | runs the scheme's **`applyResolution`** — the real side effect (disk write, exec spawn). An unavailable handler returns `410 handler-unavailable`, never success. A failing apply (≥400) preserves its result and marks the row failed without changing the client's decision; its outcome is retained, or `apply_failed` when it names none. |
|
|
3324
3379
|
| §proposal-reject-fails reject | `failed` | 400 | `rejected` | none — the action did not occur. |
|
|
3325
3380
|
| §proposal-cancel-aborts cancel | `cancelled` | 499 | `loop_aborted` | none — the loop is abandoning. |
|
|
3326
3381
|
|
|
@@ -3489,6 +3544,20 @@ Capability admission precedes this decision, so proposal disposition cannot gran
|
|
|
3489
3544
|
|
|
3490
3545
|
The durable row is lifecycle evidence and the lookup key, not a serialized callback. `subscriptions.open()` establishes both halves before yielding a composed `StreamSubscription`: an `AbortSignal` whose fused `notifyChunk` and terminal `close` methods are safe to retain without the operation's general `SchemeCtx`. `close(result, summary?, channelResults?)` validates one universal terminal producer result plus exact named channel overrides. One SQLite transition closes the subscription and installs each channel's terminal `producerResult`; its lifecycle state derives from that result. The transition then wakes the worker when appropriate and unregisters the live handle. `close_status` is a constrained relational projection of `close_result.status`, never an independent result, while `channel_results` preserves historical overrides after a later subscription replaces the channel's current evidence. A durable open row without a live handle is an explicit lifecycle failure, never a fabricated cancellation success. Channel state ({§channel-state}) + log entries ({§no-chunk-rows}) carry lifecycle.
|
|
3491
3546
|
|
|
3547
|
+
§subscription-finalization Executors and scheme subscriptions share the durable
|
|
3548
|
+
close boundary. Concurrent closes join one attempt; a committed close is
|
|
3549
|
+
idempotent, including its completion wake.
|
|
3550
|
+
|
|
3551
|
+
| Boundary | Ownership and recovery |
|
|
3552
|
+
| --- | --- |
|
|
3553
|
+
| Persistence fails | Surface the cause, retain the terminal result and callable owner, and emit no completion wake. Another close or cancellation retries settlement, not execution. |
|
|
3554
|
+
| Persistence commits | Release ownership before observational delivery. Attempt channel notifications and the completion wake even if another observer throws. |
|
|
3555
|
+
| Observer fails after commit | Surface the cause without reverting terminal state, retaining a false live owner, or repeating delivery on another close. |
|
|
3556
|
+
|
|
3557
|
+
Cancellation remains coalesced while work is live. Failed cancellation or
|
|
3558
|
+
failed settlement permits a subsequent cancellation attempt; it never converts
|
|
3559
|
+
the producer's already obtained outcome into a fictitious cancellation result.
|
|
3560
|
+
|
|
3492
3561
|
At process restart every still-open row is necessarily missing its callable owner. Boot
|
|
3493
3562
|
settles it as interruption (`500`) and errors active channels before evaluating parked
|
|
3494
3563
|
loops ({§worker-lifecycle-restart-recovery}); it never reports cancellation (`499`) or
|
|
@@ -3752,6 +3821,8 @@ Node's pre-script env-file form and the executable's post-script form share the
|
|
|
3752
3821
|
Root and trust flags apply before collection. A project plugin contributes no native panel.
|
|
3753
3822
|
Non-module native panels follow their npm-only family discovery ({§plugin-manifest-read});
|
|
3754
3823
|
a plain-folder declaration does not suppress an installed capability's panel.
|
|
3824
|
+
Linked packages resolve panels against the same canonical root as native code;
|
|
3825
|
+
an absent panel is optional, but a panel escaping that root is rejected.
|
|
3755
3826
|
The file travels with its code and is its configuration reference. All admitted files compose
|
|
3756
3827
|
one floor, applied set-if-unset beneath operator sources. `plurnk-service config defaults`
|
|
3757
3828
|
renders those same owner-labelled files, preserving comments and optional declarations without
|
|
@@ -4071,10 +4142,13 @@ The shared deadline bounds every phase, including observer delivery; forced
|
|
|
4071
4142
|
shutdown may therefore lose notifications and reports the unfinished phase.
|
|
4072
4143
|
|
|
4073
4144
|
§crash-only-stop The settle sequence is deadline-bounded
|
|
4074
|
-
(`PLURNK_SERVICE_STOP_TIMEOUT_MS
|
|
4145
|
+
(`PLURNK_SERVICE_STOP_TIMEOUT_MS`): one absolute deadline spans daemon drains
|
|
4146
|
+
and the enclosing observability, database, and HTTP-listener cleanup. No phase
|
|
4147
|
+
renews the budget. The service joins core's bounded producer/observer drain
|
|
4148
|
+
before releasing enclosing resources, including on timeout. Past the deadline each wait
|
|
4075
4149
|
is abandoned with a named error instead of hanging the daemon on a child that
|
|
4076
4150
|
never closes. A wedged child costs a forced shutdown; it must never cost an
|
|
4077
|
-
unbounded one. When the teardown settles, success or failure, the process ends
|
|
4151
|
+
unbounded one. Later cleanup phases are still attempted. When the teardown settles, success or failure, the process ends
|
|
4078
4152
|
itself: `0` after a clean teardown, `1` after a reported one. A handle an abandoned
|
|
4079
4153
|
wait left alive never keeps a stopped daemon running; the supervisor's kill is a
|
|
4080
4154
|
backstop, not the exit.
|
|
@@ -4132,8 +4206,13 @@ transfer, or remove ownership of workspace tools or shared resources.
|
|
|
4132
4206
|
|
|
4133
4207
|
§module-workspace-quiescence **A Functionality snapshot changes between
|
|
4134
4208
|
workspace operations.** Mutation admission, external installation/removal,
|
|
4135
|
-
preparation, and publication hold the same exclusive gate.
|
|
4136
|
-
|
|
4209
|
+
preparation, and publication hold the same exclusive gate. Every mutation or
|
|
4210
|
+
background refresh acquires that gate before the family's serialization lane;
|
|
4211
|
+
turn-admission refresh uses its already-held gate. A queued background refresh
|
|
4212
|
+
cannot own the family lane while waiting for a turn that needs that lane.
|
|
4213
|
+
Settling the coordinator includes accepted refreshes waiting for that gate,
|
|
4214
|
+
not only work already inside a family lane.
|
|
4215
|
+
Explicit client mutations use `try` and fail 409 before effects while the workspace is held.
|
|
4137
4216
|
Refused mutations reserve no queue position; a client retry is a new admission.
|
|
4138
4217
|
An accepted model mutation uses `wait`, proceeding after its originating turn. Activation and turn-admission refresh use `none` inside
|
|
4139
4218
|
their already-held demand boundary. Providers reject replacement while active
|
|
@@ -4488,7 +4567,9 @@ execution stream.** Preparation and publication share the family's serialized
|
|
|
4488
4567
|
lane. Publication acquires workspace exclusivity after current turns release
|
|
4489
4568
|
their leases; the invoking stream remains pending until publication completes.
|
|
4490
4569
|
It then reports `active`, `unavailable`, or `authorization-required`, or the exact
|
|
4491
|
-
publication failure.
|
|
4570
|
+
publication failure. Resource readiness is not execution liveness: a mutation's
|
|
4571
|
+
`202 authorization-required` body remains exact, while the finished manager
|
|
4572
|
+
execution closes with `200`. It does not wait for sign-in. A preparation failure may publish enabled-but-unavailable
|
|
4492
4573
|
state; a publication failure never reports a successful mutation. Stream polling,
|
|
4493
4574
|
waiting, and result observation use the ordinary execution lifecycle, without a
|
|
4494
4575
|
separate deferred-commit queue. An explicit client action publishes now, rejects
|
|
@@ -4774,6 +4855,7 @@ adding a loop to it. LOOK text anchors resolve through the same
|
|
|
4774
4855
|
|
|
4775
4856
|
| Event | Payload | When fired |
|
|
4776
4857
|
|--------------------------------------------------------------|---------|------------|
|
|
4858
|
+
| §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. READ fan-out is one dispatch; 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. |
|
|
4777
4859
|
| §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. |
|
|
4778
4860
|
| §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. |
|
|
4779
4861
|
| §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. |
|
|
@@ -4939,9 +5021,16 @@ time of measurement.
|
|
|
4939
5021
|
- §tokenomics-neutral-telemetry **Curation telemetry is state, not response allowance.** The model-facing `Context Curation` section is one JSON object carrying `logTokensTotal` and `logTokensMax`. It never presents their difference as free response tokens. The protocol definition directly requires KILL of irrelevant log items and ranges to keep the next packet within the maximum. Per-entry weights remain on log rows where they describe visible cost and curation savings. Generic packet composition and physical-token speculation are absent.
|
|
4940
5022
|
- §tokenomics-pressure-inventory **Pressure identifies its reclaimable concentration.** At `PLURNK_SERVICE_BUDGET_PRESSURE` of `logTokensMax`, a Markdown `> [!WARNING]` block follows the JSON with `> YOU MUST KILL superseded, stale, or irrelevant log items and ranges.` New output withholding replaces that mandate under {§context-output-warning}. The JSON may include `logTokensLargest`: at most `PLURNK_SERVICE_BUDGET_LARGEST_ITEMS` retained log items, each `{path, logTokens}`, ranked by that charge descending and then path. Native-only, suppressed, and metadata-only items remain eligible: whole-item KILL can reclaim their actual contribution. Include the largest prefix that fits; drop the optional list before the warning. Both participate in the final fixed-point total and complete request admission check.
|
|
4941
5023
|
- §tokenomics-content-hash-identity **Content identity, not per-tokenizer counts.** A settled channel's `content_hash` (SHA-256) is its body's identity in the content store ({§content-store}); a writer may bind it, a bound hash must match the content, and an active stream has none until it settles. `weight` is stored beside that content and is never keyed or recomputed by model.
|
|
4942
|
-
- §tokenomics-provider-usage **Provider accounting is physical-request evidence, not curation state.** Every issued physical request has one durable pre-I/O `provider_requests` identity beneath the normalized {§inference-ledger} and settles once as response or error. Each record preserves conventional {§provider-usage} quantities and required {§provider-cost} evidence; an unreported quantity remains absent, including on response-less failures, and is never replaced by zero. `model_calls` own response/failure evidence, `turn_attempts` specialize emission admission, and `provider_requests` are the sole durable accounting representation. Emissions, BARE calls, rejected responses, retries, failovers, and errors therefore remain cardinal and ordered. Turn, loop, worker, workspace, digest, and protocol accounting are derived from those records through the shared {§provider-accounting} projection; only emission calls contribute the latest-packet context gauge. The baseline stores no floating-point money, denormalized totals, or rollup triggers. A documented direct charge becomes `charged`; otherwise the provider may compute an exact-decimal USD `estimated` amount from complete usage and the exact model's Models.dev rates; insufficient evidence becomes `unknown`.
|
|
5024
|
+
- §tokenomics-provider-usage **Provider accounting is physical-request evidence, not curation state.** Every issued physical request has one durable pre-I/O `provider_requests` identity beneath the normalized {§inference-ledger} and settles once as response or error. Each record preserves conventional {§provider-usage} quantities and required {§provider-cost} evidence; an unreported quantity remains absent, including on response-less failures, and is never replaced by zero. `model_calls` own response/failure evidence, `turn_attempts` specialize emission admission, and `provider_requests` are the sole durable accounting representation. Emissions, BARE calls, rejected responses, retries, failovers, and errors therefore remain cardinal and ordered. Turn, loop, worker, workspace, digest, and protocol accounting are derived from those records through the shared {§provider-accounting} projection; only emission calls contribute the latest-packet context gauge. The baseline stores no floating-point money, denormalized totals, or rollup triggers. A documented direct charge becomes `charged`; otherwise the provider may compute an exact-decimal USD `estimated` amount from complete usage and the exact model's Models.dev rates; insufficient evidence becomes `unknown`. Complete totals and known subtotals remain distinct under {§provider-accounting}; unknown requests cannot impersonate free requests, and missing usage never becomes zero. This is operational request accounting, not invoice reconciliation. Output and reasoning are quantities the model cannot KILL, so they never alter the model-facing Budget ledger.
|
|
4943
5025
|
- §tokenomics-negative-pressure **Negative curation pressure is honest but never submitted.** The provisional readout may report `logTokensTotal` above `logTokensMax`. Crossing the maximum withholds new returned output under {§context-output-admission}; no over-ceiling packet reaches `provider.generate`. Output admission creates neither a strike nor another turn.
|
|
4944
5026
|
|
|
5027
|
+
Each physical request also retains {§provider-request-evidence}, atomically
|
|
5028
|
+
with its accounting settlement. Failure does not discard received fragments.
|
|
5029
|
+
The digest emits one linked `requests/<id>.json` artifact per physical request,
|
|
5030
|
+
including unavailable evidence as `null`, reading heavy records one at a time.
|
|
5031
|
+
Failed partial operations and reasoning remain forensic data only; they never
|
|
5032
|
+
execute, enter model history, or become a later request's successful output.
|
|
5033
|
+
|
|
4945
5034
|
### §context-output-admission Budget enforcement: returned-output admission
|
|
4946
5035
|
|
|
4947
5036
|
Operations and their results are execution history. Packet admission controls
|
|
@@ -5162,7 +5251,7 @@ source independently from this optional model-exchange record; a request-only
|
|
|
5162
5251
|
turn receives a note instead of a fabricated response.
|
|
5163
5252
|
|
|
5164
5253
|
§digest-turn-artifact-identity **Digest packet artifacts project durable turns.**
|
|
5165
|
-
After selectors are applied, digest retains every turn with exact
|
|
5254
|
+
After selectors are applied, digest retains every turn with exact content or reasoning source, a
|
|
5166
5255
|
valid stored provider request, or malformed stored packet evidence; orders those
|
|
5167
5256
|
turns by durable chronology; and names each by its log coordinate ({§share-packet-names}). The
|
|
5168
5257
|
producer does not affect projection.
|
|
@@ -5177,6 +5266,7 @@ consumer reconstructs a name. A name that cannot be a file name, or two turns sh
|
|
|
5177
5266
|
| Artifact | Present when | Authority |
|
|
5178
5267
|
|----------|--------------|-----------|
|
|
5179
5268
|
| `<stem>.assistant.md` | The turn has an `ops` source | Exact `turn_sources.content`, independent of log rows |
|
|
5269
|
+
| `<stem>.reasoning.md` | The turn has a `reasoning` source | Exact `turn_sources.content`, without relabeling it as content |
|
|
5180
5270
|
| `<stem>.system.md`, `<stem>.user.md` | The turn stored a provider request | Stored text sections projected through `PacketWire`; native parts are not Markdown |
|
|
5181
5271
|
| `<stem>.wire.json` | The turn stored a provider request | The request's text messages in order, its worker's emission rows placed ({§packet-wire-envelope}); `<stem>.wire.invalid.json` names a stored log that cannot be projected |
|
|
5182
5272
|
| `digest.json` turn `attachments` | Every turn | Stored native attachment descriptors; `[]` means a request without attachments, `null` means no valid stored request. Selection is not proof of provider acceptance. |
|
|
@@ -5185,8 +5275,8 @@ consumer reconstructs a name. A name that cannot be a file name, or two turns sh
|
|
|
5185
5275
|
| `<stem>.packet.raw.txt` | The stored packet fails typed validation | Exact stored packet text |
|
|
5186
5276
|
| `<stem>.packet.invalid.json` | The stored packet fails typed validation | Turn identity and complete validation error chain |
|
|
5187
5277
|
|
|
5188
|
-
A source-backed turn without provider participation
|
|
5189
|
-
|
|
5278
|
+
A source-backed turn without provider participation produces only its source-channel
|
|
5279
|
+
artifacts; a request-only turn produces no fabricated assistant. A
|
|
5190
5280
|
source-less programmatic turn with no provider request has no forensic payload
|
|
5191
5281
|
to project and writes no files.
|
|
5192
5282
|
|
|
@@ -5345,7 +5435,7 @@ retain distinct contracts and lifetimes.
|
|
|
5345
5435
|
- **Self-explaining rows.** A problem `title` names the stable class and `detail` states the occurrence-specific cause. Producer-known operands belong in factual extensions. `stage` appears only when neighboring stages imply different recovery; `recovery` states one generally valid next action; `retryable` is true only when the producer recommends automatically retrying the identical request. Unknown recovery or retryability is omitted rather than guessed. General workflow teaching stays in the packet rather than being duplicated into every failure. The runtime-neutral writing contract is owned by `@plurnk/plurnk-contracts`.
|
|
5346
5436
|
- **Exact Problems cross durable and external boundaries.** Scheme capabilities, proposal application, subscription conclusion, loop settlement, AG-UI, clients, digests, and benchmark records preserve the originating Problem object. The model packet alone derives `{§problem-projection}` without mutating that object. An adapter may add a missing durable `instance`, never replace an existing one; it must not rebuild failure truth from `status`, `detail`, `RUN_ERROR`, a scheduler projection, or a legacy string. A failed boundary without a valid Problem is a contract violation and fails hard.
|
|
5347
5437
|
- **Caught diagnostics are bounded.** Core-owned Problems may include a bounded preview of a caught runtime diagnostic when it states the occurrence-specific cause. `PLURNK_SERVICE_ERROR_DETAIL_LIMIT` owns that model-facing character bound; complete errors remain in daemon diagnostics. Input validation and stable contract failures do not spend this allowance on implementation text.
|
|
5348
|
-
- §notice-drain-on-read **Notices** - the few observations that are not log rows render one terse line under their distinct `## Notices` section, never a JSON dump. Packet rendering normalizes whitespace, bounds the producer message with the shared preview limits, and appends any typed position. The notice buffer drains on read; event Notices appear on at most one packet. Stateful derivation progress and provider availability coalesce in the buffer, so clients observe every checkpoint live while a later model packet receives only the current state under ordinary level filtering.
|
|
5438
|
+
- §notice-drain-on-read **Notices** - the few observations that are not log rows render one terse line under their distinct `## Notices` section, never a JSON dump. Packet rendering normalizes whitespace, bounds the producer message with the shared preview limits, and appends any typed position. The notice buffer drains on read; event Notices appear on at most one packet. Parking preserves pending notices for that loop's next packet; another loop cannot consume them. Terminal cleanup, including cancellation while parked, discards undelivered notices. This buffer is process-local, not restart-persistent. Stateful derivation progress and provider availability coalesce in the buffer, so clients observe every checkpoint live while a later model packet receives only the current state under ordinary level filtering.
|
|
5349
5439
|
- §rail-accounting-private **Rail accounting is private.** Visibility is owned by {§engine-rails}: the model sees concrete failures from admitted turns, never rejected emissions, attempt counts, the strike streak, or cycle detection. Surfacing internal state creates a gamification surface where the model optimizes for engine metrics instead of the task.
|
|
5350
5440
|
|
|
5351
5441
|
**The error rows (one channel) + the only non-log notices:**
|
|
@@ -5369,7 +5459,20 @@ retain distinct contracts and lifetimes.
|
|
|
5369
5459
|
|
|
5370
5460
|
§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.
|
|
5371
5461
|
|
|
5372
|
-
§loop-status-notice **The drain
|
|
5462
|
+
§loop-status-notice **The drain publishes lifecycle and its observation deadline together.**
|
|
5463
|
+
`notice/event` carries `{ workerId, loopId, notice: { source: "engine:lifecycle", kind: "loop_status", level: "info", status, waitUntil } }`.
|
|
5464
|
+
|
|
5465
|
+
| Edge | `status` | `waitUntil` |
|
|
5466
|
+
|---|---|---|
|
|
5467
|
+
| Claimed to run | 102 | `null` |
|
|
5468
|
+
| Parked | 202 | Persisted Unix-millisecond observation deadline, or `null` for an untimed park |
|
|
5469
|
+
| Woken, awaiting dispatch | 100 | `null` |
|
|
5470
|
+
|
|
5471
|
+
Park observations and wakes use the worker's existing drain serialization, so
|
|
5472
|
+
an earlier park cannot overwrite a later wake's cleared countdown.
|
|
5473
|
+
The beat is transient: broadcast to the workspace ({§notice-event-notify}), never
|
|
5474
|
+
a log row or packet. Terminals remain `loop/terminated`'s. Reattachment obtains
|
|
5475
|
+
the same deadline through {§application-loop-observation}, not a restarted clock.
|
|
5373
5476
|
|
|
5374
5477
|
§share **A share is the database's record, ready to send.** `plurnk-service share [<file.db>] [<folder>]`, and `npm run share` from a checkout, take a consistent copy of the database (`VACUUM INTO`; a live database is never read in place), and write its digest into `<folder>`, an ordinary folder the user archives or attaches however they like. Without a database the service's own is shared. Nothing is overwritten: a folder that exists and is not empty is refused, and a caller reusing a place removes it first. The share is the user's bug report and our dogfood, benchmark and forensics artifact alike.
|
|
5375
5478
|
|
|
@@ -5454,11 +5557,13 @@ final packet and the newest attempts always testify. A windowless witness
|
|
|
5454
5557
|
|
|
5455
5558
|
§turn-accounting-notice **The completion beat carries the spend.** `turn_generated`
|
|
5456
5559
|
carries the turn's exact settled wire accounting — request count, exact nullable
|
|
5457
|
-
USD
|
|
5560
|
+
USD and token totals with separately named known subtotals across every physical exchange the turn paid for, failed
|
|
5458
5561
|
calls included. It is the shared exact derivation from the ledger, never a second
|
|
5459
5562
|
stored fact, so a live watcher accrues running loop cost per turn (#465).
|
|
5460
5563
|
|
|
5461
5564
|
§notice-content-offset-pointer **Content-offset position.** A non-fatal diagnosis on an accepted emission (for example `grammar_unenforced` or `parse_advisory`) carries `position: { type: "content-offset", line, column }` into the model's exact `ops://<worker>/<loop>/<turn>` source; the transcript shows that turn's canonical emission instead ({§emission-row}), so the position names a line of the source, which READ of its address shows. A bounded hard parse error becomes a durable failed operation whose Problem Details preserve its line, column, source, and parser-owned diagnostic. Hard errors that make the frame untrustworthy remain only with their rejected forensic attempt.
|
|
5565
|
+
Reasoning normalization notices use source `grammar:reasoning` and omit the
|
|
5566
|
+
content-offset position: reasoning coordinates do not address the content source.
|
|
5462
5567
|
|
|
5463
5568
|
### Executable tool resources
|
|
5464
5569
|
|
|
@@ -5511,6 +5616,12 @@ with a multiline regex over matching fences), so turn 0 names every tool with it
|
|
|
5511
5616
|
signature — one row per tool, paged like every survey. Capability attenuation
|
|
5512
5617
|
restricts that matcher to the admitted exact tools. No document is delivered
|
|
5513
5618
|
unasked.
|
|
5619
|
+
When the registry supplies {§executor-tool-catalog} definitions, the family
|
|
5620
|
+
document links to its sibling `<runtime>.json`. The catalog contains exactly
|
|
5621
|
+
the effective tools and is an ordinary `application/json` resource for READ,
|
|
5622
|
+
FIND, and JSONPath selection. It follows the same reconciliation as the family
|
|
5623
|
+
document and per-tool schemas; neither the catalog nor its definitions are
|
|
5624
|
+
automatically included in turn 0 or expanded-tool surveys.
|
|
5514
5625
|
Attached tools are capabilities like every other runtime; the model never
|
|
5515
5626
|
learns an origin.
|
|
5516
5627
|
|
|
@@ -5841,7 +5952,17 @@ container identity.
|
|
|
5841
5952
|
| ------------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
5842
5953
|
| `&<symbol` | In-scope resources that reference `symbol` | Each matching reference's source span |
|
|
5843
5954
|
| `&>symbol` | In-scope resources defining names referenced by each definition of `symbol` | Each referenced symbol's definition span |
|
|
5844
|
-
| `&symbol` |
|
|
5955
|
+
| `&symbol` | In-scope resources defining `symbol` | Each definition's source span |
|
|
5956
|
+
|
|
5957
|
+
Graph storage preserves the handler's complete text coordinates, including
|
|
5958
|
+
reference columns and end positions. Match evidence and source text come from
|
|
5959
|
+
the same immutable derivation. A definition without handler-supplied columns
|
|
5960
|
+
selects its declared whole-line extent; a reference always retains its exact
|
|
5961
|
+
region. Matches are deduplicated by resource and complete region, not line.
|
|
5962
|
+
READ presents whole lines with that evidence ({§read-pattern-evidence}); EDIT
|
|
5963
|
+
replaces the selected region literally, not a semantic rename of the symbol.
|
|
5964
|
+
Upgrades invalidate obsolete derived indexes, never their source content or
|
|
5965
|
+
retained history ({§db-migrations}).
|
|
5845
5966
|
|
|
5846
5967
|
| Result | HTTP status |
|
|
5847
5968
|
|---|---|
|
|
@@ -5869,16 +5990,32 @@ one binary marker to fail a repository-wide text search.
|
|
|
5869
5990
|
Glob anchoring (`TODO*` starts-with, `*TODO*` contains, `*.log` ends-with,
|
|
5870
5991
|
`[Tt]odo*` character class) lives in the mimetypes framework.
|
|
5871
5992
|
|
|
5993
|
+
§derivation-in-flight **In-flight derivation and query are live uses.** An exact
|
|
5994
|
+
indexed operation holds its content-addressed artifact from derivation through
|
|
5995
|
+
the completed query. Producers hold artifacts while building and attaching
|
|
5996
|
+
them. Derivation and content collection share one per-database exclusion boundary:
|
|
5997
|
+
parallel uses remain parallel, a collection pass skips these two collectors
|
|
5998
|
+
while a use is active, and a new use waits for an already-running collection.
|
|
5999
|
+
Successful, failed, and cancelled uses release in `finally`; no durable pin or
|
|
6000
|
+
additional retention setting is introduced. The ordinary later pass or drained
|
|
6001
|
+
shutdown collects unattached artifacts under {§retention-policy}.
|
|
6002
|
+
|
|
5872
6003
|
### Matcher selection and evidence
|
|
5873
6004
|
|
|
5874
|
-
- §matcher-selection-signal **Matching carries navigation evidence** -
|
|
6005
|
+
- §matcher-selection-signal **Matching carries navigation evidence** - each selected resource carries `matches: MatchEvidence[]`, where `MatchEvidence` is `{channel?,locator?,region?,enclosingRegion?}`. `channel` identifies the entry channel and is absent for channel-less resources such as log rows ({§channel-selection-visibility}); `locator` preserves the structural address. `region` is the exact selection; `enclosingRegion` is presentation context only. Both use complete four-coordinate `TextRegion`s in the readable source. Exact duplicate evidence deduplicates. FIND projects this evidence as resource rows or flat locations ({§find-result-projection}); consumers never invent missing precision. An operation requiring exact source fragments refuses a selection containing unlocated or enclosing-only findings with 422 `pattern-source-unlocated`, before any mutation.
|
|
6006
|
+
|
|
6007
|
+
§matcher-index-readiness **Indexed patterns require complete evidence.** A held
|
|
6008
|
+
resource snapshot whose search derivation is excluded or failed answers 422
|
|
6009
|
+
`search-unavailable`, preserving the reason. Graph selection requiring an
|
|
6010
|
+
unsettled relationship universe answers retryable 503 `search-index-incomplete`.
|
|
6011
|
+
Neither condition is a successful empty match.
|
|
5875
6012
|
|
|
5876
6013
|
§matcher-result-resource-selection **A matcher selects resources; it never extracts a value or chooses a retrieval
|
|
5877
6014
|
window.** Every dialect answers whether a resource matches and may return
|
|
5878
|
-
`MatchEvidence { locator?, region? }` ({§matcher-selection-signal}).
|
|
5879
|
-
canonical structural locator. `region` is
|
|
5880
|
-
|
|
5881
|
-
|
|
6015
|
+
`MatchEvidence { locator?, region?, enclosingRegion? }` ({§matcher-selection-signal}).
|
|
6016
|
+
`locator` is a canonical structural locator. `region` is an exact selected
|
|
6017
|
+
`TextRegion`; `enclosingRegion` identifies presentation context, not a selection.
|
|
6018
|
+
Both address the physical text the model can READ. A matcher miss is 204. FIND's target shape projects the selected
|
|
5882
6019
|
resources according to {§find-result-projection}.
|
|
5883
6020
|
|
|
5884
6021
|
| Dialect | Selects | Natural use |
|
|
@@ -5914,16 +6051,17 @@ One/two-coordinate line shorthand is newline-aware so deleting a line does not
|
|
|
5914
6051
|
leave an empty line. A terminal position after a final newline is an exact
|
|
5915
6052
|
insertion anchor, not an additional whole line. `<1,-1>` selects all content.
|
|
5916
6053
|
|
|
5917
|
-
§zero-width-column-one-insert **
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
receipt and anchor-continuity recomputation so every site sees one body. At `<L,1,L,1>`,
|
|
6054
|
+
§zero-width-column-one-insert **An authored zero-width column-1 scope inserts whole lines.**
|
|
6055
|
+
Core prepares that fenced EDIT body once, using `wholeLineBody`, before handing
|
|
6056
|
+
literal replacements to the scheme. Mutation, receipt, and anchor-continuity
|
|
6057
|
+
calculation all consume that same prepared body. At `<L,1,L,1>`,
|
|
5922
6058
|
an anchored `<@hash,1,@hash,1>`, or `L` = final line + 1 when the content ends with a
|
|
5923
6059
|
newline, a non-empty body that does not end in a newline is inserted with the content's
|
|
5924
6060
|
line separator appended, so `X` at `<2,1,2,1>` into `a\nb` yields `a\nX\nb`. An empty
|
|
5925
6061
|
body inserts nothing. A zero-width region at any other column stays a byte-exact insert with
|
|
5926
|
-
nothing appended.
|
|
6062
|
+
nothing appended. A pattern's generated coordinates select exact matches, not
|
|
6063
|
+
authored line-insertion syntax: `/^/` inserts a literal prefix without adding
|
|
6064
|
+
a newline. COPY and MOVE transfer source bytes and are likewise untouched.
|
|
5927
6065
|
The runtime also tolerates an authored three-coordinate
|
|
5928
6066
|
`<startLine,startColumn,endLine>` scope, immediately lowers it to the complete
|
|
5929
6067
|
four-coordinate region ending after the final code point of `endLine`, and
|
|
@@ -5942,10 +6080,31 @@ down; overlaps and duplicate insertion boundaries are 409. This is the adopted
|
|
|
5942
6080
|
SARIF region/replacement algebra for exact spans and same-snapshot ordering, not
|
|
5943
6081
|
adoption of the SARIF interchange envelope.
|
|
5944
6082
|
|
|
5945
|
-
§slice-semantics-compose-pattern **
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
6083
|
+
§slice-semantics-compose-pattern **One selection, independent of operation.**
|
|
6084
|
+
A pattern runs over the canonical source channel, never a READ receipt's
|
|
6085
|
+
line-ending normalization, preview, coordinate prefixes, or other presentation.
|
|
6086
|
+
A match region uses the four-coordinate source scope. FIND reports it, READ
|
|
6087
|
+
shows its lines with that evidence, EDIT replaces it, COPY transfers it, MOVE
|
|
6088
|
+
transfers then removes it, and a textual KILL removes it. Enclosing display
|
|
6089
|
+
context never enlarges the selected span. Multiple fragments retain source
|
|
6090
|
+
order and literal text; COPY/MOVE insert no separators between them. Scope
|
|
6091
|
+
composition admits complete matches, never clipped fragments or other matches
|
|
6092
|
+
on the same line. Mutation batches retain {§edit-batch-merges} and collision
|
|
6093
|
+
handling; a pattern does not create another overlap-recovery algorithm.
|
|
6094
|
+
|
|
6095
|
+
FIND retains locators even without source coordinates. READ may display
|
|
6096
|
+
`enclosingRegion` as context, but a selected value with neither kind of location
|
|
6097
|
+
returns `422 pattern-source-unlocated`. EDIT, COPY, MOVE,
|
|
6098
|
+
and textual KILL require exact `region` evidence for every selected match;
|
|
6099
|
+
enclosing or unlocated values return that same Problem without changing any
|
|
6100
|
+
source or destination. Absence of matches remains an ordinary empty selection.
|
|
6101
|
+
|
|
6102
|
+
A follow-up ```` ```READ (resource) <SL,SC,EL,EC> ```` retrieves the exact
|
|
6103
|
+
region. JSONPath/XPath remain locators and matchers, not a structural update
|
|
6104
|
+
language: `//item` selects the element, `//item/text()` its direct text nodes,
|
|
6105
|
+
and `$.host` the JSON value including its lexical quotes/escapes, never the
|
|
6106
|
+
property name or colon. Literal replacement does not serialize a value or
|
|
6107
|
+
repair neighboring punctuation. Readable projections have their own coordinates.
|
|
5949
6108
|
|
|
5950
6109
|
### §ext-mimetype Path-extension declares mimetype
|
|
5951
6110
|
|
|
@@ -6006,7 +6165,7 @@ Auto-derived text mimetypes anywhere in plurnk-service normalize to `text/markdo
|
|
|
6006
6165
|
Carried from the contract walk; durable.
|
|
6007
6166
|
|
|
6008
6167
|
- **Dialect/mimetype mismatch** → 415 (xpath on text/plain → 415; jsonpath on JSON-shapeless mimetypes → 204 because outline is empty, not 415).
|
|
6009
|
-
- **Binary
|
|
6168
|
+
- **Binary coordinates** are numeric byte positions for READ and transfer; text EDIT does not author native bytes ({§binary-parity}). Readable projections retain their own textual coordinates ({§membership-source-projection}).
|
|
6010
6169
|
- **EDIT `<L>` on non-existent entry** → body becomes content; `<L>` is positional-only on existing content.
|
|
6011
6170
|
- §copy-l-source-range **COPY/MOVE source scope** selects only the addressed source channel and
|
|
6012
6171
|
first resolves and, when required, prepares the same canonical
|
|
@@ -6027,7 +6186,7 @@ Carried from the contract walk; durable.
|
|
|
6027
6186
|
{§copy-move-observation}.
|
|
6028
6187
|
- **READ rx** prefixes every textual line under {§render-rule-line-navigable-prefix}; eligible
|
|
6029
6188
|
editable resources carry `@hash N:`, and all others carry `N:`.
|
|
6030
|
-
- **
|
|
6189
|
+
- **Pattern selection** applies to the addressed source channel under {§slice-semantics-compose-pattern}. The path and channel select resources; FIND reports matches and READ displays their lines. EDIT, textual KILL, COPY, and MOVE act on exact selected spans, not their enclosing lines ({§read-pattern}, {§edit-pattern}, {§kill-pattern}, {§copy-move-pattern}).
|
|
6031
6190
|
- **Scoped KILL** on the **log** (`log:///`) removes a body span from its readable projection ({§log-kill-scope}); on an entry it deletes that span through the EDIT path ({§kill-scope-entry}). A whole-entry KILL deletes the entry, or one `#fragment` channel.
|
|
6032
6191
|
- **File scheme** detects with `Mimetypes.detect({ path })` and classifies with the same configured service ({§mimetype-classification-consumption}). Handler-declared binary sources materialize through {§membership-source-projection}; projected bodies are READ-able, while source-aware EDIT remains 415.
|
|
6033
6192
|
|
|
@@ -6035,7 +6194,14 @@ Carried from the contract walk; durable.
|
|
|
6035
6194
|
|
|
6036
6195
|
A KILL with a text-coordinate scope aimed at an entry-bearing scheme deletes exactly that span: core prepares and dispatches it as an EDIT with an empty body over the same marker, so anchors resolve, proposals gate it, and the merge facts and receipt are the EDIT path's — while the log row records the model's KILL. Its packet metadata and canonical log body use {§edit-result-receipt-projection}. ```` ```EDIT (path) <scope> ```` with an empty body remains the same act spelled the other way; the teaching names KILL.
|
|
6037
6196
|
|
|
6038
|
-
§kill-pattern **A pattern on
|
|
6197
|
+
§kill-pattern **A pattern on a textual entry KILL removes exactly its matches.**
|
|
6198
|
+
It is the same empty-body EDIT under {§edit-pattern}, including exact column
|
|
6199
|
+
and multiline regions, scope, preconditions, proposals, and receipt. It has no
|
|
6200
|
+
separate line-deletion mode. Zero matches leave the resource unchanged (204,
|
|
6201
|
+
`matched: 0`); a pattern never becomes whole-resource deletion. The receipt
|
|
6202
|
+
counts selected spans and retains the first and last applied effects.
|
|
6203
|
+
Log KILL still selects retirement rows ({§log-curation-set-selection}); stream
|
|
6204
|
+
KILL controls a process and refuses a content pattern (`kill-pattern-unsupported`).
|
|
6039
6205
|
|
|
6040
6206
|
---
|
|
6041
6207
|
|
|
@@ -6055,7 +6221,7 @@ teardown. The runner joins the test body's cleanup before starting the next
|
|
|
6055
6221
|
specimen. The shared workspace and story helpers cover setup, inference and
|
|
6056
6222
|
oracle failures, preserve the primary failure when their cleanup also fails,
|
|
6057
6223
|
and attempt every registered disposal.
|
|
6058
|
-
|
|
6224
|
+
The provider whole-call deadline and recovery policy remain independent; a harness cancellation is
|
|
6059
6225
|
not evidence that the provider's own deadline expired.
|
|
6060
6226
|
|
|
6061
6227
|
§provider-conformance-matrix **Every configured model alias is exercised through a
|