@llblab/pi-actors 0.58.0 → 0.58.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.
package/AGENTS.md CHANGED
@@ -88,12 +88,12 @@ For ordinary Run-file investigation, follow the accepted [same-session research
88
88
  - `file-state.ts`: canonical generic file-mutation locks and atomic JSON/text writers. withFileMutationLock preserves an exact synchronous callback rejection and a later surfaced release fault as ordered non-enumerable standard AggregateError errors/cause, including undefined/primitive/original aggregates; never coerce/flatten, replay callbacks, roll back bytes or interpret returned thenables. A single callback/release-only rejection and normal return remain exact. Atomic replacement separately preserves a single surfaced native-shaped rejection exactly, including null/undefined; retry-code access is null-safe and guarded. If that access throws, ordered private standard AggregateError errors/cause retains original then observation fault without coercion/flattening; no retry follows failed classification. Keep ordinary EPERM/EBUSY 20-attempt / 19×50ms limits, one onBeforeReplace call and already committed bytes unchanged. This is not writer rollback, fsync or cleanup proof. Acquisition, token/reclaim/lock interval and best-effort removal uncertainty stay separate. No async locking, exhaustive cleanup/native closure, public receipt or recovery of already-masked lower writer causes follows. Controlled release-fault fixtures retain their exact owner/frame and assert no workload/host exit.
89
89
  - `state-readers.ts`: resilient JSON/JSONL parsing; strict UTF-8 JSON is opt-in; capped strict reads use available nonblocking/nofollow flags, require a regular opened descriptor and reach the complete declared file, never admit a valid prefix after premature EOF. Legacy degradation stays unchanged; bounded ownership-marker admission also selects strict reading. Execution manifest export/reference admission selects it; malformed bytes must not normalize into admitted source metadata.
90
90
  - `runtime-identity.ts`, `runtime-triage.ts`: immutable package/schema identity and pure pending/stale Control classification.
91
- - `tools-response.ts`: shared response formatting, including the flat launch receipt, two-space opaque Markdown field and typed inspect-next primitives now reused by Control, pure admitted-snapshot text/JSON rendering and the literal-block primitive reused by completion packets. Launches retain every selected fact/reuse distinction, one optional current-session action only without a fully shown direct row, whole literal navigation and shared16KiB bounds including the no-navigation fallback. Never migrate the older formatRunFileNavigationHandoff packet grammar implicitly; completion/version contracts stay independent. Own-data/scalar/schema validation grants no visibility/lifecycle/timing permission. Preserve complete identities/references, CRLF/BOM/Unicode and exact ms; use dynamic literal fences rather than whitespace normalization. Compact JSON retains the same bounded payload; text fence amplification refuses the whole view, never clips or silently changes format. Tool spacing/envelope and combined delivery budgets remain separate, not extra allowance. Synthetic terminal-format fixtures prove no frozen-terminal timing or visual/public acceptance.
91
+ - `tools-response.ts`: shared response formatting, including the flat launch receipt, two-space opaque Markdown field and typed inspect-next primitives now reused by Control, pure admitted-snapshot text/JSON rendering and the literal-block primitive reused by completion packets. Its YAML and legacy Recipe hint renderers share one private exact-literal classifier; keep their framing, budget and opaque-fallback contracts separate. Launches retain every selected fact/reuse distinction, one optional current-session action only without a fully shown direct row, whole literal navigation and shared16KiB bounds including the no-navigation fallback. Never migrate the older formatRunFileNavigationHandoff packet grammar implicitly; completion/version contracts stay independent. Own-data/scalar/schema validation grants no visibility/lifecycle/timing permission. Preserve complete identities/references, CRLF/BOM/Unicode and exact ms; use dynamic literal fences rather than whitespace normalization. Compact JSON retains the same bounded payload; text fence amplification refuses the whole view, never clips or silently changes format. Tool spacing/envelope and combined delivery budgets remain separate, not extra allowance. Synthetic terminal-format fixtures prove no frozen-terminal timing or visual/public acceptance.
92
92
  - `tools-spawn.ts`, `tools-register.ts`, `tools-local.ts`: Run creation, persistent capabilities, Recipe-backed tools and compact results. Compact spawn/async-tool launch receipts retain facts, expose actual existing-Run reuse and omit the redundant session-map hint only when the complete direct row is shown; absent/unavailable/omitted rows retain that request. Compact launch metadata uses bare block YAML with nested complete location values; preserve the original JSON details, expert facts, shared bounds and old completion text. Keep one leading result-separator LF for host invocation spacing, outside the pure YAML emitter. Spawn-verbose source selects legacy pretty JSON once after eager compact evaluation, then emits full YAML only from that clone without a new fixed byte/depth cap. Keep original stringify throws outside the projection catch; absent selected JSON, malformed selected keys/strings and recoverable post-selection failures withhold the whole projection with an attributable no-auto-repeat receipt, not repaired values, partial full facts or private causes. Returned details and unrelated JSON helpers stay unchanged; compiled-package and loaded-host adoption remain separate. Do not synthesize routine Run-inspection next actions or unconditional delivery/readiness promises. Preserve existing structured/verbose metadata, expert Inspect access and separately owned targeted diagnostic remediations. Runtime argument-repair guidance is pre-dispatch only: once an executor is entered or arguments are handed to the async launcher, rethrow the exact original value/cause/details even when its text matches validation prefixes. Preparation side effects, dispatch, actuation and closure remain distinct; add no retry and preserve configured execution policy.
93
93
  - `inspector.ts`: owned-Run evidence and exact-session/generation-fenced actions through injected canonical control dependencies. `inspector-overlay.ts` and `inspector-command.ts` retain UI/navigation and host command wiring separately. **Actor Inspector** remains the product and command name, not a separate domain.
94
94
  - `pi.ts`: Pi SDK envelope boundary. AX completion fallback identity comes from the closed terminal marker for new records or the original headers for retained captures when private details are stripped; keep the original legacy RegExp coercion order, reject noncanonical/indented/broken markers and never acknowledge by body equality; never let authored body labels or Unicode line separators override it. Preserve older header recognition and detailed-envelope precedence. Parsed ids remain hints until exact owned-journal/content admission; they grant no recipient, source or native authority.
95
95
  - `observability.ts`, `run-ui-runtime.ts`: Trace attention, terminal reconciliation and Pi delivery. Fresh urgent-steer admission uses formatRunSteerMessage's single canonical AX layout only after the retained run/generation/directory/event lookup. Envelope.content is already frozen presentation: replay it directly without a new journal aspect, source refresh or reformatting. Attention and steer have no presentation selector or alternate new-message formatter; deliverRunAttentionNotifications uses the same canonical AX primitives for new notify/followup output. Saved envelope.content remains the compatibility boundary. The two AX checkpoint/reference helpers now have real ordinary/urgent reuse inside observability; keep ordinary first-eight coverage independent of steer's shared16KiB reservation/refusal loop. No ambient ordinary byte cap, event/detail copy, wake change or regeneration of committed content follows. Fresh attention uses shallow typed block-YAML metadata, bare without a body and delimited before an opaque zero-added-indent body. Preserve scalar-aligned500UTF-16 legacy previews, existing ellipsis and unknown local/upstream loss, original stringify/getter faults, whole reference sequences and first-eight slots before malformed filtering. Ordinary notify/followup remains unbounded; urgent steer validates raw essentials before reference reads and fits the complete final YAML/body with later-group omission coverage under16KiB. Serialization stays local to observability, not a new global formatter allowance; selection/read/acceptance authority stays here. Fresh urgent diagnostics also reuse its opaque field primitive: event/attention/stage records distinguish retryable admission, failed send request with unconfirmed delivery/presentation, and queued recovery with its exact evidence status/reason. Do not infer no effect from an exception or turn checkpoint retry into workload replay. Diagnostic display keeps only240pair-aligned raw message units and authored Markdown, with boundary U+2026/[omitted: unknown] for loss and unavailable for malformed text. This current UI projection is separate from unchanged whitespace-normalized/trimmed4096-unit last_error, original Error/cause and frozen envelope.content; create no saved format/aspect, reader, recovery loop or extra source permission. Fresh locally owned runtime notices use tools-response.ts:formatYamlNotice, a UI-only flat-field serializer without the model byte/depth ceilings: retain full well-formed fields, withhold malformed selected text explicitly, and keep existing diagnostic-preview bounds. Callback failure preserves the original onCallbackError value and opaque diagnostic; completion recovery preserves evidence status/pending phase/reason with no forced send; idle completion delivery is labeled accepted only after the original durable acceptance; teardown counts/whole literal summary path are explicitly report data, not scope closure. Watcher/retirement messages are forwarded unchanged from observability's new AX producer formatting. Watcher messages reuse the already captured detail/recovery strings: never read Error.message twice, add primitive-error coercion, change raw signatures/IDs/ts/dedup/32suffix/rearm policy or regenerate older diagnostic text. Paths stay whole dynamic literals. Retirement notices preserve optional-notify argument short-circuiting, exact error-message observations, attempted/sendStop/cancel/result/failure behavior including notifier throws, and unconfirmed closure. Stop returned and cancellation reported are not native success; fallback reason is stop path failed because the path also contains notifier execution. Do not repair already-discarded lower causes or rewrite result errors from the display. No new clipping, identities, state reads, notifier timing/levels/dedup, retries, error wrappers or native authority. Fresh completion admission creates canonical AX only after existing owner/location rechecks; an already-admitted batch returns untouched, including every older presentation format. Keep active/idle timing, acceptance, exact generation and source admission authority unchanged; fresh completion-prefix allocation follows the run-delivery contract below. Color terminal status only in `ctx.mode === "tui"`; JSON/print/RPC status must not require an initialized terminal theme or disable mandatory completion delivery. Shared ready-forest selection and ambient candidate checks are metadata-only for primary sources. Read/verify a selected primary source only when collecting eligible completion members, retaining exact source owner/generation and refusing capture promotion or lost-source stdout substitution. Unsupported complete raw-stream selections remain explicit or legacy diagnostics, never fabricated primary output; separately admitted executor-final-response text is not complete raw-stream selection.
96
- - `run-delivery.ts`: owner-scoped durable packet/phase persistence and bounded projections. Fresh ordinary source admission captures presentation_format=ax_records, own-data result_layout=completion_yaml_files_v1 and frozen text_budget, with no presentation selector/excerpt_format; direct and ordinary UI admission share this path. The separate inactive numbered-stream capture still inherits frontmatter_v2; do not change the private default globally or relabel retained captures. Preserve all stored encodings/absence and exact replay bytes/hints, including headings_shared_kinds and frontmatter_v1/v2; reject mixed/unknown aspects without invoking accessors. Journals store snapshots, not complete text, so neither an unreleased version nor a schema fix permits rewriting old codecs. The second frontmatter capture layout quotes unknown index as YAML "?"; the first keeps its original bytes, including unquoted ?. Fresh headers begin index, run, state, then admitted kind:primary/diagnostic; meaningful metadata and whole source/generation/location references follow. Display index is not member_index or native identity. Raw admitted Markdown follows the closed YAML at the left margin, without #N heading, result:/preview: wrapper, structural list indentation or whole-body literal fence. Known display loss is [N characters omitted] at the cut; no added ellipsis or body clipping flags/counts in YAML. Fresh rooted captures keep unknown upstream/fallback completeness/privacy warnings in header text_warnings; only an exact known character-omission marker follows a cut body. Fallback has no primary kind. Retained layouts keep their original marker placement. Visible text is admitted output/final Actor response or error/failure diagnostics, never command metadata or copied command excerpts. Source text_basis remains technical. No routine group windows/status copies, members wrapper, outer counters, Batch caption or standing full-map instruction appears in new model content; captured facts remain journal data. Material whole-result/reference omission, non-done omitted states and a whole inventory reference remain explicit. A single shown row keeps the same shape even when other results were omitted. Complete model content includes all exact references and only the necessary YAML-core packet identity/relative body-marker lengths, without fresh compiler HTML tails, under49152UTF-8 bytes for up to64candidate rows/256captured members. Equal scalar/CRLF-safe text-prefix shares freeze at admission, including service overhead; no redistribution, fixed16KiB result/2KiB preview cap, source recapture or later reallocation. Preserve every saved16KiB/48KiB allowance. Prefix admission must consider full-list/decimal discontinuities rather than miss fitting rows when omission scaffolding shrinks. Whole text has no display-cut marker when complete; known upstream clipping still forbids a full-original-output claim. The source reader selects at most48KiB from the same verified postprivacy observation; source-binding previews stay160code points. Retain chosen packet prefixes, not64independent48KiB copies. Unfit metadata rows keep bounded inventory recovery. Curate/copy/freeze members, arrays, artifacts and bindings; schema DTOs grant no publication permission and phase changes do not mutate member facts. Preserve generation/parent/source identities, exact ranges/hashes and whole references. The completion-only TUI uses independent native Markdown body components and literal Text header/marker/service components, with no global Markdown patch, source/native IO or scheduling authority. New rooted captures expose files.groups in the header: one literal root per group, relative entry paths, English role/purpose and read_first group/entry indices. Reconstruct original selected references exactly; never normalize dot/symlink routes, guess cwd or treat declared targets as produced. Unresolved paths retain path_basis=as_recorded/base_unavailable with a null root and no recommendation. Observation.group binds its original mutable Run-directory facts. All packet/inventory/whole-row omission metadata renders in the first header, not a service footer; no runtime text follows the last body except its known cut marker. Retained core-v1 captures keep their original references/locations and compact hiding rules; authored body lookalikes never disappear. Fresh ordinary hints use completion_yaml_core_v1 plus a whole-content digest; validated core lengths derive block positions. Retained completion_frontmatter_v1 hints keep their SHA-256-bound UTF-16 header/body/marker/service blocks and original compiler frames, dense ordered coverage and scalar/CRLF-safe endpoints. Invalid/missing hints and expansion reveal original full Text. These are display/correlation consistency, not authentication/read/action/acceptance/native authority. Malformed frontmatter-shaped stripped history cannot regain identity from a body Batch label or become absence/retry permission; ordinary thematic-break prose retains its legacy path. Retained pre-record codecs keep host rendering; older record/literal codecs keep exact original hints, dynamic fences, count spelling and separators. Fresh ordinary indices remain packet-local; no default stream activation follows. Fresh UI member locations are observed before journal locks after actual current-session selection/recheck, with captured_file_locations and frozen file_navigation. Data-only decoding does not grant current body/source visibility. Location snapshots retain16KiB, outcomes outrank lower-priority references, and each shown record has a whole location row or explicit omission; wholly omitted records stay inventory-covered. Reload/render/phase recovery never refreshes sources or frozen availability. Old absent/current_session_request captures keep their bytes, and optional full-map research stays a separate current-session action. Source/package checks do not prove the loaded host was reloaded.
96
+ - `run-delivery.ts`: owner-scoped durable packet/phase persistence and bounded projections. Fresh ordinary source admission captures presentation_format=ax_records, own-data result_layout=completion_yaml_files_v2 and frozen text_budget, with no presentation selector/excerpt_format; direct and ordinary UI admission share this path. The separate inactive numbered-stream capture still inherits frontmatter_v2; do not change the private default globally or relabel retained captures. Preserve all stored encodings/absence and exact replay bytes/hints, including headings_shared_kinds and frontmatter_v1/v2; reject mixed/unknown aspects without invoking accessors. Journals store snapshots, not complete text, so neither an unreleased version nor a schema fix permits rewriting old codecs. The second frontmatter capture layout quotes unknown index as YAML "?"; the first keeps its original bytes, including unquoted ?. Fresh headers begin run, state, then admitted kind:primary/diagnostic; prepend the packet-local index only when two or more results are shown. meaningful metadata and whole source/generation/location references follow. Display index is not member_index or native identity. Raw admitted Markdown follows the closed YAML at the left margin, without #N heading, result:/preview: wrapper, structural list indentation or whole-body literal fence. Known display loss is [N characters omitted] at the cut; no added ellipsis or body clipping flags/counts in YAML. Fresh rooted captures keep unknown upstream/fallback completeness/privacy warnings in header text_warnings; only an exact known character-omission marker follows a cut body. Fallback has no primary kind. Retained layouts keep their original marker placement. Visible text is admitted output/final Actor response or error/failure diagnostics, never command metadata or copied command excerpts. Source text_basis remains technical. No routine group windows/status copies, members wrapper, outer counters, Batch caption or standing full-map instruction appears in new model content; captured facts remain journal data. Material whole-result/reference omission, non-done omitted states and a whole inventory reference remain explicit. Exactly one shown row omits only its display index, including with other results omitted; preserve omission/inventory facts and internal member_index/generation/correlation. The rooted_files_v2 service discriminator gates this new presentation; retained rooted-files-v1/core-v1 snapshots keep their exact indices and bytes. Do not extend this packet-local exception to numbered streams. Complete model content includes all exact references and only the necessary YAML-core packet identity/relative body-marker lengths, without fresh compiler HTML tails, under49152UTF-8 bytes for up to64candidate rows/256captured members. Equal scalar/CRLF-safe text-prefix shares freeze at admission, including service overhead; no redistribution, fixed16KiB result/2KiB preview cap, source recapture or later reallocation. Preserve every saved16KiB/48KiB allowance. Prefix admission must consider full-list/decimal discontinuities rather than miss fitting rows when omission scaffolding shrinks. Whole text has no display-cut marker when complete; known upstream clipping still forbids a full-original-output claim. The source reader selects at most48KiB from the same verified postprivacy observation; source-binding previews stay160code points. Retain chosen packet prefixes, not64independent48KiB copies. Unfit metadata rows keep bounded inventory recovery. Curate/copy/freeze members, arrays, artifacts and bindings; schema DTOs grant no publication permission and phase changes do not mutate member facts. Preserve generation/parent/source identities, exact ranges/hashes and whole references. The completion-only TUI uses independent native Markdown body components and literal Text header/marker/service components, with no global Markdown patch, source/native IO or scheduling authority. New rooted captures expose files.groups in the header: one literal root per group, relative entry paths, English role/purpose and read_first group/entry indices. Reconstruct original selected references exactly; never normalize dot/symlink routes, guess cwd or treat declared targets as produced. Unresolved paths retain path_basis=as_recorded/base_unavailable with a null root and no recommendation. Observation.group binds its original mutable Run-directory facts. All packet/inventory/whole-row omission metadata renders in the first header, not a service footer; no runtime text follows the last body except its known cut marker. Retained core-v1 captures keep their original references/locations and compact hiding rules; authored body lookalikes never disappear. Fresh ordinary hints use completion_yaml_core_v1 plus a whole-content digest; validated core lengths derive block positions. Retained completion_frontmatter_v1 hints keep their SHA-256-bound UTF-16 header/body/marker/service blocks and original compiler frames, dense ordered coverage and scalar/CRLF-safe endpoints. Invalid/missing hints and expansion reveal original full Text. These are display/correlation consistency, not authentication/read/action/acceptance/native authority. Malformed frontmatter-shaped stripped history cannot regain identity from a body Batch label or become absence/retry permission; ordinary thematic-break prose retains its legacy path. Retained pre-record codecs keep host rendering; older record/literal codecs keep exact original hints, dynamic fences, count spelling and separators. Fresh ordinary indices remain packet-local; no default stream activation follows. Fresh UI member locations are observed before journal locks after actual current-session selection/recheck, with captured_file_locations and frozen file_navigation. Data-only decoding does not grant current body/source visibility. Location snapshots retain16KiB, outcomes outrank lower-priority references, and each shown record has a whole location row or explicit omission; wholly omitted records stay inventory-covered. Reload/render/phase recovery never refreshes sources or frozen availability. Old absent/current_session_request captures keep their bytes, and optional full-map research stays a separate current-session action. Source/package checks do not prove the loaded host was reloaded.
97
97
  - automatic draft/tool review domains: structurally redacted model review, journaled mutation, lineage, recovery, and explicit retry/reset safety.
98
98
 
99
99
  The bundled Skill Recipe dependency DAG is `artifacts → actors, swarm` and `project-work → actors, artifacts, swarm`; `actors`, `music-player`, `swarm`, and `recipe-memory` have no cross-Skill Recipe dependencies.
@@ -180,7 +180,7 @@ Automatic review receives value-free structural projections, not executable cont
180
180
 
181
181
  ## Output and Observability
182
182
 
183
- The [completion-stream contract](docs/coordinator-delivery.md#completion-streams-adopted-contract) is adopted and under implementation, not active. Keep persistent numbering in the existing delivery owner: no counter reset from missing state, no branch-history reconstruction and no activation before a coupled owner-locked packet/counter/target commit and compatible recovery/presentation. Current packet-local indices and all saved bytes/hints remain unchanged until that integration is validated. The pure whole-capture safe-integer range projection reserves nothing and grants no session/delivery authority. Kernel pending-intent storage requires an existing valid owner journal, not missing-state initialization; it supplies no fresh-session bootstrap or public start action. Never silently fall back to packet-local capture after retaining an intent. Staged numbering facts bind a complete frozen member permutation and exact range/scope or unavailability; projection must not re-sort or infer numbers from body labels/current state. Their compiler-bound technical/footer recognition is consistency/correlation only. Kernel-only captureRunCompletionStreamBatch now requires an existing valid stream journal and atomically commits the full fixed snapshot, advanced counter and pending-target activation under the existing lock. Counters are positive exact next values or explicit unavailability; malformed/missing records, mixed scopes and counters behind numbered packets stay refused. All saved numbers replay even if the current counter becomes unavailable; new packets freeze #? on admitted unavailability or whole-range exhaustion. Packet finalization/receipt rotation never clear stream state. Default runtime stream capture/recovery still requires an admitted internal binding. A trusted kernel-only completionStreamSessionAdmission port opts in only to verified fresh new/fork creation with an original manager/current ticket; an event reason, ID or copied DTO alone is not admission. Fresh wrappers must match that manager/generation; reused managers and old contexts cannot revive after A→B→A. Per-start watcher/reconciliation/timer tickets and a separate async-start ticket fence replacement. Unknown/revoked stream paths neither allocate nor ACK, including post-send replacement, which does not prove no transport effect. Missing metadata never bootstraps or falls back on this opt-in path. Startup/reload/resume, including ambiguous imports, remain refused even if the port returns true. Source/compiled real SDK lifecycle probes use controlled terminal/busy-boundary data and forbid model requests; they are not loaded/native work acceptance. No public command, bootstrap, trusted continuation/import decision or rollback recovery is enabled; direct callers cannot select numbering.
183
+ The [completion-stream contract](docs/coordinator-delivery.md#completion-streams-adopted-contract) is adopted and under implementation, not active. Keep persistent numbering in the existing delivery owner: no counter reset from missing state, no branch-history reconstruction and no activation before a coupled owner-locked packet/counter/target commit and compatible recovery/presentation. Packet-local index identities and all saved bytes/hints remain unchanged; hiding the display index on a fresh singleton does not activate or alter numbered streams. The pure whole-capture safe-integer range projection reserves nothing and grants no session/delivery authority. Kernel pending-intent storage requires an existing valid owner journal, not missing-state initialization; it supplies no fresh-session bootstrap or public start action. Never silently fall back to packet-local capture after retaining an intent. Staged numbering facts bind a complete frozen member permutation and exact range/scope or unavailability; projection must not re-sort or infer numbers from body labels/current state. Their compiler-bound technical/footer recognition is consistency/correlation only. Kernel-only captureRunCompletionStreamBatch now requires an existing valid stream journal and atomically commits the full fixed snapshot, advanced counter and pending-target activation under the existing lock. Counters are positive exact next values or explicit unavailability; malformed/missing records, mixed scopes and counters behind numbered packets stay refused. All saved numbers replay even if the current counter becomes unavailable; new packets freeze #? on admitted unavailability or whole-range exhaustion. Packet finalization/receipt rotation never clear stream state. Default runtime stream capture/recovery still requires an admitted internal binding. A trusted kernel-only completionStreamSessionAdmission port opts in only to verified fresh new/fork creation with an original manager/current ticket; an event reason, ID or copied DTO alone is not admission. Fresh wrappers must match that manager/generation; reused managers and old contexts cannot revive after A→B→A. Per-start watcher/reconciliation/timer tickets and a separate async-start ticket fence replacement. Unknown/revoked stream paths neither allocate nor ACK, including post-send replacement, which does not prove no transport effect. Missing metadata never bootstraps or falls back on this opt-in path. Startup/reload/resume, including ambiguous imports, remain refused even if the port returns true. Source/compiled real SDK lifecycle probes use controlled terminal/busy-boundary data and forbid model requests; they are not loaded/native work acceptance. No public command, bootstrap, trusted continuation/import decision or rollback recovery is enabled; direct callers cannot select numbering.
184
184
 
185
185
  Apply the project-wide [Agent Experience (AX) standard](docs/agent-experience.md) before changing Inspector, public tool output/errors or agent-bound context. AX is a shared semantic projection for both people and agents, not a Telegram theme or raw JSON dump. The adopted default for runtime-owned metadata is YAML 1.2 block mappings/sequences, not Markdown-list key/value pseudo-objects or embedded object JSON; sequence markers represent real sequences only. Preserve authored text/Markdown unindented outside the metadata header, without a YAML output scalar or added wrapper/fence; runtime-owned multiline metadata strings use proper YAML scalars. The old emitters remain current implementation facts until their owned rollout, not a competing default. Display run: demo without a duplicated namespace, preserve canonical tool targets, literal sources and machine schemas, and use only admitted exact/unknown omission facts. New presentation must preserve source/ownership boundaries, full references, uncertainty, budgets and byte-stable old packets. The standard owns detailed syntax, examples, source-owner bindings and acceptance; BACKLOG owns rollout. Do not claim design adoption is implementation or restart Grow Loop/reload/publication by implication.
186
186
 
package/BACKLOG.md CHANGED
@@ -25,7 +25,7 @@ Exit: New owned runtime projections use YAML without pseudo-records or serialize
25
25
 
26
26
  Exit: Real loaded rendering is checked separately from source/headless/native proofs. This is independent follow-up, not a claim that the already merged release received loaded-host acceptance. Reload and an operator Run require their own authorization; do not start one merely to manufacture a live Kill case.
27
27
 
28
- - [ ] **U1.1 — Retest fresh completion packets and expansion.** After authorized reload, inspect actual singleton/multiple/omitted-row packets: index-first YAML/kind, left-edge independent Markdown, literal unfinished blocks, exact cut marker, blank separation and no routine top-level completion caption/toast. Expansion and historical fallback must preserve the saved text. Verify: actual terminal/phone observation plus existing delivery/Pi owners.
28
+ - [ ] **U1.1 — Retest fresh completion packets and expansion.** After authorized reload, inspect actual singleton/multiple/omitted-row packets: run/state YAML/kind with packet-local indices only for multiple shown results, left-edge independent Markdown, literal unfinished blocks, exact cut marker, blank separation and no routine top-level completion caption/toast. Expansion and historical fallback must preserve the saved text. Verify: actual terminal/phone observation plus existing delivery/Pi owners.
29
29
  - [ ] **U1.2 — Retest the Run dropdown.** Check shifted compact placement, independent stripes/right padding, narrow/medium/wide layout and unchanged selection/source detail. Preserve the accepted navigation and refresh behavior; do not invent a performance cause or change freshness speculatively. Verify: real Inspector plus existing overlay/Inspector properties.
30
30
  - [ ] **U1.3 — Retest notification and Kill modals.** Check complete selected notification text, no prefix/reader indirection, Esc-only dismissal and scrolling only on physical overflow; check centered compact Kill, default backgrounds/insets, frozen underlay and no key leakage. Cancel returns to the same Inspector without Notice; success relies on selected status and failures remain visible. Verify: actual permitted modal cases, without claiming Kill is scope closure.
31
31
  - [ ] **U1.4 — Retest Inspector chronology.** Check newest-higher numbering across 100→101/102, filter gaps without renumbering, scrolling/detail provenance and visible `#?` for unavailable history. Do not promise permanent lifetime ordinals or reconstruct missing offsets. Verify: [chronology contract](docs/actor-inspector.md#chronological-numbering-requested-replacement) on loaded terminal/phone.
package/CHANGELOG.md CHANGED
@@ -2,7 +2,12 @@
2
2
 
3
3
  > Each release keeps at most 8 outcome records of at most 512 characters.
4
4
 
5
- ## Unreleased
5
+ ## 0.58.1: Singleton Completion Indices
6
+
7
+ - `Singleton Completion Index`: New completion packets omit the packet-local display index when exactly one result is shown, including with omitted results. Multiple shown results retain indices; omission/inventory facts, internal identity/correlation, numbered-stream behavior and historical replay remain unchanged.
8
+ - `Inspection Hint Ownership`: YAML and legacy Recipe inspection hints share one exact three-literal classifier. Existing output bytes, verbose omission, budgets and opaque fallback remain unchanged; prefix, whitespace and authored-action lookalikes gain no typed authority.
9
+ - `Capability Contract Docs`: Tool Registry owns the current retention, receipt, storage and usage contract; Capability Memory keeps architectural rationale and future evidence/lifecycle gates. Existing design anchors and safety constraints remain, without a second copy of the operating contract.
10
+ - `Installed Runner Validation`: The installed-package regression joins original runner close and canonical success under the existing shared fixture watchdog instead of racing a five-second file poll. Failed or uncertain fixtures retain evidence; deletion requires fresh runner absence. Runtime deadlines and package execution are unchanged.
6
11
 
7
12
  ## 0.58.0: Explicit Capability Retention
8
13
 
package/dist/lib/pi.js CHANGED
@@ -83,7 +83,7 @@ function unheaderedCompletionId(content) {
83
83
  if (core.state === "available")
84
84
  return core.packet.batchId;
85
85
  // Initial compiler headers only: never recover identity by scanning authored bodies.
86
- if (/^(?:index: (?:\d+|"\?")\nrun: [^\n]*\nstate:|_completion:\n (?:codec|batch_id):)/u.test(content))
86
+ if (/^(?:index: (?:\d+|"\?")\nrun: [^\n]*\nstate:|run:[^\r\n]*(?:\r\n|\r|\n)state:|_completion:\n (?:codec|batch_id):)/u.test(content))
87
87
  return { malformed: true };
88
88
  }
89
89
  if (typeof content === "string" && (hasCompletionFrontmatterPrefix(content) || /^(?:#|Run #|— Новый поток|- run:|- #0:\n|- result: omitted \(model byte limit\)\n|- omitted_results:)/u.test(content))) {
@@ -66,7 +66,7 @@ export interface RunCompletionBatch {
66
66
  /** Retained singleton capture; absence preserves older indexed bytes. Never a new-capture selector. */
67
67
  readonly single_result?: true;
68
68
  /** Captured record-list shape; no public format/version choice or source authority. */
69
- readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1";
69
+ readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2";
70
70
  /** Immutable scope/order/range data, not a caller-selected format or allocation authority. */
71
71
  readonly numbering?: RunCompletionNumbering;
72
72
  /** Formatting version/data only; no recipient ownership, read or publication capability. */
@@ -278,8 +278,11 @@ function parseInventorySource(value, batch) {
278
278
  function isFrontmatterCompletionLayout(layout) {
279
279
  return layout === "frontmatter_v1" || layout === "frontmatter_v2";
280
280
  }
281
+ function isRootedCompletionLayout(layout) {
282
+ return layout === "completion_yaml_files_v1" || layout === "completion_yaml_files_v2";
283
+ }
281
284
  function isYamlCompletionLayout(layout) {
282
- return layout === "completion_yaml_core_v1" || layout === "completion_yaml_files_v1";
285
+ return layout === "completion_yaml_core_v1" || isRootedCompletionLayout(layout);
283
286
  }
284
287
  function isSharedCompletionLayout(layout) {
285
288
  return layout === "headings_shared_results" || layout === "headings_shared_kinds" || isYamlCompletionLayout(layout) || isFrontmatterCompletionLayout(layout);
@@ -688,7 +691,7 @@ export function requestRunCompletionStream(input) {
688
691
  });
689
692
  }
690
693
  export function admitRunCompletionBatch(input) {
691
- return captureCompletionBatch(input, false, "completion_yaml_files_v1");
694
+ return captureCompletionBatch(input, false, "completion_yaml_files_v2");
692
695
  }
693
696
  /** Kernel-only opt-in; ordinary Pi capture stays fenced until session/lifecycle integration is admitted. */
694
697
  export function captureRunCompletionStreamBatch(input) {
@@ -696,7 +699,7 @@ export function captureRunCompletionStreamBatch(input) {
696
699
  }
697
700
  /** Private ordinary candidate composition; stream capture retains its separately gated codec. */
698
701
  export function captureRunCompletionYamlCandidateBatch(input) {
699
- return captureCompletionBatch(input, false, "completion_yaml_files_v1");
702
+ return captureCompletionBatch(input, false, "completion_yaml_files_v2");
700
703
  }
701
704
  function captureCompletionBatch(input, numbered, layout = "frontmatter_v2") {
702
705
  const now = (input.now ?? new Date()).toISOString();
@@ -1697,13 +1700,14 @@ function completionRootedFiles(row, member, locations) {
1697
1700
  }
1698
1701
  function prepareCompletionYamlProjection(safe, candidates, references, ordered) {
1699
1702
  const packet = { batchId: safe.batch_id, records: [] };
1700
- const rooted = safe.result_layout === "completion_yaml_files_v1";
1703
+ const rooted = isRootedCompletionLayout(safe.result_layout);
1704
+ const localSingleton = safe.result_layout === "completion_yaml_files_v2" && !safe.numbering && candidates.length === 1;
1701
1705
  if (!safe.batch_id.isWellFormed())
1702
1706
  return { state: "unsupported" };
1703
1707
  for (const [index, { row, location }] of candidates.entries()) {
1704
1708
  const member = ordered[index];
1705
1709
  const displayed = safe.numbering ? safe.numbering.kind === "stream" ? safe.numbering.first_index + index : "?" : index;
1706
- const metadata = { index: displayed };
1710
+ const metadata = localSingleton ? {} : { index: displayed };
1707
1711
  for (const piece of row.pieces) {
1708
1712
  if (piece.block)
1709
1713
  continue;
@@ -1763,7 +1767,9 @@ function prepareCompletionYamlProjection(safe, candidates, references, ordered)
1763
1767
  }
1764
1768
  packet.records.push({ metadata, parts });
1765
1769
  }
1766
- const service = rooted ? { header_layout: "rooted_files_v1" } : {};
1770
+ const service = rooted ? {
1771
+ header_layout: safe.result_layout === "completion_yaml_files_v2" ? "rooted_files_v2" : "rooted_files_v1",
1772
+ } : {};
1767
1773
  const omitted = safe.members.length - candidates.length;
1768
1774
  if (omitted) {
1769
1775
  service.omitted_results = omitted;
@@ -2302,7 +2308,7 @@ export function readRunCompletionPresentation(content, value) {
2302
2308
  hint.content_sha256 !== createHash("sha256").update(content).digest("hex"))
2303
2309
  return full;
2304
2310
  const segments = [];
2305
- const rooted = core.packet.service?.header_layout === "rooted_files_v1";
2311
+ const rooted = core.packet.service?.header_layout === "rooted_files_v1" || core.packet.service?.header_layout === "rooted_files_v2";
2306
2312
  const facts = Object.fromEntries(Object.entries(core.packet.service ?? {}).filter(([key]) => key !== "header_layout"));
2307
2313
  for (const [index, record] of core.packet.records.entries()) {
2308
2314
  if (index)
@@ -2551,6 +2557,8 @@ export function encodeCompletionYamlCarrier(input) {
2551
2557
  (Object.hasOwn(packet, "service") && (!completionYamlMapping(packet.service) || !Object.keys(packet.service).length)) ||
2552
2558
  (!packet.records.length && !Object.hasOwn(packet, "service")))
2553
2559
  return unavailable;
2560
+ const localSingleton = packet.records.length === 1 && completionYamlMapping(packet.service) &&
2561
+ packet.service.header_layout === "rooted_files_v2" && !Object.hasOwn(packet.service, "numbering");
2554
2562
  const rows = [];
2555
2563
  for (let index = 0; index < Math.max(1, packet.records.length); index++) {
2556
2564
  const row = packet.records[index];
@@ -2568,14 +2576,16 @@ export function encodeCompletionYamlCarrier(input) {
2568
2576
  !completionYamlMapping(row.metadata) || !Array.isArray(row.parts))
2569
2577
  return unavailable;
2570
2578
  const meta = row.metadata;
2571
- if (!(meta.index === "?" || (typeof meta.index === "number" && Number.isSafeInteger(meta.index) && meta.index >= 0)) ||
2579
+ const validIndex = localSingleton ? !Object.hasOwn(meta, "index")
2580
+ : meta.index === "?" || (typeof meta.index === "number" && Number.isSafeInteger(meta.index) && meta.index >= 0);
2581
+ if (!validIndex ||
2572
2582
  typeof meta.run !== "string" || !meta.run.length || typeof meta.state !== "string" || !meta.state.length ||
2573
2583
  (Object.hasOwn(meta, "kind") && meta.kind !== "primary" && meta.kind !== "diagnostic") ||
2574
2584
  Object.hasOwn(meta, completionYamlServiceKey) ||
2575
2585
  // JS enumerates array-index keys before semantic core fields; do not silently reorder the header.
2576
2586
  Object.keys(meta).some(key => /^(0|[1-9]\d*)$/u.test(key) && Number(key) < 4294967295))
2577
2587
  return unavailable;
2578
- for (const key of ["index", "run", "state", ...(Object.hasOwn(meta, "kind") ? ["kind"] : []),
2588
+ for (const key of [...(localSingleton ? [] : ["index"]), "run", "state", ...(Object.hasOwn(meta, "kind") ? ["kind"] : []),
2579
2589
  ...Object.keys(meta).filter(key => !["index", "run", "state", "kind"].includes(key))]) {
2580
2590
  Object.defineProperty(header, key, { value: meta[key], enumerable: true });
2581
2591
  }
@@ -529,16 +529,20 @@ export function compactYamlDocument(value) {
529
529
  const text = growYamlDocument(() => value, [], Limits.RUN_DELIVERY_MODEL_MAX_BYTES);
530
530
  return `\n${text.replace(/\n$/u, "")}`;
531
531
  }
532
+ function recipeInspectionHint(action) {
533
+ if (action === "inspect target=recipes view=doctor")
534
+ return { view: "doctor" };
535
+ if (action === "inspect target=recipes view=imports verbose=true")
536
+ return { view: "imports", verbose: true };
537
+ if (action === "inspect target=recipes view=summary verbose=true")
538
+ return { view: "summary", verbose: true };
539
+ return undefined;
540
+ }
532
541
  /** Only the closed read-only Recipe inspect literals become typed next; other advice stays opaque content. */
533
542
  export function nextActionMetadata(action, byteBudget) {
534
- const recognized = [
535
- ["inspect target=recipes view=doctor", "doctor", false],
536
- ["inspect target=recipes view=imports verbose=true", "imports", true],
537
- ["inspect target=recipes view=summary verbose=true", "summary", true],
538
- ];
539
- const match = recognized.find(([literal]) => literal === action);
540
- if (match) {
541
- const typed = { next: { tool: "inspect", target: "recipes", view: match[1], ...(match[2] ? { verbose: true } : {}) } };
543
+ const hint = recipeInspectionHint(action);
544
+ if (hint) {
545
+ const typed = { next: { tool: "inspect", target: "recipes", ...hint } };
542
546
  return { full: typed, selected: typed };
543
547
  }
544
548
  const instruction = selectYamlField("instruction", action, byteBudget);
@@ -546,13 +550,8 @@ export function nextActionMetadata(action, byteBudget) {
546
550
  }
547
551
  /** Only these existing read-only inspection hints become action nodes; other advice stays content. */
548
552
  export function formatInspectionHint(action) {
549
- if (action === "inspect target=recipes view=doctor")
550
- return formatInspectNextAction("recipes", "doctor");
551
- if (action === "inspect target=recipes view=imports verbose=true")
552
- return formatInspectNextAction("recipes", "imports", true);
553
- if (action === "inspect target=recipes view=summary verbose=true")
554
- return formatInspectNextAction("recipes", "summary", true);
555
- return formatMarkdownField("instruction", action);
553
+ const hint = recipeInspectionHint(action);
554
+ return hint ? formatInspectNextAction("recipes", hint.view, hint.verbose) : formatMarkdownField("instruction", action);
556
555
  }
557
556
  export function compactRecipeRegistry(summary) {
558
557
  const count = (key, source) => Array.isArray(source) ? source.length : 0;
@@ -73,7 +73,7 @@ Rollout is partial: compact launch/attachment receipts use block YAML; other ope
73
73
 
74
74
  Compact launches use bare block-YAML mappings for the Run/state/launch facts and nested observed locations, explicitly identify actual existing-Run reuse, and preserve multiline scalar contents. One leading response-separator LF supplies invocation spacing; it is outside the pure metadata emitter and is not a `---` wrapper. Model/thinking provenance groups are labeled model and thinking, without a redundant _policy suffix; structured data and saved text stay unchanged. A complete direct file-location row needs no repeated session-map hint; absent/unavailable/omitted rows retain one optional next node naming inspect, target=runtime, view=runs and verbose=true. It never executes automatically. Exact locations, verbose details and saved completion formats stay unchanged.
75
75
 
76
- Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins index, run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. One record uses the same shape as many. Display index is not member_index or generation; default indices are packet-local. Whole-result/reference omissions and non-done omitted states stay explicit. Known display loss appears at the actual cut as [N characters omitted], counting Unicode scalar characters of admitted retained text/field, never raw/private loss; no extra clipping ellipsis or body clipping flags/counts in YAML. Unknown upstream completeness/privacy remains separately visible at the body boundary, not a fabricated count or a known positive loss. Untracked fallback has no kind and cannot become primary. Full text fitting its share has no display-cut marker; upstream uncertainty still prevents a completeness claim. New packets share48KiB UTF-8 including references/framing across at most64candidate rows, with frozen equal shares and no unused-share redistribution or fixed16KiB result/2KiB preview cap. Captured members remain bounded at256. Text is admitted work output/final response or explicit error/failure diagnostics, never launch commands. Successful composition/retry/Pi text-print can retain text_basis:actor_response; scope and exact references remain technical, while original coverage facts remain structured retained data. The model receives one complete content with whole source/generation/location references or truthful omission/inventory, not a standing full-map instruction. The TUI renders compiler headers/markers as Text and each body as independent native Markdown; only whole validated header reference/location rows and framing disappear in compact view. Body-authored YAML, next/tool/batch and omission lookalikes remain content. Content-bound hashes/ranges/blocks are display consistency, not authentication, source/read/action or acceptance authority. Invalid/missing hints and expansion reveal full original text, without Run-source IO. Old saved codecs, budgets, labels, excerpts, counts and hints replay exactly with no refresh, repair, ACK/resend or restyling—including earlier #N packets and the first frontmatter encoding. Fresh unavailable indices use quoted YAML "?"; an old saved unquoted value is not silently corrected. Routine successful delivery adds no separate completions/delivery-accepted toast; actual failures and handled-generation fences remain. These source/package rules do not prove that an already loaded session was reloaded. Fresh explicit agent Trace previews append boundary … and [omitted: N chars] from normalized retained turn, with a separate upstream [omitted: unknown]. N counts only display loss after existing session privacy, not discarded original/source text. Short well-formed summaries stay unchanged, including authored older-looking markers; malformed retained text yields Agent turn [omitted: unknown] (malformed retained text), never a guessed count or repaired scalar. This is read-time display only, not a rewrite/version of saved packets or sources. Other legacy clipping is not yet uniformly covered. Follow retained references selectively without inventing completeness or permission. Agent Trace ids reference recorded entry provenance, not aggregate traversal order or chronological event numbers. Native entry keys survive sibling growth; bounded legacy/ambiguous/private-metadata fallbacks are not permanent identities, source immutability or new read/work permission.
76
+ Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. Prepend index only when two or more results are shown; exactly one shown result omits it even if other results were omitted. Omission/inventory facts remain explicit. Display index is not member_index or generation; default indices are packet-local. This new-capture rule neither restyles saved messages nor changes numbered-stream presentation. Whole-result/reference omissions and non-done omitted states stay explicit. Known display loss appears at the actual cut as [N characters omitted], counting Unicode scalar characters of admitted retained text/field, never raw/private loss; no extra clipping ellipsis or body clipping flags/counts in YAML. Unknown upstream completeness/privacy remains separately visible at the body boundary, not a fabricated count or a known positive loss. Untracked fallback has no kind and cannot become primary. Full text fitting its share has no display-cut marker; upstream uncertainty still prevents a completeness claim. New packets share48KiB UTF-8 including references/framing across at most64candidate rows, with frozen equal shares and no unused-share redistribution or fixed16KiB result/2KiB preview cap. Captured members remain bounded at256. Text is admitted work output/final response or explicit error/failure diagnostics, never launch commands. Successful composition/retry/Pi text-print can retain text_basis:actor_response; scope and exact references remain technical, while original coverage facts remain structured retained data. The model receives one complete content with whole source/generation/location references or truthful omission/inventory, not a standing full-map instruction. The TUI renders compiler headers/markers as Text and each body as independent native Markdown; only whole validated header reference/location rows and framing disappear in compact view. Body-authored YAML, next/tool/batch and omission lookalikes remain content. Content-bound hashes/ranges/blocks are display consistency, not authentication, source/read/action or acceptance authority. Invalid/missing hints and expansion reveal full original text, without Run-source IO. Old saved codecs, budgets, labels, excerpts, counts and hints replay exactly with no refresh, repair, ACK/resend or restyling—including earlier #N packets and the first frontmatter encoding. Fresh unavailable indices use quoted YAML "?"; an old saved unquoted value is not silently corrected. Routine successful delivery adds no separate completions/delivery-accepted toast; actual failures and handled-generation fences remain. These source/package rules do not prove that an already loaded session was reloaded. Fresh explicit agent Trace previews append boundary … and [omitted: N chars] from normalized retained turn, with a separate upstream [omitted: unknown]. N counts only display loss after existing session privacy, not discarded original/source text. Short well-formed summaries stay unchanged, including authored older-looking markers; malformed retained text yields Agent turn [omitted: unknown] (malformed retained text), never a guessed count or repaired scalar. This is read-time display only, not a rewrite/version of saved packets or sources. Other legacy clipping is not yet uniformly covered. Follow retained references selectively without inventing completeness or permission. Agent Trace ids reference recorded entry provenance, not aggregate traversal order or chronological event numbers. Native entry keys survive sibling growth; bounded legacy/ambiguous/private-metadata fallbacks are not permanent identities, source immutability or new read/work permission.
77
77
 
78
78
  Current completion index fields are packet-local, not persistent historical indices; earlier saved #N headings keep their original meaning. Session completion streams are adopted work in progress, not an available action; do not invent a start-stream command, initialize a missing counter or reinterpret old headings. A kernel-only path commits numbered snapshots/counters/activation atomically. Its internal runtime bridge requires trusted fresh-session opt-in plus current manager/generation binding; the default entrypoint does not opt in and no public tool/command exposes it. Unknown state does not fall back to local numbering on that path. Startup/reload/resume, including ambiguous imports, cannot resume a stream automatically; stored numbers remain data, not a new session grant. A pending target or projected scope is not an active stream. Missing state never authorizes bootstrap, and unknown/conflicting delivery never authorizes bypass or reallocation. Saved numbers stay exact; an admitted unavailable counter or unfitting whole range freezes an unknown index (quoted "?" in fresh YAML, #? in older layouts) rather than resetting or partially numbering a packet.
79
79
 
@@ -24,7 +24,7 @@ inspect target=run:<id> view=trace
24
24
  inspect target=run:<id> view=control
25
25
  ```
26
26
 
27
- Fresh root completions use index-first YAML frontmatter (index, run, state, admitted kind), followed by raw left-edge Markdown. New source captures put all runtime metadata above that body, with no service/file footer. files.groups gives one literal root plus relative entry paths; files.read_first names zero-based group/entry indices for the first useful source, not an automatic read. role/purpose guidance is English; Actor Markdown and path/name bytes are unchanged. External paths use separate roots; unknown bases remain explicit rather than guessed from cwd or Run id. Known cut counts alone may follow the cut body; unknown-loss warnings and packet omission/inventory facts stay in the header. Retained captures preserve their old bytes and presentation. No external #N heading, result:/preview: wrapper, list nesting, whole-body fence, Batch caption, members wrapper or routine outer counter is added. Primary/final Actor response uses kind:primary; explicit error/failure diagnostic text uses kind:diagnostic, never a launch command. Untracked fallback has no kind and keeps unknown original completeness/privacy explicit outside YAML. Known cut loss is [N characters omitted] at the cut, with no extra ellipsis or body clipping counters/flags in metadata. Unknown upstream loss remains separately unknown and does not assert a known positive omission. Exact source/generation/parent/location references remain in complete model content, with whole references or explicit omission, captured inventory recovery and non-done omitted states. The compact TUI independently renders literal headers/markers and native Markdown bodies from validated content-bound blocks; only whole header reference/location rows and framing are hidden. Expansion and invalid/missing hints reveal original text. Hashes/layout/markers establish consistency/correlation only, never authentication, read/action permission, acceptance or native truth. Authored YAML/next/tool/batch/omission lookalikes stay body content. Fresh packets share48KiB UTF-8 including service data, equally between up to64candidate rows, with256captured members and no redistribution of unused shares or fixed16KiB/2KiB text cap. Full admitted text fitting its share without upstream uncertainty has no cut marker; otherwise use the scalar/CRLF-safe prefix and exact retained-source loss. Allocation/text is frozen at admission; rendering/recovery does not reread sources or reallocate. Unsupported Pi event/control output is withheld. Source basis stays in reference metadata; retained structured coverage facts are not exposed as YAML clipping fields. Pending/queued/presented older formats—including #N records and the first frontmatter draft—keep exact bytes, hints and budgets. Encoding names are storage replay data, not public product choices, source permissions or work authority. No standing full-map instruction or automatic research/read follows; use selective same-session investigation when needed.
27
+ Fresh root completions use YAML frontmatter (run, state, admitted kind), followed by raw left-edge Markdown. Prepend the packet-local index only when two or more results are shown. Exactly one shown result omits its index even with omitted results; preserve omission/inventory metadata, internal member/generation/correlation and every saved message. This rule does not apply to numbered streams. New source captures put all runtime metadata above that body, with no service/file footer. files.groups gives one literal root plus relative entry paths; files.read_first names zero-based group/entry indices for the first useful source, not an automatic read. role/purpose guidance is English; Actor Markdown and path/name bytes are unchanged. External paths use separate roots; unknown bases remain explicit rather than guessed from cwd or Run id. Known cut counts alone may follow the cut body; unknown-loss warnings and packet omission/inventory facts stay in the header. Retained captures preserve their old bytes and presentation. No external #N heading, result:/preview: wrapper, list nesting, whole-body fence, Batch caption, members wrapper or routine outer counter is added. Primary/final Actor response uses kind:primary; explicit error/failure diagnostic text uses kind:diagnostic, never a launch command. Untracked fallback has no kind and keeps unknown original completeness/privacy explicit outside YAML. Known cut loss is [N characters omitted] at the cut, with no extra ellipsis or body clipping counters/flags in metadata. Unknown upstream loss remains separately unknown and does not assert a known positive omission. Exact source/generation/parent/location references remain in complete model content, with whole references or explicit omission, captured inventory recovery and non-done omitted states. The compact TUI independently renders literal headers/markers and native Markdown bodies from validated content-bound blocks; only whole header reference/location rows and framing are hidden. Expansion and invalid/missing hints reveal original text. Hashes/layout/markers establish consistency/correlation only, never authentication, read/action permission, acceptance or native truth. Authored YAML/next/tool/batch/omission lookalikes stay body content. Fresh packets share48KiB UTF-8 including service data, equally between up to64candidate rows, with256captured members and no redistribution of unused shares or fixed16KiB/2KiB text cap. Full admitted text fitting its share without upstream uncertainty has no cut marker; otherwise use the scalar/CRLF-safe prefix and exact retained-source loss. Allocation/text is frozen at admission; rendering/recovery does not reread sources or reallocate. Unsupported Pi event/control output is withheld. Source basis stays in reference metadata; retained structured coverage facts are not exposed as YAML clipping fields. Pending/queued/presented older formats—including #N records and the first frontmatter draft—keep exact bytes, hints and budgets. Encoding names are storage replay data, not public product choices, source permissions or work authority. No standing full-map instruction or automatic research/read follows; use selective same-session investigation when needed.
28
28
 
29
29
  Current completion index values restart within each packet; they are not session-wide historical references. Completion streams are adopted but not enabled, and no start-stream command is available yet. Do not infer an active stream or reset a counter from missing metadata or a pending target, and never relabel older saved packets. The kernel-only allocator now commits fixed scope/order/indices, the counter and first-packet target activation together, and an internal fresh-session bridge can use it after current manager/generation admission. The default runtime does not opt in; no public action exposes it. Event reason or a matching ID alone is insufficient. Old callbacks/wrappers cannot act after replacement; fresh wrappers must belong to the current original manager. Startup/reload/resume and ambiguous imports remain closed to stream capture/ACK, without changing saved packets or inferring a counter from history. Its whole-range exhaustion or admitted counter unavailability yields a frozen unknown index (quoted "?" in fresh YAML; #? in older saved layouts), never partial indices or an automatic fresh stream. Old packets retain their original scope while a pending switch waits; uncertainty does not permit reallocation. Stream state outlives packet cleanup/receipt rotation. Malformed/missing state remains refused, not a zero counter or proof of non-connection.
30
30
 
@@ -4,9 +4,9 @@ Status: Adopted project-wide design standard. The operator has selected **JSON i
4
4
 
5
5
  ## One first AX contract
6
6
 
7
- AX is one canonical Agent Experience being prepared for its first release, not a product family of numbered drafts or user/model-selectable formats. The selected target is YAML metadata plus optional opaque authored content; the former Markdown-list key/value grammar is an implemented pre-unification layout, not another target to preserve for new output. Ordinary source and normally built package Batch admission now capture ax_records/completion_yaml_files_v1 over the unchanged completion_yaml_core_v1 carrier, and fresh attention/steer use typed block-YAML metadata plus opaque raw body text. The inactive numbered-stream path and saved frontmatter_v1/v2 retain their older layouts. Bounded source/compiled/actual-default accepted-path evidence exists; it does not establish default-disk, global lifetime-policy or loaded-host acceptance. Remaining rollout is tracked in [BACKLOG.md](../BACKLOG.md).
7
+ AX is one canonical Agent Experience being prepared for its first release, not a product family of numbered drafts or user/model-selectable formats. The selected target is YAML metadata plus optional opaque authored content; the former Markdown-list key/value grammar is an implemented pre-unification layout, not another target to preserve for new output. Ordinary source and normally built package Batch admission now capture ax_records/completion_yaml_files_v2 over the unchanged completion_yaml_core_v1 carrier, and fresh attention/steer use typed block-YAML metadata plus opaque raw body text. The inactive numbered-stream path and saved frontmatter_v1/v2 retain their older layouts. Bounded source/compiled/actual-default accepted-path evidence exists; it does not establish default-disk, global lifetime-policy or loaded-host acceptance. Remaining rollout is tracked in [BACKLOG.md](../BACKLOG.md).
8
8
 
9
- A completion group is the result sequence itself, not a container with members. Each result's YAML metadata begins index, run, state, then kind:primary for admitted primary text/final Actor response or kind:diagnostic for explicit diagnostics. The admitted Markdown follows from the left margin, outside metadata, with no #N heading, result:/preview: wrapper or whole-body literal fence. One blank separator distinguishes records. Known display loss appears only at the cut as [N characters omitted], counting Unicode scalar characters of the admitted retained source; no extra truncation ellipsis or body clipping flags/counters appear in YAML. New rooted captures keep unknown upstream completeness/privacy in header text_warnings without inventing a count or claiming a known positive loss. Retained captures preserve their original body-boundary warnings. Untracked fallback has no primary kind. Missing text stays explicit; a checkpoint retains its Actor-authored notification body. Successful automatic delivery has no extra receipt, routine outer counters, members wrapper, Batch caption, time window, status-summary copies or standing full-map instruction; real failures stay reportable. Exact source/generation/location references remain in complete model content, with whole-reference/result omission and non-done omitted states explicit. A group with one visible row stays a group. Fresh ordinary packets put minimal packet identity and relative body/marker lengths in YAML metadata, without compiler HTML tails. Older saved layouts retain their original compiler boundary/correlation framing; neither encoding grants authenticity, read permission or acceptance. Their compatibility boundary is governed separately below; never strip required historical framing. This is one new-capture contract, not a selectable AX product version.
9
+ A completion group is the result sequence itself, not a container with members. Each result's YAML metadata begins run, state, then kind:primary for admitted primary text/final Actor response or kind:diagnostic for explicit diagnostics. The admitted Markdown follows from the left margin, outside metadata, with no #N heading, result:/preview: wrapper or whole-body literal fence. One blank separator distinguishes records. Known display loss appears only at the cut as [N characters omitted], counting Unicode scalar characters of the admitted retained source; no extra truncation ellipsis or body clipping flags/counters appear in YAML. New rooted captures keep unknown upstream completeness/privacy in header text_warnings without inventing a count or claiming a known positive loss. Retained captures preserve their original body-boundary warnings. Untracked fallback has no primary kind. Missing text stays explicit; a checkpoint retains its Actor-authored notification body. Successful automatic delivery has no extra receipt, routine outer counters, members wrapper, Batch caption, time window, status-summary copies or standing full-map instruction; real failures stay reportable. Exact source/generation/location references remain in complete model content, with whole-reference/result omission and non-done omitted states explicit. Prepend the packet-local index only when two or more results are shown. Exactly one visible row omits its display index even with omitted results; omission/inventory facts and internal member/generation/correlation stay unchanged. This rule does not apply to numbered streams. Fresh ordinary packets put minimal packet identity and relative body/marker lengths in YAML metadata, without compiler HTML tails. Older saved layouts retain their original compiler boundary/correlation framing; neither encoding grants authenticity, read permission or acceptance. Their compatibility boundary is governed separately below; never strip required historical framing. This is one new-capture contract, not a selectable AX product version.
10
10
 
11
11
  Illustrative compact completion shape (not actual Run data):
12
12
 
@@ -31,13 +31,13 @@ Module was not found.
31
31
  [120 characters omitted]
32
32
  ```
33
33
 
34
- An only item uses the same first block, not a second format. Full text has no cut marker; an unavailable index is the YAML string "?", never a fabricated zero. The compact TUI renders compiler headers and markers as literal Text and each body as independent native Markdown, so an unfinished fence/list/quote cannot consume another block. New rooted headers keep navigation visible and put packet omission/inventory facts in the first header, never after the Markdown. Retained core-v1 compact views keep their original whole-reference/location hiding. Expansion or invalid/missing hints reveals the full original text. Source bodies and retained structured coverage facts are not rewritten.
34
+ An only shown item uses the same block without its packet-local index, not a second public format. Full text has no cut marker; an unavailable index is the YAML string "?", never a fabricated zero. The compact TUI renders compiler headers and markers as literal Text and each body as independent native Markdown, so an unfinished fence/list/quote cannot consume another block. New rooted headers keep navigation visible and put packet omission/inventory facts in the first header, never after the Markdown. Retained core-v1 compact views keep their original whole-reference/location hiding. Expansion or invalid/missing hints reveals the full original text. Source bodies and retained structured coverage facts are not rewritten.
35
35
 
36
36
  Storage compatibility is separate: already-captured Batch snapshots need their original codec to reproduce exact delivery text, while steer envelopes replay their saved content directly. Do not relabel, migrate or reformat existing journals/session messages to make the interface look uniform. Retained encoding identifiers are internal replay data, not alternate AX products. See [retained capture compatibility](coordinator-delivery.md#retained-capture-compatibility).
37
37
 
38
38
  ## Rooted completion files
39
39
 
40
- New source captures use a private `completion_yaml_files_v1` snapshot layout; this is replay data, not an input selector or a new product format. The YAML carrier/hint stays `completion_yaml_core_v1`. Existing snapshots keep their exact previous projection.
40
+ New source captures use a private `completion_yaml_files_v2` snapshot layout and `rooted_files_v2` service discriminator for the singleton display rule; this is replay data, not an input selector or a new product format. The YAML carrier/hint stays `completion_yaml_core_v1`. Existing snapshots, including `completion_yaml_files_v1`/`rooted_files_v1`, keep their exact previous projection and singleton indices.
41
41
 
42
42
  All runtime metadata belongs above the selected Markdown. New compact views have no service footer, appended file list or runtime warning after the body. A known cut alone adds `[N characters omitted]` at that cut; unknown loss/privacy and whole-reference omissions belong in header fields. Authored Markdown, filenames and paths keep their original language/bytes; compiler keys and purpose explanations are English.
43
43
 
@@ -49,7 +49,6 @@ Illustrative abbreviated header, not actual Run data or a complete source bindin
49
49
 
50
50
  ```text
51
51
  ---
52
- index: 0
53
52
  run: "review"
54
53
  state: "done"
55
54
  kind: "primary"
@@ -239,7 +238,7 @@ The [runtime output projection map](output-projection-map.md) names the audited
239
238
 
240
239
  The prepared `tools-response.ts` `renderYamlMetadata` foundation uses the directly declared `yaml@2.9.0` public API for selected own-data mappings/sequences. It emits bare YAML without invocation spacing or body processing, preserves scalar types/strings and refuses unsupported or over-budget whole values. Its execution ceiling is 49,152 bytes and supported nesting is at most 64 levels; these are not caller allowances or drop-in compatibility for larger existing budgets. Preflight bounds scalar/node traversal, not atomic key enumeration or arbitrary Proxy execution. Focused parser/property and shared response-owner tests cover this foundation; compact asynchronous launch receipts are the first production caller. Other surfaces and loaded-host acceptance remain separately staged; full spawn-verbose shares the final YAML style without inheriting this bounded emitter's limits.
241
240
 
242
- The following is the current pre-unification implementation inventory, not a set of alternate adopted output styles. Existing flat records, literal JSON fields, verbose JSON and retained-layout HTML compiler frames remain code facts until their owned rollout changes; the target above does not restyle or relabel stored text. This standard spans surfaces, not a new library domain. Control compact-result/public-error is now bare block-YAML metadata with native option sequences, whole selected values or explicit omission records under the existing16KiB cap, no duplicated run namespace, stage/reuse distinctions, typed selective inspect next nodes and opaque advice scalars; verbose JSON remains the machine path. Launch model/thinking groups use the concise `model` and `thinking` labels and preserve their actual source/value relationship; compact launch navigation now remains one whole native YAML value or explicit whole-row omission within16KiB including invocation-response spacing. Full spawn-verbose in source and normally built packages uses the legacy once-only JSON selection followed by clone-only YAML, without a new fixed byte/depth cap. Absent selected JSON, malformed selected text or recoverable post-selection failures withhold the whole projection with an attributable no-auto-repeat warning; original selection throws and structured details remain unchanged. Source/unit and installed compiled response checks, the strict ordinary-metadata source/packed completion journey, and all three source/packed navigation owners are accepted within their bounded domains. Native assertions remain indirect proof, not current global absence. Owning Skill byte parity does not establish a loaded-host change. The older field/inspect-action primitives remain with their unmigrated consumers; compact launch serialization now uses the YAML metadata primitive. Structured/verbose results, exact dispatch/private error causes and old completion handoff text retain their contracts. Fresh ordinary source completion admission captures canonical AX with the private completion_yaml_core_v1 layout: index-first YAML, independently rendered raw Markdown and cut-local [N characters omitted]. The minimal ordinary hint binds whole content to the YAML core, whose relative lengths derive header/body/marker boundaries without fresh HTML tails. Retained completion_frontmatter_v1 hints keep their complete ranges and original compiler frames; neither hint name is a public selector. Only valid compiler headers can hide whole reference/location rows. Markers remain literal and body-authored labels never become metadata/actions. Expansion and invalid/missing hints reveal full original text. These checks establish display consistency, not authentication, source/read scope or acceptance; display line-ending/tab handling never rewrites saved content. Routine state-equivalent summaries remain in the journal, not the new model content; meaningful summaries, loss/redaction/unavailability and reference coverage remain visible. Exact source/generation/parent bindings, whole references and fresh48KiB/64row limits include hidden technical data; retained codecs keep16KiB. The postprivacy byte budget is divided equally between candidate rows: roughly48KiB for one,24KiB each for two,16KiB each for three, less encoded service overhead. Whole admitted text uses result only when it fits without known upstream clipping; otherwise preview uses the safe prefix with exact retained-source omissions. There is no fixed16KiB result/2KiB preview cap and no render-time source IO or reallocation. Already-retained packets keep their exact captured bytes; pre-record messages keep the host renderer and retained record messages keep their original verified view. The Pi boundary recognizes the strict whole YAML core for ordinary source records, or original closed markers/anchored headers for retained captures, after private details are stripped, preserving exact owned-context acceptance without interpreting authored body labels. Actual actors guidance describes this implemented fresh-capture route; this is not a claim that a loaded host was reloaded. Fresh source urgent-steer captures use typed YAML metadata and a separate raw selected body before saving immutable envelope.content: complete final-message fitting and whole reference sequences retain16KiB/eight-slot bounds. Ordinary attention remains unbounded; bounded source/compiled/actual-default acceptance does not establish loaded-host acceptance. Existing envelopes are not reinterpreted, and no older new-message default remains. Fresh ordinary notify/followup uses one AX formatter in the existing sink: the same opaque checkpoint/body and whole first-eight reference projection, without borrowing steer's shared byte cap or changing routing. Committed history keeps its exact text; the retired presentation selector is not a compatibility API. Fresh read-time agent Trace preview leaves now also use boundary U+2026, exact admitted normalized-retained-turn omissions and separately unknown upstream loss, without changing the160UTF-16 source allowance, identifiers/chronology, detail/source data or public JSON schema. Malformed text is unknown, not repaired; no journal capture aspect is minted for a derived current read. New urgent admission/send/recovery diagnostics now also use event/attention/stage AX records, opaque raw240-unit previews and unknown loss while their persisted message-only evidence stays unchanged. A failed send leaves delivery/presentation unconfirmed, and unknown/conflicting queued recovery does not force replay. Fresh non-runtime explicit inspection also uses bare block-YAML metadata: unchanged Run/view headers, tool activation/argument sequences and Recipe registry/focused-doctor facts, whole selected source/identity/advice scalars or explicit whole-field omission, native counts/flags and one typed read-only hint or opaque `next.instruction`. The explicit `tool:* view=schema` text is generated definition metadata in the same bare YAML form with native parameter nodes when renderable; unsupported/over-ceiling schemas retain the exact legacy JSON fallback. Compact argument sequences are whole or explicitly omitted/unavailable. Verbose views bypass compact formatting and machine details keep their JSON contracts. Only the three existing closed read-only Recipe inspect literals become typed next; other advisory strings remain opaque instruction values with full next_actions retained in unchanged details/verbose JSON. Existing body/scope/budget/default-status contracts stay independent. Compact runtime status/runs/triage now also presents only its existing facts/counts as AX fields, with full owned inventory independent from bounded verbose navigation and bounded triage rows. Fresh locally owned runtime notices (callback failure, completion recovery/acceptance, steer admission/delivery/recovery diagnostics and the shutdown teardown report) are now bare block-YAML metadata with explicit receipt/report stages and native counters. UI-only notices keep complete well-formed selected fields without borrowing the model byte/depth ceilings; malformed selected text is explicitly unavailable. Existing steer preview bounds, source/errors, acceptance and native authority are unchanged. Producer-owned watcher/retirement notices now also use uncapped bare block-YAML metadata: whole selected literal paths and opaque diagnostics preserve raw signature/dedup/rearm behavior, while returned stop/reported cancellation/skip/failure remain non-closure reports with exact existing optional-notifier/error observation semantics. Inspector document/detail rendering now uses flat semantic fields, real sequence lists and opaque literal terminal values, with ephemeral compiler-label provenance instead of parsing authored colon/bullet lines as metadata. Separator-preserving native-column wrapping keeps whole text/references, source values, root stripes and existing identity/chronology/navigation/source bounds. Empty containers remain typed values; terminal line-ending/tab display policy does not rewrite source. Ten locally authored inspect refusals now render bare block-YAML metadata with true supported-value sequences, field-local whole-field coverage records and one typed read-only next, preserving their original guards and Error/dependency behavior. Only the two already-guided tool failures retain typed read-only next actions. New local error text shares16KiB including public spacing; variable fields/actions are whole or explicitly counted omitted without shortening targets, reading raw private lengths or wrapping unowned exceptions. Session/source/dependency errors keep their separate owners and old catches rather than being globally restyled. Inspector Kill confirmation now also uses captured run/state/action AX fields with whole-value paging, while both choices and closure: unconfirmed remain pinned at narrow/low viewports. Read-only PgUp/PgDn preserves original Cancel/choice/confirmation/generation behavior and adds no actuation or source permission. Inspector Kill cancellation only closes the dialog; successful actions use the selected Run's visible status without a second Notice. Failures/refusals/uncertainty remain visible, and notifications on other surfaces are not suppressed. Remaining Inspector feedback shows the complete selected opaque message directly in a modal popup over unchanged data rows, without i prefix/command or another reader. Esc dismisses; only physical overflow scrolls within that same popup. Kill uses the same centered rectangle compositor. Both use terminal-default backgrounds rather than a theme fill, two-column left content insets and top/bottom blank spacing, plus the Inspector's shared frame/key/description color grammar. On space-constrained heights, safety/choices/readable text take priority over decorative blanks. They keep the captured underlay stable through resize/invalidation and resume ordinary refresh on close, without fresh evidence/native authority. Action-port feedback pins closure uncertainty/no automatic retry without inferring native effects from message text. Fresh Kill producers now use a shared pure selected-value AX formatter: domain180-unit normalization/trim and overlay160-unit normalization/slice remain, while a cut pair retracts one unit and malformed selected text is unknown/unavailable. Dynamic legacy values state upstream completeness/privacy unproven, with unknown local clipping markers rather than private-tail counts; compiler refusals add no fake loss. ok/callback/getter/coercion/error semantics and old success suppression stay unchanged, and the popup's anchored header recognition affects color only. This does not recover discarded Markdown/causes or create a saved capture version. Trace table rows now mark actual column/line gaps with native ellipsis while preserving full selected item/detail, and compact warning captions keep incomplete-history/non-lifetime/unavailable-rank meaning visible at narrow widths. This is UI preview loss only, not new source/private character counts, rank/identity changes or a generic selector/fit rewrite. Four locally authored Control pre-dispatch guards now also use caller target/action/result and actual supported/available-action sequences: whole target/list groups fit16KiB including public spacing or carry field/entry omission counts, while malformed selected text is unavailable without repair. Original guard/getter/join/coercion observations, plain Error/host-error behavior and all unowned/dispatch exceptions stay separate; no input/status/correlation/retry/no-effects or new dispatch authority follows. Synchronous registered-command failures now present compiler-owned exit_code/killed metadata as bare block YAML, followed by a delimited header before the unchanged selected stderr/stdout bodies (or metadata-only when no stream text was selected); trim/tail selection, truncation notices, temp-file publication and exact executor failures are unchanged. The pre-dispatch argument-repair error now likewise puts owned tool/required/optional facts in a closed YAML header and keeps the original validation prose plus the verbatim JSON invocation example as unparsed body text, and local spawn pre-launch guards use bare block YAML with one whole selected value or an explicit omission record. Three local spawn pre-launch guards present field/result and a whole or explicitly omitted selected caller value as bare block YAML rather than inventing an admitted Run: unsupported state_dir, missing run: namespace and invalid id. Whole valid-scalar values fit16KiB or are omitted; malformed selections are unavailable, without repair or source/private-tail counts. Original input/method/coercion/launch behavior stays separate. The real host still rejects unsupported state_dir through its own unchanged schema before the facade, so this does not claim all SDK validation errors are AX. Namespace/id guard errors retain real host isError behavior. Successful normal registration/update-or-persisted receipts now use original tool/outcome/source/callable facts, actual required/optional argument and warning lists, a whole fenced non-template source and one prior hint. Invocation advice stays opaque instruction; only the producer-known unverified tool-status hint is typed next. Complete safety warnings have first budget priority; all variable fields/groups/actions fit16KiB including public spacing or show whole selected-field/entry omission, with malformed selections unavailable without repair. Original post-effect warning/argument/coercion/boundary observations and all transaction/details/notify/error behavior remain. This is not new callability, host activation, rollback or invocation authority. Registry current-name listing and deletion returns now also use AX: original sorted/captured names are a whole selected group with shown/omitted/total coverage, never a new page/work quota or active/callable/global registry claim. Overlarge groups are wholly omitted and malformed groups unavailable without raw-key re-coercion or repair. Deletion keeps original selected tool/result and the exact operator reload note as opaque instruction; current-map not found stays a returned result, not a new error or orphan-file cleanup. Lookup/file/deactivation/notify/errors/details remain unchanged, including post-effect failures. Draft promotion success now also uses only its prior selected name/new-update/source=draft/exact callable display/first hint as AX. It does not inherit ordinary-registration args/warnings/boundary facts or change its admission/rollback policy. Original template String conversions remain after notify, including zero/object/Symbol behavior and post-effect failures. Whole scalars/actions fit16KiB or are explicitly omitted/unavailable; only the closed producer-known read-only status hint is typed, and invocation advice is opaque. Machine details/bytes and later activation observations remain unchanged. Locally authored registry mode/name/source/template/draft/transaction refusals now render as bare block-YAML metadata documents with compiler-literal fields, native choice sequences, and each opaque selected value whole or explicitly omitted under the unchanged16KiB cap; authored text stays scalar content with escaped line breaks rather than becoming keys or actions. Registry activation/promotion/deletion notice text remains flat report/tool fields, outside this refusal migration. No supplied source values, new helper/wrapper or changed guard/descriptor/getter/trim order. The host still owns cloning, coercion and schema validation: rejected extra/object fields need not reach these AX guards, while numeric input may normalize and preserve a non-error unnamed list result. This is not new schema, no-effects or automatic retry authority. Three ordinary name/source refusals now also use AX: invalid normalized name without raw caller echo, reserved selected-name value whole or explicitly omitted/unavailable, and missing source only for a new registration with actual source choices/opaque prior advice. Original normalization/reserved-set/resolution/lookup/blocker/fault order stays unchanged; empty-name listing, existing-tool update with retained source and dependency blocker text are not reinterpreted. SDK clone/coercion/schema remains separate. Ordinary and draft duplicate-registration refusals now show their original selected name whole/omitted/unavailable plus the original update advice as opaque instruction; distinct authoritative-file/Map/exists/blocker/update predicates and original single display coercion stay unchanged. No overwrite/retry, body-read or no-effects authority follows. Template-shape helper errors now also use fixed template/result records for nested Recipe objects, empty sequences and unsupported types, with actual supported-kind lists/opaque old correction and no supplied value echo. Getter/Array/reference/key/expand semantics and external errors stay exact; null/undefined/deletion/retained-source behavior and SDK coercion remain separate. Authored-Recipe non-object defaults, missing command description, null-at-authoring and missing-final-template constants now also use fixed field/result, without new value echoes or changes to args/from/description/default/retained-source order. Front deletion, inheritance and Schema/dependency errors keep separate ownership. The delegated runtime-owned-default-key refusal now shows only its original first selected key, defaults/result and opaque old correction. Full copy/find order, eight-name membership and the delegated-only condition remain; no all-key/value disclosure, early rejection optimization or new retry authority. Two draft-path refusals now show only their old captured allowed root or resolved path as complete dynamically fenced literals, or explicit whole-reference omission/unavailability under16KiB. Refused caller path stays undisplayed in root refusal; existing containment/exists/getter/error behavior and opaque prior advice are unchanged, not new absence/native proof. Public from-normalization refusal now also uses only its old displayed source/reason/legacy summary/doctor advice as AX, preserving inner errors, catch/coercion/method order and source/hint disagreement. Source is a whole literal; reason/summary preserve opaque Markdown, and advice is instruction content. Monotone whole-field omission/unavailability fits16KiB without parsing old summary text, adding causes/counts or widening source/catch authority. Normal candidate-admission refusal now also projects only its old source-conditional displayed source/joined diagnostics/legacy summary/advice, preserving branch/coercion/join and pre-Error order. Existing4096-unit upstream admission diagnostic clipping is not widened or repaired; selected summary fields are whole/omitted/unavailable under16KiB, with fitting diagnostics first. This adds no admission policy, full diagnostics/source proof or rollback/readiness authority. Draft raw/candidate invalid-Recipe errors now likewise expose only old optional reason/joined diagnostics with fixed draft/result, preserving separate read/diagnose, truthiness/coercion, Error-before-join and legacy diagnostic bounds. No new path/body, cause, reader, policy or retry follows; whole opaque values fit16KiB or are explicitly omitted/unavailable. Outer registration transaction errors now also project only old post-cleanup stage/resolution-generation/legacy summary/error, preserving cleanup and fallible template order exactly. Resolution generation is not a Run epoch; fitting surfaced error has budget priority and opaque inner rollback/advice text is not a new guarantee. No replay, extra cause/source read or changed transaction policy follows. Registry activation/promotion/deletion notices now also use report/tool AX fields for only old compiler report identity/name, preserving callback order/info type/faults and real hasUI gate. Report wording is not callable/full-host-removal proof. UI text stays literal with native wrapping; no borrowed model16KiB cap, whole well-formed values retained and malformed selected name unavailable. RPC delivery remains fire-and-forget, and loaded UI acceptance stays separate. Recipe registry watcher warning/refresh messages now also use report and opaque instruction constants only, preserving their distinct direct ctx.ui.notify calls (no added hasUI gate), failure dedup/pending-load/callback fault order and old default-root report rather than new verified metadata. Runtime startup warnings now also preserve true category sequences/singletons and whole opaque selected entries through the existing shared field primitive. Original suppression/classification/map/push/join/coercion precedes new projection from compiler-known slots, not parsed authored labels. Trailing LF/no UI cap remain; malformed selected warning is unavailable and old doctor advice is opaque instruction. Native Inspector Run controls retain their selection grammar rather than forced Markdown: producer-specific column gaps now carry ellipses, and complete selected_run_id context uses existing Recipe/Control literal documents, separately from authored fields. Generic fit/composition, source reads, keys and action targets remain unchanged; loaded colored-terminal/phone acceptance stays gated. Other errors/notifications/public owners remain separately scoped, with live client acceptance independent. Reuse the cohesive owner of each projection:
241
+ The following is the current pre-unification implementation inventory, not a set of alternate adopted output styles. Existing flat records, literal JSON fields, verbose JSON and retained-layout HTML compiler frames remain code facts until their owned rollout changes; the target above does not restyle or relabel stored text. This standard spans surfaces, not a new library domain. Control compact-result/public-error is now bare block-YAML metadata with native option sequences, whole selected values or explicit omission records under the existing16KiB cap, no duplicated run namespace, stage/reuse distinctions, typed selective inspect next nodes and opaque advice scalars; verbose JSON remains the machine path. Launch model/thinking groups use the concise `model` and `thinking` labels and preserve their actual source/value relationship; compact launch navigation now remains one whole native YAML value or explicit whole-row omission within16KiB including invocation-response spacing. Full spawn-verbose in source and normally built packages uses the legacy once-only JSON selection followed by clone-only YAML, without a new fixed byte/depth cap. Absent selected JSON, malformed selected text or recoverable post-selection failures withhold the whole projection with an attributable no-auto-repeat warning; original selection throws and structured details remain unchanged. Source/unit and installed compiled response checks, the strict ordinary-metadata source/packed completion journey, and all three source/packed navigation owners are accepted within their bounded domains. Native assertions remain indirect proof, not current global absence. Owning Skill byte parity does not establish a loaded-host change. The older field/inspect-action primitives remain with their unmigrated consumers; compact launch serialization now uses the YAML metadata primitive. Structured/verbose results, exact dispatch/private error causes and old completion handoff text retain their contracts. Fresh ordinary source completion admission captures canonical AX with the private completion_yaml_files_v2 layout: run/state YAML with packet-local indices only for multiple shown results, independently rendered raw Markdown and cut-local [N characters omitted]. The minimal ordinary hint binds whole content to the YAML core, whose relative lengths derive header/body/marker boundaries without fresh HTML tails. Retained completion_frontmatter_v1 hints keep their complete ranges and original compiler frames; neither hint name is a public selector. Only valid compiler headers can hide whole reference/location rows. Markers remain literal and body-authored labels never become metadata/actions. Expansion and invalid/missing hints reveal full original text. These checks establish display consistency, not authentication, source/read scope or acceptance; display line-ending/tab handling never rewrites saved content. Routine state-equivalent summaries remain in the journal, not the new model content; meaningful summaries, loss/redaction/unavailability and reference coverage remain visible. Exact source/generation/parent bindings, whole references and fresh48KiB/64row limits include hidden technical data; retained codecs keep16KiB. The postprivacy byte budget is divided equally between candidate rows: roughly48KiB for one,24KiB each for two,16KiB each for three, less encoded service overhead. Whole admitted text uses result only when it fits without known upstream clipping; otherwise preview uses the safe prefix with exact retained-source omissions. There is no fixed16KiB result/2KiB preview cap and no render-time source IO or reallocation. Already-retained packets keep their exact captured bytes; pre-record messages keep the host renderer and retained record messages keep their original verified view. The Pi boundary recognizes the strict whole YAML core for ordinary source records, or original closed markers/anchored headers for retained captures, after private details are stripped, preserving exact owned-context acceptance without interpreting authored body labels. Actual actors guidance describes this implemented fresh-capture route; this is not a claim that a loaded host was reloaded. Fresh source urgent-steer captures use typed YAML metadata and a separate raw selected body before saving immutable envelope.content: complete final-message fitting and whole reference sequences retain16KiB/eight-slot bounds. Ordinary attention remains unbounded; bounded source/compiled/actual-default acceptance does not establish loaded-host acceptance. Existing envelopes are not reinterpreted, and no older new-message default remains. Fresh ordinary notify/followup uses one AX formatter in the existing sink: the same opaque checkpoint/body and whole first-eight reference projection, without borrowing steer's shared byte cap or changing routing. Committed history keeps its exact text; the retired presentation selector is not a compatibility API. Fresh read-time agent Trace preview leaves now also use boundary U+2026, exact admitted normalized-retained-turn omissions and separately unknown upstream loss, without changing the160UTF-16 source allowance, identifiers/chronology, detail/source data or public JSON schema. Malformed text is unknown, not repaired; no journal capture aspect is minted for a derived current read. New urgent admission/send/recovery diagnostics now also use event/attention/stage AX records, opaque raw240-unit previews and unknown loss while their persisted message-only evidence stays unchanged. A failed send leaves delivery/presentation unconfirmed, and unknown/conflicting queued recovery does not force replay. Fresh non-runtime explicit inspection also uses bare block-YAML metadata: unchanged Run/view headers, tool activation/argument sequences and Recipe registry/focused-doctor facts, whole selected source/identity/advice scalars or explicit whole-field omission, native counts/flags and one typed read-only hint or opaque `next.instruction`. The explicit `tool:* view=schema` text is generated definition metadata in the same bare YAML form with native parameter nodes when renderable; unsupported/over-ceiling schemas retain the exact legacy JSON fallback. Compact argument sequences are whole or explicitly omitted/unavailable. Verbose views bypass compact formatting and machine details keep their JSON contracts. Only the three existing closed read-only Recipe inspect literals become typed next; other advisory strings remain opaque instruction values with full next_actions retained in unchanged details/verbose JSON. Existing body/scope/budget/default-status contracts stay independent. Compact runtime status/runs/triage now also presents only its existing facts/counts as AX fields, with full owned inventory independent from bounded verbose navigation and bounded triage rows. Fresh locally owned runtime notices (callback failure, completion recovery/acceptance, steer admission/delivery/recovery diagnostics and the shutdown teardown report) are now bare block-YAML metadata with explicit receipt/report stages and native counters. UI-only notices keep complete well-formed selected fields without borrowing the model byte/depth ceilings; malformed selected text is explicitly unavailable. Existing steer preview bounds, source/errors, acceptance and native authority are unchanged. Producer-owned watcher/retirement notices now also use uncapped bare block-YAML metadata: whole selected literal paths and opaque diagnostics preserve raw signature/dedup/rearm behavior, while returned stop/reported cancellation/skip/failure remain non-closure reports with exact existing optional-notifier/error observation semantics. Inspector document/detail rendering now uses flat semantic fields, real sequence lists and opaque literal terminal values, with ephemeral compiler-label provenance instead of parsing authored colon/bullet lines as metadata. Separator-preserving native-column wrapping keeps whole text/references, source values, root stripes and existing identity/chronology/navigation/source bounds. Empty containers remain typed values; terminal line-ending/tab display policy does not rewrite source. Ten locally authored inspect refusals now render bare block-YAML metadata with true supported-value sequences, field-local whole-field coverage records and one typed read-only next, preserving their original guards and Error/dependency behavior. Only the two already-guided tool failures retain typed read-only next actions. New local error text shares16KiB including public spacing; variable fields/actions are whole or explicitly counted omitted without shortening targets, reading raw private lengths or wrapping unowned exceptions. Session/source/dependency errors keep their separate owners and old catches rather than being globally restyled. Inspector Kill confirmation now also uses captured run/state/action AX fields with whole-value paging, while both choices and closure: unconfirmed remain pinned at narrow/low viewports. Read-only PgUp/PgDn preserves original Cancel/choice/confirmation/generation behavior and adds no actuation or source permission. Inspector Kill cancellation only closes the dialog; successful actions use the selected Run's visible status without a second Notice. Failures/refusals/uncertainty remain visible, and notifications on other surfaces are not suppressed. Remaining Inspector feedback shows the complete selected opaque message directly in a modal popup over unchanged data rows, without i prefix/command or another reader. Esc dismisses; only physical overflow scrolls within that same popup. Kill uses the same centered rectangle compositor. Both use terminal-default backgrounds rather than a theme fill, two-column left content insets and top/bottom blank spacing, plus the Inspector's shared frame/key/description color grammar. On space-constrained heights, safety/choices/readable text take priority over decorative blanks. They keep the captured underlay stable through resize/invalidation and resume ordinary refresh on close, without fresh evidence/native authority. Action-port feedback pins closure uncertainty/no automatic retry without inferring native effects from message text. Fresh Kill producers now use a shared pure selected-value AX formatter: domain180-unit normalization/trim and overlay160-unit normalization/slice remain, while a cut pair retracts one unit and malformed selected text is unknown/unavailable. Dynamic legacy values state upstream completeness/privacy unproven, with unknown local clipping markers rather than private-tail counts; compiler refusals add no fake loss. ok/callback/getter/coercion/error semantics and old success suppression stay unchanged, and the popup's anchored header recognition affects color only. This does not recover discarded Markdown/causes or create a saved capture version. Trace table rows now mark actual column/line gaps with native ellipsis while preserving full selected item/detail, and compact warning captions keep incomplete-history/non-lifetime/unavailable-rank meaning visible at narrow widths. This is UI preview loss only, not new source/private character counts, rank/identity changes or a generic selector/fit rewrite. Four locally authored Control pre-dispatch guards now also use caller target/action/result and actual supported/available-action sequences: whole target/list groups fit16KiB including public spacing or carry field/entry omission counts, while malformed selected text is unavailable without repair. Original guard/getter/join/coercion observations, plain Error/host-error behavior and all unowned/dispatch exceptions stay separate; no input/status/correlation/retry/no-effects or new dispatch authority follows. Synchronous registered-command failures now present compiler-owned exit_code/killed metadata as bare block YAML, followed by a delimited header before the unchanged selected stderr/stdout bodies (or metadata-only when no stream text was selected); trim/tail selection, truncation notices, temp-file publication and exact executor failures are unchanged. The pre-dispatch argument-repair error now likewise puts owned tool/required/optional facts in a closed YAML header and keeps the original validation prose plus the verbatim JSON invocation example as unparsed body text, and local spawn pre-launch guards use bare block YAML with one whole selected value or an explicit omission record. Three local spawn pre-launch guards present field/result and a whole or explicitly omitted selected caller value as bare block YAML rather than inventing an admitted Run: unsupported state_dir, missing run: namespace and invalid id. Whole valid-scalar values fit16KiB or are omitted; malformed selections are unavailable, without repair or source/private-tail counts. Original input/method/coercion/launch behavior stays separate. The real host still rejects unsupported state_dir through its own unchanged schema before the facade, so this does not claim all SDK validation errors are AX. Namespace/id guard errors retain real host isError behavior. Successful normal registration/update-or-persisted receipts now use original tool/outcome/source/callable facts, actual required/optional argument and warning lists, a whole fenced non-template source and one prior hint. Invocation advice stays opaque instruction; only the producer-known unverified tool-status hint is typed next. Complete safety warnings have first budget priority; all variable fields/groups/actions fit16KiB including public spacing or show whole selected-field/entry omission, with malformed selections unavailable without repair. Original post-effect warning/argument/coercion/boundary observations and all transaction/details/notify/error behavior remain. This is not new callability, host activation, rollback or invocation authority. Registry current-name listing and deletion returns now also use AX: original sorted/captured names are a whole selected group with shown/omitted/total coverage, never a new page/work quota or active/callable/global registry claim. Overlarge groups are wholly omitted and malformed groups unavailable without raw-key re-coercion or repair. Deletion keeps original selected tool/result and the exact operator reload note as opaque instruction; current-map not found stays a returned result, not a new error or orphan-file cleanup. Lookup/file/deactivation/notify/errors/details remain unchanged, including post-effect failures. Draft promotion success now also uses only its prior selected name/new-update/source=draft/exact callable display/first hint as AX. It does not inherit ordinary-registration args/warnings/boundary facts or change its admission/rollback policy. Original template String conversions remain after notify, including zero/object/Symbol behavior and post-effect failures. Whole scalars/actions fit16KiB or are explicitly omitted/unavailable; only the closed producer-known read-only status hint is typed, and invocation advice is opaque. Machine details/bytes and later activation observations remain unchanged. Locally authored registry mode/name/source/template/draft/transaction refusals now render as bare block-YAML metadata documents with compiler-literal fields, native choice sequences, and each opaque selected value whole or explicitly omitted under the unchanged16KiB cap; authored text stays scalar content with escaped line breaks rather than becoming keys or actions. Registry activation/promotion/deletion notice text remains flat report/tool fields, outside this refusal migration. No supplied source values, new helper/wrapper or changed guard/descriptor/getter/trim order. The host still owns cloning, coercion and schema validation: rejected extra/object fields need not reach these AX guards, while numeric input may normalize and preserve a non-error unnamed list result. This is not new schema, no-effects or automatic retry authority. Three ordinary name/source refusals now also use AX: invalid normalized name without raw caller echo, reserved selected-name value whole or explicitly omitted/unavailable, and missing source only for a new registration with actual source choices/opaque prior advice. Original normalization/reserved-set/resolution/lookup/blocker/fault order stays unchanged; empty-name listing, existing-tool update with retained source and dependency blocker text are not reinterpreted. SDK clone/coercion/schema remains separate. Ordinary and draft duplicate-registration refusals now show their original selected name whole/omitted/unavailable plus the original update advice as opaque instruction; distinct authoritative-file/Map/exists/blocker/update predicates and original single display coercion stay unchanged. No overwrite/retry, body-read or no-effects authority follows. Template-shape helper errors now also use fixed template/result records for nested Recipe objects, empty sequences and unsupported types, with actual supported-kind lists/opaque old correction and no supplied value echo. Getter/Array/reference/key/expand semantics and external errors stay exact; null/undefined/deletion/retained-source behavior and SDK coercion remain separate. Authored-Recipe non-object defaults, missing command description, null-at-authoring and missing-final-template constants now also use fixed field/result, without new value echoes or changes to args/from/description/default/retained-source order. Front deletion, inheritance and Schema/dependency errors keep separate ownership. The delegated runtime-owned-default-key refusal now shows only its original first selected key, defaults/result and opaque old correction. Full copy/find order, eight-name membership and the delegated-only condition remain; no all-key/value disclosure, early rejection optimization or new retry authority. Two draft-path refusals now show only their old captured allowed root or resolved path as complete dynamically fenced literals, or explicit whole-reference omission/unavailability under16KiB. Refused caller path stays undisplayed in root refusal; existing containment/exists/getter/error behavior and opaque prior advice are unchanged, not new absence/native proof. Public from-normalization refusal now also uses only its old displayed source/reason/legacy summary/doctor advice as AX, preserving inner errors, catch/coercion/method order and source/hint disagreement. Source is a whole literal; reason/summary preserve opaque Markdown, and advice is instruction content. Monotone whole-field omission/unavailability fits16KiB without parsing old summary text, adding causes/counts or widening source/catch authority. Normal candidate-admission refusal now also projects only its old source-conditional displayed source/joined diagnostics/legacy summary/advice, preserving branch/coercion/join and pre-Error order. Existing4096-unit upstream admission diagnostic clipping is not widened or repaired; selected summary fields are whole/omitted/unavailable under16KiB, with fitting diagnostics first. This adds no admission policy, full diagnostics/source proof or rollback/readiness authority. Draft raw/candidate invalid-Recipe errors now likewise expose only old optional reason/joined diagnostics with fixed draft/result, preserving separate read/diagnose, truthiness/coercion, Error-before-join and legacy diagnostic bounds. No new path/body, cause, reader, policy or retry follows; whole opaque values fit16KiB or are explicitly omitted/unavailable. Outer registration transaction errors now also project only old post-cleanup stage/resolution-generation/legacy summary/error, preserving cleanup and fallible template order exactly. Resolution generation is not a Run epoch; fitting surfaced error has budget priority and opaque inner rollback/advice text is not a new guarantee. No replay, extra cause/source read or changed transaction policy follows. Registry activation/promotion/deletion notices now also use report/tool AX fields for only old compiler report identity/name, preserving callback order/info type/faults and real hasUI gate. Report wording is not callable/full-host-removal proof. UI text stays literal with native wrapping; no borrowed model16KiB cap, whole well-formed values retained and malformed selected name unavailable. RPC delivery remains fire-and-forget, and loaded UI acceptance stays separate. Recipe registry watcher warning/refresh messages now also use report and opaque instruction constants only, preserving their distinct direct ctx.ui.notify calls (no added hasUI gate), failure dedup/pending-load/callback fault order and old default-root report rather than new verified metadata. Runtime startup warnings now also preserve true category sequences/singletons and whole opaque selected entries through the existing shared field primitive. Original suppression/classification/map/push/join/coercion precedes new projection from compiler-known slots, not parsed authored labels. Trailing LF/no UI cap remain; malformed selected warning is unavailable and old doctor advice is opaque instruction. Native Inspector Run controls retain their selection grammar rather than forced Markdown: producer-specific column gaps now carry ellipses, and complete selected_run_id context uses existing Recipe/Control literal documents, separately from authored fields. Generic fit/composition, source reads, keys and action targets remain unchanged; loaded colored-terminal/phone acceptance stays gated. Other errors/notifications/public owners remain separately scoped, with live client acceptance independent. Reuse the cohesive owner of each projection:
243
242
 
244
243
  - `tools-message.ts`: Control receipts, refusals and conservative public error text.
245
244
  - `tools-response.ts`, `tools-spawn.ts`, `tools-local.ts`: shared response primitives and launch/runtime-tool presentation.
@@ -18,74 +18,29 @@ The product goal is useful procedural memory with a selective tool interface, no
18
18
 
19
19
  ## Current Baseline and Its Limits
20
20
 
21
- - `lib/tools-local.ts` awaits synchronous Recipe execution, but an async tool calls `startRun` and returns launch metadata. The eventual Actor result is separate; tool registration does not itself launch an Actor.
22
- - `lib/async-runs.ts` also permits ordinary non-singleton Recipes without `async: true` through the public `spawn` path. The flag does not divide all capabilities into foreground-only and background-only classes.
23
- - `lib/tools-spawn.ts` captures inline-template launches as drafts with `async: true`. It does not capture maintained/file Recipe launches through that draft path. Filtering automatic tool promotion to sync alone would exclude this existing capture stream; ordinary foreground commands are not automatically captured by that mechanism.
24
- - `lib/runtime.ts` discovers the user Recipe root with `defaultTool: true`; `lib/recipes-discovery.ts` exposes valid enabled entries by location, not by sync/async. Active Skill components already demonstrate reusable Recipes without automatic tool exposure.
25
- - `lib/draft-review.ts` admits only promote/discard decisions. `lib/draft-sleep.ts` derives promotion from unchanged immutable captured Recipe content. Review does not generalize a hard-coded mission into a new parameterized capability.
26
- - `lib/review-projection.ts` gives automatic reviewers value-free contract shape, risk labels, usage counts, and batch-local content-equality groups. It excludes commands, descriptions, argument names/values, canonical names, and paths. Those observations cannot by themselves establish a capability's purpose, a meaningful semantic name, or future task usefulness.
27
- - `lib/recipes-usage.ts` records launches and lineage, not successful task completion or the coordinator's acceptance of a useful result. A launch count is not outcome evidence; a command exit code alone would not prove task success either.
21
+ Current user-root discovery exposes valid enabled direct Recipes by location, while active Skill components already provide reusable capabilities without automatic tool exposure. Ordinary registration supports both execution modes, and public `spawn` accepts ordinary non-singleton Recipes without `async: true`; the flag is not a foreground-only restriction. Inline-template `spawn` capture produces async drafts rather than capturing maintained/file Recipe launches, so a sync-only promotion rule would exclude that capture stream.
28
22
 
29
- These are limits on the conclusions the current mechanism supports, not permission to bypass its confidentiality projection or discard its transaction protections.
23
+ Automatic review sees value-free shape, risk labels, launch counts and batch-local content-equality groups, not commands, descriptions, argument names/values, canonical names/paths or accepted outcomes. Its current promote/discard executor preserves captured executable content rather than generalizing a mission. Usage records launches and lineage, not successful task completion. These limits neither authorize bypassing confidentiality nor justify discarding a capability whose usefulness remains unknown.
30
24
 
31
25
  ## Read-Only Inventory Checkpoint
32
26
 
33
- Retained definitions belong under `~/.pi/agent/recipes/library`; the tool root remains its existing direct `.json`/`.md` files. This separation also fails safely on older hosts whose nonrecursive tool discovery ignores the library directory, unlike an unknown opt-out field that an older host could ignore. No new Recipe field or logical-reference namespace is introduced.
27
+ The retained library stays outside nonrecursive tool-root discovery, including on older hosts. Directory separation fails safely where an unknown Recipe opt-out field could be ignored. No new Recipe field or logical-reference namespace is introduced.
34
28
 
35
- Use the same management surface:
36
-
37
- ```text
38
- inspect target=recipes view=summary
39
- inspect target=recipes view=summary verbose=true
40
- ```
41
-
42
- Compact output adds `retained` separately from root `active` candidates and drafts. Verbose/details contains `retained` rows with exact file paths, execution mode when the definition resolves, invalid/disabled state and diagnostics, plus `retained_diagnostics`. Root and retained definitions resolve in the same active Skill context. This read does not create directories, mutate Recipes/usage, register tools, or launch Actors. A stored row is not evidence of review, a callable tool, or a running Actor. Empty/missing library is an empty inventory, not an instruction to initialize one.
43
-
44
- A valid enabled row's exact file path can be reused through existing `spawn recipe=<path>` with its required caller values, or explicitly specialized through existing `register_tool from=<path>`. Invalid/disabled entries remain visible for diagnosis, not recommended for execution. Running instances remain under `inspect target=runtime view=runs` and `run:<id>`; tool activation/schema remains under `tool:<name>`. The inventory is not an alternate Run or activation registry.
45
-
46
- Use the explicit retention operation below rather than hand-populating the live registry or moving existing tools. Source/packed acceptance is separate from reloading an already running host; a loaded older tool schema does not acquire the new input automatically.
29
+ Use `inspect target=recipes view=summary` and `verbose=true` for retained paths and diagnostics. The [inspection contract](./inspection.md) owns views and coverage; the [tool registry](./tool-registry.md#retain-a-new-capability-without-tool-exposure) owns the current save/discover/reuse workflow. Inventory is storage evidence, not review, callability or a running Actor, and never initializes an absent library.
47
30
 
48
31
  ## Explicit Persistence Contract
49
32
 
50
- Status: Implemented for explicit create-only retention; automatic lifecycle remains separate.
51
-
52
- The existing `register_tool` persistence owner accepts an optional Boolean **input** `expose`. This is not a Recipe field or a new tool/registry. `kind: retained_recipe` and `activation: not_requested` distinguish successful retention from failed tool activation.
53
-
54
- - **Omitted or true:** Preserve current tool-root persistence, source modes, update/delete behavior, activation and callability proof.
55
- - **False:** Save a new named definition under `recipes/library/<name>.json` without requesting host registration, changing the active-tool set, or launching work. A name and exactly one `template` or `from` source are required. Apply existing name/reserved-name and effective typed-argument/default admission; sync/async is not a selection filter.
56
- - **References, not relocation:** `from` persists the existing compact logical/file delegation, retaining the source's origins, imports, async, artifacts and Control. A retained wrapper is not a self-contained backup of its source. Reject direct references whose selected source is in managed disposable drafts rather than create an entry knowingly dependent on draft disposal. Apply the same owning resolver/lifetime check to Recipe-valued leaves in authored template graphs, not just the `from` spelling. This is not a transitive lifetime guarantee for arbitrary external files or their dependencies. `template` authors new content at its final library location. No existing Recipe is moved, rewritten or generalized.
57
- - **Create-only first slice:** Retained `update=true`, null/empty-template deletion, and `draft` source mode fail before persistence. They need explicit source-preservation, CAS/recovery and dependency contracts before becoming supported; do not fall back to active-tool mutation. A duplicate retained stem in either JSON or Markdown is a conflict, not permission to shadow or overwrite it. A tool-root entry with the same stem remains a distinct entrypoint and is not modified.
58
-
59
- Explicit flow (supply the capability's required caller values):
33
+ The implemented create-only operation is `register_tool expose=false` with a new name and one template/from source. Omitted/true keeps ordinary registration. The [tool registry](./tool-registry.md#retain-a-new-capability-without-tool-exposure) owns supported inputs, source preservation, conflicts, mutation fences and withdrawal limits; this design does not define a second persistence path.
60
34
 
61
- ```text
62
- register_tool name=changes_review from=swarm/lens-review expose=false
63
- inspect target=recipes view=summary verbose=true
64
- spawn recipe=<exact retained path> values=<caller-owned inputs>
65
- register_tool name=changes_review from=<exact retained path>
66
- ```
67
-
68
- The last step deliberately creates a compact wrapper in the ordinary tool root. It does not copy the executable graph or move the retained definition. `callable_now` and actual tool invocation still need the existing proof. Removing an admitted exposed wrapper through the existing deletion path leaves the retained source intact; this does not turn deletion of an old standalone tool into safe retention. Active Runs retain their original execution contract and are not stopped by wrapper withdrawal.
35
+ The management path is **save deliberately → find through Recipe inspection → reuse the exact Recipe reference → expose explicitly when useful → withdraw only the wrapper when appropriate**. Moving executable sources, converting existing tools/drafts, retained updates/deletion and automatic transitions require separately admitted contracts. Source/package acceptance does not reload an older host or authorize live portfolio changes.
69
36
 
70
37
  ### Receipt and Failure Truth
71
38
 
72
- A successful retain receipt must distinguish **retention** from failed activation: `kind: retained_recipe`, `result: retained`, `persisted: true`, `resolved: true`, `validated: true`, and `activation: not_requested`, plus the exact retained Recipe path and effective required/optional argument names. It must not claim a global `callable_now: false` or `active_tool: false`: a separately exposed tool with the same name may already be callable. The retained branch never calls the host registration/activation ports, and the receipt's next action is read-only Recipe inspection rather than repair/reload advice. This is an extension of the receipt contract, not reconstruction of missing host state.
73
-
74
- Exact paths and selected metadata must use the existing whole-value YAML/omission budget, with full structured details preserved. No executable body, secret-bearing defaults, source installation root or invented semantic assessment is added to the receipt. Storage/validation do not prove review or useful task completion.
75
-
76
- Preflight validates mode/type/source/size and resolves the effective contract before creating library state. The serialized candidate obeys the existing 1 MiB per-Recipe bound even when admission uses an in-memory authored candidate. Operation selection preserves the existing name/source guard order and releases its tool-name reservation before retention locks are acquired. Persistence uses the existing canonical mutation-lock/atomic-write owner, with root → library → target ordering, regular non-symlink files, root identity/containment rechecks and JSON/Markdown conflict detection at the commit boundary. Exclusive publication links complete staged bytes without overwriting a competing creator; an unsupported filesystem refuses without a replacement fallback. Do not infer filesystem sandboxing or hostile-writer exclusion from cooperative locks.
77
-
78
- The first slice has no prior retained bytes to overwrite. It must preserve any competing/pre-existing entry and re-admit its own exact persisted candidate before returning success. Rollback may remove only its own proven unchanged candidate under the original root/target fences; an uncertain replacement, release or notification failure preserves effect uncertainty and original causes rather than blindly deleting or replaying. The retained failure boundary encloses the whole root-lock operation, including post-publication release; exact original or aggregate rejections remain its private cause. Ordinary registration keeps its existing rollback and callback behavior; the retained branch is not a reason to restyle or reorder unrelated guards.
79
-
80
- Retention itself records no launch, success, review or fabricated usage. There is no automatic expiry, background retention loop or live portfolio migration in this slice. Aggregate retention bounds and expiry/disposal remain required before future automatic retention, not a reason to impose an arbitrary new tool-count quota now.
39
+ Retention must be distinguishable from failed activation: `kind: retained_recipe`, `activation: not_requested`, and an exact reusable Recipe path, without global callability claims about a same-named tool. The [current receipt and storage contract](./tool-registry.md#retention-safety-and-accounting) owns fields, budgets, original causes and partial-effect handling. Unknown effects require inspection, not automatic retry or deletion.
81
40
 
82
41
  ### One Usage Owner, Distinct Entrypoints
83
42
 
84
- Library launches use the existing `.usage` owner under the parent Recipe root, not a second ledger root inside `library`. Private ledger identity is `library/<stem>` for retained entries and the existing stem for tool-root entries; this is not a new Recipe name or public `<skill>/<recipe>` reference. A root wrapper and retained definition may share a filename without merging their launch counters or rewriting each other's revision history. JSON/Markdown representations follow the same rule. Neither creating a definition nor exposing its wrapper is a launch.
85
-
86
- Automatic same-source rename inference stays within the retained namespace or within the existing root/draft namespace; disappearance plus matching content cannot silently transfer lineage across the new boundary. Any future deliberate transition must use the existing explicit lineage move/transaction owner. Do not migrate pre-existing nested/legacy ledgers by guessing their ownership or manufacture missing counts; preserve them for separately admitted diagnosis/migration.
87
-
88
- The management result is one coherent path: **save deliberately → find through existing Recipe inspection → reuse the exact Recipe reference → expose explicitly when useful → withdraw only the wrapper when appropriate**. This first contract does not adopt automatic retention/exposure, semantic review, retained updates/deletion, or conversion of existing tools/drafts.
43
+ Reuse the parent's existing usage owner rather than create a library ledger system. Retention, exposure and withdrawal must preserve distinct entrypoint history without inventing accepted outcomes; the [usage/lineage contract](./tool-registry.md#usage-and-lineage) owns the implemented namespace and move rules. Aggregate retention bounds, expiry/disposal and semantic evidence remain prerequisites for future automatic retention, not new tool-count quotas for the manual slice.
89
44
 
90
45
  ## Adopted Lifecycle Direction
91
46
 
@@ -113,7 +113,7 @@ Phases are monotonic:
113
113
 
114
114
  Every journal mutation uses the canonical token-owned lock, expected-phase fencing, owner and generation validation, and atomic replacement. Repeated transitions are idempotent. Corrupt, oversized, foreign-owner, or stale-generation state fails closed with bounded diagnostics.
115
115
 
116
- Ordinary source completion admission has one fresh path: presentation_format=ax_records, private result_layout=completion_yaml_files_v1 and frozen text_budget, without excerpt_format or a public selector. The inactive numbered-stream kernel path keeps its separate frontmatter_v2 default. Bounded source/compiled and actual-default source/packed acceptance observes the normal index path and in-memory entry/context/provider/hint tuple. Unchanged storage/registered-renderer/accepted-history-reopen facts transfer only on the successful original-current-manager path; this is neither fresh default-disk observation nor global lifetime-policy, native-scope or loaded-host acceptance. Direct admission and ordinary run-ui-runtime use it after unchanged owner/location checks; an existing batch stays untouched. Each shown record begins YAML frontmatter with index, run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit error/failure excerpts. Untracked fallback has no kind and retains unknown completeness/privacy outside YAML. The closed header is followed by raw, unindented Markdown, with no #N heading, result:/preview: wrapper or compiler literal fence around the body. Known local loss is [N characters omitted] at the cut, not a YAML flag/count or extra ellipsis; N counts the admitted postprivacy source prefix loss, not private/native output. Unknown upstream loss remains separate. Original coverage remains structured member data; exact source/generation/location references remain whole typed nested YAML values. Routine summaries/windows/status copies/standing map instructions remain journal facts, not duplicated model content. Material omitted_results, non-done omitted_states and whole result_inventory recovery stay explicit. Each shown record has a whole run_files row or explicit omission, with unavailable reasons retained; omitted records do not leave orphan location rows. Outcomes precede lower-priority references under the total48KiB UTF-8/64candidate-row bound including framing. Prefix admission considers full-list and decimal-count discontinuities, freezes equal scalar/CRLF-safe shares without unused-share redistribution, and never clips references or rewrites a retained excerpt. Older captures retain their original16KiB/48KiB budgets.
116
+ Ordinary source completion admission has one fresh path: presentation_format=ax_records, private result_layout=completion_yaml_files_v2 and frozen text_budget, without excerpt_format or a public selector. The inactive numbered-stream kernel path keeps its separate frontmatter_v2 default. Bounded source/compiled and actual-default source/packed acceptance observes the normal index path and in-memory entry/context/provider/hint tuple. Unchanged storage/registered-renderer/accepted-history-reopen facts transfer only on the successful original-current-manager path; this is neither fresh default-disk observation nor global lifetime-policy, native-scope or loaded-host acceptance. Direct admission and ordinary run-ui-runtime use it after unchanged owner/location checks; an existing batch stays untouched. Each shown record begins YAML frontmatter with run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit error/failure excerpts. Untracked fallback has no kind and retains unknown completeness/privacy outside YAML. The closed header is followed by raw, unindented Markdown, with no #N heading, result:/preview: wrapper or compiler literal fence around the body. Known local loss is [N characters omitted] at the cut, not a YAML flag/count or extra ellipsis; N counts the admitted postprivacy source prefix loss, not private/native output. Unknown upstream loss remains separate. Original coverage remains structured member data; exact source/generation/location references remain whole typed nested YAML values. Routine summaries/windows/status copies/standing map instructions remain journal facts, not duplicated model content. Prepend a packet-local index only when two or more results are shown; exactly one shown result omits only that display field even if other results were omitted. Internal member_index, generation and correlation remain unchanged; the rooted_files_v2 discriminator gates this rule, not member count in an older snapshot or numbered-stream scope. Material omitted_results, non-done omitted_states and whole result_inventory recovery stay explicit. Each shown record has a whole run_files row or explicit omission, with unavailable reasons retained; omitted records do not leave orphan location rows. Outcomes precede lower-priority references under the total48KiB UTF-8/64candidate-row bound including framing. Prefix admission considers full-list and decimal-count discontinuities, freezes equal scalar/CRLF-safe shares without unused-share redistribution, and never clips references or rewrites a retained excerpt. Older captures retain their original16KiB/48KiB budgets.
117
117
 
118
118
  Fresh ordinary source hints carry the core format and whole-content digest; the validated YAML core carries only packet identity and relative body/marker lengths, from which boundaries are derived. It adds no fresh HTML tail or duplicate coordinate table. These are consistency facts, not source or acceptance authority.
119
119
 
@@ -131,7 +131,7 @@ Removing fresh collection of untracked bodies would leave affected old/intermedi
131
131
 
132
132
  ### Retained capture compatibility
133
133
 
134
- The numbered wire strings ax_records_v1/v2/v3, old indexed/single_result captures and result_layout records/run_headers/headings/headings_flat_omissions/headings_outcomes/headings_shared_results/headings_shared_kinds/frontmatter_v1/frontmatter_v2 are retained storage encodings, not public alternatives. Fresh ordinary source admission chooses own-data completion_yaml_files_v1 with canonical ax_records and text_budget (over the unchanged completion_yaml_core_v1 carrier); earlier completion_yaml_core_v1 snapshots retain their old layout, never single_result. Absence preserves its original indexed/singleton codec; inherited aspects never restyle data and accessors are refused without invocation. Earlier record/header/count/kind grammar and each captured16KiB/48KiB share remain exact. The first frontmatter draft retains its original bytes and hints, including unquoted unknown index ?. Retained v2 fixed that one YAML case by writing index: "?"; numeric indices and other fields/body bytes are unchanged, and the presentation-hint schema remains completion_frontmatter_v1 because its block structure is unchanged. Preserve the frozen v1 unknown-content fingerprint90e29fb36087e2620fe0cf150b4238bce8a6d1dcc68ee922a1cf71ee8604610e and prior shared-result fingerprint4428de318b8ebaa029d3588ab7e8e705b9a80fa5cf08b6a2cc7151916207e266. Journals store snapshots rather than complete text: neither an unreleased product, a YAML correction nor member count permits relabeling/migration. Pending/queued/presented replay must reproduce original model bytes and hints without operator journal scans, source refresh or message rewrites. Removing compatibility requires a separate history-lifetime decision.
134
+ The numbered wire strings ax_records_v1/v2/v3, old indexed/single_result captures and result_layout records/run_headers/headings/headings_flat_omissions/headings_outcomes/headings_shared_results/headings_shared_kinds/frontmatter_v1/frontmatter_v2 are retained storage encodings, not public alternatives. Fresh ordinary source admission chooses own-data completion_yaml_files_v2 with canonical ax_records and text_budget (over the unchanged completion_yaml_core_v1 carrier); earlier completion_yaml_core_v1 and completion_yaml_files_v1 snapshots retain their old layout and singleton indices, never single_result. Absence preserves its original indexed/singleton codec; inherited aspects never restyle data and accessors are refused without invocation. Earlier record/header/count/kind grammar and each captured16KiB/48KiB share remain exact. The first frontmatter draft retains its original bytes and hints, including unquoted unknown index ?. Retained v2 fixed that one YAML case by writing index: "?"; numeric indices and other fields/body bytes are unchanged, and the presentation-hint schema remains completion_frontmatter_v1 because its block structure is unchanged. Preserve the frozen v1 unknown-content fingerprint90e29fb36087e2620fe0cf150b4238bce8a6d1dcc68ee922a1cf71ee8604610e and prior shared-result fingerprint4428de318b8ebaa029d3588ab7e8e705b9a80fa5cf08b6a2cc7151916207e266. Journals store snapshots rather than complete text: neither an unreleased product, a YAML correction nor member count permits relabeling/migration. Pending/queued/presented replay must reproduce original model bytes and hints without operator journal scans, source refresh or message rewrites. Removing compatibility requires a separate history-lifetime decision.
135
135
 
136
136
  Steer envelopes already store complete content. Both attention and steer now have one canonical new-message formatter with no presentation selector; the redundant legacy formatting branches/path/body helpers are removed where no retained-data consumer needs them. Existing steer identity is reused before formatting and saved content bypasses the formatter in every pending/queued/presented recovery path. Removing stored Batch codecs later requires a separate retention/data-lifetime decision; an unreleased product is not permission to change previously captured delivery bytes.
137
137
 
@@ -91,7 +91,7 @@ F1.6 source-audit correction: Pi 1.0 native custom-message storage, session reco
91
91
  ### 10. Completion Projection, Compiler Frame and Native Renderer
92
92
 
93
93
  - **Owners:** `run-delivery.ts:1510` `completionRecordRow`, `:1683` `assembleFrontmatter`, `:1886` `projectCompletionRecords`, `:2110` `projectRunCompletionBatchPresentation`, `:2233` `readRunCompletionPresentation`, `:2283` retained projection, `:2328` message formatting. `run-ui-runtime.ts:68` `registerRunCompletionRenderer` is wired at `extension-runtime.ts:122`.
94
- - **Current:** Fresh ordinary `completion_yaml_files_v1` snapshots use the unchanged strict YAML-core carrier. Header files.groups stores literal roots with relative entries, source bindings and English purposes; read_first is a group/entry pointer. Unknown-base paths stay explicitly as recorded. Native compact presentation exposes those file groups and places omission/inventory facts in the first header, never after the Markdown. Only known character-cut markers remain beside a truncated body. Earlier core-v1 and historical layouts keep their exact projection and hiding/footer behavior.
94
+ - **Current:** Fresh ordinary `completion_yaml_files_v2` snapshots use the unchanged strict YAML-core carrier. Header files.groups stores literal roots with relative entries, source bindings and English purposes; read_first is a group/entry pointer. Unknown-base paths stay explicitly as recorded. Native compact presentation exposes those file groups and places omission/inventory facts in the first header, never after the Markdown. Only known character-cut markers remain beside a truncated body. Exactly one shown result omits its packet-local display index, including with omissions; multiple shown results retain indices. Internal member/generation/correlation and omission/inventory facts stay unchanged. Earlier rooted-v1, core-v1 and historical layouts keep their exact indices, projection and hiding/footer behavior; numbered streams are separate.
95
95
  - **Prepared wire core:** `run-delivery.ts` `encodeCompletionYamlCarrier` / `readCompletionYamlCarrier` provide the accepted pure/nondefault mechanics; the prototype encodes and typed native view decodes them. Ordinary source/default capture uses the rooted snapshot layout; the earlier core-v1 snapshot and inactive numbered-stream frontmatter_v2 remain separate replay/gated paths. Strict-core Pi correlation and source/packed SDK evidence bind the selected content without granting native or read authority. They encode one `_completion` packet ID/codec and relative body/marker lengths, then derive dense ranges while decoding. Canonical bare headers are independent YAML fragments separated by codec-owned blank lines, not one mapping or a standard YAML multi-document stream; body-present headers are delimited and raw parts remain opaque. All-omitted is bare service metadata, not a fake Run. Empty selected bodies are distinct from absent bodies; empty-marker-only wrappers are refused. Input uses named top-level result keys with explicit depth/work bounds; loaded-host acceptance remains F1.7/U1-gated, and meaningful service warnings must not be hidden wholesale.
96
96
  - **Prepared source projection (nondefault):** `projectRunCompletionYamlPrototype` projects current AX/frontmatter selected snapshots through one shared private fitter; it returns content, a format/digest-only hint and fitting facts, not a newly admitted or relabeled Batch. Frozen budgets/prefixes remain immutable. Canonical header/raw-part costs are measured additively, with unsupported data distinct from byte overflow; final content must agree with the unchanged core encoder/decoder. This prototype API remains data-only and source-class restricted. The ordinary rooted capture reuses internal YAML assembly and the same independently measured quotas/inventory rather than relabeling an old frozen snapshot. Native renderer support is prepared below; actual carrier acceptance remains a separate gate.
97
97
  - **Native view:** `readRunCompletionPresentation` derives frozen typed segments from the strict core and exact minimal format/digest hint; the registered renderer keeps new rooted file groups and all meaningful service facts in headers, then renders each body as independent native Markdown with literal Text metadata/markers. Retained core-v1 captures keep their earlier reference hiding and service placement. Valid-core missing/invalid hints and declared-new malformed content expose original full Text; expansion keeps that same source. Malformed content without a safely readable own new-format declaration retains historical dispatch, not a body-scanning heuristic. Headless widths/padding and old-history preservation are proved. Repo SDK 1.0.0's public `CustomMessageComponent` falls back to one Markdown component when a renderer is absent, returns undefined or throws, joining text-block arrays; a fresh component probe confirms this boundary, not session/interactive dispatch. Preserve that fallback unchanged: full content supplied to Markdown is neither independent-body rendering nor literal-visibility proof. Independent Markdown belongs only to the validated registered compact branch; registered degraded/expanded views keep original Text. Actual source-admitted native storage/context/provider/reopen and loaded terminal/phone behavior remain separate acceptance.
package/docs/releasing.md CHANGED
@@ -15,7 +15,7 @@ The adopted CI layout has three isolated test jobs on each supported OS: `instal
15
15
 
16
16
  Each job uses a separate checkout and test-agent state, Node24 and the existing single-worker/preload flags. Package validation (types, Recipe QA, committed build parity and extension import) plus dry-pack runs once per OS on `installed`, not on every shard. Local `npm test` and `npm run validate` remain complete unsharded entrypoints. The reusable workflow must wait for all nine test jobs and the single dependency audit before release publication; one successful shard never substitutes for the full gate. This layout reduces aggregate critical-path pressure, not the cost or correctness obligations of an individual native test.
17
17
 
18
- Simple tools/registration fixtures bind original runner births and actual `close`, then validate canonical success and fresh ESRCH again at deletion. Their joint acceptance phase has one10-second watchdog, replacing the old approximately2-second result/exit polling assumption; this is a fixture allowance, not a product/SDK/workload deadline. Missing post-close results fail promptly; uncertainty retains roots without signals or automatic wait inflation.
18
+ Simple tools/registration and installed-runner fixtures bind original runner births and actual `close`, then validate canonical success and fresh ESRCH again at deletion. Their joint acceptance phase has one10-second watchdog, replacing the old short result/exit polling assumptions; this is a fixture allowance, not a product/SDK/workload deadline. Missing post-close results fail promptly; uncertainty retains roots without signals or automatic wait inflation.
19
19
 
20
20
  Implementation and native CI acceptance are tracked in BACKLOG until the complete sharded candidate passes.
21
21
 
@@ -47,11 +47,28 @@ register_tool name=repo_check expose=false template="make check" description="Ru
47
47
  register_tool name=review_changes expose=false from=swarm/lens-review
48
48
  ```
49
49
 
50
- This create-only mode writes `recipes/library/<name>.json`, not a tool-root entry. It accepts a new name and one template/from source; retained update, null/empty deletion, draft promotion and direct references to managed disposable drafts (including Recipe-valued template leaves) are rejected. JSON/Markdown stem conflicts, invalid source/defaults, oversized candidates and unsafe storage fail without activating a tool. Existing tools with the same name are untouched. Publication is a complete atomic no-overwrite file link; unsupported filesystems refuse rather than falling back to replacement.
50
+ This create-only mode writes `recipes/library/<name>.json`, not a tool-root entry. The optional Boolean `expose` is registration input, not a Recipe field; omitted/true preserves ordinary registration. A new name and exactly one template/from source are required. Retained update, null/empty deletion, draft promotion and direct managed disposable-draft dependencies, including Recipe-valued template leaves, are rejected. JSON/Markdown stem conflicts, invalid source/defaults, oversized candidates and unsafe storage fail without activating a tool; a same-named exposed tool is untouched. Retaining never calls host registration/activation ports, mutates the active-tool set or launches work.
51
51
 
52
- A `kind: retained_recipe`, `activation: not_requested` receipt confirms admission/persistence and returns the exact Recipe path with required/optional argument names. It omits global callability flags and defaults: a separately exposed same-named tool might already be callable. The next hint is read-only Recipe inspection, not activation repair. Reuse the exact retained file with `spawn recipe=<path>`, or expose a compact wrapper deliberately with ordinary `register_tool name=<tool> from=<path>`. Deleting an admitted wrapper through the existing deletion path does not delete its retained source or stop active Runs. No automatic retention, review decision, source relocation or live migration is added.
52
+ Retained `from` stores compact logical/file delegation and inherits the effective source contract, origins, imports, async, artifacts and Control without copying or moving its executable graph. It is an external dependency, not a self-contained backup or transitive lifetime guarantee. Newly authored template references resolve from their final library location.
53
53
 
54
- A post-persistence admission, storage, publication-cleanup or lock-release failure can leave committed bytes; original causes are retained and uncertain files are not blindly deleted. Inspect the inventory before considering any retry. Ordinary tool registration keeps its existing rollback and activation contract.
54
+ Use the existing surfaces, supplying required caller values:
55
+
56
+ ```text
57
+ register_tool name=changes_review from=swarm/lens-review expose=false
58
+ inspect target=recipes view=summary verbose=true
59
+ spawn recipe=<exact retained path> values=<caller-owned inputs>
60
+ register_tool name=changes_review from=<exact retained path>
61
+ ```
62
+
63
+ Inspection distinguishes retained rows from tool-root candidates and drafts, using the same active Skill context. Compact output gives a retained count; verbose detail gives exact paths, resolved execution mode, invalid/disabled state and diagnostics. Reads create no directories, usage, tools or Runs; an absent library is empty. Reuse only valid enabled definitions. The final step deliberately exposes a wrapper; verify `callable_now` and actual tool invocation separately. Deleting an admitted wrapper preserves its retained source and does not stop active Runs or turn deletion of an old standalone tool into safe retention. No automatic retention, review decision, source relocation or live migration is added. See [Management Inspection](./inspection.md) for views and coverage.
64
+
65
+ ### Retention Safety and Accounting
66
+
67
+ Preflight preserves existing name/source guard order and validates the effective typed-argument/default contract and complete serialized candidate before library writes, including the existing 1 MiB Recipe limit. The tool-name reservation releases before root → library → target mutation locks. Regular non-symlink directory/file identity and containment frames, JSON/Markdown conflict checks and exact persisted-content re-admission fence publication and success. Complete staged bytes publish through an atomic no-overwrite hard link; unsupported filesystems refuse without a replacement fallback. These cooperative guards are not a filesystem sandbox or hostile-writer exclusion.
68
+
69
+ Success reports `kind: retained_recipe`, `result: retained`, `persisted: true`, `resolved: true`, `validated: true`, `activation: not_requested`, effective async mode, the exact Recipe path and required/optional argument names. It omits global `callable_now`/`active_tool` flags because a same-named tool may already exist. Metadata follows the existing whole-value YAML/omission budget with complete structured details; no executable body, secret-bearing defaults, source installation root or semantic usefulness claim is added. Its next hint is read-only Recipe inspection, not activation repair. Storage alone proves neither review, callability nor task success.
70
+
71
+ Post-publication admission, cleanup or lock-release faults can leave committed bytes. The failure boundary includes release of the outer root lock and preserves the exact original or aggregate cause privately; public effects remain unconfirmed. Rollback may remove only its own proven unchanged candidate under the original root/target fences. Do not blindly delete an uncertain candidate or replay the operation: inspect retained inventory first. Ordinary registration keeps its existing rollback and activation contract. Retention itself records no launch, success or review, and introduces no automatic expiry or migration; usage accounting remains with the existing owner below.
55
72
 
56
73
  ## Resolution
57
74
 
@@ -81,9 +98,7 @@ These parameters are not Recipe-authored args. Singleton tools do not expose `ru
81
98
 
82
99
  ## Retention Versus Exposure — Adopted Direction
83
100
 
84
- The [capability-memory design](./capability-memory.md) separates preserving a reviewed reusable Recipe from offering it as a named tool. Either sync or async execution can qualify; a subagent-backed tool launches a capability, not a persisted live subagent. Async calls return a launch receipt, not the eventual work result.
85
-
86
- The explicit create-only slice is implemented; the automatic lifecycle remains a target. The user root still exposes valid enabled Recipes by location, automatic draft review still chooses promote/discard, and ordinary `register_tool` remains available for both modes. `expose=false` explicitly retains new template/from definitions without activation. Read-only `inspect target=recipes view=summary` lists library definitions separately from tool candidates; verbose detail provides exact paths, mode and invalid/disabled diagnostics. No Recipe exposure field or retain/defer review action is added. A library row is storage intent, not proof of review, callability or a running Actor. Structural review and launch counts alone cannot prove semantic usefulness or accepted successful reuse. Remaining integration belongs to [BACKLOG.md](../BACKLOG.md).
101
+ The [capability-memory design](./capability-memory.md) owns the separation, future lifecycle and evidence gates; [BACKLOG.md](../BACKLOG.md) owns remaining work. Sync/async is execution policy, not a retention/usefulness rule: a subagent-backed tool launches a capability, and its async receipt is not the eventual result. Explicit create-only retention is implemented above; automatic retain/defer/expose transitions are not. Existing automatic promote/discard review and live portfolios remain unchanged.
87
102
 
88
103
  ## Automatic Review
89
104
 
@@ -111,6 +126,8 @@ Set `PI_ACTORS_AUTOMATIC_REVIEW=off` to disable scheduling and safe-boundary act
111
126
 
112
127
  Usage and lineage live in locked metadata ledgers rather than authored Recipe files. Launch accounting briefly shares the portfolio transaction fence so quarantine cannot invalidate an already-authorized launch. Revision snapshots, rollback, demotion, rename, and identical-source deduplication retain CAS/hash evidence.
113
128
 
129
+ Retained launches use the parent Recipe root's existing `.usage` owner, not a second ledger under `library`. Private `library/<stem>` identity keeps them separate from same-stem tool-root entrypoints for JSON and Markdown alike; it is not a public Recipe reference. Retaining or exposing a definition is not a launch. Automatic missing-source/content-equality rename inference stays within the library namespace or within the existing root/draft namespace. Deliberate moves use the existing explicit lineage transaction owner; do not guess migrations or missing counts from legacy nested ledgers. Launch history does not establish useful accepted outcomes.
130
+
114
131
  ## Specializing Existing Recipes
115
132
 
116
133
  Use `register_tool from=<skill>/<recipe> defaults={...}` for one maintained capability under a persistent name or narrower defaults. Pi supplies one authoritative active-session Skill snapshot across global, project, package, settings, CLI, and extension-contributed locations. Registration resolves the source from that snapshot, stores only the logical direct-delegation reference plus caller specialization, and activates the tool from the already-resolved effective contract without ambient re-resolution. It does not copy async, args/types, Control, artifacts, helpers, or runtime-owned `{recipe_dir}`/`{skill_dir}`; symlinks and absolute helper paths are not substitutes. Named imports remain for multi-node Recipe composition, not one-source specialization. Skill Recipes remain components and are never exposed merely because their Skill is active. Install only specific capabilities; internal automatic-review Recipes must not become user-callable tools.
package/lib/pi.ts CHANGED
@@ -123,7 +123,7 @@ function unheaderedCompletionId(content: string): string | { malformed: true } |
123
123
  const core = RunDelivery.readCompletionYamlCarrier(content);
124
124
  if (core.state === "available") return core.packet.batchId;
125
125
  // Initial compiler headers only: never recover identity by scanning authored bodies.
126
- if (/^(?:index: (?:\d+|"\?")\nrun: [^\n]*\nstate:|_completion:\n (?:codec|batch_id):)/u.test(content)) return { malformed: true };
126
+ if (/^(?:index: (?:\d+|"\?")\nrun: [^\n]*\nstate:|run:[^\r\n]*(?:\r\n|\r|\n)state:|_completion:\n (?:codec|batch_id):)/u.test(content)) return { malformed: true };
127
127
  }
128
128
  if (typeof content === "string" && (hasCompletionFrontmatterPrefix(content) || /^(?:#|Run #|— Новый поток|- run:|- #0:\n|- result: omitted \(model byte limit\)\n|- omitted_results:)/u.test(content))) {
129
129
  return RunDelivery.readRunCompletionRecordMarker(content)?.batchId ?? { malformed: true };
@@ -69,7 +69,7 @@ export interface RunCompletionBatch {
69
69
  /** Retained singleton capture; absence preserves older indexed bytes. Never a new-capture selector. */
70
70
  readonly single_result?: true;
71
71
  /** Captured record-list shape; no public format/version choice or source authority. */
72
- readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1";
72
+ readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2";
73
73
  /** Immutable scope/order/range data, not a caller-selected format or allocation authority. */
74
74
  readonly numbering?: RunCompletionNumbering;
75
75
  /** Formatting version/data only; no recipient ownership, read or publication capability. */
@@ -467,8 +467,12 @@ function isFrontmatterCompletionLayout(layout: unknown): boolean {
467
467
  return layout === "frontmatter_v1" || layout === "frontmatter_v2";
468
468
  }
469
469
 
470
+ function isRootedCompletionLayout(layout: unknown): boolean {
471
+ return layout === "completion_yaml_files_v1" || layout === "completion_yaml_files_v2";
472
+ }
473
+
470
474
  function isYamlCompletionLayout(layout: unknown): boolean {
471
- return layout === "completion_yaml_core_v1" || layout === "completion_yaml_files_v1";
475
+ return layout === "completion_yaml_core_v1" || isRootedCompletionLayout(layout);
472
476
  }
473
477
 
474
478
  function isSharedCompletionLayout(layout: unknown): boolean {
@@ -895,7 +899,7 @@ export function requestRunCompletionStream(input: { tempDir: string; ownerId: st
895
899
  }
896
900
 
897
901
  export function admitRunCompletionBatch(input: AdmitRunCompletionBatchInput): RunCompletionBatch {
898
- return captureCompletionBatch(input, false, "completion_yaml_files_v1");
902
+ return captureCompletionBatch(input, false, "completion_yaml_files_v2");
899
903
  }
900
904
 
901
905
  /** Kernel-only opt-in; ordinary Pi capture stays fenced until session/lifecycle integration is admitted. */
@@ -905,10 +909,10 @@ export function captureRunCompletionStreamBatch(input: AdmitRunCompletionBatchIn
905
909
 
906
910
  /** Private ordinary candidate composition; stream capture retains its separately gated codec. */
907
911
  export function captureRunCompletionYamlCandidateBatch(input: AdmitRunCompletionBatchInput): RunCompletionBatch {
908
- return captureCompletionBatch(input, false, "completion_yaml_files_v1");
912
+ return captureCompletionBatch(input, false, "completion_yaml_files_v2");
909
913
  }
910
914
 
911
- function captureCompletionBatch(input: AdmitRunCompletionBatchInput, numbered: boolean, layout: "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" = "frontmatter_v2"): RunCompletionBatch {
915
+ function captureCompletionBatch(input: AdmitRunCompletionBatchInput, numbered: boolean, layout: "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" = "frontmatter_v2"): RunCompletionBatch {
912
916
  const now = (input.now ?? new Date()).toISOString();
913
917
  if (Object.hasOwn(input, "presentationFormat")) throw new Error("Completion presentation selection is not supported; new batches use AX.");
914
918
  if (Object.hasOwn(input, "numbering")) throw new Error("Completion numbering is assigned only by journal capture");
@@ -1869,12 +1873,13 @@ type PreparedCompletionYamlProjection =
1869
1873
  function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: readonly { row: CompletionRow; location?: CompletionPiece }[],
1870
1874
  references: ReadonlySet<number>, ordered: readonly RunCompletionBatchMember[]): PreparedCompletionYamlProjection {
1871
1875
  const packet: CompletionYamlPacket = { batchId: safe.batch_id, records: [] };
1872
- const rooted = safe.result_layout === "completion_yaml_files_v1";
1876
+ const rooted = isRootedCompletionLayout(safe.result_layout);
1877
+ const localSingleton = safe.result_layout === "completion_yaml_files_v2" && !safe.numbering && candidates.length === 1;
1873
1878
  if (!safe.batch_id.isWellFormed()) return { state: "unsupported" };
1874
1879
  for (const [index, { row, location }] of candidates.entries()) {
1875
1880
  const member = ordered[index]!;
1876
1881
  const displayed = safe.numbering ? safe.numbering.kind === "stream" ? safe.numbering.first_index + index : "?" : index;
1877
- const metadata: Record<string, CompletionYamlData> = { index: displayed };
1882
+ const metadata: Record<string, CompletionYamlData> = localSingleton ? {} : { index: displayed };
1878
1883
  for (const piece of row.pieces) {
1879
1884
  if (piece.block) continue;
1880
1885
  if (!piece.field) return { state: "unsupported" };
@@ -1917,7 +1922,9 @@ function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: r
1917
1922
  }
1918
1923
  packet.records.push({ metadata, parts });
1919
1924
  }
1920
- const service: Record<string, CompletionYamlData> = rooted ? { header_layout: "rooted_files_v1" } : {};
1925
+ const service: Record<string, CompletionYamlData> = rooted ? {
1926
+ header_layout: safe.result_layout === "completion_yaml_files_v2" ? "rooted_files_v2" : "rooted_files_v1",
1927
+ } : {};
1921
1928
  const omitted = safe.members.length - candidates.length;
1922
1929
  if (omitted) {
1923
1930
  service.omitted_results = omitted;
@@ -2349,7 +2356,7 @@ export function readRunCompletionPresentation(content: string, value: unknown):
2349
2356
  !completionYamlKeys(hint, ["format", "content_sha256"]) || hint.format !== completionYamlCodec ||
2350
2357
  hint.content_sha256 !== createHash("sha256").update(content).digest("hex")) return full;
2351
2358
  const segments: NonNullable<RunCompletionPresentationView["segments"]>[number][] = [];
2352
- const rooted = core.packet.service?.header_layout === "rooted_files_v1";
2359
+ const rooted = core.packet.service?.header_layout === "rooted_files_v1" || core.packet.service?.header_layout === "rooted_files_v2";
2353
2360
  const facts = Object.fromEntries(Object.entries(core.packet.service ?? {}).filter(([key]) => key !== "header_layout"));
2354
2361
  for (const [index, record] of core.packet.records.entries()) {
2355
2362
  if (index) segments.push({ kind: "separator", text: "\n" });
@@ -2581,6 +2588,8 @@ export function encodeCompletionYamlCarrier(input: unknown): { state: "available
2581
2588
  typeof packet.batchId !== "string" || !packet.batchId.length || !Array.isArray(packet.records) || packet.records.length > 64 ||
2582
2589
  (Object.hasOwn(packet, "service") && (!completionYamlMapping(packet.service) || !Object.keys(packet.service).length)) ||
2583
2590
  (!packet.records.length && !Object.hasOwn(packet, "service"))) return unavailable;
2591
+ const localSingleton = packet.records.length === 1 && completionYamlMapping(packet.service) &&
2592
+ packet.service.header_layout === "rooted_files_v2" && !Object.hasOwn(packet.service, "numbering");
2584
2593
  const rows: string[] = [];
2585
2594
  for (let index = 0; index < Math.max(1, packet.records.length); index++) {
2586
2595
  const row: CompletionYamlData | undefined = packet.records[index];
@@ -2596,13 +2605,15 @@ export function encodeCompletionYamlCarrier(input: unknown): { state: "available
2596
2605
  if (!completionYamlMapping(row) || !completionYamlKeys(row, ["metadata", "parts"]) ||
2597
2606
  !completionYamlMapping(row.metadata) || !Array.isArray(row.parts)) return unavailable;
2598
2607
  const meta = row.metadata;
2599
- if (!(meta.index === "?" || (typeof meta.index === "number" && Number.isSafeInteger(meta.index) && meta.index >= 0)) ||
2608
+ const validIndex = localSingleton ? !Object.hasOwn(meta, "index")
2609
+ : meta.index === "?" || (typeof meta.index === "number" && Number.isSafeInteger(meta.index) && meta.index >= 0);
2610
+ if (!validIndex ||
2600
2611
  typeof meta.run !== "string" || !meta.run.length || typeof meta.state !== "string" || !meta.state.length ||
2601
2612
  (Object.hasOwn(meta, "kind") && meta.kind !== "primary" && meta.kind !== "diagnostic") ||
2602
2613
  Object.hasOwn(meta, completionYamlServiceKey) ||
2603
2614
  // JS enumerates array-index keys before semantic core fields; do not silently reorder the header.
2604
2615
  Object.keys(meta).some(key => /^(0|[1-9]\d*)$/u.test(key) && Number(key) < 4294967295)) return unavailable;
2605
- for (const key of ["index", "run", "state", ...(Object.hasOwn(meta, "kind") ? ["kind"] : []),
2616
+ for (const key of [...(localSingleton ? [] : ["index"]), "run", "state", ...(Object.hasOwn(meta, "kind") ? ["kind"] : []),
2606
2617
  ...Object.keys(meta).filter(key => !["index", "run", "state", "kind"].includes(key))]) {
2607
2618
  Object.defineProperty(header, key, { value: meta[key]!, enumerable: true });
2608
2619
  }
@@ -538,16 +538,18 @@ export function compactYamlDocument(value: Record<string, unknown>): string {
538
538
  return `\n${text.replace(/\n$/u, "")}`;
539
539
  }
540
540
 
541
+ function recipeInspectionHint(action: string): { view: "doctor" | "imports" | "summary"; verbose?: true } | undefined {
542
+ if (action === "inspect target=recipes view=doctor") return { view: "doctor" };
543
+ if (action === "inspect target=recipes view=imports verbose=true") return { view: "imports", verbose: true };
544
+ if (action === "inspect target=recipes view=summary verbose=true") return { view: "summary", verbose: true };
545
+ return undefined;
546
+ }
547
+
541
548
  /** Only the closed read-only Recipe inspect literals become typed next; other advice stays opaque content. */
542
549
  export function nextActionMetadata(action: string, byteBudget: number): YamlPart {
543
- const recognized = [
544
- ["inspect target=recipes view=doctor", "doctor", false],
545
- ["inspect target=recipes view=imports verbose=true", "imports", true],
546
- ["inspect target=recipes view=summary verbose=true", "summary", true],
547
- ] as const;
548
- const match = recognized.find(([literal]) => literal === action);
549
- if (match) {
550
- const typed = { next: { tool: "inspect", target: "recipes", view: match[1], ...(match[2] ? { verbose: true } : {}) } };
550
+ const hint = recipeInspectionHint(action);
551
+ if (hint) {
552
+ const typed = { next: { tool: "inspect", target: "recipes", ...hint } };
551
553
  return { full: typed, selected: typed };
552
554
  }
553
555
  const instruction = selectYamlField("instruction", action, byteBudget);
@@ -556,10 +558,8 @@ export function nextActionMetadata(action: string, byteBudget: number): YamlPart
556
558
 
557
559
  /** Only these existing read-only inspection hints become action nodes; other advice stays content. */
558
560
  export function formatInspectionHint(action: string): string {
559
- if (action === "inspect target=recipes view=doctor") return formatInspectNextAction("recipes", "doctor");
560
- if (action === "inspect target=recipes view=imports verbose=true") return formatInspectNextAction("recipes", "imports", true);
561
- if (action === "inspect target=recipes view=summary verbose=true") return formatInspectNextAction("recipes", "summary", true);
562
- return formatMarkdownField("instruction", action);
561
+ const hint = recipeInspectionHint(action);
562
+ return hint ? formatInspectNextAction("recipes", hint.view, hint.verbose) : formatMarkdownField("instruction", action);
563
563
  }
564
564
 
565
565
  export function compactRecipeRegistry(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-actors",
3
- "version": "0.58.0",
3
+ "version": "0.58.1",
4
4
  "private": false,
5
5
  "description": "Local Actor Kernel for Pi",
6
6
  "keywords": [
@@ -73,7 +73,7 @@ Rollout is partial: compact launch/attachment receipts use block YAML; other ope
73
73
 
74
74
  Compact launches use bare block-YAML mappings for the Run/state/launch facts and nested observed locations, explicitly identify actual existing-Run reuse, and preserve multiline scalar contents. One leading response-separator LF supplies invocation spacing; it is outside the pure metadata emitter and is not a `---` wrapper. Model/thinking provenance groups are labeled model and thinking, without a redundant _policy suffix; structured data and saved text stay unchanged. A complete direct file-location row needs no repeated session-map hint; absent/unavailable/omitted rows retain one optional next node naming inspect, target=runtime, view=runs and verbose=true. It never executes automatically. Exact locations, verbose details and saved completion formats stay unchanged.
75
75
 
76
- Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins index, run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. One record uses the same shape as many. Display index is not member_index or generation; default indices are packet-local. Whole-result/reference omissions and non-done omitted states stay explicit. Known display loss appears at the actual cut as [N characters omitted], counting Unicode scalar characters of admitted retained text/field, never raw/private loss; no extra clipping ellipsis or body clipping flags/counts in YAML. Unknown upstream completeness/privacy remains separately visible at the body boundary, not a fabricated count or a known positive loss. Untracked fallback has no kind and cannot become primary. Full text fitting its share has no display-cut marker; upstream uncertainty still prevents a completeness claim. New packets share48KiB UTF-8 including references/framing across at most64candidate rows, with frozen equal shares and no unused-share redistribution or fixed16KiB result/2KiB preview cap. Captured members remain bounded at256. Text is admitted work output/final response or explicit error/failure diagnostics, never launch commands. Successful composition/retry/Pi text-print can retain text_basis:actor_response; scope and exact references remain technical, while original coverage facts remain structured retained data. The model receives one complete content with whole source/generation/location references or truthful omission/inventory, not a standing full-map instruction. The TUI renders compiler headers/markers as Text and each body as independent native Markdown; only whole validated header reference/location rows and framing disappear in compact view. Body-authored YAML, next/tool/batch and omission lookalikes remain content. Content-bound hashes/ranges/blocks are display consistency, not authentication, source/read/action or acceptance authority. Invalid/missing hints and expansion reveal full original text, without Run-source IO. Old saved codecs, budgets, labels, excerpts, counts and hints replay exactly with no refresh, repair, ACK/resend or restyling—including earlier #N packets and the first frontmatter encoding. Fresh unavailable indices use quoted YAML "?"; an old saved unquoted value is not silently corrected. Routine successful delivery adds no separate completions/delivery-accepted toast; actual failures and handled-generation fences remain. These source/package rules do not prove that an already loaded session was reloaded. Fresh explicit agent Trace previews append boundary … and [omitted: N chars] from normalized retained turn, with a separate upstream [omitted: unknown]. N counts only display loss after existing session privacy, not discarded original/source text. Short well-formed summaries stay unchanged, including authored older-looking markers; malformed retained text yields Agent turn [omitted: unknown] (malformed retained text), never a guessed count or repaired scalar. This is read-time display only, not a rewrite/version of saved packets or sources. Other legacy clipping is not yet uniformly covered. Follow retained references selectively without inventing completeness or permission. Agent Trace ids reference recorded entry provenance, not aggregate traversal order or chronological event numbers. Native entry keys survive sibling growth; bounded legacy/ambiguous/private-metadata fallbacks are not permanent identities, source immutability or new read/work permission.
76
+ Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. Prepend index only when two or more results are shown; exactly one shown result omits it even if other results were omitted. Omission/inventory facts remain explicit. Display index is not member_index or generation; default indices are packet-local. This new-capture rule neither restyles saved messages nor changes numbered-stream presentation. Whole-result/reference omissions and non-done omitted states stay explicit. Known display loss appears at the actual cut as [N characters omitted], counting Unicode scalar characters of admitted retained text/field, never raw/private loss; no extra clipping ellipsis or body clipping flags/counts in YAML. Unknown upstream completeness/privacy remains separately visible at the body boundary, not a fabricated count or a known positive loss. Untracked fallback has no kind and cannot become primary. Full text fitting its share has no display-cut marker; upstream uncertainty still prevents a completeness claim. New packets share48KiB UTF-8 including references/framing across at most64candidate rows, with frozen equal shares and no unused-share redistribution or fixed16KiB result/2KiB preview cap. Captured members remain bounded at256. Text is admitted work output/final response or explicit error/failure diagnostics, never launch commands. Successful composition/retry/Pi text-print can retain text_basis:actor_response; scope and exact references remain technical, while original coverage facts remain structured retained data. The model receives one complete content with whole source/generation/location references or truthful omission/inventory, not a standing full-map instruction. The TUI renders compiler headers/markers as Text and each body as independent native Markdown; only whole validated header reference/location rows and framing disappear in compact view. Body-authored YAML, next/tool/batch and omission lookalikes remain content. Content-bound hashes/ranges/blocks are display consistency, not authentication, source/read/action or acceptance authority. Invalid/missing hints and expansion reveal full original text, without Run-source IO. Old saved codecs, budgets, labels, excerpts, counts and hints replay exactly with no refresh, repair, ACK/resend or restyling—including earlier #N packets and the first frontmatter encoding. Fresh unavailable indices use quoted YAML "?"; an old saved unquoted value is not silently corrected. Routine successful delivery adds no separate completions/delivery-accepted toast; actual failures and handled-generation fences remain. These source/package rules do not prove that an already loaded session was reloaded. Fresh explicit agent Trace previews append boundary … and [omitted: N chars] from normalized retained turn, with a separate upstream [omitted: unknown]. N counts only display loss after existing session privacy, not discarded original/source text. Short well-formed summaries stay unchanged, including authored older-looking markers; malformed retained text yields Agent turn [omitted: unknown] (malformed retained text), never a guessed count or repaired scalar. This is read-time display only, not a rewrite/version of saved packets or sources. Other legacy clipping is not yet uniformly covered. Follow retained references selectively without inventing completeness or permission. Agent Trace ids reference recorded entry provenance, not aggregate traversal order or chronological event numbers. Native entry keys survive sibling growth; bounded legacy/ambiguous/private-metadata fallbacks are not permanent identities, source immutability or new read/work permission.
77
77
 
78
78
  Current completion index fields are packet-local, not persistent historical indices; earlier saved #N headings keep their original meaning. Session completion streams are adopted work in progress, not an available action; do not invent a start-stream command, initialize a missing counter or reinterpret old headings. A kernel-only path commits numbered snapshots/counters/activation atomically. Its internal runtime bridge requires trusted fresh-session opt-in plus current manager/generation binding; the default entrypoint does not opt in and no public tool/command exposes it. Unknown state does not fall back to local numbering on that path. Startup/reload/resume, including ambiguous imports, cannot resume a stream automatically; stored numbers remain data, not a new session grant. A pending target or projected scope is not an active stream. Missing state never authorizes bootstrap, and unknown/conflicting delivery never authorizes bypass or reallocation. Saved numbers stay exact; an admitted unavailable counter or unfitting whole range freezes an unknown index (quoted "?" in fresh YAML, #? in older layouts) rather than resetting or partially numbering a packet.
79
79
 
@@ -24,7 +24,7 @@ inspect target=run:<id> view=trace
24
24
  inspect target=run:<id> view=control
25
25
  ```
26
26
 
27
- Fresh root completions use index-first YAML frontmatter (index, run, state, admitted kind), followed by raw left-edge Markdown. New source captures put all runtime metadata above that body, with no service/file footer. files.groups gives one literal root plus relative entry paths; files.read_first names zero-based group/entry indices for the first useful source, not an automatic read. role/purpose guidance is English; Actor Markdown and path/name bytes are unchanged. External paths use separate roots; unknown bases remain explicit rather than guessed from cwd or Run id. Known cut counts alone may follow the cut body; unknown-loss warnings and packet omission/inventory facts stay in the header. Retained captures preserve their old bytes and presentation. No external #N heading, result:/preview: wrapper, list nesting, whole-body fence, Batch caption, members wrapper or routine outer counter is added. Primary/final Actor response uses kind:primary; explicit error/failure diagnostic text uses kind:diagnostic, never a launch command. Untracked fallback has no kind and keeps unknown original completeness/privacy explicit outside YAML. Known cut loss is [N characters omitted] at the cut, with no extra ellipsis or body clipping counters/flags in metadata. Unknown upstream loss remains separately unknown and does not assert a known positive omission. Exact source/generation/parent/location references remain in complete model content, with whole references or explicit omission, captured inventory recovery and non-done omitted states. The compact TUI independently renders literal headers/markers and native Markdown bodies from validated content-bound blocks; only whole header reference/location rows and framing are hidden. Expansion and invalid/missing hints reveal original text. Hashes/layout/markers establish consistency/correlation only, never authentication, read/action permission, acceptance or native truth. Authored YAML/next/tool/batch/omission lookalikes stay body content. Fresh packets share48KiB UTF-8 including service data, equally between up to64candidate rows, with256captured members and no redistribution of unused shares or fixed16KiB/2KiB text cap. Full admitted text fitting its share without upstream uncertainty has no cut marker; otherwise use the scalar/CRLF-safe prefix and exact retained-source loss. Allocation/text is frozen at admission; rendering/recovery does not reread sources or reallocate. Unsupported Pi event/control output is withheld. Source basis stays in reference metadata; retained structured coverage facts are not exposed as YAML clipping fields. Pending/queued/presented older formats—including #N records and the first frontmatter draft—keep exact bytes, hints and budgets. Encoding names are storage replay data, not public product choices, source permissions or work authority. No standing full-map instruction or automatic research/read follows; use selective same-session investigation when needed.
27
+ Fresh root completions use YAML frontmatter (run, state, admitted kind), followed by raw left-edge Markdown. Prepend the packet-local index only when two or more results are shown. Exactly one shown result omits its index even with omitted results; preserve omission/inventory metadata, internal member/generation/correlation and every saved message. This rule does not apply to numbered streams. New source captures put all runtime metadata above that body, with no service/file footer. files.groups gives one literal root plus relative entry paths; files.read_first names zero-based group/entry indices for the first useful source, not an automatic read. role/purpose guidance is English; Actor Markdown and path/name bytes are unchanged. External paths use separate roots; unknown bases remain explicit rather than guessed from cwd or Run id. Known cut counts alone may follow the cut body; unknown-loss warnings and packet omission/inventory facts stay in the header. Retained captures preserve their old bytes and presentation. No external #N heading, result:/preview: wrapper, list nesting, whole-body fence, Batch caption, members wrapper or routine outer counter is added. Primary/final Actor response uses kind:primary; explicit error/failure diagnostic text uses kind:diagnostic, never a launch command. Untracked fallback has no kind and keeps unknown original completeness/privacy explicit outside YAML. Known cut loss is [N characters omitted] at the cut, with no extra ellipsis or body clipping counters/flags in metadata. Unknown upstream loss remains separately unknown and does not assert a known positive omission. Exact source/generation/parent/location references remain in complete model content, with whole references or explicit omission, captured inventory recovery and non-done omitted states. The compact TUI independently renders literal headers/markers and native Markdown bodies from validated content-bound blocks; only whole header reference/location rows and framing are hidden. Expansion and invalid/missing hints reveal original text. Hashes/layout/markers establish consistency/correlation only, never authentication, read/action permission, acceptance or native truth. Authored YAML/next/tool/batch/omission lookalikes stay body content. Fresh packets share48KiB UTF-8 including service data, equally between up to64candidate rows, with256captured members and no redistribution of unused shares or fixed16KiB/2KiB text cap. Full admitted text fitting its share without upstream uncertainty has no cut marker; otherwise use the scalar/CRLF-safe prefix and exact retained-source loss. Allocation/text is frozen at admission; rendering/recovery does not reread sources or reallocate. Unsupported Pi event/control output is withheld. Source basis stays in reference metadata; retained structured coverage facts are not exposed as YAML clipping fields. Pending/queued/presented older formats—including #N records and the first frontmatter draft—keep exact bytes, hints and budgets. Encoding names are storage replay data, not public product choices, source permissions or work authority. No standing full-map instruction or automatic research/read follows; use selective same-session investigation when needed.
28
28
 
29
29
  Current completion index values restart within each packet; they are not session-wide historical references. Completion streams are adopted but not enabled, and no start-stream command is available yet. Do not infer an active stream or reset a counter from missing metadata or a pending target, and never relabel older saved packets. The kernel-only allocator now commits fixed scope/order/indices, the counter and first-packet target activation together, and an internal fresh-session bridge can use it after current manager/generation admission. The default runtime does not opt in; no public action exposes it. Event reason or a matching ID alone is insufficient. Old callbacks/wrappers cannot act after replacement; fresh wrappers must belong to the current original manager. Startup/reload/resume and ambiguous imports remain closed to stream capture/ACK, without changing saved packets or inferring a counter from history. Its whole-range exhaustion or admitted counter unavailability yields a frozen unknown index (quoted "?" in fresh YAML; #? in older saved layouts), never partial indices or an automatic fresh stream. Old packets retain their original scope while a pending switch waits; uncertainty does not permit reallocation. Stream state outlives packet cleanup/receipt rotation. Malformed/missing state remains refused, not a zero counter or proof of non-connection.
30
30