@wichayutdew/pi-workflows 1.0.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/README.md +320 -223
  2. package/agents/step.md +4 -11
  3. package/dist/index.js +2554 -976
  4. package/examples/mr-comments.workflow.yaml +16 -8
  5. package/examples/prompts/mr-comments/implement.md +13 -9
  6. package/examples/prompts/mr-comments/plan.md +44 -15
  7. package/examples/prompts/mr-comments/verify.md +8 -7
  8. package/examples/settings.yaml +7 -1
  9. package/examples/starter-kit/mr-comment.workflow.yaml +149 -0
  10. package/examples/starter-kit/mr-review.workflow.yaml +130 -0
  11. package/examples/starter-kit/steps/mr-comment/fetch.md +33 -0
  12. package/examples/starter-kit/steps/mr-comment/implement.md +38 -0
  13. package/examples/starter-kit/steps/mr-comment/plan.md +62 -0
  14. package/examples/starter-kit/steps/mr-comment/publish.md +36 -0
  15. package/examples/starter-kit/steps/mr-comment/verify.md +35 -0
  16. package/examples/starter-kit/steps/mr-review/fetch.md +25 -0
  17. package/examples/starter-kit/steps/mr-review/publish.md +30 -0
  18. package/examples/starter-kit/steps/mr-review/review.md +69 -0
  19. package/examples/starter-kit/steps/mr-review/verify.md +24 -0
  20. package/examples/starter-kit/steps/shared/prepare-workspace.md +57 -0
  21. package/examples/starter-kit/steps/ticket/implement.md +35 -0
  22. package/examples/starter-kit/steps/ticket/plan.md +40 -0
  23. package/examples/starter-kit/steps/ticket/verify.md +29 -0
  24. package/examples/starter-kit/steps/work/implement.md +34 -0
  25. package/examples/starter-kit/steps/work/plan.md +38 -0
  26. package/examples/starter-kit/steps/work/verify.md +30 -0
  27. package/examples/starter-kit/ticket.workflow.yaml +100 -0
  28. package/examples/starter-kit/work.workflow.yaml +97 -0
  29. package/package.json +3 -3
  30. package/schemas/workflow.schema.json +78 -44
  31. package/src/command-names.ts +1 -0
  32. package/src/commands.ts +33 -4
  33. package/src/config/ceiling.ts +6 -12
  34. package/src/config/load-workflows.ts +12 -1
  35. package/src/config/step-digests.ts +19 -0
  36. package/src/config/types.ts +17 -22
  37. package/src/config/validation/permissions.ts +5 -66
  38. package/src/config/validation/prompt.ts +1 -0
  39. package/src/config/validation/shared.ts +0 -2
  40. package/src/config/validation/step.ts +106 -2
  41. package/src/config/validation/workflow.ts +76 -0
  42. package/src/engine/create-run.ts +3 -0
  43. package/src/engine/gate-transitions.ts +58 -9
  44. package/src/engine/reconciliation-history.ts +61 -24
  45. package/src/engine/run-advance.ts +37 -4
  46. package/src/engine/run-lifecycle.ts +11 -0
  47. package/src/engine/run-reconciliation.ts +51 -21
  48. package/src/engine/run-validation.ts +235 -0
  49. package/src/engine/run-workflow-validation.ts +191 -0
  50. package/src/engine/state-types.ts +108 -5
  51. package/src/engine/state.ts +15 -1
  52. package/src/engine/step-trace.ts +495 -0
  53. package/src/engine/transitions.ts +1 -0
  54. package/src/harness/action-context.ts +31 -6
  55. package/src/harness/core-actions.ts +30 -1
  56. package/src/harness/delegation-control-actions.ts +27 -2
  57. package/src/harness/delegation-failure.ts +42 -9
  58. package/src/harness/delegation-plan.ts +96 -40
  59. package/src/harness/delegation-recovery-validation.ts +3 -1
  60. package/src/harness/delegation-response-actions.ts +73 -3
  61. package/src/harness/delegation-retry-policy.ts +5 -3
  62. package/src/harness/dependencies.ts +11 -2
  63. package/src/harness/gate-submission-action.ts +5 -31
  64. package/src/harness/lifecycle-actions.ts +4 -5
  65. package/src/harness/pause-actions.ts +10 -1
  66. package/src/harness/plannotator-result-actions.ts +20 -11
  67. package/src/harness/prompt-gate-actions.ts +40 -2
  68. package/src/harness/resume-action.ts +75 -1
  69. package/src/harness/start-actions.ts +77 -3
  70. package/src/harness/status-actions.ts +7 -17
  71. package/src/harness/step-effects.ts +61 -0
  72. package/src/harness/step-execution-actions.ts +181 -25
  73. package/src/harness/step-reporting.ts +168 -0
  74. package/src/harness/types.ts +1 -0
  75. package/src/harness/workspace-directory.ts +67 -0
  76. package/src/harness.ts +37 -9
  77. package/src/integrations/plannotator-requests.ts +40 -5
  78. package/src/integrations/subagents/child-policy-sections.ts +71 -84
  79. package/src/integrations/subagents/child-policy-types.ts +7 -7
  80. package/src/integrations/subagents/child-policy-validation.ts +10 -4
  81. package/src/integrations/subagents/child-runtime-completion.ts +1 -0
  82. package/src/integrations/subagents/child-runtime-files.ts +29 -86
  83. package/src/integrations/subagents/child-runtime-policy.ts +8 -33
  84. package/src/integrations/subagents/child-runtime.ts +3 -15
  85. package/src/integrations/subagents/delegated-result.ts +1 -0
  86. package/src/integrations/subagents/diagnostic-format.ts +5 -0
  87. package/src/integrations/subagents/diagnostic-types.ts +7 -1
  88. package/src/integrations/subagents/diagnostics.ts +2 -0
  89. package/src/integrations/subagents/failure-correlation.ts +52 -2
  90. package/src/integrations/subagents/failure-transcript.ts +60 -1
  91. package/src/integrations/subagents/replay-audit.ts +0 -1
  92. package/src/integrations/subagents/replay-safety.ts +12 -27
  93. package/src/integrations/subagents/session-diagnostics.ts +102 -3
  94. package/src/policy/bash-authorization.ts +2 -21
  95. package/src/policy/bash-types.ts +0 -5
  96. package/src/policy/bash.ts +1 -2
  97. package/src/policy/tool-call-authorization.ts +1 -7
  98. package/src/preflight.ts +0 -5
  99. package/src/prompt/retry-task.ts +11 -3
  100. package/src/prompt/step-contract.ts +10 -56
  101. package/src/prompt/step-sections.ts +8 -10
  102. package/src/prompt/step-task.ts +41 -10
  103. package/src/prompt/template.ts +3 -2
  104. package/src/runtime/completion-tool.ts +14 -0
  105. package/src/runtime/main-step-completion.ts +3 -0
  106. package/src/runtime/main-step-policy.ts +2 -1
  107. package/src/runtime/main-step-runtime-types.ts +9 -1
  108. package/src/runtime/main-step-runtime.ts +2 -0
  109. package/src/runtime/main-step-state.ts +6 -0
  110. package/src/runtime/main-step-trace.ts +45 -0
  111. package/src/runtime/step-result.ts +57 -0
  112. package/src/step-log.ts +178 -0
  113. package/src/workflow-doctor.ts +254 -0
  114. package/src/workflow-status/format-status.ts +32 -3
  115. package/src/workflow-status/render-board.ts +7 -4
  116. package/src/workflow-status/render-path.ts +51 -24
  117. package/src/workflow-status/render-step-detail.ts +379 -0
  118. package/src/workflow-status/render-summary.ts +22 -0
  119. package/src/workflow-status/transcript-reader.ts +231 -0
  120. package/src/workflow-status/types.ts +8 -0
  121. package/src/workflow-status/view.ts +161 -14
  122. package/src/workflow-status.ts +6 -0
  123. package/src/policy/approved-command-extraction.ts +0 -71
  124. package/src/policy/approved-commands.ts +0 -15
  125. package/src/policy/bash-read-only.ts +0 -161
  126. package/src/policy/restricted-git.ts +0 -30
  127. package/src/policy/reviewed-artifact.ts +0 -97
  128. package/src/policy/reviewed-command-safety.ts +0 -150
  129. package/src/policy/reviewed-command-shape.ts +0 -49
  130. package/src/policy/reviewed-repository-contract.ts +0 -138
  131. package/src/policy/reviewed-repository-cwd.ts +0 -102
package/README.md CHANGED
@@ -1,8 +1,20 @@
1
+ # Pi Workflows
2
+
3
+ **Turn repeatable agent work into declarative, pauseable workflows that cannot
4
+ silently loop forever.** Put the steps, tools, prompts, approvals, and outcomes
5
+ in YAML; Pi Workflows supplies durable checkpoints, finite automatic execution,
6
+ and a live status view without learning your language, framework, or process.
7
+
1
8
  [![codecov](https://codecov.io/gh/wichayutdew/pi-workflows/graph/badge.svg?token=33xrCBRM82)](https://codecov.io/gh/wichayutdew/pi-workflows)
2
9
 
3
- # Pi Workflows
10
+ ```bash
11
+ pi install npm:@wichayutdew/pi-workflows
12
+ ```
4
13
 
5
- A declarative, pauseable workflow harness for Pi.
14
+ - Compose main-agent and isolated subagent steps from one strict YAML contract.
15
+ - Pause for built-in or Plannotator review, then resume the same checkpoint.
16
+ - Reject dead-end graphs up front and pause bounded cycles at `maxStepVisits`.
17
+ - Keep every domain decision in your workflow files—not in the harness.
6
18
 
7
19
  ## Overview
8
20
 
@@ -47,43 +59,115 @@ delegated step cannot start.
47
59
 
48
60
  Pi loads `src/index.ts` through the package manifest. Restart Pi or run `/reload` after changing extension source.
49
61
 
50
- ## Add a workflow
62
+ ## Quick start: bootstrap four practical workflows
51
63
 
52
- User workflows live in one of these formats:
64
+ The checked-in [`examples/starter-kit`](./examples/starter-kit) is a portable,
65
+ user-owned starting point for:
53
66
 
54
- ```text
55
- ~/.pi/agent/workflows/*.workflow.yaml
56
- ~/.pi/agent/workflows/*.workflow.yml
67
+ | Command | Included flow |
68
+ | ------------- | ---------------------------------------------------------------------------------------------------------- |
69
+ | `/work` | Prepare or reuse one dedicated Git worktree, plan, approve, implement, and verify local work. |
70
+ | `/ticket` | Prepare or reuse one dedicated Git worktree, read a ticket, plan, approve, implement, and verify. |
71
+ | `/mr-review` | Fetch a hosted review, produce a child review, approve it, publish it, and verify the remote effect. |
72
+ | `/mr-comment` | Fetch review comments, plan and approve fixes, edit only the current branch/worktree, verify, push, reply. |
73
+
74
+ The starter YAML explicitly selects Pi Subagents' standard role profiles:
75
+ `scout` for evidence gathering, `planner` for implementation plans, `worker`
76
+ for mutations and publication, and `reviewer` for independent review and
77
+ verification. Change those `subagent.agent` values when your own Pi Subagents
78
+ configuration uses different profiles. The generic `pi-workflows.step` profile
79
+ remains available for user-authored `subagent: {}` steps, but the starter kit
80
+ does not rely on it.
81
+
82
+ Install the integrations required by these four examples:
83
+
84
+ ```bash
85
+ pi install npm:pi-subagents
86
+ pi install npm:@plannotator/pi-extension
57
87
  ```
58
88
 
59
- YAML keeps nested steps and permission lists compact. The loader uses the
60
- strict YAML 1.2 core schema: duplicate keys, merge keys, invalid tags,
61
- multiple documents, non-1.2 directives, and excessive alias expansion fail
62
- closed.
89
+ Configure a Pi MCP proxy for the `atlassian`, `gitlab`, and/or `github` server
90
+ IDs when you want that access route. The MR examples try a matching MCP server
91
+ first but can fall back to the repository/host CLIs or cURL named in their
92
+ YAML; ensure at least one route is authenticated and available. The ticket
93
+ example requires Atlassian MCP by default. MCP server names, authentication,
94
+ tool availability, Git hosting, and repository commands are environment
95
+ choices, so adapt the selectors, `requires`, and Bash rules instead of
96
+ expecting the extension to infer them.
63
97
 
64
- Set `PI_WORKFLOWS_DIR` to use another directory. The example can be copied as a starting point:
98
+ Copy the starter files into the user workflow directory:
65
99
 
66
100
  ```bash
67
- mkdir -p ~/.pi/agent/workflows/prompts
68
- cp examples/mr-comments.workflow.yaml ~/.pi/agent/workflows/
69
- cp -R examples/prompts/mr-comments ~/.pi/agent/workflows/prompts/
101
+ mkdir -p ~/.pi/agent/workflows
102
+ cp examples/starter-kit/*.workflow.yaml ~/.pi/agent/workflows/
103
+ cp -R examples/starter-kit/steps ~/.pi/agent/workflows/
70
104
  ```
71
105
 
72
- The example YAML language-server schema path is repository-relative. Adjust or
73
- remove its first comment after copying.
106
+ If files with those names already exist, review and merge them instead of
107
+ overwriting your working configuration. Then customize:
108
+
109
+ 1. In `work.workflow.yaml` and `ticket.workflow.yaml`, set each
110
+ `workspace.allowedRoots` to relative directories where the preparation
111
+ prompt may create or reuse a worktree.
112
+ 2. Replace or narrow the `atlassian`, `gitlab`, and `github` MCP selectors to
113
+ match your configured adapter. Remove an unused host consistently from the
114
+ relevant `permissions.mcp` blocks and prompts.
115
+ 3. Review every Bash mode and executable. The starter implementation and
116
+ verification steps are deliberately language-neutral and therefore
117
+ unrestricted; replace them with repository-specific allow lists when
118
+ possible. Command syntax—including package-manager argument order—belongs
119
+ in your prompt and repository context.
120
+ 4. Edit the prompt files under `steps/` to define your artifact format,
121
+ acceptance criteria, publication policy, and organization-specific rules.
122
+ Pi Workflows treats all of that content as opaque domain configuration.
123
+
124
+ Reload and diagnose every graph before the first run:
125
+
126
+ ```text
127
+ /reload
128
+ /workflow-reload
129
+ /workflow-doctor work
130
+ /workflow-doctor ticket
131
+ /workflow-doctor mr-review
132
+ /workflow-doctor mr-comment
133
+ ```
74
134
 
75
- Run `/workflow-reload`, then start by configured command:
135
+ Start them from the repository checkout that should supply the initial
136
+ workspace:
76
137
 
77
138
  ```text
78
- /mr-comments <merge-request URL or description>
139
+ /work update the navigation
140
+ /ticket PROJ-123 retry failed requests
141
+ /mr-review https://gitlab.example.com/group/project/-/merge_requests/42
142
+ /mr-comment https://github.com/example/project/pull/42
79
143
  ```
80
144
 
81
- Every workflow is also available through:
145
+ `/work` and `/ticket` bind the exact worktree returned by their user-authored
146
+ preparation prompt. `/mr-comment` intentionally has no workspace-binding step:
147
+ every child stays on the branch and worktree from which the run started.
148
+ Approval rejection pauses either review workflow; it never launches an
149
+ automatic replacement plan. Remote publication prompts first check whether an
150
+ approved effect already exists because the harness cannot guarantee
151
+ exactly-once external side effects.
152
+
153
+ ## Add a workflow
154
+
155
+ User workflows live in one of these formats:
82
156
 
83
157
  ```text
84
- /workflow-start mr-comments <merge-request URL or description>
158
+ ~/.pi/agent/workflows/*.workflow.yaml
159
+ ~/.pi/agent/workflows/*.workflow.yml
85
160
  ```
86
161
 
162
+ YAML keeps nested steps and permission lists compact. The loader uses the
163
+ strict YAML 1.2 core schema: duplicate keys, merge keys, invalid tags,
164
+ multiple documents, non-1.2 directives, and excessive alias expansion fail
165
+ closed.
166
+
167
+ Set `PI_WORKFLOWS_DIR` to use another directory. For a complete portable
168
+ starting point, copy the four-workflow starter kit above. Every configured
169
+ command is also available as `/workflow-start <workflow-id> [input]`.
170
+
87
171
  ## Minimal workflow
88
172
 
89
173
  ```yaml
@@ -99,7 +183,11 @@ steps:
99
183
  permissions:
100
184
  tools: [read, grep, bash]
101
185
  bash:
102
- mode: read-only
186
+ mode: allow-list
187
+ allow:
188
+ - executable: git
189
+ argsPrefixes: [[status], [diff]]
190
+ - executable: rg
103
191
  requires:
104
192
  tools: [read, bash]
105
193
  transitions:
@@ -114,7 +202,7 @@ steps:
114
202
  bash:
115
203
  mode: allow-list
116
204
  allow:
117
- - executable: bun
205
+ - executable: project-check
118
206
  argsPrefix: [test]
119
207
  transitions:
120
208
  done: $done
@@ -143,15 +231,16 @@ Top-level fields:
143
231
 
144
232
  Each step supports:
145
233
 
146
- | Field | Required | Description |
147
- | ------------- | -------- | --------------------------------------------------------------------------------------- |
148
- | `title` | No | Human-readable name. Defaults to the step identifier. |
149
- | `prompt` | Yes | Inline text or `{ "file": "relative/path.md" }`. |
150
- | `subagent` | No | Opt into isolated delegation and select the Pi Subagents profile and execution budgets. |
151
- | `permissions` | No | Resources callable during this step. Everything defaults to denied. |
152
- | `requires` | No | Dependencies that must be detectable before the step starts. |
153
- | `transitions` | Yes | Exact outcome to next step, `$pause`, or `$done`. |
154
- | `gate` | No | Built-in prompt or Plannotator human-review gate. |
234
+ | Field | Required | Description |
235
+ | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
236
+ | `title` | No | Human-readable name. Defaults to the step identifier. |
237
+ | `prompt` | Yes | Inline text or `{ "file": "relative/path.md" }`. |
238
+ | `subagent` | No | Opt into isolated delegation and select the Pi Subagents profile and execution budgets. |
239
+ | `permissions` | No | Resources callable during this step. Everything defaults to denied. |
240
+ | `requires` | No | Dependencies that must be detectable before the step starts. |
241
+ | `transitions` | Yes | Exact outcome to next step, `$pause`, or `$done`. |
242
+ | `gate` | No | Built-in prompt or Plannotator human-review gate. |
243
+ | `workspace` | No | Bind one delegated step result as the working directory for all reachable downstream delegated steps. |
155
244
 
156
245
  Supported prompt variables:
157
246
 
@@ -162,14 +251,26 @@ Supported prompt variables:
162
251
  {{step.id}}
163
252
  {{step.title}}
164
253
  {{last.summary}}
254
+ {{reviewed.artifact}}
255
+ {{reviewed.feedback}}
165
256
  {{gate.feedback}}
257
+ {{resume.input}}
166
258
  ```
167
259
 
168
260
  Unknown variables fail configuration loading.
169
261
 
170
262
  `{{last.summary}}` normally contains the previous completed step's handoff.
171
263
  After a step-requested `$pause`, it contains both the preserved incoming
172
- approved/previous-step handoff and the latest paused-attempt summary.
264
+ previous-step handoff and the latest paused-attempt summary. Gate artifacts and
265
+ summaries stay separate: prompts opt into the opaque approved artifact through
266
+ `{{reviewed.artifact}}`.
267
+ `{{resume.input}}` contains guidance supplied to the current attempt through
268
+ `/workflow-resume [guidance]`. If a prompt omits that variable, the harness
269
+ adds the guidance in a clearly delimited standard section, so every workflow
270
+ can still use it. Standard-section guidance is an authoritative task-level
271
+ amendment for that retry, but it cannot change the workflow graph or bypass
272
+ YAML-enforced resource and workspace boundaries. The value is replaced on each
273
+ explicit resume and cleared after the step returns an outcome.
173
274
 
174
275
  ### Per-step subagents
175
276
 
@@ -205,6 +306,34 @@ The expanded defaults are `agent: pi-workflows.step`, `context: fresh`,
205
306
  original workflow input and the previous step's compact handoff, never the
206
307
  parent or a sibling transcript.
207
308
 
309
+ The run captures Pi's current working directory when it starts. Without a
310
+ `workspace` binding, every delegated visit—including cycles, retries, and
311
+ resumed steps—uses that directory.
312
+
313
+ One delegated, non-gated step may bind a different directory through structured
314
+ result data:
315
+
316
+ ```yaml
317
+ workspace:
318
+ bindOn: [ready]
319
+ allowedRoots: ['..']
320
+ ```
321
+
322
+ On a binding outcome, the result must include
323
+ `workspace: { cwd: "/absolute/directory" }`. The harness resolves its real path,
324
+ requires an existing directory under one configured root relative to the
325
+ run-start directory, persists it once, and passes that exact directory to every
326
+ reachable downstream child, revisit, recovery attempt, and resume. Other
327
+ outcomes must omit `workspace`; later results cannot replace the binding. All
328
+ reachable nonterminal steps after a binding must be delegated because the main
329
+ Pi process cannot change its working directory.
330
+
331
+ The workflow prompt owns how the directory is prepared and what it represents.
332
+ The harness does not know Git, worktrees, languages, frameworks, or command
333
+ syntax, and it never derives a directory from summaries or gate artifacts. A
334
+ legacy checkpoint without a captured directory fails closed before delegation;
335
+ abort it and start a new run.
336
+
208
337
  Use a profile name directly when only the child profile changes:
209
338
 
210
339
  ```yaml
@@ -339,14 +468,14 @@ process; the tool policy does not unload extension code.
339
468
 
340
469
  ### Bash modes
341
470
 
342
- | Mode | Behavior |
343
- | -------------- | ---------------------------------------------------------------------------------------- |
344
- | `deny` | Blocks Bash. This is the default. |
345
- | `read-only` | Allows a small built-in inspection preset. Shell composition and expansion are rejected. |
346
- | `allow-list` | Allows one executable plus configured argument prefixes. |
347
- | `unrestricted` | Allows any Bash command. Use only in user-owned workflows. |
471
+ | Mode | Behavior |
472
+ | -------------- | ------------------------------------------------------------------- |
473
+ | `deny` | Blocks Bash. This is the default. |
474
+ | `allow-list` | Allows one executable plus user-configured argument prefixes. |
475
+ | `unrestricted` | Allows any Bash command. Use only in trusted, user-owned workflows. |
348
476
 
349
- Restricted modes reject shell operators, substitutions, expansions, wrapper shells, environment assignments, and known execution options in the read-only preset.
477
+ Allow-list mode rejects shell operators, substitutions, expansions, wrapper
478
+ shells, and environment assignments before matching the declarative rule.
350
479
 
351
480
  Allow-list entries are OR alternatives. `argsPrefix` is one ordered token
352
481
  sequence:
@@ -356,11 +485,11 @@ mode: allow-list
356
485
  allow:
357
486
  - executable: git
358
487
  argsPrefix: [status]
359
- - executable: bun
488
+ - executable: project-check
360
489
  argsPrefix: [test]
361
490
  ```
362
491
 
363
- This permits `bun test --runInBand` but not `bun run build`.
492
+ This permits `project-check test --focused` but not `project-check build`.
364
493
 
365
494
  Use `argsPrefixes` to merge several alternatives for one executable without
366
495
  widening permission:
@@ -380,96 +509,13 @@ sequence `git status diff`; it does not mean “status or diff.” `argsPrefix`
380
509
  `argsPrefixes` are mutually exclusive in one rule. Omitting both allows that
381
510
  executable with any safely tokenized arguments.
382
511
 
383
- An allow-list may also import exact command strings from the run's most recent
384
- human-reviewed gate artifact:
385
-
386
- ```yaml
387
- mode: allow-list
388
- allow:
389
- - executable: git
390
- argsPrefix: [status]
391
- approvedSources: [verification-worker]
392
- ```
393
-
394
- Supported sources are:
395
-
396
- | Source | Reviewed JSON path |
397
- | ----------------------- | --------------------------------------------------------------------- |
398
- | `verification-worker` | `repositories[].worker[].command` |
399
- | `verification-reviewer` | `repositories[].reviewer[].command` |
400
- | `remote-actions` | `actions[]` where `toolName` is `bash` and `input.command` is present |
401
- | `remote-push` | Exact approved non-force `git push` command |
402
- | `remote-drafts` | Parent-synthesized author-private review drafts |
403
-
404
- The JSON must be the whole reviewed artifact or appear in a fenced `json`
405
- block. The harness copies only exact strings into the correlated step policy.
406
- Verification sources reject shell wrappers, remote-transfer programs,
407
- `gh`/`glab`, publishing commands, and non-local Git operations. Remote actions
408
- accept only `gh api`, `glab api`, or non-force `git push`. A model cannot widen
409
- an approved command by adding arguments or shell composition.
410
-
411
- Approved sources fail closed until a gate has actually been approved. Ordinary
412
- step summaries never become command provenance. Legacy v1 checkpoints remain
413
- readable, but they receive no reviewed-command capabilities until a new gate
414
- produces an approved artifact.
415
-
416
- Static allow-list rules for `gh api` and `glab api` are GET-only: mutation
417
- flags such as fields, input, forms, or an explicit method are blocked. A
418
- mutating API call therefore needs an exact `remote-actions` command from a
419
- reviewed artifact.
420
-
421
- #### How `approvedSources` works
422
-
423
- `approvedSources` does not allow an executable, run a command, or read from the
424
- current step summary. It tells the harness which fixed field in the most recent
425
- human-approved artifact may contribute exact command strings. Approval may
426
- come from the built-in Pi prompt gate or Plannotator.
427
-
428
- For example, suppose the approved artifact contains:
429
-
430
- ```json
431
- {
432
- "repositories": [
433
- {
434
- "cwd": "/absolute/path/to/repository",
435
- "sourceCwd": "/absolute/path/to/source",
436
- "worker": [
437
- {
438
- "command": "bun --cwd /absolute/path/to/repository test"
439
- }
440
- ]
441
- }
442
- ]
443
- }
444
- ```
445
-
446
- A later step with `approvedSources: [verification-worker]` may run only the
447
- exact reviewed command. Cwd-dependent commands must encode that entry's
448
- absolute `repositories[].cwd`, such as `bun --cwd /reviewed/root test`; they
449
- may not substitute another directory or add `--watch`.
450
- `verification-reviewer` reads the sibling `reviewer` list with the same rule.
451
- `remote-actions` reads only Bash actions from
452
- `actions[]` and additionally filters them to supported hosted-API mutations or
453
- non-force pushes.
454
-
455
- A delegated step accepts one distinct reviewed repository directory; repeated
456
- entries may name that same absolute `cwd`. Missing, relative, or ambiguous
457
- multiple directories fail closed before the child starts. A not-yet-created
458
- worktree may bootstrap only from the same contract's one existing absolute
459
- `sourceCwd`; file mutations remain confined to the reviewed target `cwd`, and
460
- all setup and later Bash commands must still match the approved strings.
512
+ The engine deliberately has no package-manager, language, framework, Git, or
513
+ hosted-API command knowledge. It does not rewrite command argument order and
514
+ does not derive Bash authority from prompts, summaries, or gate artifacts.
515
+ Command meaning and syntax belong to the step prompt and the agent's own
516
+ context; executable scope belongs entirely to the YAML `allow` rules.
461
517
 
462
- The complete path is:
463
-
464
- ```text
465
- step artifact -> human approval -> persisted reviewed artifact
466
- -> source-specific extraction -> correlated step policy -> exact string check
467
- ```
468
-
469
- If no gate has been approved, the selected field is absent, the command is
470
- unsafe for that source, or the string differs at all, no permission is added.
471
-
472
- Hard turn and tool-call budgets are best for read-only inspection and
518
+ Hard turn and tool-call budgets are best for non-mutating inspection and
473
519
  verification steps. For a step that edits files, use a generous timeout and no
474
520
  hard count budget unless partial edits are acceptable; inspect the working tree
475
521
  after any interruption before resuming.
@@ -486,14 +532,16 @@ gate:
486
532
  rejectedOutcome: changes-requested
487
533
  transitions:
488
534
  approved: implement
489
- changes-requested: plan
535
+ changes-requested: $pause
490
536
  blocked: $pause
491
537
  ```
492
538
 
493
539
  When the step completes with outcome `submit`, it must include the full content
494
540
  in `artifact`. Pi shows Approve, Request changes, and Pause workflow. Requested
495
541
  changes are returned through `{{gate.feedback}}`; approval persists the
496
- artifact as the reviewed handoff. Dismissing the panel pauses the workflow and
542
+ artifact as `{{reviewed.artifact}}` while the step's `summary` remains the
543
+ compact handoff. A requested change pauses at the same step with feedback, so
544
+ revision starts only after explicit `/workflow-resume`. Dismissing the panel
497
545
  keeps the pending artifact, so `/workflow-resume` reopens the same review.
498
546
 
499
547
  Dialog-capable UI is available in Pi TUI and RPC modes. In print or JSON mode,
@@ -515,7 +563,8 @@ Pi Workflows uses Plannotator's shared extension API as a human approval gate:
515
563
  - A workflow submits its plan or other Markdown artifact.
516
564
  - Plannotator opens the visual review in your browser.
517
565
  - Approval advances through the configured transition.
518
- - Requested changes return structured feedback to the configured revision step.
566
+ - Requested changes follow the workflow's configured transition with structured
567
+ feedback.
519
568
  - Pausing never discards a decision; resume queries the same review identifier.
520
569
 
521
570
  This keeps workflow order and permissions declarative while Plannotator handles
@@ -531,36 +580,37 @@ gate:
531
580
  submitOutcome: submit
532
581
  approvedOutcome: approved
533
582
  rejectedOutcome: changes-requested
534
- timeoutMs: 5000
583
+ timeoutMs: 30000
535
584
  transitions:
536
585
  approved: implement
537
- changes-requested: plan
586
+ changes-requested: $pause
538
587
  blocked: $pause
539
588
  ```
540
589
 
541
- Setting `provider: plannotator` is the entire opt-in; the harness preflights the
542
- installed extension automatically. A main-agent planning step calls
590
+ Setting `provider: plannotator` is the entire opt-in; do not also grant the
591
+ planning child Plannotator extension tools. The harness preflights the installed
592
+ extension automatically. A main-agent planning step calls
543
593
  `workflow_complete_step`; a delegated planning child calls
544
- `structured_output`. In either case it uses outcome `submit` and places the full
545
- content in `artifact`. The harness correlates the Plannotator review identifier
546
- and accepts only the matching decision. On approval, that reviewed artifact—not
547
- the step's separate summary—becomes the authoritative handoff to the next step.
594
+ `structured_output`. In either case it uses the configured submit outcome and
595
+ places the review content in `artifact`. The harness correlates the Plannotator
596
+ review identifier and accepts only the matching decision. On approval, the
597
+ artifact is preserved as an opaque template value; the separate `summary`
598
+ remains the next step's compact handoff.
599
+
600
+ The artifact is never substituted for a missing summary. If an older pending
601
+ gate has no separately stored summary, its transition uses an empty compact
602
+ handoff.
548
603
 
549
604
  If review finishes while the workflow is paused, the result is checkpointed and applied only after `/workflow-resume`. Resume also queries Plannotator’s durable review status, so a decision made while Pi was closed is not lost.
550
605
 
551
- ### Planning is the decision boundary
552
-
553
- For a delegated plan workflow, put every unresolved choice in the plan artifact
554
- with evidence, options, a recommendation, and an adopted default. The built-in
555
- review panel or Plannotator is where the user resolves those choices. Approval
556
- makes that reviewed artifact the final implementation contract and compact
557
- handoff.
606
+ ### Artifact format belongs to the workflow
558
607
 
559
- Post-approval implementation and verification children are non-interactive:
560
- they do not ask questions in the terminal or detach for supervisor input. If an
561
- approved contract is missing, stale, or contradictory, the child pauses with a
562
- declarative evidence summary instead of starting a replacement or opening a
563
- side channel.
608
+ Pi Workflows imposes no plan headings, acceptance-criteria layout,
609
+ machine-readable appendix, command schema, or other Plannotator prompt format.
610
+ The step's YAML prompt defines what the artifact means and how downstream steps
611
+ use `{{reviewed.artifact}}`. Outcome names are equally opaque: names such as
612
+ `approved`, `retry`, or `replan` have only the transitions and meanings the
613
+ workflow author gives them.
564
614
 
565
615
  In print or JSON mode, a pending built-in plan review remains safely paused.
566
616
  Reopen the same session in TUI or RPC mode and run `/workflow-resume` to show
@@ -581,10 +631,18 @@ the Pi session. A late completion cannot advance a paused, aborted,
581
631
  reconfigured, or replaced run.
582
632
 
583
633
  When a step itself transitions to `$pause`, the checkpoint keeps both the
584
- incoming reviewed/previous-step handoff and the latest failed-attempt summary.
585
- The resumed execution sees both. Exact reviewed commands continue to derive only
586
- from the separately persisted reviewed artifact, never from the failed attempt
587
- or a legacy unreviewed summary.
634
+ incoming previous-step handoff and the latest failed-attempt summary. The
635
+ resumed execution sees both. The run-start directory, any accepted workspace
636
+ binding, and any separately persisted reviewed artifact are preserved without
637
+ being interpreted.
638
+
639
+ Every settled step also posts one visible chat summary without starting another
640
+ agent turn. Successful and `$pause` outcomes show only the step's validated
641
+ `summary`; the final one also states that the workflow completed. Manual,
642
+ restored-session, and review pauses show their concise pause reason. Runtime
643
+ failures show only a short, redacted failure summary—not the task, artifact,
644
+ tool transcript, or full diagnostic. Complete evidence remains available in
645
+ the status explorer.
588
646
 
589
647
  For a delegated step, if child termination is not confirmed within five
590
648
  seconds, the pause is recorded but main tools remain isolated and resume is
@@ -599,10 +657,11 @@ automatic recovery child. The audit accepts only regular, non-symlink session
599
657
  files contained by the current parent session's child-run root, requires the
600
658
  persisted policy-stripped task and its per-request binding to match the active
601
659
  delegation, reads a bounded complete tail, and proves that every recorded call
602
- was read-only or rejected by that step's actual Bash policy before execution.
603
- Approved exact Bash commands are evaluated with the same authorization inputs
604
- used by the child. A zero-tool attempt is also replay-safe when the complete
605
- bound transcript proves it.
660
+ used a known-safe non-Bash tool or was rejected by policy before execution.
661
+ A zero-tool attempt is also replay-safe when the complete bound transcript
662
+ proves it. Executed Bash is treated as an unknown effect; automatic recovery
663
+ requires explicit authorization and still cannot claim that a domain-specific
664
+ command was non-mutating.
606
665
 
607
666
  When the terminal error identifies a failed tool, the harness also records the
608
667
  exact correlated call, tool error, subagent exit code, terminal error, and
@@ -635,26 +694,26 @@ can consume at most three times its per-child timeout, turn budget, and tool
635
694
  budget.
636
695
 
637
696
  Inside a live child, recovery is not tied to a list of known error strings. The
638
- completion contract requires the agent to inspect the exact error and current
639
- state, try a permitted semantically equivalent alternative, and continue the
640
- original step. It may pause only after safe alternatives are exhausted, with
641
- the failed call, error, attempted alternatives, and remaining blocker in its
642
- handoff. A fresh retry is explicitly a continuation: it inspects state first
643
- and must not repeat a side effect that is already present.
697
+ agent receives the exact error and current state, then follows the user-authored
698
+ step prompt and configured outcomes. The engine does not assign a recovery,
699
+ pause, or replanning meaning to any outcome name.
644
700
 
645
701
  While paused, fix repository code, workflow YAML, prompts, MCP configuration,
646
702
  an extension, or any other environmental problem. Then run:
647
703
 
648
704
  ```text
649
- /workflow-resume
705
+ /workflow-resume inspect the existing partial output before retrying
650
706
  ```
651
707
 
652
708
  Resume reloads configuration before continuing:
653
709
 
710
+ - Optional text after `/workflow-resume` is passed as a user-authored
711
+ task-level amendment for this attempt. It may supersede conflicting prompt or
712
+ handoff instructions, but never YAML-enforced resource or workspace policy.
654
713
  - The paused step restarts in its configured main-agent or delegated mode.
655
714
  - A changed current step restarts that step.
656
715
  - A changed ordinary completed step restarts the earliest changed completed step.
657
- - A completed human-approved gate keeps its persisted reviewed artifact authoritative; later prompt or configuration digest changes do not reopen that plan while the gate and approved outcome still match.
716
+ - A completed human-approved gate keeps its opaque reviewed artifact; later prompt or configuration digest changes do not reopen that gate while its configuration and approved outcome still match.
658
717
  - Future-only changes preserve the current checkpoint.
659
718
  - Removing the current or a completed step fails closed and requires restoring configuration or aborting.
660
719
  - Restoring a Pi session automatically pauses an in-progress workflow for inspection.
@@ -663,29 +722,56 @@ Resume reloads configuration before continuing:
663
722
 
664
723
  ## Commands
665
724
 
666
- The full status overlay opens when a workflow starts and is toggled with
667
- `Ctrl+Alt+W` by default (`q` or `Esc` also hides it). Set `statusShortcut` in
668
- `settings.yaml` to another Pi key identifier, then run Pi's `/reload` to
669
- re-register it; `/workflow-reload` cannot change extension shortcuts. The
670
- overlay shows run timing, execution or review, pause reasons, configuration
671
- drift, and the completed attempt path without a task-viewer pane below the
672
- editor. The main surface shows only one small animated `◐`/`◓`/`◑`/`◒` working
673
- indicator while a workflow runs, then clears it when execution stops. All step,
674
- progress, history, failure, and review detail stays in the overlay. There, `✓`
675
- marks a completed step, `✕` a failed or aborted run, and `◆` a paused step or
676
- pending review. Long reasons are clamped to the available display width; the
677
- durable checkpoint retains the full text. On short terminals, use `↑`/`↓`,
678
- PgUp/PgDn, or Home/End to scroll the overlay.
679
-
680
- | Command | Purpose |
681
- | ------------------------------- | ---------------------------------------------------- |
682
- | `/workflow-list` | List loaded workflows and their configured commands. |
683
- | `/workflow-start <id> [input]` | Start by workflow identifier. |
684
- | `/<configured-command> [input]` | Start through a workflow alias. |
685
- | `/workflow-pause [reason]` | Halt without losing the checkpoint. |
686
- | `/workflow-resume` | Reload, reconcile, and continue. |
687
- | `/workflow-abort [reason]` | End the active run and restore baseline tools. |
688
- | `/workflow-reload` | Reload definitions while no workflow is running. |
725
+ The full status overlay is an on-demand verification and history page. Toggle
726
+ it with `Ctrl+Alt+W` by default (`q` or `Esc` hides the board). Set
727
+ `statusShortcut` in `settings.yaml` to another Pi key identifier, then run Pi's
728
+ `/reload` to re-register it; `/workflow-reload` cannot change extension
729
+ shortcuts. The overlay shows run timing, execution or review, pause reasons,
730
+ configuration drift, and the completed attempt path without a task-viewer pane
731
+ below the editor. The main surface shows only one small animated
732
+ `◐`/`◓`/`◑`/`◒` working
733
+ indicator followed by the workflow id and current step title/id while a
734
+ workflow runs, then clears it when execution stops. This makes live progress
735
+ visible without opening the status page. All attempt logs, history, failure,
736
+ and review detail stays in the overlay. There, `✓` marks a completed step, `✕`
737
+ a failed or aborted run, and `◆` a paused step or pending review.
738
+
739
+ Use `↑`/`↓` or `j`/`k` to select a step, then `Enter`, `→`, or `l` to inspect
740
+ the bounded task supplied to each attempt, its result and gate decision, and a
741
+ chronological execution log when available. In the detail view,
742
+ `↑`/`↓` or `j`/`k` scrolls; `←`, `h`, or `Esc` returns to the board; `q` or the
743
+ configured shortcut closes it. PgUp/PgDn and Home/End retain page navigation.
744
+ Trace references and bounded task/result evidence live in the checkpoint, so
745
+ completed, paused, resumed, and restored runs remain inspectable. Child logs
746
+ are path-confined, size-bounded, control-sanitized, and redact common
747
+ credential forms.
748
+ For new main-agent attempts, the extension arms only on the exact workflow
749
+ task and checkpoints a redacted, size-bounded prefix of finalized assistant
750
+ and tool events in source order. This log remains part of the parent session,
751
+ but the explorer never reads unrelated parent-session traffic. Legacy
752
+ checkpoints without a main-agent log still show their bounded task and result.
753
+ Long reasons are clamped to the display width while the durable checkpoint
754
+ retains the full reason.
755
+
756
+ | Command | Purpose |
757
+ | ------------------------------- | --------------------------------------------------------- |
758
+ | `/workflow-list` | List loaded workflows and their configured commands. |
759
+ | `/workflow-doctor [id]` | Diagnose completion paths, unreachable steps, and cycles. |
760
+ | `/workflow-start <id> [input]` | Start by workflow identifier. |
761
+ | `/<configured-command> [input]` | Start through a workflow alias. |
762
+ | `/workflow-pause [reason]` | Halt without losing the checkpoint. |
763
+ | `/workflow-resume [guidance]` | Reload, reconcile, and continue with an optional hint. |
764
+ | `/workflow-abort [reason]` | End the active run and restore baseline tools. |
765
+ | `/workflow-reload` | Reload definitions while no workflow is running. |
766
+
767
+ Before a workflow starts or resumes, the doctor rejects graphs whose start
768
+ cannot reach `$done` or whose reachable branches contain a step that cannot
769
+ reach `$done`.
770
+ Unreachable steps and cycles are reported as warnings; a cycle with an exit may
771
+ run, but `maxStepVisits` pauses the uninterrupted run before a step can execute
772
+ more than its configured limit. An explicit resume can continue from that
773
+ checkpoint, so the guard bounds automatic graph advancement rather than
774
+ guaranteeing completion or wall-clock duration.
689
775
 
690
776
  Configured aliases also accept multiline input. For example, if `work` is a
691
777
  loaded workflow command, Pi Workflows normalizes:
@@ -720,7 +806,12 @@ permissionCeiling:
720
806
  mcp: []
721
807
  extensions: []
722
808
  skills: []
723
- bash: { mode: read-only }
809
+ bash:
810
+ mode: allow-list
811
+ allow:
812
+ - executable: git
813
+ argsPrefixes: [[status], [diff]]
814
+ - executable: rg
724
815
  subagent:
725
816
  agents: [scout, planner, worker, reviewer]
726
817
  contexts: [fresh]
@@ -741,34 +832,36 @@ path.
741
832
  Project workflows load only when Pi trusts the project and every step stays
742
833
  within this ceiling. The `subagent` ceiling is optional for main-only project
743
834
  workflows; if omitted, any project step that declares `subagent` is rejected.
835
+ Project workflows cannot declare `workspace` binding at all, even when their
836
+ other permissions fit the ceiling. Keep workflows that create, choose, or bind
837
+ a different execution directory in the user-owned workflow directory.
744
838
  Each delegated project step must declare `turnBudget` and `toolBudget` with
745
839
  `"block": "*"`, so it cannot silently inherit unbounded child defaults or keep
746
840
  mutation tools after reaching the hard limit. The ceiling also controls
747
841
  agent profile names, fresh-context use, model overrides, timeouts, artifact
748
- retention, and the Bash rules and approved sources that a project workflow may
749
- request. Project workflows cannot override user workflow identifiers or
750
- commands.
842
+ retention, and the Bash rules that a project workflow may request. Project
843
+ workflows cannot override user workflow identifiers or commands.
751
844
 
752
845
  ## Architecture
753
846
 
754
847
  The package keeps the Pi entry point intentionally small:
755
848
 
756
- | Module | Responsibility |
757
- | --------------------------------- | --------------------------------------------------------------------- |
758
- | `src/index.ts` | Pi entry point only. |
759
- | `src/harness.ts` | Runtime orchestration and session lifecycle. |
760
- | `src/commands.ts` | User command surface. |
761
- | `src/config/` | Types, strict validation, prompt loading, precedence, ceilings. |
762
- | `src/engine/` | Serializable run state and deterministic transitions. |
763
- | `src/policy/` | Tool, MCP, and Bash enforcement. |
764
- | `src/policy/approved-commands.ts` | Filtered exact-command extraction from human-reviewed JSON artifacts. |
765
- | `src/integrations/subagents/` | Delegation client, child protocol, and child policy runtime. |
766
- | `src/integrations/plannotator.ts` | Versioned Plannotator gate adapter. |
767
- | `src/integrations/prompt-gate.ts` | Built-in Pi prompt review adapter. |
768
- | `src/runtime/` | Shared completion parsing and main-agent step runtime. |
769
- | `src/preflight.ts` | Required tool, extension, and skill checks. |
770
- | `src/prompt.ts` | Template rendering and step contract. |
771
- | `agents/step.md` | Default general-purpose profile plus workflow child guidance. |
849
+ | Module | Responsibility |
850
+ | --------------------------------- | --------------------------------------------------------------- |
851
+ | `src/index.ts` | Pi entry point only. |
852
+ | `src/harness.ts` | Runtime orchestration and session lifecycle. |
853
+ | `src/commands.ts` | User command surface. |
854
+ | `src/config/` | Types, strict validation, prompt loading, precedence, ceilings. |
855
+ | `src/engine/` | Serializable run state and deterministic transitions. |
856
+ | `src/policy/` | Tool, MCP, and Bash enforcement. |
857
+ | `src/workflow-doctor.ts` | Deterministic transition-graph liveness diagnostics. |
858
+ | `src/integrations/subagents/` | Delegation client, child protocol, and child policy runtime. |
859
+ | `src/integrations/plannotator.ts` | Versioned Plannotator gate adapter. |
860
+ | `src/integrations/prompt-gate.ts` | Built-in Pi prompt review adapter. |
861
+ | `src/runtime/` | Shared completion parsing and main-agent step runtime. |
862
+ | `src/preflight.ts` | Required tool, extension, and skill checks. |
863
+ | `src/prompt.ts` | Template rendering and step contract. |
864
+ | `agents/step.md` | Default general-purpose profile plus workflow child guidance. |
772
865
 
773
866
  The engine and policy modules do not depend on Pi runtime types, so they are fast to test.
774
867
 
@@ -787,7 +880,7 @@ process separation when a step opts into pi-subagents:
787
880
  - a single-use, parent-created child capability tied to the delegated step;
788
881
  - explicit MCP server and tool checks;
789
882
  - restricted Bash parsing;
790
- - exact Bash capabilities derived from a correlated human-reviewed artifact;
883
+ - exact user-declared Bash executable and argument-prefix rules;
791
884
  - project trust and a user-owned permission ceiling;
792
885
  - fail-closed durable state, correlated child results, and correlated gate results.
793
886
 
@@ -800,14 +893,15 @@ source before installing or enabling it.
800
893
  Step completion is structurally validated—policy digest, declared outcome,
801
894
  non-empty bounded summary, required gate artifact, and sole completion call—but
802
895
  the harness cannot prove that a model's semantic claims or test evidence are
803
- true. Put exact checks in reviewed command contracts, use an independent
804
- verification step, and keep consequential actions behind a human gate.
896
+ true. Put exact checks and acceptance criteria in the workflow prompt, use an
897
+ independent verification step, and keep consequential actions behind a human
898
+ gate.
805
899
 
806
900
  The harness does not provide exactly-once external effects. If a publish step
807
901
  is interrupted after a remote action succeeds but before it checkpoints, a
808
- resumed execution receives the same approved capability. Publish prompts should
809
- query the remote effect first, skip only proven-complete actions, and pause on
810
- ambiguous state.
902
+ resumed execution receives the same declarative step permissions. Publish
903
+ prompts should query the remote effect first, skip only proven-complete actions,
904
+ and pause on ambiguous state.
811
905
 
812
906
  ## Development
813
907
 
@@ -823,10 +917,14 @@ main-agent completion, built-in feedback/approval, subagent request correlation
823
917
  and cancellation, child policy enforcement, and dependency preflight,
824
918
  including bounded automatic recovery after replay-safe terminal errors,
825
919
  timeouts, budget exhaustion, and nonzero exits; duplicate-failure stopping;
826
- reviewed exact-command propagation; and fail-closed legacy checkpoints.
920
+ opaque gate artifacts; workspace binding and cwd reuse; workflow liveness
921
+ diagnostics; and fail-closed legacy checkpoints.
827
922
  `bun run check` also launches real Pi RPC subprocesses, invokes
828
923
  `/work`, and verifies fresh `scout`, `worker`, and `reviewer` children receive
829
- only the explicit compact handoff from the immediately preceding step.
924
+ only the explicit compact handoff from the immediately preceding step. The
925
+ real-Pi scenario binds a sibling workspace, revisits its worker once, and
926
+ verifies that every downstream visit keeps the bound cwd and receives no
927
+ undeclared `replan` outcome.
830
928
 
831
929
  ## Publishing checklist
832
930
 
@@ -847,7 +945,6 @@ extensions, without hard-coding them into the orchestrator, are:
847
945
  | --------------------------------- | -------------------------------------------------------------------------------------------------- |
848
946
  | Configurable recovery and backoff | Replace the fixed two-attempt recovery cap with a ceiling-aware per-step transient-failure policy. |
849
947
  | Acceptance criteria | Give each step machine-checkable completion evidence and verification commands. |
850
- | Working directory or worktree | Isolate mutating steps, monorepo packages, and concurrent branches. |
851
948
  | Parallel groups and join policy | Run independent steps together and declare fail-fast, quorum, or all-success behavior. |
852
949
  | Generic gates | Add ticket, CI, chat, or custom approval providers behind the same versioned gate contract. |
853
950
  | Output schema and named artifacts | Pass structured data between steps instead of relying only on a summary. |
@@ -861,7 +958,7 @@ extensions, without hard-coding them into the orchestrator, are:
861
958
  - Gate providers are built-in prompt and Plannotator; custom providers are not yet configurable.
862
959
  - Delegated steps require pi-subagents 0.36.0 or newer and launch the actual profile selected by `subagent.agent`.
863
960
  - Extension tools are enforced; autonomous extension event-handler side effects cannot be disabled per step.
864
- - Completion evidence is model-reported; use reviewed executable checks and a fresh verification step when correctness matters.
961
+ - Completion evidence is model-reported; use declarative executable checks and a fresh verification step when correctness matters.
865
962
  - Workflow configuration uses YAML. Prompt bodies may live in separate Markdown files.
866
963
 
867
964
  ## License