@osolmaz/pi-workflows 0.12.0 → 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.
- package/README.md +56 -31
- package/dist/builtins/autodoc.workflow.d.ts +4 -4
- package/dist/builtins/autoimplement.workflow.d.ts +797 -142
- package/dist/builtins/autoimplement.workflow.js +17 -105
- package/dist/builtins/autoimplement.workflow.js.map +1 -1
- package/dist/builtins/autoplan.workflow.d.ts +126 -13
- package/dist/builtins/autoplan.workflow.js +200 -29
- package/dist/builtins/autoplan.workflow.js.map +1 -1
- package/dist/builtins/catalog.js +7 -5
- package/dist/builtins/catalog.js.map +1 -1
- package/dist/builtins/index.d.ts +4 -2
- package/dist/builtins/index.js +3 -1
- package/dist/builtins/index.js.map +1 -1
- package/dist/builtins/monitor.workflow.d.ts +56 -23
- package/dist/builtins/monitor.workflow.js +508 -329
- package/dist/builtins/monitor.workflow.js.map +1 -1
- package/dist/builtins/pi-agent-group.d.ts +72 -0
- package/dist/builtins/pi-agent-group.js +1087 -0
- package/dist/builtins/pi-agent-group.js.map +1 -0
- package/dist/builtins/plain-summary.workflow.d.ts +32 -0
- package/dist/builtins/plain-summary.workflow.js +134 -0
- package/dist/builtins/plain-summary.workflow.js.map +1 -0
- package/dist/builtins/plan-approval.workflow.d.ts +39 -5
- package/dist/builtins/plan-approval.workflow.js +92 -14
- package/dist/builtins/plan-approval.workflow.js.map +1 -1
- package/dist/builtins/plan-change.workflow.d.ts +449 -0
- package/dist/builtins/plan-change.workflow.js +256 -0
- package/dist/builtins/plan-change.workflow.js.map +1 -0
- package/dist/builtins/plan-presentation.js +2 -2
- package/dist/builtins/plan-presentation.js.map +1 -1
- package/dist/builtins/sanity-check.workflow.d.ts +50 -6
- package/dist/builtins/sanity-check.workflow.js +150 -28
- package/dist/builtins/sanity-check.workflow.js.map +1 -1
- package/dist/controllers/effects.d.ts +3 -2
- package/dist/controllers/effects.js +8 -1
- package/dist/controllers/effects.js.map +1 -1
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/index.js +1 -1
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/manager.d.ts +1 -0
- package/dist/controllers/manager.js +41 -17
- package/dist/controllers/manager.js.map +1 -1
- package/dist/controllers/sqlite.d.ts +107 -85
- package/dist/controllers/sqlite.js +1611 -1486
- package/dist/controllers/sqlite.js.map +1 -1
- package/dist/controllers/store.d.ts +9 -8
- package/dist/controllers/store.js +1 -31
- package/dist/controllers/store.js.map +1 -1
- package/dist/controllers/types.d.ts +3 -0
- package/dist/controllers/workflow-engine-scheduler.d.ts +1 -1
- package/dist/controllers/workflow-engine-scheduler.js +3 -5
- package/dist/controllers/workflow-engine-scheduler.js.map +1 -1
- package/dist/controllers/workflows.d.ts +2 -2
- package/dist/controllers/workflows.js +11 -10
- package/dist/controllers/workflows.js.map +1 -1
- package/dist/extension/controller-host.js +2 -2
- package/dist/extension/controller-host.js.map +1 -1
- package/dist/extension/decision-channels.d.ts +4 -2
- package/dist/extension/decision-channels.js +333 -146
- package/dist/extension/decision-channels.js.map +1 -1
- package/dist/extension/executor.d.ts +9 -2
- package/dist/extension/executor.js +89 -2
- package/dist/extension/executor.js.map +1 -1
- package/dist/extension/herdr-viewer.d.ts +0 -1
- package/dist/extension/herdr-viewer.js +0 -4
- package/dist/extension/herdr-viewer.js.map +1 -1
- package/dist/extension/index.js +209 -127
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/recorder.d.ts +3 -10
- package/dist/extension/recorder.js +13 -22
- package/dist/extension/recorder.js.map +1 -1
- package/dist/extension/session-events.d.ts +2 -2
- package/dist/extension/step-message.d.ts +7 -2
- package/dist/extension/step-message.js +94 -2
- package/dist/extension/step-message.js.map +1 -1
- package/dist/extension/widget.js +29 -3
- package/dist/extension/widget.js.map +1 -1
- package/dist/host/rpc-executor.d.ts +3 -0
- package/dist/host/rpc-executor.js +2 -0
- package/dist/host/rpc-executor.js.map +1 -1
- package/dist/host/runner.d.ts +3 -6
- package/dist/host/runner.js +83 -32
- package/dist/host/runner.js.map +1 -1
- package/dist/render/graph-render.js +15 -10
- package/dist/render/graph-render.js.map +1 -1
- package/dist/state/database.d.ts +35 -0
- package/dist/state/database.js +287 -0
- package/dist/state/database.js.map +1 -0
- package/dist/state/index.d.ts +4 -0
- package/dist/state/index.js +5 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/json.d.ts +6 -0
- package/dist/state/json.js +38 -0
- package/dist/state/json.js.map +1 -0
- package/dist/state/mutation.d.ts +57 -0
- package/dist/state/mutation.js +255 -0
- package/dist/state/mutation.js.map +1 -0
- package/dist/state/schema.d.ts +6 -0
- package/dist/state/schema.js +473 -0
- package/dist/state/schema.js.map +1 -0
- package/dist/viewer/cli.d.ts +2 -2
- package/dist/viewer/cli.js +142 -122
- package/dist/viewer/cli.js.map +1 -1
- package/dist/viewer/render.d.ts +4 -4
- package/dist/viewer/render.js +9 -23
- package/dist/viewer/render.js.map +1 -1
- package/dist/viewer/session-reducer.d.ts +1 -1
- package/dist/viewer/session-reducer.js +1 -1
- package/dist/viewer/tui.d.ts +3 -3
- package/dist/viewer/tui.js +15 -13
- package/dist/viewer/tui.js.map +1 -1
- package/dist/viewer/watch.d.ts +2 -5
- package/dist/viewer/watch.js +13 -13
- package/dist/viewer/watch.js.map +1 -1
- package/dist/workflows/catalog.js +7 -2
- package/dist/workflows/catalog.js.map +1 -1
- package/dist/workflows/composition.js +20 -2
- package/dist/workflows/composition.js.map +1 -1
- package/dist/workflows/decision-presentation.d.ts +1 -1
- package/dist/workflows/decision-presentation.js +51 -38
- package/dist/workflows/decision-presentation.js.map +1 -1
- package/dist/workflows/definition.d.ts +6 -2
- package/dist/workflows/definition.js +17 -0
- package/dist/workflows/definition.js.map +1 -1
- package/dist/workflows/engine.d.ts +7 -7
- package/dist/workflows/engine.js +196 -115
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/errors.d.ts +16 -3
- package/dist/workflows/errors.js +18 -3
- package/dist/workflows/errors.js.map +1 -1
- package/dist/workflows/human-decision.d.ts +45 -8
- package/dist/workflows/human-decision.js +641 -274
- package/dist/workflows/human-decision.js.map +1 -1
- package/dist/workflows/index.d.ts +5 -6
- package/dist/workflows/index.js +4 -5
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/progress.d.ts +1 -0
- package/dist/workflows/progress.js +15 -3
- package/dist/workflows/progress.js.map +1 -1
- package/dist/workflows/schema.js +27 -1
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.d.ts +83 -103
- package/dist/workflows/store.js +907 -951
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/types.d.ts +88 -126
- package/docs/CONTROLLERS.md +10 -8
- package/docs/DEFERRED_TURNS.md +2 -2
- package/docs/DESIGN_PHILOSOPHY.md +4 -2
- package/docs/HUMAN_DECISIONS.md +36 -47
- package/docs/HUMAN_DECISION_PRESENTATIONS.md +14 -24
- package/docs/MONITOR.md +179 -237
- package/docs/SQLITE_STATE.md +219 -0
- package/docs/WORKFLOW_COMPOSITION.md +27 -26
- package/docs/WORKFLOW_STEP_MESSAGES.md +20 -18
- package/docs/WORKFLOW_UPDATES.md +10 -9
- package/docs/development.md +9 -9
- package/docs/live-replay-protocol.md +28 -37
- package/docs/plans/2026-08-16-workflow-updates-plan.md +1 -1
- package/docs/plans/2026-08-19-human-decision-gates-plan.md +1 -1
- package/docs/plans/2026-08-21-autoimplement-timeout-fallback-plan.md +1 -1
- package/docs/plans/2026-08-21-plan-change-approval-policy-plan.md +322 -0
- package/docs/plans/2026-08-21-sanity-check-plan.md +217 -95
- package/docs/plans/2026-08-22-goal-finishing-monitor-plan.md +200 -0
- package/docs/plans/2026-08-23-assistant-agent-completion-plan.md +701 -0
- package/docs/plans/2026-08-23-sqlite-state-plan.md +970 -0
- package/docs/plans/replayable-run-bundles-implementation-plan.md +2 -2
- package/docs/plans/session-event-replay-implementation-plan.md +1 -1
- package/docs/plans/tui-viewer-implementation-plan.md +1 -1
- package/docs/session-event-journal.md +63 -434
- package/docs/tui-viewer.md +13 -15
- package/docs/workflows.md +127 -53
- package/examples/workflows/approved-plan.workflow.ts +19 -46
- package/examples/workflows/plain-summary.workflow.ts +1 -0
- package/herdr-plugin.toml +1 -1
- package/package.json +7 -7
- package/plugins/herdr/viewer.mjs +1 -11
- package/schemas/human-decision-accepted-v1.schema.json +15 -3
- package/schemas/human-decision-continuation-v1.schema.json +10 -1
- package/schemas/human-decision-delivery-v1.schema.json +8 -0
- package/schemas/human-decision-receipt-v1.schema.json +8 -0
- package/schemas/human-decision-request-v1.schema.json +24 -4
- package/skills/autoimplement/SKILL.md +27 -0
- package/skills/autoplan/SKILL.md +5 -4
- package/skills/monitor/SKILL.md +91 -135
- package/skills/pi-workflows/SKILL.md +9 -8
- package/skills/sanity-check/SKILL.md +44 -0
- package/src/builtins/autoimplement.workflow.ts +19 -118
- package/src/builtins/autoplan.workflow.ts +290 -40
- package/src/builtins/catalog.ts +7 -5
- package/src/builtins/index.ts +18 -1
- package/src/builtins/monitor.workflow.ts +673 -382
- package/src/builtins/pi-agent-group.ts +1407 -0
- package/src/builtins/plain-summary.workflow.ts +185 -0
- package/src/builtins/plan-approval.workflow.ts +157 -24
- package/src/builtins/plan-change.workflow.ts +321 -0
- package/src/builtins/plan-presentation.ts +2 -2
- package/src/builtins/sanity-check.workflow.ts +248 -48
- package/src/controllers/effects.ts +7 -0
- package/src/controllers/index.ts +0 -6
- package/src/controllers/manager.ts +72 -32
- package/src/controllers/sqlite.ts +2420 -1948
- package/src/controllers/store.ts +17 -38
- package/src/controllers/types.ts +3 -0
- package/src/controllers/workflow-engine-scheduler.ts +4 -8
- package/src/controllers/workflows.ts +45 -21
- package/src/extension/controller-host.ts +1 -2
- package/src/extension/decision-channels.ts +456 -203
- package/src/extension/executor.ts +105 -2
- package/src/extension/herdr-viewer.ts +0 -5
- package/src/extension/index.ts +251 -151
- package/src/extension/recorder.ts +13 -22
- package/src/extension/session-events.ts +2 -2
- package/src/extension/step-message.ts +106 -4
- package/src/extension/widget.ts +32 -5
- package/src/host/rpc-executor.ts +4 -0
- package/src/host/runner.ts +93 -41
- package/src/render/graph-render.ts +12 -6
- package/src/state/database.ts +375 -0
- package/src/state/index.ts +29 -0
- package/src/state/json.ts +42 -0
- package/src/state/mutation.ts +435 -0
- package/src/state/schema.ts +475 -0
- package/src/viewer/cli.ts +151 -144
- package/src/viewer/render.ts +19 -30
- package/src/viewer/session-reducer.ts +1 -1
- package/src/viewer/tui.ts +18 -17
- package/src/viewer/watch.ts +13 -17
- package/src/workflows/catalog.ts +7 -2
- package/src/workflows/composition.ts +21 -3
- package/src/workflows/decision-presentation.ts +56 -43
- package/src/workflows/definition.ts +36 -3
- package/src/workflows/engine.ts +228 -130
- package/src/workflows/errors.ts +27 -3
- package/src/workflows/human-decision.ts +921 -349
- package/src/workflows/index.ts +20 -30
- package/src/workflows/progress.ts +18 -3
- package/src/workflows/schema.ts +36 -1
- package/src/workflows/store.ts +1300 -1163
- package/src/workflows/types.ts +100 -137
- package/dist/builtins/sanity-check-session.d.ts +0 -17
- package/dist/builtins/sanity-check-session.js +0 -168
- package/dist/builtins/sanity-check-session.js.map +0 -1
- package/dist/workflows/artifacts.d.ts +0 -40
- package/dist/workflows/artifacts.js +0 -155
- package/dist/workflows/artifacts.js.map +0 -1
- package/dist/workflows/migrate-sources.d.ts +0 -42
- package/dist/workflows/migrate-sources.js +0 -133
- package/dist/workflows/migrate-sources.js.map +0 -1
- package/docs/run-bundles.md +0 -481
- package/schemas/human-decision-accepted-v2.schema.json +0 -50
- package/schemas/human-decision-delivery-v2.schema.json +0 -36
- package/schemas/human-decision-receipt-v2.schema.json +0 -39
- package/schemas/human-decision-request-v2.schema.json +0 -69
- package/schemas/human-decision-resolution-v2.schema.json +0 -27
- package/src/builtins/sanity-check-session.ts +0 -205
- package/src/workflows/artifacts.ts +0 -188
- package/src/workflows/migrate-sources.ts +0 -178
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
# Live replay protocol
|
|
2
2
|
|
|
3
|
-
The Rust viewer (`tui/`) can watch runs in two ways: by reading
|
|
3
|
+
The Rust viewer (`tui/`) can watch runs in two ways: by reading SQLite runs
|
|
4
4
|
directly from the filesystem (the default, in-process) or by connecting to a
|
|
5
5
|
`piw serve` WebSocket server. Both paths produce the same semantic state; the
|
|
6
6
|
protocol below is the network form of that state. Protocol id:
|
|
7
7
|
`pi-workflows.replay.v1`.
|
|
8
8
|
|
|
9
|
-
The server is a reader like any other: it only consumes
|
|
10
|
-
[
|
|
9
|
+
The server is a reader like any other: it only consumes SQLite runs (see
|
|
10
|
+
[SQLITE_STATE.md](SQLITE_STATE.md)) and never writes them. The protocol has no
|
|
11
11
|
authentication, so the server only accepts loopback bind addresses and refuses
|
|
12
|
-
to start on anything else;
|
|
12
|
+
to start on anything else; workflow state contains private data, and remote viewing
|
|
13
13
|
goes through an SSH tunnel. Handshakes that
|
|
14
14
|
carry an `Origin` header are rejected: browsers always send one, and a web
|
|
15
|
-
page must not be able to read
|
|
15
|
+
page must not be able to read workflow state by opening a WebSocket to localhost.
|
|
16
16
|
|
|
17
17
|
## Transport and framing
|
|
18
18
|
|
|
@@ -49,18 +49,15 @@ run:
|
|
|
49
49
|
}
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
- `manifest`, `workflow`, `state`, `events`, and every `session` field are
|
|
53
|
-
|
|
54
|
-
top-level `events` are
|
|
55
|
-
|
|
56
|
-
`session.capture` is capture integrity. `session
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
bundle has not changed for 60 seconds.
|
|
62
|
-
- Artifact references inside the view stay references; contents are fetched
|
|
63
|
-
on demand.
|
|
52
|
+
- `manifest`, `workflow`, `state`, `events`, and every `session` field are
|
|
53
|
+
semantic projections from SQLite. `workflow` is the definition snapshot,
|
|
54
|
+
top-level `events` are workflow events, `session.entries` are settled Pi
|
|
55
|
+
entries, `session.events` are normalized temporal events, and
|
|
56
|
+
`session.capture` is capture integrity. `session` is `null` until a binding
|
|
57
|
+
exists.
|
|
58
|
+
- `live` is true while the run status is non-terminal. `possiblyInterrupted`
|
|
59
|
+
is a reader-side diagnostic based on current ownership and update time.
|
|
60
|
+
- Values are resolved from content-addressed SQLite blobs.
|
|
64
61
|
|
|
65
62
|
Because the full trace and session history are part of the view, replay
|
|
66
63
|
scrubbing is a pure client-side operation; rewinding never requires the
|
|
@@ -106,7 +103,7 @@ Client to server:
|
|
|
106
103
|
| `watch_runs` | — | subscribe to the run listing |
|
|
107
104
|
| `watch_run` | `runId` | subscribe to one run's view |
|
|
108
105
|
| `unwatch_run` | `runId` | end a run subscription |
|
|
109
|
-
| `fetch_artifact` | `runId`, `path` |
|
|
106
|
+
| `fetch_artifact` | `runId`, `path` | unsupported; returns `error` |
|
|
110
107
|
|
|
111
108
|
Server to client:
|
|
112
109
|
|
|
@@ -116,13 +113,11 @@ Server to client:
|
|
|
116
113
|
| `runs` | `runs` | full run listing (summaries), re-sent on change |
|
|
117
114
|
| `run_snapshot` | `runId`, `revision`, `view` | full view after subscribe |
|
|
118
115
|
| `run_patch` | `runId`, `revision`, `patch` | incremental view update |
|
|
119
|
-
| `artifact` | `runId`, `path`, `content` |
|
|
116
|
+
| `artifact` | `runId`, `path`, `content` | reserved; not sent by SQLite-backed servers |
|
|
120
117
|
| `error` | `message`, `runId?` | request failed |
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
symlinks whose canonical targets leave it are refused. Responses are capped at
|
|
125
|
-
4 MiB of actual file size; anything else produces an `error`.
|
|
119
|
+
SQLite-backed views contain resolved values. A `fetch_artifact` request returns
|
|
120
|
+
an `error` because there is no artifact directory.
|
|
126
121
|
|
|
127
122
|
Run listing summaries are the manifest plus `live` and
|
|
128
123
|
`possiblyInterrupted`:
|
|
@@ -136,20 +131,16 @@ run views use patches.
|
|
|
136
131
|
|
|
137
132
|
## Reconnection
|
|
138
133
|
|
|
139
|
-
The native client treats the run listing
|
|
140
|
-
|
|
134
|
+
The native client treats the run listing and selected run as desired state rather
|
|
135
|
+
than one-shot commands. After a connection closes,
|
|
141
136
|
it keeps the cached run visible with a stale/reconnecting label, retries with
|
|
142
137
|
bounded backoff, sends `watch_runs` after the next valid `hello`, and restores
|
|
143
138
|
the current `watch_run`. A reconnect receives a fresh snapshot before later
|
|
144
|
-
patches.
|
|
145
|
-
|
|
146
|
-
##
|
|
147
|
-
|
|
148
|
-
The server
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
`manifest.json` are
|
|
153
|
-
re-read on change; a `state.json` whose `traceSeq` is older than the last
|
|
154
|
-
tailed trace event is stale and is replaced when the writer catches up. After
|
|
155
|
-
a terminal status, watching stops.
|
|
139
|
+
patches.
|
|
140
|
+
|
|
141
|
+
## SQLite semantics behind the protocol
|
|
142
|
+
|
|
143
|
+
The server polls `state.sqlite` through a query-only connection. Each refresh
|
|
144
|
+
reads a committed run projection, immutable events, session rows, and blob
|
|
145
|
+
values. A transaction is either fully visible or not visible, so a client never
|
|
146
|
+
observes half of a state transition.
|
|
@@ -68,7 +68,7 @@ Pi and Telegram implement one channel interface. Workflows address a named audie
|
|
|
68
68
|
### Documentation and display
|
|
69
69
|
|
|
70
70
|
- Add the authoring API to `docs/workflows.md`.
|
|
71
|
-
- Add human decision state to `docs/
|
|
71
|
+
- Add human decision state to `docs/SQLITE_STATE.md`.
|
|
72
72
|
- Add channel setup and recovery instructions.
|
|
73
73
|
- Add a custom gate example and a composed plan approval example.
|
|
74
74
|
- Show pending and accepted choices in TypeScript and Rust viewers.
|
|
@@ -153,7 +153,7 @@ A repeated node performs only missing work. It must not create a duplicate commi
|
|
|
153
153
|
7. Route supported `timed_out` outcomes to the fallback. Preserve success, failure, and cancellation behavior.
|
|
154
154
|
8. Update consequential-node prompts so repeated attempts inspect state and perform only missing work.
|
|
155
155
|
9. Increment the built-in Autoimplement revision from 5 to 6 in `src/builtins/catalog.ts`.
|
|
156
|
-
10. Update `docs/workflows.md` and `docs/
|
|
156
|
+
10. Update `docs/workflows.md` and `docs/SQLITE_STATE.md` when implementation ships so public documentation matches the code.
|
|
157
157
|
|
|
158
158
|
## Alpha cutover
|
|
159
159
|
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plan Change Approval Policy Plan
|
|
3
|
+
author: Onur Solmaz <2453968+osolmaz@users.noreply.github.com>
|
|
4
|
+
date: 2026-08-21
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Plan change approval policy plan
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Autoimplement and Monitor must use one shared workflow whenever they create or revise a plan. The shared workflow plans, records the plan in canonical documentation, asks for the configured human decision, and handles bounded replanning.
|
|
12
|
+
|
|
13
|
+
The default policy is autonomous. It asks the `operator` audience to continue, stop, or replan. If no valid answer is accepted within 10 minutes, it continues with the exact presented plan. A required policy waits for an explicit answer. A skip policy continues immediately without creating a human decision.
|
|
14
|
+
|
|
15
|
+
The timeout default belongs to the general `humanDecision()` contract. It must be durable, deterministic, bound to the exact request and plan digest, and separate from a human answer. Autoimplement and Monitor must not contain their own decision timers or copies of approval and replan logic.
|
|
16
|
+
|
|
17
|
+
## Goals
|
|
18
|
+
|
|
19
|
+
The change must provide these results:
|
|
20
|
+
|
|
21
|
+
- Every plan newly created or changed by Autoimplement or Monitor passes through one shared plan-change workflow.
|
|
22
|
+
- Existing supplied or discovered plans do not receive a new decision.
|
|
23
|
+
- The default policy asks for a decision and continues after 10 minutes when there is no answer.
|
|
24
|
+
- Operators can require an explicit answer or skip the decision.
|
|
25
|
+
- Pi and Telegram show and settle the same durable decision.
|
|
26
|
+
- A human answer, timeout default, and cancellation cannot create more than one continuation.
|
|
27
|
+
- Cancellation remains immediate and terminal.
|
|
28
|
+
- Repeated entry with the same plan digest does not create another decision.
|
|
29
|
+
- Monitor does not cause Autoimplement to ask again for the plan that Monitor already selected.
|
|
30
|
+
|
|
31
|
+
## Approval policy
|
|
32
|
+
|
|
33
|
+
Autoimplement and Monitor use the same policy shape:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
type PlanApprovalPolicy = {
|
|
37
|
+
mode: "auto" | "required" | "skip";
|
|
38
|
+
audience?: string;
|
|
39
|
+
timeoutMinutes?: number;
|
|
40
|
+
maxReplans?: number;
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The workflow input field remains `approval`. When it is absent, parsing supplies this policy:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"mode": "auto",
|
|
49
|
+
"audience": "operator",
|
|
50
|
+
"timeoutMinutes": 10,
|
|
51
|
+
"maxReplans": 3
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The modes have these meanings:
|
|
56
|
+
|
|
57
|
+
- `auto` creates a human decision. It continues with the presented plan when no valid answer is accepted before the deadline.
|
|
58
|
+
- `required` creates a human decision with no automatic response. It waits for `continue`, `stop`, or `replan`.
|
|
59
|
+
- `skip` creates no human decision and continues immediately.
|
|
60
|
+
|
|
61
|
+
`audience` defaults to `operator`. `timeoutMinutes` applies only to `auto` and defaults to 10. `maxReplans` defaults to 3 and bounds the exact-instructions replan loop. Parsers reject unknown fields, unsupported combinations, non-positive timeouts, and invalid replan limits.
|
|
62
|
+
|
|
63
|
+
The skills must map common requests as follows:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"approval": {
|
|
68
|
+
"mode": "required"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Use this for requests such as “block on plan changes.”
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"approval": {
|
|
78
|
+
"mode": "skip"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Use this for requests such as “do not block on plan changes.” Omitting `approval` uses the 10-minute autonomous default.
|
|
84
|
+
|
|
85
|
+
## Shared plan-change workflow
|
|
86
|
+
|
|
87
|
+
Add one internal finite workflow that owns this sequence:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
autoplan
|
|
91
|
+
-> autodoc
|
|
92
|
+
-> plan-approval
|
|
93
|
+
-> continue -> ready
|
|
94
|
+
-> stop -> blocked
|
|
95
|
+
-> replan -> autoplan
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The workflow receives the planning problem, scope, constraints, repository and document context, previous plan, new evidence, and approval policy. It returns either:
|
|
99
|
+
|
|
100
|
+
- `ready`, with the selected plan, plan digest, canonical documents, revision, and decision provenance; or
|
|
101
|
+
- `blocked`, with the reason and evidence.
|
|
102
|
+
|
|
103
|
+
The workflow owns the replan count and passes exact operator instructions back to Autoplan. Each changed plan gets a new positive revision. The plan digest binds the plan, documentation result, approval request, and final output.
|
|
104
|
+
|
|
105
|
+
The workflow bypasses the human-decision node in `skip` mode but still records `skipped` as the plan selection provenance. It does not create a synthetic human receipt.
|
|
106
|
+
|
|
107
|
+
Promote the existing approved-plan composition pattern into this internal built-in workflow. Keep `plan-approval` as the low-level reusable decision workflow. Do not add a standalone `plan-approval` skill.
|
|
108
|
+
|
|
109
|
+
## Human-decision timeout default
|
|
110
|
+
|
|
111
|
+
Extend the public `humanDecision()` definition with a general optional timeout response:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
humanDecision({
|
|
115
|
+
audience: "operator",
|
|
116
|
+
choices,
|
|
117
|
+
request,
|
|
118
|
+
onTimeout: {
|
|
119
|
+
afterMs: 10 * 60_000,
|
|
120
|
+
response: { choice: "continue" },
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The policy may also be derived from the node context so the shared plan-change workflow can use its parsed input. `afterMs` must be a positive finite duration. The response must satisfy the same typed choice and input contract as a human response. An absent `onTimeout` keeps the current indefinite wait.
|
|
126
|
+
|
|
127
|
+
When the engine creates the request, it computes and persists:
|
|
128
|
+
|
|
129
|
+
- the absolute expiry time;
|
|
130
|
+
- the validated default response;
|
|
131
|
+
- the request and presentation digests;
|
|
132
|
+
- the exact node and attempt identity; and
|
|
133
|
+
- the plan digest and revision already present in the decision subject.
|
|
134
|
+
|
|
135
|
+
The request digest includes the deadline policy and default response. A changed deadline, response, plan, or revision therefore creates a different request identity.
|
|
136
|
+
|
|
137
|
+
## Resolution and provenance
|
|
138
|
+
|
|
139
|
+
A timeout default is an automatic workflow-policy resolution. It is not a human answer and must not use a human actor or channel identity.
|
|
140
|
+
|
|
141
|
+
The existing resolution record gains a distinct timeout-default outcome and provenance in place. Human acceptance, timeout default, and cancellation all compete for the same immutable resolution record. The first valid resolution wins. The accepted workflow output states whether the result came from:
|
|
142
|
+
|
|
143
|
+
- `human`;
|
|
144
|
+
- `timeout`;
|
|
145
|
+
- `skipped`; or
|
|
146
|
+
- `cancelled`, where a terminal record is exposed.
|
|
147
|
+
|
|
148
|
+
A human answer is valid only before the deadline and while no terminal resolution exists. A late answer cannot replace a timeout default. A timeout resolver must re-read an existing resolution and adopt it rather than create another result.
|
|
149
|
+
|
|
150
|
+
The plan-approval continue result carries the plan digest, decision revision, response, and resolution provenance. A timeout result carries no human actor. A skipped result carries no human-decision receipt.
|
|
151
|
+
|
|
152
|
+
## Recovery and ownership
|
|
153
|
+
|
|
154
|
+
Use the existing one-second human-decision recovery loop. Do not add a service, daemon, controller, or second timer system.
|
|
155
|
+
|
|
156
|
+
For an unresolved request with an eligible timeout default, the current owner must:
|
|
157
|
+
|
|
158
|
+
1. confirm that the parent run is still waiting at the same request;
|
|
159
|
+
2. confirm that the request deadline has passed;
|
|
160
|
+
3. confirm that the run and decision are not cancelled;
|
|
161
|
+
4. atomically write or adopt the timeout-default resolution;
|
|
162
|
+
5. create or adopt the deterministic continuation record;
|
|
163
|
+
6. start the continuation only when the owning process can claim it; and
|
|
164
|
+
7. settle every open Pi and Telegram view.
|
|
165
|
+
|
|
166
|
+
If no owner is active at the deadline, the request becomes eligible at that time. The next active owner resolves it and starts or adopts the continuation. The saved absolute deadline means a restart does not restart the 10-minute period.
|
|
167
|
+
|
|
168
|
+
Auto mode must continue after the deadline even when no decision channel is configured. Required mode remains waiting and reports the missing channel configuration. Skip mode does not use a channel.
|
|
169
|
+
|
|
170
|
+
## Cancellation and races
|
|
171
|
+
|
|
172
|
+
Explicit workflow cancellation remains terminal. It must cancel the waiting decision, close channel views, and prevent a timeout continuation.
|
|
173
|
+
|
|
174
|
+
The cancellation path and timeout resolver must check the durable run cancellation state before and after claiming the decision resolution and before starting a continuation. If cancellation races with an automatic resolution, the cancelled run and its deterministic continuation must not execute more workflow nodes. A later recovery pass must not revive either run.
|
|
175
|
+
|
|
176
|
+
A human answer and timeout default use the immutable resolution as their race boundary. Tests must cover both winners at the deadline boundary and prove that only one continuation can exist.
|
|
177
|
+
|
|
178
|
+
## Autoimplement integration
|
|
179
|
+
|
|
180
|
+
Autoimplement must use the shared plan-change workflow only for a changed plan produced by its internal redesign route.
|
|
181
|
+
|
|
182
|
+
These plans bypass the gate:
|
|
183
|
+
|
|
184
|
+
- an explicit plan supplied in the Autoimplement input;
|
|
185
|
+
- a current plan found by plan discovery; and
|
|
186
|
+
- a plan passed by Monitor after Monitor completed the shared plan-change workflow.
|
|
187
|
+
|
|
188
|
+
When new evidence routes Autoimplement to redesign, the shared workflow receives the current plan as `previousPlan` and the new issue as evidence. A changed ready plan returns to implementation. A stopped or exhausted plan change returns blocked. The same digest must not create another decision after resume or route re-entry.
|
|
189
|
+
|
|
190
|
+
Remove Autoimplement’s duplicate approval route, approval input mapping, and replan guard. Keep only policy parsing and the mapping into the shared workflow.
|
|
191
|
+
|
|
192
|
+
## Monitor integration
|
|
193
|
+
|
|
194
|
+
Each Monitor repair that requires a new plan enters the shared plan-change workflow. This includes every exact-instructions replan requested by the operator.
|
|
195
|
+
|
|
196
|
+
A ready plan is passed to Autoimplement with its plan digest and canonical documentation state. Autoimplement treats it as selected and does not ask about it again. If Autoimplement later produces a changed plan because of implementation, review, or CI evidence, Autoimplement uses the shared workflow for that new digest.
|
|
197
|
+
|
|
198
|
+
Remove Monitor’s duplicate approval route, plan-approval input mapping, and replan guard. Keep the monitor repair authorization, no-progress protection, and post-repair observation unchanged.
|
|
199
|
+
|
|
200
|
+
## Skills and examples
|
|
201
|
+
|
|
202
|
+
Update the Autoimplement and Monitor skills with complete one-shot calls for:
|
|
203
|
+
|
|
204
|
+
- omitted approval, which uses the 10-minute autonomous default;
|
|
205
|
+
- `approval.mode: "required"`; and
|
|
206
|
+
- `approval.mode: "skip"`.
|
|
207
|
+
|
|
208
|
+
The examples must retain the required task, scope, constraints, repository, base branch, merge authority, and other workflow-specific input. They must not show a model calling the answer action for a protected human decision.
|
|
209
|
+
|
|
210
|
+
Update the workflow authoring skill and examples to explain `humanDecision().onTimeout`, timeout provenance, and the rule that only a policy-defined response can run automatically.
|
|
211
|
+
|
|
212
|
+
## Public contracts and persisted data
|
|
213
|
+
|
|
214
|
+
Change the current alpha contracts in place:
|
|
215
|
+
|
|
216
|
+
- add `onTimeout` to the public typed human-decision definition;
|
|
217
|
+
- add the persisted deadline and default response to the current human-decision request contract;
|
|
218
|
+
- add timeout-default provenance to the current accepted result, receipt, resolution, continuation, and channel settlement handling where it applies;
|
|
219
|
+
- add the shared `PlanApprovalPolicy` and plan-change input and output types;
|
|
220
|
+
- change Autoimplement and Monitor approval inputs to the shared policy; and
|
|
221
|
+
- keep existing camelCase JSON fields and current schema and contract identifiers.
|
|
222
|
+
|
|
223
|
+
Persisted request and resolution JSON remains under the current human-decision state root. Run bundles remain under the current run store. Add no migration reader, dual read, dual write, alias, feature flag, or new schema generation.
|
|
224
|
+
|
|
225
|
+
Increment the affected built-in revisions as one hard alpha cutover:
|
|
226
|
+
|
|
227
|
+
- Autoimplement revision 6 to 7;
|
|
228
|
+
- Monitor revision 7 to 8; and
|
|
229
|
+
- plan-approval revision 2 to 3.
|
|
230
|
+
|
|
231
|
+
Older active runs refuse resume through the existing source-change behavior. The new internal plan-change workflow does not need to be a user-facing catalog entry or skill.
|
|
232
|
+
|
|
233
|
+
## Documentation
|
|
234
|
+
|
|
235
|
+
When implementation ships, update:
|
|
236
|
+
|
|
237
|
+
- `docs/HUMAN_DECISIONS.md` for timeout responses, provenance, recovery, races, and channel behavior;
|
|
238
|
+
- `docs/WORKFLOW_COMPOSITION.md` for the shared plan-change workflow;
|
|
239
|
+
- `docs/workflows.md` for the public API and Autoimplement behavior;
|
|
240
|
+
- `docs/MONITOR.md` for repair-plan decisions;
|
|
241
|
+
- `docs/SQLITE_STATE.md` for request, resolution, continuation, and snapshot fields;
|
|
242
|
+
- Autoimplement and Monitor skill text and examples; and
|
|
243
|
+
- package examples and generated layout fixtures affected by the graph change.
|
|
244
|
+
|
|
245
|
+
Keep the previous human-decision and composition plans unchanged as historical records.
|
|
246
|
+
|
|
247
|
+
## Implementation steps
|
|
248
|
+
|
|
249
|
+
1. Add and validate the typed `humanDecision().onTimeout` contract. Bind the validated default response and absolute deadline into request identity and persisted request data.
|
|
250
|
+
2. Extend the human-decision store with one atomic timeout-default resolution operation. Preserve one immutable resolution and one deterministic continuation.
|
|
251
|
+
3. Update extension decision recovery to resolve eligible defaults, recover after restart, settle channels, and start only the owned continuation. Keep cancellation checks around resolution and continuation claims.
|
|
252
|
+
4. Update Pi and Telegram decision presentation and settlement so the deadline and automatic action are clear and a completed timeout closes pending views.
|
|
253
|
+
5. Extend plan-approval with the shared policy and explicit human, timeout, and skipped provenance.
|
|
254
|
+
6. Add the internal shared plan-change workflow with Autoplan, Autodoc, plan approval, and bounded exact-instructions replanning.
|
|
255
|
+
7. Replace the duplicate Autoimplement planning approval path with the shared workflow and gate only changed internal redesign results.
|
|
256
|
+
8. Replace the duplicate Monitor repair-plan approval path with the shared workflow and pass its selected plan to Autoimplement without another decision.
|
|
257
|
+
9. Update public exports, current schemas, built-in revisions, skills, examples, documentation, and generated fixtures.
|
|
258
|
+
10. Run all unit, integration, real-Pi, documentation, formatting, dependency-boundary, and package-resource checks.
|
|
259
|
+
|
|
260
|
+
## Tests
|
|
261
|
+
|
|
262
|
+
Use fake clocks, temporary directories, and fake channels. Tests must not call a real model, use a real Telegram credential, or mutate a real remote.
|
|
263
|
+
|
|
264
|
+
Cover:
|
|
265
|
+
|
|
266
|
+
- `onTimeout` type and runtime validation;
|
|
267
|
+
- absent timeout behavior;
|
|
268
|
+
- the default 10-minute deadline;
|
|
269
|
+
- custom positive timeout values;
|
|
270
|
+
- invalid timeout and response combinations;
|
|
271
|
+
- auto, required, and skip policy parsing;
|
|
272
|
+
- human continue, stop, and exact-text replan;
|
|
273
|
+
- human-answer and timeout-default races with each winner;
|
|
274
|
+
- timeout provenance without a human actor;
|
|
275
|
+
- late answer rejection;
|
|
276
|
+
- immediate terminal cancellation before and during timeout resolution;
|
|
277
|
+
- one continuation after concurrent or repeated recovery;
|
|
278
|
+
- restart recovery before and after the deadline;
|
|
279
|
+
- auto mode with no configured channel;
|
|
280
|
+
- required mode with no configured channel;
|
|
281
|
+
- Pi and Telegram delivery, expiry text, and settlement;
|
|
282
|
+
- plan digest and positive revision binding;
|
|
283
|
+
- no duplicate decision for the same digest;
|
|
284
|
+
- bounded replans;
|
|
285
|
+
- Autoimplement changed-plan routing;
|
|
286
|
+
- Autoimplement supplied and discovered plan bypass;
|
|
287
|
+
- Monitor repair-plan routing;
|
|
288
|
+
- no second decision when Monitor passes its selected plan to Autoimplement;
|
|
289
|
+
- later Autoimplement redesign after Monitor selection;
|
|
290
|
+
- built-in revision refusal for old active runs;
|
|
291
|
+
- package skill and workflow discovery; and
|
|
292
|
+
- real-Pi continuation with a short fake-clock deadline and no real model.
|
|
293
|
+
|
|
294
|
+
## Verification
|
|
295
|
+
|
|
296
|
+
Run:
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
npm run check
|
|
300
|
+
npm run test:e2e
|
|
301
|
+
npx slophammer-ts@latest dry .
|
|
302
|
+
npx slophammer-ts@latest check . --only ts.dependency-boundaries-required
|
|
303
|
+
npx -y @simpledoc/simpledoc check
|
|
304
|
+
git diff --check
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Inspect the complete public diff before each commit, push, or pull-request update. Verify GitHub CI and Pi Reviewer before delivery.
|
|
308
|
+
|
|
309
|
+
## Boundaries
|
|
310
|
+
|
|
311
|
+
This work changes only the pi-workflows repository. It may change the workflow engine, extension decision recovery, built-in workflow composition, skills, tests, examples, fixtures, and documentation needed for this policy.
|
|
312
|
+
|
|
313
|
+
It must not:
|
|
314
|
+
|
|
315
|
+
- change Pi core or use undocumented Pi APIs;
|
|
316
|
+
- add a service, daemon, controller, scheduler, or persistence location;
|
|
317
|
+
- change external services, credentials, Telegram configuration, CI policy, or unrelated repositories;
|
|
318
|
+
- add a standalone plan-approval skill;
|
|
319
|
+
- queue, revive, or extend deferred successor turns;
|
|
320
|
+
- add compatibility readers, migrations, dual paths, new schema generations, aliases, or feature flags;
|
|
321
|
+
- merge the implementation pull request; or
|
|
322
|
+
- publish a package or release.
|