@llblab/pi-actors 0.22.5 → 0.24.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 (180) hide show
  1. package/AGENTS.md +125 -59
  2. package/BACKLOG.md +88 -403
  3. package/CHANGELOG.md +39 -0
  4. package/README.md +14 -1
  5. package/dist/fixtures/protocol/actor-message-branch.json +13 -0
  6. package/dist/fixtures/protocol/artifact-manifest.json +9 -0
  7. package/dist/fixtures/protocol/mailbox-contract.json +15 -0
  8. package/dist/fixtures/protocol/recipe-summary.json +16 -0
  9. package/dist/fixtures/protocol/room-message.json +11 -0
  10. package/dist/fixtures/protocol/room-roster.json +11 -0
  11. package/dist/fixtures/protocol/run-inbox-message.json +9 -0
  12. package/dist/fixtures/protocol/run-outbox-event.json +9 -0
  13. package/dist/fixtures/protocol/run-state.json +10 -0
  14. package/dist/index.js +18 -2
  15. package/dist/lib/actor-inspector-tui.d.ts +4 -0
  16. package/dist/lib/actor-inspector-tui.js +58 -44
  17. package/dist/lib/actor-rooms.d.ts +16 -0
  18. package/dist/lib/actor-rooms.js +123 -28
  19. package/dist/lib/actor-worker.d.ts +13 -0
  20. package/dist/lib/actor-worker.js +86 -0
  21. package/dist/lib/async-runner.d.ts +5 -0
  22. package/dist/lib/async-runner.js +134 -0
  23. package/dist/lib/async-runs.d.ts +34 -2
  24. package/dist/lib/async-runs.js +224 -50
  25. package/dist/lib/build-dist.d.ts +5 -0
  26. package/dist/lib/build-dist.js +24 -0
  27. package/dist/lib/command-templates.js +5 -5
  28. package/dist/lib/conformance.d.ts +12 -0
  29. package/dist/lib/conformance.js +28 -0
  30. package/dist/lib/coordinator.d.ts +5 -0
  31. package/dist/lib/coordinator.js +557 -0
  32. package/dist/lib/limits.d.ts +11 -0
  33. package/dist/lib/limits.js +11 -0
  34. package/dist/lib/locker.d.ts +5 -0
  35. package/dist/lib/locker.js +310 -0
  36. package/dist/lib/mailbox-loop.d.ts +41 -0
  37. package/dist/lib/mailbox-loop.js +62 -0
  38. package/dist/lib/observability.d.ts +2 -2
  39. package/dist/lib/observability.js +57 -57
  40. package/dist/lib/output.js +4 -5
  41. package/dist/lib/prompts.d.ts +1 -1
  42. package/dist/lib/prompts.js +1 -1
  43. package/dist/lib/recipe-discovery.js +1 -0
  44. package/dist/lib/recipe-references.d.ts +11 -2
  45. package/dist/lib/recipe-references.js +29 -4
  46. package/dist/lib/recipe-usage.d.ts +2 -1
  47. package/dist/lib/recipe-usage.js +15 -3
  48. package/dist/lib/recipe-utils.d.ts +5 -0
  49. package/dist/lib/recipe-utils.js +385 -0
  50. package/dist/lib/runtime-notifier.js +3 -7
  51. package/dist/lib/runtime.js +12 -2
  52. package/dist/lib/state-readers.d.ts +21 -0
  53. package/dist/lib/state-readers.js +74 -0
  54. package/dist/lib/tools.js +198 -39
  55. package/dist/lib/validate-recipe.d.ts +6 -0
  56. package/dist/lib/validate-recipe.js +104 -0
  57. package/dist/recipes/actor-worker.json +35 -0
  58. package/dist/recipes/coordinator-locker.json +45 -0
  59. package/dist/recipes/lens-swarm.json +66 -0
  60. package/dist/recipes/locker.json +45 -0
  61. package/dist/recipes/music-player.json +38 -0
  62. package/dist/recipes/pipeline-architect-coordinator.json +95 -0
  63. package/dist/recipes/pipeline-artifact-bundle.json +100 -0
  64. package/dist/recipes/pipeline-artifact-report.json +58 -0
  65. package/dist/recipes/pipeline-artifact-write.json +72 -0
  66. package/dist/recipes/pipeline-async-run-ops.json +70 -0
  67. package/dist/recipes/pipeline-checkpoint-continuation.json +67 -0
  68. package/dist/recipes/pipeline-development-tasking.json +81 -0
  69. package/dist/recipes/pipeline-docs-maintenance.json +80 -0
  70. package/dist/recipes/pipeline-media-library.json +59 -0
  71. package/dist/recipes/pipeline-quorum-review.json +79 -0
  72. package/dist/recipes/pipeline-release-readiness.json +110 -0
  73. package/dist/recipes/pipeline-release-summary.json +88 -0
  74. package/dist/recipes/pipeline-repo-health.json +89 -0
  75. package/dist/recipes/pipeline-research-synthesis.json +94 -0
  76. package/dist/recipes/pipeline-review-readiness.json +54 -0
  77. package/dist/recipes/pipeline-room-swarm.json +50 -0
  78. package/dist/recipes/subagent-artifact.json +32 -0
  79. package/dist/recipes/subagent-checkpoint.json +33 -0
  80. package/dist/recipes/subagent-conflict-report.json +32 -0
  81. package/dist/recipes/subagent-contradiction-map.json +33 -0
  82. package/dist/recipes/subagent-critic.json +35 -0
  83. package/dist/recipes/subagent-evidence-map.json +33 -0
  84. package/dist/recipes/subagent-followup.json +33 -0
  85. package/dist/recipes/subagent-judge.json +33 -0
  86. package/dist/recipes/subagent-merge.json +33 -0
  87. package/dist/recipes/subagent-message.json +34 -0
  88. package/dist/recipes/subagent-normalize.json +31 -0
  89. package/dist/recipes/subagent-plan.json +33 -0
  90. package/dist/recipes/subagent-prompt.json +28 -0
  91. package/dist/recipes/subagent-quorum.json +43 -0
  92. package/dist/recipes/subagent-review-coordinator.json +114 -0
  93. package/dist/recipes/subagent-review.json +37 -0
  94. package/dist/recipes/subagent-task-card.json +35 -0
  95. package/dist/recipes/subagent-tools.json +27 -0
  96. package/dist/recipes/subagent-verify.json +34 -0
  97. package/dist/recipes/subagents-prompts.json +51 -0
  98. package/dist/recipes/utility-actor-message.json +23 -0
  99. package/dist/recipes/utility-artifact-manifest.json +16 -0
  100. package/dist/recipes/utility-artifact-write.json +16 -0
  101. package/dist/recipes/utility-changelog-head.json +11 -0
  102. package/dist/recipes/utility-changelog-section.json +13 -0
  103. package/dist/recipes/utility-coordinator-lock-snapshot.json +13 -0
  104. package/dist/recipes/utility-git-log.json +11 -0
  105. package/dist/recipes/utility-git-status.json +9 -0
  106. package/dist/recipes/utility-jsonl-tail.json +10 -0
  107. package/dist/recipes/utility-markdown-index.json +14 -0
  108. package/dist/recipes/utility-package-summary.json +11 -0
  109. package/dist/recipes/utility-playlist-build.json +17 -0
  110. package/dist/recipes/utility-playlist-scan.json +11 -0
  111. package/dist/recipes/utility-run-ops-snapshot.json +17 -0
  112. package/dist/recipes/utility-run-state-files.json +13 -0
  113. package/dist/recipes/utility-run-summary.json +11 -0
  114. package/dist/recipes/utility-skill-summary.json +13 -0
  115. package/dist/recipes/utility-validate-recipe.json +13 -0
  116. package/dist/recipes/utility-validation-wrapper.json +13 -0
  117. package/dist/scripts/actor-worker.mjs +31 -0
  118. package/dist/scripts/async-runner.mjs +31 -0
  119. package/dist/scripts/build-dist.mjs +25 -0
  120. package/dist/scripts/conformance.mjs +33 -0
  121. package/dist/scripts/coordinator.mjs +31 -0
  122. package/dist/scripts/locker.mjs +33 -0
  123. package/dist/scripts/music-player.mjs +964 -0
  124. package/dist/scripts/recipe-utils.mjs +31 -0
  125. package/dist/scripts/validate-recipe.mjs +34 -0
  126. package/dist/skills/actors/SKILL.md +375 -0
  127. package/dist/skills/swarm/SKILL.md +467 -0
  128. package/dist/skills/swarm/references/development-swarm.md +596 -0
  129. package/docs/actor-messages.md +2 -2
  130. package/docs/async-runs.md +13 -1
  131. package/docs/template-recipes.md +2 -2
  132. package/docs/tool-registry.md +0 -1
  133. package/fixtures/protocol/actor-message-branch.json +13 -0
  134. package/fixtures/protocol/artifact-manifest.json +9 -0
  135. package/fixtures/protocol/mailbox-contract.json +15 -0
  136. package/fixtures/protocol/recipe-summary.json +16 -0
  137. package/fixtures/protocol/room-message.json +11 -0
  138. package/fixtures/protocol/room-roster.json +11 -0
  139. package/fixtures/protocol/run-inbox-message.json +9 -0
  140. package/fixtures/protocol/run-outbox-event.json +9 -0
  141. package/fixtures/protocol/run-state.json +10 -0
  142. package/index.ts +21 -0
  143. package/lib/actor-inspector-tui.ts +138 -59
  144. package/lib/actor-rooms.ts +241 -60
  145. package/lib/actor-worker.ts +118 -0
  146. package/lib/async-runner.ts +173 -0
  147. package/lib/async-runs.ts +302 -53
  148. package/lib/build-dist.ts +30 -0
  149. package/lib/command-templates.ts +5 -5
  150. package/lib/conformance.ts +46 -0
  151. package/lib/coordinator.ts +649 -0
  152. package/lib/limits.ts +12 -0
  153. package/lib/locker.ts +340 -0
  154. package/lib/mailbox-loop.ts +148 -0
  155. package/lib/observability.ts +34 -23
  156. package/lib/output.ts +4 -6
  157. package/lib/prompts.ts +1 -1
  158. package/lib/recipe-discovery.ts +1 -0
  159. package/lib/recipe-references.ts +57 -6
  160. package/lib/recipe-usage.ts +31 -4
  161. package/lib/recipe-utils.ts +486 -0
  162. package/lib/runtime-notifier.ts +4 -6
  163. package/lib/runtime.ts +31 -7
  164. package/lib/state-readers.ts +93 -0
  165. package/lib/tools.ts +297 -58
  166. package/lib/validate-recipe.ts +110 -0
  167. package/package.json +11 -2
  168. package/recipes/actor-worker.json +35 -0
  169. package/recipes/pipeline-quorum-review.json +12 -7
  170. package/scripts/actor-worker.mjs +31 -0
  171. package/scripts/async-runner.mjs +11 -195
  172. package/scripts/build-dist.mjs +25 -0
  173. package/scripts/conformance.mjs +33 -0
  174. package/scripts/coordinator.mjs +19 -616
  175. package/scripts/locker.mjs +23 -322
  176. package/scripts/music-player.mjs +21 -2
  177. package/scripts/recipe-utils.mjs +20 -467
  178. package/scripts/validate-recipe.mjs +23 -113
  179. package/skills/actors/SKILL.md +7 -4
  180. package/skills/swarm/SKILL.md +3 -1
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Recipe utility command bundle shim.
5
+ *
6
+ * Runtime logic lives in lib/recipe-utils.ts and is compiled to
7
+ * dist/lib/recipe-utils.js for installed JS-only packages.
8
+ */
9
+
10
+ import { existsSync } from "node:fs";
11
+ import { dirname, join } from "node:path";
12
+ import { fileURLToPath, pathToFileURL } from "node:url";
13
+
14
+ function packageRoot() {
15
+ return dirname(dirname(fileURLToPath(import.meta.url)));
16
+ }
17
+
18
+ function mainModulePath() {
19
+ const root = packageRoot();
20
+ const compiled = join(root, "dist", "lib", "recipe-utils.js");
21
+ return existsSync(compiled) ? compiled : join(root, "lib", "recipe-utils.ts");
22
+ }
23
+
24
+ const { runRecipeUtils } = await import(pathToFileURL(mainModulePath()).href);
25
+
26
+ try {
27
+ runRecipeUtils(process.argv.slice(2));
28
+ } catch (error) {
29
+ console.error(error instanceof Error ? error.message : String(error));
30
+ process.exit(1);
31
+ }
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env -S node --experimental-strip-types
2
+
3
+ /**
4
+ * Template recipe validator CLI shim.
5
+ *
6
+ * Runtime logic lives in lib/validate-recipe.ts and is compiled to
7
+ * dist/lib/validate-recipe.js for installed JS-only packages.
8
+ */
9
+
10
+ import { existsSync } from "node:fs";
11
+ import { dirname, join } from "node:path";
12
+ import { fileURLToPath, pathToFileURL } from "node:url";
13
+
14
+ function packageRoot() {
15
+ return dirname(dirname(fileURLToPath(import.meta.url)));
16
+ }
17
+
18
+ function mainModulePath() {
19
+ const root = packageRoot();
20
+ const compiled = join(root, "dist", "lib", "validate-recipe.js");
21
+ return existsSync(compiled) ? compiled : join(root, "lib", "validate-recipe.ts");
22
+ }
23
+
24
+ const { validateRecipes } = await import(pathToFileURL(mainModulePath()).href);
25
+
26
+ try {
27
+ const report = validateRecipes(process.argv.slice(2));
28
+ if (report.help) console.error(report.usage);
29
+ else console.log(JSON.stringify(report, null, 2));
30
+ process.exit(report.ok ? 0 : 1);
31
+ } catch (error) {
32
+ console.error(error instanceof Error ? error.message : String(error));
33
+ process.exit(1);
34
+ }
@@ -0,0 +1,375 @@
1
+ ---
2
+ name: actors
3
+ description: Highest-density practical guide for pi-actors. Read this skill whenever prompt and tools are not enough for spawn, message, inspect, actor runs, tools, recipes, command templates, async lifecycle, mailboxes, artifacts, and local orchestration mechanics.
4
+ metadata:
5
+ version: 0.24.0
6
+ ---
7
+
8
+ # Actors (pi-actors)
9
+
10
+ `pi-actors` turns trusted local capabilities into addressable actors. This skill is the compact operator/reference layer for the extension itself: tools, nouns, lifecycle, message protocol, recipes, and common edge cases. It is not a multi-agent strategy guide; use a swarm skill for decomposition, quorum design, reviewer lenses, and consensus methodology.
11
+
12
+ Maintain this skill as the extension's agent-facing manual. When implementation changes reveal new durable mechanics, invariants, warnings, or safer operating patterns, update this skill alongside code/docs so future agents learn the current actor model instead of rediscovering it.
13
+
14
+ ## Knowledge Surfaces
15
+
16
+ Context arrives in layers:
17
+
18
+ - **Injected prompt**: always present at extension load. It is a bootstrap/reminder of current verbs, paths, and runtime rules; it should not try to be documentation.
19
+ - **Skill header**: automatically matched by agents from `name`/`description`. Its job is to signal: if pi-actors use is unclear, read this skill body.
20
+ - **This skill body**: highest-density practical reference. It should explain extension operation from multiple angles and link to deeper docs without becoming a changelog or swarm-methodology guide.
21
+ - **README**: human entrypoint. It explains what pi-actors is, why it matters, benefits, rhythm, and representative scenarios; it is not automatically in agent context.
22
+ - **Docs**: transportable standards by domain: command templates, recipes, async runs, actor messages, registry, recipe library; read on demand.
23
+ - **AGENTS.md**: project context for agents changing pi-actors: architecture constraints, durable conventions, do/don't rules, validation; read for repo work.
24
+
25
+ ## Core Nouns
26
+
27
+ ```text
28
+ Trusted local capability
29
+ -> Command template execution graph
30
+ -> Recipe saved actor definition
31
+ -> spawn starts one run instance
32
+ -> run:<id> addressable actor
33
+
34
+ Trusted local capability
35
+ -> Command template or recipe
36
+ -> register_tool persists an agent-callable wrapper
37
+ -> tool:<name> addressable tool actor
38
+ ```
39
+
40
+ - **Command template**: portable execution graph. String leaf, sequence array, or object node with controls.
41
+ - **Recipe**: saved JSON definition wrapping a template with args, defaults, imports, mailbox, artifacts, metadata, and optional `async: true`.
42
+ - **Run actor**: one detached execution instance addressable as `run:<id>` with status, logs, messages, mailbox metadata, files, communication snapshot, and artifacts.
43
+ - **Room actor**: shared timeline + roster endpoint addressable as `room:<run>`; every spawned run gets `room:<run>`.
44
+ - **Tool actor**: registered persistent capability addressable as `tool:<name>` and callable through the generated tool or `message`.
45
+ - **Coordinator/session**: the current pi session endpoint that receives bounded actor follow-ups.
46
+ - **Mailbox**: public interaction contract: message types the actor accepts/emits.
47
+ - **Artifact**: named durable output path declared by a recipe/run.
48
+
49
+ ## Three Verbs
50
+
51
+ ### `spawn` — create a run actor
52
+
53
+ Use for long work, background services, subagents, fanout, pipelines, and reusable recipes.
54
+
55
+ ```json
56
+ {
57
+ "as": "run:repo-health",
58
+ "file": "pipeline-repo-health",
59
+ "values": { "path": "/repo" },
60
+ "artifacts": { "report": "/tmp/repo-health.md" }
61
+ }
62
+ ```
63
+
64
+ Rules:
65
+
66
+ - Use `file`/`recipe` for saved recipes; bare names resolve under `~/.pi/agent/recipes`.
67
+ - Use inline `template` for one-off experiments; promote useful repeats to recipes.
68
+ - When a successful actor follow-up suggests persistence, offer to save or register the pattern under `~/.pi/agent/recipes`; ask before writing the user recipe root.
69
+ - Use stable `as` names when you will inspect or message the actor later.
70
+ - `async: true` on the recipe is the detached run switch.
71
+
72
+ ### `message` — send a typed envelope
73
+
74
+ ```json
75
+ {
76
+ "to": "run:repo-health",
77
+ "type": "control.cancel",
78
+ "summary": "Cancel stale repo-health run",
79
+ "body": {}
80
+ }
81
+ ```
82
+
83
+ Envelope fields:
84
+
85
+ - Required: `to`, `type`.
86
+ - Useful: `summary`, `body`, `from`, `reply_to`, `correlation_id`, `metadata`.
87
+ - Addresses: `run:<id>`, `branch:<run>/<branch>`, `room:<run>`, `tool:<name>`, `coordinator`, `session:<id>`.
88
+ - Room posts require `from` from the same run (`run:<run>` or `branch:<run>/<branch>`).
89
+ - Standard termination messages: `control.stop`, `control.cancel`, `control.kill`; terminal retention messages: `control.archive`, `control.prune`.
90
+
91
+ Check `inspect view=mailbox` before domain-specific messages.
92
+
93
+ ### `inspect` — observe intentionally
94
+
95
+ ```json
96
+ { "target": "run:repo-health", "view": "status" }
97
+ { "target": "run:repo-health", "view": "tail", "lines": "80" }
98
+ { "target": "run:repo-health", "view": "messages" }
99
+ { "target": "run:repo-health", "view": "communication" }
100
+ { "target": "run:repo-health", "view": "artifacts" }
101
+ { "target": "room:repo-health", "view": "status" }
102
+ { "target": "room:repo-health", "view": "roster" }
103
+ { "target": "room:repo-health", "view": "contacts" }
104
+ { "target": "room:repo-health", "view": "previews" }
105
+ { "target": "tool:music_player", "view": "status" }
106
+ { "target": "recipes", "view": "status" }
107
+ { "target": "coordinator", "view": "status" }
108
+ ```
109
+
110
+ Views:
111
+
112
+ - `status`: lifecycle, pid, values, progress, result, compact summary.
113
+ - `tail`: recent stdout/stderr/log tail.
114
+ - `messages`: actor messages emitted by the run, or room timeline entries for `room:*`.
115
+ - `communication`: run/branch communication snapshot with self/root/default-room/member/contact hints.
116
+ - `roster`: room member list with address, role, parent, caps, claim, status, and last seen.
117
+ - `contacts`: roster-derived direct-message targets without full roster metadata.
118
+ - `previews`: TUI-ready bounded room message previews with timestamp/from/to/type/summary/body_preview.
119
+ - `mailbox`: declared accepts/emits contract for runs; queued direct branch inbox messages for `branch:<run>/<branch>` with `id`, status, route/type, and queue/handling timestamps.
120
+ - `files`: run state directory file list.
121
+ - `artifacts`: declared artifact paths/status.
122
+ - `recipes` target: registry summary for active, shadowed, invalid, disabled, and diagnostic recipe entries.
123
+
124
+ Actor inspector commands:
125
+
126
+ - `/actors-inspector-toggle [rows]`: open/close the compact table or set row count; default is 12 log rows when no size is supplied.
127
+ - `/actors-inspector-filter all|room|direct|broadcast|unread|branch <name>|current-branch <name>|mention <text>`: narrow table previews without changing room/run state.
128
+ - `/actors-inspect <number>`: open one visible row as a full-message view.
129
+
130
+ The table is compact and optimistic by default: bounded body previews, capped noisy room rows, branch-local inbox previews, stable event ids in selected-message details, and an inline roster summary in the form `name/role` that wraps only when needed. Use `unread` for queued branch inbox work and `branch <name>` / `current-branch <name>` for one branch's room/direct/inbox traffic. Rows with `metadata.requires_response=true` show a `!` attention marker. `/actors-inspect <number>` marks that row read for the current session filter. Active roster members use the target color; members that sent `actor.leave` stay visible as inactive/muted participants from the current run. Actor display names come from `actor.join` bodies (`display`) or branch addresses, keeping debugger output plain and name-driven.
131
+
132
+ Let terminal notifications arrive; avoid sleep-poll loops except during diagnosis.
133
+
134
+ ## Stable Multi-Actor Review Rules
135
+
136
+ - Prefer independent read-only reviewers for review swarms. Use shared room messages for coordination signals and observability, not for letting reviewers converge early, unless the task explicitly asks for collaborative discussion.
137
+ - Treat inspector-visible communication logs as recipe-quality evidence. Full room/direct timelines show whether recipes coordinate clearly, emit useful summaries, over-chat, miss handoffs, choose poor message types, or need better mailbox/artifact conventions. Use `inspect room:<run> view=messages|previews`, `inspect run:<id> view=communication`, and the actor inspector table/full-message views to improve recipes after real runs.
138
+ - Smoke-test provider/model availability before launching expensive fanout, or choose a provider known to be configured in this environment. A failed provider fanout creates noisy run transitions without useful review signal.
139
+ - Keep one public communication model: `spawn` creates actors, `message` sends typed envelopes, and `inspect` observes. Avoid adding public side channels or storage nouns when a normal actor address/view can express the operation.
140
+ - Keep route and semantic type separate. Direct, room, coordinator, and session messages may share `type`; delivery behavior comes from `to`.
141
+ - Any UI, summary, or aggregate view that scans run directories must apply coordinator/session ownership filters before exposing summaries or body previews.
142
+ - Treat `communication.json` as visible actor context, not a global mutable truth table. Run-level snapshots should identify the run actor; branch-local snapshots should identify the branch actor.
143
+ - Prefer same-run provenance checks on lateral actor routes. If `from` is accepted for room or branch routes, validate that it belongs to the addressed run.
144
+
145
+ ## Persistent Backlog Implementers
146
+
147
+ When using actors as backlog implementers, avoid one-shot subagents that exit after one task. Use long-lived branch actors and keep task selection with the coordinator:
148
+
149
+ 1. Coordinator assigns a concrete backlog slice with `task.assign`.
150
+ 2. Actor posts `task.claim` to `room:<run>` before editing.
151
+ 3. Actor executes and validates the slice.
152
+ 4. Actor posts `task.result` and `awaiting_assignment`.
153
+ 5. Actor stays alive until the coordinator sends another `task.assign` or an explicit `control.stop`.
154
+
155
+ Use `front`/`back` actors for opposite backlog ends when reducing overlap. Implementer workflows should be packaged as reusable recipe composition, not bespoke scripts: use `coordinator-locker` for queue/assignment/locking, subagent launcher recipes for execution cells, actor-message utility recipes for structured handoffs, and `lib/mailbox-loop.ts` helpers when writing mailbox-consuming workers. Mailbox loops should claim one run or branch inbox message at a time, mark success as `handled`, mark exceptions as `failed`, and treat `control.stop` / `control.cancel` / `control.kill` as standard stop messages; bounded drains may process available work until a stop message or max-message guard. If the existing recipe library cannot express the scenario, add missing reusable component recipes first, then compose the higher-level workflow from them. Supervisors should route coordinator assignments by `body.actor`, preserve the assignment as an object rather than a JSON string, and keep stopped-worker summaries tied to the original actor list.
156
+
157
+ Current packaged building blocks:
158
+
159
+ - `coordinator-locker`: long-lived queue/lock coordinator for assignment and resource ownership.
160
+ - `subagent-prompt`, `subagent-tools`, `subagents-prompts`: execution launchers for one or many agent prompts.
161
+ - `utility-actor-message`: deterministic actor-message envelope construction for handoffs/results.
162
+ - `utility-run-ops-snapshot` and `pipeline-async-run-ops`: inspect live runs/messages before deciding the next assignment.
163
+
164
+ The missing higher-level persistent backlog-implementer workflow is intentionally future work until it can be expressed from reusable recipe cells.
165
+
166
+ ## Command Template Standard
167
+
168
+ Forms:
169
+
170
+ ```json
171
+ "npm test -- {file}"
172
+ ["npm run typecheck", "npm test"]
173
+ { "parallel": true, "template": ["job-a", "job-b"] }
174
+ ```
175
+
176
+ Controls:
177
+
178
+ - `args`, `defaults`: public placeholder declarations and defaults.
179
+ - `parallel: true`: fanout child nodes.
180
+ - `when`: conditional execution.
181
+ - `timeout`, `delay`, `retry`: timing and retry controls; string placeholders are allowed where supported.
182
+ - `failure`: `continue`, `branch`, or `root` propagation.
183
+ - `recover`: cleanup between retry attempts.
184
+ - `repeat`: repeated node expansion.
185
+ - `output`: output behavior selection.
186
+
187
+ Placeholders:
188
+
189
+ - `{name}` required value.
190
+ - `{name=default}` inline default.
191
+ - `{name:type=default}` typed inline arg.
192
+ - `{value??fallback}` nullish fallback.
193
+ - `{flag?yes:no}` ternary fallback.
194
+
195
+ Templates are synchronous and portable. Recipes give them identity and lifecycle.
196
+
197
+ ## Recipe Standard
198
+
199
+ Minimal actor recipe:
200
+
201
+ ```json
202
+ {
203
+ "async": true,
204
+ "args": ["path:path", "model:string"],
205
+ "defaults": {},
206
+ "mailbox": {
207
+ "accepts": ["control.stop", "control.cancel", "control.kill"],
208
+ "emits": ["command.done", "run.done", "run.failed"]
209
+ },
210
+ "artifacts": { "report": "{path}/report.md" },
211
+ "template": "some-command {path} --model {model}"
212
+ }
213
+ ```
214
+
215
+ Rules:
216
+
217
+ 1. Every recipe owns `template` directly.
218
+ 2. `async: true` makes spawned work a detached actor run.
219
+ 3. Public knobs belong in `args`/`defaults`; hidden launch mechanics stay inside `template`.
220
+ 4. Use `imports` to compose recipes; imported recipes are definitions, not nested async runs.
221
+ 5. Declare `mailbox` for actors that accept or emit meaningful messages.
222
+ 6. Declare `artifacts` for durable outputs the coordinator should inspect.
223
+ 7. File-backed recipe identity comes from the filename basename; legacy top-level `name` fields are ignored by loaders.
224
+ 8. File-backed async recipes pass child `pi -p` actors a bounded JSONL recipe context bundle by default: raw entry/import recipe records, derived `name`, import path/alias, and `"you_are_here": true` on the launching recipe node. Set `"actor_context": false` or `"off"` to suppress it for minimal prompts.
225
+ 9. Keep packaged recipes generic: no machine-local paths, no private companion identities, no project-specific defaults unless the recipe is explicitly project-specific.
226
+ 10. Do not ship concrete model-version defaults in packaged recipes; expose `model`, `models`, and stage-specific model args so the caller must choose current policy at launch.
227
+
228
+ Priority for same-id recipes:
229
+
230
+ 1. No recipe: no capability.
231
+ 2. Packaged pi-actors recipe: standard-library declarative actor component.
232
+ 3. Explicit ad hoc user recipe file outside `~/.pi/agent/recipes`.
233
+ 4. User recipe in `~/.pi/agent/recipes/*.json` or `*.md`: highest-priority operator tool surface.
234
+
235
+ Only matching filename ids compete. Higher priority shadows lower priority; within one priority layer, same-id JSON shadows Markdown. An invalid or `disabled: true` higher-priority recipe blocks fallback so the agent does not silently run standard-library behavior when a user override is broken or intentionally disabled.
236
+
237
+ Muscle-memory lens: `~/.pi/agent/recipes/*.json` and `*.md` are the agent's capability memory. Every recipe in that directory becomes an easy-to-call tool automatically and survives into later sessions. Agents grow this memory either by calling `register_tool`, which writes recipe files there under the hood, or by deliberately editing those recipe files. Treat this directory like `MEMORY.md` for executable habits: useful local patterns belong there; packaged recipes elsewhere are reusable components, not tools.
238
+
239
+ Usage lens: user recipes may carry extension-maintained launch metadata such as `usage.calls` and `usage.last_called`. The extension increments the counter when it starts that concrete recipe; agents should not hand-edit counters as part of normal recipe maintenance. Treat usage as evidence for usefulness analysis: heavily used recipes are good candidates for promotion, documentation, or stronger tests; unused recipes are cleanup candidates. Do not use failure counts as a primary usefulness signal because failures may reflect bad caller judgment rather than bad recipes. Do not delete or demote solely from counters without operator approval.
240
+
241
+ Cleanup rule: periodically inspect `~/.pi/agent/recipes` as the live muscle-memory set. For each stale, duplicate, too-specific, or low-value recipe, choose one explicit action: keep as a tool, move it out of the agent recipe root to retain recipe-only memory, merge into a better recipe, or delete/archive the file. Prefer moving over deletion when the recipe may still be useful as a component. Never silently remove tools during unrelated work.
242
+
243
+ ## Registered Tools
244
+
245
+ `register_tool` persists trusted local capabilities as recipe files in `~/.pi/agent/recipes/*.json`; hand-authored Markdown recipes in the same directory are also discovered as tools.
246
+
247
+ Use it when a command/template/recipe should become durable agent muscle memory. Prefer typed args or placeholder-derived args; use `update=true` for replacement and `template=null` or `template=""` for deletion. `register_tool` should create/update/delete recipe files in the user recipe root; direct file editing is allowed but is the lower-level path.
248
+
249
+ Tool-registration lenses are open-ended prompts for deciding what deserves durable tool status:
250
+
251
+ 1. **Reliability lens**: register wrappers for operations where agents commonly omit checks, run steps out of order, pass ambiguous inputs, or recover poorly from partial failure.
252
+ 2. **Safety lens**: prefer read-only diagnostics, dry-runs, preflights, confirmations, or bounded adapters around high-impact operations before registering direct action tools.
253
+ 3. **Context-affordance lens**: register tools whose mere presence in the injected capability list should steer agents toward the right operational habit.
254
+ 4. **Existing-recipe lens**: scan already-authored recipes before inventing a new tool. Packaged recipes, ad hoc project recipes, and recipes co-located under skill directories are often the first candidates to copy/register into the user recipe root when they match a recurring local workflow.
255
+ 5. **Composition lens**: register small semantic entrypoints over reusable recipe components instead of baking one large scenario-specific shell command into a tool.
256
+ 6. **Portability lens**: keep recipe files transportable; make tool exposure a consequence of placement in `~/.pi/agent/recipes`, not recipe-owned markers or machine-local assumptions.
257
+
258
+ Default bias: register diagnostic/preflight tools before action tools, and promote existing recipes before writing new orchestration. A good persistent tool shrinks the chance of a subtle operational mistake, not just the number of keystrokes.
259
+
260
+ Tool templates may be:
261
+
262
+ - A foreground command template.
263
+ - A file-backed recipe name/path.
264
+ - A complete recipe body, optionally `async: true`.
265
+
266
+ The user recipe root is the default tool set by location. It accepts canonical JSON recipes and literate Markdown recipes with frontmatter plus fenced `template`/`json recipe` blocks; same-id JSON shadows Markdown in the same priority layer. Packaged recipes are lower-priority standard-library components and are not tools unless copied or registered into the agent recipe root. Ideal runtime behavior is reactive: create/edit/delete recipe files, validate them, then connect valid tools or surface diagnostics without requiring agents to hand-maintain a separate registry.
267
+
268
+ ## Recipe Navigator
269
+
270
+ Use packaged recipes by name with `spawn file=<name>` for async actors, or register/call them as tools when repeated use deserves a stable shortcut. The links below point to recipe files shipped with this extension; read the JSON for args, defaults, mailbox, artifacts, and imports.
271
+
272
+ ### Coordination and Services
273
+
274
+ - [`coordinator-locker`](../../recipes/coordinator-locker.json): queue + acquire/renew/release lease locks + journaled coordinator messages + platform-adapted control metadata.
275
+ - [`locker`](../../recipes/locker.json): modular queue + acquire/renew/release lease locks + journaled locker messages + platform-adapted control metadata.
276
+ - [`utility-coordinator-lock-snapshot`](../../recipes/utility-coordinator-lock-snapshot.json): one-shot JSON snapshot of a coordinator-locker state directory.
277
+ - [`music-player`](../../recipes/music-player.json): background local/URL/directory/playlist playback actor controlled by messages.
278
+ - [`actor-worker`](../../recipes/actor-worker.json): canonical mailbox-backed branch worker demo that claims branch inbox work, emits room-visible task lifecycle messages, and stops on standard control messages.
279
+
280
+ ### Subagent Atoms
281
+
282
+ - Launchers: [`subagent-prompt`](../../recipes/subagent-prompt.json), [`subagent-tools`](../../recipes/subagent-tools.json), [`subagents-prompts`](../../recipes/subagents-prompts.json).
283
+ - Review chain: [`subagent-review`](../../recipes/subagent-review.json), [`subagent-verify`](../../recipes/subagent-verify.json), [`subagent-merge`](../../recipes/subagent-merge.json), [`subagent-judge`](../../recipes/subagent-judge.json), [`subagent-normalize`](../../recipes/subagent-normalize.json).
284
+ - Planning/evidence: [`subagent-plan`](../../recipes/subagent-plan.json), [`subagent-task-card`](../../recipes/subagent-task-card.json), [`subagent-evidence-map`](../../recipes/subagent-evidence-map.json), [`subagent-contradiction-map`](../../recipes/subagent-contradiction-map.json), [`subagent-critic`](../../recipes/subagent-critic.json).
285
+ - Handoffs: [`subagent-checkpoint`](../../recipes/subagent-checkpoint.json), [`subagent-followup`](../../recipes/subagent-followup.json), [`subagent-message`](../../recipes/subagent-message.json), [`subagent-artifact`](../../recipes/subagent-artifact.json), [`subagent-conflict-report`](../../recipes/subagent-conflict-report.json).
286
+ - Composition: [`subagent-quorum`](../../recipes/subagent-quorum.json), [`subagent-review-coordinator`](../../recipes/subagent-review-coordinator.json), [`lens-swarm`](../../recipes/lens-swarm.json).
287
+
288
+ ### Pipelines
289
+
290
+ - [`pipeline-release-readiness`](../../recipes/pipeline-release-readiness.json): changelog/package/skill/validation evidence → release review → artifact report.
291
+ - [`pipeline-release-summary`](../../recipes/pipeline-release-summary.json): evidence-only release summary, risk checklist, and PR body draft artifact without release side effects.
292
+ - [`pipeline-repo-health`](../../recipes/pipeline-repo-health.json): git/doc/validation evidence → normalized repository health report.
293
+ - [`pipeline-async-run-ops`](../../recipes/pipeline-async-run-ops.json): run summary + selected run messages → operations report.
294
+ - [`pipeline-docs-maintenance`](../../recipes/pipeline-docs-maintenance.json): docs index/review/planning → maintenance artifact.
295
+ - Artifacts: [`pipeline-artifact-report`](../../recipes/pipeline-artifact-report.json), [`pipeline-artifact-write`](../../recipes/pipeline-artifact-write.json), [`pipeline-artifact-bundle`](../../recipes/pipeline-artifact-bundle.json).
296
+ - Review gates: [`pipeline-quorum-review`](../../recipes/pipeline-quorum-review.json), [`pipeline-review-readiness`](../../recipes/pipeline-review-readiness.json).
297
+ - Task-first workflows: [`pipeline-architect-coordinator`](../../recipes/pipeline-architect-coordinator.json), [`pipeline-research-synthesis`](../../recipes/pipeline-research-synthesis.json), [`pipeline-development-tasking`](../../recipes/pipeline-development-tasking.json), [`pipeline-checkpoint-continuation`](../../recipes/pipeline-checkpoint-continuation.json), [`pipeline-media-library`](../../recipes/pipeline-media-library.json), [`pipeline-room-swarm`](../../recipes/pipeline-room-swarm.json). For room swarms, choose `mode` from `consensus`, `pipeline`, `fanout`, or `pool`; prefer `roles_path` for custom role JSON and keep role `name` ASCII-safe for branch addresses. Use `locker=true` when the swarm needs a coordinator-locker-backed artifact lock and journal.
298
+
299
+ ### Utilities
300
+
301
+ - Repo/release evidence: [`utility-git-status`](../../recipes/utility-git-status.json), [`utility-git-log`](../../recipes/utility-git-log.json), [`utility-changelog-head`](../../recipes/utility-changelog-head.json), [`utility-changelog-section`](../../recipes/utility-changelog-section.json), [`utility-package-summary`](../../recipes/utility-package-summary.json), [`utility-skill-summary`](../../recipes/utility-skill-summary.json).
302
+ - Validation/state: [`utility-validation-wrapper`](../../recipes/utility-validation-wrapper.json), [`utility-validate-recipe`](../../recipes/utility-validate-recipe.json), [`utility-run-summary`](../../recipes/utility-run-summary.json), [`utility-run-ops-snapshot`](../../recipes/utility-run-ops-snapshot.json), [`utility-run-state-files`](../../recipes/utility-run-state-files.json), [`utility-jsonl-tail`](../../recipes/utility-jsonl-tail.json).
303
+ - Artifacts/media/messages: [`utility-artifact-manifest`](../../recipes/utility-artifact-manifest.json), [`utility-artifact-write`](../../recipes/utility-artifact-write.json), [`utility-actor-message`](../../recipes/utility-actor-message.json), [`utility-markdown-index`](../../recipes/utility-markdown-index.json), [`utility-playlist-scan`](../../recipes/utility-playlist-scan.json), [`utility-playlist-build`](../../recipes/utility-playlist-build.json).
304
+
305
+ Deep inventory: [`docs/recipe-library.md`](../../docs/recipe-library.md).
306
+
307
+ ## Operating Patterns
308
+
309
+ - **Short deterministic command**: call foreground registered tool or command template.
310
+ - **Long job/service/fanout**: `spawn` async recipe, then inspect/messages/artifacts.
311
+ - **One-off experiment**: inline `template`; promote after repeat use.
312
+ - **Reusable workflow**: packaged or user recipe with public knobs, mailbox, artifacts, docs.
313
+ - **Subagent/swarm execution**: compose packaged recipes/pipelines from smaller recipe cells; add missing generic cells to the extension rather than creating one-off external orchestration scripts.
314
+ - **Consensus-first build**: when many lenses should shape one artifact, have proposer subagents post room messages, then one named implementer writes, one QA reviewer checks, and one finalizer emits `run.done`; do not ask every lens to mutate the same artifact.
315
+ - **Coordinated workers**: spawn `coordinator-locker` when several actors need a shared queue, acquire/renew/release resource leases, or a journaled coordination point.
316
+ - **Release/review pipeline**: pi-actors can prepare evidence, summaries, and artifacts; external actions such as commit, PR, merge, tag, and publish require the appropriate gated release workflow.
317
+
318
+ ## Complementary Methodology Engines
319
+
320
+ pi-actors is the local execution engine for methodology skills. A methodology skill can define abstract patterns such as lens swarm, quorum, task cards, lock discipline, consensus-first build, or clean-context merge; pi-actors turns those patterns into concrete local actors, recipes, queues, leases, artifacts, and messages.
321
+
322
+ Example mapping:
323
+
324
+ ```text
325
+ methodology says: protect shared files
326
+ pi-actors does: spawn coordinator-locker, enqueue tasks, lease resources
327
+
328
+ methodology says: run reviewers then merge
329
+ pi-actors does: spawn review pipeline, inspect messages/artifacts
330
+ ```
331
+
332
+ Keep the split clean: methodology chooses coordination shape; pi-actors supplies addressable local machinery.
333
+
334
+ ## Lifecycle Discipline
335
+
336
+ 1. Choose existing recipe/tool when available.
337
+ 2. Spawn with a stable actor id for observable work.
338
+ 3. Inspect `status` after launch.
339
+ 4. Use notifications and `inspect`; do not busy-poll.
340
+ 5. Read `messages` and `artifacts`, not only stdout.
341
+ 6. Use `message` for explicit control or domain commands; treat direct branch messages as intended initiating work. Direct branch envelopes are queued under the recipient branch inbox and can be inspected with `inspect branch:<run>/<branch> view=mailbox`; queued entries have stable `id` values and internal `claimed` / `handled` / `failed` states for worker protocols and retries. Room messages are shared transcript/context.
342
+ 7. Promote repeated inline forms to recipes.
343
+ 8. Keep recipes small and shallow: files over 1 MiB or import chains deeper than 32 are rejected.
344
+ 9. Update docs/context when changing public behavior; if the change affects how agents operate this extension, update this skill and the bundled prompt guidance too.
345
+
346
+ ## Common Pitfalls
347
+
348
+ - Treating actor mechanics as multi-agent methodology.
349
+ - Repeating inline templates instead of promoting recipes.
350
+ - Creating task-specific external orchestration scripts when the scenario belongs in pi-actors as a reusable recipe/pipeline with prompts, roles, artifact paths, and model/tool policy passed as args.
351
+ - Embedding complex shell loops or Bash `${...}` parameter expansion directly in command templates; braces are pi-actors placeholders too, so put only generic trusted helper cells in packaged scripts when command-template composition is not enough.
352
+ - Omitting stable run ids for work that needs follow-up.
353
+ - Sending domain messages without checking `mailbox`.
354
+ - Expecting current room messages to wake prompt-only subagents; use direct branch messages or a runner protocol for initiating work.
355
+ - Reading only stdout and missing actor messages/artifacts.
356
+ - Assuming every packaged message-controlled script is native-Windows-ready; core run control is platform-adapted, but Unix-tool scripts must be migrated recipe by recipe.
357
+ - Baking local absolute paths into published docs or reusable recipes.
358
+ - Creating recipes that perform external side effects without explicit operator gates.
359
+ - Letting project insights live only in chat instead of updating BACKLOG/CHANGELOG/docs and, when agent behavior changes, the packaged skill or prompt guidance.
360
+ - Preserving old runtime/event/FIFO vocabulary instead of `spawn`/`message`/`inspect` and actor messages.
361
+
362
+ ## Deep References
363
+
364
+ - `docs/command-templates.md` — execution graph semantics.
365
+ - `docs/template-recipes.md` — recipe storage, imports, defaults, references.
366
+ - `docs/async-runs.md` — detached lifecycle, state, cancellation, observability.
367
+ - `docs/actor-messages.md` — addressed envelope protocol and mailbox model.
368
+ - `docs/tool-registry.md` — persistent tool registry and generated tools.
369
+ - `docs/recipe-library.md` — packaged recipes.
370
+ - `docs/task-first-recipes.md` — deriving reusable pipelines from operator tasks.
371
+ - `docs/component-recipes.md` — reusable coordinator/subagent building blocks.
372
+
373
+ ## One-Sentence Contract
374
+
375
+ Use pi-actors to wrap local capabilities as addressable actors: define launch with templates, preserve semantics in recipes/tools, start with `spawn`, communicate with `message`, observe with `inspect`, and hand off durable results through messages and artifacts.