@sublang/playbook 5.0.0 → 7.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 (72) hide show
  1. package/README.md +22 -14
  2. package/docs/cli.md +138 -90
  3. package/docs/configuration.md +113 -29
  4. package/docs/embedding.md +24 -16
  5. package/package.json +42 -21
  6. package/reference/sdlc/captain.playbook/captain.playbook.js +2 -0
  7. package/reference/sdlc/captain.playbook/captain.playbook.ts +2 -0
  8. package/reference/sdlc/code.md +55 -97
  9. package/reference/sdlc/code.playbook/bin/launch-config.js +938 -0
  10. package/reference/sdlc/code.playbook/bin/playbook.js +145 -562
  11. package/reference/sdlc/code.playbook/bin/provision.js +84 -38
  12. package/reference/sdlc/code.playbook/bin/run.js +1171 -983
  13. package/reference/sdlc/code.playbook/bin/session-store.js +1169 -0
  14. package/reference/sdlc/code.playbook/code.fsm.d.ts +229 -94
  15. package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +26 -44
  16. package/reference/sdlc/code.playbook/code.fsm.introspect.js +61 -66
  17. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +100 -149
  18. package/reference/sdlc/code.playbook/code.fsm.js +587 -1347
  19. package/reference/sdlc/code.playbook/code.fsm.ts +809 -1650
  20. package/reference/sdlc/code.playbook/code.gears.md +51 -263
  21. package/reference/sdlc/code.playbook/code.playbook.d.ts +8 -47
  22. package/reference/sdlc/code.playbook/code.playbook.js +69 -656
  23. package/reference/sdlc/code.playbook/code.playbook.ts +90 -867
  24. package/reference/sdlc/code.playbook/code.registry.d.ts +9 -25
  25. package/reference/sdlc/code.playbook/code.registry.js +20 -78
  26. package/reference/sdlc/code.playbook/code.registry.ts +58 -122
  27. package/reference/sdlc/code.playbook/playbook-captain.d.ts +70 -3
  28. package/reference/sdlc/code.playbook/playbook-captain.js +954 -80
  29. package/reference/sdlc/code.playbook/playbook-captain.ts +1408 -80
  30. package/reference/sdlc/code.playbook/playbook.config.template.yaml +37 -36
  31. package/reference/sdlc/decide.md +54 -0
  32. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +261 -0
  33. package/reference/sdlc/decide.playbook/decide.fsm.js +894 -0
  34. package/reference/sdlc/decide.playbook/decide.fsm.ts +1152 -0
  35. package/reference/sdlc/decide.playbook/decide.gears.md +88 -0
  36. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +67 -0
  37. package/reference/sdlc/{discuss.playbook/discuss.playbook.js → decide.playbook/decide.playbook.js} +545 -372
  38. package/reference/sdlc/{discuss.playbook/discuss.playbook.ts → decide.playbook/decide.playbook.ts} +665 -454
  39. package/reference/sdlc/decide.playbook/decide.registry.d.ts +41 -0
  40. package/reference/sdlc/decide.playbook/decide.registry.js +60 -0
  41. package/reference/sdlc/decide.playbook/decide.registry.ts +125 -0
  42. package/reference/sdlc/review.md +81 -0
  43. package/reference/sdlc/review.playbook/review.fsm.d.ts +183 -0
  44. package/reference/sdlc/review.playbook/review.fsm.js +524 -0
  45. package/reference/sdlc/review.playbook/review.fsm.ts +652 -0
  46. package/reference/sdlc/review.playbook/review.gears.md +112 -0
  47. package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -0
  48. package/reference/sdlc/review.playbook/review.playbook.js +112 -0
  49. package/reference/sdlc/review.playbook/review.playbook.ts +201 -0
  50. package/reference/sdlc/review.playbook/review.registry.d.ts +43 -0
  51. package/reference/sdlc/review.playbook/review.registry.js +73 -0
  52. package/reference/sdlc/review.playbook/review.registry.ts +138 -0
  53. package/slc/gears2fsm.md +13 -4
  54. package/slc/link.md +83 -14
  55. package/slc/text2gears.md +22 -2
  56. package/src/runtime.d.ts +21 -2
  57. package/src/runtime.ts +38 -6
  58. package/src/xstate-playbook-runtime.d.ts +9 -2
  59. package/src/xstate-playbook-runtime.js +319 -35
  60. package/src/xstate-playbook-runtime.ts +412 -41
  61. package/src/xstate-runtime.d.ts +19 -2
  62. package/src/xstate-runtime.js +384 -57
  63. package/src/xstate-runtime.ts +542 -71
  64. package/reference/sdlc/discuss.md +0 -93
  65. package/reference/sdlc/discuss.playbook/discuss.fsm.d.ts +0 -396
  66. package/reference/sdlc/discuss.playbook/discuss.fsm.js +0 -2067
  67. package/reference/sdlc/discuss.playbook/discuss.fsm.ts +0 -2465
  68. package/reference/sdlc/discuss.playbook/discuss.gears.md +0 -258
  69. package/reference/sdlc/discuss.playbook/discuss.playbook.d.ts +0 -113
  70. package/reference/sdlc/discuss.playbook/discuss.registry.d.ts +0 -58
  71. package/reference/sdlc/discuss.playbook/discuss.registry.js +0 -97
  72. package/reference/sdlc/discuss.playbook/discuss.registry.ts +0 -153
package/README.md CHANGED
@@ -21,13 +21,14 @@ SubLang Playbook addresses both:
21
21
 
22
22
  Vocabulary: the **Boss** is you; the **Captain** is the coordinating agent you talk to; **players** are the agents a playbook delegates work to.
23
23
 
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.
24
+ 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
25
 
26
26
  ## Quick start
27
27
 
28
- Out of the box, Playbook includes **CODE**, a coding-and-review loop, and **DISCUSS**, in which two agents develop, reconcile, and review a specification.
28
+ 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
+ CODE and DECIDE call REVIEW as a nested playbook.
29
30
 
30
- The interactive starter config uses Claude as both Captain and Coder, and Codex as Reviewer.
31
+ The shared starter config uses Claude as both Captain and Coder, and Codex as Reviewer.
31
32
 
32
33
  ```sh
33
34
  npm install -g @sublang/playbook
@@ -40,10 +41,11 @@ If an SDK is missing or older than cligent supports, Playbook prints the pinned
40
41
  Prerequisites:
41
42
 
42
43
  - Node.js >= 20.6.0
43
- - `tmux` and [`glow`](https://github.com/charmbracelet/glow#installation) on `PATH`
44
44
  - Authenticated [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) or `ANTHROPIC_API_KEY`
45
45
  - Authenticated [Codex CLI](https://github.com/openai/codex) or `OPENAI_API_KEY`
46
46
 
47
+ Interactive `playbook` additionally needs `tmux` and [`glow`](https://github.com/charmbracelet/glow#installation) on `PATH`; headless `playbook run` does not.
48
+
47
49
  CODE works in the current directory and can edit and commit autonomously, so use a clean branch or worktree.
48
50
 
49
51
  ```sh
@@ -51,18 +53,22 @@ cd /path/to/your/project
51
53
  playbook
52
54
  ```
53
55
 
54
- Type a task, or enter `/code <task>` to select CODE directly.
56
+ Type a task, enter `/code <task>` for implementation, or enter
57
+ `/decide <question>` for an independently proposed and reviewed decision.
55
58
 
56
59
  On first launch, Playbook writes its config to `${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`.
57
60
 
58
- One-shot runs use separate defaults instead of the interactive lineup.
59
- Without configured `run` defaults, the Captain and every player use Claude; retain the Codex Reviewer with:
61
+ The same config, compiled Captain, enabled playbooks, players, and nested calls power headless turns.
62
+ Run REVIEW explicitly, or pipe a longer request to Captain:
60
63
 
61
64
  ```sh
62
- playbook run @sublang/playbook/code/registry "add a test for parseArgs" --player reviewer=codex --json
65
+ playbook run "/review review the latest commit"
66
+ printf '%s\n' 'Implement the approved specification, then review it.' | playbook run
63
67
  ```
64
68
 
65
- 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.
69
+ `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.
70
+
71
+ 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.
66
72
 
67
73
  ## Create your own playbook
68
74
 
@@ -71,10 +77,12 @@ The separate [SLC compiler](https://github.com/sublang-ai/slc) requires Node.js
71
77
  ```sh
72
78
  npm install -g @sublang/slc
73
79
  slc playbook my-workflow.md
74
- playbook run ./my-workflow.ts "<your task>"
80
+ # After enabling /absolute/path/to/my-workflow.ts in the shared config:
81
+ playbook run "/my-workflow <your task>"
75
82
  ```
76
83
 
77
- 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.
84
+ SLC writes `my-workflow.ts`, a registry entry ready for Playbook, beside the source, and the inspectable intermediates and tests under `my-workflow.playbook/`.
85
+ 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).
78
86
 
79
87
  ## How it compiles
80
88
 
@@ -85,7 +93,7 @@ SLC's `playbook` pipeline has three phases:
85
93
  3. **FSM → runtime** ([slc/link.md](slc/link.md)) — links the machine to a host-independent interface for user input, agent calls, status, and telemetry.
86
94
 
87
95
  The default [optimization pass](slc/optimize.md) replaces eligible mechanical steps with local shell scripts; `--no-optimize` skips it.
88
- Inspect the complete [Captain](reference/sdlc/captain.md), [CODE](reference/sdlc/code.md), and [DISCUSS](reference/sdlc/discuss.md) examples.
96
+ Inspect the complete [Captain](reference/sdlc/captain.md), [CODE](reference/sdlc/code.md), [REVIEW](reference/sdlc/review.md), and [DECIDE](reference/sdlc/decide.md) examples.
89
97
 
90
98
  ## Contributing
91
99
 
@@ -108,8 +116,8 @@ pnpm playbook # drive a Boss turn against the source tree
108
116
  ```
109
117
 
110
118
  Playbook is itself spec-driven: the compiler phases are specs in [`slc/`](slc), and the reference playbooks are regenerated from their prose sources.
111
- Edit a source, regenerate its GEARS, FSM, and runtime artifacts, sync the tests and downstream specs until `pnpm test` passes, and commit with co-author trailers per [`specs/dev/git.md`](specs/dev/git.md).
112
- The gears↔FSM contract ([the PLAYBOOK dev items](specs/dev/playbook.md)) and the runtime contract ([the PBRT dev items](specs/dev/playbook-runtime.md)) are pinned in [`specs/dev/`](specs/dev) and verified by the test suite.
119
+ Edit a source, regenerate its GEARS, FSM, and runtime artifacts, sync the tests and downstream specs until `pnpm test` passes, and commit with co-author trailers per [`specs/packages/git.md`](specs/packages/git.md).
120
+ The gears↔FSM contract ([the playbook package](specs/packages/playbook.md)) and runtime contract ([the playbook-runtime package](specs/packages/playbook-runtime.md)) are pinned in [`specs/packages/`](specs/packages) and verified by the test suite.
113
121
 
114
122
  ## License
115
123
 
package/docs/cli.md CHANGED
@@ -3,9 +3,10 @@
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.
9
10
 
10
11
  ## Installing agent SDKs
11
12
 
@@ -50,7 +51,7 @@ runtime is reported as not installed; a stale one with its installed
50
51
  and required versions, never as absent. Either way the remedy printed
51
52
  is cligent's pinned install, `npm install -g <package>@<version>`, so
52
53
  following it cannot install a version the gate refuses again
53
- ([PBCLI-40](../specs/user/playbook-cli.md#pbcli-40)).
54
+ ([[playbook-cli-40](../specs/packages/playbook-cli.md#playbook-cli-40)]).
54
55
 
55
56
  ## Interactive
56
57
 
@@ -81,117 +82,164 @@ The command resolves its config (seeding it on first run), composes a
81
82
  `tmux-play` config, checks adapter readiness, and launches. It exits
82
83
  with tmux-play's status, re-raises a terminating signal on itself, and
83
84
  exits `127` when it cannot launch at all
84
- ([PBCLI-1](../specs/user/playbook-cli.md#pbcli-1),
85
- [PBCLI-2](../specs/user/playbook-cli.md#pbcli-2)).
85
+ ([[playbook-cli-1](../specs/packages/playbook-cli.md#playbook-cli-1)],
86
+ [[playbook-cli-2](../specs/packages/playbook-cli.md#playbook-cli-2)]).
86
87
 
87
88
  ### Running a Boss turn
88
89
 
89
90
  The Boss pane starts at the Playbook Captain shell, where the session
90
- Captain runs for the whole session and sees every turn. Use
91
- `/code <task>` to select the CODE playbook explicitly — a registered
92
- command resolves deterministically, with no model call parsing it: at
93
- idle it starts that playbook, at its own leaf it delivers the rest of
94
- the line, an enabled command absent from the active path switches to it,
95
- and a bare `/code` answers with status or a clarification instead of
96
- restarting anything. Type ordinary text and the session Captain decides
97
- the turn instead: it chats back, starts or switches a playbook, hands
98
- the text to the working playbook, dismisses it, or applies one recovery
99
- action the running playbook currently offers. It never does the
100
- specialized work itself, and a conversational turn — including a
101
- progress or status question — leaves the engagement, its parked state,
102
- and any pending player question untouched
103
- ([CAPTAIN-1](../specs/user/playbook-captain.md#captain-1),
104
- [CAPTAIN-2](../specs/user/playbook-captain.md#captain-2)).
105
-
106
- Once a turn reaches CODE, the CODE judge classifies it into an FSM event
107
- start a coding turn, continue or summarize an iteration, interrupt to
108
- a named state, or nothing
109
- ([PBRT-1](../specs/user/playbook-runtime.md#pbrt-1)). When a player
110
- surfaces a clarifying question the FSM parks, the pane shows the
111
- question, and your next turn is normally classified as the reply — a
112
- fresh directive abandons it
113
- ([PBRT-2](../specs/user/playbook-runtime.md#pbrt-2)).
91
+ Captain runs for the whole session and sees every turn. Use `/code`,
92
+ `/review`, or `/decide` followed by a task to select one of the bundled
93
+ playbooks explicitly. A registered command resolves deterministically,
94
+ with no model call parsing it: at idle it starts that playbook, at its
95
+ own leaf it delivers the rest of the line, an enabled command absent
96
+ from the active path switches to it, and a bare command answers with
97
+ status or a clarification instead of restarting anything. Type ordinary
98
+ text and the session Captain decides the turn instead: it chats back,
99
+ starts or switches a playbook, hands the text to the working playbook,
100
+ dismisses it, or applies one recovery action the running playbook
101
+ currently offers. It never does the specialized work itself, and a
102
+ conversational turn — including a progress or status question — leaves
103
+ the engagement, its parked state, and any pending player question
104
+ untouched
105
+ ([[playbook-captain-1](../specs/packages/playbook-captain.md#playbook-captain-1)],
106
+ [[playbook-captain-2](../specs/packages/playbook-captain.md#playbook-captain-2)]).
107
+
108
+ The current CODE, REVIEW, and DECIDE workflows take their deterministic
109
+ initial event from the selecting Boss turn. CODE and DECIDE then call
110
+ REVIEW as a nested playbook: an exact same-name child role continues the
111
+ ancestor's player pane and backend conversation, while any additional
112
+ role uses REVIEW's configured fallback. When a player surfaces a
113
+ clarifying question the FSM parks, the pane shows the question, and a
114
+ judge classifies your next turn as its reply or a fresh directive that
115
+ abandons it
116
+ ([[playbook-runtime-2](../specs/packages/playbook-runtime.md#playbook-runtime-2)]).
114
117
 
115
118
  The Captain pane shows start/stop/finished status with `◇` lines and
116
119
  streams progress with captain-speech classification and questions
117
- ([PBRT-3](../specs/user/playbook-runtime.md#pbrt-3)), while player
120
+ ([[playbook-runtime-3](../specs/packages/playbook-runtime.md#playbook-runtime-3)]), while player
118
121
  prompts ride their own panes. A turn that actually did something ends
119
122
  with one Captain reply summarizing what changed, composed only from that
120
123
  turn's reported outcome; a turn that changed nothing ends with an
121
124
  ordinary reply and no saved-counts line
122
- ([CAPTAIN-19](../specs/user/playbook-captain.md#captain-19)).
125
+ ([[playbook-captain-19](../specs/packages/playbook-captain.md#playbook-captain-19)]).
123
126
 
124
- ## Non-interactive
127
+ ## Headless
125
128
 
126
- `playbook run <from> [task]` runs one playbook once, without tmux-play
127
- and without a config entry point it straight at a registry module:
129
+ `playbook run [input]` submits one exact Boss turn to the same Captain that
130
+ the interactive pane hosts, without constructing tmux. The shared config
131
+ selects the Captain, enabled playbooks, players, options, provisioning, and
132
+ readiness; a slash command selects a playbook through Captain, and ordinary
133
+ text remains a conversational Captain turn.
128
134
 
129
135
  ```sh
130
- playbook run @sublang/playbook/code/registry "add a test for parseArgs" \
131
- --player coder=claude --player reviewer=codex --cwd ./my-repo
136
+ cd ./my-repo
137
+ playbook run "/review review the latest commit"
138
+ playbook run "/code implement the approved specification"
139
+ printf '%s\n' 'Summarize the current work and propose the next step.' | playbook run
132
140
  ```
133
141
 
134
- `[task]` is read from stdin when omitted pipe long or multi-line
135
- intents the same way you would to `claude -p` or `codex exec`.
142
+ When `[input]` is absent, stdin is read to EOF as verbatim UTF-8 text.
143
+ Use `--` before one flag-shaped input. Plain stdout is exactly the one
144
+ Boss-visible Captain reply plus a line feed; status and diagnostics use
145
+ stderr, and `--verbose` adds only telemetry topic names to stderr.
146
+ `--json` instead prints exactly `{"sessionId":"…","reply":"…"}`.
136
147
 
137
148
  | Flag | Meaning |
138
149
  | --- | --- |
139
- | `--player <role>=<agent>` | bind a required role |
140
- | `--captain <agent>` | set the captain/judge agent |
141
- | `--option <key>=<value>` | a playbook option (CODE's `committer`) |
142
- | `--cwd <dir>` | the agents' working directory |
143
- | `--json` | one envelope: `outcome`, `sessionId`, output or questions |
144
- | `--no-provision` | never create engine links beside a filesystem `<from>` |
145
-
146
- `<agent>` is `<adapter>[:<model>][@<effort>]` `codex:gpt-5.5@xhigh`,
147
- or `claude@high` for the default model at high reasoning effort. The
148
- model keeps every interior colon (`opencode:ollama/llama3:8b@max`), and
149
- an unsupported effort is rejected up front naming the adapter's
150
- supported values. Roles and the captain default to `claude` unless the
151
- config supplies [run defaults](configuration.md#defaults-for-playbook-run).
152
-
153
- Exit codes: `0` terminal, `1` bad argument or module, `2` failure, `3`
154
- the playbook needs a Boss reply
155
- ([PBCLI-18](../specs/user/playbook-cli.md#pbcli-18)).
156
-
157
- ### Engine provisioning
158
-
159
- A compiled playbook module imports `xstate` and
160
- `@sublang/playbook/xstate-runtime` from its own directory. When a
161
- filesystem `<from>` cannot resolve them typically under a global
162
- install with no project-local packages
163
- `playbook run` provisions them automatically before loading: it creates
164
- `node_modules/xstate` and `node_modules/@sublang/playbook` beside the
165
- module as symlinks to the running host's own packages and prints one
166
- line naming what it linked
167
- ([PBCLI-36](../specs/user/playbook-cli.md#pbcli-36),
150
+ | `--with <path>` | overlay the shared config for a new session; repeatable |
151
+ | `--no-provision` | do not create missing engine links for configured filesystem registries |
152
+ | `--json` | print exactly one `sessionId` / `reply` object |
153
+ | `--verbose` | add Captain telemetry topic names to stderr |
154
+ | `--continue` | continue the latest durable Captain session |
155
+ | `--session <id>` | continue one durable Captain session explicitly |
156
+ | `--retry-uncertain` | with `--session`, retry its exact recorded uncertain input |
157
+ | `--discard-uncertain` | with `--session`, abandon its uncertain attempt |
158
+ | `--` | end options before one literal input or reply |
159
+ | `-h`, `--help` | print the complete grammar without reading stdin or config |
160
+
161
+ Exit `0` means the Captain turn and its durable hand-off were presented,
162
+ even when the selected action reported rejection or failure through the
163
+ Captain reply. Argument, config, catalog, readiness, or pre-turn setup errors
164
+ exit `1`; a started-turn, persistence, lease-release, or presentation failure
165
+ exits `2` with stdout empty. SIGINT, SIGTERM, and SIGHUP preserve the
166
+ uncertain boundary, withhold stdout, and are re-raised after lease retirement
167
+ ([[playbook-cli-18](../specs/packages/playbook-cli.md#playbook-cli-18)]).
168
+
169
+ The former positional `<from>`, `resume`, `--player`, `--captain`,
170
+ `--option`, `--cwd`, `--last`, run-only `--config`, and top-level `run:`
171
+ config are removed. Enable a registry under `playbooks`, tune its inline
172
+ agents and options there or in a fresh `--with` overlay, invoke its effective
173
+ `/command`, and run from the working directory you want agents to use.
174
+
175
+ ### Piping a Spex update prompt
176
+
177
+ `spex scaffold --update` refreshes its scaffold before printing guidance and
178
+ a fenced reconciliation prompt. Force Spex's non-interactive agent-file
179
+ selection, capture its successful output, extract the first fenced prompt,
180
+ and pass only that prompt to Captain:
181
+
182
+ ```sh
183
+ update_output="$(spex scaffold --update </dev/null)" &&
184
+ printf '%s\n' "$update_output" |
185
+ awk '/^```$/{if (++n==2) exit; next} n==1' |
186
+ playbook run
187
+ ```
188
+
189
+ The capture prevents a failed Spex command from launching Playbook. Without
190
+ `--lang`, the first fenced block is the sole structure reconciliation or
191
+ legacy-migration prompt; a language switch adds a second translation prompt.
192
+
193
+ ### External playbooks and engine provisioning
194
+
195
+ Enable an external registry in the shared config and invoke its effective
196
+ slash command; a path-shaped `playbooks.<id>.from` is resolved relative to
197
+ the primary config file. Before either front end imports a configured
198
+ filesystem registry, the shared launcher checks whether that module can
199
+ resolve `xstate` and `@sublang/playbook/xstate-runtime`. When needed, it
200
+ creates engine symlinks beside the module and prints one provisioning line
201
+ ([[playbook-cli-36](../specs/packages/playbook-cli.md#playbook-cli-36)],
168
202
  [DR-024](../specs/decisions/024-runtime-engine-provisioning.md)).
169
- A directory where the imports already resolve is never touched — a
170
- project-local install always wins — and `--no-provision` disables the
171
- mechanism entirely.
172
203
 
173
- If the module's directory is a git repository, add `node_modules/` to
174
- its `.gitignore` so the provisioned links never land in commits made by
175
- player agents working there.
204
+ A directory where both imports already resolve is untouched, and
205
+ `--no-provision` disables new links for either fresh front end. If the
206
+ module's directory is a git repository, add `node_modules/` to its
207
+ `.gitignore` so provisioned links never enter player commits.
208
+
209
+ ### Continuing a Captain session
210
+
211
+ Every successfully presented headless turn is stored under
212
+ `${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions/` before stdout.
213
+ Continue the newest logical session, or select the id returned by `--json`:
214
+
215
+ ```sh
216
+ playbook run --continue "keep the scope small; skip the docs"
217
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1
218
+ ```
219
+
220
+ A missing reply is read verbatim from stdin. Continuation restores the exact
221
+ compiled Captain conversation, engagement stack, nested child boundary,
222
+ mapped-player conversations, normalized execution config, and absolute
223
+ working directory. It does not reread current config, does not repeat a
224
+ settled or pending child start, and rejects `--with` because an existing
225
+ session's lineup is frozen
226
+ ([[playbook-cli-22](../specs/packages/playbook-cli.md#playbook-cli-22)],
227
+ [DR-031](../specs/decisions/031-shared-captain-session-front-ends.md)).
176
228
 
177
- ### Resuming a parked run
229
+ ### Recovering an uncertain turn
178
230
 
179
- When the playbook stops to ask something, the run is parked, not lost:
180
- the question prints to stdout, the session is saved under
181
- `${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions/`, and stderr
182
- names the command that continues it.
231
+ Before model work, the runner takes one exclusive session lease and writes an
232
+ uncertain marker. If the process is interrupted after effects may
233
+ have begun but before settlement is durable, ordinary continuation refuses
234
+ to guess. Choose explicitly:
183
235
 
184
236
  ```sh
185
- playbook run resume 4f2c…9ab1 "keep the scope small; skip the docs"
186
- playbook run resume --last # most recently parked session; reply on stdin
237
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --retry-uncertain
238
+ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --discard-uncertain
187
239
  ```
188
240
 
189
- A resumed run picks up exactly where it parked same session id, same
190
- workflow state, and each agent continues its own conversation then
191
- prints the final output and exits `0`, or parks again and exits `3`. The
192
- lineup, options, and working directory are stored with the session, so
193
- `resume` takes no binding flags. In scripts, capture the session id from
194
- the `--json` envelope, like Claude Code's `session_id` or
195
- `codex exec resume`
196
- ([PBCLI-22](../specs/user/playbook-cli.md#pbcli-22),
197
- [DR-014](../specs/decisions/014-durable-one-shot-run-sessions.md)).
241
+ Retry reads no input and reuses the byte-exact recorded turn; it may duplicate
242
+ external effects. Discard reads no input and runs no model: it restores the
243
+ exact prior settled boundary, or deletes a never-settled fresh session, while
244
+ abandoning the attempted work. Session files written by the removed direct
245
+ v6 runner are not shared-Captain sessions and cannot be continued.
@@ -3,7 +3,7 @@
3
3
 
4
4
  # Configuring agents
5
5
 
6
- `playbook` reads one config at
6
+ `playbook` and every fresh `playbook run` read one config at
7
7
  `${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`. The
8
8
  first launch seeds it from the bundled starter and prints the path;
9
9
  later launches reuse it untouched.
@@ -16,9 +16,10 @@ $EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml"
16
16
 
17
17
  The config is top-level (no `config:` wrapper): a `captain` agent (it
18
18
  runs the session Captain's hidden control calls, the hidden judge calls,
19
- and the replies you see in the Captain pane), optional
19
+ and the replies you see in the Captain pane or on headless stdout), optional
20
20
  `layout` / `notifications` / `theme`, and a `playbooks` map of enabled
21
- playbooks.
21
+ playbooks. Those three presentation fields apply only to interactive tmux;
22
+ headless runs ignore them.
22
23
 
23
24
  Each `captain` or `players.<role>` value is either an adapter shorthand
24
25
  (`claude`, `codex`) or a block carrying that agent's own `adapter`,
@@ -33,8 +34,8 @@ Within a `playbooks.<id>` block, `from` (the registry module), `command`
33
34
  every other key is that playbook's option slice. The launcher injects
34
35
  the rest — you do not write host wiring by hand.
35
36
 
36
- The seeded config runs the Coder on Claude Opus 4.8 1m and the Reviewer
37
- on GPT-5.5:
37
+ The seeded config runs each Coder on Claude Opus 4.8 1m and each
38
+ Reviewer on GPT-5.5:
38
39
 
39
40
  ```yaml
40
41
  captain:
@@ -54,6 +55,16 @@ playbooks:
54
55
  effort: xhigh
55
56
  permissions:
56
57
  mode: auto # protected auto mode for the Claude Coder
58
+
59
+ review:
60
+ from: '@sublang/playbook/review/registry'
61
+ players:
62
+ coder:
63
+ adapter: claude
64
+ model: claude-opus-4-8[1m]
65
+ effort: xhigh
66
+ permissions:
67
+ mode: auto
57
68
  reviewer:
58
69
  adapter: codex
59
70
  model: gpt-5.5
@@ -62,15 +73,47 @@ playbooks:
62
73
  mode: auto
63
74
  writablePaths:
64
75
  - .git # allow git metadata writes under Codex auto mode
65
- committer: coder # which role commits — `coder` or `reviewer`
76
+
77
+ decide:
78
+ from: '@sublang/playbook/decide/registry'
79
+ players:
80
+ coder:
81
+ adapter: claude
82
+ model: claude-opus-4-8[1m]
83
+ effort: xhigh
84
+ permissions:
85
+ mode: auto
86
+ reviewer:
87
+ adapter: codex
88
+ model: gpt-5.5
89
+ effort: xhigh
90
+ permissions:
91
+ mode: auto
92
+ writablePaths:
93
+ - .git
66
94
  ```
67
95
 
68
- `committer` is CODE's one option: an alias naming which role runs the
69
- commit turn (fallback semantics:
70
- [PBRT-8](../specs/dev/playbook-runtime.md#pbrt-8)). Each role's per-run
71
- prompt names its pinned `model`, else its `adapter`
72
- ([PBRT-4](../specs/user/playbook-runtime.md#pbrt-4)), so commit trailers
73
- credit the concrete model rather than the adapter family.
96
+ The current bundled workflows accept no workflow-specific options.
97
+ Each role's per-run prompt names its pinned `model`, else its `adapter`
98
+ ([[playbook-runtime-4](../specs/packages/playbook-runtime.md#playbook-runtime-4)]),
99
+ so commit trailers credit the concrete model rather than the adapter
100
+ family.
101
+
102
+ ## Nested roles and sessions
103
+
104
+ The launcher creates a namespaced fallback player for every configured
105
+ playbook role, but a nested call maps an exact same-name role to the
106
+ nearest ancestor's effective player and backend conversation. CODE's
107
+ nested REVIEW therefore continues CODE's `coder` and uses REVIEW's
108
+ configured `reviewer`; DECIDE's nested REVIEW continues both of
109
+ DECIDE's roles. A standalone REVIEW starts with REVIEW's own configured
110
+ players, and every new root engagement starts fresh
111
+ ([DR-030](../specs/decisions/030-shared-mapped-player-continuity.md)).
112
+
113
+ The separate fallback entries are still required because tmux creates
114
+ its roster at launch time. The host changes which existing panes are
115
+ visible as the active nested leaf changes; it does not create a new
116
+ host player or backend agent session for a mapped role.
74
117
 
75
118
  ## Choosing the Captain agent
76
119
 
@@ -80,7 +123,7 @@ instead of doing the work itself. Claude enforces
80
123
  that at the provider level. The Codex adapter cannot — it rejects any
81
124
  tool list — so a `captain:` on `codex` falls back to a prompt-level
82
125
  restriction
83
- ([DR-013 A1](../specs/decisions/013-routing-only-captain-control.md#addendum-a1-prompt-level-isolation-for-adapters-without-tool-enforcement)).
126
+ ([DR-013](../specs/decisions/013-routing-only-captain-control.md) A1).
84
127
  Codex remains a good choice for *players*, where full tools are wanted.
85
128
 
86
129
  Adapter readiness is intentionally light: `claude` is ready with local
@@ -96,6 +139,7 @@ recursively, other values replace):
96
139
 
97
140
  ```sh
98
141
  playbook --with fast-lineup.yaml
142
+ playbook run --with fast-lineup.yaml "/code implement the approved change"
99
143
  ```
100
144
 
101
145
  ```yaml
@@ -109,8 +153,8 @@ playbooks:
109
153
  effort: medium
110
154
  permissions:
111
155
  mode: auto
112
- # The seeded `committer` is `coder`, so this role runs the commit
113
- # turn; a Codex agent needs the `.git` grant to write git metadata.
156
+ # CODE's Coder commits, so Codex needs the `.git` grant to write
157
+ # repository metadata.
114
158
  writablePaths:
115
159
  - .git
116
160
  ```
@@ -122,25 +166,65 @@ role switched to `codex` needs its own `writablePaths` grant, because
122
166
  the base Claude block had no reason to carry one.
123
167
 
124
168
  The global file is never modified, and `--with` is not forwarded to
125
- `tmux-play` ([PBCLI-25](../specs/user/playbook-cli.md#pbcli-25)).
169
+ `tmux-play` ([[playbook-cli-25](../specs/packages/playbook-cli.md#playbook-cli-25)]).
170
+ Overlays apply only when creating a fresh session. A continued headless
171
+ session restores its frozen config and working directory and rejects `--with`.
126
172
 
127
- ## Defaults for `playbook run`
173
+ ## Shared headless configuration
128
174
 
129
- An optional top-level `run` block supplies the non-interactive host's
130
- lineup so you stop retyping flags `run.captain`, `run.players.<role>`,
131
- and a `run.player` catch-all for any other required role, each an
132
- `<adapter>[:<model>][@<effort>]` string. Flags win per role, and
133
- `resume` always keeps the lineup stored with the parked session
134
- ([PBCLI-28](../specs/user/playbook-cli.md#pbcli-28),
135
- [DR-017](../specs/decisions/017-run-defaults-config.md)).
175
+ Fresh interactive and headless sessions use the same top-level `captain`
176
+ and `playbooks` blocks. A headless session retains the normalized lineup,
177
+ catalog, options, and absolute working directory with every durable turn;
178
+ continuation does not reread the current file. Presentation-only fields are
179
+ inert headlessly.
180
+
181
+ ## External playbooks
182
+
183
+ `slc playbook my-workflow.md` emits `my-workflow.ts` beside its artifact
184
+ directory. That file already default-exports the registry manifest Playbook
185
+ requires: `id`, `command`, `intent`, `requiredRoleIds`, `validateOptions`,
186
+ and `createRuntime`. Enable it under `playbooks`, bind every role listed in
187
+ its `requiredRoleIds`, and invoke its effective slash command through Captain:
136
188
 
137
189
  ```yaml
138
- run:
139
- captain: claude:claude-opus-4-8@high
140
- players:
141
- coder: claude:claude-opus-4-8[1m]@xhigh
190
+ playbooks:
191
+ my-workflow:
192
+ from: /absolute/path/to/my-workflow.ts
193
+ players:
194
+ worker: claude
142
195
  ```
143
196
 
197
+ ```sh
198
+ playbook run "/my-workflow perform the task"
199
+ ```
200
+
201
+ A relative path-shaped `from` is resolved relative to the primary config
202
+ file, not the invocation directory; an absolute path is clearest for an SLC
203
+ entry emitted in a project working tree.
204
+ Before either front end imports a filesystem registry, the shared launcher
205
+ checks and, unless `--no-provision` is set, provisions its runtime engine
206
+ links as described in [Using the CLI](cli.md#external-playbooks-and-engine-provisioning).
207
+
208
+ ## Migrating direct runs from 6.x
209
+
210
+ The top-level `run:` block is deliberately rejected rather than silently
211
+ ignored or rewritten, because doing otherwise could change the agents after
212
+ an upgrade. Re-express `run.captain`, `run.players`, and former `--player`
213
+ bindings as the inline agent blocks above; the old `run.player` catch-all has
214
+ no shared equivalent, so configure every required role explicitly at
215
+ `playbooks.<id>.players.<role>`. Use a fresh `--with` fragment for temporary
216
+ lineup changes. Move former `--option` values into their `playbooks.<id>`
217
+ block, run from the desired directory instead of passing `--cwd`, enable a
218
+ former positional `<from>` as a configured registry, and quote or pipe one
219
+ `/command task` Boss message. Replace `resume` and `--last` with `--continue`
220
+ or `--session`.
221
+
222
+ The JSON response is now exactly `{ "sessionId": "…", "reply": "…" }`.
223
+ Released direct-run session records are not complete Captain sessions and
224
+ cannot be continued by the new host ([[playbook-cli-19](../specs/packages/playbook-cli.md#playbook-cli-19)],
225
+ [[playbook-cli-22](../specs/packages/playbook-cli.md#playbook-cli-22)],
226
+ [[playbook-cli-28](../specs/packages/playbook-cli.md#playbook-cli-28)]).
227
+
144
228
  ## Migrating from `profiles`
145
229
 
146
230
  Configs written before 3.0.0 carried a top-level `profiles` map. The
@@ -153,7 +237,7 @@ do by hand.
153
237
 
154
238
  For a one-off, pass a raw `tmux-play` config explicitly. This bypasses
155
239
  the seed, composition, and readiness gate, forwarding arguments to
156
- `tmux-play` verbatim ([PBCLI-1](../specs/user/playbook-cli.md#pbcli-1)):
240
+ `tmux-play` verbatim ([[playbook-cli-1](../specs/packages/playbook-cli.md#playbook-cli-1)]):
157
241
 
158
242
  ```sh
159
243
  playbook --config ./tmux-play.config.yaml