@llblab/pi-actors 0.58.1 → 0.58.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/AGENTS.md +3 -3
  2. package/BACKLOG.md +2 -2
  3. package/CHANGELOG.md +12 -0
  4. package/README.md +38 -36
  5. package/dist/lib/draft-sleep.js +3 -3
  6. package/dist/lib/extension-runtime.js +7 -2
  7. package/dist/lib/prompts.d.ts +3 -3
  8. package/dist/lib/prompts.js +10 -9
  9. package/dist/lib/recipes-references.js +7 -7
  10. package/dist/lib/registry.js +27 -24
  11. package/dist/lib/review-control.js +1 -1
  12. package/dist/lib/run-delivery.d.ts +1 -1
  13. package/dist/lib/run-delivery.js +41 -17
  14. package/dist/lib/run-evidence-policy.js +2 -2
  15. package/dist/lib/runtime.d.ts +3 -0
  16. package/dist/lib/runtime.js +24 -10
  17. package/dist/lib/tool-review-scheduler.js +7 -7
  18. package/dist/lib/tools-access.js +1 -1
  19. package/dist/lib/tools-inspect.js +10 -10
  20. package/dist/lib/tools-message.d.ts +1 -1
  21. package/dist/lib/tools-message.js +10 -10
  22. package/dist/lib/tools-register.d.ts +3 -3
  23. package/dist/lib/tools-register.js +4 -4
  24. package/dist/lib/tools-response.d.ts +1 -1
  25. package/dist/lib/tools-response.js +42 -20
  26. package/dist/lib/tools-spawn.js +1 -1
  27. package/dist/lib/tools.d.ts +7 -0
  28. package/dist/lib/tools.js +25 -0
  29. package/dist/skills/actors/SKILL.md +29 -21
  30. package/dist/skills/actors/references/diagnostics.md +11 -11
  31. package/dist/skills/actors/references/persistent-tools.md +19 -15
  32. package/dist/skills/actors/references/recipes.md +1 -1
  33. package/dist/skills/actors/references/runs.md +10 -10
  34. package/dist/skills/music-player/SKILL.md +4 -4
  35. package/dist/skills/music-player/scripts/playback.mjs +1 -1
  36. package/dist/skills/recipe-memory/SKILL.md +7 -7
  37. package/docs/README.md +2 -2
  38. package/docs/actor-inspector.md +1 -1
  39. package/docs/agent-experience.md +8 -8
  40. package/docs/async-runs.md +13 -13
  41. package/docs/capability-memory.md +6 -6
  42. package/docs/coordinator-delivery.md +2 -2
  43. package/docs/inspection.md +21 -21
  44. package/docs/output-projection-map.md +1 -1
  45. package/docs/run-supervision.md +21 -21
  46. package/docs/tool-registry.md +27 -19
  47. package/docs/windows-process-observation.md +1 -1
  48. package/lib/draft-sleep.ts +3 -3
  49. package/lib/extension-runtime.ts +7 -5
  50. package/lib/prompts.ts +10 -9
  51. package/lib/recipes-references.ts +7 -7
  52. package/lib/registry.ts +26 -24
  53. package/lib/review-control.ts +1 -1
  54. package/lib/run-delivery.ts +34 -17
  55. package/lib/run-evidence-policy.ts +2 -2
  56. package/lib/runtime.ts +26 -11
  57. package/lib/tool-review-scheduler.ts +7 -7
  58. package/lib/tools-access.ts +1 -1
  59. package/lib/tools-inspect.ts +10 -10
  60. package/lib/tools-message.ts +10 -10
  61. package/lib/tools-register.ts +4 -4
  62. package/lib/tools-response.ts +39 -20
  63. package/lib/tools-spawn.ts +1 -1
  64. package/lib/tools.ts +28 -0
  65. package/package.json +1 -1
  66. package/skills/actors/SKILL.md +29 -21
  67. package/skills/actors/references/diagnostics.md +11 -11
  68. package/skills/actors/references/persistent-tools.md +19 -15
  69. package/skills/actors/references/recipes.md +1 -1
  70. package/skills/actors/references/runs.md +10 -10
  71. package/skills/music-player/SKILL.md +4 -4
  72. package/skills/music-player/scripts/playback.mjs +1 -1
  73. package/skills/recipe-memory/SKILL.md +7 -7
package/AGENTS.md CHANGED
@@ -22,7 +22,7 @@ Run = Recipe + Trace + Control
22
22
 
23
23
  An actor is any runnable local capability, including a script, tool, service, pipeline, or subagent. Recipes define actors' reusable execution. Runs are concrete actor instances and own one generation of execution and evidence. Trace owns observations. Control owns actor-local inputs for services that actually consume them. `register_tool` persists capabilities separately.
24
24
 
25
- Public Run verbs remain `spawn`, `message`, and `inspect`. Agent Experience (AX) is a project-wide design principle: structured, visible, decision-relevant context that both the agent and the human can read, between raw machine data and unstructured prose. The [AX standard](docs/agent-experience.md) governs presentation across surfaces without changing their data or authority contracts.
25
+ Canonical public tools are `actors_tool_register`, `actors_run_spawn`, `actors_control_apply`, and `actors_inspect`. Advertise only these names. Explicit compatibility dispatch retains old `register_tool`, `spawn`, `message`, and `inspect` calls with the same schemas/executors, without rewriting saved calls or Recipe identities. Control applies Run/runtime actions, not agent chat. New configurable tool names use their functional owner's namespace (for example `audio_transcribe`); never automatically prefix/migrate persisted Recipe names. Reject normalized host-tool collisions, including inactive foreign tools, before exposure or mutation; `update=true` is not foreign-tool overwrite permission. Agent Experience (AX) is a project-wide design principle: structured, visible, decision-relevant context that both the agent and the human can read, between raw machine data and unstructured prose. The [AX standard](docs/agent-experience.md) governs presentation across surfaces without changing their data or authority contracts.
26
26
 
27
27
  The adopted presentation direction is **JSON structured inputs → block-YAML runtime-output metadata + unchanged authored text/Markdown**. This covers tool/launch/status/Control/inspect/error/notification/completion output, not only Actor results. Metadata-only receipts are bare YAML without `---` or a code fence; use opening/closing `---` only when a separate selected text/Markdown body follows. Framing depends on body presence, not synchronous versus asynchronous execution. Keep exactly one visual blank line between host-owned tool invocation header/arguments and response, including errors; this is boundary spacing, not a reason to rewrite selected content, echo private inputs or add YAML delimiters. Do not invent a Markdown-list pseudo-object grammar or serialize runtime objects as JSON strings inside YAML. SDK/Recipe input contracts, machine DTOs/journals/native wire formats and literal source content remain separate. YAML rollout is pending, not a claim that current emitters or a loaded host conform; preserve old saved bytes/codecs, exact content, privacy/generation fences and budgets, and gate service-framing migration on equivalent boundary/correlation/replay evidence.
28
28
 
@@ -93,7 +93,7 @@ For ordinary Run-file investigation, follow the accepted [same-session research
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_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.
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_v3 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 useful whole source/location references follow; full source/generation/hash facts remain in the frozen snapshot rather than repeated per file. 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_v3 service discriminator gates fresh compact file projection and the singleton rule; retained rooted-files-v1/v2/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, selected relative paths, role/name, concise deterministic admitted status and read_first group/entry indices. Keep primary/diagnostic/inventory/artifact references and observed context-index/result/execution paths (metadata fallback), not absent optional technical files or repeated purpose/format/size/mutable/generation/hash fields. Retain source/privacy distinctions, declaration uncertainty, unavailable locations and missing terminal result facts; saved full bindings remain accessible and unchanged. Compact is the actual human/model content, not UI-only hiding. 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. Saved file_navigation binds the original mutable Run-directory facts independently from the compact projection. 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.
@@ -253,4 +253,4 @@ Operator-owned staging may change concurrently through the UI. Do not gate work
253
253
  - `.github/workflows/release.yml` owns the immutable sequence reusable validation → npm Trusted Publisher publication/verification → GitHub Release convergence; follow [docs/releasing.md](docs/releasing.md).
254
254
  - Keep npm publication tokenless: use the exact npm Trusted Publisher binding and job-scoped OIDC permission, never a long-lived npm token or token fallback.
255
255
  - Manifest-loaded packages expose bundled Skills only through `pi.skills`, preserving package resource filters and package-owned provenance. Only a checkout auto-discovered directly below a user or project Pi `extensions/` root may contribute its source Skill root through `resources_discover`; compiled-vs-source filename shape does not determine ownership.
256
- - Until a stable version beyond `1.x`, prefer clean breaking simplification over compatibility aliases or renamed legacy abstractions.
256
+ - Prefer clean simplification over compatibility aliases except the explicitly adopted TOOL-NAMES migration above; preserve its legacy dispatch and saved identities. Do not generalize that exception into unrelated compatibility surfaces.
package/BACKLOG.md CHANGED
@@ -19,13 +19,13 @@ Outcome: JSON structured inputs, block-YAML runtime-output metadata and unchange
19
19
 
20
20
  Exit: New owned runtime projections use YAML without pseudo-records or serialized JSON objects: bare when metadata-only, `---`-delimited headers only when a separate text body follows. Literal content, meaning, source/privacy bounds and saved messages remain intact. Service-carrier adoption has its own evidence gate; do not delete current framing to simulate completion.
21
21
 
22
- - [ ] **F1.7 — Accept the rollout on a loaded host.** Source/headless audit is done: one shared framing owner keeps exactly one host-separation blank line on migrated paths, no runtime-authored object dump or pseudo-record remains in the migrated set, history/literal bodies are unchanged, and source/compiled/package parity passes. Remainder is the permitted loaded terminal/phone observation of one rollout candidate, including rooted completion headers, English read-first guidance and no post-Markdown runtime footer, which needs the same separate authorization as U1; keep capture codecs and live claims distinct and claim no automatic default activation.
22
+ - [ ] **F1.7 — Accept the rollout on a loaded host.** Source/headless audit is done: one shared framing owner keeps exactly one host-separation blank line on migrated paths, no runtime-authored object dump or pseudo-record remains in the migrated set, history/literal bodies are unchanged, and source/compiled/package parity passes. Remainder is the permitted loaded terminal/phone observation of one rollout candidate, including compact selected launch paths and rooted completion references/status, English read-first guidance and no post-Markdown runtime footer, which needs the same separate authorization as U1; keep capture codecs and live claims distinct and claim no automatic default activation.
23
23
 
24
24
  ### U1 — Loaded UI/AX acceptance
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: 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.
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, compact useful file paths/status without repeated technical metadata, 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,6 +2,18 @@
2
2
 
3
3
  > Each release keeps at most 8 outcome records of at most 512 characters.
4
4
 
5
+ ## 0.58.3: Compact Run File Navigation
6
+
7
+ - `Useful File References`: Compact spawn/async-tool receipts select useful exact starting paths without per-file format, size, mutable, scope or generation dumps. Fresh completion headers keep rooted source/artifact paths and concise admitted status, not repeated purposes or hashes. Full machine details and saved snapshot bindings remain accessible.
8
+ - `Truthful Projection and Replay`: Real unavailable/missing-result observations, unknown text loss, failed outcomes and whole-reference/result omissions remain visible within existing budgets. Formatting adds no source reads, probes or status authority. A private fresh-capture layout preserves byte-exact earlier packet formats and unchanged Actor Markdown.
9
+ - `Acceptance Boundary`: Owner properties and actual-default source/packed SDK journeys cover compact content, exact references, retained bindings, fixed budgets and replay. Loaded terminal/phone acceptance, integration and publication remain separate; no reload or live registry mutation is implied.
10
+
11
+ ## 0.58.2: Canonical Actor Tool Names
12
+
13
+ - `Canonical Tool Surface`: New calls use `actors_tool_register`, `actors_run_spawn`, `actors_control_apply`, and `actors_inspect`. Explicit legacy dispatch shares the same schemas/executors while model declarations and ordinary callable listings advertise canonical names only. Saved calls, Recipe identities and Run semantics remain unchanged.
14
+ - `Control and Capability Ownership`: Control applies Run/runtime actions, not chat. Functional-owner namespaces are agent-facing naming guidance, not runtime ownership inference. Registration/discovery reject normalized foreign host collisions, including inactive tools; `update=true` grants no foreign overwrite. Own retained inactive declarations permit Recipe recreation/restoration after discovery loss. Saved names remain exact; deactivation is not complete host unregister.
15
+ - `Migration Evidence and Guidance`: Tool/registry properties and isolated source/npm-packed default SDK journeys cover canonical/legacy parity, saved-call preservation, loss/restoration, foreign replacement refusal and canonical-only model declarations. Skills, runtime advice, schema copy and packaged references use canonical names; historical completion framing stays exact. No live registry migration, host reload or publication is implied.
16
+
5
17
  ## 0.58.1: Singleton Completion Indices
6
18
 
7
19
  - `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.
package/README.md CHANGED
@@ -9,7 +9,7 @@ Recipe --spawn--> Run
9
9
  Run = Recipe + Trace + Control
10
10
  ```
11
11
 
12
- An **actor** is any runnable local capability: a script, tool, service, pipeline, or subagent. A **Recipe** is its reusable executable definition. `spawn` creates a **Run**—one concrete actor instance—which captures its Recipe, appends observable **Trace**, and may consume actor-local **Control**.
12
+ An **actor** is any runnable local capability: a script, tool, service, pipeline, or subagent. A **Recipe** is its reusable executable definition. `actors_run_spawn` creates a **Run**—one concrete actor instance—which captures its Recipe, appends observable **Trace**, and may consume actor-local **Control**.
13
13
 
14
14
  ## Agent Experience (AX)
15
15
 
@@ -29,7 +29,7 @@ Design notes for [portable Recipe composition bundles and CodeMode interoperabil
29
29
 
30
30
  A reusable Recipe does not have to become a named tool. The [adopted capability-memory direction](docs/capability-memory.md) separates retention from tool exposure: sync/async determines execution, not usefulness, and a subagent-backed tool is a capability launcher rather than a saved live Actor. The aim is useful procedural memory with a selective tool interface, not more registered names.
31
31
 
32
- Use `register_tool expose=false` with a new name and a template/from source to save a capability in `recipes/library` without activating a tool. Its retained_recipe/not_requested receipt returns the exact Recipe path for `spawn` or later deliberate `register_tool from` exposure. Creation is exclusive; retained update, delete and draft promotion are not supported. `inspect target=recipes view=summary` distinguishes retained definitions, with exact paths, modes and diagnostics in verbose detail. Automatic retained lifecycle is not implemented. Current tool-root discovery, automatic review and ordinary registration remain unchanged; structural review and launch counts alone do not prove useful successful reuse. [BACKLOG.md](BACKLOG.md) owns implementation and evidence gates; adopting the direction neither migrates existing tools nor reloads a running host.
32
+ Use `actors_tool_register expose=false` with a new name and a template/from source to save a capability in `recipes/library` without activating a tool. Its retained_recipe/not_requested receipt returns the exact Recipe path for `actors_run_spawn` or later deliberate `actors_tool_register from` exposure. Creation is exclusive; retained update, delete and draft promotion are not supported. `actors_inspect target=recipes view=summary` distinguishes retained definitions, with exact paths, modes and diagnostics in verbose detail. Automatic retained lifecycle is not implemented. Current tool-root discovery, automatic review and ordinary registration remain unchanged; structural review and launch counts alone do not prove useful successful reuse. [BACKLOG.md](BACKLOG.md) owns implementation and evidence gates; adopting the direction neither migrates existing tools nor reloads a running host.
33
33
 
34
34
  ## Install
35
35
 
@@ -49,20 +49,22 @@ The package contributes the extension and six capability-owning Skills for actor
49
49
 
50
50
  ## Public Tools
51
51
 
52
- ### `spawn`
52
+ Only `actors_tool_register`, `actors_run_spawn`, `actors_control_apply`, and `actors_inspect` are advertised for new calls. Explicit legacy `register_tool`, `spawn`, `message`, and `inspect` dispatch remains compatible with saved calls through the same schemas and executors. Saved Recipe identities and completion text are not migrated. Control applies Run/runtime actions, not chat. See [Tool Registry](docs/tool-registry.md#public-names-and-compatible-dispatch) for compatibility visibility, namespace and collision rules; this change does not reload an already running host.
53
+
54
+ ### `actors_run_spawn`
53
55
 
54
56
  Create a Run from an active-Skill Recipe, an explicit Recipe file, or an inline command template:
55
57
 
56
58
  ```text
57
- spawn template="sleep 30" as=run:demo
58
- spawn recipe=project-work/repo-health values={"repo":"/work/project","model":"provider/model"}
59
- spawn recipe=music-player/playback values={"source":"/music"}
60
- spawn template="make test" as=run:test
59
+ actors_run_spawn template="sleep 30" as=run:demo
60
+ actors_run_spawn recipe=project-work/repo-health values={"repo":"/work/project","model":"provider/model"}
61
+ actors_run_spawn recipe=music-player/playback values={"source":"/music"}
62
+ actors_run_spawn template="make test" as=run:test
61
63
  ```
62
64
 
63
65
  Use a Run when work may outlive the current turn, needs steering, fans out, produces artifacts, or must remain inspectable. Short foreground commands can remain ordinary tools.
64
66
 
65
- ### `message`
67
+ ### `actors_control_apply`
66
68
 
67
69
  Send one exact Control:
68
70
 
@@ -78,38 +80,38 @@ Send one exact Control:
78
80
  Run targets accept Recipe-declared actor-local actions plus runtime-owned `kill`, `archive`, and `prune`, subject to Run state. Runtime targets accept only reserved review actions:
79
81
 
80
82
  ```text
81
- message target=runtime action=review.retry input={"scope":"draft"}
82
- message target=runtime action=review.retry input={"scope":"tool"}
83
- message target=runtime action=review.reset input={"scope":"draft"}
84
- message target=runtime action=review.reset input={"scope":"tool"}
83
+ actors_control_apply target=runtime action=review.retry input={"scope":"draft"}
84
+ actors_control_apply target=runtime action=review.retry input={"scope":"tool"}
85
+ actors_control_apply target=runtime action=review.reset input={"scope":"draft"}
86
+ actors_control_apply target=runtime action=review.reset input={"scope":"tool"}
85
87
  ```
86
88
 
87
89
  Lifecycle `kill` remains runtime-owned rather than Recipe-declared.
88
90
 
89
- ### `inspect`
91
+ ### `actors_inspect`
90
92
 
91
93
  Inspect one exact management target:
92
94
 
93
95
  ```text
94
- inspect target=run:test view=recipe
95
- inspect target=run:test view=trace source=lifecycle lines=40
96
- inspect target=run:test view=control
97
- inspect target=runtime view=status
98
- inspect target=runtime view=runs status=failed
99
- inspect target=runtime view=triage
100
- inspect target=recipes view=status
101
- inspect target=recipes view=summary
102
- inspect target=recipes view=doctor identity=music-player/playback
103
- inspect target=tool:my_tool view=status
96
+ actors_inspect target=run:test view=recipe
97
+ actors_inspect target=run:test view=trace source=lifecycle lines=40
98
+ actors_inspect target=run:test view=control
99
+ actors_inspect target=runtime view=status
100
+ actors_inspect target=runtime view=runs status=failed
101
+ actors_inspect target=runtime view=triage
102
+ actors_inspect target=recipes view=status
103
+ actors_inspect target=recipes view=summary
104
+ actors_inspect target=recipes view=doctor identity=music-player/playback
105
+ actors_inspect target=tool:my_tool view=status
104
106
  ```
105
107
 
106
- Recipe `summary` and `registry` are the same inspection path; only `verbose` selects compact text versus structured details. Recipe and tool views are listed above; `inspect` parameter help and unsupported-view refusals name the actual accepted view sequences.
108
+ Recipe `summary` and `registry` are the same inspection path; only `verbose` selects compact text versus structured details. Recipe and tool views are listed above; `actors_inspect` parameter help and unsupported-view refusals name the actual accepted view sequences.
107
109
 
108
- A Run exposes exactly `recipe`, `trace`, and `control` views. Run-specific `inspect` and `message` require a current coordinator session whose id exactly matches the persisted non-empty Run owner; possessing `run:<id>` alone is not authorization. Missing-session, ownerless, and cross-owner access fails closed. Use `inspect target=runtime view=runs` for the current session's exact-owner inventory. See the complete [management inspection matrix](./docs/inspection.md).
110
+ A Run exposes exactly `recipe`, `trace`, and `control` views. Run-specific `actors_inspect` and `actors_control_apply` require a current coordinator session whose id exactly matches the persisted non-empty Run owner; possessing `run:<id>` alone is not authorization. Missing-session, ownerless, and cross-owner access fails closed. Use `actors_inspect target=runtime view=runs` for the current session's exact-owner inventory. See the complete [management inspection matrix](./docs/inspection.md).
109
111
 
110
- ### `register_tool`
112
+ ### `actors_tool_register`
111
113
 
112
- Persist a maintained Recipe with `register_tool name=<tool> from=<skill>/<recipe> defaults={...}`, or register a trusted command through the separate `template` mode. Definitions live under `~/.pi/agent/recipes`. With `expose=false`, a new template/from definition is retained under `recipes/library` instead; its not_requested receipt makes no tool-callability claim. Treat an exposed tool as callable in the current session only when the result reports `callable_now: true`; persistence, Recipe spawning, and registered-tool invocation are distinct states.
114
+ Persist a maintained Recipe with `actors_tool_register name=<tool> from=<skill>/<recipe> defaults={...}`, or register a trusted command through the separate `template` mode. Definitions live under `~/.pi/agent/recipes`. With `expose=false`, a new template/from definition is retained under `recipes/library` instead; its not_requested receipt makes no tool-callability claim. Treat an exposed tool as callable in the current session only when the result reports `callable_now: true`; persistence, Recipe spawning, and registered-tool invocation are distinct states.
113
115
 
114
116
  ## Recipe
115
117
 
@@ -166,7 +168,7 @@ String command-template leaves execute directly without shell interpretation. Us
166
168
  }
167
169
  ```
168
170
 
169
- Trace fields are exact: `id`, `ts`, `kind`, and optional `summary`, `data`, `level`, `attention`. Address, sender, recipient, reply, and routing fields fail validation. Trace is a bounded retained suffix, not an audit archive: the canonical authority appends within 2,048 events and 4 MiB or atomically keeps the newest suffix plus one warning-only `runtime.trace_compacted` marker. That marker means older history was discarded; `result.json`, `execution.json`, terminal state, and declared artifacts retain their own authority. `inspect view=trace` reports whether retained history is complete. Reads are newline-safe and deterministic; first-party scripts never write this file directly.
171
+ Trace fields are exact: `id`, `ts`, `kind`, and optional `summary`, `data`, `level`, `attention`. Address, sender, recipient, reply, and routing fields fail validation. Trace is a bounded retained suffix, not an audit archive: the canonical authority appends within 2,048 events and 4 MiB or atomically keeps the newest suffix plus one warning-only `runtime.trace_compacted` marker. That marker means older history was discarded; `result.json`, `execution.json`, terminal state, and declared artifacts retain their own authority. `actors_inspect view=trace` reports whether retained history is complete. Reads are newline-safe and deterministic; first-party scripts never write this file directly.
170
172
 
171
173
  Generic command lifecycle is Trace-only: runner-owned `command.done` records preserve completion and execution evidence but never request or project attention, including malformed legacy records carrying `steer`. There is no Recipe-level command-completion delivery switch. Semantic attention is explicit: `notify` shows visible status without a model turn, `followup` supplies ordinary checkpoint context, and `steer` requests urgent delivery at Pi's next safe assistant/tool boundary. `notify` and `followup` remain retained wake hints that may compact away, so persist recovery state or an artifact first. `steer` is admitted to the bounded owner delivery journal before `deliverAs: "steer"`, acknowledged only in exact model-bound context, and never suppresses the eventual root-terminal batch. Store large evidence in artifacts or bounded execution captures. New urgent steers keep the canonical checkpoint and whole optional references within 16 KiB, explicitly counting omitted paths instead of cutting a path; saved envelopes retain their original text. Essential text that cannot fit remains retryable before admission, not partially delivered. Ordinary notify/followup shares exact reference spelling and explicit eight-slot coverage; its wake policy is unchanged. Legacy body and steer-diagnostic clipping explicitly marks unknown omission counts when no retained privacy context admits safe numbers; it is not a new privacy or completeness guarantee.
172
174
 
@@ -174,9 +176,9 @@ Ordinary finite Runs project terminal results through one root-coordinator compl
174
176
 
175
177
  Implemented UX/AX subset: completions share48KiB UTF-8 including service fields, divided equally between up to64 candidate results: nearly48KiB for one,24KiB each for two,16KiB each for three. Whole admitted text fitting its share is result; otherwise preview carries the safe prefix and exact omitted count, without a fixed16KiB result/2KiB preview cap. Completions show admitted work output or the bounded executor-selected final Actor response, never command metadata. Saved packets keep their original budget/text; source-backed prefix selection occurs only at fresh admission, not replay/render. Direct Pi text-print answers and successful composition/retry responses use the original producer privacy; observed upstream clipping stays explicit and is not confused with preview loss. Ordinary completions can carry retained primary-text, artifact-declaration inventory and diagnostic-metadata references. Follow the exact reference for clipped or omitted evidence; it records capture-time identity/hash/counts, not perpetual readability. Artifact inventories list declarations only, not proof that target files exist or were produced, and do not grant body-read permission. Diagnostic excerpts identify the selected field with literal UTF-8/Unicode counts; their source contains recorded command/error/failure-reason metadata, not complete primary output. Source loss is explicit and never replaced by guessed legacy bodies or paths. See [Run supervision](docs/run-supervision.md) for implemented boundaries and remaining acceptance gates.
176
178
 
177
- Implemented A2 subset: `inspect target=runtime view=runs verbose=true` now adds a bounded [root-first file map](docs/run-supervision.md#same-session-file-investigation) for the actual session's already cataloged directories. Follow selected locations with ordinary tools, without an original producer key. Source/npm-packed SDK fixtures resume the same saved session in a new process after real Run producers and their coordinator host have exited, then read the actual result and select recorded stdout via the mapped execution manifest with ordinary tools; another session gets no inherited branch. The read-only map exposes canonical starting-location coverage and expected format hints, not a full file inventory or format/completeness validation. Its published_sessions link locates the fixed role catalog physically under the owned Run root, even without a semantic index or producer key; this does not certify its body or historical publication. SDK checks select one controlled partial preview and also read an actual private-writer preview after its holder exits and the same saved session opens in another process. Exact tool-read paths and final byte/absence snapshots are checked, including selected-preview loss errors without cached/raw fallback; the private publisher uses controlled recorded-session sources, not genuine Actor conversations. A finite public spawn and later same-saved-session research also pass through real source/npm entrypoints, without replacement tools or copied lifecycle wiring. Corrupt catalogs stay unavailable without repair. Inventory filters observe current Run status, not the registration-time cache. Ordinary maps retain root-group recency with known failed children first; add status=failed to the verbose request for observed failed-subtree-first ordering across roots without filtering the full owned map or adding reads. Priority is partial observed data, not terminal authority. Launches and compatible singleton attachments now register after lifecycle release; catalog failure returns `catalog=unavailable` without failing or retrying the launched work. SDK fork/clone preserves inherited history but gives the new logical session no fresh map branch. Compact launch receipts now include exact-generation current-session starting locations without evidence-body or catalog reads, or explicit unavailability/whole-row omission. New completion batches freeze bounded same-session location rows at admission and render them after outcomes within the shared budget, alongside the optional current-session map command. Legacy absent/request-only packets retain their text; source/npm SDK verifies an explicitly requested result read from a terminal row. This closes representative navigation acceptance, not the release. Neither captured locations nor the request execute inspection automatically or grant copied/forked history fresh ownership. Legacy batches keep their original text; no full map is embedded into immutable outcomes. Compact/default inspection, curated previews and timing/work/native authority are unchanged.
179
+ Implemented A2 subset: `actors_inspect target=runtime view=runs verbose=true` now adds a bounded [root-first file map](docs/run-supervision.md#same-session-file-investigation) for the actual session's already cataloged directories. Follow selected locations with ordinary tools, without an original producer key. Source/npm-packed SDK fixtures resume the same saved session in a new process after real Run producers and their coordinator host have exited, then read the actual result and select recorded stdout via the mapped execution manifest with ordinary tools; another session gets no inherited branch. The read-only map exposes canonical starting-location coverage and expected format hints, not a full file inventory or format/completeness validation. Its published_sessions link locates the fixed role catalog physically under the owned Run root, even without a semantic index or producer key; this does not certify its body or historical publication. SDK checks select one controlled partial preview and also read an actual private-writer preview after its holder exits and the same saved session opens in another process. Exact tool-read paths and final byte/absence snapshots are checked, including selected-preview loss errors without cached/raw fallback; the private publisher uses controlled recorded-session sources, not genuine Actor conversations. A finite public spawn and later same-saved-session research also pass through real source/npm entrypoints, without replacement tools or copied lifecycle wiring. Corrupt catalogs stay unavailable without repair. Inventory filters observe current Run status, not the registration-time cache. Ordinary maps retain root-group recency with known failed children first; add status=failed to the verbose request for observed failed-subtree-first ordering across roots without filtering the full owned map or adding reads. Priority is partial observed data, not terminal authority. Launches and compatible singleton attachments now register after lifecycle release; catalog failure returns `catalog=unavailable` without failing or retrying the launched work. SDK fork/clone preserves inherited history but gives the new logical session no fresh map branch. Compact launch receipts now include exact-generation current-session starting locations without evidence-body or catalog reads, or explicit unavailability/whole-row omission. New completion batches freeze bounded same-session location rows at admission and render them after outcomes within the shared budget, alongside the optional current-session map command. Legacy absent/request-only packets retain their text; source/npm SDK verifies an explicitly requested result read from a terminal row. This closes representative navigation acceptance, not the release. Neither captured locations nor the request execute inspection automatically or grant copied/forked history fresh ownership. Legacy batches keep their original text; no full map is embedded into immutable outcomes. Compact/default inspection, curated previews and timing/work/native authority are unchanged.
178
180
 
179
- Compact spawn/asynchronous-tool launch receipts use bare block YAML with nested file-location data and identify an existing Run reuse instead of implying another launch. Full `spawn verbose=true` metadata remains JSON during the staged rollout; private details and input schemas keep their machine formats. When a complete direct file-location row is shown, it replaces the redundant session-wide map hint; missing, unavailable or omitted rows retain that optional investigation command. Exact references, expert details, shared bounds and saved completion-packet text are preserved.
181
+ Compact spawn/asynchronous-tool launch receipts use bare block YAML with nested file-location data and identify an existing Run reuse instead of implying another launch. Full `actors_run_spawn verbose=true` metadata remains JSON during the staged rollout; private details and input schemas keep their machine formats. When a complete direct file-location row is shown, it replaces the redundant session-wide map hint; missing, unavailable or omitted rows retain that optional investigation command. Exact references, expert details, shared bounds and saved completion-packet text are preserved.
180
182
 
181
183
  New automatic completion packets show direct `omitted:N chars` fields for positive tracked primary/diagnostic loss, counted in Unicode code points after privacy projection. Full retained references and older saved packet text stay unchanged. This does not yet cover every legacy summary/body or attention clipping path, nor grant broader output publication.
182
184
 
@@ -186,14 +188,14 @@ Runtime argument guidance stops at the execution handoff. Failures after an exec
186
188
 
187
189
  An exception does not guarantee an unapplied action: actor-local delivery can fail after handling is recorded, and retirement can fail after data has moved or been removed. Use existing owned evidence rather than replaying the action. The [partial-failure evidence map](docs/run-supervision.md#control-partial-failure-evidence-existing-facts-not-a-new-receipt-contract) distinguishes these paths from still-gated native stop receipts.
188
190
 
189
- Controls persist to `controls.jsonl` before transport. One token-owned lock rejects a 65th pending Control or 1 MiB rewrite before admission, fails closed on malformed or stale-generation evidence, and atomically admits one record. Canonical transitions retain a 128-terminal tail, expected-state fencing, and 4 KiB errors. Admitted nonterminal Controls never expire automatically. Every record carries immutable `run_instance_id`. `inspect view=control` reports pending capacity, saturation, stale work, journal bytes, and bounded diagnostics.
191
+ Controls persist to `controls.jsonl` before transport. One token-owned lock rejects a 65th pending Control or 1 MiB rewrite before admission, fails closed on malformed or stale-generation evidence, and atomically admits one record. Canonical transitions retain a 128-terminal tail, expected-state fencing, and 4 KiB errors. Admitted nonterminal Controls never expire automatically. Every record carries immutable `run_instance_id`. `actors_inspect view=control` reports pending capacity, saturation, stale work, journal bytes, and bounded diagnostics.
190
192
 
191
- Runtime-owned lifecycle and retention actions use the same `message` tool:
193
+ Runtime-owned lifecycle and retention actions use the same `actors_control_apply` tool:
192
194
 
193
195
  ```text
194
- message target=run:<id> action=kill
195
- message target=run:<id> action=archive
196
- message target=run:<id> action=prune input={"preserve_artifacts":true}
196
+ actors_control_apply target=run:<id> action=kill
197
+ actors_control_apply target=run:<id> action=archive
198
+ actors_control_apply target=run:<id> action=prune input={"preserve_artifacts":true}
197
199
  ```
198
200
 
199
201
  Compact Control replies report an understandable action stage instead of dumping status objects: queued/delivered is not handled; archive/prune success is complete; a kill attempt leaves full termination explicitly unconfirmed. Only a relevant evidence hint is shown (Control for actor delivery, Trace for a stop attempt, owned inventory after identity replacement); already-terminal refusal needs no routine follow-up. Use `verbose: true` on the original request for full JSON, not a repeated destructive action. Changed-owner/generation refusals also omit the replacement status from full/verbose replies; verbosity grants no extra scope. Same-identity receipt detail remains available. Actor-local dispatch exceptions still fail, conservatively leaving delivery, handling and effects unconfirmed; do not repeat automatically. Their optional follow-up starts at fresh owned inventory, not a copied stale Control id/generation. Raw causes remain Kernel-local even with verbose; oversized request targets are wholly omitted with explicit coverage under 16 KiB. This presentation/curation does not change the legacy stop engine or prove closure.
@@ -234,7 +236,7 @@ Core files:
234
236
 
235
237
  The runtime preserves owner filtering, process-identity verification, lifecycle locking, shutdown kill independent of actor-local Control capacity, terminal reconciliation, bounded captures, owned Pi sessions, path containment, and redaction. Trace/Control quotas do not constrain user-declared artifacts, repositories, media sources, complete captures, or actor-owned workload state. Restart clears generation-local Trace, Control, endpoint, execution, and terminal evidence; archive preserves the bounded tree, while prune preserves only requested artifacts.
236
238
 
237
- New completion captures in 0.57.1 keep runtime metadata above the Actor Markdown, with no service/file footer. [Rooted completion files](docs/agent-experience.md#rooted-completion-files) show one explicit path base per group, relative entries, English purpose labels and a read-first pointer. External paths have separate roots; unresolved bases stay explicit. Existing captured messages keep their original layout.
239
+ New completion captures in 0.57.1 keep runtime metadata above the Actor Markdown, with no service/file footer. [Rooted completion files](docs/agent-experience.md#rooted-completion-files) show one explicit path base per group, relative entries and a read-first pointer. Since 0.58.3, compact launch/completion navigation selects useful paths and concise admitted status instead of per-file technical dumps; full details and saved bindings remain available. External paths have separate roots; unresolved bases stay explicit. Existing captured messages keep their original layout.
238
240
 
239
241
  ## Actor Inspector
240
242
 
@@ -390,7 +390,7 @@ export function createDraftSleepScheduler(deps) {
390
390
  ...existing,
391
391
  failedStage: processed.stage ?? "result_processing",
392
392
  lastError: processed.error ?? "automatic draft review processing failed",
393
- nextAction: "message target=runtime action=review.retry input={\"scope\":\"draft\"}",
393
+ nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"draft\"}",
394
394
  phase: "processing_failed",
395
395
  processingAttempts: (existing.processingAttempts ?? 0) + 1,
396
396
  updatedAt: now().toISOString(),
@@ -401,7 +401,7 @@ export function createDraftSleepScheduler(deps) {
401
401
  ...existing,
402
402
  failedStage: processed.stage ?? "review_result",
403
403
  lastError: processed.error ?? "automatic draft reviewer failed",
404
- nextAction: "message target=runtime action=review.retry input={\"scope\":\"draft\"}",
404
+ nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"draft\"}",
405
405
  phase: "failed",
406
406
  runId: undefined,
407
407
  updatedAt: now().toISOString(),
@@ -443,7 +443,7 @@ export function createDraftSleepScheduler(deps) {
443
443
  attempts: (prior?.batchId === batch.batchId ? prior.attempts : 0) + 1,
444
444
  failedStage: "review_launch",
445
445
  lastError: error instanceof Error ? error.message : String(error),
446
- nextAction: "message target=runtime action=review.retry input={\"scope\":\"draft\"}",
446
+ nextAction: "actors_control_apply target=runtime action=review.retry input={\"scope\":\"draft\"}",
447
447
  batchId: batch.batchId,
448
448
  inputPath: batch.inputPath,
449
449
  phase: "failed",
@@ -207,6 +207,9 @@ export function createActorExtensionRuntime(pi, supervisionPorts, completionStre
207
207
  parentSession = scopeBinding;
208
208
  closeSupervision();
209
209
  recipeResolutionContextsBySession.set(sessionId, RecipeResolution.createEmptyRecipeResolutionContext(sessionId, ctx.cwd));
210
+ // Deferred compatibility dispatch needs activation only after the host binds its ports.
211
+ // Its loadout hook hides declarations; explicit later loadout restrictions still win.
212
+ pi.setActiveTools([...new Set([...pi.getActiveTools(), ...Object.keys(Tools.LEGACY_TOOL_NAMES)])]);
210
213
  ctx.ui.setWidget("zz-pi-actors-comms", undefined);
211
214
  activeRunContext = ctx;
212
215
  activeRunOwnerId = sessionId;
@@ -229,7 +232,7 @@ export function createActorExtensionRuntime(pi, supervisionPorts, completionStre
229
232
  recipeReload.watch(ctx);
230
233
  },
231
234
  registerCoreTools() {
232
- Pi.registerToolDefinitions(pi, Tools.createCoreActorToolDefinitions({
235
+ const definitions = Tools.createCoreActorToolDefinitions({
233
236
  configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
234
237
  getActiveTools: () => pi.getActiveTools(),
235
238
  getRecipeResolutionContext: () => activeRunContext
@@ -240,7 +243,9 @@ export function createActorExtensionRuntime(pi, supervisionPorts, completionStre
240
243
  handleRuntimeControl: automaticReview.handleControl,
241
244
  registryRuntime: runtime,
242
245
  setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
243
- }).map(withCurrentThinkingContext));
246
+ });
247
+ const legacy = Tools.createLegacyActorToolDefinitions(definitions);
248
+ Pi.registerToolDefinitions(pi, [...definitions, ...legacy].map(withCurrentThinkingContext));
244
249
  },
245
250
  };
246
251
  }
@@ -4,11 +4,11 @@
4
4
  * Owns LLM-facing descriptions, prompt snippets, guidelines, and parameter descriptions
5
5
  */
6
6
  export declare const REGISTER_TOOL_DESCRIPTION: string;
7
- export declare const REGISTER_TOOL_PROMPT_SNIPPET = "Persist command templates or Recipes with register_tool; use expose=false to retain without tool activation";
7
+ export declare const REGISTER_TOOL_PROMPT_SNIPPET = "Persist command templates or Recipes with actors_tool_register; use expose=false to retain without tool activation";
8
8
  export declare const REGISTER_TOOL_GUIDELINES: string[];
9
- export declare const ONBOARDING_SYSTEM_PROMPT = "pi-actors Skill routing:\n- Treat active bundled Skills as the operating authority.\n- For non-trivial pi-actors operation, diagnosis, or development, load and read the actors Skill before acting.\n- For work requiring multiple actors or subagents, additionally load and read the swarm Skill.\n- For capability-specific selection or constraints, load the owning capability Skill; actors owns generic mechanics and swarm owns multi-actor methodology.\n- Keep a Skill Recipe distinct from a registered tool and a Recipe spawn distinct from registered-tool invocation; actors owns the proof rules.\n- Treat persistence or registration as distinct from current callability; actors owns activation proof.\n- On failure or disagreement, preserve the logical Recipe identity, stop, and follow actors diagnosis; never bypass the owning Skills with copied contracts, helper paths, shell evaluation, or background-process workarounds.\n- If a capability Skill conflicts with actors about generic mechanics, follow actors and report the stale capability guidance.\n- README and docs are human-facing references, not the normal agent operating path.\n- AGENTS, source, and tests are implementation protocol and evidence; use them when changing or debugging the extension, not as substitutes for operating Skills.";
9
+ export declare const ONBOARDING_SYSTEM_PROMPT = "pi-actors Skill routing:\n- Treat active bundled Skills as the operating authority.\n- Route actors_tool_register, actors_run_spawn, actors_control_apply, and actors_inspect to the actors Skill; use canonical tool names for new calls.\n- For non-trivial pi-actors operation, diagnosis, or development, load and read the actors Skill before acting.\n- For work requiring multiple actors or subagents, additionally load and read the swarm Skill.\n- For capability-specific selection or constraints, load the owning capability Skill; actors owns generic mechanics and swarm owns multi-actor methodology.\n- Keep a Skill Recipe distinct from a registered tool and a Recipe spawn distinct from registered-tool invocation; actors owns the proof rules.\n- Treat persistence or registration as distinct from current callability; actors owns activation proof.\n- On failure or disagreement, preserve the logical Recipe identity, stop, and follow actors diagnosis; never bypass the owning Skills with copied contracts, helper paths, shell evaluation, or background-process workarounds.\n- If a capability Skill conflicts with actors about generic mechanics, follow actors and report the stale capability guidance.\n- README and docs are human-facing references, not the normal agent operating path.\n- AGENTS, source, and tests are implementation protocol and evidence; use them when changing or debugging the extension, not as substitutes for operating Skills.";
10
10
  export declare const REGISTER_TOOL_PARAM_DESCRIPTIONS: {
11
- readonly name: "Tool name in snake_case (e.g., 'transcribe')";
11
+ readonly name: "Tool name in snake_case under its functional owner's namespace (e.g., 'audio_transcribe' or 'music_player'); keep existing persisted names when updating";
12
12
  readonly description: "Describe what the tool does for the LLM. Required unless deleting; omitted updates keep the old description.";
13
13
  readonly from: "Recipe to specialize by canonical <skill>/<recipe> identity or explicit .json/.md path. Inherits async, args/types, source defaults, artifacts, Control, and runtime origins.";
14
14
  readonly defaults: "Optional caller-owned defaults. Keys and values must satisfy the effective source or command-template argument contract.";
@@ -7,18 +7,19 @@ export const REGISTER_TOOL_DESCRIPTION = "Register a persistent custom tool from
7
7
  "Use from for Recipe specialization, template for trusted commands, or draft for promotion. " +
8
8
  "Set expose=false to retain a new template/from Recipe without tool activation. " +
9
9
  "Definitions persist under ~/.pi/agent/recipes; activation is reported separately.";
10
- export const REGISTER_TOOL_PROMPT_SNIPPET = "Persist command templates or Recipes with register_tool; use expose=false to retain without tool activation";
10
+ export const REGISTER_TOOL_PROMPT_SNIPPET = "Persist command templates or Recipes with actors_tool_register; use expose=false to retain without tool activation";
11
11
  export const REGISTER_TOOL_GUIDELINES = [
12
- "Use register_tool from=<skill>/<recipe> with defaults={...} to specialize a maintained Recipe without copying its contract.",
13
- "Use register_tool template only for trusted command templates, and use register_tool draft only for captured draft promotion.",
14
- "Use register_tool expose=false to retain a new named template/from Recipe without activation; update, delete and draft promotion are unsupported in this mode.",
15
- "A register_tool retained_recipe receipt with activation=not_requested is deliberate retention, not failed activation; reuse its exact Recipe path through spawn.",
16
- "When register_tool requests tool exposure, trust callable_now and activation; persistence alone is not callability.",
17
- 'Set template=null or template="" in register_tool to delete a persisted tool.',
18
- "Set update=true in register_tool to overwrite an existing tool registration.",
12
+ "Use actors_tool_register from=<skill>/<recipe> with defaults={...} to specialize a maintained Recipe without copying its contract.",
13
+ "Use actors_tool_register template only for trusted command templates, and use actors_tool_register draft only for captured draft promotion.",
14
+ "Use actors_tool_register expose=false to retain a new named template/from Recipe without activation; update, delete and draft promotion are unsupported in this mode.",
15
+ "A actors_tool_register retained_recipe receipt with activation=not_requested is deliberate retention, not failed activation; reuse its exact Recipe path through actors_run_spawn.",
16
+ "When actors_tool_register requests tool exposure, trust callable_now and activation; persistence alone is not callability.",
17
+ 'Set template=null or template="" in actors_tool_register to delete a persisted tool.',
18
+ "Set update=true in actors_tool_register to overwrite an existing tool registration.",
19
19
  ];
20
20
  export const ONBOARDING_SYSTEM_PROMPT = `pi-actors Skill routing:
21
21
  - Treat active bundled Skills as the operating authority.
22
+ - Route actors_tool_register, actors_run_spawn, actors_control_apply, and actors_inspect to the actors Skill; use canonical tool names for new calls.
22
23
  - For non-trivial pi-actors operation, diagnosis, or development, load and read the actors Skill before acting.
23
24
  - For work requiring multiple actors or subagents, additionally load and read the swarm Skill.
24
25
  - For capability-specific selection or constraints, load the owning capability Skill; actors owns generic mechanics and swarm owns multi-actor methodology.
@@ -29,7 +30,7 @@ export const ONBOARDING_SYSTEM_PROMPT = `pi-actors Skill routing:
29
30
  - README and docs are human-facing references, not the normal agent operating path.
30
31
  - AGENTS, source, and tests are implementation protocol and evidence; use them when changing or debugging the extension, not as substitutes for operating Skills.`;
31
32
  export const REGISTER_TOOL_PARAM_DESCRIPTIONS = {
32
- name: "Tool name in snake_case (e.g., 'transcribe')",
33
+ name: "Tool name in snake_case under its functional owner's namespace (e.g., 'audio_transcribe' or 'music_player'); keep existing persisted names when updating",
33
34
  description: "Describe what the tool does for the LLM. Required unless deleting; omitted updates keep the old description.",
34
35
  from: "Recipe to specialize by canonical <skill>/<recipe> identity or explicit .json/.md path. Inherits async, args/types, source defaults, artifacts, Control, and runtime origins.",
35
36
  defaults: "Optional caller-owned defaults. Keys and values must satisfy the effective source or command-template argument contract.",
@@ -72,7 +72,7 @@ export function inventoryActiveSkillRecipeComponents(context) {
72
72
  for (const [skill, roots] of Object.entries(context.namespaces)) {
73
73
  if (roots.length > 1) {
74
74
  rejected.push({
75
- reason: `Duplicate active Skill identity ${skill} (${roots.length} active definitions); exact Recipe resolution is ambiguous. Next: inspect target=recipes view=doctor identity=${skill}/<recipe>`,
75
+ reason: `Duplicate active Skill identity ${skill} (${roots.length} active definitions); exact Recipe resolution is ambiguous. Next: actors_inspect target=recipes view=doctor identity=${skill}/<recipe>`,
76
76
  skill,
77
77
  });
78
78
  continue;
@@ -175,11 +175,11 @@ function qualifiedRecipeNameForFile(file, context) {
175
175
  }
176
176
  function assertRecipeReferencePrefixWasNotRemoved(value) {
177
177
  if (value.startsWith("std:")) {
178
- throw new Error("std: Recipe references were removed in pi-actors 0.46. Use <skill>/<recipe> or an explicit .json/.md file path. Next: inspect target=recipes view=status to identify the active owning Skill.");
178
+ throw new Error("std: Recipe references were removed in pi-actors 0.46. Use <skill>/<recipe> or an explicit .json/.md file path. Next: actors_inspect target=recipes view=status to identify the active owning Skill.");
179
179
  }
180
180
  if (value.startsWith("skill:")) {
181
181
  const identity = value.slice("skill:".length);
182
- throw new Error(`skill: Recipe references were removed in pi-actors 0.46. Use ${identity} without a prefix. Next: inspect target=recipes view=doctor identity=${identity}`);
182
+ throw new Error(`skill: Recipe references were removed in pi-actors 0.46. Use ${identity} without a prefix. Next: actors_inspect target=recipes view=doctor identity=${identity}`);
183
183
  }
184
184
  }
185
185
  function skillRecipeCandidates(value, context) {
@@ -189,14 +189,14 @@ function skillRecipeCandidates(value, context) {
189
189
  const [, skillName, recipeName] = match;
190
190
  const roots = [...(context.namespaces[skillName] ?? [])];
191
191
  if (roots.length === 0)
192
- throw new Error(`Active Skill Recipe not found: ${skillName}/${recipeName}. Owning Skill "${skillName}" is not active. Next: activate Skill ${skillName}, then inspect target=recipes view=doctor identity=${skillName}/${recipeName}`);
192
+ throw new Error(`Active Skill Recipe not found: ${skillName}/${recipeName}. Owning Skill "${skillName}" is not active. Next: activate Skill ${skillName}, then actors_inspect target=recipes view=doctor identity=${skillName}/${recipeName}`);
193
193
  if (roots.length > 1)
194
- throw new Error(`Duplicate active Skill identity ${skillName} (${roots.length} active definitions); ${skillName}/${recipeName} cannot resolve unambiguously. Next: inspect target=recipes view=doctor identity=${skillName}/${recipeName}`);
194
+ throw new Error(`Duplicate active Skill identity ${skillName} (${roots.length} active definitions); ${skillName}/${recipeName} cannot resolve unambiguously. Next: actors_inspect target=recipes view=doctor identity=${skillName}/${recipeName}`);
195
195
  const root = roots[0];
196
196
  const candidates = ["json", "md"].map((extension) => resolve(root, `${recipeName}.${extension}`));
197
197
  const existing = candidates.filter((candidate) => existsSync(candidate));
198
198
  if (existing.length === 0) {
199
- throw new Error(`Skill Recipe component not found: ${skillName}/${recipeName}; owning Skill "${skillName}" is active. Next: inspect target=recipes view=doctor identity=${skillName}/${recipeName}`);
199
+ throw new Error(`Skill Recipe component not found: ${skillName}/${recipeName}; owning Skill "${skillName}" is active. Next: actors_inspect target=recipes view=doctor identity=${skillName}/${recipeName}`);
200
200
  }
201
201
  if (existing.length > 1) {
202
202
  throw new Error(`Skill Recipe stem collision: ${skillName}/${recipeName} has both .json and .md files`);
@@ -227,7 +227,7 @@ function findOwningSkillDir(recipeFile) {
227
227
  function assertRecipeHasNoDeclaredName(raw) {
228
228
  if (!Object.hasOwn(raw, "name"))
229
229
  return;
230
- throw new Error("Recipe.name was removed in pi-actors 0.46. File-backed Recipe identity is derived from its file name. Next: remove the name field, keep the intended filename stem, then inspect target=recipes view=doctor.");
230
+ throw new Error("Recipe.name was removed in pi-actors 0.46. File-backed Recipe identity is derived from its file name. Next: remove the name field, keep the intended filename stem, then actors_inspect target=recipes view=doctor.");
231
231
  }
232
232
  function assertRuntimeRecipeValuesNotDeclared(raw) {
233
233
  const args = Array.isArray(raw.args)