@osolmaz/pi-workflows 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/README.md +64 -19
  2. package/dist/builtins/autodoc.workflow.d.ts +58 -0
  3. package/dist/builtins/autodoc.workflow.js +266 -0
  4. package/dist/builtins/autodoc.workflow.js.map +1 -0
  5. package/dist/builtins/autoimplement.workflow.d.ts +353 -0
  6. package/dist/builtins/autoimplement.workflow.js +961 -0
  7. package/dist/builtins/autoimplement.workflow.js.map +1 -0
  8. package/dist/builtins/autoplan.workflow.d.ts +58 -0
  9. package/dist/builtins/autoplan.workflow.js +190 -0
  10. package/dist/builtins/autoplan.workflow.js.map +1 -0
  11. package/dist/builtins/catalog.js +9 -1
  12. package/dist/builtins/catalog.js.map +1 -1
  13. package/dist/builtins/index.d.ts +6 -0
  14. package/dist/builtins/index.js +7 -0
  15. package/dist/builtins/index.js.map +1 -0
  16. package/dist/builtins/monitor.workflow.d.ts +29 -3
  17. package/dist/builtins/monitor.workflow.js +325 -13
  18. package/dist/builtins/monitor.workflow.js.map +1 -1
  19. package/dist/builtins/plan-approval.workflow.d.ts +83 -0
  20. package/dist/builtins/plan-approval.workflow.js +148 -0
  21. package/dist/builtins/plan-approval.workflow.js.map +1 -0
  22. package/dist/builtins/plan-presentation.d.ts +7 -0
  23. package/dist/builtins/plan-presentation.js +44 -0
  24. package/dist/builtins/plan-presentation.js.map +1 -0
  25. package/dist/extension/decision-channels.d.ts +132 -0
  26. package/dist/extension/decision-channels.js +1082 -0
  27. package/dist/extension/decision-channels.js.map +1 -0
  28. package/dist/extension/index.d.ts +1 -0
  29. package/dist/extension/index.js +426 -11
  30. package/dist/extension/index.js.map +1 -1
  31. package/dist/extension/widget.js +26 -2
  32. package/dist/extension/widget.js.map +1 -1
  33. package/dist/extension/workflow-tool.d.ts +1 -37
  34. package/dist/extension/workflow-tool.js +1 -42
  35. package/dist/extension/workflow-tool.js.map +1 -1
  36. package/dist/host/rpc-bridge.js +4 -21
  37. package/dist/host/rpc-bridge.js.map +1 -1
  38. package/dist/render/graph-render.js +46 -10
  39. package/dist/render/graph-render.js.map +1 -1
  40. package/dist/viewer/render.js +36 -2
  41. package/dist/viewer/render.js.map +1 -1
  42. package/dist/workflows/catalog.d.ts +1 -0
  43. package/dist/workflows/catalog.js +6 -0
  44. package/dist/workflows/catalog.js.map +1 -1
  45. package/dist/workflows/composition.d.ts +45 -0
  46. package/dist/workflows/composition.js +485 -0
  47. package/dist/workflows/composition.js.map +1 -0
  48. package/dist/workflows/decision-presentation.d.ts +18 -0
  49. package/dist/workflows/decision-presentation.js +417 -0
  50. package/dist/workflows/decision-presentation.js.map +1 -0
  51. package/dist/workflows/decision.d.ts +11 -5
  52. package/dist/workflows/decision.js.map +1 -1
  53. package/dist/workflows/definition.d.ts +22 -3
  54. package/dist/workflows/definition.js +46 -3
  55. package/dist/workflows/definition.js.map +1 -1
  56. package/dist/workflows/engine.d.ts +2 -1
  57. package/dist/workflows/engine.js +199 -18
  58. package/dist/workflows/engine.js.map +1 -1
  59. package/dist/workflows/graph.js +8 -6
  60. package/dist/workflows/graph.js.map +1 -1
  61. package/dist/workflows/human-decision.d.ts +87 -0
  62. package/dist/workflows/human-decision.js +583 -0
  63. package/dist/workflows/human-decision.js.map +1 -0
  64. package/dist/workflows/index.d.ts +5 -2
  65. package/dist/workflows/index.js +4 -1
  66. package/dist/workflows/index.js.map +1 -1
  67. package/dist/workflows/loader.d.ts +5 -4
  68. package/dist/workflows/loader.js +118 -18
  69. package/dist/workflows/loader.js.map +1 -1
  70. package/dist/workflows/schema.d.ts +3 -1
  71. package/dist/workflows/schema.js +64 -2
  72. package/dist/workflows/schema.js.map +1 -1
  73. package/dist/workflows/store.js +39 -2
  74. package/dist/workflows/store.js.map +1 -1
  75. package/dist/workflows/tool-input.d.ts +72 -0
  76. package/dist/workflows/tool-input.js +141 -0
  77. package/dist/workflows/tool-input.js.map +1 -0
  78. package/dist/workflows/types.d.ts +300 -2
  79. package/docs/CONTROLLERS.md +1 -1
  80. package/docs/DESIGN_PHILOSOPHY.md +1 -1
  81. package/docs/HUMAN_DECISIONS.md +371 -0
  82. package/docs/HUMAN_DECISION_PRESENTATIONS.md +323 -0
  83. package/docs/MONITOR.md +46 -18
  84. package/docs/WORKFLOW_COMPOSITION.md +333 -0
  85. package/docs/plans/2026-08-19-human-decision-gates-plan.md +296 -0
  86. package/docs/plans/2026-08-19-human-decision-presentations-plan.md +172 -0
  87. package/docs/plans/2026-08-19-provider-compatible-workflow-tool-schema-plan.md +45 -0
  88. package/docs/plans/2026-08-19-workflow-composition-plan.md +308 -0
  89. package/docs/run-bundles.md +45 -10
  90. package/docs/workflows.md +106 -15
  91. package/examples/workflows/approved-plan.workflow.ts +58 -0
  92. package/examples/workflows/autoimplement.workflow.ts +1 -92
  93. package/examples/workflows/autoplan.workflow.ts +1 -0
  94. package/examples/workflows/human-decision.workflow.ts +62 -0
  95. package/herdr-plugin.toml +1 -1
  96. package/package.json +6 -1
  97. package/schemas/decision-presentation-v1.schema.json +83 -0
  98. package/schemas/human-decision-accepted-v1.schema.json +44 -0
  99. package/schemas/human-decision-accepted-v2.schema.json +50 -0
  100. package/schemas/human-decision-answer-attempt-v1.schema.json +37 -0
  101. package/schemas/human-decision-cancellation-v1.schema.json +15 -0
  102. package/schemas/human-decision-continuation-v1.schema.json +16 -0
  103. package/schemas/human-decision-delivery-v1.schema.json +28 -0
  104. package/schemas/human-decision-delivery-v2.schema.json +36 -0
  105. package/schemas/human-decision-receipt-v1.schema.json +33 -0
  106. package/schemas/human-decision-receipt-v2.schema.json +39 -0
  107. package/schemas/human-decision-request-v1.schema.json +59 -0
  108. package/schemas/human-decision-request-v2.schema.json +69 -0
  109. package/schemas/human-decision-resolution-v1.schema.json +27 -0
  110. package/schemas/human-decision-resolution-v2.schema.json +27 -0
  111. package/schemas/human-decision-settlement-v1.schema.json +28 -0
  112. package/skills/autodoc/SKILL.md +43 -0
  113. package/skills/autoimplement/SKILL.md +58 -0
  114. package/skills/autoimplement/agents/openai.yaml +4 -0
  115. package/skills/autoplan/SKILL.md +25 -0
  116. package/skills/monitor/SKILL.md +8 -1
  117. package/skills/pi-workflows/SKILL.md +5 -3
  118. package/src/builtins/autodoc.workflow.ts +325 -0
  119. package/src/builtins/autoimplement.workflow.ts +1123 -0
  120. package/src/builtins/autoplan.workflow.ts +231 -0
  121. package/src/builtins/catalog.ts +9 -1
  122. package/src/builtins/index.ts +32 -0
  123. package/src/builtins/monitor.workflow.ts +396 -15
  124. package/src/builtins/plan-approval.workflow.ts +190 -0
  125. package/src/builtins/plan-presentation.ts +57 -0
  126. package/src/extension/decision-channels.ts +1533 -0
  127. package/src/extension/index.ts +499 -9
  128. package/src/extension/widget.ts +39 -2
  129. package/src/extension/workflow-tool.ts +5 -81
  130. package/src/host/rpc-bridge.ts +7 -30
  131. package/src/render/graph-render.ts +54 -5
  132. package/src/viewer/render.ts +56 -3
  133. package/src/workflows/catalog.ts +7 -0
  134. package/src/workflows/composition.ts +642 -0
  135. package/src/workflows/decision-presentation.ts +501 -0
  136. package/src/workflows/decision.ts +12 -5
  137. package/src/workflows/definition.ts +118 -8
  138. package/src/workflows/engine.ts +257 -20
  139. package/src/workflows/graph.ts +8 -6
  140. package/src/workflows/human-decision.ts +819 -0
  141. package/src/workflows/index.ts +89 -0
  142. package/src/workflows/loader.ts +186 -18
  143. package/src/workflows/schema.ts +79 -2
  144. package/src/workflows/store.ts +45 -2
  145. package/src/workflows/tool-input.ts +202 -0
  146. package/src/workflows/types.ts +374 -2
  147. package/examples/workflows/elegant-solution.workflow.ts +0 -95
package/docs/MONITOR.md CHANGED
@@ -17,13 +17,14 @@ The monitor checks a target, sends one status notification after every accepted
17
17
 
18
18
  ## Input fields
19
19
 
20
- | Field | Required | Type | Default | Meaning |
21
- | --------------------- | -------- | ------- | ------------------ | -------------------------------- |
22
- | `task` | Yes | string | None | Self-contained monitor task. |
23
- | `everyMinutes` | No | integer | `30` | Minutes between accepted checks. |
24
- | `stopWhen` | No | string | Explicit user stop | Condition that ends monitoring. |
25
- | `maxChecks` | No | integer | `1000` | Run safety limit. |
26
- | `checkTimeoutMinutes` | No | integer | Derived | Timeout for one agent check. |
20
+ | Field | Required | Type | Default | Meaning |
21
+ | --------------------- | -------- | ------- | ------------------ | --------------------------------- |
22
+ | `task` | Yes | string | None | Self-contained monitor task. |
23
+ | `everyMinutes` | No | integer | `30` | Minutes between accepted checks. |
24
+ | `stopWhen` | No | string | Explicit user stop | Condition that ends monitoring. |
25
+ | `maxChecks` | No | integer | `1000` | Run safety limit. |
26
+ | `checkTimeoutMinutes` | No | integer | Derived | Timeout for one agent check. |
27
+ | `repair` | No | object | None | Explicit automatic-repair policy. |
27
28
 
28
29
  `task` is 1 to 8,000 characters after trimming. It should name the target, stable identifier, source of truth, durable outputs, authorized routine work, and safety boundary. It must state any authorized mutations. Monitoring is read-only when the task does not authorize a mutation.
29
30
 
@@ -35,6 +36,10 @@ The monitor checks a target, sends one status notification after every accepted
35
36
 
36
37
  `checkTimeoutMinutes` is from 5 through 1,440. When omitted, the workflow uses the larger of 60 minutes and `everyMinutes`. The node timeout includes the existing two-minute runtime margin.
37
38
 
39
+ `repair` must set `authorized: true`. It can constrain scope, repository, base branch, merge behavior, and other implementation constraints. Omitted `merge` means the repair can prepare but cannot merge a pull request; merging requires explicit `merge: true`. Without this object the monitor is observation-only. Repair authority does not permit a protected model, benchmark, credential, hardware, spending, or scope change.
40
+
41
+ `repair.approval` is optional. It contains a logical `audience` and `maxReplans` from 1 through 20. When present, monitor sends the documented repair plan through the reusable human `plan-approval` workflow. Continue starts implementation, stop ends the repair truthfully, and replan preserves exact operator text before autoplan and autodoc run again. The model-facing workflow tool cannot approve the gate.
42
+
38
43
  `reportWhen` is removed. The monitor always reports after every accepted check.
39
44
 
40
45
  ## Check output
@@ -67,19 +72,20 @@ The check agent submits:
67
72
 
68
73
  Fields:
69
74
 
70
- | Field | Required | Type | Meaning |
71
- | ------------- | -------- | ------ | ------------------------------ |
72
- | `route` | Yes | string | `continue` or `stop`. |
73
- | `observation` | Yes | string | Current factual state. |
74
- | `report` | Yes | string | Concise user-facing update. |
75
- | `progress` | No | object | Current progress tracks. |
76
- | `reason` | Yes | string | Reason for the selected route. |
75
+ | Field | Required | Type | Meaning |
76
+ | ------------- | ---------- | ------ | ------------------------------------------- |
77
+ | `route` | Yes | string | `continue`, authorized `repair`, or `stop`. |
78
+ | `observation` | Yes | string | Current factual state. |
79
+ | `report` | Yes | string | Concise user-facing update. |
80
+ | `progress` | No | object | Current progress tracks. |
81
+ | `repair` | For repair | object | Problem, evidence, and stable fingerprint. |
82
+ | `reason` | Yes | string | Reason for the selected route. |
77
83
 
78
84
  `observation` is at most 8,000 characters. `report` is at most 4,000 characters. `reason` is at most 2,000 characters. All three must be non-empty after trimming.
79
85
 
80
86
  `progress.tracks` contains from 1 through 256 entries. Each entry has a unique `key` and one valid `pi-workflows.progress.v1` data object. The progress update rules, reserved `overall` key, and validation behavior come from [WORKFLOW_UPDATES.md](WORKFLOW_UPDATES.md).
81
87
 
82
- Unknown check fields are validation errors. A missing report is a validation error for both routes.
88
+ Unknown check fields are validation errors. A missing report is a validation error for every route. A repair route without input authorization or repair details is also invalid.
83
89
 
84
90
  ## Graph
85
91
 
@@ -93,7 +99,20 @@ prepare
93
99
  → report
94
100
  → decide
95
101
  ├─ stop → finish
96
- └─ continue → schedule → sleep → check
102
+ ├─ continue → schedule → sleep → check
103
+ └─ repair → repairGuard
104
+ ├─ blocked → repairBlocked → repairReport → finish
105
+ └─ initialDesign: autoplan
106
+ ├─ blocked → repairBlocked
107
+ └─ documentation: autodoc
108
+ ├─ blocked → repairBlocked
109
+ ├─ no approval → implementation: autoimplement
110
+ └─ approval: plan-approval
111
+ ├─ stop → repairBlocked
112
+ ├─ replan → initialDesign
113
+ └─ continue → implementation: autoimplement
114
+ ├─ blocked → repairBlocked
115
+ └─ completed → check
97
116
  ```
98
117
 
99
118
  - `prepare` is a `compute` node that validates and applies input defaults.
@@ -102,6 +121,9 @@ prepare
102
121
  - `publish_progress` is a function `action` that publishes each validated observed track.
103
122
  - `report` is a `notify` node that queues exactly one report.
104
123
  - `decide` is a `compute` node that applies the route and check safety limit.
124
+ - `repairGuard` stops a repeated issue when a completed repair did not change its fingerprint or observed target state.
125
+ - `initialDesign`, `documentation`, optional `approval`, and `implementation` are included workflows. Replan returns exact operator text to initialDesign. Autoimplement can enter nested `autoplan`, then autodoc, when later evidence requires redesign.
126
+ - `repairBlocked` and `repairReport` preserve a truthful blocked result and user notification.
105
127
  - `schedule` is a function `action` that publishes the next-check time.
106
128
  - `sleep` is the existing runtime-owned shell wait.
107
129
  - `finish` is a `compute` node that returns the final observation and reason.
@@ -260,7 +282,9 @@ The monitor skill must disclose a surfaced host limit and must never invent a sm
260
282
 
261
283
  ## Safety boundaries
262
284
 
263
- An observation-only request authorizes only observation and scheduled checks. When the user asks the monitor to keep an objective running or finish it, the monitor skill may record routine, bounded work in `task`, including retries, restarts, pinned task code, tests, configuration repairs, and temporary cleanup. The task must preserve the exact objective and state every mutation boundary.
285
+ An observation-only request authorizes only observation and scheduled checks. Automatic repair also requires the explicit `repair` input object. An optional `repair.approval` object names a logical audience and inserts human plan approval after autodoc. Continue starts implementation, stop ends truthfully, and replan sends the exact human text back to autoplan before autodoc and approval run again.
286
+
287
+ When the user asks the monitor to keep an objective running or finish it, the monitor skill may record routine, bounded work in `task` and the repair policy. This can include retries, restarts, pinned task code, tests, configuration repairs, and temporary cleanup. The task must preserve the exact objective and state every mutation boundary.
264
288
 
265
289
  A progress object is data. It cannot contain a command or grant execution authority. Fixed probes belong in workflow-authored `action` or `shell` nodes.
266
290
 
@@ -273,7 +297,11 @@ The implementation must test:
273
297
  - input defaults and bounds
274
298
  - removal of `reportWhen`
275
299
  - rejection of old quiet routes
276
- - required reports on both routes
300
+ - required reports on every route
301
+ - repair rejection without explicit authorization
302
+ - outer design, autodoc, optional approval, nested redesign, and post-repair checking
303
+ - continue, stop, and exact-text replan approval routes
304
+ - repeated no-progress repair detection
277
305
  - exactly one notification per accepted check
278
306
  - no assistant turn from a notification
279
307
  - progress omission and multiple tracks
@@ -0,0 +1,333 @@
1
+ # Workflow composition
2
+
3
+ Pi Workflows can include one workflow inside another without copying nodes, prompts, or routing logic. The included workflow still runs on its own. The parent supplies input and connects the included workflow's named exits to later parent steps.
4
+
5
+ Composition keeps one run, trace, pause state, cancellation state, and final presentation. Controllers remain the correct tool for independent or indefinitely reconciled child runs.
6
+
7
+ Work is tracked in the [workflow composition plan](plans/2026-08-19-workflow-composition-plan.md).
8
+
9
+ ## TypeScript API
10
+
11
+ A TypeScript workflow definition is both executable code and a typed contract. Its input parser and exit parsers provide runtime validation and TypeScript inference from one declaration.
12
+
13
+ ```typescript
14
+ import { agent, compute, defineWorkflow } from "@osolmaz/pi-workflows";
15
+
16
+ type RepairInput = { task: string };
17
+ type Fixed = { summary: string };
18
+ type Blocked = { reason: string };
19
+
20
+ export default defineWorkflow({
21
+ source: import.meta.url,
22
+ name: "repair",
23
+ input: (value): RepairInput => {
24
+ if (
25
+ value === null ||
26
+ typeof value !== "object" ||
27
+ typeof (value as RepairInput).task !== "string"
28
+ ) {
29
+ throw new Error("repair input requires task");
30
+ }
31
+ return value as RepairInput;
32
+ },
33
+ startAt: "implement",
34
+ exits: {
35
+ fixed: {
36
+ from: "finish",
37
+ validate: (value): Fixed => value as Fixed,
38
+ },
39
+ blocked: {
40
+ from: "blocked",
41
+ validate: (value): Blocked => value as Blocked,
42
+ },
43
+ },
44
+ nodes: {
45
+ implement: agent({
46
+ prompt: ({ input }) => `Implement ${input.task}`,
47
+ expectedOutput: `{ "route": "fixed" | "blocked", "summary": "result" }`,
48
+ }),
49
+ finish: compute({ run: ({ outputs }) => outputs.implement }),
50
+ blocked: compute({ run: () => ({ reason: "repair could not continue" }) }),
51
+ },
52
+ edges: [
53
+ {
54
+ from: "implement",
55
+ switch: {
56
+ on: "$.route",
57
+ cases: { fixed: "finish", blocked: "blocked" },
58
+ },
59
+ },
60
+ ],
61
+ });
62
+ ```
63
+
64
+ ### Direct imports
65
+
66
+ Direct imports are the normal TypeScript interface. `includeWorkflow()` checks the mapped input and makes the child exit names available to the parent definition.
67
+
68
+ ```typescript
69
+ import { agent, compute, defineWorkflow, includeWorkflow } from "@osolmaz/pi-workflows";
70
+ import repair from "./repair.workflow.js";
71
+
72
+ export default defineWorkflow({
73
+ source: import.meta.url,
74
+ name: "monitor-with-repair",
75
+ startAt: "check",
76
+ includes: {
77
+ repair: includeWorkflow(repair, {
78
+ input: ({ outputs }) => ({
79
+ task: (outputs.check as { issue: string }).issue,
80
+ }),
81
+ }),
82
+ },
83
+ nodes: {
84
+ check: agent({ prompt: () => "Check the target." }),
85
+ wait: compute({ run: () => ({}) }),
86
+ finish: compute({ run: ({ outputs }) => outputs.check }),
87
+ },
88
+ edges: [
89
+ {
90
+ from: "check",
91
+ switch: {
92
+ on: "$.route",
93
+ cases: { continue: "wait", repair: "repair", stop: "finish" },
94
+ },
95
+ },
96
+ { from: "wait", to: "check" },
97
+ { from: "repair.fixed", to: "check" },
98
+ { from: "repair.blocked", to: "finish" },
99
+ ],
100
+ });
101
+ ```
102
+
103
+ `repair` is the only parent-visible entry. `repair.fixed` and `repair.blocked` are its exits. The parent cannot connect to an internal child node.
104
+
105
+ ### Dynamic references
106
+
107
+ Names and paths remain available for project overrides and configuration-driven loading:
108
+
109
+ ```typescript
110
+ includeWorkflow({ workflow: "repair", input: mapRepair });
111
+ includeWorkflow({ workflow: "builtin:repair", input: mapRepair });
112
+ includeWorkflow({ workflow: "./repair.workflow.ts", input: mapRepair });
113
+ ```
114
+
115
+ A dynamic reference is resolved before the run starts. Runtime input and exit validation still applies. A direct import gives better TypeScript inference and is preferred when the parent and child ship together.
116
+
117
+ Relative references resolve from the including workflow file. Absolute paths keep their normal meaning. Project and global lookup remain available, as do built-ins. Built-ins cannot use relative paths unless their definitions use direct imports.
118
+
119
+ ## Definition rules
120
+
121
+ - A workflow has one entry through `startAt`.
122
+ - A workflow can declare several named exits.
123
+ - Each exit points to one successful terminal node.
124
+ - One terminal node can define at most one exit.
125
+ - Exit and mount names use the normal node-name rules.
126
+ - A parent edge enters a child through the mount name.
127
+ - A parent edge leaves a child through `<mount>.<exit>`.
128
+ - Parent edges cannot name child nodes.
129
+ - The same child source can be mounted several times under different names.
130
+ - Re-entering a mount creates a fresh invocation.
131
+
132
+ A standalone workflow ignores its exit names for routing. Its terminal node completes the run as before.
133
+
134
+ ## Typed contracts
135
+
136
+ `WorkflowDefinition` carries generic input and exit types. `includeWorkflow()` uses them to check the parent input mapper and expose a discriminated child result:
137
+
138
+ ```typescript
139
+ type RepairResult = { exit: "fixed"; output: Fixed } | { exit: "blocked"; output: Blocked };
140
+ ```
141
+
142
+ The parent reads the latest result from `outputs.repair`. `includedResult(repairWorkflow, outputs.repair)` returns the discriminated result type without a cast. Unknown exit names and incompatible direct-import input mappers are TypeScript errors. Dynamic references use runtime checks and can supply an explicit contract when compile-time checking is required.
143
+
144
+ `defineWorkflowRegistry()` creates a typed set of shipped workflows. Shipped contracts use a stable `contractId`. A project or global override must match that identity and keep the registered input and exit shape. The selected source remains subject to the normal project, global, and built-in precedence rules.
145
+
146
+ ## Resolution
147
+
148
+ Composition is resolved before `run_started`.
149
+
150
+ 1. Resolve the root source.
151
+ 2. Resolve every direct or dynamic child reference.
152
+ 3. Repeat for nested includes.
153
+ 4. Validate each standalone graph and its input and exit declarations.
154
+ 5. Reject source cycles and report the full mount chain.
155
+ 6. Build one executable graph with qualified node names.
156
+ 7. Freeze the source set and resolved definition digest.
157
+
158
+ Resolution is eager. An unused include must still exist. A workflow reference cannot change after the run starts.
159
+
160
+ Direct and indirect source cycles are invalid:
161
+
162
+ ```text
163
+ A -> A
164
+ A -> B -> A
165
+ A -> B -> C -> A
166
+ ```
167
+
168
+ Using one source at independent mount paths is valid:
169
+
170
+ ```text
171
+ monitor/initialDesign
172
+ monitor/implementation/redesign
173
+ ```
174
+
175
+ ## Runtime behavior
176
+
177
+ ### Local child context
178
+
179
+ A child callback receives:
180
+
181
+ - its mapped and validated input;
182
+ - outputs and results from its current invocation under local node names;
183
+ - local steps for its current invocation;
184
+ - the local current node name;
185
+ - the root run ID and active abort signal.
186
+
187
+ A child cannot read parent state except through mapped input. A parent sees only the declared child result.
188
+
189
+ ### Re-entry
190
+
191
+ Each mount entry starts with empty local outputs and results. Earlier invocation data stays in the trace but cannot satisfy callbacks in a later invocation. The latest named exit replaces the parent-visible mount output.
192
+
193
+ ### Limits and progress
194
+
195
+ The root `maxSteps` limits all real node attempts in the run. Each child `maxSteps` limits one invocation. Include entry and exit transitions are recorded but do not count as user-authored node attempts.
196
+
197
+ A repair loop must also check useful progress. A repeated issue stops as blocked when the issue, plan, implementation revision, supporting evidence, and target state have not changed. `maxSteps` remains the final safety bound.
198
+
199
+ ### Failures, pauses, and cancellation
200
+
201
+ Child nodes keep their normal timeouts. Unhandled failures, timeouts, cancellations, and routing errors keep their existing run outcome. A parent cannot turn an unhandled failure into success through a named exit.
202
+
203
+ A checkpoint inside a child uses the normal continuation behavior and resumes at the qualified child location. Pause and cancellation apply to the complete run.
204
+
205
+ ### Reports and presentation
206
+
207
+ Notify nodes and updates keep qualified node identities. Only the root workflow produces final presentation. A child's `presentationPrompt` applies when the child runs alone and is ignored when included.
208
+
209
+ ## Persistence
210
+
211
+ Composition extends the existing run bundle.
212
+
213
+ The manifest and state record:
214
+
215
+ ```json
216
+ {
217
+ "workflowSource": {
218
+ "kind": "file",
219
+ "path": "/path/to/monitor.workflow.ts",
220
+ "hash": "1111111111111111111111111111111111111111111111111111111111111111"
221
+ },
222
+ "workflowSources": [
223
+ {
224
+ "mountPath": ["repair"],
225
+ "workflowName": "repair",
226
+ "source": {
227
+ "kind": "file",
228
+ "path": "/path/to/repair.workflow.ts",
229
+ "hash": "2222222222222222222222222222222222222222222222222222222222222222"
230
+ }
231
+ }
232
+ ],
233
+ "definitionDigest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
234
+ }
235
+ ```
236
+
237
+ `workflowSources` is sorted by mount path. The definition snapshot records the resolved mounts and qualified graph. The trace adds `include_entered` and `include_exited` events with mount path, invocation number, and named exit. It does not copy source text or credentials.
238
+
239
+ Resume resolves and verifies the complete source set and definition digest. Any missing or changed child source refuses normal resume. Old runs without composition metadata remain readable.
240
+
241
+ ## Viewer behavior
242
+
243
+ Existing readers can render qualified nodes as a flat graph. Updated viewers group nodes under their mount path while keeping the exact qualified name available in details and replay.
244
+
245
+ ```text
246
+ monitor
247
+ initialDesign
248
+ frame
249
+ choose
250
+ plan
251
+ implementation
252
+ implement
253
+ verify
254
+ redesign
255
+ frame
256
+ choose
257
+ plan
258
+ ```
259
+
260
+ ## Autoplan, autodoc, and autoimplement
261
+
262
+ `autoplan` accepts the problem, scope, constraints, an optional previous plan, and new evidence. It automatically selects the best practical in-scope solution. The ideal end state can win when it is feasible, but an unavailable upstream change cannot block a valid practical solution. It exits through `ready` or `blocked` and returns a plan digest and change status.
263
+
264
+ `autodoc` accepts an already selected plan or finds it in the active conversation and referenced canonical documents. It adopts current documentation or updates the canonical specification and implementation plan, runs documentation checks, and returns a documented-plan record. It never selects a solution or implements one.
265
+
266
+ `autoimplement` requires a clear existing plan, but the structured `plan` input is optional because the plan can already be in conversation context or canonical documentation. It blocks when it cannot find a clear plan. It skips autodoc when documentation is current and includes autodoc when documentation is missing or stale. The absence of `input.plan` never routes to initial autoplan.
267
+
268
+ Autoimplement includes `autoplan` only as evidence-driven `redesign`. When implementation, verification, review, comments, or CI proves that the approach is wrong, the revised plan passes through autodoc before implementation resumes. Local bugs go to a fix step instead.
269
+
270
+ Review rounds record findings at every severity from P0 through P2. P0 or P1 findings require another implementation and review round. A P2-only round can be addressed, but the workflow does not run the reviewer again solely because P2 work changed files.
271
+
272
+ Reviewer and CI commands record the executable, arguments, working directory, and timeout as structured fields. A failed reviewer invocation returns to a model step that corrects the command. The executable remains `pi-reviewer`; no hidden reviewer substitution is allowed.
273
+
274
+ A CI wait is bounded to five minutes. If CI remains pending, the workflow asks the model to run additional useful local tests. It does not spend another model turn waiting and checks CI again after the tests.
275
+
276
+ Autoimplement prepares a ready PR by default. It merges only when its input explicitly sets `merge: true`. Monitor repair passes that permission only when `repair.merge` is explicitly true. Required CI still gates merge unless repository policy permits a documented unrelated failure.
277
+
278
+ ## Monitor repair
279
+
280
+ Monitor remains observation-only unless its input explicitly authorizes mutation. An authorized repair path is:
281
+
282
+ ```text
283
+ check
284
+ -> initialDesign: autoplan
285
+ -> documentation: autodoc
286
+ -> approval: plan-approval when requested
287
+ -> replan: initialDesign
288
+ -> implementation: autoimplement
289
+ -> redesign: autoplan -> autodoc when needed
290
+ -> check
291
+ ```
292
+
293
+ The outer `autoplan` creates the first plan. Autodoc records it before implementation. An optional plan approval gate can continue, stop, or return exact replan instructions to autoplan. The inner redesign mount revises a plan only when new evidence invalidates it and records the revision through autodoc. The monitor checks the target again after implementation and does not trust a repair claim by itself.
294
+
295
+ A protected change to model choice, benchmark method, credentials, hardware, spending authority, or another user decision exits as blocked. The workflow never changes the protected part of the task silently.
296
+
297
+ ## Compatibility and release
298
+
299
+ Workflows without inputs, exits, or includes run unchanged. Existing controller child workflows remain unchanged. Existing terminal run bundles remain readable.
300
+
301
+ This is a compatible public API addition under the project's pre-1.0 policy. It targets `0.10.0` if no earlier release changes the next version.
302
+
303
+ ## Contract impact
304
+
305
+ - **Session state:** normal workflow messages and tool results only.
306
+ - **Other persistent data:** additive source and mount data, definition digests, and include events in existing run bundles.
307
+ - **Pi internals:** none.
308
+ - **Public Pi API:** existing extension APIs only.
309
+ - **Public Pi Workflows API:** typed workflow inputs and exits, `includeWorkflow()`, direct imports, dynamic references, and `defineWorkflowRegistry()`.
310
+
311
+ ## Required tests
312
+
313
+ The implementation must cover:
314
+
315
+ - standalone workflows with exits;
316
+ - direct typed imports and dynamic references;
317
+ - compile-time invalid input and exit examples;
318
+ - runtime input and exit validation;
319
+ - one and several named exits;
320
+ - nested and repeated mounts;
321
+ - re-entry without stale data;
322
+ - source-cycle rejection;
323
+ - root and per-invocation step limits;
324
+ - failures and timeouts plus cancellation, checkpoint resume, and pause behavior;
325
+ - changed child sources and changed definition digests;
326
+ - include trace events and definition snapshots;
327
+ - flat and grouped rendering;
328
+ - reviewer command correction;
329
+ - P0 through P2 plus clean review routes;
330
+ - five-minute CI wait and opportunistic testing routes;
331
+ - monitor observation-only and authorized repair modes;
332
+ - repeated repair with no progress;
333
+ - real-Pi execution of nested monitor repair.