pi-subagents 0.82.0 → 0.83.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 (93) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +1 -1
  3. package/bundle/agents.js +4 -4
  4. package/bundle/background-work.js +1 -1
  5. package/bundle/child-tool-plan.js +3 -3
  6. package/bundle/{chunk-7PCKZHR5.js → chunk-4BW55BTL.js} +6 -6
  7. package/bundle/{chunk-7IVSUMQQ.js → chunk-527E3D2J.js} +6 -6
  8. package/bundle/{chunk-NRQ75MGH.js → chunk-5ESXK62X.js} +40 -1076
  9. package/bundle/{chunk-ZQGSDHL6.js → chunk-6B4ITO2W.js} +8 -4
  10. package/bundle/{chunk-CIZQXJ5Q.js → chunk-7F5SK2U3.js} +39 -6
  11. package/bundle/{chunk-OYF6AFDY.js → chunk-BKFWQ642.js} +2 -2
  12. package/bundle/{chunk-ZLINIYTP.js → chunk-CDI3GMNV.js} +48 -32
  13. package/bundle/{chunk-GC4DSPMH.js → chunk-CGXWSNPA.js} +12 -18
  14. package/bundle/{chunk-SIJ4S3EN.js → chunk-CNLDYEH4.js} +12 -12
  15. package/bundle/{chunk-4SDU2BZX.js → chunk-CSSZRTKY.js} +2 -2
  16. package/bundle/{chunk-W2SZ22EM.js → chunk-CZTMUBUI.js} +10 -8
  17. package/bundle/{chunk-WVD4UEL4.js → chunk-HJJAVHFB.js} +28 -24
  18. package/bundle/{chunk-GJECHSAR.js → chunk-HLE22FSH.js} +2 -2
  19. package/bundle/{chunk-M2CTFYT3.js → chunk-HXVKGS33.js} +5 -5
  20. package/bundle/{chunk-5LFLVSTM.js → chunk-JEZOSEWG.js} +2 -0
  21. package/bundle/{chunk-YKEWIB4M.js → chunk-JHZ6DZ5M.js} +1 -1
  22. package/bundle/{chunk-B5EKXDHE.js → chunk-LDMXJIA6.js} +458 -657
  23. package/bundle/{chunk-43SCHIMD.js → chunk-MBDOYZ2V.js} +1 -1
  24. package/bundle/{chunk-XSWOTIA3.js → chunk-MHX22USZ.js} +1 -1
  25. package/bundle/{chunk-VH5OAWVG.js → chunk-OOFW75PV.js} +5 -5
  26. package/bundle/{chunk-RMQFMMAT.js → chunk-P2NCCTZP.js} +231 -10
  27. package/bundle/{chunk-NGGAFDL6.js → chunk-RZJN63GU.js} +12 -5
  28. package/bundle/{chunk-7YMXOYEU.js → chunk-TJQJ3MEA.js} +12 -11
  29. package/bundle/{chunk-5TYMSZX3.js → chunk-VTMNBPCQ.js} +2 -2
  30. package/bundle/{chunk-52UBALJL.js → chunk-WG2OTTAK.js} +2 -2
  31. package/bundle/{chunk-N2BN7BF5.js → chunk-XA3DY6UG.js} +7 -5
  32. package/bundle/{chunk-MHZ4G23A.js → chunk-XXKG3P2W.js} +9 -6
  33. package/bundle/{chunk-PLCCBLPY.js → chunk-Y3I6H6DV.js} +2 -2
  34. package/bundle/control-channel.js +3 -3
  35. package/bundle/index.js +1 -1
  36. package/bundle/intercom-bridge.js +3 -3
  37. package/bundle/preflight.js +9 -9
  38. package/bundle/project-panes.js +4 -4
  39. package/bundle/shared-types.js +1 -1
  40. package/docs/agents.md +6 -7
  41. package/docs/configuration.md +1 -1
  42. package/docs/extension-api.md +19 -4
  43. package/docs/observability.md +1 -0
  44. package/docs/tool-reference.md +1 -1
  45. package/package.json +1 -1
  46. package/skills/council-mode/SKILL.md +1 -4
  47. package/skills/pi-subagents/SKILL.md +130 -107
  48. package/skills/pi-subagents/references/orchestration.md +124 -0
  49. package/skills/pi-subagents/references/prompting-and-roles.md +96 -295
  50. package/src/agents/agent-management.js +8 -14
  51. package/src/agents/agent-serializer.js +1 -2
  52. package/src/agents/agents.js +19 -3
  53. package/src/api/background-work.d.ts +9 -6
  54. package/src/api/background-work.js +14 -7
  55. package/src/extension/index.js +4 -1
  56. package/src/extension/public-execution.d.ts +2 -2
  57. package/src/extension/public-execution.js +3 -3
  58. package/src/extension/reply-workflow-script.js +5 -3
  59. package/src/extension/rpc.js +3 -1
  60. package/src/extension/subagent-guide.js +1 -2
  61. package/src/extension/subagent-options.js +17 -4
  62. package/src/runs/background/async-execution.js +4 -1
  63. package/src/runs/background/async-job-tracker.js +2 -1
  64. package/src/runs/background/async-status.d.ts +2 -0
  65. package/src/runs/background/async-status.js +1 -1
  66. package/src/runs/background/auto-drain.js +2 -3
  67. package/src/runs/background/fleet-view.js +1 -1
  68. package/src/runs/background/run-child-session.js +22 -6
  69. package/src/runs/background/subagent-wait.d.ts +2 -1
  70. package/src/runs/background/subagent-wait.js +5 -2
  71. package/src/runs/background/terminal-run-index.d.ts +1 -0
  72. package/src/runs/background/terminal-run-index.js +40 -1
  73. package/src/runs/foreground/execution.js +22 -6
  74. package/src/runs/foreground/subagent-executor.js +2 -5
  75. package/src/runs/shared/child-launch.js +5 -2
  76. package/src/runs/shared/child-session.d.ts +6 -0
  77. package/src/runs/shared/child-session.js +20 -4
  78. package/src/runs/shared/herdr-machine.d.ts +2 -0
  79. package/src/runs/shared/herdr-machine.js +2 -0
  80. package/src/runs/shared/herdr-placed-run.js +11 -4
  81. package/src/runs/shared/subagent-prompt-runtime.js +11 -17
  82. package/src/shared/disabled-features.d.ts +3 -1
  83. package/src/shared/disabled-features.js +11 -3
  84. package/src/shared/types.d.ts +3 -1
  85. package/src/shared/types.js +2 -0
  86. package/src/tui/fleet.js +1 -0
  87. package/src/workflows/scripted-workflow.js +9 -1070
  88. package/workflow-script-worker.cjs +1067 -0
  89. package/skills/pi-subagents/references/constraints-and-recipes.md +0 -74
  90. package/skills/pi-subagents/references/execution-controls.md +0 -564
  91. package/skills/pi-subagents/references/management-authoring-rpc.md +0 -165
  92. package/skills/pi-subagents/references/multi-lane-orchestration.md +0 -61
  93. package/skills/pi-subagents/references/review-and-validation.md +0 -73
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  resolveIntercomSessionTarget
3
- } from "./chunk-XSWOTIA3.js";
3
+ } from "./chunk-MHX22USZ.js";
4
4
  import "./chunk-7F6RKT6W.js";
5
- import "./chunk-CIZQXJ5Q.js";
6
- import "./chunk-5LFLVSTM.js";
5
+ import "./chunk-7F5SK2U3.js";
6
+ import "./chunk-JEZOSEWG.js";
7
7
  import "./chunk-YFCK7H2S.js";
8
8
  import "./chunk-Z7KVHQHL.js";
9
9
  export {
@@ -2,22 +2,22 @@ import {
2
2
  buildEffectiveSystemPrompt,
3
3
  canPreferForkFromSnapshot,
4
4
  resolveSubagentLaunchContext
5
- } from "./chunk-GJECHSAR.js";
6
- import "./chunk-PLCCBLPY.js";
5
+ } from "./chunk-HLE22FSH.js";
6
+ import "./chunk-Y3I6H6DV.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-NGGAFDL6.js";
9
+ } from "./chunk-RZJN63GU.js";
10
10
  import {
11
11
  nestedResultsPath,
12
12
  processTerminalCandidatePath,
13
13
  processTerminalPath,
14
14
  resultFilePath
15
- } from "./chunk-NRQ75MGH.js";
15
+ } from "./chunk-5ESXK62X.js";
16
16
  import {
17
17
  applyIntercomBridgeToAgent,
18
18
  resolveIntercomBridge,
19
19
  validateIntercomBridgeConfig
20
- } from "./chunk-XSWOTIA3.js";
20
+ } from "./chunk-MHX22USZ.js";
21
21
  import {
22
22
  AGENT_DEFINITION_PROJECTION_VERSION,
23
23
  resolveLaunchBinding,
@@ -26,7 +26,7 @@ import {
26
26
  import {
27
27
  applyThinkingSuffix,
28
28
  resolvePiLaunchToolPlan
29
- } from "./chunk-4SDU2BZX.js";
29
+ } from "./chunk-CSSZRTKY.js";
30
30
  import {
31
31
  assertRequiredChildExtensionsAdmitted,
32
32
  resolveRequiredChildExtensions
@@ -34,7 +34,7 @@ import {
34
34
  import {
35
35
  getArtifactPaths,
36
36
  getArtifactsDir
37
- } from "./chunk-5TYMSZX3.js";
37
+ } from "./chunk-VTMNBPCQ.js";
38
38
  import {
39
39
  assertClaudeCodeModelScope,
40
40
  assertThinkingWithinCeiling,
@@ -61,12 +61,12 @@ import {
61
61
  resolveSkillsWithFallback,
62
62
  resolveStepBehavior,
63
63
  unknownAgentDiagnosticContext
64
- } from "./chunk-CIZQXJ5Q.js";
64
+ } from "./chunk-7F5SK2U3.js";
65
65
  import {
66
66
  DIRS,
67
67
  SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
68
68
  TEMP_ROOT_DIR
69
- } from "./chunk-5LFLVSTM.js";
69
+ } from "./chunk-JEZOSEWG.js";
70
70
  import "./chunk-YFCK7H2S.js";
71
71
  import {
72
72
  capabilityCeilingAgentRestrictionMessage,
@@ -8,11 +8,11 @@ import {
8
8
  openProjectPane,
9
9
  projectPaneBindingPath,
10
10
  readProjectPaneBinding
11
- } from "./chunk-52UBALJL.js";
11
+ } from "./chunk-WG2OTTAK.js";
12
12
  import "./chunk-7J4ZXMY7.js";
13
- import "./chunk-5TYMSZX3.js";
14
- import "./chunk-CIZQXJ5Q.js";
15
- import "./chunk-5LFLVSTM.js";
13
+ import "./chunk-VTMNBPCQ.js";
14
+ import "./chunk-7F5SK2U3.js";
15
+ import "./chunk-JEZOSEWG.js";
16
16
  import "./chunk-YFCK7H2S.js";
17
17
  import "./chunk-Z7KVHQHL.js";
18
18
  export {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_FORK_PREAMBLE,
3
3
  wrapForkTask
4
- } from "./chunk-5LFLVSTM.js";
4
+ } from "./chunk-JEZOSEWG.js";
5
5
  export {
6
6
  DEFAULT_FORK_PREAMBLE,
7
7
  wrapForkTask
package/docs/agents.md CHANGED
@@ -43,7 +43,7 @@ Builtins load at the lowest priority, so a user or project agent with the same n
43
43
  | `researcher` | Web/docs research with sources: official docs, specs, benchmarks, recent changes, and a concise research brief. |
44
44
  | `evidence-auditor` | Independent evidence review of important claims in an existing research brief. |
45
45
  | `worker` | Implementation work, including approved oracle handoffs. It edits files, validates, and escalates unapproved decisions instead of guessing. |
46
- | `reviewer` | Code review and small fixes. It checks the implementation against the task/plan, tests, edge cases, and simplicity. |
46
+ | `reviewer` | Read-only code review. It checks the implementation against the task/plan, tests, edge cases, and simplicity. |
47
47
  | `oracle` | A second opinion before acting. It challenges assumptions, catches drift, and recommends the safest next move without editing. |
48
48
  | `delegate` | A lightweight general delegate when you want a child agent that behaves close to the parent session. |
49
49
 
@@ -650,11 +650,10 @@ The package bundles a `pi-subagents` skill that is automatically available to th
650
650
 
651
651
  What it covers:
652
652
 
653
- - **Delegation patterns**: how to select a bounded agent and single, parallel, scripted, or async shape after delegation is authorized, including fresh or forked context.
654
- - **Prompt workflow recipes**: how to apply the packaged techniques directly with `subagent(...)` when the user describes the workflow in natural language instead of invoking a slash command. This includes parallel review, review-loop, parallel research, parallel context-build, parallel handoff-plan, gather-context-and-clarify, and parallel cleanup.
655
- - **Role-agent prompting guidance**: compact contract prompts instead of long scripts, what to include in role-specific meta prompts, and retrieval budgets for researchers.
656
- - **Safety boundaries**: child agents must not run subagents unless their resolved builtin tools explicitly include `subagent`, must not invent intercom targets, and must escalate unapproved decisions.
657
- - **Intercom conventions**: when to ask vs send, and how parent-side supervisor/result delivery works through the native channel.
658
- - **Control and diagnostics**: attention signals, soft interrupts, status, and the `doctor` action.
653
+ - **Calls**: the common `subagent` calls, workflow script and resume shapes, and async waiting rules.
654
+ - **Delegation rules**: when to delegate at all, what every child brief contains, one writer per worktree, fresh or forked context, and what to do when a lane fails.
655
+ - **Prompt workflow recipes**: how to apply the packaged techniques directly with `subagent(...)` when the user describes the workflow in natural language instead of invoking a slash command: parallel review, review loop, parallel research, gather-context-and-clarify, parallel cleanup, and oracle consultation.
656
+ - **Orchestration**: splitting work into lanes, review loops, finding disposition, and gate-failure triage.
657
+ - **Lookups**: which `guide` section answers each rarer question, so the skill does not copy this reference.
659
658
 
660
659
  If you are writing an agent that has been asked to orchestrate subagents, the bundled skill helps it behave correctly without guessing the patterns. If you are a human user, you do not need to read it; the README and prompt shortcuts encode the same workflows in user-facing form.
@@ -124,7 +124,7 @@ Pi records each tool definition and prompt section a session declares, and decla
124
124
  { "disabledFeatures": ["watchdog", "panes", "preflight", "lane-metadata", "gates"] }
125
125
  ```
126
126
 
127
- Removes feature groups you do not use from the `subagent` tool. Each listed feature loses its top-level parameters from the model-facing schema and its `options` keys are rejected, and any request that still uses one of its parameters or actions fails with an error naming this setting. The check covers the parent tool, fanout-child tools, RPC, slash commands, prompt templates, scheduled launches, delegated launches, and workflow `runs.run`/`runs.all`/`runs.lanes` children, which are rejected before they launch. The built-in tool descriptions, the unknown-action list, the fanout-child tool description, and RPC `ping` no longer mention disabled features, and `{ action: "guide", options: { topic: "tool-reference" } }` starts with a notice listing what is disabled. Custom tool descriptions are not changed. Nothing is disabled by default, and the default schema and description are unchanged. An unknown or duplicate feature name fails config loading rather than silently re-enabling every feature.
127
+ Removes feature groups you do not use from the `subagent` tool. Each listed feature loses its top-level parameters from the model-facing schema and its `options` keys are rejected, and any request that still uses one of its parameters or actions fails with an error naming this setting. The check covers the parent tool, fanout-child tools, RPC, slash commands, prompt templates, scheduled launches, delegated launches, and workflow `runs.run`/`runs.all`/`runs.lanes` children, which are rejected before they launch. The built-in tool descriptions, the unknown-action list, the fanout-child tool description, and RPC `ping` no longer mention disabled features. Every `{ action: "guide" }` response starts with a notice: a topic lists what is disabled, and a section points to the `tool-reference` topic for that list. With `workflow-scripts` disabled, the notice also says to use the top-level `tasks` or `chain` fields instead. Custom tool descriptions are not changed. Nothing is disabled by default, and the default schema and description are unchanged. An unknown or duplicate feature name fails config loading rather than silently re-enabling every feature.
128
128
 
129
129
  | Feature | Parameters removed | Actions rejected |
130
130
  |---|---|---|
@@ -129,6 +129,7 @@ Method notes:
129
129
  Capability advertisements on `ping`:
130
130
 
131
131
  - `events.asyncComplete` — exact process-local completion correlation after RPC `spawn`.
132
+ - `events.jobsChanged`, `events.asyncStarted`, `events.childStatus`, `events.processTerminal` — the event names a host can listen to instead of polling `status` (see [Refresh a host view without polling](#refresh-a-host-view-without-polling)).
132
133
  - `managementActions` — exact schedule management actions accepted by RPC `manage`.
133
134
  - `launchResolvedExtensions` — the optional launch-resolved extension projection in status details.
134
135
  - `runtimeAcknowledgedExtensions` — the optional child-runtime acknowledgement projection and event name.
@@ -141,6 +142,20 @@ Capability advertisements on `ping`:
141
142
 
142
143
  Structured delegation progress updates carry `runId` as soon as foreground execution allocates it, so a caller can retain the package-owned revival target even if its own tool turn is interrupted before the terminal response. Foreground `details.results[]` rows also include a numeric `index` that is unique within the run and stable across partial progress snapshots and the final result; use `(runId, index)` instead of row position to correlate single, counted parallel, and chain children.
143
144
 
145
+ ### Refresh a host view without polling
146
+
147
+ A host that shows background subagent activity (an editor panel, a footer, a status bar) can read `status` when something changed instead of on a timer:
148
+
149
+ 1. Subscribe to the names under `ping.events`: `jobsChanged`, `asyncStarted`, `childStatus`, `asyncComplete`, and `processTerminal`.
150
+ 2. Read `status` once, when the host starts or reconnects. Events are not replayed after a host restart, and subscribing first means a change during that read still triggers another one.
151
+ 3. When any of the events fires, read `status` again. Events can arrive in bursts and can repeat, so coalesce them in the host, for example one `status` read per 250 ms, and keep a refresh that arrives while a read is in flight for after it ends.
152
+
153
+ `subagent:jobs-changed` carries only `{ version: 1 }`. It fires whenever the parent's background job view changes: a run starts, moves to another step (no other event reports a chain or parallel run's step changes), reports new activity (a tool, a turn, tokens, or output), finishes, or is cleared from the widget. While a child streams output this can be about once per second per run. Starts and finishes fire right away; step and activity changes fire when the parent next reads the run's status file, which on macOS is a check every 5 seconds. It fires only in sessions with a UI, which covers interactive and RPC mode; print mode (`pi -p`) and SDK embeddings without a UI do not get it. It fires even when the async widget is turned off.
154
+
155
+ Foreground children are not background jobs. Their progress arrives as updates to the parent's `subagent` tool call (Pi's `tool_execution_update` events), with the `details.results[]` rows described above.
156
+
157
+ To rebuild what ran in a session after a reload, read the records the session file already holds: the `subagent` tool result's `details.results[]` for foreground runs and the `subagent-notify` message's `details.runs[]` for background runs (see [Host session lifetime and completion wakes](#host-session-lifetime-and-completion-wakes)). The `cost` method returns per-child rows built from the same records.
158
+
144
159
  ### Direct async launch correlation
145
160
 
146
161
  Direct async runs retain their originating `toolCallId` in status and result
@@ -440,16 +455,16 @@ const dispose = registerBackgroundWorkProvider({
440
455
  name: "my-background-extension",
441
456
  wakeChannels: ["my-extension:job-finished"],
442
457
  listActiveWork: (context) => jobs
443
- .filter((job) => job.status === "running" && (!context || job.ownerSessionId === context.sessionId))
458
+ .filter((job) => job.status === "running" && (!context || context.sessionIds.includes(job.ownerSessionId)))
444
459
  .map((job) => ({ id: job.id, sessionId: job.ownerSessionId })),
445
- reconcile: ({ sessionId, nowMs }) => reconcileJobs(sessionId, nowMs),
460
+ reconcile: ({ sessionIds, nowMs }) => reconcileJobs(sessionIds, nowMs),
446
461
  });
447
462
  ```
448
463
 
449
464
  Semantics:
450
465
 
451
- - Each item needs a stable provider-local ID and the exact Pi session ID that owns it. `bg_wait` captures those identities rather than a count, so one job finishing while another starts still satisfies first-completion waits without losing the replacement.
452
- - `listActiveWork` receives an optional `{ sessionId, nowMs }` context during snapshots. Providers can use `sessionId` to avoid scanning unrelated work; existing zero-argument `() => items` providers continue to work, and returned items are still validated and filtered to the exact requested session.
466
+ - Each item needs a stable provider-local ID and the session that owns it, as either `ctx.sessionManager.getSessionId()` or the session file path (`ctx.sessionManager.getSessionFile()`); both are accepted. `bg_wait` captures those identities rather than a count, so one job finishing while another starts still satisfies first-completion waits without losing the replacement.
467
+ - `listActiveWork` receives an optional `{ sessionId, sessionIds, nowMs }` context during snapshots, and `reconcile` receives the same fields. `sessionIds` holds every form of the current session (its file path when it has one, and its session id); `sessionId` is the first of them. Providers can use them to avoid scanning unrelated work; existing zero-argument `() => items` providers continue to work, and returned items are still validated and filtered to the current session. Each provider is called once per snapshot.
453
468
  - It filters snapshots to the active session, fails closed if a provider disappears while its work is tracked, and surfaces malformed snapshots or provider errors with provider context.
454
469
  - Wake channels only shorten polling; validated snapshots remain authoritative.
455
470
  - Providers share a registry through `Symbol.for("pi-subagents.background-work.v1")`, allowing independently loaded extension modules to meet in one Pi process.
@@ -334,6 +334,7 @@ Async events:
334
334
 
335
335
  - `subagent:async-started`
336
336
  - `subagent:async-complete`
337
+ - `subagent:jobs-changed` (see [extension-api.md](extension-api.md#refresh-a-host-view-without-polling))
337
338
 
338
339
  For regular async starts, the `subagent:async-started` payload includes redacted `task` and `goal` prompt fields. Async workflow script roots emit the same event with `mode: "workflow"` after their initial `status.json` is durable; workflow roots can omit `task`, and any included prompt fields are redacted. Their keyed children are then announced dynamically through `subagent:child-status`. Companion UI extensions can combine those hints with the authoritative live lifecycle artifacts under `asyncDir` without scraping terminal output.
339
340
 
@@ -110,7 +110,7 @@ The `subagent` tool schema lists `agent`, `task`, `workflow`, `args`, `async`, `
110
110
  | `options.checkpointBeforeDeadlineMs` | number | none | Async single-agent runs only. The runner requests that the child "checkpoint and stop" this many milliseconds before the run deadline (finish the current tool call, report changed files, build/test state, remaining work, commit/PR state; start no new work). This best-effort steer uses the normal steering lifecycle at the next tool boundary, so the receipt is visible in status and events; the ordinary deadline kill still applies. Precedence: call value → config `checkpointBeforeDeadlineMs`. Disarmed when the deadline leaves under one second before the checkpoint. |
111
111
  | `options.toolBudget` | object | none | Optional child tool-call budget `{ soft?, hard, block? }`: `hard` is a positive integer and `soft`, if set, is a positive integer no greater than `hard`. At `soft` the child is nudged to finalize. After `hard`, configured tools are blocked; `block` defaults to `read`, `grep`, `find`, and `ls`, and accepts either a nonempty array of tool names or `"*"` for every tool call. Final assistant text is never blocked. |
112
112
  | `options.usageBudget` | object | none | Optional root-only reported-usage budget `{ tokens?: { soft?, hard }, costUsd?: { soft?, hard } }`. Include at least one metric; each `hard` must be positive and each optional `soft` positive and no greater than its `hard`. Soft limits are status-only. Hard limits prevent later child launches after reported usage is reconciled; already-running children are not stopped and no reservations are made. |
113
- | `options.extensionBindings` | object | none | Child-only plain JSON keyed by namespaces like `package.name/1` (positive version): at most 16 namespaces, nesting depth 16, 256 total object properties, and 16 KiB of canonical UTF-8 JSON. Native Pi launches only; external runners and retained resumes reject it. |
113
+ | `options.extensionBindings` | object | none | Child-only plain JSON keyed by namespaces like `package.name/1` (positive version): at most 16 namespaces, nesting depth 16, 256 total object properties, and 16 KiB of canonical UTF-8 JSON. Native Pi launches only; external runners and retained resumes reject it. A child's extensions read it as canonical JSON from `PI_SUBAGENT_EXTENSION_BINDINGS` in their factory or `session_start`; a foreground child sees it only until its session has started, after which the parent's environment is restored. |
114
114
  | `options.preflight` | object | none | Advisory lane hints for raw scripts (`workflow: true` or a script path) only; not accepted with named workflows or direct children. See [bounded workflows](workflows.md#opt-in-bounded-workflows). |
115
115
  | `cwd` | string | runtime cwd | Override working directory. With `machine`, the directory on that machine. |
116
116
  | `options.machine` | string | - | Herdr saved machine (label or profile id) for external-cli agents; see [agents.md](agents.md#running-external-cli-agents-on-a-herdr-saved-machine). |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "pi-subagents",
4
- "version": "0.82.0",
4
+ "version": "0.83.0",
5
5
  "description": "Pi extension for single-agent delegation and scripted multi-agent workflows",
6
6
  "author": "Nico Bailon",
7
7
  "license": "MIT",
@@ -9,10 +9,7 @@ Council mode is parent-supervised advice for a material decision with real trade
9
9
 
10
10
  The parent selects the roster, relays only curated claims, decides validity, and writes the memo. Advisors stay read-only and do not see peer transcripts by default.
11
11
 
12
- Before launch, read:
13
-
14
- - `skills/pi-subagents/references/execution-controls.md`
15
- - `skills/council-mode/references/pass-contracts.md`
12
+ Before launch, read `skills/council-mode/references/pass-contracts.md`.
16
13
 
17
14
  ## Roster
18
15
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: pi-subagents
3
3
  description: |
4
- Technical guidance for operator-requested delegation to builtin or custom
5
- subagents: bounded handoffs, parallel review, scripted workflows, async work,
6
- forked context, isolation, and coordinated execution.
4
+ Delegate work to Pi subagents after the operator asks for it: one child,
5
+ parallel or scripted workflows, async runs, resume/steer/stop, review fanout,
6
+ and multi-lane or worktree orchestration.
7
7
  ---
8
8
 
9
9
  # Pi Subagents
@@ -14,111 +14,134 @@ instructions. Task size, complexity, risk, tool-call count, recipe fit, or an
14
14
  available specialist does not independently authorize delegation.
15
15
 
16
16
  Once authorized, choose the smallest bounded shape that earns its token and
17
- elapsed-time overhead through concrete evidence, independent review,
18
- specialization, useful parallelism, or needed isolation. A single child is
19
- valid; writer, challenge, and review stages must each earn their overhead rather
20
- than becoming default ceremony. The parent keeps user intent, constraints,
21
- routing, arbitration, decisions, final acceptance, and publication authority,
22
- and may perform the work directly where it is the most efficient owner.
17
+ elapsed-time overhead through evidence, independent review, specialization,
18
+ useful parallelism, or isolation. A single child is valid. The parent keeps
19
+ intent, routing, decisions, final acceptance, and publication authority, and
20
+ does the work itself where that is cheaper.
21
+
22
+ ## Calls
23
+
24
+ ```typescript
25
+ subagent({ agent: "worker", task: "<brief>" }) // one child; async by default
26
+ subagent({ workflow: "parallel", args: { tasks: [{ agent, task, cwd?, model? }] } }) // independent children
27
+ subagent({ workflow: true }) // runs the one ```js workflow block in this same reply
28
+ subagent({ workflow: "./lane.js", args }) // script file, path relative to the request cwd
29
+ subagent({ action: "validate", workflow: "./lane.js" }) // check a script without launching
30
+ subagent({ action: "status", id }) // options: { view: "fleet" } or { view: "transcript", index: 0 }
31
+ subagent({ action: "resume", id, message }) // completed or paused child; returns a new run id
32
+ subagent({ action: "steer", id, message }) // live async child
33
+ subagent({ action: "stop", id }) // ends the run; not resumable
34
+ subagent({ action: "interrupt", id }) // pauses the child's current turn
35
+ subagent({ action: "list" }) · subagent({ action: "models" })
36
+ subagent({ action: "guide", options: { topic: "<section address>" } })
37
+ ```
38
+
39
+ Launches are async by default. Set `async: false` only when the parent must
40
+ block; final reviews and gates stay async. After launching, keep doing safe
41
+ independent work, or yield: native completion wakes this session. Do not sleep,
42
+ poll, or call `bg_wait` for ordinary children. Use `bg_wait` only for provider
43
+ or detached work that has no native notification and whose result this turn
44
+ needs.
45
+
46
+ ## Workflow scripts
47
+
48
+ Use a script when later steps depend on earlier results, or for keyed,
49
+ retried, aggregated, or resumed children. Write one ```` ```js workflow ````
50
+ block in the reply and call `subagent({ workflow: true })` in the same reply.
51
+ For a long script, write it to a file and pass `workflow: "./path.js"`; calls in
52
+ one reply run at the same time, so write the file in one reply and `validate` or
53
+ launch it in the next. When a `workflow: true` call reports the block missing,
54
+ pass the source as `options: { script: "..." }` in place of `workflow: true` for
55
+ the rest of the turn: on some hosts, text after a tool call reaches the session
56
+ as a summary without the block.
57
+
58
+ ```js workflow
59
+ const scan = await runs.run("scan", { label: "Map auth flow", agent: "scout", task: "..." });
60
+ const reviews = await runs.all([
61
+ { key: "correctness", label: "Review auth correctness", agent: "reviewer", task: "... " + scan.output },
62
+ { key: "tests", label: "Review auth tests", agent: "reviewer", task: "..." },
63
+ ]);
64
+ return reviews.map((review) => review.output);
65
+ ```
66
+
67
+ - Scripts are statement bodies with an explicit `return`, top-level `await`,
68
+ and plain helpers. Nested async functions, arrows, and methods are rejected.
69
+ - Every `runs.run` / `runs.all` item needs a stable `key`. Add a short
70
+ verb + behavior `label` unless the user gave one.
71
+ - Bind files with `output: "plans/x.md"` (relative paths land in run
72
+ artifacts) and return `outputReference` or `artifactPaths`. A filename in
73
+ task text does not route output. Never send reports to the repo root.
74
+ - `runs.lanes([{ key, stages: [...] }])` runs a predeclared plan: first stages
75
+ together, later stages in order per lane.
76
+
77
+ Resuming a retained child:
78
+
79
+ ```js workflow
80
+ let child = await runs.run("fix-1", { agent: "worker", task: "..." });
81
+ child = await runs.run("fix-2", { resume: child.runId, task: "Apply these accepted findings: ..." });
82
+ return child.output;
83
+ ```
84
+
85
+ - Always resume the latest returned run id; every resume returns a new one.
86
+ - Use a new stable key for every resume pass.
87
+ - `resume` excludes `agent` and `gate`; the child keeps its agent, model, and tools.
88
+ - Resume a completed child; steer a live one. Top-level `{ action: "resume" }` is detached.
89
+
90
+ ## Briefs
91
+
92
+ Every child starts cold. Its task states: goal; repo, explicit `cwd`, and
93
+ ref; authority and edit boundary; relevant files, decisions, and evidence;
94
+ success criteria; validation; expected output; and when to stop or ask.
95
+ Make parallel briefs differ by seam, evidence, and decision, not just an item
96
+ number.
97
+
98
+ ## Rules
99
+
100
+ - One writer per cwd or worktree. Parallelize reading, review, and
101
+ validation. `worktree: true` needs a clean checkout (untracked files count;
102
+ `.pi/subagents/` does not). For Pi extension repos, put lane worktrees
103
+ outside `~/.pi/agent/extensions`, for example `~/.pi/agent/worktrees`.
104
+ - Reviewers use fresh context. Use `context: "fork"` only when the child needs
105
+ the parent's history; it requires a persisted parent session.
106
+ - Children do not spawn subagents unless the parent delegated fanout and their
107
+ resolved `tools` include `subagent`.
108
+ - A failed workflow, launch, prompt runtime, extension load, or child tool
109
+ setup blocks the lane. Stop, report the exact failure and run/worktree state,
110
+ verify a clean worktree or capture the partial diff, then retry the same way
111
+ once. Switching to `interactive_shell`, `pi -ne`, or another CLI needs owner
112
+ approval.
113
+ - As a conservative orchestration policy, do not pass a hard `toolBudget` or tight `usageBudget` to mutation-capable workers. The default tool budget blocks read/search tools rather than mutation tools. If interrupted after a tool call starts, checkpoint after the current tool returns with changed files, build/test state, and commit or PR state.
114
+ - Route workers and scouts to a fast capable tier, serious reviews to a strong
115
+ tier, and top reasoning only to bounded read-only critique. Exact model names
116
+ belong in user or project settings, not here.
117
+ - `subagent`, `subagents_enable`, `subagent_supervisor`, `contact_supervisor`, and `structured_output` are model-only: call them as ordinary model tool calls. Codemode scripts cannot reach them through `tools.*`, `ALL_TOOLS`, or `searchTools`.
118
+ - Receipts, CI, and review bots are evidence, not authority. Backlog, release,
119
+ and merge policy belong to the user's or project's own skill.
23
120
 
24
- Children do not spawn subagents unless the parent explicitly delegated fanout
25
- and their resolved `tools` allow `subagent`.
121
+ ## Look up the rest
26
122
 
27
- ## Launch shape
123
+ If only `subagents_enable` is visible, call it first; `subagent` and `guide`
124
+ work from the next request. Read one section, not a whole topic:
28
125
 
29
- | Need | Use |
30
- | --- | --- |
31
- | One bounded task for one child | direct `{ agent, task }` |
32
- | JavaScript control flow or data-dependent branching; sequence, fanout, retry, rolling fanout, or aggregation | a workflow script with `runs.run(...)` / `runs.all(...)` |
33
- | A broad plan split into visible narrow stages per lane | a workflow script with `runs.lanes([{ key, stages: [...] }])` |
34
- | Independent worktree or repository lanes | `references/multi-lane-orchestration.md` |
35
- | Council of advisors | `../council-mode/SKILL.md` |
36
- | Management, status, steering, authoring, or inspection | `action` |
37
-
38
- To launch a workflow script, write it as one ```` ```js workflow ```` fenced
39
- block in your reply, then call `subagent({ workflow: true, ... })` in the same
40
- reply. Use `workflow: "./path/to/script.js"` for a script file and
41
- `workflow: "<name>"` for a named resource.
42
-
43
- A workflow script is code-driven: `runs.run(...)` for keyed steps,
44
- `runs.all([...])` for fanout, plain JavaScript for branching and aggregation.
45
- Keep scripts portable: use top-level `await`, plain helpers, or explicit Promise
46
- chains, not nested async helpers. Legacy top-level `chain` / `tasks` inputs and
47
- durable `.chain.md` execution are inspection or migration material only, except
48
- that `disabledFeatures: ["workflow-scripts"]` replaces scripts with top-level
49
- `chain` and `tasks` (see [configuration](../../docs/configuration.md#chain-and-tasks-without-workflow-scripts)).
50
-
51
- Use `runs.lanes(...)` only inside a workflow script, not as a top-level mode,
52
- when a broad, predeclared plan benefits from visible per-lane stages; otherwise
53
- use ordinary `runs.run(...)` / `runs.all(...)`. See the [canonical staged-lane
54
- example](../../docs/workflows.md#parallel-sequential-lanes). Keep assignments
55
- bounded, but do not add stages or ceremony just to satisfy this skill.
56
-
57
- When composing `runs.run(...)`, `runs.all(...)`, or `runs.lanes(...)`, always
58
- supply a short verb + behavior display `label` derived from the task, unless
59
- the user supplied an explicit label; preserve that label. Keep the stable
60
- machine `key` independent (for example, `issue2011-writer` with
61
- `label: "Fix workflow steering"`). For `runs.lanes`, put labels on stage
62
- items, not lane objects. Use stage-appropriate labels for reviews and retained-child
63
- follow-ups too (for example, `Review workflow steering`). Generate labels in
64
- the orchestrator while composing the launch—no extra model call, runtime
65
- generator, or schema change. Native direct `{ agent, task }` calls have no
66
- top-level `label` parameter; do not invent one or wrap a tiny single task in
67
- a workflow just to label it.
68
-
69
- Use async/background by default. Set `async:false` only when the parent must
70
- block. Final reviews, validation gates, oracle checks, and publication checks
71
- stay async.
72
-
73
- In an ordinary interactive session, yield after launching or triaging useful
74
- async lanes and let Pi wake the parent on completion; ordinary async subagents
75
- already have native completion notifications, so do not call `bg_wait()` merely
76
- because a child is active. Use blocking `bg_wait()` only for provider,
77
- detached, or other background work without a native notification when a
78
- headless/run-to-completion contract or a required same-turn artifact makes the
79
- result necessary before this turn ends. For
80
- “continue/orchestrate/work until done,” keep the lane board moving while a safe
81
- immediate action remains; if only async lanes are running, record the revisit
82
- trigger and yield.
83
-
84
- Package agents appear in `subagent({ action: "list" })`. External CLI/job agents
85
- use their own runner contract. Do not pass native Pi child options to them unless
86
- that runner explicitly supports the option.
87
-
88
- ## Read the reference for the branch
89
-
90
- For exact API fields and worked examples, call `subagent({action:"guide",options:{topic:"tool-reference"}})` or `topic:"workflows"`. The compact tool definition is not the recipe catalog; use `topic:"missions"` for mission updates and schedules.
91
-
92
- | Branch | Read |
126
+ | Need | Guide section |
93
127
  | --- | --- |
94
- | Delegate or choose roles, prompts, models, or slash commands | `references/prompting-and-roles.md` |
95
- | Execute single, scripted, async, scheduled, mission, forked, watchdog, oracle, or intercom workflows | `references/execution-controls.md` |
96
- | Review, validate, triage gate failures, or prepare delivery | `references/review-and-validation.md` |
97
- | Coordinate lanes, worktrees, repositories, or writer waves | `references/multi-lane-orchestration.md` |
98
- | List, create, edit, disable, eject, or expose agents/RPC | `references/management-authoring-rpc.md` |
99
- | Check safety constraints, recipes, or error handling | `references/constraints-and-recipes.md` |
100
-
101
- For an authorized complex delegated workflow, read `prompting-and-roles.md` and
102
- `execution-controls.md`, then load `review-and-validation.md` and
103
- `constraints-and-recipes.md` before launch or review.
104
-
105
- ## Operating rules
106
-
107
- - Avoid duplicate scouts, overlapping writers, and vague prompts without a concrete deliverable.
108
- - Call `subagent`, `subagents_enable`, `subagent_supervisor`, `contact_supervisor`, and `structured_output` as ordinary model tool calls. They are model-only, so codemode scripts cannot reach them through `tools.*`, `ALL_TOOLS`, or `searchTools`.
109
- - Keep the parent on the ordinary strong default model. Route workers/scouts to a fast capable tier, serious reviews to a strong tier, and top reasoning to bounded read-only critique.
110
- - Exact model names are deployment policy. Put them in user/project settings or profiles, not package guidance.
111
- - Give every child a compact meta-prompt checklist: objective; repo/cwd/ref; authority/edit boundary; relevant files/contracts and constraints; success/acceptance criteria; validation; expected output/report; and stop/ask conditions. See `references/prompting-and-roles.md`.
112
- - Before launching a writer for substantial mutation work, classify it as single-seam or multi-seam and partition multi-seam work across exclusive component owners, gates, and durable handoffs before an integration-only owner. See `references/multi-lane-orchestration.md`.
113
- - For mutation work, use an isolated lane/worktree when isolation, overlap, or concurrent juggling matters; keep one writer per cwd/worktree. `worktree: true` refuses to launch unless the source checkout is clean (untracked files count; `.pi/subagents/` does not), so commit your own changes first or plan the lane without managed isolation. See `references/multi-lane-orchestration.md` for lane mechanics.
114
- - Keep long/high-output validation out of chat: prefer `interactive_shell` dispatch/background monitors, bounded logs, or subagent-owned reports; return a concise summary plus report path unless same-turn output is required. Do not use `interactive_shell` as an implicit fallback for a failed `subagent` lane; see `references/execution-controls.md`.
115
- - Treat subagent workflow, child launch, prompt runtime, extension load, and child tooling setup failures as lane infrastructure blockers. Stop, report the exact failure and run/worktree state, verify a clean worktree or capture a partial diff, and use only a clear same-protocol retry or an owner-approved execution-mode fallback.
116
- - For cross-codebase work, record the repo, explicit `cwd`, authority boundary, and expected output before launch.
117
- - Make parallel prompts distinct by source seam, evidence, and decision. Do not clone prompts with only item numbers swapped.
118
- - Prefer fresh-context review/validation fanout, then synthesize and apply fixes in the parent.
119
- - For Pi extension repos under `~/.pi/agent/extensions`, put lane worktrees outside extension auto-discovery, such as `~/.pi/agent/worktrees`.
120
- - Preserve capability ceilings, including child tool limits and allowed-agent restrictions.
121
- - Preserve parent authority and escalate unresolved choices.
122
- - Treat receipts, CI, review bots, and external-run records as evidence, not authority.
123
- - For backlog maintenance, releases, merge queues, or other public-repo mutation policy, load the matching user/project skill. This package defines delegation primitives, not private policy.
124
- - As a conservative orchestration policy, do not pass a hard `toolBudget` or tight `usageBudget` to mutation-capable workers. The default tool budget blocks read/search tools rather than mutation tools. If interrupted after a tool call starts, checkpoint after the current tool returns with changed files, build/test state, and commit or PR state.
128
+ | Script API: `runs.*`, `state`, limits | `workflows/scripted-workflows` |
129
+ | Typed gates, host commands, rolling fanout | `workflows/typed-post-run-checks-and-typed-steps`, `workflows/host-command-steps`, `workflows/advanced-rolling-child-runs` |
130
+ | Budgets, timeouts, `baseRef`, `gate`, `output` | `tool-reference/execution-parameters`, `tool-reference/output-mode-details` |
131
+ | Fresh or forked context | `tool-reference/fork-context-details` |
132
+ | Resume, steer modes, stop, status | `tool-reference/retained-children`, `tool-reference/resume`, `tool-reference/steer`, `tool-reference/stop`, `tool-reference/status` |
133
+ | Acceptance and review gates | `tool-reference/acceptance-gates` |
134
+ | Worktrees and handoffs | `workflows/worktree-isolation` |
135
+ | Child asks the parent (`contact_supervisor`) | `workflows/supervisor-coordination-child-asks-parent` |
136
+ | Agent create, update, eject, disable, refine | `tool-reference/management-actions`, `agents/frontmatter-reference` |
137
+ | Missions and schedules | `missions/missions`, `missions/schedules` |
138
+ | Watchdog | `watchdog/when-it-runs`, `watchdog/choosing-a-model` |
139
+ | Model overrides and profiles | `models/setting-defaults-and-overrides` |
140
+ | Other projects in panes | `tool-reference/herdr-project-panes` |
141
+ | Setup looks wrong | `subagent({ action: "doctor" })` |
142
+
143
+ ## References
144
+
145
+ - Choosing roles, writing prompts, review/research/cleanup techniques, oracle → [prompting-and-roles.md](references/prompting-and-roles.md)
146
+ - Several lanes, worktrees, repositories, staged fixes, review loops, finding and gate triage → [orchestration.md](references/orchestration.md)
147
+ - Advisor council → [../council-mode/SKILL.md](../council-mode/SKILL.md)
@@ -0,0 +1,124 @@
1
+ # Orchestration
2
+
3
+ Use this when several tasks need coordinated children, worktrees, or
4
+ repositories, or when a change goes through write, review, and fix rounds.
5
+ Create lanes only after delegation is operator-authorized and each lane
6
+ materially improves evidence, independent review, specialization, useful
7
+ parallelism, or isolated execution. Keep dependent work serial.
8
+
9
+ ## Recipes
10
+
11
+ Recipes select a shape; they do not authorize delegation. Pick the smallest:
12
+
13
+ - **Recon then implement:** one focused `scout`, then one `worker` that gets its findings.
14
+ - **Implementation:** settle scope and acceptance first, then use a scout, writer, or fresh reviewer only where that stage earns its overhead. Split large work into serial milestones, not a writer swarm.
15
+ - **Parallel analysis:** fan out only independent read, review, or validation work, or give each writer its own worktree.
16
+
17
+ ## Seams before writers
18
+
19
+ Before launching a writer for substantial mutation work, classify it as
20
+ **single-seam** or **multi-seam**. Two or more independently testable
21
+ contracts or source boundaries make it multi-seam. One PR does not imply one
22
+ writer.
23
+
24
+ - **Multi-seam:** give each component writer exclusive file or contract
25
+ ownership, a focused gate, and a committed or otherwise durable handoff.
26
+ Start one integration-only owner after those handoffs are ready. Repartition
27
+ any writer brief that owns all major outcomes across independent boundaries.
28
+ - **Single-seam:** one writer is right when the work is one coupled seam, or
29
+ when splitting would create overlapping ownership or artificial handoffs.
30
+ Record that evidence. Do not split coupled work to raise the lane count.
31
+
32
+ ## Lane board
33
+
34
+ Before more than one mutation-capable lane starts, record in the parent:
35
+
36
+ `Lane | repo/cwd | decision | owned files or contract | isolation path | authority | next gate | handoff | why independent`
37
+
38
+ One source seam or decision is one lane. Record each lane's delivery target,
39
+ allowed actions, validation, and review rigor. For cross-repository work,
40
+ name the shared contract and which repository changes first. A blocked
41
+ decision is a lane state: owner, options, recommended default, and the
42
+ evidence needed to continue.
43
+
44
+ Mutation lanes need distinct isolation paths and explicit `cwd` values.
45
+ `worktree: true` branches from `HEAD` (or `baseRef`) and refuses a dirty
46
+ checkout; in a shared or dirty checkout, commit first or give each lane a
47
+ worktree you created. Use one async workflow for a coordinated wave:
48
+ `runs.all` for independent lanes, `runs.run` for dependent stages, repo slug
49
+ or lane key in every child key and output path.
50
+
51
+ While one lane waits, run safe independent preparation, validation, or
52
+ read-only review. When only async lanes remain, record what reopens work and
53
+ yield; completion wakes the parent.
54
+
55
+ ## Review loop
56
+
57
+ 1. Inspect the source, diff, issue, or plan directly.
58
+ 2. One writer implements inside its boundary and runs focused validation that can fail for the changed behavior.
59
+ 3. When the delegation contract calls for independent review, fresh-context read-only reviewers inspect the actual worktree. Otherwise parent inspection is enough; skip review for trivial wording, renames, or local probes.
60
+ 4. The parent classifies findings (below) and sends accepted fixes to one writer: resume the original worker with its latest run id, or launch one forked `worker` as `/review-loop` does.
61
+ 5. Re-run affected validation and review only the changed blast radius.
62
+ 6. Stop when no blocker or fix worth doing now remains, an unapproved product, scope, or architecture decision appears, or the round cap is reached (default 3). Do not loop for polish. Children never decide the loop outcome.
63
+
64
+ An async writer's handoff is an intermediate state, not completion, unless the
65
+ user asked for writer-only work.
66
+
67
+ | Situation | Review shape |
68
+ | --- | --- |
69
+ | One coherent diff or risk | one reviewer |
70
+ | Independent risks (correctness, tests, security, UI) | parallel reviewers with distinct contracts |
71
+ | Possible over-scope | same-writer challenge before fresh review |
72
+ | Material design tradeoff | council mode |
73
+
74
+ ### Staged fixes
75
+
76
+ When reviews have produced findings across several clusters:
77
+
78
+ 1. Run a read-only planning fanout, one reviewer per cluster or angle, each returning exact files, lines, fixes, and validation.
79
+ 2. Classify the accepted fixes as single-seam or multi-seam (above) on the lane board before any writer starts.
80
+ 3. Give a writer only its assigned stage. Pass each earlier result into the later task by variable or by its declared `output` path, not as a whole aggregate blob. With `runs.lanes`, keep stages narrow: red test, helper change, one render seam, validation, review.
81
+ 4. Validate the integrated result with fresh read-only reviewers on distinct angles.
82
+
83
+ When a child returns a target list, validate it in JavaScript and map bounded
84
+ entries into `runs.all`.
85
+
86
+ ## Finding disposition
87
+
88
+ Classify each finding against the current head:
89
+
90
+ - **Valid blocker:** concrete failure, repro, security issue, contract mismatch, or source-proven regression. Fix now.
91
+ - **Valid non-blocker:** real but outside the slice. Record or defer.
92
+ - **Stale:** already fixed or absent. Cite current evidence.
93
+ - **Invalid:** contradicted by source, tests, docs, or approved scope. Cite it.
94
+ - **Out of scope or policy:** needs an unapproved product, architecture, authority, or release decision. Escalate.
95
+ - **Speculative:** no contract, repro, or reachable failure. Do not block.
96
+
97
+ Classify bot comments the same way before assigning severity.
98
+
99
+ ## Gate failures
100
+
101
+ 1. Confirm the run belongs to the exact head under judgment.
102
+ 2. Read the focused failing log; name the failing test, assertion, or contract.
103
+ 3. Classify: current diff, stale test, environment, or existing flake.
104
+ 4. Reproduce with the narrowest command when practical.
105
+ 5. Patch forward when the diff caused it. For a stale or flaky failure, collect proof before one rerun.
106
+ 6. Re-run the affected command or exact-head gate after every fix.
107
+
108
+ ## Handoff and cleanup
109
+
110
+ A handoff states lane status, repository and worktree, changed files,
111
+ validation, open decisions, next action, and artifact or receipt paths. Copy
112
+ only final evidence to memory, a mission, a PR, or an approved docs path, then
113
+ remove scratch reports from the worktree.
114
+
115
+ Keep a worktree until its handoff is durable, no run owns it, and no later
116
+ gate needs it. If a run stops or needs attention, preserve its worktree and
117
+ artifacts, then resume that run or start one replacement lane from the
118
+ handoff. Never start a second writer while worktree ownership is unclear.
119
+
120
+ Before reporting done, check the board: every lane terminal or blocked with a
121
+ named next action; one writer per worktree; required validation and fresh
122
+ review done; accepted findings fixed and revalidated; publication authority
123
+ present before any push, comment, merge, or release; residual risks and
124
+ skipped checks stated.