@sublang/playbook 6.0.0 → 8.0.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 (63) hide show
  1. package/README.md +28 -11
  2. package/docs/cli.md +158 -68
  3. package/docs/configuration.md +246 -108
  4. package/docs/embedding.md +71 -25
  5. package/package.json +6 -3
  6. package/reference/sdlc/captain.playbook/captain.playbook.js +3 -3
  7. package/reference/sdlc/captain.playbook/captain.playbook.ts +3 -3
  8. package/reference/sdlc/code.md +1 -1
  9. package/reference/sdlc/code.playbook/bin/interactive-session.js +816 -0
  10. package/reference/sdlc/code.playbook/bin/launch-config.js +1900 -0
  11. package/reference/sdlc/code.playbook/bin/playbook.js +573 -535
  12. package/reference/sdlc/code.playbook/bin/provision.js +84 -38
  13. package/reference/sdlc/code.playbook/bin/run.js +1164 -991
  14. package/reference/sdlc/code.playbook/bin/session-store.js +1961 -0
  15. package/reference/sdlc/code.playbook/code.fsm.d.ts +5 -5
  16. package/reference/sdlc/code.playbook/code.fsm.introspect.js +2 -2
  17. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +2 -2
  18. package/reference/sdlc/code.playbook/code.fsm.js +7 -11
  19. package/reference/sdlc/code.playbook/code.fsm.ts +9 -17
  20. package/reference/sdlc/code.playbook/code.gears.md +1 -1
  21. package/reference/sdlc/code.playbook/code.playbook.d.ts +2 -1
  22. package/reference/sdlc/code.playbook/code.playbook.js +12 -13
  23. package/reference/sdlc/code.playbook/code.playbook.ts +22 -15
  24. package/reference/sdlc/code.playbook/code.registry.d.ts +5 -13
  25. package/reference/sdlc/code.playbook/code.registry.js +3 -10
  26. package/reference/sdlc/code.playbook/code.registry.ts +7 -32
  27. package/reference/sdlc/code.playbook/playbook-captain.d.ts +101 -9
  28. package/reference/sdlc/code.playbook/playbook-captain.js +1690 -213
  29. package/reference/sdlc/code.playbook/playbook-captain.ts +2492 -253
  30. package/reference/sdlc/code.playbook/playbook.config.template.yaml +44 -62
  31. package/reference/sdlc/decide.md +4 -4
  32. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +9 -9
  33. package/reference/sdlc/decide.playbook/decide.fsm.js +21 -14
  34. package/reference/sdlc/decide.playbook/decide.fsm.ts +27 -23
  35. package/reference/sdlc/decide.playbook/decide.gears.md +3 -5
  36. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +9 -13
  37. package/reference/sdlc/decide.playbook/decide.playbook.js +244 -143
  38. package/reference/sdlc/decide.playbook/decide.playbook.ts +326 -171
  39. package/reference/sdlc/decide.playbook/decide.registry.d.ts +5 -13
  40. package/reference/sdlc/decide.playbook/decide.registry.js +3 -9
  41. package/reference/sdlc/decide.playbook/decide.registry.ts +7 -31
  42. package/reference/sdlc/review.md +4 -5
  43. package/reference/sdlc/review.playbook/review.fsm.d.ts +9 -11
  44. package/reference/sdlc/review.playbook/review.fsm.js +30 -24
  45. package/reference/sdlc/review.playbook/review.fsm.ts +39 -35
  46. package/reference/sdlc/review.playbook/review.gears.md +6 -5
  47. package/reference/sdlc/review.playbook/review.playbook.d.ts +2 -1
  48. package/reference/sdlc/review.playbook/review.playbook.js +16 -21
  49. package/reference/sdlc/review.playbook/review.playbook.ts +26 -26
  50. package/reference/sdlc/review.playbook/review.registry.d.ts +5 -13
  51. package/reference/sdlc/review.playbook/review.registry.js +3 -16
  52. package/reference/sdlc/review.playbook/review.registry.ts +7 -38
  53. package/slc/gears2fsm.md +27 -23
  54. package/slc/link.md +140 -97
  55. package/slc/text2gears.md +19 -18
  56. package/src/runtime.d.ts +24 -8
  57. package/src/runtime.ts +29 -13
  58. package/src/xstate-playbook-runtime.d.ts +21 -17
  59. package/src/xstate-playbook-runtime.js +301 -159
  60. package/src/xstate-playbook-runtime.ts +405 -186
  61. package/src/xstate-runtime.d.ts +19 -2
  62. package/src/xstate-runtime.js +403 -62
  63. package/src/xstate-runtime.ts +566 -78
package/README.md CHANGED
@@ -19,16 +19,23 @@ SubLang Playbook addresses both:
19
19
 
20
20
  ![Venn diagram: Skill is flexible, Workflow is deterministic, and Playbook sits in the intersection as both.](docs/assets/playbook-venn.svg)
21
21
 
22
- Vocabulary: the **Boss** is you; the **Captain** is the coordinating agent you talk to; **players** are the agents a playbook delegates work to.
22
+ Vocabulary: the **Boss** is you; the **Captain** is the coordinating agent you
23
+ talk to; a **role** is a playbook-local job such as `coder`; and a **player** is
24
+ a stable Captain-session agent and provider conversation to which one or more
25
+ roles bind. Roles describe the workflow, while player IDs decide which work
26
+ shares conversation continuity.
23
27
 
24
- Run `playbook` for an interactive tmux UI powered by [cligent](https://github.com/sublang-ai/cligent), or `playbook run` for one-shot scripts and CI.
28
+ Run `playbook` for an interactive tmux UI powered by [cligent](https://github.com/sublang-ai/cligent), or `playbook run` for the same Captain session without tmux in scripts and CI.
25
29
 
26
30
  ## Quick start
27
31
 
28
32
  Out of the box, Playbook includes **CODE** for implementation, **REVIEW** for commit-based review and fixes, and **DECIDE** for independently proposed and reviewed specification decisions.
29
33
  CODE and DECIDE call REVIEW as a nested playbook.
30
34
 
31
- The interactive starter config uses Claude as both Captain and Coder, and Codex as Reviewer.
35
+ The shared starter config uses Claude as both Captain and the `dev.coder`
36
+ player, and Codex as `dev.reviewer`. CODE, REVIEW, and DECIDE bind their local
37
+ roles explicitly to those two stable players, so nested and later engagements
38
+ share a conversation only where their bindings name the same player ID.
32
39
 
33
40
  ```sh
34
41
  npm install -g @sublang/playbook
@@ -41,10 +48,11 @@ If an SDK is missing or older than cligent supports, Playbook prints the pinned
41
48
  Prerequisites:
42
49
 
43
50
  - Node.js >= 20.6.0
44
- - `tmux` and [`glow`](https://github.com/charmbracelet/glow#installation) on `PATH`
45
51
  - Authenticated [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) or `ANTHROPIC_API_KEY`
46
52
  - Authenticated [Codex CLI](https://github.com/openai/codex) or `OPENAI_API_KEY`
47
53
 
54
+ Interactive `playbook` additionally needs tmux 3.3 or newer and [`glow`](https://github.com/charmbracelet/glow#installation) on `PATH`; headless `playbook run` does not.
55
+
48
56
  CODE works in the current directory and can edit and commit autonomously, so use a clean branch or worktree.
49
57
 
50
58
  ```sh
@@ -57,16 +65,23 @@ Type a task, enter `/code <task>` for implementation, or enter
57
65
 
58
66
  On first launch, Playbook writes its config to `${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`.
59
67
 
60
- One-shot runs use separate defaults instead of the interactive lineup.
61
- Without configured `run` defaults, the Captain and every player use Claude; run standalone REVIEW with a Codex Reviewer using:
68
+ The same config, compiled Captain, enabled playbooks, stable players, and
69
+ nested calls power headless turns. Both front ends create the same durable
70
+ logical session: copy the reported session ID to reopen an interactive session
71
+ headlessly or a headless session interactively.
72
+ Run REVIEW explicitly, or pipe a longer request to Captain:
62
73
 
63
74
  ```sh
64
- playbook run @sublang/playbook/review/registry "review the latest commit" --player reviewer=codex --json
75
+ playbook run "/review review the latest commit"
76
+ printf '%s\n' 'Implement the approved specification, then review it.' | playbook run
77
+ # Later, either presentation can reopen the returned/reported session id:
78
+ playbook --session 4f2c0000-0000-4000-8000-000000009ab1
79
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 "continue"
65
80
  ```
66
81
 
67
- CODE and DECIDE require interactive `playbook` because the one-shot host does not drive nested calls.
82
+ `playbook run` prints the one Boss-visible Captain reply to stdout and operational status to stderr; CODE and DECIDE can complete their nested REVIEW calls there too.
68
83
 
69
- See [Using the CLI](docs/cli.md) for flags and session resume, [Configuring agents](docs/configuration.md) for lineups, [Embedding](docs/embedding.md) for custom hosts, and the [changelog](CHANGELOG.md) for releases.
84
+ See [Using the CLI](docs/cli.md) for flags and durable continuation, [Configuring agents](docs/configuration.md) for the shared lineup, [Embedding](docs/embedding.md) for custom hosts, and the [changelog](CHANGELOG.md) for releases.
70
85
 
71
86
  ## Create your own playbook
72
87
 
@@ -75,10 +90,12 @@ The separate [SLC compiler](https://github.com/sublang-ai/slc) requires Node.js
75
90
  ```sh
76
91
  npm install -g @sublang/slc
77
92
  slc playbook my-workflow.md
78
- playbook run ./my-workflow.ts "<your task>"
93
+ # After enabling /absolute/path/to/my-workflow.ts in the shared config:
94
+ playbook run "/my-workflow <your task>"
79
95
  ```
80
96
 
81
- SLC writes `my-workflow.ts` beside the source, and the inspectable intermediates and tests under `my-workflow.playbook/`; see the [SLC documentation](https://github.com/sublang-ai/slc#quick-start) for setup and phase commands.
97
+ SLC writes `my-workflow.ts`, a registry entry ready for Playbook, beside the source, and the inspectable intermediates and tests under `my-workflow.playbook/`.
98
+ Enable that entry and bind each role it declares under `playbooks.my-workflow` in the shared config, then invoke `/my-workflow`; see [External playbooks](docs/configuration.md#external-playbooks) and the [SLC documentation](https://github.com/sublang-ai/slc#quick-start).
82
99
 
83
100
  ## How it compiles
84
101
 
package/docs/cli.md CHANGED
@@ -3,9 +3,13 @@
3
3
 
4
4
  # Using the CLI
5
5
 
6
- `playbook` has two surfaces: an interactive tmux-play session, and a
7
- one-shot non-interactive `run`. Agent settings for both come from the
8
- [config](configuration.md).
6
+ `playbook` has two presentations of one configured Captain session: an
7
+ interactive tmux-play UI and a headless `playbook run` turn for scripts and
8
+ CI. Both use the same compiled Captain, enabled catalog, players, nested
9
+ stack, and [config](configuration.md); only presentation differs.
10
+
11
+ The interactive form requires tmux 3.3 or newer and `glow` on `PATH`;
12
+ the headless form requires neither presentation tool.
9
13
 
10
14
  ## Installing agent SDKs
11
15
 
@@ -55,9 +59,11 @@ following it cannot install a version the gate refuses again
55
59
  ## Interactive
56
60
 
57
61
  ```sh
58
- playbook # launch the configured playbooks in tmux-play
59
- playbook --list # ids, slash commands, and intents; no launch
60
- playbook --help # config path, auth pointers, agent-swap recipe
62
+ playbook # fresh durable session in this directory
63
+ playbook --cwd /path/to/repo # fresh session in an explicit directory
64
+ playbook --session <id> # reopen either front end's settled session
65
+ playbook --list # ids, slash commands, and intents; no launch
66
+ playbook --help # config path, auth pointers, binding recipe
61
67
  ```
62
68
 
63
69
  Without a global install, `npx` runs the same bin — but name each
@@ -77,10 +83,21 @@ already present, since each distinct package set is a distinct tree —
77
83
  and replaying your original arguments, so the printed command works in
78
84
  one hop.
79
85
 
80
- The command resolves its config (seeding it on first run), composes a
81
- `tmux-play` config, checks adapter readiness, and launches. It exits
82
- with tmux-play's status, re-raises a terminating signal on itself, and
83
- exits `127` when it cannot launch at all
86
+ For a managed launch, the outer command resolves current config (seeding it on
87
+ first use), prepares the complete stored catalog and presenter, waits for the
88
+ pane child to acquire the session lease and publish its settled turn-zero
89
+ record, prints the verified session ID, and then attaches. A normal outer
90
+ detach exits `0`; the pane child keeps owning the durable session and accepting
91
+ turns until it shuts down. Preparation, attachment, or required cleanup
92
+ failure prints its diagnostics and exits nonzero.
93
+
94
+ Before native-client hand-off, SIGHUP, SIGINT, or SIGTERM aborts activation,
95
+ joins the child, retires the lease, and only then re-raises the signal. At the
96
+ synchronous native-client hand-off, ownership transfers before tmux starts, so
97
+ later signals use native client detach or termination semantics and do not
98
+ retire the pane child's session. Only `--config` and composed
99
+ `--theme-diagnostics` use the stock subprocess boundary: those forms mirror
100
+ its exit status or signal and exit `127` when it cannot be spawned
84
101
  ([[playbook-cli-1](../specs/packages/playbook-cli.md#playbook-cli-1)],
85
102
  [[playbook-cli-2](../specs/packages/playbook-cli.md#playbook-cli-2)]).
86
103
 
@@ -105,10 +122,12 @@ untouched
105
122
  [[playbook-captain-2](../specs/packages/playbook-captain.md#playbook-captain-2)]).
106
123
 
107
124
  The current CODE, REVIEW, and DECIDE workflows take their deterministic
108
- initial event from the selecting Boss turn. CODE and DECIDE then call
109
- REVIEW as a nested playbook: an exact same-name child role continues the
110
- ancestor's player pane and backend conversation, while any additional
111
- role uses REVIEW's configured fallback. When a player surfaces a
125
+ initial event from the selecting Boss turn. CODE and DECIDE then call REVIEW
126
+ as a nested playbook. Local role names do not imply continuity: each frame
127
+ uses the exact stable player IDs configured under its `roles` map. Equal IDs
128
+ share one pane and provider conversation across nested and later root
129
+ engagements; distinct IDs remain isolated even when their agent settings are
130
+ identical. When a player surfaces a
112
131
  clarifying question the FSM parks, the pane shows the question, and a
113
132
  judge classifies your next turn as its reply or a fresh directive that
114
133
  abandons it
@@ -123,78 +142,149 @@ turn's reported outcome; a turn that changed nothing ends with an
123
142
  ordinary reply and no saved-counts line
124
143
  ([[playbook-captain-19](../specs/packages/playbook-captain.md#playbook-captain-19)]).
125
144
 
126
- ## Non-interactive
145
+ ## Headless
127
146
 
128
- `playbook run <from> [task]` runs one playbook once, without tmux-play
129
- and without an interactive config entry. For example, run REVIEW
130
- directly against the latest commit:
147
+ `playbook run [input]` submits one exact Boss turn to the same Captain that
148
+ the interactive pane hosts, without constructing tmux. The shared config
149
+ selects the Captain, enabled playbooks, players, options, provisioning, and
150
+ readiness; a slash command selects a playbook through Captain, and ordinary
151
+ text remains a conversational Captain turn.
131
152
 
132
153
  ```sh
133
- playbook run @sublang/playbook/review/registry "review the latest commit" \
134
- --player coder=claude --player reviewer=codex --cwd ./my-repo
154
+ cd ./my-repo
155
+ playbook run "/review review the latest commit"
156
+ playbook run "/code implement the approved specification"
157
+ printf '%s\n' 'Summarize the current work and propose the next step.' | playbook run
135
158
  ```
136
159
 
137
- `[task]` is read from stdin when omitted pipe long or multi-line
138
- intents the same way you would to `claude -p` or `codex exec`.
160
+ When `[input]` is absent, stdin is read to EOF as verbatim UTF-8 text.
161
+ Use `--` before one flag-shaped input. Plain stdout is exactly the one
162
+ Boss-visible Captain reply plus a line feed; status and diagnostics use
163
+ stderr, and `--verbose` adds only telemetry topic names to stderr.
164
+ `--json` instead prints exactly `{"sessionId":"…","reply":"…"}`.
139
165
 
140
166
  | Flag | Meaning |
141
167
  | --- | --- |
142
- | `--player <role>=<agent>` | bind a required role |
143
- | `--captain <agent>` | set the captain/judge agent |
144
- | `--option <key>=<value>` | a registry-defined playbook option (none in the current bundled workflows) |
145
- | `--cwd <dir>` | the agents' working directory |
146
- | `--json` | one envelope: `outcome`, `sessionId`, output or questions |
147
- | `--no-provision` | never create engine links beside a filesystem `<from>` |
148
-
149
- `<agent>` is `<adapter>[:<model>][@<effort>]` `codex:gpt-5.5@xhigh`,
150
- or `claude@high` for the default model at high reasoning effort. The
151
- model keeps every interior colon (`opencode:ollama/llama3:8b@max`), and
152
- an unsupported effort is rejected up front naming the adapter's
153
- supported values. Roles and the captain default to `claude` unless the
154
- config supplies [run defaults](configuration.md#defaults-for-playbook-run).
155
-
156
- Exit codes: `0` terminal, `1` bad argument or module, `2` failure, `3`
157
- the playbook needs a Boss reply
168
+ | `--with <path>` | overlay current config for a fresh session or compatible ordinary reopen; repeatable |
169
+ | `--no-provision` | do not create missing engine links for configured filesystem registries |
170
+ | `--json` | print exactly one `sessionId` / `reply` object |
171
+ | `--verbose` | add Captain telemetry topic names to stderr |
172
+ | `--continue` | continue the latest durable Captain session |
173
+ | `--session <id>` | continue one durable Captain session explicitly |
174
+ | `--retry-uncertain` | with `--session`, retry its exact recorded uncertain input |
175
+ | `--discard-uncertain` | with `--session`, abandon its uncertain attempt |
176
+ | `--` | end options before one literal input or reply |
177
+ | `-h`, `--help` | print the complete grammar without reading stdin or config |
178
+
179
+ Exit `0` means the Captain turn and its durable hand-off were presented,
180
+ even when the selected action reported rejection or failure through the
181
+ Captain reply. Argument, config, catalog, readiness, or pre-turn setup errors
182
+ exit `1`; a started-turn, persistence, lease-release, or presentation failure
183
+ exits `2` with stdout empty. SIGINT, SIGTERM, and SIGHUP preserve the
184
+ uncertain boundary, withhold stdout, and are re-raised after lease retirement
158
185
  ([[playbook-cli-18](../specs/packages/playbook-cli.md#playbook-cli-18)]).
159
186
 
160
- ### Engine provisioning
187
+ The former positional `<from>`, `resume`, `--player`, `--captain`,
188
+ `--option`, `--cwd`, `--last`, run-only `--config`, and top-level `run:`
189
+ config are removed from `playbook run`. Enable a registry under `playbooks`,
190
+ declare provider agents once under top-level `players`, bind every local role
191
+ under `playbooks.<id>.roles`, tune compatible model and effort in a `--with`
192
+ overlay, invoke the effective `/command`, and run from the working directory
193
+ you want agents to use. Legacy `playbooks.<id>.players` blocks are rejected and
194
+ are not auto-migrated because choosing equal or distinct new player IDs chooses
195
+ conversation sharing or isolation; see [Migrating per-playbook
196
+ players](configuration.md#migrating-per-playbook-players).
197
+
198
+ ### Piping a Spex update prompt
199
+
200
+ `spex scaffold --update` refreshes its scaffold before printing guidance and
201
+ a fenced reconciliation prompt. Force Spex's non-interactive agent-file
202
+ selection, capture its successful output, extract the first fenced prompt,
203
+ and pass only that prompt to Captain:
204
+
205
+ ```sh
206
+ update_output="$(spex scaffold --update </dev/null)" &&
207
+ printf '%s\n' "$update_output" |
208
+ awk '/^```$/{if (++n==2) exit; next} n==1' |
209
+ playbook run
210
+ ```
211
+
212
+ The capture prevents a failed Spex command from launching Playbook. Without
213
+ `--lang`, the first fenced block is the sole structure reconciliation or
214
+ legacy-migration prompt; a language switch adds a second translation prompt.
215
+
216
+ ### External playbooks and engine provisioning
161
217
 
162
- A compiled playbook module imports `xstate` and
163
- `@sublang/playbook/xstate-runtime` from its own directory. When a
164
- filesystem `<from>` cannot resolve them typically under a global
165
- install with no project-local packages
166
- `playbook run` provisions them automatically before loading: it creates
167
- `node_modules/xstate` and `node_modules/@sublang/playbook` beside the
168
- module as symlinks to the running host's own packages and prints one
169
- line naming what it linked
218
+ Enable an external registry in the shared config and invoke its effective
219
+ slash command; a path-shaped `playbooks.<id>.from` is resolved relative to
220
+ the primary config file. Before either front end imports a configured
221
+ filesystem registry, the shared launcher checks whether that module can
222
+ resolve `xstate` and `@sublang/playbook/xstate-runtime`. When needed, it
223
+ creates engine symlinks beside the module and prints one provisioning line
170
224
  ([[playbook-cli-36](../specs/packages/playbook-cli.md#playbook-cli-36)],
171
225
  [DR-024](../specs/decisions/024-runtime-engine-provisioning.md)).
172
- A directory where the imports already resolve is never touched — a
173
- project-local install always wins — and `--no-provision` disables the
174
- mechanism entirely.
175
226
 
176
- If the module's directory is a git repository, add `node_modules/` to
177
- its `.gitignore` so the provisioned links never land in commits made by
178
- player agents working there.
227
+ A directory where both imports already resolve is untouched, and
228
+ `--no-provision` disables new links for either fresh front end. If the
229
+ module's directory is a git repository, add `node_modules/` to its
230
+ `.gitignore` so provisioned links never enter player commits.
179
231
 
180
- ### Resuming a parked run
232
+ ### Continuing a Captain session
181
233
 
182
- When the playbook stops to ask something, the run is parked, not lost:
183
- the question prints to stdout, the session is saved under
184
- `${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions/`, and stderr
185
- names the command that continues it.
234
+ Interactive and headless commands write the same logical-session records under
235
+ `${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions/`. A fresh interactive
236
+ child persists turn zero before printing `playbook: session <id>` and opening
237
+ Boss input; a fresh headless turn returns the same kind of ID in `--json`.
238
+ After the current writer exits or explicitly hands off, either presentation
239
+ can reopen either origin:
186
240
 
187
241
  ```sh
188
- playbook run resume 4f2c…9ab1 "keep the scope small; skip the docs"
189
- playbook run resume --last # most recently parked session; reply on stdin
242
+ # Reopen the latest settled session headlessly:
243
+ playbook run --continue "keep the scope small; skip the docs"
244
+
245
+ # Reopen one exact session in either presentation:
246
+ playbook --session 4f2c0000-0000-4000-8000-000000009ab1
247
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1
190
248
  ```
191
249
 
192
- A resumed run picks up exactly where it parked same session id, same
193
- workflow state, and each agent continues its own conversation — then
194
- prints the final output and exits `0`, or parks again and exits `3`. The
195
- lineup, options, and working directory are stored with the session, so
196
- `resume` takes no binding flags. In scripts, capture the session id from
197
- the `--json` envelope, like Claude Code's `session_id` or
198
- `codex exec resume`
250
+ A missing headless reply is read verbatim from stdin. Reopening restores the
251
+ compiled Captain conversation, engagement stack, nested child boundary,
252
+ stable-player ledger, and absolute working directory without replaying a
253
+ settled or pending child start. One exclusive writer owns the session, so a
254
+ detached interactive pane child remains the owner until it shuts down; a
255
+ competing front end fails closed instead of forking the history.
256
+
257
+ An ordinary reopen reads current config and any opening `--with` fragments,
258
+ projects them to the stored catalog and player roster, and requires the stored
259
+ role bindings plus every structural setting to remain exact. Compatible
260
+ current `model` and `effort` selections apply to the next call, including an
261
+ explicit boolean `false` provider-default reset. The retained provider token
262
+ is never silently replaced by a fresh conversation if that selection is not
263
+ supported
199
264
  ([[playbook-cli-22](../specs/packages/playbook-cli.md#playbook-cli-22)],
200
- [DR-014](../specs/decisions/014-durable-one-shot-run-sessions.md)).
265
+ [DR-032](../specs/decisions/032-explicit-roles-session-players.md)).
266
+
267
+ ### Recovering an uncertain turn
268
+
269
+ Before model work, the runner takes one exclusive session lease and writes an
270
+ uncertain marker. If the process is interrupted after effects may
271
+ have begun but before settlement is durable, ordinary continuation refuses
272
+ to guess. Choose explicitly:
273
+
274
+ ```sh
275
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --retry-uncertain
276
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --discard-uncertain
277
+ ```
278
+
279
+ Retry reads no input and reuses the byte-exact recorded turn and its exact
280
+ attempted Captain, player, and per-role model/effort selections; current config
281
+ cannot retune that attempt, and retry may duplicate external effects. Discard
282
+ reads no input and runs no model: it restores the exact prior settled boundary,
283
+ or deletes a never-settled fresh session, while abandoning the attempted work.
284
+ An interrupted interactive turn uses the same uncertain record and is
285
+ recovered with these headless commands. Session files written by the removed
286
+ direct v6 runner and legacy record schemas are not shared schema-3 Captain
287
+ sessions and cannot be continued. Explicit selection rejects them. Implicit
288
+ `--continue` reports and skips released schema-2 Captain records, naming each
289
+ session and path; move them outside the sessions directory or remove them to
290
+ silence the warning. Malformed records and unknown schemas still fail closed.