@plurnk/plurnk-service 1.20.0 → 1.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/.env.defaults +4 -2
  2. package/INSTALL.md +3 -2
  3. package/SPEC.md +118 -54
  4. package/dist/build-info.json +1 -1
  5. package/dist/content/line-anchors.d.ts.map +1 -1
  6. package/dist/content/line-anchors.js +51 -16
  7. package/dist/content/line-anchors.js.map +1 -1
  8. package/dist/content/scope-format.d.ts +2 -2
  9. package/dist/content/scope-format.d.ts.map +1 -1
  10. package/dist/content/scope-format.js.map +1 -1
  11. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  12. package/dist/core/AdmittedTurnExecutor.js +21 -12
  13. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  14. package/dist/core/BareBatchRunner.d.ts +2 -1
  15. package/dist/core/BareBatchRunner.d.ts.map +1 -1
  16. package/dist/core/BareBatchRunner.js +20 -1
  17. package/dist/core/BareBatchRunner.js.map +1 -1
  18. package/dist/core/BudgetReadout.d.ts +1 -1
  19. package/dist/core/BudgetReadout.d.ts.map +1 -1
  20. package/dist/core/BudgetReadout.js +4 -7
  21. package/dist/core/BudgetReadout.js.map +1 -1
  22. package/dist/core/Dispatcher.js +1 -1
  23. package/dist/core/Dispatcher.js.map +1 -1
  24. package/dist/core/Engine.d.ts +1 -0
  25. package/dist/core/Engine.d.ts.map +1 -1
  26. package/dist/core/Engine.js.map +1 -1
  27. package/dist/core/KnownToxins.d.ts +5 -0
  28. package/dist/core/KnownToxins.d.ts.map +1 -0
  29. package/dist/core/KnownToxins.js +31 -0
  30. package/dist/core/KnownToxins.js.map +1 -0
  31. package/dist/core/LoopDriver.d.ts.map +1 -1
  32. package/dist/core/LoopDriver.js +10 -3
  33. package/dist/core/LoopDriver.js.map +1 -1
  34. package/dist/core/LoopLifecycle.d.ts +5 -0
  35. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  36. package/dist/core/LoopLifecycle.js +10 -0
  37. package/dist/core/LoopLifecycle.js.map +1 -1
  38. package/dist/core/LoopLifecycle.sql +36 -0
  39. package/dist/core/PacketBuilder.d.ts +1 -0
  40. package/dist/core/PacketBuilder.d.ts.map +1 -1
  41. package/dist/core/PacketBuilder.js +6 -9
  42. package/dist/core/PacketBuilder.js.map +1 -1
  43. package/dist/core/ReasoningView.d.ts +5 -1
  44. package/dist/core/ReasoningView.d.ts.map +1 -1
  45. package/dist/core/ReasoningView.js +9 -4
  46. package/dist/core/ReasoningView.js.map +1 -1
  47. package/dist/core/TurnRunner.d.ts.map +1 -1
  48. package/dist/core/TurnRunner.js +46 -3
  49. package/dist/core/TurnRunner.js.map +1 -1
  50. package/dist/core/packet-wire.d.ts.map +1 -1
  51. package/dist/core/packet-wire.js +49 -51
  52. package/dist/core/packet-wire.js.map +1 -1
  53. package/dist/core/turn-signals.d.ts +5 -0
  54. package/dist/core/turn-signals.d.ts.map +1 -1
  55. package/dist/core/turn-signals.js +6 -0
  56. package/dist/core/turn-signals.js.map +1 -1
  57. package/dist/digest/Digest.d.ts.map +1 -1
  58. package/dist/digest/Digest.js +19 -49
  59. package/dist/digest/Digest.js.map +1 -1
  60. package/dist/digest/DigestEvidence.d.ts +9 -0
  61. package/dist/digest/DigestEvidence.d.ts.map +1 -0
  62. package/dist/digest/DigestEvidence.js +52 -0
  63. package/dist/digest/DigestEvidence.js.map +1 -0
  64. package/dist/digest/DigestRender.d.ts +2 -1
  65. package/dist/digest/DigestRender.d.ts.map +1 -1
  66. package/dist/digest/DigestRender.js +84 -39
  67. package/dist/digest/DigestRender.js.map +1 -1
  68. package/dist/digest/DigestRequiem.d.ts.map +1 -1
  69. package/dist/digest/DigestRequiem.js +48 -43
  70. package/dist/digest/DigestRequiem.js.map +1 -1
  71. package/dist/digest/digest-rows.d.ts +7 -8
  72. package/dist/digest/digest-rows.d.ts.map +1 -1
  73. package/dist/digest/digest.sql +14 -11
  74. package/dist/schemes/Worker.d.ts.map +1 -1
  75. package/dist/schemes/Worker.js +6 -3
  76. package/dist/schemes/Worker.js.map +1 -1
  77. package/dist/server/Functionality.d.ts +1 -0
  78. package/dist/server/Functionality.d.ts.map +1 -1
  79. package/dist/server/Functionality.js +7 -4
  80. package/dist/server/Functionality.js.map +1 -1
  81. package/docs/copy-move.md +6 -6
  82. package/docs/env.md +9 -14
  83. package/docs/members.md +28 -23
  84. package/docs/skills.md +22 -22
  85. package/package.json +34 -33
package/.env.defaults CHANGED
@@ -144,11 +144,13 @@ PLURNK_SERVICE_PREVIEW_LINES=100
144
144
  PLURNK_SERVICE_PREVIEW_CHARS=16000
145
145
  # Turn0 reasoning READ: -1 = complete; 0 = omit; N = first N lines. Later reads are model-chosen.
146
146
  # Alias override: PLURNK_REASONING_VIEW_LINES_<alias>. Source retention/streaming are unchanged.
147
- PLURNK_REASONING_VIEW_LINES=-1
147
+ PLURNK_REASONING_VIEW_LINES=100
148
+ # After a turn with no operation, its reasoning is read back: same scale, same alias override.
149
+ PLURNK_REASONING_EMPTY_TURN_LINES=100
148
150
  # Cold-start input allowance reserved for automatic prompt bodies, percentage in (0,100).
149
151
  # Alias override: PLURNK_SERVICE_PROMPT_PROJECTION_<alias>. Full prompts remain addressable.
150
152
  PLURNK_SERVICE_PROMPT_PROJECTION=25%
151
- # Neighboring lines hashed on each side of an editable line anchor; 0 = addressed line only.
153
+ # Minimum neighbors hashed on each side of an editable line anchor; repeated handles widen context.
152
154
  PLURNK_SERVICE_LINE_ANCHOR_CONTEXT_LINES=2
153
155
  # Surrounding and changed lines shown at each EDIT boundary; overlapping windows coalesce.
154
156
  PLURNK_SERVICE_EDIT_RECEIPT_CONTEXT_LINES=4
package/INSTALL.md CHANGED
@@ -62,8 +62,9 @@ the owning declaration specifies its meaning.
62
62
  | File creation and membership | Separate policies. Creating an out-of-root file, admitting a new file, and editing an existing member are distinct decisions. |
63
63
  | User-facing behavior | Operating policy; use configuration for runtime controls. |
64
64
 
65
- The [model chapter](skill://plurnk/references/models.md) covers alias tuning,
66
- reasoning and output budgets, local endpoints, caching, and connectivity.
65
+ The `@plurnk/plurnk-providers` README covers alias tuning, reasoning and output
66
+ budgets, local endpoints, caching, and connectivity; the
67
+ [model chapter](skill://plurnk/references/models.md) is what a model is told.
67
68
  The defaults catalog groups the remaining settings by their owning subsystem:
68
69
  permissions, loop limits, residency, execution, context, indexing, MCP, A2A,
69
70
  hooks, HTTP, and content handling. Search the catalog for that subsystem instead
package/SPEC.md CHANGED
@@ -496,7 +496,7 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
496
496
  | `READ` | existing literal name | Collect the named worker's deliverable. |
497
497
  | `KILL` | existing literal name | Terminate the named worker or caller. |
498
498
 
499
- - §worker-scheme-spawn **Spawn** — ```` ```WORK (worker://<name>)? ```` with a task body creates a new worker sister (empty log) and starts it with that task on its first loop. WORK/FORK are the worker-creation verbs: EDIT is file/entry only, so EDIT on the bare worker entity is a **400** steering to WORK/FORK — the entity is not an entry. Names remain unique within a workspace for the lifetime of retained Worker rows, including after termination. An existing name returns 409; concurrent claims cannot redirect a published address or expose a raw uniqueness failure.
499
+ - §worker-scheme-spawn **Spawn** — ```` ```WORK (worker://<name>)? ```` with a task body creates a new child worker (empty log) and starts it with that task on its first loop. WORK/FORK are the worker-creation verbs: EDIT is file/entry only, so EDIT on the bare worker entity is a **400** steering to WORK/FORK — the entity is not an entry. Names remain unique within a workspace for the lifetime of retained Worker rows, including after termination. An existing name returns 409; concurrent claims cannot redirect a published address or expose a raw uniqueness failure.
500
500
  - §worker-spawn-prompt-resource **The spawn slot is overloaded by scheme.** A `worker://` path is
501
501
  the child's address and keeps the address rules ({§worker-control-addressing}). A path of any
502
502
  other scheme is the child's prompt resource: it is read whole (`<1,-1>`) under the caller's read capabilities, composed with
@@ -506,9 +506,9 @@ Every admitted authority is a literal `workers.name`; self-addressing uses the c
506
506
  resource with no body is `422 spawn-prompt-empty`. Naming the child and giving a resource in one
507
507
  statement is not expressible; the body can READ the resource instead. Taught in the deep
508
508
  reference only.
509
- - §worker-scheme-irc **irc** — ```` ```SEND (worker://<name>) ```` with a message body delivers it to an existing sister, the **voice door** ({§actor-boundary-two-doors}): an active sister folds it into its next turn, an idle one wakes ({§actor-boundary-passive-wake}). A fresh receiving loop retains that worker's durable model, spawn override, and reasoning policy; the sender and daemon default do not re-select it. The caller addresses itself by its literal name; a literal name with no worker in the workspace is 404.
509
+ - §worker-scheme-irc **irc** — ```` ```SEND (worker://<name>) ```` with a message body or attachments delivers it to an existing worker, the **voice door** ({§actor-boundary-two-doors}): an active worker folds it into its next turn, an idle one wakes ({§actor-boundary-passive-wake}). No text beyond whitespace and no attachments is 422 `message-empty`, before message admission or recipient loop creation. Nonempty text is delivered verbatim; attachment-only delivery uses {§send-resource-attachments}. A fresh receiving loop retains that worker's durable model, spawn override, and reasoning policy; the sender and daemon default do not re-select it. The caller addresses itself by its literal name; a literal name with no worker in the workspace is 404.
510
510
  - §worker-scheme-fork **Fork** — ```` ```FORK (worker://<name>)? ```` with a task body branches the
511
- current worker into a **named** sister: its log is deep-copied
511
+ current worker into a **named** child: its log is deep-copied
512
512
  ({§machine-processes-fork-copies-the-log}), which continues with `task`; the
513
513
  world is shared, never copied ({§machine-processes-fork-shares-the-world}).
514
514
  WORK and FORK are distinct verbs — WORK spawns a fresh worker, FORK branches
@@ -633,7 +633,7 @@ and never re-fetch a match.
633
633
  project file is exactly one of three things: **invisible**, **added**, or **tracked
634
634
  by git**. There is no fourth category. Membership — what the model can READ and
635
635
  FIND, what is materialized into the store, what a packet can ship to a provider — is
636
- the allowlist `(tracked ∪ include) − exclude` and nothing else. No file is a member because
636
+ the allowlist `(tracked ∪ include ∪ created) − exclude` and nothing else. No file is a member because
637
637
  it exists on disk, because git does not ignore it, or because a model would find it
638
638
  convenient: ambient admission of untracked files is prohibited, so a workspace rooted
639
639
  in a home directory or a monorepo exposes exactly what was committed or added (the
@@ -1083,6 +1083,7 @@ These are the complete strike sources:
1083
1083
  |---------------------|------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|
1084
1084
  | Hard result | An admitted non-execution operation or bounded parse-error status is `>= 400`, except the soft set `404`, `409`, `416`, `425`, `501`. | The originating failure row. |
1085
1085
  | Cycle | The executed operations and their observed results repeat under {§engine-cycle-evidence}. | None; cycle detection itself is private engine accounting. |
1086
+ | Empty turn | An admitted turn with no authored response operation ({§empty-turn}). | The turn's `422` error row, and its reasoning read back ({§reasoning-empty-turn-read}). |
1086
1087
 
1087
1088
  Execution results remain exact model-visible evidence but are always soft: an
1088
1089
  executor error is not a PLURNK contract violation. Cycle detection remains an
@@ -1521,7 +1522,7 @@ Registration precedes loop affinity:
1521
1522
  | Boundary | Contract |
1522
1523
  |---|---|
1523
1524
  | Prompt | A resource path, an inline body, or both ({§bare-statement}). The sole user message contains the complete addressed READ representation followed by the body, separated by two newlines when both are nonempty. Resource resolution occurs at the operation's execution point through {§universal-read-composition}, including source preparation, identity, channel selection, and retained log lines. No preview limit, presentation prefixes, or extra READ receipt. |
1524
- | Admission | Ordinary {§capability-admission} checks BARE execution and, for a path, source observation before acquisition or inference. An unsuccessful source result becomes the BARE receipt unchanged; the inline tail is not a fallback. Empty combined text yields 422 `bare-prompt-empty`. Neither refusal creates a model call. |
1525
+ | Admission | Ordinary {§capability-admission} checks BARE execution and, for a path, source observation before acquisition or inference. An unsuccessful source result becomes the BARE receipt unchanged; the inline tail is not a fallback. Empty combined text yields 422 `bare-prompt-empty`, whose detail names where a prompt goes: the fence body, a resource path, or both, never the aside. Neither refusal creates a model call. |
1525
1526
  | Isolation | No inherited PLURNK packet, context, tools, GBNF, parser, or persistent child worker. Non-prompt call identity and accounting remain ordinary provider metadata. |
1526
1527
  | Provider | Exactly the loop's WORK/FORK child provider; durable inherit policy falls back to the parent. |
1527
1528
  | Execution | A contiguous group's prompt acquisition precedes model-call creation; interrupted acquisition leaves no unstarted inference records. Admitted calls acquire identities in authored order and launch concurrently under the loop cancellation signal. Core awaits the group and records results and notifications in authored order, regardless of completion order. An intervening operation is an execution boundary. |
@@ -1530,7 +1531,7 @@ Registration precedes loop affinity:
1530
1531
 
1531
1532
  - §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.
1532
1533
  - §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.
1533
- - §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. 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.
1534
+ - §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.
1534
1535
  - §anchor-offset **An anchor offset is tolerated, never taught (#749).** A line mark may carry an offset from its anchor (`@abcde+1`, `@abcde-2`), and a bare `+N` after an anchor counts from that anchor (`<@abcde,+1>`). The anchor resolves as usual and the offset is added; a result before line 1 is an invalid mark, and past the end is the ordinary range refusal. Continuity and current-anchor preconditions check the anchor's own line. No teaching text, scope table or receipt mentions offsets; `plurnk.md` keeps its two anchor forms. A bare `+N` with no anchor before it is refused as before.
1535
1536
  - §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.
1536
1537
  - §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`.
@@ -1855,18 +1856,42 @@ coordinates and derives its internal anchors from canonical content and identity
1855
1856
  not from whether a model-facing READ publishes them. Explicit log anchors remain
1856
1857
  available for curation without granting source EDIT.
1857
1858
 
1858
- For canonical model-facing
1859
- resource identity `R`, configured non-negative neighbor count `C`, ordered
1860
- content array `W` containing that line and up to `C` complete lines on either
1861
- side (all excluding separators), and the line's offset `O` within `W`
1862
- (`min(L-1, C)` for one-based ordinal `L`), core hashes the JSON tuple
1863
- `["plurnk-line-anchor-v2",R,C,O,W]` with SHA-256, interprets the digest as a
1864
- big-endian integer modulo `62^5`, and encodes five fixed-width characters with
1865
- alphabet `0-9A-Za-z`. The ordinal itself is not hashed (#428): a line keeps its
1866
- anchor wherever it moves while its content and neighborhood are unchanged, so
1867
- edits above a line — the model's own earlier edits included — never stale the
1868
- anchors below them; identical neighborhoods share one anchor and resolve as
1869
- ambiguous with the matching lines, never as a silent landing on a twin. The universal READ projector derives
1859
+ For canonical resource identity `R`, minimum neighbor count `C` from
1860
+ `PLURNK_SERVICE_LINE_ANCHOR_CONTEXT_LINES`, one-based line `L`, and ordered
1861
+ window `W` containing the line and up to `C` neighbors on either side (without
1862
+ separators), the initial fingerprint is SHA-256 of the JSON tuple
1863
+ `["plurnk-line-anchor-v2",R,C,min(L-1,C),W]`. Its big-endian integer modulo
1864
+ `62^5`, encoded with alphabet `0-9A-Za-z`, supplies the five-character handle.
1865
+ Absolute ordinals and occurrence numbers are not identity.
1866
+
1867
+ §line-anchor-disambiguation Repeated handles expand their content context on
1868
+ the complete canonical resource, before any READ scope or preview:
1869
+
1870
+ | Condition | Derivation / outcome |
1871
+ | --- | --- |
1872
+ | Handle is unique | Keep it; expansion elsewhere does not re-key it. |
1873
+ | Handle repeats | Double the context radius (`0` first becomes `1`), re-fingerprint the repeated lines, and recheck all resulting handles. |
1874
+ | Expanded context | Hash the ordered left block, addressed line, and right block with `R`, `C`, and the expanded radius. Compose doubled side blocks from their two previous SHA-256 fingerprints; missing blocks are `null`. No absolute position, mutable registry, or fuzzy relocation. |
1875
+ | Shift outside distinguishing context | Handle remains valid when that context and its uniqueness remain unchanged. |
1876
+ | Context or required disambiguation changes | The old handle may become stale; do not redirect it by ordinal or occurrence. |
1877
+ | Full-resource radius reached | Stop expansion. A residual short-hash collision remains ambiguous and is refused, never resolved by picking a match. |
1878
+
1879
+ Side-block leaves cover up to `max(C,1)` neighboring lines and hash their
1880
+ ordered line arrays; expanded handles hash
1881
+ `["plurnk-line-anchor-context-v1",R,C,radius,left,line,right]`, where `line`
1882
+ hashes the addressed line's text. Side-block parents hash the ordered pair of
1883
+ child fingerprints. Context expansion takes logarithmically many rounds and
1884
+ linear auxiliary storage, not increasingly large substring copies per line.
1885
+ Larger distinguishing contexts deliberately carry larger stale-check regions.
1886
+ Anchors are content preconditions, not persistent physical-line identities: an
1887
+ exact copy of the distinguishing context cannot be told from a move after the
1888
+ original context disappears. Multiple current matches are never guessed.
1889
+ Within one program {§edit-anchor-continuity} retains proven bindings through
1890
+ its own splices, including changes to contextual disambiguation. This does not
1891
+ grant bindings to another program or bypass concurrent-write checks. Applied
1892
+ EDIT receipts publish current anchors under {§edit-receipt-anchored-context}.
1893
+
1894
+ The universal READ projector derives
1870
1895
  anchors from the complete canonical selected channel before applying the
1871
1896
  authored text slice; its durable result retains the canonical derivation
1872
1897
  identity and anchors aligned with returned lines. Packet rendering right-aligns
@@ -2001,7 +2026,7 @@ READ is the one fan-out core performs ({§read-fan-out}).
2001
2026
  Each such row carries `attrs.fanout` (`target`, the authored glob; `matched`, the
2002
2027
  survey's matching path count; `index`; `count`), so a client presents the authored
2003
2028
  statement once and folds the paths beneath it without inferring the group.
2004
- Without a scope each path renders its ordinary `<1,16>` preview; with a pattern
2029
+ Without a scope each path uses {§markerless-first-page}; with a pattern
2005
2030
  only the matching lines, `grep -n` style. The authored statement contributes
2006
2031
  `rowsWritten`, the receipt count, to its turn's sequence. No path is one 204
2007
2032
  receipt on the authored glob (`matched: 0` when a pattern selected nothing); a
@@ -2084,7 +2109,7 @@ same transitions the dispatcher's atomic curation event makes, without the row.
2084
2109
  |---|---|
2085
2110
  | Evidence | Original provider reasoning remains verbatim in immutable model-call responses and admitted packets. Resource and log operations never rewrite it. Only an admitted response, or the final exhausted emission attempt, produces a model reasoning source; missing provider reasoning creates no substitute. A non-model producer may record its own authored rationale under {§turn-source-resources}. |
2086
2111
  | Resource | `reasoning://<worker>/<loop>/<turn>` is immutable text/plain source belonging to the named workspace worker's turn under {§turn-source-resources}. Every workspace actor may READ, FIND, search and COPY from it; none may EDIT, KILL, COPY into or MOVE it. |
2087
- | Delivery | Initialization READs its own authored rationale under {§reasoning-initial-read}. Further observations require deliberate READs. The selected model reasoning source is stored before its OPs execute, so an ordinary READ of the current turn resolves immediately and is visible in subsequent packets. Every READ retains its authored scope and ordinary range metadata, without edit anchors. |
2112
+ | Delivery | Initialization READs its own authored rationale under {§reasoning-initial-read}, and an empty turn's reasoning is read back under {§reasoning-empty-turn-read}. Further observations require deliberate READs. The selected model reasoning source is stored before its OPs execute, so an ordinary READ of the current turn resolves immediately and is visible in subsequent packets. Every READ retains its authored scope and ordinary range metadata, without edit anchors. |
2088
2113
  | Curation | Scoped log KILL suppresses receipt lines; whole log KILL retires the receipt. Neither affects the source. Explicit log READs retain ordinary curation anchors. A mutable working copy requires ordinary COPY into an editable resource. |
2089
2114
  | Lifecycle | Restart retains sources and observations. FORK snapshots sources under the child's name at the same loop/turn coordinates and receipts with independent curation. No curation or lifecycle event automatically READs model reasoning. A turn the provider left without reasoning reads empty; absent workers and turns return the ordinary missing result ({§turn-source-resources}). |
2090
2115
  | Client | Standard live reasoning events and replay retain original provider reasoning; working resources and READ receipts never substitute for or replay that stream. |
@@ -2098,10 +2123,21 @@ The program begins with its own NOTE and READs its reasoning and persisted ops,
2098
2123
  demonstrating both NOTE placements and their ordinary results. The initial message arrives separately as an
2099
2124
  inbound SEND ({§message-arrival}). Neither initialization nor later turns
2100
2125
  manufacture a task inventory.
2101
- `PLURNK_REASONING_VIEW_LINES` (default `-1`, alias-scoped) selects this one READ's
2126
+ `PLURNK_REASONING_VIEW_LINES` (alias-scoped, default in `.env.defaults`) selects this one READ's
2102
2127
  scope: `0` omits it, `-1` reads the complete rationale, and a positive integer
2103
2128
  bounds it to the first N lines. Source retention, deliberate READs, and client
2104
- streaming are independent. No later turn automatically requests reasoning.
2129
+ streaming are independent. The only other automatic reasoning READ follows an empty
2130
+ turn ({§reasoning-empty-turn-read}).
2131
+
2132
+ §reasoning-empty-turn-read **An empty turn's reasoning is read back to the model.** After a
2133
+ turn admitted under {§empty-turn}, one runtime turn of the same loop
2134
+ (`{ producer="_plurnk", kind="operation" }`) dispatches
2135
+ `READ (reasoning://<worker>/<loop>/<turn>) <!-- turn N emitted no OP -->` over that turn's stored
2136
+ reasoning source; its receipt renders in the next packet like any other log row.
2137
+ `PLURNK_REASONING_EMPTY_TURN_LINES` (alias-scoped, default in `.env.defaults`) selects the scope on the same
2138
+ scale as `PLURNK_REASONING_VIEW_LINES`. No read follows a turn without reasoning, and none follows
2139
+ a turn whose emission or reasoning carries a foreign tool-call grammar ({§response-text-note});
2140
+ the strike and its error row are unchanged.
2105
2141
 
2106
2142
  ### §log-kill-scope KILL on the log: whole items and scoped bodies
2107
2143
 
@@ -2138,27 +2174,25 @@ type and projection facts under {§read-bytes}.
2138
2174
  The `## Log` section is a sequence of ordinary Markdown records separated by one blank line:
2139
2175
 
2140
2176
  ```text
2141
- ### log:///<loop>/<turn>/<item>/<leaf> · <logTokens>
2142
- OP (operands) <marks> [metadata] <!-- aside -->
2143
- {"oneLine":"strict JSON result facts"}
2177
+ ### log:///<loop>/<turn>/<item>/<leaf> → path pattern · <logTokens>
2178
+ {"oneLine":"strict JSON facts"}
2144
2179
  <coordinate-prefixed body lines when visible>
2145
2180
  ```
2146
2181
 
2147
2182
  | Line | Content | Rule |
2148
2183
  |---|---|---|
2149
- | H3 | The row's complete model-facing identity and canonical READ address, then ` · ` and its `logTokens` charge ({§packet-token-accounting}). | Always present; nothing else repeats the identity, the operation, or the charge. |
2150
- | written | The request as the language writes it ({§heading-slot-order}): the operation or runtime, every operand in the packet's canonical spelling ({§log-address-metadata}), marks, metadata blocks, matcher, aside. No fence, no body. | Present for every operation and execution row; absent on `error` and `extension` rows. |
2151
- | facts | One strict JSON object of result facts in stable alphabetical order. | Present only when a fact exists; it never re-encodes the written line. |
2184
+ | H3 | Only the row's complete READ address, addressed resource(s), selection pattern(s), and ` · ` followed by its `logTokens` charge ({§packet-token-accounting}). | Always present. Canonical operands follow arrows ({§log-address-metadata}); each pattern follows its operand. No invocation parentheses, scope, aside or metadata block. The operation appears only in the URI leaf. |
2185
+ | facts | One strict JSON object in stable alphabetical order. | Present only when a fact exists. Asides, scopes, opaque invocation metadata and result facts belong here, not on the H3. |
2152
2186
  | body | Coordinate-prefixed lines. | Present when the row is visible. |
2153
2187
 
2154
- The written line is the model's own request, so a matcher such as `/\bhello\b/i` returns exactly as it was written, never JSON-quoted. Absent fields are not invented. Every physical body line retains its canonical numeric `N:` or anchored `@hash N:` coordinate, so source text cannot create a record boundary. The section contains records only, with no leading prose or enclosing fence.
2188
+ Patterns retain their literal spelling; a pattern containing a line break is JSON-quoted to keep the H3 on one physical line. Receipts are descriptive records, not reconstructed operation headings. Absent fields are not invented. Every physical body line retains its canonical numeric `N:` or anchored `@hash N:` coordinate, so source text cannot create a record boundary. The section contains records only, with no leading prose or enclosing fence.
2155
2189
 
2156
2190
  §log-address-metadata **Addresses name their relationship, not the row's producer.**
2157
2191
 
2158
2192
  | Spelling | Meaning | Where |
2159
2193
  |---|---|---|
2160
- | `OP (path)` | The operation's addressed operand: read resource, mutation subject, message recipient, or executor operand. Explicit and automatic READs are written identically. Pathless operations are written bare. | Written line |
2161
- | `COPY (from) <marks> (to) <marks>` | COPY/MOVE's two operand selections, each retaining its optional scope; neither replaces actor attribution. | Written line |
2194
+ | `→ path` | The operation's addressed operand: read resource, mutation subject, message recipient, or executor operand. Explicit and automatic READs share this spelling. Pathless operations have no operand. | H3 |
2195
+ | `→ from pattern → to` | COPY/MOVE's ordered operands and any operand pattern; neither replaces actor attribution. Scopes remain paired by `scope.from` and `scope.to` in JSON. | H3 |
2162
2196
  | `stream` | An executor invocation's separately created output address, never a READ's alternative spelling of its operand. | Facts |
2163
2197
  | `resource` | A distinct returned resource under {§operation-resource-receipt}. | Facts |
2164
2198
 
@@ -2175,6 +2209,7 @@ Coordinate-prefixed lines are the text currently in context; a metadata-only row
2175
2209
 
2176
2210
  | Field | Coordinate owner | Representation |
2177
2211
  |---|---|---|
2212
+ | `scope` | The submitted operation | `<marks>` when present; COPY/MOVE use `{from,to}` with only the authored scopes. Omitted when a READ/FIND's result or Problem already supplies its range. |
2178
2213
  | `range` | The resource addressed by a successful READ/FIND | `<first,last> of N lines/resources/match locations/bytes`; singleton scopes use `<first>`. A complete dense selection reduces to `N units`; an empty selection from a nonempty extent is `none of N units`. |
2179
2214
  | `range` for exact text | The addressed text resource | `<startLine,startColumn,endLine,endColumn>`; no invented available extent. |
2180
2215
  | `preview` | The retained receipt body | Only when displayed incompletely: selected scope(s) `of N lines`, or exact selected region `of` complete region for an in-line cut. Replaces the body's otherwise redundant `lines` count. |
@@ -2192,7 +2227,7 @@ numbers and its receipt's body-relative curation coordinates remain distinct
2192
2227
  ({§log-kill-scope}). Byte ranges describe the hex selection, not native-media
2193
2228
  cropping ({§packet-attachment-parts}).
2194
2229
 
2195
- Successful retrieval metadata omits requested coordinates; durable results and
2230
+ Retrieval results omit redundant requested coordinates; durable results and
2196
2231
  submitted programs retain them. Failed selections keep requested coordinates
2197
2232
  and available extent in their owning Problem. Projection never parses its
2198
2233
  display strings to recover typed facts. A hidden body has no `preview`; a
@@ -2202,6 +2237,8 @@ curation, admission, or immutable evidence.
2202
2237
 
2203
2238
  Field absence carries defaults: `origin` is omitted for the owning model, `source` for the owning worker, and `status` for a routine 200. Dispositions always carry their lifecycle status, SEND its delivery status, KILL keeps an explicit 200, and every non-200 stays explicit. A present authored aside appears as `aside`. Every row's accounting follows {§packet-token-accounting}.
2204
2239
 
2240
+ Authored `metadata` retains its opaque ordered block strings under {§scheme-metadata-modifier}; COPY/MOVE pair them as `{from,to}`. Packet rendering does not interpret scheme options or discard malformed input from a failed operation.
2241
+
2205
2242
  - §operation-resource-receipt A result's nonempty `resource` address remains visible in receipt metadata when distinct from its `path` and `stream`. It identifies returned material without replacing the addressed operand or injecting that material into context; ordinary READ acquires it.
2206
2243
  - §packet-attachment-parts A successful READ of an attachable resource carries projection facts with its
2207
2244
  result ({§mimetype-projection-facts}): an image ({§mimetype-image}) as
@@ -2227,7 +2264,7 @@ Field absence carries defaults: `origin` is omitted for the owning model, `sourc
2227
2264
  records the exact READ coordinates sent without controlling retention. Missing immutable bytes are an
2228
2265
  internal integrity failure, never silently dropped content. No ejection message or permanent teaching is
2229
2266
  added. These stable curation weights are not provider-token measurements ({§tokenomics-render-weight-budget}).
2230
- - §packet-token-accounting Every row reports one `logTokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, written request, facts, visible body, and selected native attachment. The completed record is measured to a fixed point, including the accounting field itself. No `tokensBody`, `tokensMetadata`, or `tokensActive` field is serialized. Hidden text is not charged; metadata-only rows still have a reclaimable charge. Source/FIND-item `tokens` measure source content, not the observation's context footprint. A FIND's nonzero `itemsTokenTotal` weighs the complete matched set; a nonzero `returnedItemsTokenTotal` appears only when the returned page differs. All use stable curation weights, not provider tokens or dollars. Native component accounting follows {§packet-attachment-parts}; ordinary addressability and truthful errors follow {§log-wire-format}.
2267
+ - §packet-token-accounting Every row reports one `logTokens` charge on its H3 ({§log-wire-format}): its complete materialized H3, facts, visible body, and selected native attachment. The completed record is measured to a fixed point, including the accounting field itself. No `tokensBody`, `tokensMetadata`, or `tokensActive` field is serialized. Hidden text is not charged; metadata-only rows still have a reclaimable charge. Source/FIND-item `tokens` measure source content, not the observation's context footprint. A FIND's nonzero `itemsTokenTotal` weighs the complete matched set; a nonzero `returnedItemsTokenTotal` appears only when the returned page differs. All use stable curation weights, not provider tokens or dollars. Native component accounting follows {§packet-attachment-parts}; ordinary addressability and truthful errors follow {§log-wire-format}.
2231
2268
 
2232
2269
  ### §retrieval-packet-metadata READ/FIND packet metadata
2233
2270
 
@@ -2241,10 +2278,10 @@ The packet projects one actionable owner for each retrieval fact:
2241
2278
  | catalog/path FIND | `range` in resources | none | none |
2242
2279
  | 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` |
2243
2280
  | exact matcher FIND | `range` in match locations | each row's locator/region; a regex or glob row also carries `matched`, the matched text | none |
2244
- | pattern READ ({§read-pattern}) | `range` over the physical lines | the selected lines with their ordinals and anchors | `matcher` and `matched`, the selected line count |
2281
+ | pattern READ ({§read-pattern}) | `range` over the physical lines | the selected lines with their ordinals and anchors | the heading's pattern and `matched`, the selected line count |
2245
2282
 
2246
- Any row whose statement carried a heading pattern ({§matcher-option}) names it as
2247
- `matcher`, and a pattern mutation ({§edit-pattern}, {§kill-pattern},
2283
+ Any row whose statement carried a heading pattern ({§matcher-option}) retains it
2284
+ in its H3, and a pattern mutation ({§edit-pattern}, {§kill-pattern},
2248
2285
  {§copy-move-pattern}) carries its `matched` count beside its receipt, so a
2249
2286
  digest can show what a pattern selected and how much it touched.
2250
2287
 
@@ -2529,7 +2566,7 @@ Log history preserved — `log_entries` stores path tuple as text, not FK to `en
2529
2566
  - §find-glob-filter-on-content The heading's `pattern` option ({§matcher-option})
2530
2567
  matches the selected channel's content or derivation; path globs select
2531
2568
  resources through `(target)` ({§path-glob}).
2532
- - §find-fulltext-selection Every matcher operates only over the candidate set selected by `(target)`; indexed matchers do not bypass that selection. `~query` passes the native FTS5 expression to SQLite and ranks matching candidates by ascending BM25, with resource identity breaking ties. Native BM25 uses the shared index's term statistics; candidate visibility, owner, channel and target filters determine which resources can be returned. The ordinary FIND pager selects resources for broad targets or match locations for exact targets: markerless search defaults to `<1,16>`, `<N>` selects position N and `<N,M>` selects an inclusive range. Fractions are invalid result coordinates, not similarity thresholds. Results expose addressable matched text regions; neither cosine scores nor percentage similarity is invented. Native query-syntax failures return 400 with SQLite's diagnostic; database and implementation failures propagate.
2569
+ - §find-fulltext-selection Every matcher operates only over the candidate set selected by `(target)`; indexed matchers do not bypass that selection. `~query` passes the native FTS5 expression to SQLite and ranks matching candidates by ascending BM25, with resource identity breaking ties. Native BM25 uses the shared index's term statistics; candidate visibility, owner, channel and target filters determine which resources can be returned. The ordinary FIND pager selects resources for broad targets or match locations for exact targets: markerless search uses {§markerless-first-page}, `<N>` selects position N and `<N,M>` selects an inclusive range. Fractions are invalid result coordinates, not similarity thresholds. Results expose addressable matched text regions; neither cosine scores nor percentage similarity is invented. Native query-syntax failures return 400 with SQLite's diagnostic; database and implementation failures propagate.
2533
2570
  - §find-scoped-isolation Workspace + scheme scoped — no cross-workspace/cross-scheme leakage.
2534
2571
  - §find-result-projection **The authored target shape determines the result unit; result cardinality never changes it** ({§find-result-unit}). Returns `FindResult { status, content, mimetype, results, range, matchingPathCount, matchLocationCount, itemsWeightTotal, returnedItemsWeightTotal }`:
2535
2572
 
@@ -2692,7 +2729,13 @@ accounting and model-visible failure evidence remain separately owned by
2692
2729
  Delivered as a SEND, the text read as an answer and confirmed that speaking outside operations
2693
2730
  works; reported as a count of invalid characters, it sent a model to repair its prose into
2694
2731
  live operations (`demo-show-dont-run-qdN9u2` executed the KILL it meant to show). A NOTE
2695
- neither delivers nor concludes (operator, 2026-09-22). This is the far end of the teaching
2732
+ neither delivers nor concludes (operator, 2026-09-22). Storing interstitial text is a
2733
+ privilege, not a right (operator, 2026-09-23): a span is retained only on a turn that
2734
+ executed at least one operation, and only when it is narration. An empty turn retains no
2735
+ NOTE, and on any turn a span that carries a known foreign tool-call grammar, a leaked
2736
+ template token, or an operation attempt outside its fence retains none either. The exact
2737
+ emission stays at `ops://`, and the packet never echoes the grammar that broke a turn for
2738
+ the next turn to imitate. The registers are mechanism (`KnownToxins`). This is the far end of the teaching
2696
2739
  scale: text outside every operation breaks the first rule of `plurnk.md` — *"YOU MUST ONLY
2697
2740
  use valid Plurnk OPs"* — and takes the largest reinterpretation, while a
2698
2741
  departure as small as a missing closer is read as meant ({§closer-fallback}).
@@ -2708,9 +2751,11 @@ accounting and model-visible failure evidence remain separately owned by
2708
2751
  Count parsed response operations before outside-text and reasoning NOTEs join them;
2709
2752
  neither enters the count. When none exist and no boundary was lost, retain the turn and its raw
2710
2753
  sources and count one progress-contract strike, whether or not the turn carried text
2711
- ({§response-text-note}). The strike sends no notice of its own; the threshold terminal is
2712
- where it becomes visible, and it says why ({§engine-rails}). An empty turn uses its exact
2713
- text as the cycle fingerprint ({§engine-cycle-evidence});
2754
+ ({§response-text-note}). The strike sends no notice of its own: the turn records one `_plurnk`
2755
+ error row, `422` `The turn performed no operation.`, which rides the next packet's errors like
2756
+ any failure ({§operation-result-uniform-error-channel}), and its reasoning is read back to the
2757
+ model under {§reasoning-empty-turn-read}; the threshold terminal still says why ({§engine-rails}).
2758
+ An empty turn uses its exact text as the cycle fingerprint ({§engine-cycle-evidence});
2714
2759
  different empty programs are not a repeated cycle merely because neither contained
2715
2760
  operations. Lost-boundary handling remains {§unparsed-tail-boundary}; no confirmation
2716
2761
  token or private retry is invented here.
@@ -2789,7 +2834,7 @@ control capabilities, not exceptions granting write access to stdout/resources.
2789
2834
 
2790
2835
  ### §exec Executions
2791
2836
 
2792
- AST: `{ runtime (the fence name in its registered lowercase spelling; there is no operation keyword), target (optional runtime-specific target), body: string | null (runtime-specific input), lineMarker (timeout/poll) }`.
2837
+ AST: `{ runtime (the fence name in its registered lowercase spelling; there is no operation keyword), target (optional runtime-specific target), body: string | null (runtime-specific input), lineMarker }`. Execution refuses a non-null scope under {§exec-lifetime}.
2793
2838
 
2794
2839
  §exec-target-routing Engine routes unconditionally to the `exec` scheme,
2795
2840
  resolves the runtime first, selects its static {§executor-invocation} or exact
@@ -2864,7 +2909,7 @@ target at its run boundary.
2864
2909
  §exec-source-temporary **Resource execution preserves source identity.** After
2865
2910
  acceptance, Core reparses the complete authored address and resolves one exact `<1,-1>` READ through
2866
2911
  {§universal-read-composition}; internal source consumption never borrows the
2867
- model-facing 16-line preview. For the default channel, a source owner supplying
2912
+ model-facing preview ({§body-projection}). For the default channel, a source owner supplying
2868
2913
  a native file through {§scheme-source-bytes} supplies the executor target:
2869
2914
  its filename, extension, sibling imports, and source-relative assets remain
2870
2915
  intact. This neither bypasses admission nor changes the executor's working
@@ -2920,11 +2965,6 @@ catalogue.
2920
2965
 
2921
2966
  Per-tool programs such as `go`, `cargo`, `make`, and `npm` do not earn executor tags merely because they are executables; they are complete shell commands in a `sh` executable fence. Registered tags exist only for tools that own a distinct body, target, or output contract. {§exec-registry-resolves}
2922
2967
 
2923
- **Timeout and poll — `<T,P>` on the `<L>` slot (grammar 0.74.20).** An execution
2924
- repurposes the line-marker slot as `<timeout, poll>` in **minutes** — agentic
2925
- latencies make a sub-minute horizon a trap — converted at the parse boundary to the
2926
- catalog's internal `stream.seconds`. WAIT takes no timing; future wakes belong to the schedule family.
2927
-
2928
2968
  §exec-lifetime **How long a spawn may live is the fence's metadata, one field.**
2929
2969
  `[{"lifetime": …}]` takes a duration (`30s`, `30m`, `2h`), or one of three words;
2930
2970
  absent is `loop`. An execution takes no scope: a numeric coordinate on an
@@ -3472,6 +3512,10 @@ loading; their runtime dependency graphs contain no leaf consumers. A required
3472
3512
  default leaf missing from a service install is a broken install. A direct
3473
3513
  framework consumer may intentionally omit leaves and receives that framework's
3474
3514
  documented unavailable-capability behavior.
3515
+ Packed executor coverage distinguishes installation from enablement: verify
3516
+ the package floor, explicit opt-in, and composed allowlist/disable behavior
3517
+ through discovery and registration outside the development dependency graph
3518
+ ({§executor-default-inventory}, {§executor-policy}).
3475
3519
  Every non-optional grammar in the mimetype framework's registry is a required
3476
3520
  service runtime dependency, and an optional one ({§mimetype-optional-grammars})
3477
3521
  must not be. Installation coverage loads each default grammar and verifies
@@ -3618,7 +3662,7 @@ Each knob's value lives on its panel and nowhere else (`plurnk-service config de
3618
3662
  | `PLURNK_SERVICE_PREVIEW_LINES` | First page of every markerless retrieval, in the projection's own units, and the head bound of an automatic preview ({§markerless-first-page}, {§body-projection}). |
3619
3663
  | `PLURNK_SERVICE_PREVIEW_CHARS` | Independent Unicode code-point bound on the same previews, with CRLF treated as one indivisible separator ({§body-projection}). |
3620
3664
  | `PLURNK_SERVICE_PROMPT_PROJECTION` | Aggregate curation-weight share of the provider-derived input capacity available to the automatic projection of arrivals from outside the workspace ({§message-projection}); alias-scoped overrides are supported. |
3621
- | `PLURNK_SERVICE_LINE_ANCHOR_CONTEXT_LINES` | Complete neighboring lines hashed on each side of a model-facing line anchor ({§line-anchors}). |
3665
+ | `PLURNK_SERVICE_LINE_ANCHOR_CONTEXT_LINES` | Minimum neighboring lines hashed on each side; repeated handles expand their context ({§line-anchor-disambiguation}). |
3622
3666
  | `PLURNK_SERVICE_EDIT_RECEIPT_CONTEXT_LINES` | Surrounding and landed lines shown at each EDIT result boundary ({§edit-result-receipt-projection}). |
3623
3667
  | `PLURNK_SERVICE_MIN_CYCLES` | Min repetitions before cycle detection fires ({§engine-rails}). |
3624
3668
  | `PLURNK_SERVICE_MAX_CYCLE_PERIOD` | Max period length cycle detection examines ({§engine-rails}). |
@@ -3660,6 +3704,12 @@ instead of a user's boot, and a dead knob cannot ship.
3660
3704
  | Operator env/shell | Model alias declarations and explicit selection overrides, provider capability such as GBNF, endpoints, credentials, tuning, and deliberate ceiling overrides. |
3661
3705
  | `test/setup.ts` | Mock-only alias, envelope, resource, storage, and isolation fixtures; unit/integration never consume the real-model profile. |
3662
3706
 
3707
+ The profile clears `PLURNK_SERVICE_POLICY`, disabling the implicit XDG
3708
+ `AGENTS.md` policy under {§policy-sections}. Mock tests do the same in their
3709
+ bootstrap. Live/demo and benchmarks may select a harness-owned policy explicitly;
3710
+ none implicitly inherit the daily-driving policy. This does not disable project
3711
+ `AGENTS.md` guidance or modify the operator's file.
3712
+
3663
3713
  The profile does not repeat `NODE_OPTIONS`: runner selection belongs to the invoking command, and a process-global Node option would leak into the daemon and its children. Hard ceilings such as max turns, max commands, and Git denial remain operator-owned; harnesses bound paid experiments through their per-call contract and never widen a configured ceiling here.
3664
3714
 
3665
3715
  §operator-config-zero-pin-gate **Zero-pin is a counterfactual real-model gate,
@@ -3679,6 +3729,17 @@ The floor reports every removed key. A gate that succeeds only with those pins
3679
3729
  is red because provider capacity did not derive for
3680
3730
  a fresh-user configuration.
3681
3731
 
3732
+ §turn-cap-counts-the-tree **The turn ceiling is the worker tree's budget of model
3733
+ calls.** The owner is the current loop of the topmost ancestor-or-self worker that has
3734
+ one: for a tree a client started, the root worker's loop current when this loop began (its
3735
+ `max_turns`: the client's `maxTurns` clamped by the operator ceiling below); a loop with no
3736
+ such ancestor owns its own budget. Every model call on the owner's loop and on any later
3737
+ loop of the owner's descendants spends it, emission turns and BARE calls alike, open or
3738
+ settled, one per call however many physical requests it took. `LoopDriver` reads the tree's count before each turn and rules the `max-turns` 429
3739
+ terminal ({§loop-terminals}) when the ceiling is met; a BARE beyond the budget is refused
3740
+ 429 `max-turns` before any provider call, so one turn cannot spend past it with a batch. A
3741
+ child loop inherits the value and binds the same count.
3742
+
3682
3743
  §operator-config-max-turns-ceiling Enforcement is per-use-site — no central most-restrictive pass; each ceiling is checked where it bites. `PLURNK_SERVICE_MAX_TURNS` ships **off** (`-1` = no cap; the loop ends via SEND, budget, strikes, or cycle detection) and, when an operator sets a positive value, the per-call request is `min()`-capped against it.
3683
3744
 
3684
3745
  §operator-config-workspace-settings **Client open-context (per workspace).**
@@ -4043,7 +4104,8 @@ publications before inspection or shutdown.
4043
4104
 
4044
4105
  §functionality-documents **Generated documents describe the shared snapshot.**
4045
4106
  Documents are projected through the existing worker generated subtree
4046
- ({§worker-generated-subtree}); the projection does not confer ownership.
4107
+ ({§worker-generated-subtree}); the projection does not confer ownership, and it
4108
+ follows the family's admission ({§schemes-directory}): a denied family projects none.
4047
4109
  Enabled, active definitions are discoverable. Disabled or unavailable
4048
4110
  definitions add no hot-path teaching. Their exact state and Problem remain
4049
4111
  available through `list`.
@@ -4501,7 +4563,7 @@ time of measurement.
4501
4563
  - **Derivation is exhaustive and demand-led.** Explicit searchable-resource changes may start one coalesced warm. Passive creation and attachment do not. The first model turn starts or joins that warm; later turns derive intervening changes before dispatch. No model operation observes partial graph or full-text coverage. Progress notices make the wait visible. {§derivation-exhaustive}
4502
4564
  - §membership-binary-sniff **Binary truth beats a text label.** Filesystem source acquisition, including tracked members and installed skill resources, inspects up to the first 8192 bytes when extension detection does not identify a binary type. NUL marks `application/octet-stream`; existing binary types retain their declared type. Member projections follow {§membership-source-projection}; installed skill projections follow {§skills-resources}.
4503
4565
  - §tokenomics-agnostic-ruler **One model-agnostic curation ruler.** The daemon runs workers on different models in one workspace concurrently, while catalog and log accounting are workspace-wide. `contentWeight = ceil(chars/2)` therefore gives one content one stable number without per-model workspace state or recount passes. It controls curation only; every provider call independently measures the complete request as well as it can.
4504
- - §tokenomics-neutral-telemetry **Curation telemetry is state, not response allowance.** The model-facing `Context Curation` section is one JSON object carrying `logTokensTotal` and `logTokensMax` (and `tokensResponseMax` when an output floor is disclosed). 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.
4566
+ - §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.
4505
4567
  - §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.
4506
4568
  - §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.
4507
4569
  - §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`. Derived `costUsd` sums every USD-expressible request and is `null` only when no request is expressible; a response-less failure or an uncataloged model is skipped, never allowed to erase the expressible evidence. Each derived aggregate usage field independently sums its reported quantity, so heterogeneous detail coverage remains partial rather than becoming fictitiously complete. This is operational request accounting, not invoice reconciliation. Output and reasoning are quantities the model cannot KILL, so they never alter the model-facing Budget ledger.
@@ -4783,7 +4845,7 @@ Retired terms stay retired: the lexicon guard rejects `thinking`, the unqualifie
4783
4845
  | inbound `SEND` from outside the workspace | budgeted head under {§message-projection} |
4784
4846
  | structured `EDIT` receipt or textual `COPY`/`MOVE` effects | complete receipt-owned join context |
4785
4847
  | every other nonempty body | head bounded independently by `PLURNK_SERVICE_PREVIEW_LINES` and `PLURNK_SERVICE_PREVIEW_CHARS` |
4786
- | bodyless row | heading, written request, and any facts; no coordinate lines; `logTokens` includes any selected native part |
4848
+ | bodyless row | heading and any facts; no coordinate lines; `logTokens` includes any selected native part |
4787
4849
 
4788
4850
  §markerless-first-page **Every markerless retrieval takes the same implicit marker.** A marker's
4789
4851
  unit is whatever its projection counts, so `PLURNK_SERVICE_PREVIEW_LINES` is the first page of
@@ -4937,13 +4999,14 @@ retain distinct contracts and lifetimes.
4937
4999
  | Import `@plurnk/plurnk-service/digest` | Ships `Digest` and its package-owned SqlRite statements; importing performs no I/O or process action. The CLI wrapper alone invokes it. |
4938
5000
  | `run({ dbPath })` | Reads the required database and writes a complete digest to `./test/digest` relative to the caller's working directory. |
4939
5001
  | `digestDir` | Selects a nonempty output directory. Both `run` and `requiem` refuse an output containing the input pathname or its resolved database before database/provider I/O or output writes; normalized and real paths participate in that check. `run` removes and recreates output so stale artifacts cannot survive; concurrent callers use distinct directories. |
4940
- | Reader lifetime | Both methods close their database reader on successful or failed reads, before rendering output or awaiting witness inference. |
5002
+ | Reader lifetime | `run` reads heavy evidence on demand while rendering, then closes its reader on success or failure. `requiem` closes its reader before awaiting witness inference. |
5003
+ | Export completion | Packet and response bodies are read and serialized one record at a time, without discarding evidence. `digest.json` is promoted from a partial file only after every artifact is written; its absence identifies an incomplete export. |
4941
5004
  | `workerId` | Narrows workers and every dependent loop, turn, turn-attached logical inference, specialization, physical request, and log row to that one worker. |
4942
5005
  | `workspaceId` | Narrows workers plus every logical inference and dependent evidence owned by one workspace, when both selectors are present they intersect. |
4943
5006
 
4944
5007
  §digest-cost-kind **Cost basis named.** A rendered Cost line carries the basis of its dollar figure: `(charged)` only when every settled request's cost is provider-charged; `(estimated — catalog rates)` when any settled request's cost is an estimate, because a mixed sum is no more trustworthy than its weakest term. A dollar figure without its basis reads as billed truth, and an estimate must never impersonate a charge.
4945
5008
 
4946
- §output-allowance-notice **The output allowance is disclosed, and a ceiling cut names its cause.** The packet's budget section carries `tokensResponseMax: <tokens>` beside the curation ceiling whenever the provider resolves an output budget — the per-turn response allowance is a capacity fact, disclosed rather than discovered by truncation. The disclosed number is the program's guaranteed room — the configured output floor less the reasoning subset, since reasoning spends from the same allowance — never the wire grant: overflow tolerance (#482) is never advertised in the packet, and a cut's notice names the true per-call grant from the response's own capacity record. When a provider finish is `length`, the engine emits an `output_truncated` notice (source `engine:capacity`) naming the allowance — the fact alone, never advice on what to do about it — on every path — railed or not — and the rails verdict never blames the model's grammar for a cut the engine's own ceiling made. The same precedence governs a cut so deep no operation parses: the rejection notice names the truncation as the cause, not the parser's symptom, overriding {§invalid-emission-attempts}'s parser diagnostic for `length` finishes.
5009
+ §output-allowance-notice **The output allowance is not disclosed; a ceiling cut names its cause.** The packet's budget section carries the curation state and no response allowance: a model does not plan in tokens and no harness tells it its output ceiling, so the number was a fact without a use — across 9,124 recorded model turns none was cut at the allowance, while 45 emissions or reasonings spent tokens interpreting it (#826, operator, 2026-09-24). Overflow tolerance (#482) is likewise never advertised; a cut's notice names the true per-call grant from the response's own capacity record. When a provider finish is `length`, the engine emits an `output_truncated` notice (source `engine:capacity`) naming the allowance — the fact alone, never advice on what to do about it — on every path — railed or not — and the rails verdict never blames the model's grammar for a cut the engine's own ceiling made. The same precedence governs a cut so deep no operation parses: the rejection notice names the truncation as the cause, not the parser's symptom, overriding {§invalid-emission-attempts}'s parser diagnostic for `length` finishes.
4947
5010
 
4948
5011
  §digest-wire-line **Wire health aggregated.** Each worker summary renders a `Wire:` line — total physical provider requests, error-outcome count, and the error percentage when nonzero. Provider-level failures are absorbed by retries below the packet stream, so without this aggregate a rate-limit storm is invisible in every summary while the model's experience stays clean.
4949
5012
 
@@ -5227,6 +5290,7 @@ section because they are language extensions rather than executable tools.
5227
5290
  |---|---|
5228
5291
  | Registered and model-visible scheme | Its reference is eligible when at least one supported resource capability is admitted by the effective policy ({§capability-admission}). Illustrative operations never determine admission. |
5229
5292
  | Runtime output scheme | Its runtime's reference owns discovery; no duplicate scheme reference. |
5293
+ | Family manager and its generated documents | Eligible while the family's manager runtime is admitted by the effective policy ({§capability-admission}), by name or by trait: a denied family has no page, no generated document and no runnable verb, so a masked family never stands in the survey empty (#842). |
5230
5294
  | Excluded scheme | `PLURNK_SERVICE_DOCS_EXCLUDE` omits its reference, not its functionality. |
5231
5295
  | Reference content | Required meta-owned content follows {§teaching-corpus}; other schemes may supply optional `manifest.documentation`. Absent optional content contributes nothing; a failed required source read surfaces its cause. |
5232
5296
  | Policy layers | Materialization, Turn0, and direct operations use the same current workspace policy and service ceiling. |
@@ -1 +1 @@
1
- {"package":"@plurnk/plurnk-service","version":"1.20.0","revision":"e546e762f4003c68993473ab86bf635f55728912","dirty":false}
1
+ {"package":"@plurnk/plurnk-service","version":"1.21.1","revision":"7650feb0526a2dd34ca0102af7a3f10ccfb15689","dirty":false}
@@ -1 +1 @@
1
- {"version":3,"file":"line-anchors.d.ts","sourceRoot":"","sources":["../../src/content/line-anchors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"line-anchors.d.ts","sourceRoot":"","sources":["../../src/content/line-anchors.ts"],"names":[],"mappings":"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"}