@osolmaz/pi-workflows 0.11.2 → 0.12.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 (123) hide show
  1. package/README.md +11 -7
  2. package/dist/builtins/autoimplement-command-batches.d.ts +52 -0
  3. package/dist/builtins/autoimplement-command-batches.js +258 -0
  4. package/dist/builtins/autoimplement-command-batches.js.map +1 -0
  5. package/dist/builtins/autoimplement.workflow.d.ts +29 -3
  6. package/dist/builtins/autoimplement.workflow.js +876 -231
  7. package/dist/builtins/autoimplement.workflow.js.map +1 -1
  8. package/dist/builtins/catalog.js +3 -1
  9. package/dist/builtins/catalog.js.map +1 -1
  10. package/dist/builtins/index.d.ts +2 -0
  11. package/dist/builtins/index.js +1 -0
  12. package/dist/builtins/index.js.map +1 -1
  13. package/dist/builtins/sanity-check-session.d.ts +17 -0
  14. package/dist/builtins/sanity-check-session.js +168 -0
  15. package/dist/builtins/sanity-check-session.js.map +1 -0
  16. package/dist/builtins/sanity-check.workflow.d.ts +83 -0
  17. package/dist/builtins/sanity-check.workflow.js +398 -0
  18. package/dist/builtins/sanity-check.workflow.js.map +1 -0
  19. package/dist/controllers/sqlite.d.ts +90 -2
  20. package/dist/controllers/sqlite.js +380 -5
  21. package/dist/controllers/sqlite.js.map +1 -1
  22. package/dist/extension/decision-channels.js +7 -7
  23. package/dist/extension/deferred-turn-coordinator.d.ts +32 -0
  24. package/dist/extension/deferred-turn-coordinator.js +143 -0
  25. package/dist/extension/deferred-turn-coordinator.js.map +1 -0
  26. package/dist/extension/deferred-turn.d.ts +44 -0
  27. package/dist/extension/deferred-turn.js +110 -0
  28. package/dist/extension/deferred-turn.js.map +1 -0
  29. package/dist/extension/index.js +286 -47
  30. package/dist/extension/index.js.map +1 -1
  31. package/dist/extension/step-message.d.ts +1 -0
  32. package/dist/extension/step-message.js.map +1 -1
  33. package/dist/herdr/setup.js +4 -4
  34. package/dist/workflows/command-batch.d.ts +38 -0
  35. package/dist/workflows/command-batch.js +176 -0
  36. package/dist/workflows/command-batch.js.map +1 -0
  37. package/dist/workflows/engine.js +8 -4
  38. package/dist/workflows/engine.js.map +1 -1
  39. package/dist/workflows/index.d.ts +1 -0
  40. package/dist/workflows/index.js +1 -0
  41. package/dist/workflows/index.js.map +1 -1
  42. package/dist/workflows/schema.js +2 -1
  43. package/dist/workflows/schema.js.map +1 -1
  44. package/dist/workflows/shell.d.ts +4 -0
  45. package/dist/workflows/shell.js +6 -0
  46. package/dist/workflows/shell.js.map +1 -1
  47. package/dist/workflows/store.js +3 -1
  48. package/dist/workflows/store.js.map +1 -1
  49. package/dist/workflows/types.d.ts +4 -3
  50. package/docs/2026-08-18-herdr-piw-plan.md +1 -1
  51. package/docs/2026-08-20-durable-workflow-launch-plan.md +19 -23
  52. package/docs/CONTROLLERS.md +2 -2
  53. package/docs/DEFERRED_TURNS.md +298 -0
  54. package/docs/DESIGN_PHILOSOPHY.md +1 -1
  55. package/docs/HUMAN_DECISIONS.md +7 -7
  56. package/docs/HUMAN_DECISION_PRESENTATIONS.md +3 -3
  57. package/docs/MONITOR.md +2 -2
  58. package/docs/WORKFLOW_COMPOSITION.md +2 -2
  59. package/docs/WORKFLOW_STEP_MESSAGES.md +5 -5
  60. package/docs/WORKFLOW_UPDATES.md +28 -5
  61. package/docs/plans/2026-08-04-controller-runtime-plan.md +1 -1
  62. package/docs/plans/2026-08-05-always-on-workflows-plan.md +1 -1
  63. package/docs/plans/2026-08-10-agent-managed-monitor-workflows-plan.md +9 -9
  64. package/docs/plans/2026-08-13-built-in-workflow-catalog-plan.md +1 -1
  65. package/docs/plans/2026-08-13-session-addressed-workflow-notifications-plan.md +1 -1
  66. package/docs/plans/2026-08-16-workflow-updates-plan.md +3 -3
  67. package/docs/plans/2026-08-17-bundled-skills-plan.md +6 -6
  68. package/docs/plans/2026-08-19-human-decision-gates-plan.md +5 -5
  69. package/docs/plans/2026-08-19-human-decision-presentations-plan.md +1 -1
  70. package/docs/plans/2026-08-19-provider-compatible-workflow-tool-schema-plan.md +1 -1
  71. package/docs/plans/2026-08-19-workflow-composition-plan.md +6 -6
  72. package/docs/plans/2026-08-20-autoimplement-blocker-challenge-plan.md +3 -3
  73. package/docs/plans/2026-08-20-bounded-command-batches-plan.md +206 -0
  74. package/docs/plans/2026-08-20-herdr-plugin-sync-plan.md +9 -9
  75. package/docs/plans/2026-08-21-autoimplement-timeout-fallback-plan.md +242 -0
  76. package/docs/plans/2026-08-21-deferred-turn-intents-plan.md +324 -0
  77. package/docs/plans/2026-08-21-sanity-check-plan.md +175 -0
  78. package/docs/run-bundles.md +3 -1
  79. package/docs/workflows.md +62 -19
  80. package/examples/workflows/command-batch.workflow.ts +50 -0
  81. package/examples/workflows/sanity-check.workflow.ts +1 -0
  82. package/herdr-plugin.toml +3 -3
  83. package/package.json +1 -1
  84. package/schemas/decision-presentation-v1.schema.json +1 -1
  85. package/schemas/human-decision-accepted-v1.schema.json +1 -1
  86. package/schemas/human-decision-accepted-v2.schema.json +1 -1
  87. package/schemas/human-decision-answer-attempt-v1.schema.json +1 -1
  88. package/schemas/human-decision-cancellation-v1.schema.json +1 -1
  89. package/schemas/human-decision-continuation-v1.schema.json +1 -1
  90. package/schemas/human-decision-delivery-v1.schema.json +1 -1
  91. package/schemas/human-decision-delivery-v2.schema.json +1 -1
  92. package/schemas/human-decision-receipt-v1.schema.json +1 -1
  93. package/schemas/human-decision-receipt-v2.schema.json +1 -1
  94. package/schemas/human-decision-request-v1.schema.json +1 -1
  95. package/schemas/human-decision-request-v2.schema.json +1 -1
  96. package/schemas/human-decision-resolution-v1.schema.json +1 -1
  97. package/schemas/human-decision-resolution-v2.schema.json +1 -1
  98. package/schemas/human-decision-settlement-v1.schema.json +1 -1
  99. package/skills/autodoc/SKILL.md +33 -2
  100. package/skills/autoimplement/SKILL.md +66 -12
  101. package/skills/autoplan/SKILL.md +26 -2
  102. package/skills/monitor/SKILL.md +35 -21
  103. package/skills/pi-workflows/SKILL.md +19 -5
  104. package/src/builtins/autoimplement-command-batches.ts +364 -0
  105. package/src/builtins/autoimplement.workflow.ts +1065 -261
  106. package/src/builtins/catalog.ts +3 -1
  107. package/src/builtins/index.ts +13 -0
  108. package/src/builtins/sanity-check-session.ts +205 -0
  109. package/src/builtins/sanity-check.workflow.ts +624 -0
  110. package/src/controllers/sqlite.ts +580 -7
  111. package/src/extension/decision-channels.ts +7 -7
  112. package/src/extension/deferred-turn-coordinator.ts +171 -0
  113. package/src/extension/deferred-turn.ts +166 -0
  114. package/src/extension/index.ts +359 -49
  115. package/src/extension/step-message.ts +1 -0
  116. package/src/herdr/setup.ts +4 -4
  117. package/src/workflows/command-batch.ts +254 -0
  118. package/src/workflows/engine.ts +8 -5
  119. package/src/workflows/index.ts +15 -0
  120. package/src/workflows/schema.ts +2 -1
  121. package/src/workflows/shell.ts +10 -0
  122. package/src/workflows/store.ts +3 -1
  123. package/src/workflows/types.ts +4 -3
@@ -0,0 +1,175 @@
1
+ ---
2
+ title: Add the Sanity Check Workflow
3
+ author: Onur Solmaz <2453968+osolmaz@users.noreply.github.com>
4
+ date: 2026-08-21
5
+ ---
6
+
7
+ # Add the Sanity Check Workflow
8
+
9
+ ## Goal
10
+
11
+ Add a built-in `sanity-check` workflow that reviews a pull request or local contribution before implementation, approval, or merge. The review checks whether the change is needed, duplicates existing code, should use a simpler design, adds unnecessary data models or public plugin APIs, or has scope and test problems.
12
+
13
+ The workflow runs its model work in temporary read-only Pi sessions. It does not put review prompts or model replies in the Pi session that started the workflow. The origin session receives the final report through a workflow notification that does not start another model turn.
14
+
15
+ ## Scope
16
+
17
+ The change is limited to pi-workflows. It adds the built-in workflow, the smallest supporting code needed to run isolated read-only Pi sessions, workflow discovery and exports, documentation, unit tests, and real-Pi end-to-end coverage.
18
+
19
+ The workflow uses existing `action`, `compute`, and `notify` nodes. It does not add a workflow primitive, change a persisted schema, change Pi core, or change the Pi plugin SDK.
20
+
21
+ The child sessions can use only `read`, `grep`, `find`, and `ls`. They cannot edit files or run shell commands. They are temporary and do not write Pi session files.
22
+
23
+ ## Input
24
+
25
+ The workflow accepts a review mode and the base reference needed to inspect the current change. Serial mode is the default.
26
+
27
+ ```json
28
+ {
29
+ "mode": "serial",
30
+ "baseRef": "origin/main"
31
+ }
32
+ ```
33
+
34
+ `mode` is `serial` or `parallel`. The current repository and checked-out branch are the contribution under review. When `baseRef` is omitted, the workflow tries the remote default branch, the current branch upstream, and the first parent, then uses `HEAD` for a working-tree-only review. Pull request intent, linked issue context, and acceptance criteria are collected when they are available. The workflow also supports a local contribution with no pull request metadata.
35
+
36
+ ## Evidence
37
+
38
+ The first node collects facts without model judgment. It uses fixed, non-mutating commands to collect:
39
+
40
+ - the pull request description and linked issue context when available;
41
+ - stated acceptance criteria;
42
+ - the base and head revisions;
43
+ - changed files;
44
+ - the diff and diff statistics;
45
+ - relevant new exports, schemas, persisted fields, and nearby existing code.
46
+
47
+ Untrusted pull request and repository text is treated as evidence, not as workflow instructions. The evidence is bounded before it enters a model prompt or run bundle.
48
+
49
+ ## Review modes
50
+
51
+ ### Serial mode
52
+
53
+ Serial mode starts one temporary review session. That session checks all four areas in order:
54
+
55
+ 1. Whether the change is needed.
56
+ 2. Duplication and refactoring opportunities.
57
+ 3. New data models and public plugin or SDK APIs.
58
+ 4. Scope and tests.
59
+
60
+ The review session must give exact evidence and the strongest case for accepting the current design. A second temporary session verifies and combines the findings. Serial mode therefore uses two model sessions.
61
+
62
+ ### Parallel mode
63
+
64
+ Parallel mode starts four temporary review sessions at the same time. Each session checks one area:
65
+
66
+ 1. Whether the change is needed.
67
+ 2. Duplication and refactoring opportunities.
68
+ 3. New data models and public plugin or SDK APIs.
69
+ 4. Scope and tests.
70
+
71
+ Each session must give exact evidence and the strongest case for accepting the current design. After all four sessions finish, one temporary session verifies and combines their findings. Parallel mode therefore uses five model sessions.
72
+
73
+ ## Verification
74
+
75
+ The final session receives the collected evidence and all review results. It must:
76
+
77
+ - remove claims that the evidence does not support;
78
+ - require exact file and symbol references for repository claims;
79
+ - separate facts from assumptions;
80
+ - resolve conflicting findings when the evidence permits it;
81
+ - place unresolved questions in the final `unknowns` or contributor questions;
82
+ - return one of `keep`, `simplify`, `refactor`, `drop`, or `needs_evidence`.
83
+
84
+ There is no extra review loop. Missing product intent or unresolved evidence produces `needs_evidence` instead of an invented conclusion.
85
+
86
+ ## Result
87
+
88
+ The accepted result contains a verdict, a short summary, findings with evidence, required changes, contributor questions, and unknowns. Findings cover necessity, duplication, data models, public APIs, scope, and tests.
89
+
90
+ The workflow formats the accepted result as a concise report and sends it to the origin session with `notify({ kind: "final" })`. The notification has `triggerTurn: false`, so the origin model does not restate the report.
91
+
92
+ ## Implementation
93
+
94
+ Add a built-in definition named `sanity-check` and register it in the built-in catalog and exports. The graph has these stages:
95
+
96
+ ```text
97
+ collect evidence
98
+ |
99
+ run serial review or four parallel reviews
100
+ |
101
+ verify and combine
102
+ |
103
+ notify origin session
104
+ ```
105
+
106
+ The review nodes are function actions. The isolated runner starts Pi in non-interactive JSON mode with no saved session, no discovered extensions or skills, and only the read-only tools:
107
+
108
+ ```text
109
+ --mode json
110
+ --print
111
+ --no-session
112
+ --no-extensions
113
+ --no-skills
114
+ --no-context-files
115
+ --tools read,grep,find,ls
116
+ ```
117
+
118
+ Serial mode starts one combined review and then one verification session. Parallel mode starts the four focused reviews concurrently, waits for all of them, and then starts one verification session. Cancellation and timeout stop every affected child process. Output and error text are bounded. Serialized evidence and review results are also bounded before prompt construction, with an explicit truncation marker when the full input does not fit.
119
+
120
+ The workflow validates its input and every model result. A missing child result, failed child process, malformed result, cancellation, or timeout fails the active action with a clear bounded error.
121
+
122
+ ## Documentation
123
+
124
+ Add `sanity-check` to the built-in workflow list and document its input, review modes, read-only session boundary, result, and notification behavior in `docs/workflows.md`. Keep this plan as the record of the selected implementation.
125
+
126
+ ## Tests
127
+
128
+ Unit tests must cover:
129
+
130
+ - input validation and the serial default;
131
+ - serial mode starting exactly one review session and one verification session;
132
+ - parallel mode starting exactly four concurrent review sessions and one verification session;
133
+ - the four required review areas;
134
+ - the acceptance case and evidence requirements in every review prompt;
135
+ - read-only child tool arguments and disabled session, extension, and skill discovery;
136
+ - structured result validation and all five verdicts;
137
+ - unsupported and conflicting finding handling in the verification prompt;
138
+ - bounded output and error handling;
139
+ - child failure, malformed output, timeout, cancellation, and process cleanup;
140
+ - final notification delivery without a model turn;
141
+ - built-in discovery and export behavior.
142
+
143
+ The real-Pi end-to-end test must use the repository test provider. It must not call a real model or make destructive changes.
144
+
145
+ Before completion, run all checks required by `AGENTS.md`:
146
+
147
+ ```bash
148
+ npm run check
149
+ npm run test:e2e
150
+ npx slophammer-ts@latest dry .
151
+ npx slophammer-ts@latest check . --only ts.dependency-boundaries-required
152
+ ```
153
+
154
+ ## Acceptance criteria
155
+
156
+ The implementation is complete when:
157
+
158
+ - `/workflow sanity-check` discovers and starts the built-in workflow;
159
+ - omitted mode selects serial mode;
160
+ - serial mode uses two temporary model sessions;
161
+ - parallel mode uses five temporary model sessions, with the four review sessions running concurrently;
162
+ - child sessions have only read-only repository tools and create no session files;
163
+ - both modes cover all required review questions and the case for accepting the design;
164
+ - final verification rejects unsupported claims and requires exact repository evidence;
165
+ - the final verdict is one of the five selected values;
166
+ - the origin session receives the report without another model turn;
167
+ - documentation and all required checks pass.
168
+
169
+ ## Contract impact
170
+
171
+ - **Origin session:** The normal workflow start record and one final workflow notification.
172
+ - **Other persistent data:** The normal workflow run bundle only. Child Pi sessions are not saved.
173
+ - **Pi internals:** None.
174
+ - **Pi public API:** Existing documented CLI and extension behavior only.
175
+ - **Pi Workflows public API:** Existing workflow definitions and `action`, `compute`, and `notify` nodes only.
@@ -183,7 +183,9 @@ A serializable snapshot of the graph taken at run start
183
183
  (`pi-workflows.definition-snapshot.v1`). Functions such as prompts and
184
184
  validators are not serialized. Each node keeps only its metadata (`nodeType`,
185
185
  `timeoutMs`, `statusDetail`, `expectedOutput`, `summary`, `actionExecution`),
186
- and edges are copied verbatim. Included nodes also record `mountPath`, `localNodeId`, and internal entry or exit status. The top-level `composition.mounts` list records every mount, entry, named exit, and child step limit. The snapshot is what lets viewers draw all nodes, including ones that have not run yet. It is immutable after run start.
186
+ and edges are copied verbatim. A fixed `timeoutMs: null` is preserved and means
187
+ that the node has no wall-clock deadline. Timeout callbacks remain omitted.
188
+ Included nodes also record `mountPath`, `localNodeId`, and internal entry or exit status. The top-level `composition.mounts` list records every mount, entry, named exit, and child step limit. The snapshot is what lets viewers draw all nodes, including ones that have not run yet. It is immutable after run start.
187
189
 
188
190
  ## Resume and repair
189
191
 
package/docs/workflows.md CHANGED
@@ -16,7 +16,7 @@ Files are discovered by suffix (`.workflow.ts`, `.workflow.js`, `.workflow.mts`,
16
16
  3. Workflows built into Pi Workflows
17
17
 
18
18
  Pi Workflows includes built-in `autoplan`, `autodoc`, `autoimplement`,
19
- `plan-approval`, and `monitor` workflows. `autoplan` is the current name for the
19
+ `plan-approval`, `sanity-check`, and `monitor` workflows. `autoplan` is the current name for the
20
20
  planning workflow that was first released as `autodevise`; the old command and
21
21
  export are not retained. A project or global file named `monitor.workflow.ts`
22
22
  replaces the built-in monitor. The package registers each built-in in
@@ -161,11 +161,13 @@ then fails the step. If an agent node times out or the workflow is cancelled,
161
161
  the extension also aborts its active Pi turn. The model cannot continue to use
162
162
  tools after the engine has closed that attempt.
163
163
 
164
- `timeoutMs` can be a finite positive number or a function of the normal node
165
- context. A timeout function can use prepared outputs to select a deadline for
166
- this run. It has 30 seconds to return a value. Computed timeout functions are
167
- runtime code, so definition snapshots omit them; fixed numeric timeouts remain
168
- in the snapshot.
164
+ `timeoutMs` can be a finite positive number, `null`, or a function of the normal
165
+ node context that returns either value. Omit it to use the 15-minute engine
166
+ default. Set it to `null` to disable only the wall-clock deadline; cancellation,
167
+ parking, claim loss, shutdown, and the node's abort signal still work. A timeout
168
+ function can use prepared outputs to select a policy for this run. It has 30
169
+ seconds to return. Computed timeout functions are runtime code, so definition
170
+ snapshots omit them. Snapshots keep fixed numbers and fixed `null` values.
169
171
 
170
172
  ### compute
171
173
 
@@ -417,12 +419,46 @@ The built-in `autoplan` workflow selects a practical in-scope solution and write
417
419
 
418
420
  The built-in `plan-approval` workflow offers verified human `continue`, `stop`, and exact-text `replan` exits. It is optional. A replan exit returns the unchanged text to autoplan, documents the revised plan, and asks again through a new plan digest.
419
421
 
420
- Autoimplement writes and runs the exact Pi Reviewer command. It records P0 through P2 by review round. P0 or P1 work requires another review. P2-only work can be addressed and verified without another reviewer run. CI tracking commands are also explicit. One CI watch lasts at most five minutes, after which the model runs more useful local tests before checking CI again.
422
+ Autoimplement runs independent commands through bounded command batches. A batch is an ordinary function action that calls the public `runCommandBatch` helper. Each command has a stable ID, executable, arguments, absolute working directory, timeout, and output limit. Results stay separate and return in input order. One command uses the same path with concurrency one.
423
+
424
+ Autoimplement gives `implement` an eight-hour deadline. When a supported
425
+ long-running agent node times out, one shared read-only fallback inspects the
426
+ current repository, accepted workflow outputs, and relevant pull-request state.
427
+ It then retries the timed-out stage or routes to verification, review, CI,
428
+ delivery, the existing redesign workflow, or blocked. The fallback can run at
429
+ most three times in one Autoimplement run. Its own failure or timeout is
430
+ terminal. Cancellation remains immediate and never enters fallback. A repeated
431
+ effect step first checks what already exists and performs only missing work.
432
+ This graph fallback starts after the timed-out turn ends and is separate from
433
+ successor-turn delivery.
434
+
435
+ Autoimplement uses batches for pi-reviewer, pending CI watches, and local verification commands from independent repositories. It keeps model turns, fixes, pushes, comment changes, merges, and releases in their existing order. Reviewer commands are tied to the repository, base branch, pushed head, and relevant dependency fingerprint. A later review round includes only repositories whose head or dependency fingerprint changed. P0 or P1 work still requires another review. P2-only work can be addressed and verified without another reviewer run only because of that P2 work.
436
+
437
+ Autoimplement inspects every pull request before it waits for CI. It accepts only supported pending `gh pr checks --watch` or `gh run watch` descriptors and binds each one to the validated pull request as `gh pr checks <PR URL> --watch`. Repository and pull-request overrides are rejected. One watch lasts at most five minutes. A failed or timed-out watch affects only its pull request. When checks remain pending, the model runs more useful local tests before checking CI again. Autoimplement does not invent an ETA.
438
+
439
+ The action abort signal stops active command process groups and prevents queued commands from starting. Accepted outputs use the existing trace and artifacts. An interrupted unaccepted batch runs again because batch commands are read-only or isolated local checks. Progress updates contain metadata only and never control routing. Truncated reviewer or CI output cannot count as clean. See [Run independent commands in bounded batches](plans/2026-08-20-bounded-command-batches-plan.md) for the complete contract and implementation plan.
421
440
 
422
441
  A model-generated blocker from implementation or a safe later stage does not end autoimplement by itself. A separate blocker-challenge agent checks the task, approved plan, current result, evidence, scope, authority, earlier attempts, and practical alternatives. It confirms a blocker only when the blocker exists now, is outside the granted authority, has no safe path forward, has an empty next action, and includes concrete evidence and checked alternatives. A rejected blocker must name the next practical action and routes through the existing redesign workflow before implementation and verification continue.
423
442
 
424
443
  Autoimplement can run the blocker challenge at most three times in one run. Each later challenge receives the earlier challenge results. Reaching the limit stops with the normal workflow safety-limit reason. Explicit human stops, cancellation, exhausted workflow or replan limits, protected authorization gaps, and an independent blocked result from redesign remain direct stops. These hard boundaries do not enter the blocker challenge.
425
444
 
445
+ ### Built-in sanity check
446
+
447
+ The built-in `sanity-check` workflow reviews a pull request or local contribution before implementation, approval, or merge. It checks whether the change is needed, duplicates existing code, should use a simpler design, adds unnecessary data models or public plugin and SDK APIs, or has scope and test problems.
448
+
449
+ ```json
450
+ {
451
+ "mode": "serial",
452
+ "baseRef": "origin/main"
453
+ }
454
+ ```
455
+
456
+ Serial mode is the default. It runs one temporary read-only Pi session for all four review areas, then one temporary session to verify and combine the findings. Parallel mode runs four focused review sessions at the same time, then one verification session. Serial mode uses two model sessions. Parallel mode uses five. When `baseRef` is omitted, the workflow tries the remote default branch, the current branch upstream, and the first parent, then uses `HEAD` for a working-tree-only review.
457
+
458
+ The workflow collects pull request intent and repository diff evidence before model review. It bounds serialized evidence and review results before prompt construction and marks truncated input. Every review must cite evidence and give the strongest case for accepting the current design. The verification session removes unsupported claims, requires exact file and symbol references, resolves supported conflicts, and returns `keep`, `simplify`, `refactor`, `drop`, or `needs_evidence`.
459
+
460
+ Child sessions have only `read`, `grep`, `find`, and `ls`. They do not load discovered extensions, skills, or repository context files, cannot mutate the repository, and do not save Pi session files. The workflow sends the final report through a final notification with `triggerTurn: false`, so the origin model does not produce another response. See [the Sanity Check plan](plans/2026-08-21-sanity-check-plan.md) for the selected implementation and test boundaries.
461
+
426
462
  ### Built-in monitor
427
463
 
428
464
  The built-in `monitor` workflow turns a plain request for repeated checks into
@@ -496,9 +532,10 @@ use the same card and keep the active attempt id.
496
532
 
497
533
  Headless RPC execution receives the same complete prompt without TUI metadata.
498
534
  Workflow notifications use a separate message type with `triggerTurn: false`,
499
- so a notification does not start an assistant response. See
500
- [WORKFLOW_STEP_MESSAGES.md](WORKFLOW_STEP_MESSAGES.md) for the message contract
501
- and renderer rules.
535
+ so a notification does not start an assistant response. Deferred successor turns
536
+ use an internal turn-intent contract instead of the notification outbox. See
537
+ [WORKFLOW_STEP_MESSAGES.md](WORKFLOW_STEP_MESSAGES.md) for the step-message contract
538
+ and [Deferred workflow turns](DEFERRED_TURNS.md) for the successor-turn contract.
502
539
 
503
540
  ## Result presentation
504
541
 
@@ -521,9 +558,11 @@ After the final run state has been persisted, the Pi extension sends the
521
558
  presentation instructions and bounded final result to the model as a hidden
522
559
  follow-up message. The next visible message is a normal assistant response.
523
560
  Returning `undefined`, returning an empty string, or omitting
524
- `presentationPrompt` produces no follow-up. Failed, timed-out, and cancelled
525
- runs are never presented; the extension reports their persisted status and
526
- error directly. Async prompt builders have 30 seconds to finish and receive an
561
+ `presentationPrompt` produces no presentation. Failed, timed-out, and cancelled
562
+ runs are never presented. When one of those outcomes would otherwise strand an
563
+ agent after a workflow-caused turn abort or asynchronous crash, the extension
564
+ uses the deferred-turn contract to send one factual fallback after settlement.
565
+ Async prompt builders have 30 seconds to finish and receive an
527
566
  `AbortSignal` that fires on timeout, session shutdown, or when a new workflow
528
567
  or normal user turn starts; stale presentations are discarded. Once a presentation message has
529
568
  been queued, another workflow cannot start until that assistant response
@@ -561,13 +600,17 @@ possible. Defaults worth knowing:
561
600
  and `running`. `workflow status` and `workflow cancel` accept the run ID before a run bundle
562
601
  exists.
563
602
  - If deferred activation fails, the queue stores a bounded safe error, releases the session
564
- reservation, and sends one follow-up turn to the initiating model. The model can correct the
565
- cause and make a new explicit start call. Pi Workflows does not retry blindly.
566
- - `/workflow cancel` aborts the current node and marks the run `cancelled`.
567
- When no run is live but the widget still shows a parked or finished run,
568
- the same command clears the widget.
603
+ reservation, and creates one deferred-turn intent for the initiating session. A workflow that
604
+ reports `started` and then crashes before its first prompt follows the same path. The model gets
605
+ one factual follow-up after settlement and can make a new explicit start call. Pi Workflows does
606
+ not retry blindly.
607
+ - An agent-issued `workflow cancel` aborts the current node and the current Pi turn, then creates
608
+ one deferred-turn intent. The next natural workflow message resolves it when possible; otherwise
609
+ one factual fallback starts after settlement. Direct `/workflow cancel` remains quiet because it
610
+ is explicit user control. When no run is live but the widget still shows a parked or finished run,
611
+ the command clears the widget.
569
612
  - One workflow runs per session at a time.
570
- - After the workflow tool accepts an agent-step submission, the extension removes any assistant tail text from the rest of that agent run. The next workflow message or notification is the visible continuation. Explicit final presentation remains a separate opt-in response.
613
+ - After the workflow tool accepts an agent-step submission, the extension removes any assistant tail text from the rest of that agent run. The next workflow message is the visible continuation. A deferred intent makes a workflow prompt, presentation, and factual fallback compete to provide one successor turn, so an abort cannot produce two continuation turns.
571
614
  - Agent nudges: if the model ends its turn without submitting the pending
572
615
  step, it gets a reminder, twice by default, then the step fails.
573
616
 
@@ -0,0 +1,50 @@
1
+ import {
2
+ action,
3
+ compute,
4
+ defineWorkflow,
5
+ runCommandBatch,
6
+ type CommandBatchRequest,
7
+ } from "@osolmaz/pi-workflows";
8
+
9
+ type Input = {
10
+ cwd: string;
11
+ };
12
+
13
+ export default defineWorkflow({
14
+ name: "command-batch",
15
+ input: (value): Input => value as Input,
16
+ startAt: "prepare",
17
+ nodes: {
18
+ prepare: compute({
19
+ run: ({ input }) =>
20
+ ({
21
+ maxConcurrency: 2,
22
+ items: [
23
+ {
24
+ id: "first",
25
+ command: "printf",
26
+ args: ["%s", "first"],
27
+ cwd: (input as Input).cwd,
28
+ timeoutMs: 10_000,
29
+ maxOutputChars: 10_000,
30
+ },
31
+ {
32
+ id: "second",
33
+ command: "printf",
34
+ args: ["%s", "second"],
35
+ cwd: (input as Input).cwd,
36
+ timeoutMs: 10_000,
37
+ maxOutputChars: 10_000,
38
+ },
39
+ ],
40
+ }) satisfies CommandBatchRequest,
41
+ }),
42
+ run: action({
43
+ run: async (context) =>
44
+ await runCommandBatch(context.outputs.prepare as CommandBatchRequest, {
45
+ signal: context.signal,
46
+ }),
47
+ }),
48
+ },
49
+ edges: [{ from: "prepare", to: "run" }],
50
+ });
@@ -0,0 +1 @@
1
+ export { sanityCheckWorkflow as default } from "@osolmaz/pi-workflows/builtins";
package/herdr-plugin.toml CHANGED
@@ -1,8 +1,8 @@
1
1
  id = "osolmaz.pi-workflows"
2
- name = "Pi Workflows"
3
- version = "0.11.2"
2
+ name = "pi-workflows"
3
+ version = "0.12.0"
4
4
  min_herdr_version = "0.7.0"
5
- description = "Open the active Pi Workflows run in piw from a managed Herdr pane."
5
+ description = "Open the active pi-workflows run in piw from a managed Herdr pane."
6
6
  platforms = ["linux", "macos"]
7
7
 
8
8
  [[panes]]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osolmaz/pi-workflows",
3
- "version": "0.11.2",
3
+ "version": "0.12.0",
4
4
  "description": "Workflow and controller runtime with a live terminal viewer for the pi coding agent",
5
5
  "keywords": [
6
6
  "pi-package"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/decision-presentation-v1.schema.json",
4
- "title": "Pi Workflows decision presentation v1",
4
+ "title": "pi-workflows decision presentation v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": ["schema", "summary", "blocks"],
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-accepted-v1.schema.json",
4
- "title": "Pi Workflows accepted human decision v1",
4
+ "title": "pi-workflows accepted human decision v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-accepted-v2.schema.json",
4
- "title": "Pi Workflows accepted human decision v2",
4
+ "title": "pi-workflows accepted human decision v2",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-answer-attempt-v1.schema.json",
4
- "title": "Pi Workflows human decision answer attempt v1",
4
+ "title": "pi-workflows human decision answer attempt v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-cancellation-v1.schema.json",
4
- "title": "Pi Workflows human decision cancellation v1",
4
+ "title": "pi-workflows human decision cancellation v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": ["schema", "decisionId", "requestDigest", "cancelledAt", "reason"],
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-continuation-v1.schema.json",
4
- "title": "Pi Workflows human decision continuation v1",
4
+ "title": "pi-workflows human decision continuation v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": ["schema", "decisionId", "requestDigest", "parentRunId", "runId", "createdAt"],
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-delivery-v1.schema.json",
4
- "title": "Pi Workflows human decision delivery v1",
4
+ "title": "pi-workflows human decision delivery v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-delivery-v2.schema.json",
4
- "title": "Pi Workflows human decision delivery v2",
4
+ "title": "pi-workflows human decision delivery v2",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-receipt-v1.schema.json",
4
- "title": "Pi Workflows redacted human decision receipt v1",
4
+ "title": "pi-workflows redacted human decision receipt v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-receipt-v2.schema.json",
4
- "title": "Pi Workflows redacted human decision receipt v2",
4
+ "title": "pi-workflows redacted human decision receipt v2",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-request-v1.schema.json",
4
- "title": "Pi Workflows human decision request v1",
4
+ "title": "pi-workflows human decision request v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-request-v2.schema.json",
4
- "title": "Pi Workflows human decision request v2",
4
+ "title": "pi-workflows human decision request v2",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-resolution-v1.schema.json",
4
- "title": "Pi Workflows human decision resolution v1",
4
+ "title": "pi-workflows human decision resolution v1",
5
5
  "oneOf": [
6
6
  {
7
7
  "type": "object",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-resolution-v2.schema.json",
4
- "title": "Pi Workflows human decision resolution v2",
4
+ "title": "pi-workflows human decision resolution v2",
5
5
  "oneOf": [
6
6
  {
7
7
  "type": "object",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://github.com/osolmaz/pi-workflows/schemas/human-decision-settlement-v1.schema.json",
4
- "title": "Pi Workflows human decision settlement v1",
4
+ "title": "pi-workflows human decision settlement v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
7
  "required": [
@@ -1,12 +1,43 @@
1
1
  ---
2
2
  name: autodoc
3
3
  description: Use when an existing selected solution or clear implementation plan must be recorded or updated in canonical documentation before implementation, including choosing the right repository and applying SimpleDoc conventions.
4
- compatibility: Requires Pi Workflows and the built-in autodoc workflow.
4
+ compatibility: Requires pi-workflows and the built-in autodoc workflow.
5
5
  ---
6
6
 
7
7
  # Autodoc
8
8
 
9
- Use the built-in `autodoc` Pi Workflow when it is available. At top level, list workflows, then start `autodoc` once with the task, existing plan, repository, known documents, and evidence from the conversation. Do not manually duplicate stages owned by the workflow.
9
+ ## Start the workflow
10
+
11
+ Use the built-in `autodoc` workflow when it is available. At top level, list workflows, build the complete input, and start `autodoc` once. Do not manually duplicate stages owned by the workflow.
12
+
13
+ Build the input as follows:
14
+
15
+ - `task`: State what selected plan must be recorded and that this run is documentation-only.
16
+ - `plan`: Pass the complete selected plan. Autodoc does not devise or improve it.
17
+ - `repository`: Use the absolute path of the repository that owns the canonical documentation.
18
+ - `documents`: Include every known canonical specification or plan candidate. Use an empty array when none is known.
19
+ - `evidence`: Include implementation evidence or current-document evidence when it affects whether documentation is current.
20
+
21
+ Replace the example values below with facts from the conversation, then make one start call:
22
+
23
+ ```json
24
+ {
25
+ "action": "start",
26
+ "workflow": "autodoc",
27
+ "input": {
28
+ "task": "Record the selected timeout fallback plan without implementing it.",
29
+ "plan": {
30
+ "summary": "Add one bounded read-only timeout fallback.",
31
+ "requirements": ["Keep cancellation terminal."]
32
+ },
33
+ "repository": "/absolute/path/to/repository",
34
+ "documents": ["docs/plans/timeout-fallback-plan.md"],
35
+ "evidence": {
36
+ "currentBehavior": "A timeout ends the run."
37
+ }
38
+ }
39
+ }
40
+ ```
10
41
 
11
42
  When this skill is loaded inside an active workflow step, do not start another workflow. Complete the current step contract.
12
43