@llblab/pi-actors 0.41.1 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/AGENTS.md +11 -6
  2. package/BACKLOG.md +2 -62
  3. package/CHANGELOG.md +15 -0
  4. package/README.md +22 -4
  5. package/dist/index.js +25 -121
  6. package/dist/lib/async-runs.d.ts +25 -5
  7. package/dist/lib/async-runs.js +136 -47
  8. package/dist/lib/automatic-review-runtime.d.ts +18 -0
  9. package/dist/lib/automatic-review-runtime.js +96 -0
  10. package/dist/lib/draft-consolidation-transaction.d.ts +65 -0
  11. package/dist/lib/draft-consolidation-transaction.js +610 -0
  12. package/dist/lib/draft-consolidation.d.ts +35 -0
  13. package/dist/lib/draft-consolidation.js +126 -0
  14. package/dist/lib/draft-review.d.ts +56 -0
  15. package/dist/lib/draft-review.js +254 -0
  16. package/dist/lib/draft-sleep.d.ts +65 -0
  17. package/dist/lib/draft-sleep.js +468 -0
  18. package/dist/lib/file-state.d.ts +8 -1
  19. package/dist/lib/file-state.js +115 -18
  20. package/dist/lib/inspector-actions.d.ts +16 -0
  21. package/dist/lib/inspector-actions.js +57 -0
  22. package/dist/lib/inspector-command.d.ts +7 -0
  23. package/dist/lib/inspector-command.js +37 -0
  24. package/dist/lib/inspector-overlay.d.ts +20 -3
  25. package/dist/lib/inspector-overlay.js +275 -74
  26. package/dist/lib/inspector.d.ts +9 -0
  27. package/dist/lib/inspector.js +48 -0
  28. package/dist/lib/observability.d.ts +1 -0
  29. package/dist/lib/observability.js +11 -1
  30. package/dist/lib/paths.d.ts +7 -0
  31. package/dist/lib/paths.js +28 -0
  32. package/dist/lib/recipes-discovery.js +32 -24
  33. package/dist/lib/recipes-usage.d.ts +18 -6
  34. package/dist/lib/recipes-usage.js +445 -34
  35. package/dist/lib/review-control.d.ts +14 -0
  36. package/dist/lib/review-control.js +111 -0
  37. package/dist/lib/review-diagnostics.d.ts +11 -0
  38. package/dist/lib/review-diagnostics.js +148 -0
  39. package/dist/lib/review-projection.d.ts +14 -0
  40. package/dist/lib/review-projection.js +170 -0
  41. package/dist/lib/run-ui-runtime.d.ts +18 -0
  42. package/dist/lib/run-ui-runtime.js +123 -0
  43. package/dist/lib/runs-artifacts.d.ts +1 -1
  44. package/dist/lib/runs-artifacts.js +1 -1
  45. package/dist/lib/runs-control.d.ts +8 -2
  46. package/dist/lib/runs-control.js +23 -6
  47. package/dist/lib/runs-identity.d.ts +1 -1
  48. package/dist/lib/runs-identity.js +1 -1
  49. package/dist/lib/runs-index.d.ts +11 -2
  50. package/dist/lib/runs-index.js +46 -23
  51. package/dist/lib/runs-mailbox.d.ts +1 -1
  52. package/dist/lib/runs-mailbox.js +1 -1
  53. package/dist/lib/runs-messages.d.ts +1 -1
  54. package/dist/lib/runs-messages.js +1 -1
  55. package/dist/lib/runs-outbox.d.ts +1 -1
  56. package/dist/lib/runs-outbox.js +1 -1
  57. package/dist/lib/runs-ownership.d.ts +1 -1
  58. package/dist/lib/runs-ownership.js +1 -1
  59. package/dist/lib/runs-parent-teardown.d.ts +51 -0
  60. package/dist/lib/runs-parent-teardown.js +172 -0
  61. package/dist/lib/runs-process.d.ts +1 -1
  62. package/dist/lib/runs-process.js +1 -1
  63. package/dist/lib/runs-retention.d.ts +1 -1
  64. package/dist/lib/runs-retention.js +1 -1
  65. package/dist/lib/runs-start.d.ts +5 -3
  66. package/dist/lib/runs-start.js +6 -48
  67. package/dist/lib/runs-status.d.ts +5 -3
  68. package/dist/lib/runs-status.js +4 -6
  69. package/dist/lib/runtime.d.ts +7 -1
  70. package/dist/lib/runtime.js +32 -18
  71. package/dist/lib/tool-review-lineage-transaction.d.ts +27 -0
  72. package/dist/lib/tool-review-lineage-transaction.js +597 -0
  73. package/dist/lib/tool-review-lineage.d.ts +24 -0
  74. package/dist/lib/tool-review-lineage.js +98 -0
  75. package/dist/lib/tool-review-scheduler.d.ts +80 -0
  76. package/dist/lib/tool-review-scheduler.js +494 -0
  77. package/dist/lib/tool-review-transaction.d.ts +50 -0
  78. package/dist/lib/tool-review-transaction.js +362 -0
  79. package/dist/lib/tool-review.d.ts +56 -0
  80. package/dist/lib/tool-review.js +197 -0
  81. package/dist/lib/tools-inspect.js +26 -3
  82. package/dist/lib/tools-local.js +4 -2
  83. package/dist/lib/tools-message.d.ts +1 -0
  84. package/dist/lib/tools-message.js +29 -17
  85. package/dist/lib/tools-spawn.js +4 -1
  86. package/dist/lib/tools.d.ts +1 -0
  87. package/dist/lib/tools.js +1 -0
  88. package/dist/recipes/draft-review.json +24 -0
  89. package/dist/recipes/tool-review.json +24 -0
  90. package/dist/scripts/release-gates.mjs +165 -0
  91. package/dist/skills/actors/SKILL.md +9 -8
  92. package/dist/skills/swarm/SKILL.md +1 -1
  93. package/docs/actor-inspector.md +20 -11
  94. package/docs/async-runs.md +9 -1
  95. package/docs/recipe-library.md +7 -3
  96. package/docs/template-recipes.md +4 -11
  97. package/docs/tool-registry.md +11 -4
  98. package/index.ts +27 -142
  99. package/lib/async-runs.ts +218 -62
  100. package/lib/automatic-review-runtime.ts +135 -0
  101. package/lib/draft-consolidation-transaction.ts +821 -0
  102. package/lib/draft-consolidation.ts +181 -0
  103. package/lib/draft-review.ts +325 -0
  104. package/lib/draft-sleep.ts +576 -0
  105. package/lib/file-state.ts +143 -19
  106. package/lib/inspector-actions.ts +79 -0
  107. package/lib/inspector-command.ts +54 -0
  108. package/lib/inspector-overlay.ts +325 -91
  109. package/lib/inspector.ts +72 -0
  110. package/lib/observability.ts +14 -1
  111. package/lib/paths.ts +43 -0
  112. package/lib/recipes-discovery.ts +34 -26
  113. package/lib/recipes-usage.ts +569 -40
  114. package/lib/review-control.ts +137 -0
  115. package/lib/review-diagnostics.ts +164 -0
  116. package/lib/review-projection.ts +200 -0
  117. package/lib/run-ui-runtime.ts +153 -0
  118. package/lib/runs-artifacts.ts +1 -1
  119. package/lib/runs-control.ts +49 -5
  120. package/lib/runs-identity.ts +1 -1
  121. package/lib/runs-index.ts +57 -21
  122. package/lib/runs-mailbox.ts +1 -1
  123. package/lib/runs-messages.ts +1 -1
  124. package/lib/runs-outbox.ts +1 -1
  125. package/lib/runs-ownership.ts +1 -1
  126. package/lib/runs-parent-teardown.ts +257 -0
  127. package/lib/runs-process.ts +1 -1
  128. package/lib/runs-retention.ts +1 -1
  129. package/lib/runs-start.ts +12 -68
  130. package/lib/runs-status.ts +12 -8
  131. package/lib/runtime.ts +34 -17
  132. package/lib/tool-review-lineage-transaction.ts +881 -0
  133. package/lib/tool-review-lineage.ts +145 -0
  134. package/lib/tool-review-scheduler.ts +635 -0
  135. package/lib/tool-review-transaction.ts +563 -0
  136. package/lib/tool-review.ts +270 -0
  137. package/lib/tools-inspect.ts +33 -3
  138. package/lib/tools-local.ts +8 -2
  139. package/lib/tools-message.ts +45 -30
  140. package/lib/tools-spawn.ts +8 -1
  141. package/lib/tools.ts +5 -0
  142. package/package.json +3 -2
  143. package/recipes/draft-review.json +24 -0
  144. package/recipes/tool-review.json +24 -0
  145. package/scripts/release-gates.mjs +165 -0
  146. package/skills/actors/SKILL.md +9 -8
  147. package/skills/swarm/SKILL.md +1 -1
package/AGENTS.md CHANGED
@@ -40,11 +40,12 @@ Pi host
40
40
  - `identity.ts`, `paths.ts`, `config.ts`: names, paths, and persistence.
41
41
  - `registry.ts`, `runtime.ts`: register/update/delete, load/conflict/registration coordination.
42
42
  - `execution.ts`, `execution-output.ts`, `limits.ts`: registered-tool execution and bounded output.
43
- - `recipes-references.ts`, `recipes-discovery.ts`, `recipes-usage.ts`: recipe graph, discovery, and usage metadata.
43
+ - `recipes-references.ts`, `recipes-discovery.ts`, `recipes-usage.ts`, `draft-review.ts`, `draft-sleep.ts`, `tool-review.ts`, `tool-review-scheduler.ts`, `tool-review-transaction.ts`, `tool-review-lineage.ts`, `tool-review-lineage-transaction.ts`, `review-projection.ts`, `review-diagnostics.ts`, `review-control.ts`, `draft-consolidation.ts`, `draft-consolidation-transaction.ts`: recipe graph/discovery, automatic review admission, journaled filesystem and lineage execution/recovery, and bounded diagnostics.
44
44
  - `async-runs.ts`: detached run lifecycle facade; `runs-*` subdomains own artifacts, start guards, status, indexes, inbox/outbox, delivery, process control, and retention internals.
45
45
  - `runtime-notifier.ts`, `mailbox-loop.ts`: wake notifications and reusable run/branch mailbox worker loops.
46
46
  - `messages.ts`, `rooms.ts`, `recipes-context.ts`, `session-evidence.ts`, `inspector.ts`, `inspector-overlay.ts`, `observability.ts`: addressed message protocol, rooms, recipe prompt context, bounded/redacted child-session turns, inspector evidence/navigation, keyboard-driven overlay UI, and ambient run status.
47
47
  - `prompts.ts`, `temp.ts`: LLM-facing copy and temp cleanup.
48
+ - `automatic-review-runtime.ts`, `run-ui-runtime.ts`, `inspector-command.ts`: session-bound review composition, ambient run-observability lifecycle, and Inspector host-command adapters kept outside the entrypoint.
48
49
  - `tools.ts`: public tool family composition and reserved tool names.
49
50
  - `tools-message.ts`: public `message` tool behavior, including run controls, branch/room routing, tool actor invocation, and delivery feedback.
50
51
  - `tools-inspect.ts`: public `inspect` tool behavior, including recipe registry, room/session/tool/run views, and observation formatting.
@@ -68,7 +69,7 @@ Pi host
68
69
 
69
70
  ## Operating Principles
70
71
 
71
- - Prefer explicit operator action over silent user-config rewrites.
72
+ - Automatic recipe evolution remains silent but mechanically fenced: no-tools reviewers select lifecycle/name operations from value-free structural projections without receiving recipe bodies, template/default values, authored prose, canonical names, draft basenames, raw content hashes, or filesystem paths; batch-local opaque occurrence IDs and equality-only content groups preserve decision correlation and deduplication, while sensitive active recipes stay outside model review as defense in depth, deterministic executors derive unchanged recipes from separate trusted captures, and safe-session activation separates approval from live registry mutation. `PI_ACTORS_AUTOMATIC_REVIEW=off` is the explicit startup opt-out and must disable both scheduling and safe-boundary activation while remaining visible in runtime status. Automatic portfolio review may keep, demote, rename, or deduplicate canonically identical recipes; replacement, split, and executable contract changes require explicit operator authoring. Transactions must hold canonical source/target locks, enforce compare-and-swap preconditions, preserve complete recipes, quarantine before commit, journal process-crash recovery phases, validate recovery CAS/hashes, and derive evidence from runtime outcomes. Prefer `register_tool draft=...` for a fenced manual single-draft override; deliberate filesystem promotion remains valid but may invalidate and defer an already captured batch.
72
73
  - Keep published documentation portable: use `~`, `<repo>`, or relative paths instead of machine-local absolute paths.
73
74
  - Preserve runtime output discipline because tool output flows directly into agent context. Tool result/error text contributes exactly one leading line break; Pi's renderer contributes the other break after the call header, producing one empty separator row without doubled gaps.
74
75
  - Optimize every actor-facing surface for signal over volume: prefer compact state-backed hints and fewer concepts over broad explanatory prose or speculative guidance.
@@ -102,7 +103,7 @@ Pi host
102
103
  ## Runtime Contract
103
104
 
104
105
  - Register trusted command templates with placeholder-derived args, progressive typed arg declarations, inline/default/`??`/ternary fallback, and split-first command argv construction.
105
- - Serialize extension-authored recipe mutations with the canonical-path file lock across the complete check/read/write/runtime-update window; keep usage telemetry in locked `.usage/<recipe-filename>.json` sidecars so metadata cannot overwrite authored recipes, and do not replace keyed locking with a broad registry lock.
106
+ - Serialize extension-authored recipe mutations with canonical-path locks across each complete check/read/write/runtime-update window; keep usage and lineage evidence in the locked `.usage/recipes/<recipe-name>.json` ledger plus path index so metadata cannot overwrite authored recipes, and do not replace keyed recipe locking with a broad registry lock. Launch accounting is the narrow exception: it briefly shares the portfolio transaction’s canonical recipe-root fence before taking index/ledger locks, so quarantine cannot make an already-authorized launch disappear; a source that changed before that fence rejects the stale launch and asks for reload.
106
107
  - Keep command templates synchronous and portable; `async: true` is the detached run switch.
107
108
  - Preserve node controls: `when`, positive `timeout`, `delay`, bounded `retry`, `failure`, and `recover` cleanup.
108
109
  - Persist every async command's complete byte-exact stdout/stderr under command- and retry-specific run-state paths while keeping returned tails bounded and pipeline stdin complete.
@@ -114,8 +115,8 @@ Pi host
114
115
  ## Recipes And Registry
115
116
 
116
117
  - `~/.pi/agent/recipes/*.json` is executable muscle memory: recipes there become persistent tools by location.
117
- - Preserve filename identity, atomic writes, explicit operator-gated changes, and local transportability.
118
- - Recipe live reload must watch the parent when the user recipe root is absent, switch to the root watcher when it appears, and rearm after deletion/rename without polling or duplicate watcher ownership.
118
+ - Preserve filename identity, atomic writes, explicit operator-gated changes, and local transportability. Extension-authored draft creation must take the same canonical per-path mutation lock used by consolidation so source compare-and-swap and quarantine cannot race a writer.
119
+ - Recipe live reload must watch the parent when the user recipe root is absent, switch to the root watcher when it appears, and rearm after deletion/rename without polling or duplicate watcher ownership. Every callback must compare its exact watcher instance before closing, replacing, notifying, or scheduling so delayed callbacks from closed generations cannot affect the current watcher.
119
120
  - Packaged/ad hoc recipes outside the agent root are components, not user tools.
120
121
  - Register existing recipes by importing them from the user-root wrapper and using a `{ "name": "alias" }` template node; do not duplicate a ready recipe's script command, defaults, mailbox, or artifact contract in the wrapper.
121
122
  - Skill-owned scripts must be exposed through skill-owned recipes first. If a local tool needs that capability, import the skill recipe via `{agent}/skills/<skill>/recipes/<recipe>.json` instead of calling `{agent}/skills/<skill>/scripts/*` directly.
@@ -141,9 +142,13 @@ Pi host
141
142
  - Keep tail truncation, full-output temp files, failure formatting, and centralized limits intact.
142
143
  - Published docs must not include machine-local absolute paths.
143
144
  - Any view scanning run directories must apply coordinator/session ownership filters before exposing summaries or previews.
145
+ - Actor Inspector remains evidence-first; its `Kill` action is available only for a focused owned running run, requires in-overlay confirmation, revalidates exact ownership/status at action time, routes through canonical `control.kill`, and renders bounded success/failure feedback without direct process signaling.
144
146
  - Direct branch messages are active inbox queues; guard branch-local append/status rewrites with the branch inbox lock and keep claim/handled/failed transitions tested.
145
147
  - Run-state launch and destructive retention require the runtime ownership marker bound to the canonical directory and run id; reject non-run directories, missing/mismatched markers, and symlink aliases rather than trusting `run.json`.
146
- - Runner lifecycle and destructive process controls require the persisted cross-platform process identity proof (start time, command, and cwd where available); dead, mismatched, or unsupported proofs stay distinct and fail closed rather than degrading to pid liveness.
148
+ - Runner lifecycle and destructive process controls require the persisted cross-platform process identity proof (start time, command, and cwd where available), revalidated at authorization and immediately before signaling; dead, mismatched, or unsupported proofs stay distinct and fail closed rather than degrading to pid liveness. On Unix, only process-group `ESRCH` followed by another matching identity proof permits exact-pid fallback. Keep the residual post-read OS PID/PGID reuse window explicit because Node lacks one portable identity-stable group handle.
149
+ - Automatic draft review may schedule one silent review after ordinary `agent_end` only when twelve drafts exist and no actor is running; it must snapshot an exact batch, leave newer drafts for later, suppress routine terminal/outbox delivery, and never mutate recipes from the reviewer process.
150
+ - Automatic tool review seeds zero-call lineage without fabricating launches, admits only current non-sensitive revisions lacking a review fingerprint, captures exactly thirty-six oldest eligible active user tools, and uses the same silent post-turn/active-actor boundary. Completed output becomes a size-bounded immutable approval only after result validation plus source and target CAS; approval must not mutate the live registry. Approved filesystem mutation uses intent-before-mutation journaling and source quarantine, composition invokes it only during `session_start` before runtime tool loading, persists `lineage_pending`, and must finalize lineage before quarantine cleanup. Failed cycles persist bounded stage/error/remediation evidence; explicit `review.retry`/`review.reset` messages to `tool:pi-actors` may reset counters or disposable state, but reset must reject approved/transaction/lineage evidence that requires roll-forward recovery. Draft retry must preserve the original reviewer run once a transaction journal exists and derive lineage/evidence from that authenticated journal plan, never from later reviewer output.
151
+ - Parent-session teardown runs on every Pi `session_shutdown`, never ordinary `agent_end`: select discovered readable persisted `running` runs with the exact retiring session `ownerId`, carry immutable `run_instance_id` through canonical `control.kill`, serialize control against same-directory restart, fence teardown evidence to that generation, continue across partial failures, and leave terminal, ambiguous, changed-generation, or other-session runs untouched. Use unbounded teardown discovery, count unreadable/corrupt state as failures, and persist one bounded shutdown summary outside individual runs. Descendant Pi sessions remain separate exact owners and rely on their own shutdown hooks; hard termination keeps OS/manual orphan recovery as an honest boundary.
147
152
  - Room/branch provenance checks should validate that accepted `from` addresses belong to the addressed run.
148
153
 
149
154
  ## Coordination And Lifecycle
package/BACKLOG.md CHANGED
@@ -1,67 +1,7 @@
1
1
  # Project Backlog
2
2
 
3
- ## Implementation Boundary
4
-
5
- Work only inside `pi-actors`: strengthen the current Pi extension and local actor kernel. Do not split work into an external transportable standard, do not design `mcp-actors`, and do not change public positioning.
6
-
7
- Current carrying contour:
8
-
9
- - `spawn`, `message`, and `inspect` stay the durable public verbs.
10
- - Async run state stays file-backed and inspectable.
11
- - Tool exposure stays recipe-based and location-derived from `~/.pi/agent/recipes`.
12
- - Durable inbox and outbox files remain canonical intent and message state.
13
- - Rooms, rosters, and branch inboxes remain local coordination memory.
14
- - Wake notifications remain advisory acceleration, not the queue.
15
- - Operator-facing observability stays explicit and bounded.
16
-
17
- Core invariant:
18
-
19
- ```text
20
- Recipe = portable executable capability.
21
- Run = addressable lifecycle instance.
22
- Message = typed semantic envelope.
23
- Mailbox = durable intent queue.
24
- Wake = advisory acceleration.
25
- Room = shared local coordination memory.
26
- Inspect = intentional observation.
27
- Artifact = durable result.
28
- ```
29
-
30
- Non-goals:
31
-
32
- - Distributed workers.
33
- - Generic scheduler DSL.
34
- - Cloud sync.
35
- - External transport standard.
36
- - MCP implementation.
37
- - Arbitrary subrooms.
38
- - Heavy broker abstraction.
39
-
40
3
  ## Open Work
41
4
 
42
- ### Manual draft-memory consolidation
43
-
44
- - [ ] Add a manually invoked command that launches an agent-led consolidation cycle over `~/.pi/agent/recipes/drafts`. The cycle must inventory and classify every draft, propose a complete `promote`, `merge`, or `discard` plan, require explicit operator confirmation before mutations, normalize approved reusable capabilities into active recipe-backed tools under `~/.pi/agent/recipes`, and remove every handled source so the drafts directory finishes empty. It must never run automatically or promote tools silently; preserve evidence for each decision and add regressions for plan-only, confirmation, promotion, merge, discard, failure recovery, and empty-directory completion.
45
-
46
- ## Backlog Curation Rules
47
-
48
- - Completed work belongs in `CHANGELOG.md`, not in `BACKLOG.md`.
49
- - File length alone is not a domain-split trigger: ~1000-line cohesive domain files are acceptable when ownership is clear.
50
- - Consider splitting only when a file crosses roughly 2000 lines, mixes real ownership zones, or hides a clearer domain boundary.
51
- - Prefer semantic compression before file splitting: fewer public nouns, consistent outcomes, compact diagnostics, and domain-owned constants/helpers.
52
- - Preserve signal/noise balance: feedback should be state-backed, compact, and action-shaped; do not add advisory prose just because a surface exists.
53
-
54
- The backlog is intentionally pruned to the 20% of work most likely to deliver 80% of value for `pi-actors` as a local actor kernel. Bias toward consolidation, smaller public surface area, and reliability over new feature breadth.
55
-
56
- ## Explicitly Deferred
57
-
58
- These are valid ideas but not current focus. Reintroduce only with concrete evidence from real actor workflows.
5
+ ### Windows filesystem fencing verification
59
6
 
60
- - Spawn preflight mode: useful later, but lower value than resilient inspect and mailbox-loop consolidation.
61
- - Run restart/reattach policy: risky for isolation; defer until corruption recovery and protocol fixtures are stronger.
62
- - Cross-session force kill or attach/adopt/reparent: useful later, but ownership policy should not change until observability makes current boundaries clear.
63
- - Actor address helper CLI: keep diagnostics improving opportunistically inside existing parser/tests.
64
- - Golden flow docs and flow conformance runner: useful after the diagnostic and promotion surfaces are stable.
65
- - Host-level tool unregistration: blocked on host API support.
66
- - Branch-local checkpoint semantics: wait for real collaborative branch-runner experiments.
67
- - Actor recipe feedback loop: keep advisory and operator-gated after real runs produce evidence.
7
+ - [ ] Add Windows CI and native NTFS regressions for consolidation root identity, directory junction/reparse-point substitution, lifecycle locks, and recovery without requiring privileged symbolic-link creation. Keep bigint device/inode capture, document filesystems that report weak or zero file identity, and evaluate a native handle-relative mutation layer only if real Windows evidence justifies expanding beyond Node’s portable process-crash and trusted-state-tree contract.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.42.0: Automatic Recipe Evolution and Recipe-first Inspector
6
+
7
+ - `Recipe-first Inspector`: The Inspector now opens on a bounded, redacted `Recipe` document for the selected owned run, showing authored identity, resolved launch template and values, composition, policy, mailbox, and artifacts without following mutable external recipe paths. `Messages` and `Turns` remain adjacent tabs; Turns use one scrollable detail level without duplicated recipe context, and documents/timelines/details support arrows plus PageUp/PageDown. Nested values render as compact indented text with label-first, separator-aware wrapping and consistent lowercase hints. Recipe documents retain ↑-at-top/← navigation to tabs, and ← now also returns a scrolled Messages or Turns list directly to its tabs without resetting the selected row. Turns retain one cached evidence snapshot while list/detail navigation remains active, eliminating repeated full session-file parsing on every arrow key while preserving periodic refresh when focus returns to higher-level controls.
8
+ - `Pre-release Surface Compression`: Automatic-review persistence remains intentionally unversioned until a public compatibility boundary exists; transitional UUID-ledger and filename-sidecar migrations are removed. Canonical recipe names own lineage identity, hashes own content/CAS identity, revisions describe executable history, and operation-local UIDs remain confined to fencing and correlation.
9
+ - `Automatic Draft Evolution`: Twelve eligible inline-spawn drafts trigger one silent no-tools review of a value-free structural projection after the foreground turn and active actors finish; canonical names, draft basenames, raw hashes, recipe bodies, template/default values, authored prose, and filesystem paths remain in the separate trusted capture; batch-local opaque occurrence IDs and equality-only content groups preserve decision correlation without cross-batch identity disclosure. Every captured draft receives one quota-free `promote` or `discard` decision without recipe content; the deterministic executor derives promotions from exact immutable sources, rejects incomplete, stale, unsafe, secret-bearing, temporary-path, duplicate, or colliding outcomes, atomically applies the batch, preserves newer drafts, and records bounded garbage-collection evidence. `register_tool draft=...` remains the preferred fenced single-draft override, while deliberate filesystem promotion stays valid and may defer a captured batch.
10
+ - `Automatic Tool Portfolio Evolution`: Thirty-six eligible non-sensitive active recipe revisions trigger a separate no-tools review of the same value-free structural projection; `PI_ACTORS_AUTOMATIC_REVIEW=off` explicitly disables reviewer scheduling and safe-boundary activation, with the effective policy visible in runtime status. Usage, adaptability, duplication, safety, contract quality, and likely future value inform quota-free `keep`, unchanged-source rename (`evolve`), unchanged-source `demote`, or identical-source `merge` decisions; reviewers cannot return recipe content, while `replace`, `split`, and executable contract changes require explicit operator authoring. Mechanically validated immutable approval plans remain non-mutating until the next safe `session_start` activation boundary.
11
+ - `Deterministic Transactions And Recovery`: Draft and portfolio mutations use exact source/target CAS, authenticated plan-derived operation graphs, root identity and symlink/path containment, intent-before-mutation journals, source quarantine, complete recipe validation, and idempotent rollback/roll-forward recovery. Cross-session admission and activation serialize through canonical state locks; launch accounting shares the portfolio mutation fence so quarantine cannot lose usage evidence, while already-stale loaded sources reject and request reload. Malformed/missing reviewer state and processing failures stop after bounded retries, and hard crashes at every transaction/lineage transition converge without overwriting concurrent edits.
12
+ - `Recipe Lineage, Revisions, And Rollback`: Canonical name-and-priority ledgers preserve lifetime usage, launch-kind counters, former names/paths, review epochs, and transition history across rename, revision, promotion, demotion, merge, and split; replacement starts new meaning. Revision-local counters restart on executable fingerprint changes, unchanged automatic demotions remain in cooldown, and evolve/replace retain a bounded 32-slot snapshot ring. The internal rollback recovery primitive now journals exact recipe and lineage writes before mutation, CAS-validates both, and rolls post-write failures forward idempotently without resetting lifetime usage; 0.42 does not expose a public operator rollback action.
13
+ - `Review Diagnostics And Recovery`: `inspect target=recipes view=reviews` exposes bounded read-only draft/tool phases, action counts, garbage collection, lineage/revision usage, demotion and rollback provenance, transaction state, retained snapshots, and actionable failed stage/error/next-action evidence without starting reviewers or generating foreground turns. Explicit `review.retry` and safe `review.reset` messages to `tool:pi-actors` recover bounded failures while preserving approved transaction/lineage evidence that must roll forward. Draft retry with an existing journal resumes the original reviewer run and authenticated transaction decisions, preventing later reviewer output from splitting committed recipes and lineage.
14
+ - `Generation-fenced Run Control`: Every async start receives an immutable run generation. Inspector `k kill`, parent-session teardown, cancellation, and replacement-sensitive controls compare exact owner/generation inside the canonical lifecycle lock before signaling; stale, terminal, ambiguous, unsupported-proof, or replacement runs fail closed. Session shutdown discovers all readable exact-owner running actors, continues across partial failures, and persists a bounded survivor summary while descendant Pi sessions remain separately owned.
15
+ - `Lock, Watcher, And Signal Safety`: Canonical-path mutation locks use token-owned reclaim/release boundaries with deterministic sibling-process contention and dead-owner recovery, preventing stale owners or concurrent reclaimers from deleting replacement locks. Recipe watchers fence callbacks to their exact generation, and process control revalidates stable identity immediately before group signaling and after `ESRCH`; the remaining host-level PID/PGID reuse window and native Windows NTFS junction verification remain explicit platform boundaries.
16
+ - `Composition Root Compression`: Reduced `index.ts` from 389 to 118 lines by moving automatic-review scheduler/launch/control wiring, ambient run watcher/reconciliation/teardown lifecycle, and Inspector command adaptation into focused domains. The entrypoint now retains host event registration, dependency wiring, tool wrapping, and session context while low-level actor/review operations remain behind named runtime contracts.
17
+ - `Selective Recipe Installation`: Replaced bulk library-copy guidance with explicit selected-recipe or thin-wrapper installation. Internal `draft-review.json` and `tool-review.json` selectors remain runtime-owned components rather than user-installed callable tools.
18
+ - `Validation`: Primary CI release validation now includes protocol conformance, high-severity dependency audit, strict source Domain DAG, an exact temporary-index diff/secret/public-path hygiene pass, and ABCd root/routing/link checks; the local peer test lock advances Pi from `0.75.3` to `0.80.10`, clearing the prior audit findings. Passed 631 tests, 171 conformance tests, 63 packaged-recipe QA checks, a clean `npm audit`, TypeScript, extension import, package build/dry-run for `0.42.0`, and the reproducible supplemental release gates.
19
+
5
20
  ## 0.41.1: Actor Inspector and Delivery Hotfix
6
21
 
7
22
  - `Terminal Delivery`: Added bounded ten-second terminal reconciliation and watcher rearm so owned terminal follow-ups converge without reload when file watching misses or fails. Delivery still uses Pi follow-ups with owner filtering, `triggerTurn`, no historical outbox replay, and the existing at-least-once handled-marker contract; routine run-directory removal stays quiet while real watcher degradation remains diagnostic.
package/README.md CHANGED
@@ -129,11 +129,13 @@ Routing comes from `to`, actor ownership, and runtime policy. `type` describes i
129
129
  | Message protocol | Typed envelopes across run, tool, branch, room, coordinator, and session targets | Continue, approve, kill, or route work without restarting actors |
130
130
  | Rooms and rosters | Run-local group timeline with actor join/leave, contacts, previews, and branch-aware delivery | Coordinate multiple subagents under one visible run |
131
131
  | Registry and recipe doctor | Discovered tools, overrides, drafts, invalid recipes, and advisory risk labels | Audit local capability memory before using or promoting it |
132
- | Draft promotion | Captured ad hoc spawn patterns can become explicit recipes after operator approval | Turn successful improvisation into durable local tools |
132
+ | Draft promotion | Captured ad hoc spawn patterns can become explicit recipes through one operator-selected promotion or bounded automatic unchanged-source review | Turn successful improvisation into durable local tools without granting a reviewer executable-authoring authority |
133
133
  | Review/swarm recipes | Maintained packaged pipelines with preflight, marked semantic evidence, quorum knobs, model/thinking inheritance, one-turn prompt-file transport, and diagnostics | Delegate reviews without rebuilding fanout commands |
134
- | Actor inspector | One manual `Messages or Turns → filtered timeline → detail` overlay for owned actor messages and persisted subagent sessions, with bounded/redacted prompt, model, thinking, tool, result, usage, and provenance evidence | Follow actor traffic and every persisted subagent turn without exposing another session or inventing hidden reasoning |
134
+ | Actor inspector | One manual `Recipe → Messages or Turns → timeline → one detail level` overlay for owned actor evidence, plus confirmed `K` → `control.kill` for the selected running run | Understand the selected recipe and launch, follow actor traffic and persisted subagent turns, or explicitly terminate one owned actor without exposing another session or signaling directly |
135
135
  | Packaged recipe QA | Installed-package-safe checks for helper paths, mailbox contracts, platform scope, artifacts, and recipe structure | Keep shipped actor components executable and diagnosable |
136
136
 
137
+ Detached actors survive ordinary agent turns. When their owning Pi session quits, reloads, or is replaced, pi-actors scans run state without the ordinary index depth cap and attempts canonical `control.kill` for each readable still-running exact-owner run. Destructive control is fenced by immutable run generation and serialized against state-directory restart; terminal, ambiguous, changed-generation, and other-session runs remain untouched. Unreadable/corrupt state becomes an explicit failure and every shutdown writes a bounded summary under the run root; actors owned by descendant Pi sessions remain outside the exact-owner contract and require their own shutdown hook or manual OS recovery.
138
+
137
139
  ## Golden path: from local workflow to actor memory
138
140
 
139
141
  Create a reusable async actor recipe in the user recipe root:
@@ -198,7 +200,8 @@ Rules:
198
200
  - Same-id JSON recipes shadow Markdown recipes in the same priority layer.
199
201
  - Packaged recipes are standard-library components, not automatically installed operator policy.
200
202
  - Draft recipes in `~/.pi/agent/recipes/drafts/` are replayable memory, not active tools.
201
- - `register_tool` creates, updates, lists, deletes, or explicitly promotes draft recipe files through the normal agent interface.
203
+ - `register_tool` creates, updates, lists, deletes, or explicitly promotes one draft recipe file through the normal agent interface.
204
+ - Batch draft consolidation is automatic and silent. Prefer fenced `register_tool draft=...` for one early promotion; deliberate move/copy into the recipe root remains valid but may defer an already captured batch.
202
205
 
203
206
  Register a foreground tool:
204
207
 
@@ -223,14 +226,29 @@ Promote a captured draft only after explicit operator approval:
223
226
  register_tool name=docs_review draft=~/.pi/agent/recipes/drafts/spawned-run.json
224
227
  ```
225
228
 
229
+ Successful inline spawns accumulate draft memory automatically. When twelve drafts exist, pi-actors waits for the foreground turn and active actors to finish, captures an exact immutable batch, and attaches a value-free structural projection to a silent reviewer with no tools. The projection replaces canonical names, draft basenames, and raw hashes with batch-local opaque occurrence IDs and equality-only content groups, and omits recipe bodies, template text, defaults, authored prose, and filesystem paths; the reviewer selects one quota-free `promote` or `discard` decision per source but cannot return recipe content. The executor derives every promotion from the exact captured source, applies the batch through its journaled transaction, garbage-collects discarded drafts, and leaves newer drafts for the next cycle.
230
+
231
+ Automatic review and mutation remain separate trust boundaries: reviewers receive only value-free structural/usage evidence and have neither filesystem tools, raw recipe access, mutation tools, nor executable-authoring authority. Active-tool portfolio review excludes recipes detected as sensitive and can only select `keep`, unchanged-source rename (`evolve`), unchanged-source `demote`, or deduplication of canonically identical recipes (`merge`). `replace`, `split`, and any executable contract change require an explicit operator-authored recipe mutation through the existing recipe/register surface. Deterministic executors revalidate the exact batch, source and target hashes, complete captured recipes, quarantine state, and journals before committing or recovering internally. The runtime exposes no separate manual batch command.
232
+
226
233
  Inspect the registry:
227
234
 
228
235
  ```text
229
236
  inspect target=recipes view=status
237
+ inspect target=recipes view=reviews
230
238
  inspect target=recipes view=summary verbose=true
231
239
  inspect target=tool:pi-actors view=triage
232
240
  ```
233
241
 
242
+ Failed automatic cycles retain a bounded failed stage, error, retry count, and exact next action. Retry the same immutable scope through the reserved runtime actor; reset only disposable failed/completed admission state:
243
+
244
+ ```text
245
+ message to=tool:pi-actors type=review.retry body={"scope":"draft"}
246
+ message to=tool:pi-actors type=review.retry body={"scope":"tool"}
247
+ message to=tool:pi-actors type=review.reset body={"scope":"draft"}
248
+ ```
249
+
250
+ Draft retry with an existing transaction journal resumes the original reviewer run and uses the journal’s authenticated decisions for lineage/evidence; it never launches a second reviewer over already-committed filesystem state. Tool review recovery that already has approved/transaction evidence cannot be reset; retry preserves that evidence and may require `/reload` for the safe `session_start` activation boundary.
251
+
234
252
  ## Command templates
235
253
 
236
254
  A command template is the launch substrate. It can be a string, a sequence, or a composed graph.
@@ -298,7 +316,7 @@ Packaged recipes should prefer mailbox/wake behavior for portable control. Recip
298
316
 
299
317
  Commands execute directly without shell evaluation where possible, but trusted executables still run with the same system permissions as Pi. Only register commands, scripts, recipes, and paths you trust.
300
318
 
301
- High-risk templates such as shells, interpreter eval modes, network access, external side effects, and broad filesystem mutation may surface warnings, but the runtime is not a security boundary.
319
+ High-risk templates such as shells, interpreter eval modes, network access, external side effects, and broad filesystem mutation may surface warnings, but the runtime is not a security boundary. Automatic reviewers cannot author or change executable contracts: they receive attached immutable evidence with no tools and may only select unchanged-source lifecycle/name operations. Disable all automatic draft/tool review and safe-boundary activation before starting Pi with `PI_ACTORS_AUTOMATIC_REVIEW=off`; `inspect target=tool:pi-actors view=status` reports `automatic_review=false`.
302
320
 
303
321
  Prefer:
304
322
 
package/dist/index.js CHANGED
@@ -4,101 +4,30 @@
4
4
  *
5
5
  * Wraps command templates as callable pi tools, stores durable user tools as recipe files, and exposes actor orchestration across reloads and sessions.
6
6
  */
7
- import * as AsyncRuns from "./lib/async-runs.js";
7
+ import * as AutomaticReviewRuntime from "./lib/automatic-review-runtime.js";
8
8
  import * as CommandTemplates from "./lib/command-templates.js";
9
- import * as InspectorOverlay from "./lib/inspector-overlay.js";
10
- import * as Observability from "./lib/observability.js";
9
+ import * as InspectorCommand from "./lib/inspector-command.js";
11
10
  import * as Paths from "./lib/paths.js";
12
11
  import * as Pi from "./lib/pi.js";
13
12
  import * as Prompts from "./lib/prompts.js";
13
+ import * as RunUiRuntime from "./lib/run-ui-runtime.js";
14
14
  import * as Runtime from "./lib/runtime.js";
15
15
  import * as Temp from "./lib/temp.js";
16
16
  import * as Tools from "./lib/tools.js";
17
17
  import * as ToolsResponse from "./lib/tools-response.js";
18
18
  export default function toolRegistryExtension(pi) {
19
- let runsAnimationInterval;
20
- let runsNotifyTimeout;
21
19
  let activeRunContext;
22
- let lastRunWatcherDiagnosticId = 0;
23
- const runUi = Observability.createRunUiObservationState();
24
- const retirementAttempts = new Set();
25
- const terminalNotificationsInFlight = new Set();
26
20
  const getRunOwnerId = Pi.getSessionId;
27
- const retireCandidateRuns = (ctx, summary) => {
28
- void Observability.executeRunRetirements(summary, {
29
- attempted: retirementAttempts,
30
- cancelRun: (candidate) => AsyncRuns.cancelRun(candidate.stateDir),
31
- notify: (message, level) => ctx.ui.notify(message, level),
32
- sendStop: (candidate) => AsyncRuns.sendRunMessage(candidate.stateDir, "stop"),
33
- });
34
- };
35
- const updateRunUi = (ctx, notify = false, terminalOnly = false) => {
36
- const ownerId = getRunOwnerId(ctx);
37
- const snapshot = Observability.readRunUiSnapshot(runUi, ownerId);
38
- ctx.ui.setStatus("zz-pi-actors-runs", snapshot.status ? ctx.ui.theme.fg("dim", snapshot.status) : undefined);
39
- if (!notify)
40
- return;
41
- const notificationSink = Pi.createNotificationSink(pi, ctx);
42
- retireCandidateRuns(ctx, snapshot.summary);
43
- Observability.deliverRunTransitionNotifications(snapshot.transitions, notificationSink, terminalNotificationsInFlight);
44
- Observability.pruneRunUiObservationState(runUi, snapshot);
45
- if (!terminalOnly) {
46
- Observability.deliverRunOutboxNotifications(snapshot.outboxEvents, notificationSink);
47
- }
48
- };
49
- const closeRunWatchers = () => {
50
- runWatcher.close();
51
- terminalReconciliation.close();
52
- if (runsNotifyTimeout)
53
- clearTimeout(runsNotifyTimeout);
54
- runsNotifyTimeout = undefined;
55
- };
56
- const reportRunWatcherDiagnostics = (ctx) => {
57
- for (const diagnostic of runWatcher.getDiagnostics()) {
58
- if (diagnostic.id <= lastRunWatcherDiagnosticId)
59
- continue;
60
- lastRunWatcherDiagnosticId = diagnostic.id;
61
- ctx.ui.notify(diagnostic.message, diagnostic.code === "rearmed" ? "info" : "warning");
62
- }
63
- };
64
- const scheduleRunEventUpdate = () => {
65
- if (runsNotifyTimeout)
66
- clearTimeout(runsNotifyTimeout);
67
- runsNotifyTimeout = setTimeout(() => {
68
- const ctx = activeRunContext;
69
- if (!ctx)
70
- return;
71
- runWatcher.refresh();
72
- updateRunUi(ctx, true);
73
- reportRunWatcherDiagnostics(ctx);
74
- }, 50);
75
- runsNotifyTimeout.unref?.();
76
- };
77
- const runWatcher = Observability.createRunStateWatcher({
78
- stateRoot: Paths.EXTENSION_RUNTIME_PATHS.runStateRoot,
79
- onChange: scheduleRunEventUpdate,
21
+ const automaticReview = AutomaticReviewRuntime.createAutomaticReviewRuntime({
22
+ getActiveContext: () => activeRunContext,
23
+ getRunOwnerId,
24
+ getThinkingLevel: () => pi.getThinkingLevel(),
80
25
  });
81
- const terminalReconciliation = Observability.createRunTerminalReconciliationLoop({
82
- onError: (error) => {
83
- const ctx = activeRunContext;
84
- if (!ctx)
85
- return;
86
- const message = error instanceof Error ? error.message : String(error);
87
- ctx.ui.notify(`Actor terminal reconciliation failed: ${message}`, "error");
88
- },
89
- reconcile: () => {
90
- const ctx = activeRunContext;
91
- if (!ctx)
92
- return;
93
- Observability.reconcileRunTerminalNotifications({
94
- inFlight: terminalNotificationsInFlight,
95
- ownerId: getRunOwnerId(ctx),
96
- sink: Pi.createNotificationSink(pi, ctx),
97
- state: runUi,
98
- });
99
- reportRunWatcherDiagnostics(ctx);
100
- },
101
- refreshWatcher: () => runWatcher.refresh(),
26
+ const runUiRuntime = RunUiRuntime.createRunUiRuntime({
27
+ getActiveContext: () => activeRunContext,
28
+ getRunOwnerId,
29
+ onRunEvent: automaticReview.schedule,
30
+ pi,
102
31
  });
103
32
  const actorToolDefinitions = new Map();
104
33
  const withCurrentThinkingContext = (definition) => {
@@ -148,54 +77,28 @@ export default function toolRegistryExtension(pi) {
148
77
  // Clear the pre-overlay widget after hot reloads from older pi-actors builds.
149
78
  ctx.ui.setWidget("zz-pi-actors-comms", undefined);
150
79
  activeRunContext = ctx;
151
- closeRunWatchers();
80
+ runUiRuntime.close();
81
+ automaticReview.close();
152
82
  recipeReload.close();
153
83
  await Temp.prepareExtensionTempDir(Paths.EXTENSION_RUNTIME_PATHS.tempDir);
154
84
  if (activeRunContext !== ctx)
155
85
  return;
86
+ automaticReview.start(ctx);
156
87
  runtime.loadTools(ctx);
157
- updateRunUi(ctx, true, true);
158
- runWatcher.refresh();
159
- terminalReconciliation.start();
88
+ runUiRuntime.start(ctx);
160
89
  recipeReload.watch(ctx);
161
- if (runsAnimationInterval)
162
- clearInterval(runsAnimationInterval);
163
- runsAnimationInterval = setInterval(() => {
164
- if (activeRunContext === ctx)
165
- updateRunUi(ctx, false);
166
- }, 1000);
167
- runsAnimationInterval.unref?.();
168
90
  });
169
- pi.on("session_shutdown", async () => {
170
- if (runsAnimationInterval)
171
- clearInterval(runsAnimationInterval);
172
- runsAnimationInterval = undefined;
91
+ pi.on("agent_end", async (_event, ctx) => {
92
+ if (activeRunContext === ctx)
93
+ automaticReview.schedule();
94
+ });
95
+ pi.on("session_shutdown", async (event, ctx) => {
173
96
  activeRunContext = undefined;
174
- closeRunWatchers();
97
+ automaticReview.close();
175
98
  recipeReload.close();
99
+ runUiRuntime.shutdown(event.reason, ctx);
176
100
  });
177
- pi.registerCommand("actors-inspector", {
178
- description: "Open the keyboard-driven actor inspector overlay",
179
- handler: async (_args, ctx) => {
180
- ctx.ui.setWidget("zz-pi-actors-comms", undefined);
181
- await ctx.ui.custom((tui, theme, _keybindings, done) => new InspectorOverlay.ActorInspectorOverlay({
182
- done,
183
- ownerId: getRunOwnerId(ctx),
184
- stateRoot: Paths.EXTENSION_RUNTIME_PATHS.runStateRoot,
185
- theme,
186
- tui,
187
- }), {
188
- overlay: true,
189
- overlayOptions: {
190
- anchor: "center",
191
- width: "94%",
192
- minWidth: 72,
193
- maxHeight: "94%",
194
- margin: 1,
195
- },
196
- });
197
- },
198
- });
101
+ InspectorCommand.registerActorInspectorCommand(pi, getRunOwnerId);
199
102
  pi.on("before_agent_start", async (event) => ({
200
103
  systemPrompt: `${event.systemPrompt}\n\n${Prompts.ONBOARDING_SYSTEM_PROMPT}`,
201
104
  }));
@@ -203,6 +106,7 @@ export default function toolRegistryExtension(pi) {
203
106
  configPath: Paths.EXTENSION_RUNTIME_PATHS.configPath,
204
107
  getActiveTools: () => pi.getActiveTools(),
205
108
  getRuntimeTool: (name) => Tools.resolveActiveRuntimeTool(name, runtime.getTools(), (activeName) => actorToolDefinitions.get(activeName)),
109
+ handleRuntimeMessage: automaticReview.handleMessage,
206
110
  registryRuntime: runtime,
207
111
  setActiveTools: (toolNames) => pi.setActiveTools(toolNames),
208
112
  }).map(withCurrentThinkingContext));
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Command-template async run lifecycle facade.
3
- * Owns launch, state observation, listing, message/control facade methods, and retention while runs-* subdomains own narrower run internals.
3
+ * Owns: launch, state observation, listing, message/control facade methods, and retention while runs-* subdomains own narrower run internals.
4
4
  */
5
5
  import type { CommandTemplateFailureScope, CommandTemplateValue } from "./command-templates.ts";
6
6
  import { type CurrentPolicyProvenance } from "./model-context.ts";
@@ -9,8 +9,10 @@ import { type RunArtifactDeclaration } from "./runs-artifacts.ts";
9
9
  import { type RunOutboxEvent } from "./runs-outbox.ts";
10
10
  import { type RunProcessIdentity } from "./runs-process.ts";
11
11
  import * as RunsIndex from "./runs-index.ts";
12
+ import * as RunsParentTeardown from "./runs-parent-teardown.ts";
12
13
  import { type ProcessRunInboxResult, type RunInboxMessage, type RunInboxStatus } from "./runs-mailbox.ts";
13
14
  import { type SendRunMessageOptions } from "./runs-messages.ts";
15
+ import { type AsyncRunStatus } from "./runs-status.ts";
14
16
  export type AsyncRunLaunchSource = "spawn" | "tool";
15
17
  export interface AsyncRunControlEndpoint {
16
18
  path: string;
@@ -21,6 +23,9 @@ export interface AsyncRunStartParams {
21
23
  control?: AsyncRunControlEndpoint;
22
24
  file?: string;
23
25
  launch_source?: AsyncRunLaunchSource;
26
+ lifecycleHooks?: {
27
+ onLockContention?(): void;
28
+ };
24
29
  name?: string;
25
30
  ownerId?: string;
26
31
  run_id?: string;
@@ -40,6 +45,7 @@ export interface AsyncRunStartParams {
40
45
  output?: string;
41
46
  artifacts?: Record<string, RunArtifactDeclaration>;
42
47
  mailbox?: RecipesReferences.TemplateRecipeMailbox;
48
+ notification_policy?: "normal" | "silent";
43
49
  retire_when?: "children_terminal";
44
50
  retry?: number | string;
45
51
  failure?: CommandTemplateFailureScope;
@@ -50,7 +56,7 @@ export interface AsyncRunStartParams {
50
56
  actor_context?: boolean | string;
51
57
  cwd?: string;
52
58
  }
53
- export type AsyncRunStatus = "running" | "done" | "failed" | "exited" | "cancelled" | "killed";
59
+ export type { AsyncRunStatus } from "./runs-status.ts";
54
60
  export interface AsyncRunMeta {
55
61
  argv: string[];
56
62
  createdAt: string;
@@ -61,6 +67,7 @@ export interface AsyncRunMeta {
61
67
  recipe?: string;
62
68
  recipe_file?: string;
63
69
  run: string;
70
+ run_instance_id: string;
64
71
  state_dir: string;
65
72
  status: AsyncRunStatus;
66
73
  tool?: string;
@@ -70,6 +77,7 @@ export interface AsyncRunMeta {
70
77
  control?: AsyncRunControlEndpoint;
71
78
  mailbox?: RecipesReferences.TemplateRecipeMailbox;
72
79
  model_policy?: CurrentPolicyProvenance;
80
+ notification_policy?: "normal" | "silent";
73
81
  process_identity?: RunProcessIdentity;
74
82
  recipe_context_records?: RecipesReferences.TemplateRecipeContextRecord[];
75
83
  retire_when?: "children_terminal";
@@ -82,10 +90,17 @@ export { parseRunOutboxEventLine } from "./runs-outbox.ts";
82
90
  export type { RunOutboxDelivery, RunOutboxEvent, RunOutboxLevel, } from "./runs-outbox.ts";
83
91
  export declare function getRunStatus(runOrDir: string): Record<string, unknown>;
84
92
  export type { RunStateIndexEntry } from "./runs-index.ts";
85
- export declare function listRunStateDirs(stateRoot?: string, depth?: number, seen?: Set<string>): string[];
93
+ export declare function listRunStateDirs(stateRoot?: string): string[];
86
94
  export declare function rebuildRunStateIndex(stateRoot?: string): RunsIndex.RunStateIndexEntry[];
87
95
  export declare function readRunStateIndex(stateRoot?: string): RunsIndex.RunStateIndexEntry[] | undefined;
88
96
  export declare function listRuns(stateRoot?: string, statusFilter?: string): Array<Record<string, unknown>>;
97
+ export type { ParentRunTeardownAttempt, ParentRunTeardownDiscoveryFailure, ParentRunTeardownResult, } from "./runs-parent-teardown.ts";
98
+ export interface ParentRunsTeardownSummaryResult extends RunsParentTeardown.ParentRunTeardownResult {
99
+ summaryPath?: string;
100
+ }
101
+ export declare function teardownRunsOwnedByParent(ownerId: string | undefined, stateRoot?: string, options?: {
102
+ trigger?: string;
103
+ }): ParentRunsTeardownSummaryResult;
89
104
  export declare function tailRun(runOrDir: string, lines?: number): string;
90
105
  export declare function readRunEvents(runOrDir: string, lines?: number): RunOutboxEvent[];
91
106
  export type { ProcessRunInboxResult, RunInboxMessage, RunInboxStatus, } from "./runs-mailbox.ts";
@@ -115,10 +130,15 @@ export type { SendRunMessageOptions } from "./runs-messages.ts";
115
130
  export declare function sendRunMessage(runOrDir: string, message: string, options?: SendRunMessageOptions): Promise<Record<string, unknown>>;
116
131
  export { getRunProcessSignalPlan } from "./runs-control.ts";
117
132
  export type { RunProcessSignalPlan } from "./runs-control.ts";
133
+ export interface RunControlExpectation {
134
+ onLocked?(): void;
135
+ ownerId?: string;
136
+ runInstanceId?: string;
137
+ }
118
138
  export declare function markRunTerminalNotificationHandled(stateDir: string, status: string): void;
119
- export declare function cancelRun(runOrDir: string): Record<string, unknown>;
139
+ export declare function cancelRun(runOrDir: string, expected?: RunControlExpectation): Record<string, unknown>;
120
140
  export declare function archiveRun(runOrDir: string): Record<string, unknown>;
121
141
  export declare function pruneRun(runOrDir: string, options?: {
122
142
  preserveArtifacts?: boolean;
123
143
  }): Record<string, unknown>;
124
- export declare function killRun(runOrDir: string): Record<string, unknown>;
144
+ export declare function killRun(runOrDir: string, expected?: RunControlExpectation): Record<string, unknown>;