@osolmaz/pi-workflows 0.13.3 → 0.14.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 +136 -118
- package/dist/builtins/autoimplement.workflow.d.ts +12 -12
- package/dist/builtins/autoplan.workflow.d.ts +3 -3
- package/dist/builtins/autoplan.workflow.js +44 -35
- package/dist/builtins/autoplan.workflow.js.map +1 -1
- package/dist/builtins/catalog.js +1 -1
- package/dist/builtins/plan-change.workflow.d.ts +6 -6
- package/dist/controllers/index.d.ts +1 -1
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/sqlite.d.ts +34 -31
- package/dist/controllers/sqlite.js +116 -77
- package/dist/controllers/sqlite.js.map +1 -1
- package/dist/extension/index.js +721 -202
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/restart-policy.d.ts +38 -0
- package/dist/extension/restart-policy.js +116 -0
- package/dist/extension/restart-policy.js.map +1 -0
- package/dist/extension/terminal-decision.d.ts +51 -0
- package/dist/extension/terminal-decision.js +110 -0
- package/dist/extension/terminal-decision.js.map +1 -0
- package/dist/state/prune.js +36 -10
- package/dist/state/prune.js.map +1 -1
- package/dist/workflows/tool-input.d.ts +4 -0
- package/dist/workflows/tool-input.js +6 -1
- package/dist/workflows/tool-input.js.map +1 -1
- package/docs/2026-08-25-workflow-follow-ups.md +8 -6
- package/docs/DEFERRED_TURNS.md +39 -26
- package/docs/HUMAN_DECISIONS.md +12 -4
- package/docs/SQLITE_STATE.md +24 -0
- package/docs/WORKFLOW_COMPOSITION.md +1 -1
- package/docs/plans/2026-08-19-human-decision-gates-plan.md +34 -8
- package/docs/plans/2026-08-27-workflow-terminal-restart-plan.md +357 -0
- package/docs/workflows.md +85 -29
- package/herdr-plugin.toml +1 -1
- package/package.json +1 -1
- package/skills/autodoc/SKILL.md +1 -1
- package/skills/autoimplement/SKILL.md +1 -1
- package/skills/autoplan/SKILL.md +6 -6
- package/skills/pi-workflows/SKILL.md +2 -0
- package/src/builtins/autoplan.workflow.ts +45 -37
- package/src/builtins/catalog.ts +1 -1
- package/src/controllers/index.ts +3 -0
- package/src/controllers/sqlite.ts +226 -155
- package/src/extension/index.ts +881 -220
- package/src/extension/restart-policy.ts +163 -0
- package/src/extension/terminal-decision.ts +172 -0
- package/src/state/prune.ts +35 -9
- package/src/workflows/tool-input.ts +9 -1
package/docs/DEFERRED_TURNS.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Deferred workflow turns
|
|
2
2
|
|
|
3
|
-
This specification defines how Pi Workflows schedules one successor agent turn after a workflow event stops or strands the current turn. It covers cancellation, timeout,
|
|
3
|
+
This specification defines how Pi Workflows schedules one successor agent turn after a workflow event stops or strands the current turn. It covers every top-level interactive terminal result, cancellation, timeout, launch failure, controller interruption, and claim loss.
|
|
4
4
|
|
|
5
|
-
The implementation
|
|
5
|
+
The implementation plans are [Guarantee one successor turn after workflow interruption](plans/2026-08-21-deferred-turn-intents-plan.md) and [Workflow terminal decision and restart](plans/2026-08-27-workflow-terminal-restart-plan.md).
|
|
6
6
|
|
|
7
7
|
## Terms
|
|
8
8
|
|
|
@@ -18,10 +18,10 @@ The implementation plan is [Guarantee one successor turn after workflow interrup
|
|
|
18
18
|
Each eligible source event creates at most one turn intent. Exactly one of these message paths can resolve it:
|
|
19
19
|
|
|
20
20
|
1. a workflow agent prompt;
|
|
21
|
-
2. a
|
|
21
|
+
2. a result presentation;
|
|
22
22
|
3. a factual fallback.
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Every top-level interactive terminal run owns one intent. Its presentation and fallback claim that same intent before sending. A waiting presentation can resolve an earlier interruption intent, but waiting state does not create a terminal intent. A resolved intent cannot start another turn.
|
|
25
25
|
|
|
26
26
|
Cancellation and process termination remain immediate. Pi Workflows does not keep the old assistant turn alive and does not wait for the successor before stopping active work.
|
|
27
27
|
|
|
@@ -56,25 +56,25 @@ Resolution records message delivery into the Pi session or the presence of the s
|
|
|
56
56
|
Valid causes are:
|
|
57
57
|
|
|
58
58
|
```text
|
|
59
|
-
agentCancelled | timedOut | failed | launchFailed | controllerInterrupted | claimLost
|
|
59
|
+
agentCancelled | timedOut | failed | launchFailed | controllerInterrupted | claimLost | terminal | cancelled
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
The event policy is:
|
|
63
63
|
|
|
64
|
-
| Event | Intent
|
|
65
|
-
| -------------------------------------------------------------- |
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
| Workflow reports started, then crashes before its first prompt | Create after durable failure.
|
|
70
|
-
| Queued launch activation fails | Create after the queue row is durably failed.
|
|
71
|
-
| Controller interrupts an active workflow turn | Create before the turn abort when possible.
|
|
72
|
-
| Active workflow turn loses its queue claim | Create before the turn abort when possible.
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
| Workflow pause | Do not create.
|
|
76
|
-
| User Escape or held workflow | Do not create.
|
|
77
|
-
| Session shutdown | Do not create.
|
|
64
|
+
| Event | Intent | Fallback rule |
|
|
65
|
+
| -------------------------------------------------------------- | --------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
66
|
+
| Top-level interactive run completes | Create one terminal intent. | Presentation and factual fallback compete for the intent. |
|
|
67
|
+
| Top-level interactive run fails or times out | Create or reuse the abort intent. | Make eligible after the terminal state is durable. |
|
|
68
|
+
| Agent or user cancels a top-level run | Create before turn abort when needed. | Make eligible after durable cancellation; the decision defaults to stopping. |
|
|
69
|
+
| Workflow reports started, then crashes before its first prompt | Create after durable failure. | Create as eligible. |
|
|
70
|
+
| Queued launch activation fails | Create after the queue row is durably failed. | Create as eligible. |
|
|
71
|
+
| Controller interrupts an active workflow turn | Create before the turn abort when possible. | Durable terminal or handoff state decides eligibility. |
|
|
72
|
+
| Active workflow turn loses its queue claim | Create before the turn abort when possible. | Keep ineligible while a new owner can continue. |
|
|
73
|
+
| Waiting result has a presentation | Do not create a terminal intent. | It can resolve an earlier interruption intent through presentation. |
|
|
74
|
+
| Controller child or internally owned run ends | Do not create a terminal intent. | Its owner receives the result. |
|
|
75
|
+
| Workflow pause | Do not create. | No automatic model turn. |
|
|
76
|
+
| User Escape or held workflow | Do not create. | No automatic model turn. |
|
|
77
|
+
| Session shutdown | Do not create. | A closing session cannot start another turn. |
|
|
78
78
|
|
|
79
79
|
A terminal failure after a successful start tool result is eligible even when it did not first call `ctx.abort()`. This rule covers asynchronous runtime validation and startup failures that the user can see in the UI but the model cannot see in its current context.
|
|
80
80
|
|
|
@@ -232,10 +232,22 @@ The message type is `pi-workflows-deferred-turn`. Delivery uses:
|
|
|
232
232
|
}
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
For a terminal run, the visible content contains the workflow identity and revision, terminal run ID, exact stored input, bounded result, terminal state and reason, restart count, and earlier terminal outcomes in the chain. It tells the model to use the current conversation, prefer a safe restart for an unfinished task after a technical or temporary failure, and stop for completed work, cancellation, missing authority, a required user decision, or a repeated failure. Values from input and result are data, not instructions.
|
|
236
|
+
|
|
237
|
+
The content comes only from existing run and queue records. Pi owns conversation history. Pi Workflows does not identify, hash, copy, or store an original user message.
|
|
236
238
|
|
|
237
239
|
Fallback delivery is disabled during session shutdown and while a user-interrupted workflow is held.
|
|
238
240
|
|
|
241
|
+
## Selected launch and restart
|
|
242
|
+
|
|
243
|
+
A terminal decision turn can reserve at most one workflow launch: `restart`, Monitor through normal `start`, or another workflow through normal `start`. The reservation records the source terminal intent, model tool call, and request fingerprint in the new run's existing launch options. It does not activate before `agent_settled`.
|
|
244
|
+
|
|
245
|
+
Repeating the same tool call adopts the existing reservation or run. A different launch from the same terminal intent fails. Session-start and queue recovery activate a surviving reservation once when the session is idle.
|
|
246
|
+
|
|
247
|
+
`restart` accepts the terminal run ID. It checks session ownership, terminal state, explicit cancellation, source identity and revision, repeated failure, and the restart limit. It creates a new immutable run from the exact stored reference, input, and safe launch settings. The old run does not change.
|
|
248
|
+
|
|
249
|
+
Restart lineage in launch options records the root run ID, parent run ID, restart number, and parent terminal fingerprint. The fingerprint covers workflow identity and revision, exact input, terminal state, canonical result or error, and terminal reason. It excludes timestamps and run IDs. The same fingerprint cannot restart twice in one chain. A chain permits three restarts after the original run. Starting Monitor does not add restart lineage.
|
|
250
|
+
|
|
239
251
|
## Delivery recovery
|
|
240
252
|
|
|
241
253
|
Every resolving message includes the intent ID in its custom-message details.
|
|
@@ -262,7 +274,7 @@ Pending `launch_failure` rows from the earlier alpha contract are incompatible.
|
|
|
262
274
|
|
|
263
275
|
## Post-completion follow-ups
|
|
264
276
|
|
|
265
|
-
Deferred turns
|
|
277
|
+
Deferred turns provide the terminal decision before ordered post-completion prompts. Those prompts represent user-requested normal work after successful completion, use `workflow_follow_up_queues` and `workflow_follow_ups`, and are delivered by the separate follow-up coordinator after the terminal intent is resolved. Neither feature reads or changes the other's rows.
|
|
266
278
|
|
|
267
279
|
See [Continue normal work after a workflow finishes](2026-08-25-workflow-follow-ups.md).
|
|
268
280
|
|
|
@@ -293,12 +305,13 @@ This is an alpha hard cutover.
|
|
|
293
305
|
|
|
294
306
|
An implementation conforms when:
|
|
295
307
|
|
|
296
|
-
-
|
|
297
|
-
-
|
|
298
|
-
- an agent self-cancel receives one fallback after settlement;
|
|
308
|
+
- every top-level interactive terminal run produces at most one intent and one decision message;
|
|
309
|
+
- an agent self-cancel and a direct cancellation receive one fallback after settlement;
|
|
299
310
|
- an asynchronous crash after a successful start result receives one fallback after settlement;
|
|
300
311
|
- a natural recovery prompt or presentation suppresses fallback by resolving the same intent;
|
|
301
|
-
-
|
|
312
|
+
- waiting checkpoints, controller children, internal owners, pause, Escape, user hold, and shutdown do not create terminal turns;
|
|
302
313
|
- claim transfer permits natural resolution by the new owner and prevents stale writes;
|
|
303
|
-
-
|
|
314
|
+
- one terminal turn reserves at most one launch and activates it after `agent_settled`;
|
|
315
|
+
- exact replay adopts the same launch, while reload, lease expiry, and send-before-resolution failure do not duplicate turns or runs;
|
|
316
|
+
- restart keeps the prior run immutable, preserves exact input, rejects cancellation and repeated fingerprints, and stops after three restarts;
|
|
304
317
|
- passive workflow notifications keep their current behavior.
|
package/docs/HUMAN_DECISIONS.md
CHANGED
|
@@ -322,19 +322,23 @@ Recovery follows these rules:
|
|
|
322
322
|
|
|
323
323
|
A required decision with no available channel remains waiting and reports the configuration problem. An automatic decision does not need a channel to apply its saved response after the deadline. A skipped plan policy creates no decision.
|
|
324
324
|
|
|
325
|
+
Direct answer handling and recovery can notice the same accepted decision at the same time. Both paths use one continuation coordinator. The coordinator prepares the deterministic continuation through the existing durable run queue. The first caller creates and claims the queue row. Only that caller receives the claim token and starts the engine. A compatible later caller adopts the existing row without starting another engine.
|
|
326
|
+
|
|
327
|
+
Adoption does not change the lease, claim generation, queue state, timestamps, or events. An adopter cannot renew, release, park, complete, or replace the winning claim. Reuse with a different workflow source, definition, input, launch options, parent, or owning session fails without changing the existing run. If the winning process stops after it claims the row, existing lease expiry and activation recovery can continue the prepared run.
|
|
328
|
+
|
|
325
329
|
## Compatibility
|
|
326
330
|
|
|
327
|
-
This alpha change updates the current request, accepted-result, receipt, resolution, continuation, and snapshot contracts in place. Old active runs refuse resume through normal source and definition identity checks. There is no compatibility reader, migration, dual path, or new schema generation. Updated viewers label a human decision as a checkpoint, show its deadline and automatic action when present, and keep the canonical subject separate. Private channel configuration and transport identifiers remain hidden.
|
|
331
|
+
This alpha change updates the current request, accepted-result, receipt, resolution, continuation, and snapshot contracts in place. Old active runs refuse resume through normal source and definition identity checks. There is no compatibility reader, migration, dual path, or new schema generation. The continuation startup fix uses existing queue and lease records. It adds no field, table, migration, or schema version. Existing compatible prepared or initialized continuations are adopted. Updated viewers label a human decision as a checkpoint, show its deadline and automatic action when present, and keep the canonical subject separate. Private channel configuration and transport identifiers remain hidden.
|
|
328
332
|
|
|
329
333
|
The engine remains independent from Pi and Telegram. Core code owns decision contracts, validation, durable acceptance, and continuation. The Pi extension owns UI and channel lifecycle. The Telegram adapter owns Bot API translation. Workflow definitions own only the question, choices, audience, and routes.
|
|
330
334
|
|
|
331
335
|
## Contract impact
|
|
332
336
|
|
|
333
337
|
- **Session state:** Pi records normal workflow messages and interactive decision results.
|
|
334
|
-
- **Other persistent data:** decision requests and resolutions can carry a deadline, automatic response, and resolution provenance in the existing decision store. The private channel index remains rebuildable.
|
|
338
|
+
- **Other persistent data:** decision requests and resolutions can carry a deadline, automatic response, and resolution provenance in the existing decision store. Continuation startup uses existing run, queue, source, binding, lease, event, continuation, and decision-effect records. It adds no new persistent shape. The private channel index remains rebuildable.
|
|
335
339
|
- **Pi internals:** none.
|
|
336
340
|
- **Public Pi API:** documented extension lifecycle and UI methods only.
|
|
337
|
-
- **Public pi-workflows API:** typed human choices, `humanDecision().onTimeout`, `humanDecisionEdge()`, the channel interface, the plan approval policy,
|
|
341
|
+
- **Public pi-workflows API:** typed human choices, `humanDecision().onTimeout`, `humanDecisionEdge()`, the channel interface, the plan approval policy, the shared plan-change workflow, and the additive queue prepare-or-adopt operation.
|
|
338
342
|
|
|
339
343
|
## Verification requirements
|
|
340
344
|
|
|
@@ -350,6 +354,10 @@ The implementation must test:
|
|
|
350
354
|
- unauthorized users and chats;
|
|
351
355
|
- stale request digests;
|
|
352
356
|
- concurrent Pi and Telegram answers;
|
|
357
|
+
- a direct verified answer racing recovery for the same accepted decision;
|
|
358
|
+
- one claim generation, one engine start, one continuation, and one execution of each continuation node;
|
|
359
|
+
- compatible continuation adoption without lease, queue, timestamp, or event mutation;
|
|
360
|
+
- incompatible continuation identity reuse without mutation;
|
|
353
361
|
- identical and conflicting retries;
|
|
354
362
|
- crashes before and after answer acceptance and continuation creation;
|
|
355
363
|
- ambiguous Telegram sends;
|
|
@@ -357,4 +365,4 @@ The implementation must test:
|
|
|
357
365
|
- decision cancellation and expiry;
|
|
358
366
|
- included `plan-approval` routes and bounded replan loops;
|
|
359
367
|
- viewer redaction; and
|
|
360
|
-
- real Pi execution without real Telegram credentials or network calls.
|
|
368
|
+
- real Pi execution without real Telegram credentials or network calls, duplicate-start failures, revision conflicts, or a stranded running continuation.
|
package/docs/SQLITE_STATE.md
CHANGED
|
@@ -111,6 +111,30 @@ The shared records do not replace domain schemas. The following `STRICT` tables
|
|
|
111
111
|
|
|
112
112
|
Foreign keys join projects, runs, attempts, decisions, controllers, effects, and channel records. Partial unique indexes enforce one active node attempt per run, one queued or running reservation per Pi session, one decision winner, and one deterministic effect key. A parked waiting parent does not block its continuation. Reserving that continuation settles the parked parent queue in the same transaction, so a failed reservation leaves the parent recoverable.
|
|
113
113
|
|
|
114
|
+
### Terminal restart state
|
|
115
|
+
|
|
116
|
+
The [terminal workflow restart contract](plans/2026-08-27-workflow-terminal-restart-plan.md)
|
|
117
|
+
uses the existing tables. It adds no state store or table. A restarted run keeps
|
|
118
|
+
its root run ID, parent run ID, restart number, and parent terminal fingerprint
|
|
119
|
+
in the existing launch-options value. The fingerprint uses the workflow
|
|
120
|
+
identity and revision, exact input, terminal state, canonical result or error,
|
|
121
|
+
and canonical reason. It excludes run IDs, timestamps, and other values that
|
|
122
|
+
change between equivalent attempts.
|
|
123
|
+
|
|
124
|
+
One terminal turn intent covers result presentation and factual fallback. A
|
|
125
|
+
selected restart, Monitor run, or other workflow start uses the existing
|
|
126
|
+
session reservation, run queue, and effect receipt. The successor run's launch
|
|
127
|
+
options record the source terminal run, intent, model tool call, and canonical
|
|
128
|
+
request fingerprint. A repeated call adopts that reservation or run. Activation
|
|
129
|
+
waits for `agent_settled`, and normal queue recovery activates a surviving
|
|
130
|
+
reservation once.
|
|
131
|
+
|
|
132
|
+
Restart creates a new run. The terminal run remains unchanged. Restart lineage
|
|
133
|
+
allows three restarts after the original run and rejects a repeated terminal
|
|
134
|
+
fingerprint in the same chain. A Monitor selection records terminal selection
|
|
135
|
+
but no restart lineage. Conversation history remains in Pi. This state does not
|
|
136
|
+
identify, hash, copy, or store an original user message.
|
|
137
|
+
|
|
114
138
|
## Content-addressed values
|
|
115
139
|
|
|
116
140
|
`blobs` stores canonical JSON and UTF-8 text as bytes. Its primary key is the 32-byte SHA-256 digest of the bytes.
|
|
@@ -282,7 +282,7 @@ monitor
|
|
|
282
282
|
|
|
283
283
|
## Autoplan, autodoc, and autoimplement
|
|
284
284
|
|
|
285
|
-
`autoplan` accepts the problem, scope, constraints, an optional previous plan, and new evidence.
|
|
285
|
+
`autoplan` accepts the problem, scope, constraints, an optional previous plan, and new evidence. Its `solutions` step records two through four practical candidates and asks whether each is a Long term elegant and production ready solution. Its `holyGrail` step describes the Holy grail separately. Its `select` step chooses the best in-scope option and records one rejection reason for every other explicit candidate, including the Holy grail. It includes `plain-summary` on ready and blocked routes, so the user sees one short normal assistant response before the parent continues. The response calls the choice a plan selected for approval and cannot satisfy the later human decision. Autoplan exits through `ready` or `blocked` and returns the full candidates, selection, detailed plan when ready, plain summary, plan digest, and change status.
|
|
286
286
|
|
|
287
287
|
`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.
|
|
288
288
|
|
|
@@ -52,6 +52,11 @@ Pi and Telegram implement one channel interface. Workflows address a named audie
|
|
|
52
52
|
- Accept the first valid response with a no-replace write.
|
|
53
53
|
- Adopt identical retries and reject conflicting responses.
|
|
54
54
|
- Derive one continuation identity from the accepted decision.
|
|
55
|
+
- Prepare that continuation through one atomic queue operation.
|
|
56
|
+
- Let the first caller create and claim the queue row.
|
|
57
|
+
- Let compatible concurrent or repeated callers adopt the row without changing its lease, claim generation, queue state, timestamps, or events.
|
|
58
|
+
- Reject incompatible workflow source, definition, input, launch options, parent, or owning session without changing the existing row.
|
|
59
|
+
- Give only the winning caller a claim token and permission to start the engine.
|
|
55
60
|
- Reject stale responses by decision ID and canonical request digest.
|
|
56
61
|
- Rebuild the pending-decision index from immutable records.
|
|
57
62
|
|
|
@@ -83,6 +88,10 @@ Pi and Telegram implement one channel interface. Workflows address a named audie
|
|
|
83
88
|
- Promise exactly-once Telegram message creation after an ambiguous Bot API response.
|
|
84
89
|
- Add arbitrary forms in the first release. Choice buttons and one text input cover the required flows.
|
|
85
90
|
- Change existing checkpoints or historical run bundles.
|
|
91
|
+
- Add a database field, table, migration, schema version, compatibility reader, or dual-write path for continuation startup.
|
|
92
|
+
- Coordinate continuation startup with a process-local promise map, timing guard, retry loop, or swallowed error.
|
|
93
|
+
- Change general queue claim behavior for unrelated launch paths.
|
|
94
|
+
- Repair an already stranded live continuation as part of this change.
|
|
86
95
|
- Enable human approval by default in existing built-in workflows.
|
|
87
96
|
|
|
88
97
|
## Design decisions
|
|
@@ -107,7 +116,13 @@ The Telegram adapter accepts replan text only as a reply to the exact `ForceRepl
|
|
|
107
116
|
|
|
108
117
|
### Make answer acceptance exact
|
|
109
118
|
|
|
110
|
-
Channel delivery can be retried or fail independently. Decision acceptance is one atomic no-replace operation. The accepted response and deterministic continuation identity prevent two channels from
|
|
119
|
+
Channel delivery can be retried or fail independently. Decision acceptance is one atomic no-replace operation. The accepted response and deterministic continuation identity prevent two channels from selecting different continuations.
|
|
120
|
+
|
|
121
|
+
### Prepare or adopt one continuation
|
|
122
|
+
|
|
123
|
+
Direct answer handling and periodic recovery can both see the accepted decision. They use one continuation coordinator and one durable queue operation. The operation creates and claims a missing queue row or returns a compatible existing row as adopted. Only a newly claimed preparation can call `WorkflowEngine.continueRun()`.
|
|
124
|
+
|
|
125
|
+
An adopted result is normal success. It does not start another engine or change the winning lease, claim generation, queue state, timestamps, or events. The adopter receives no claim token, so it cannot renew, release, park, complete, or replace the winning claim. Incompatible reuse fails without mutation. Existing cleanup handles failure before run initialization, and existing lease expiry and activation recovery handle a winning process that stops after preparation.
|
|
111
126
|
|
|
112
127
|
### Handle Telegram delivery limits honestly
|
|
113
128
|
|
|
@@ -171,10 +186,17 @@ A private SQLite index may track pending decisions, channel leases, Telegram upd
|
|
|
171
186
|
- Validate the accepted response through the node contract.
|
|
172
187
|
- Preserve the parent's original workflow input.
|
|
173
188
|
- Expose the response as the checkpoint output.
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
|
|
189
|
+
- Derive the deterministic continuation identity.
|
|
190
|
+
- Add a typed atomic prepare-or-adopt operation to the existing SQLite queue store.
|
|
191
|
+
- Compare the stored workflow source, definition digest, input, launch options, parent, and owning session before adoption.
|
|
192
|
+
- Build one prepared continuation value in the Pi extension.
|
|
193
|
+
- Route direct verified answers and recovery through one continuation coordinator.
|
|
194
|
+
- Start `WorkflowEngine.continueRun()` only with the new claim token.
|
|
195
|
+
- Return normal started or already-continuing success to the answer path.
|
|
196
|
+
- Keep enqueue and lease behavior unchanged for other launch paths.
|
|
197
|
+
- Leave legacy checkpoint continuation unchanged.
|
|
198
|
+
|
|
199
|
+
Test crashes before acceptance, after acceptance, during continuation creation, and after continuation completion. Add a focused race test for direct answer handling and recovery. It must prove one claim generation, one engine start, one continuation, one execution of each continuation node, coherent queue and run state, and no duplicate-start or revision-conflict failure. Add a real-Pi version of the same regression with a durable barrier instead of sleep-only timing.
|
|
178
200
|
|
|
179
201
|
### Channel management
|
|
180
202
|
|
|
@@ -248,7 +270,9 @@ The setup command uses an existing mode-`0600` token file instead of collecting
|
|
|
248
270
|
- The workflow tool cannot answer a protected human decision.
|
|
249
271
|
- Pi and Telegram can receive the same decision through one audience profile.
|
|
250
272
|
- The first concurrent valid answer wins and creates one continuation.
|
|
251
|
-
-
|
|
273
|
+
- Direct answer handling and recovery can race without starting it twice or replacing its lease.
|
|
274
|
+
- The first queue preparation starts the engine, and a compatible repeat adopts it without mutation.
|
|
275
|
+
- An incompatible continuation identity, conflicting answer, or stale answer is rejected without mutation.
|
|
252
276
|
- The original workflow input survives a human-decision continuation.
|
|
253
277
|
- Old checkpoints and old bundles pass their existing tests unchanged.
|
|
254
278
|
- The Telegram adapter accepts text only from the bound reply and approved numeric actor.
|
|
@@ -267,6 +291,8 @@ npx vitest run test/human-decision-api.test.ts test/human-decision-store.test.ts
|
|
|
267
291
|
npx vitest run test/human-decision-engine.test.ts test/run-resume.test.ts
|
|
268
292
|
npx vitest run test/pi-decision-channel.test.ts test/telegram-decision-channel.test.ts
|
|
269
293
|
npx vitest run test/plan-approval.test.ts test/composition.test.ts
|
|
294
|
+
npx vitest run test/run-queue.test.ts test/extension.test.ts
|
|
295
|
+
npx vitest run --config vitest.e2e.config.ts test/e2e/workflow.e2e.test.ts
|
|
270
296
|
```
|
|
271
297
|
|
|
272
298
|
Run all repository gates before review:
|
|
@@ -290,7 +316,7 @@ This work adds compatible public APIs and additive persisted records. Release it
|
|
|
290
316
|
## Contract impact
|
|
291
317
|
|
|
292
318
|
- **Session state:** normal workflow messages and interactive decision results.
|
|
293
|
-
- **Other persistent data:** additive decision records, a rebuildable private channel index,
|
|
319
|
+
- **Other persistent data:** additive decision records, a rebuildable private channel index, private channel configuration, and existing run queue and lease records. The continuation startup fix adds no persistent field, table, migration, or schema version.
|
|
294
320
|
- **Pi internals:** none.
|
|
295
321
|
- **Public Pi API:** documented extension lifecycle plus command and UI methods only.
|
|
296
|
-
- **Public pi-workflows API:** typed human choices, `humanDecision()`, `humanDecisionEdge()`, the channel interface,
|
|
322
|
+
- **Public pi-workflows API:** typed human choices, `humanDecision()`, `humanDecisionEdge()`, the channel interface, the `plan-approval` workflow, and an additive queue prepare-or-adopt operation.
|