@osolmaz/pi-workflows 0.12.1 → 0.13.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 (209) hide show
  1. package/README.md +52 -28
  2. package/dist/builtins/autodoc.workflow.d.ts +4 -4
  3. package/dist/builtins/autoimplement.workflow.d.ts +369 -73
  4. package/dist/builtins/autoplan.workflow.d.ts +126 -13
  5. package/dist/builtins/autoplan.workflow.js +200 -29
  6. package/dist/builtins/autoplan.workflow.js.map +1 -1
  7. package/dist/builtins/catalog.js +6 -4
  8. package/dist/builtins/catalog.js.map +1 -1
  9. package/dist/builtins/index.d.ts +2 -1
  10. package/dist/builtins/index.js +1 -0
  11. package/dist/builtins/index.js.map +1 -1
  12. package/dist/builtins/monitor.workflow.d.ts +56 -21
  13. package/dist/builtins/monitor.workflow.js +497 -216
  14. package/dist/builtins/monitor.workflow.js.map +1 -1
  15. package/dist/builtins/plain-summary.workflow.d.ts +32 -0
  16. package/dist/builtins/plain-summary.workflow.js +134 -0
  17. package/dist/builtins/plain-summary.workflow.js.map +1 -0
  18. package/dist/builtins/plan-change.workflow.d.ts +170 -22
  19. package/dist/builtins/sanity-check.workflow.d.ts +45 -3
  20. package/dist/builtins/sanity-check.workflow.js +45 -7
  21. package/dist/builtins/sanity-check.workflow.js.map +1 -1
  22. package/dist/controllers/effects.d.ts +3 -2
  23. package/dist/controllers/effects.js +8 -1
  24. package/dist/controllers/effects.js.map +1 -1
  25. package/dist/controllers/index.d.ts +1 -1
  26. package/dist/controllers/index.js +1 -1
  27. package/dist/controllers/index.js.map +1 -1
  28. package/dist/controllers/manager.d.ts +1 -0
  29. package/dist/controllers/manager.js +41 -17
  30. package/dist/controllers/manager.js.map +1 -1
  31. package/dist/controllers/sqlite.d.ts +107 -85
  32. package/dist/controllers/sqlite.js +1611 -1486
  33. package/dist/controllers/sqlite.js.map +1 -1
  34. package/dist/controllers/store.d.ts +9 -8
  35. package/dist/controllers/store.js +1 -31
  36. package/dist/controllers/store.js.map +1 -1
  37. package/dist/controllers/types.d.ts +3 -0
  38. package/dist/controllers/workflow-engine-scheduler.d.ts +1 -1
  39. package/dist/controllers/workflow-engine-scheduler.js +3 -5
  40. package/dist/controllers/workflow-engine-scheduler.js.map +1 -1
  41. package/dist/controllers/workflows.d.ts +2 -2
  42. package/dist/controllers/workflows.js +11 -10
  43. package/dist/controllers/workflows.js.map +1 -1
  44. package/dist/extension/controller-host.js +2 -2
  45. package/dist/extension/controller-host.js.map +1 -1
  46. package/dist/extension/decision-channels.d.ts +2 -0
  47. package/dist/extension/decision-channels.js +311 -118
  48. package/dist/extension/decision-channels.js.map +1 -1
  49. package/dist/extension/executor.d.ts +9 -2
  50. package/dist/extension/executor.js +89 -2
  51. package/dist/extension/executor.js.map +1 -1
  52. package/dist/extension/herdr-viewer.d.ts +0 -1
  53. package/dist/extension/herdr-viewer.js +0 -4
  54. package/dist/extension/herdr-viewer.js.map +1 -1
  55. package/dist/extension/index.js +156 -103
  56. package/dist/extension/index.js.map +1 -1
  57. package/dist/extension/recorder.d.ts +3 -10
  58. package/dist/extension/recorder.js +13 -22
  59. package/dist/extension/recorder.js.map +1 -1
  60. package/dist/extension/step-message.d.ts +7 -2
  61. package/dist/extension/step-message.js +94 -2
  62. package/dist/extension/step-message.js.map +1 -1
  63. package/dist/extension/widget.js +6 -0
  64. package/dist/extension/widget.js.map +1 -1
  65. package/dist/host/rpc-executor.d.ts +3 -0
  66. package/dist/host/rpc-executor.js +2 -0
  67. package/dist/host/rpc-executor.js.map +1 -1
  68. package/dist/host/runner.d.ts +3 -6
  69. package/dist/host/runner.js +83 -32
  70. package/dist/host/runner.js.map +1 -1
  71. package/dist/render/graph-render.js +14 -8
  72. package/dist/render/graph-render.js.map +1 -1
  73. package/dist/state/database.d.ts +35 -0
  74. package/dist/state/database.js +287 -0
  75. package/dist/state/database.js.map +1 -0
  76. package/dist/state/index.d.ts +4 -0
  77. package/dist/state/index.js +5 -0
  78. package/dist/state/index.js.map +1 -0
  79. package/dist/state/json.d.ts +6 -0
  80. package/dist/state/json.js +38 -0
  81. package/dist/state/json.js.map +1 -0
  82. package/dist/state/mutation.d.ts +57 -0
  83. package/dist/state/mutation.js +255 -0
  84. package/dist/state/mutation.js.map +1 -0
  85. package/dist/state/schema.d.ts +6 -0
  86. package/dist/state/schema.js +473 -0
  87. package/dist/state/schema.js.map +1 -0
  88. package/dist/viewer/cli.d.ts +2 -2
  89. package/dist/viewer/cli.js +142 -122
  90. package/dist/viewer/cli.js.map +1 -1
  91. package/dist/viewer/render.d.ts +4 -4
  92. package/dist/viewer/render.js +2 -17
  93. package/dist/viewer/render.js.map +1 -1
  94. package/dist/viewer/session-reducer.d.ts +1 -1
  95. package/dist/viewer/session-reducer.js +1 -1
  96. package/dist/viewer/tui.d.ts +3 -3
  97. package/dist/viewer/tui.js +15 -13
  98. package/dist/viewer/tui.js.map +1 -1
  99. package/dist/viewer/watch.d.ts +2 -5
  100. package/dist/viewer/watch.js +13 -13
  101. package/dist/viewer/watch.js.map +1 -1
  102. package/dist/workflows/composition.js +12 -2
  103. package/dist/workflows/composition.js.map +1 -1
  104. package/dist/workflows/definition.d.ts +6 -2
  105. package/dist/workflows/definition.js +17 -0
  106. package/dist/workflows/definition.js.map +1 -1
  107. package/dist/workflows/engine.d.ts +6 -6
  108. package/dist/workflows/engine.js +183 -103
  109. package/dist/workflows/engine.js.map +1 -1
  110. package/dist/workflows/errors.d.ts +3 -3
  111. package/dist/workflows/errors.js +3 -3
  112. package/dist/workflows/human-decision.d.ts +29 -4
  113. package/dist/workflows/human-decision.js +547 -283
  114. package/dist/workflows/human-decision.js.map +1 -1
  115. package/dist/workflows/index.d.ts +4 -5
  116. package/dist/workflows/index.js +3 -4
  117. package/dist/workflows/index.js.map +1 -1
  118. package/dist/workflows/schema.js +17 -1
  119. package/dist/workflows/schema.js.map +1 -1
  120. package/dist/workflows/store.d.ts +83 -103
  121. package/dist/workflows/store.js +902 -951
  122. package/dist/workflows/store.js.map +1 -1
  123. package/dist/workflows/types.d.ts +55 -81
  124. package/docs/CONTROLLERS.md +10 -8
  125. package/docs/DEFERRED_TURNS.md +2 -2
  126. package/docs/DESIGN_PHILOSOPHY.md +4 -2
  127. package/docs/HUMAN_DECISIONS.md +13 -14
  128. package/docs/MONITOR.md +179 -231
  129. package/docs/SQLITE_STATE.md +219 -0
  130. package/docs/WORKFLOW_COMPOSITION.md +19 -19
  131. package/docs/WORKFLOW_STEP_MESSAGES.md +20 -18
  132. package/docs/WORKFLOW_UPDATES.md +10 -9
  133. package/docs/development.md +9 -9
  134. package/docs/live-replay-protocol.md +28 -37
  135. package/docs/plans/2026-08-16-workflow-updates-plan.md +1 -1
  136. package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
  137. package/docs/plans/2026-08-21-autoimplement-timeout-fallback-plan.md +1 -1
  138. package/docs/plans/2026-08-21-plan-change-approval-policy-plan.md +1 -1
  139. package/docs/plans/2026-08-21-sanity-check-plan.md +30 -16
  140. package/docs/plans/2026-08-22-goal-finishing-monitor-plan.md +200 -0
  141. package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +701 -0
  142. package/docs/plans/2026-08-23-sqlite-state-plan.md +970 -0
  143. package/docs/plans/replayable-run-bundles-implementation-plan.md +2 -2
  144. package/docs/plans/session-event-replay-implementation-plan.md +1 -1
  145. package/docs/plans/tui-viewer-implementation-plan.md +1 -1
  146. package/docs/session-event-journal.md +63 -434
  147. package/docs/tui-viewer.md +13 -15
  148. package/docs/workflows.md +104 -50
  149. package/examples/workflows/plain-summary.workflow.ts +1 -0
  150. package/herdr-plugin.toml +1 -1
  151. package/package.json +1 -1
  152. package/plugins/herdr/viewer.mjs +1 -11
  153. package/skills/autoplan/SKILL.md +5 -4
  154. package/skills/monitor/SKILL.md +91 -163
  155. package/skills/pi-workflows/SKILL.md +7 -7
  156. package/skills/sanity-check/SKILL.md +1 -1
  157. package/src/builtins/autoplan.workflow.ts +290 -40
  158. package/src/builtins/catalog.ts +6 -4
  159. package/src/builtins/index.ts +7 -1
  160. package/src/builtins/monitor.workflow.ts +663 -249
  161. package/src/builtins/plain-summary.workflow.ts +185 -0
  162. package/src/builtins/sanity-check.workflow.ts +62 -7
  163. package/src/controllers/effects.ts +7 -0
  164. package/src/controllers/index.ts +0 -6
  165. package/src/controllers/manager.ts +72 -32
  166. package/src/controllers/sqlite.ts +2420 -1948
  167. package/src/controllers/store.ts +17 -38
  168. package/src/controllers/types.ts +3 -0
  169. package/src/controllers/workflow-engine-scheduler.ts +4 -8
  170. package/src/controllers/workflows.ts +45 -21
  171. package/src/extension/controller-host.ts +1 -2
  172. package/src/extension/decision-channels.ts +427 -144
  173. package/src/extension/executor.ts +105 -2
  174. package/src/extension/herdr-viewer.ts +0 -5
  175. package/src/extension/index.ts +180 -118
  176. package/src/extension/recorder.ts +13 -22
  177. package/src/extension/step-message.ts +106 -4
  178. package/src/extension/widget.ts +8 -0
  179. package/src/host/rpc-executor.ts +4 -0
  180. package/src/host/runner.ts +93 -41
  181. package/src/render/graph-render.ts +11 -4
  182. package/src/state/database.ts +375 -0
  183. package/src/state/index.ts +29 -0
  184. package/src/state/json.ts +42 -0
  185. package/src/state/mutation.ts +435 -0
  186. package/src/state/schema.ts +475 -0
  187. package/src/viewer/cli.ts +151 -144
  188. package/src/viewer/render.ts +12 -24
  189. package/src/viewer/session-reducer.ts +1 -1
  190. package/src/viewer/tui.ts +18 -17
  191. package/src/viewer/watch.ts +13 -17
  192. package/src/workflows/composition.ts +12 -3
  193. package/src/workflows/definition.ts +36 -3
  194. package/src/workflows/engine.ts +212 -116
  195. package/src/workflows/errors.ts +3 -3
  196. package/src/workflows/human-decision.ts +795 -340
  197. package/src/workflows/index.ts +15 -19
  198. package/src/workflows/schema.ts +19 -1
  199. package/src/workflows/store.ts +1295 -1163
  200. package/src/workflows/types.ts +61 -81
  201. package/dist/workflows/artifacts.d.ts +0 -40
  202. package/dist/workflows/artifacts.js +0 -155
  203. package/dist/workflows/artifacts.js.map +0 -1
  204. package/dist/workflows/migrate-sources.d.ts +0 -42
  205. package/dist/workflows/migrate-sources.js +0 -133
  206. package/dist/workflows/migrate-sources.js.map +0 -1
  207. package/docs/run-bundles.md +0 -481
  208. package/src/workflows/artifacts.ts +0 -188
  209. package/src/workflows/migrate-sources.ts +0 -178
package/docs/MONITOR.md CHANGED
@@ -2,173 +2,168 @@
2
2
 
3
3
  This specification defines the built-in `monitor` workflow and its use of [workflow updates](WORKFLOW_UPDATES.md).
4
4
 
5
- The monitor checks a target, sends one status notification after every accepted check, publishes optional progress tracks, waits, and repeats until its stop rule or safety limit is reached.
5
+ Monitor finishes an authorized goal. It observes the real target, performs a safe action when work is incomplete and idle, confirms the result, and checks again on schedule until the goal is complete or cannot continue safely.
6
6
 
7
- ## Minimal input
7
+ ## Input
8
8
 
9
9
  ```json
10
10
  {
11
- "task": "Check pull request 123 in osolmaz/example. Read state and checks with gh. Observe only.",
12
- "stopWhen": "Stop when the pull request is merged or closed."
11
+ "task": "Resume the six missing modules and monitor the full 27-module build. Use the saved outputs. Keep total paid work below the recorded limit.",
12
+ "stopWhen": "Stop when all 27 modules have verified outputs or when safe continuation is blocked.",
13
+ "everyMinutes": 15
13
14
  }
14
15
  ```
15
16
 
16
- `everyMinutes` defaults to 30. The first check starts immediately.
17
+ The public input has four fields:
17
18
 
18
- ## Input fields
19
+ | Field | Required | Type | Default | Meaning |
20
+ | -------------- | -------- | ------- | ------------------ | --------------------------------- |
21
+ | `task` | Yes | string | None | Goal, authority, and constraints. |
22
+ | `stopWhen` | No | string | Explicit user stop | Condition that ends monitoring. |
23
+ | `everyMinutes` | No | integer | `30` | Minutes between timed checks. |
24
+ | `maxChecks` | No | integer | `1000` | Observation safety limit. |
19
25
 
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. |
26
+ `task` is 1 to 8,000 characters after trimming. It must preserve the user's goal and the authority already present in the conversation and repository instructions. This includes:
28
27
 
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.
28
+ - allowed files, systems, providers, runtimes, and resources
29
+ - forbidden changes
30
+ - cost and resource limits
31
+ - required checks
32
+ - stop conditions
33
+ - allowed recovery actions
34
+ - durable progress, checkpoints, and known target identifiers
30
35
 
31
- `everyMinutes` is from 1 through 1,440. The interval begins after a check report is durably queued. It does not delay the first check.
36
+ `stopWhen` is 1 to 4,000 characters when supplied. When the conversation gives no finish condition, the workflow uses `Stop only when the user explicitly asks to stop.`
32
37
 
33
- `stopWhen` is 1 to 4,000 characters when supplied. When the conversation gives no clear finish condition, the caller omits it and the workflow uses `Stop only when the user explicitly asks to stop.`
38
+ `everyMinutes` is an integer from 1 through 1,440. The first observation starts immediately. The interval applies only after an observation proves that work is moving or waiting for an external event.
34
39
 
35
- `maxChecks` is from 1 through 1,000. Agents must omit it unless the user explicitly asks for a fixed check count. The workflow's default of 1,000 is a disclosed runtime safety limit. The agent does not infer it as a finish condition.
40
+ `maxChecks` is an integer from 1 through 1,000. Callers omit it unless the user asks for a fixed limit. The default is a runtime safety limit.
36
41
 
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.
42
+ The input parser rejects every unknown field before a run is created. Inputs such as `audience`, `repair`, and `checkTimeoutMinutes` fail with a direct unsupported-field error. There are no compatibility aliases for removed fields.
38
43
 
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.
44
+ ## Authority
40
45
 
41
- `repair.approval` uses `auto`, `required`, or `skip` mode. When omitted, Monitor uses `auto` with audience `operator`, a 10-minute timeout, and three allowed replans. Auto mode asks and then continues with the exact plan if no answer is accepted by the deadline. Required mode waits for an explicit human answer. Skip mode asks nothing. Continue starts implementation, stop ends the repair truthfully, and replan preserves exact operator text before the shared plan-change workflow runs again. The model-facing workflow tool cannot approve the gate.
46
+ Monitor uses only authority that already exists in `task`, `stopWhen`, the conversation, and repository instructions. It does not infer permission from an idle target or from the existence of a possible action.
42
47
 
43
- `reportWhen` is removed. The monitor always reports after every accepted check.
48
+ The first observation extracts the applicable contract:
44
49
 
45
- ## Check output
50
+ - the complete goal
51
+ - allowed files and systems
52
+ - forbidden changes
53
+ - cost ceiling
54
+ - provider and runtime contract
55
+ - required checks
56
+ - stop conditions
57
+ - allowed recovery actions
46
58
 
47
- The check agent submits:
59
+ An action can run only when its full effect is inside that contract. Monitor stops and reports the missing decision when an action would exceed the contract.
48
60
 
49
- ```json
50
- {
51
- "route": "continue",
52
- "observation": "The pull request is open and 8 of 10 checks passed.",
53
- "report": "PR 123 remains open. Eight of ten checks passed; two are running.",
54
- "progress": {
55
- "tracks": [
56
- {
57
- "key": "checks",
58
- "data": {
59
- "schema": "pi-workflows.progress.v1",
60
- "label": "Checks",
61
- "status": "running",
62
- "completed": 8,
63
- "total": 10,
64
- "unit": "checks"
65
- }
66
- }
67
- ]
68
- },
69
- "reason": "The stop condition is not met."
70
- }
71
- ```
61
+ A monitoring request does not create spending approval. Before paid work starts or resumes, the action must verify an applicable approval and prove that the next action stays inside its cumulative cost limit. It must not launch when the cost limit is missing, cannot be verified, or would be exceeded.
72
62
 
73
- Fields:
63
+ ## Read-only observation
74
64
 
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. |
65
+ Every cycle begins with the `observe` agent step. The first observation and all observations after actions are read-only. The model uses normal tools to inspect authoritative target state and durable outputs.
83
66
 
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.
67
+ The observation answers these questions:
85
68
 
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).
69
+ - Is the goal complete?
70
+ - Is useful work active?
71
+ - Is the goal incomplete and idle?
72
+ - Did work fail?
73
+ - Is there a material blocker?
74
+ - Which safe actions are already authorized?
87
75
 
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.
76
+ The result uses one of three routes:
89
77
 
90
- ## Graph
78
+ - `wait`: Work is moving, or an external event must finish.
79
+ - `act`: The goal is incomplete and a safe authorized action is available.
80
+ - `stop`: The goal is complete or cannot continue safely.
91
81
 
92
- The built-in graph uses existing nodes:
82
+ The observation records the goal state and target work state separately. It also lists the safe actions that the user has already authorized, even when no action is needed now. Monitor state is never evidence that target work is running.
93
83
 
94
- ```text
95
- prepare
96
- → check
97
- → estimate
98
- → publish_progress
99
- → report
100
- → decide
101
- ├─ stop → finish
102
- ├─ continue → schedule → sleep → check
103
- └─ repair → repairGuard
104
- ├─ blocked → repairBlocked → repairReport → finish
105
- └─ planChange
106
- ├─ blocked → repairBlocked
107
- └─ ready → implementation: autoimplement
108
- ├─ blocked → repairBlocked
109
- └─ completed → check
110
- ```
84
+ ## Action request
111
85
 
112
- - `prepare` is a `compute` node that validates and applies input defaults.
113
- - `check` is an `agent` node that inspects the target and submits the check output.
114
- - `estimate` is a `compute` node that updates per-track rate and ETA state with the pure progress helpers.
115
- - `publish_progress` is a function `action` that publishes each validated observed track.
116
- - `report` is a `notify` node that queues exactly one report.
117
- - `decide` is a `compute` node that applies the route and check safety limit.
118
- - `repairGuard` stops a repeated issue when a completed repair did not change its fingerprint or observed target state.
119
- - `planChange` and `implementation` are included workflows. Plan change owns Autoplan, Autodoc, approval policy, and exact-text replanning. Autoimplement receives the selected plan without another decision and enters its own plan-change mount only when later evidence requires a changed plan.
120
- - `repairBlocked` and `repairReport` preserve a truthful blocked result and user notification.
121
- - `schedule` is a function `action` that publishes the next-check time.
122
- - `sleep` is the existing runtime-owned shell wait.
123
- - `finish` is a `compute` node that returns the final observation and reason.
86
+ An `act` result contains one action request with:
124
87
 
125
- The workflow has no quiet route, report acknowledgement agent, or `presentationPrompt`.
88
+ - `kind`: `advance`, `recover`, or `repair`
89
+ - what is incomplete
90
+ - evidence that proves it
91
+ - the exact next action
92
+ - why existing authority covers the action
93
+ - files, systems, or resources that may change
94
+ - how to verify the action
95
+ - a stable failure ID
96
+ - a stable target-state ID
126
97
 
127
- ## Check prompt
98
+ The failure ID identifies the same failure across checks. The target-state ID identifies the relevant target state. Both values come from observed facts and remain stable while those facts remain unchanged.
128
99
 
129
- The check prompt includes:
100
+ The action request cannot grant authority. It can only describe authority found during observation.
130
101
 
131
- - check number and safety limit
132
- - task
133
- - stop condition
134
- - previous accepted observation
135
- - previous progress and estimate summary when present
136
- - read-only boundary unless the task authorizes a mutation
137
- - required output shape
102
+ ## Direct actions
138
103
 
139
- It tells the model that every accepted check must include a concise report. It tells the model to submit observed progress facts and target-provided ETA values only. The model does not calculate the official rate, confidence, or measured ETA.
104
+ `advance` starts or continues normal requested work. `recover` restarts or resumes work after an operational stop.
140
105
 
141
- A check may use available tools to read current state. It must use the target's authoritative source instead of treating a prior report or workflow update as current truth.
106
+ Both routes use one mutation-capable `act` agent step with normal Pi tools. The step performs only the stated action. Its prompt includes the exact action, authority basis, allowed mutation set, and verification rule from the read-only observation.
142
107
 
143
- ## Progress ownership boundary
108
+ Direct actions can include:
144
109
 
145
- The regular Pi model running the check is the observation adapter. It uses the target-specific tools authorized by the task, converts observed facts into `pi-workflows.progress.v1` tracks, and publishes them through the existing `workflow` tool. pi-workflows validates, stores, estimates, and displays those tracks.
110
+ - starting work
111
+ - resuming saved work
112
+ - restarting stopped work
113
+ - running the next command
114
+ - updating a stale launch file
115
+ - retrying a safe external operation
116
+ - continuing from a verified checkpoint
146
117
 
147
- The monitored target stays independent of pi-workflows. A monitor must not require a target Job or application to import pi-workflows, emit a Pi schema, write a Pi progress file, expose a Pi endpoint, create a progress store, or add a progress reader command solely for monitoring. Provider-specific clients and credentials do not belong in pi-workflows.
118
+ A normal start, resume, or restart does not run Autoplan, Autodoc, or Autoimplement.
148
119
 
149
- When a target does not expose a factual count, total, or source estimate, the check reports that ETA is unavailable. Better application telemetry is separate work. It should expose normal operational facts for all operators, not a Pi-specific reporting protocol.
120
+ The action step returns whether the action succeeded, failed, or was blocked, with factual evidence. Monitor then runs `observe` again immediately. A failed direct action can lead to a new authorized recovery action, but it cannot cause an unbounded retry loop.
150
121
 
151
- ## Progress publication
122
+ ## Repair actions
152
123
 
153
- `estimate` keeps the last eight usable intervals for each track in its normal node output. The output is durable and becomes the prior estimator state on the next loop visit.
124
+ `repair` changes code or configuration to fix a defect. It uses the existing shared plan-change workflow and Autoimplement workflow. Monitor does not copy their design, documentation, implementation, test, review, or delivery steps.
154
125
 
155
- `publish_progress` calls `context.publishUpdate()` once for each track with:
126
+ The repair input preserves the action request, target evidence, authority, constraints, repository, and delivery limits. Existing plan approval rules still apply when the recorded contract requires them.
156
127
 
157
- ```ts
158
- {
159
- type: "progress",
160
- key: track.key,
161
- data: track.data,
162
- }
128
+ Paid workers affected by a shared code or data defect must stop at safe boundaries before repair starts. Monitor preserves their durable outputs and failure evidence.
129
+
130
+ After a completed repair, Monitor runs `observe` immediately. If the same failure ID and target-state ID return, Monitor stops. It does not run the same repair cycle again.
131
+
132
+ ## Workflow graph
133
+
134
+ ```text
135
+ observe
136
+ ├─ stop → finish
137
+ ├─ wait → report → schedule → sleep → observe
138
+ └─ act
139
+ ├─ advance → direct action → observe immediately
140
+ ├─ recover → direct action → observe immediately
141
+ └─ repair → plan change → Autoimplement → observe immediately
163
142
  ```
164
143
 
165
- The published data remains the observed progress snapshot. Derived estimates stay in the estimator output and presentation view. The widget and viewer combine the observed update history with the pure estimator so they do not misrepresent estimates as target facts.
144
+ The timer exists only on the `wait` route. No schedule or sleep step can occur between an action and its verification observation.
145
+
146
+ `maxChecks` counts accepted observations. Reaching the limit reports the real goal and work state before the workflow stops.
147
+
148
+ ## Progress
166
149
 
167
- When a check contains no progress object, `estimate` and `publish_progress` return an empty result. The report still runs.
150
+ Progress is optional. The regular Pi model reads the target through normal tools and converts observed facts into `pi-workflows.progress.v1` tracks. The existing workflow update channel stores and displays those tracks.
151
+
152
+ The target stays independent of Pi Workflows. Monitor must not require a target process, Job, application, provider, or repository to:
153
+
154
+ - import Pi Workflows
155
+ - expose a Pi-specific API or endpoint
156
+ - write a Pi-specific progress file
157
+ - create a Pi-specific store or schema
158
+ - add a Pi-specific command or dependency
159
+
160
+ When the target does not expose a factual completed value, total, rate, or source estimate, Monitor reports that the value or ETA is unavailable. It does not invent one.
161
+
162
+ Progress data cannot contain a command or grant mutation authority.
168
163
 
169
164
  ## Schedule publication
170
165
 
171
- Before sleeping, `schedule` publishes:
166
+ On the `wait` route, `schedule` publishes:
172
167
 
173
168
  ```json
174
169
  {
@@ -183,130 +178,83 @@ Before sleeping, `schedule` publishes:
183
178
  }
184
179
  ```
185
180
 
186
- All fields are required. Times use RFC 3339 UTC form. `everyMinutes` must match the prepared monitor configuration.
181
+ All fields are required. Times use RFC 3339 UTC form. `everyMinutes` must match the prepared Monitor configuration.
187
182
 
188
- The schedule update lets the widget and viewer show time since the last check and time until the next check without calling a model or writing state on each clock tick.
183
+ No schedule update is published on `act` or `stop` routes.
189
184
 
190
- ## Report formatting
185
+ ## Reports
191
186
 
192
- The notification begins with the submitted `report`. When progress is present, a model-free formatter appends a bounded structured summary.
187
+ Every accepted observation sends one notification. Reports show Monitor state, goal state, and target work state as separate facts.
193
188
 
194
- Example:
189
+ A moving target report uses this form:
195
190
 
196
191
  ```text
197
- Import remains healthy.
198
- Progress: 420/1,000 rows (42%, +60)
199
- Rate: 29–33 rows/min
200
- ETA: 18–20 min (medium confidence, 4 samples)
201
- Next check: 30 min
192
+ Monitor: active
193
+ Goal: incomplete
194
+ Work: running
195
+ Progress: 21/27 modules
196
+ Last action: resumed six missing modules
197
+ Next check: 15 minutes
202
198
  ```
203
199
 
204
- Rules:
205
-
206
- - Show absolute values before deltas.
207
- - Label source ETA as `source ETA`.
208
- - Show `ETA unavailable` with a short reason when no valid estimate exists.
209
- - Do not display a negative countdown after an ETA passes.
210
- - Use `ETA passed; awaiting next check` until a new sample arrives.
211
- - Keep failed, blocked, or stale state ahead of rate details.
212
- - Show every track when the formatted report remains within 4,000 characters.
213
- - When it does not fit, show `overall`, failed or blocked tracks, then as many active tracks as fit, followed by the omitted count.
214
-
215
- Unrelated tracks are never combined. The monitor uses an explicit `overall` track when the target supplies meaningful aggregate progress.
216
-
217
- ## Notification delivery
218
-
219
- Each accepted check reaches `report`, including a check that selects `stop`. The `notify` node writes one durable message through the existing session-addressed outbox.
220
-
221
- The extension delivers the custom Pi message with `triggerTurn: false`. The notification stays in session history and later model context. Its arrival does not start an assistant response.
222
-
223
- The monitor does not use `sendUserMessage`. It does not ask an agent to repeat or acknowledge the notification. After the workflow tool accepts the check, the extension removes any extra assistant tail text from that agent run, so only the notification reports the check.
224
-
225
- A check that times out or fails before producing accepted output is not an accepted check. The run enters its normal terminal error state and the extension shows the workflow lifecycle notification. It does not invent a successful check report.
226
-
227
- ## Routing and stopping
228
-
229
- `route: "stop"` queues the report and then completes the workflow.
230
-
231
- `route: "continue"` queues the report and then checks the safety limit. If the limit remains available, the workflow schedules and waits for the next check. If the accepted check reaches `maxChecks`, the workflow finishes after that check's report and records `Reached the <n>-check safety limit.`
232
-
233
- A user cancellation stops the active check or wait immediately. It does not queue another report. The existing workflow lifecycle notification reports cancellation.
234
-
235
- Failures, blocked states, and unavailable status follow the user's `stopWhen` rule. The check may continue after reporting an unavailable source when observation remains safe and the stop condition is not met. It must stop when the requested terminal state is verified.
236
-
237
- ## Widget
238
-
239
- Progress display is optional. A monitor without progress uses the normal workflow graph widget.
240
-
241
- With progress, the widget uses the existing 10-line budget. It keeps the active graph row and uses remaining lines for a compact progress panel. It shows `overall` first, then failed or blocked tracks, then active tracks. Existing widget scrolling exposes omitted tracks.
242
-
243
- The widget may show:
200
+ An idle target that has an authorized action uses this form before the action runs:
244
201
 
245
202
  ```text
246
- Overall 420/1,000 rows ETA 18–20m
247
- Worker A running 7m elapsed
248
- Worker B waiting
249
- Last check 7m ago next check 23m
203
+ Monitor: active
204
+ Goal: incomplete
205
+ Work: idle
206
+ Next action: refreshing launch files and resuming work now
250
207
  ```
251
208
 
252
- Between checks, the existing one-second widget ticker may update:
253
-
254
- - workflow and phase elapsed time
255
- - time since the last progress sample
256
- - ETA countdown derived from the last estimate
257
- - time until the next check
258
-
259
- It does not advance observed `completed`, publish updates, write bundle state, or call a model.
260
-
261
- When an ETA expires, the widget shows that the estimate passed and waits for the next sample. `piw` shows the complete track list, update history, estimate basis, confidence, and source timestamps.
262
-
263
- ## Several monitored processes
264
-
265
- One monitor can track several processes. Each uses a stable progress key. A missing key in a later check does not mean completion; the check should publish an explicit terminal or `unknown` state before it stops reporting that process.
266
-
267
- The progress estimator treats each key independently. A phase, unit, total, or counter reset in one track does not reset another track.
209
+ A report must not say `Work: running` because Monitor itself is active. It may say running only when target evidence proves useful work is active.
268
210
 
269
- ## Interval and lifetime
211
+ Progress formatting follows these rules:
270
212
 
271
- The normal workflow engine remains finite. The built-in monitor therefore retains the 1,000-check safety ceiling and must not claim to be mathematically unbounded.
272
-
273
- At the default 30-minute interval, the ceiling allows about 20 days and 20 hours after the immediate first check. A caller that needs longer unattended reconciliation should use the controller runtime. A controller-backed indefinite monitor is a separate resource lifecycle. The workflow engine keeps its finite-step guard.
274
-
275
- The monitor skill must disclose a surfaced host limit and must never invent a smaller limit such as two checks. When no finish condition is clear, it sets the stop rule to explicit user stop and omits `maxChecks` so the workflow uses its documented safety ceiling.
276
-
277
- ## Safety boundaries
278
-
279
- 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.
280
-
281
- 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.
282
-
283
- A progress object is data. It cannot contain a command or grant execution authority. Fixed probes belong in workflow-authored `action` or `shell` nodes.
284
-
285
- A monitoring request does not create spending approval or a default spending ceiling. Existing approvals can cover paid actions, and the monitor should continue without another prompt while each action stays within them. Paid compute, inference runtime, and other domain policies continue to apply to every check.
286
-
287
- ## Validation and acceptance
288
-
289
- The implementation must test:
290
-
291
- - input defaults and bounds
292
- - removal of `reportWhen`
293
- - rejection of old quiet routes
294
- - required reports on every route
295
- - repair rejection without explicit authorization
296
- - outer design, autodoc, optional approval, nested redesign, and post-repair checking
297
- - continue, stop, and exact-text replan approval routes
298
- - repeated no-progress repair detection
299
- - exactly one notification per accepted check
300
- - no assistant turn from a notification
301
- - progress omission and multiple tracks
302
- - invalid and duplicate track keys
303
- - progress resets and stale samples
304
- - measured, source, unavailable, paused, and expired ETA display
305
- - schedule timestamps and countdown rendering
306
- - final report before stop
307
- - safety-limit report before completion
308
- - immediate cancellation during a check or wait
309
- - resume after host interruption
310
- - widget behavior with zero, one, and many tracks
311
-
312
- The real-Pi end-to-end test must start a short monitor, observe its custom notification without a new assistant turn, inspect the widget, and stop the run without mutating an external target.
213
+ - Show absolute values before deltas.
214
+ - Label a target-provided ETA as `source ETA`.
215
+ - Show `ETA unavailable` with a short reason when no valid estimate exists.
216
+ - Keep failed, blocked, or idle state ahead of rate details.
217
+ - Keep independent progress tracks separate.
218
+
219
+ Notifications use the existing session-addressed outbox with `triggerTurn: false`. They do not start an extra assistant response.
220
+
221
+ ## Stop conditions
222
+
223
+ Monitor stops when:
224
+
225
+ - the goal is complete
226
+ - a material blocker prevents safe continuation
227
+ - the next action is outside recorded authority
228
+ - a paid action lacks approval or would exceed its limit
229
+ - a provider, runtime, method, data source, or other protected contract would change
230
+ - a required credential lacks prior source-and-destination authority
231
+ - a checkpoint is invalid or cannot preserve useful work
232
+ - the same failure and target state return after one completed repair
233
+ - the observation safety limit is reached
234
+ - the user cancels the run
235
+
236
+ Monitor reports the current goal and target work state before a normal `stop` route completes.
237
+
238
+ ## Acceptance tests
239
+
240
+ The implementation must test at least these cases:
241
+
242
+ 1. The goal is already complete.
243
+ 2. Work is active, so Monitor waits.
244
+ 3. Work is idle, so Monitor starts it.
245
+ 4. Saved work exists, so Monitor resumes it.
246
+ 5. An action succeeds, so Monitor observes again immediately.
247
+ 6. An action fails once, then recovery succeeds.
248
+ 7. The same repaired failure returns, so Monitor stops.
249
+ 8. An action is outside authority, so Monitor stops.
250
+ 9. A paid action exceeds the limit, so Monitor does not launch it.
251
+ 10. Monitor is active while the target is idle.
252
+ 11. The target completes between timed observations.
253
+ 12. Unknown input fields fail before run creation.
254
+ 13. A normal restart does not trigger planning or documentation.
255
+ 14. A real code defect uses the existing repair path.
256
+ 15. No target-specific monitoring API is required.
257
+
258
+ Existing progress, notification, cancellation, interruption, resume, widget, schedule, and safety-limit tests must continue to pass where they apply to the new graph.
259
+
260
+ The real-Pi end-to-end test must start a short Monitor run, observe its notification without an extra assistant turn, inspect the widget, and stop the run without mutating an external target.