@sublang/playbook 7.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.
- package/README.md +17 -4
- package/docs/cli.md +74 -29
- package/docs/configuration.md +209 -112
- package/docs/embedding.md +71 -25
- package/package.json +4 -3
- package/reference/sdlc/captain.playbook/captain.playbook.js +3 -3
- package/reference/sdlc/captain.playbook/captain.playbook.ts +3 -3
- package/reference/sdlc/code.md +1 -1
- package/reference/sdlc/code.playbook/bin/interactive-session.js +816 -0
- package/reference/sdlc/code.playbook/bin/launch-config.js +1078 -116
- package/reference/sdlc/code.playbook/bin/playbook.js +489 -34
- package/reference/sdlc/code.playbook/bin/run.js +283 -298
- package/reference/sdlc/code.playbook/bin/session-store.js +818 -26
- package/reference/sdlc/code.playbook/code.fsm.d.ts +5 -5
- package/reference/sdlc/code.playbook/code.fsm.introspect.js +2 -2
- package/reference/sdlc/code.playbook/code.fsm.introspect.ts +2 -2
- package/reference/sdlc/code.playbook/code.fsm.js +7 -11
- package/reference/sdlc/code.playbook/code.fsm.ts +9 -17
- package/reference/sdlc/code.playbook/code.gears.md +1 -1
- package/reference/sdlc/code.playbook/code.playbook.d.ts +2 -1
- package/reference/sdlc/code.playbook/code.playbook.js +12 -13
- package/reference/sdlc/code.playbook/code.playbook.ts +22 -15
- package/reference/sdlc/code.playbook/code.registry.d.ts +5 -13
- package/reference/sdlc/code.playbook/code.registry.js +3 -10
- package/reference/sdlc/code.playbook/code.registry.ts +7 -32
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +39 -14
- package/reference/sdlc/code.playbook/playbook-captain.js +970 -289
- package/reference/sdlc/code.playbook/playbook-captain.ts +1403 -396
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +41 -49
- package/reference/sdlc/decide.md +4 -4
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +9 -9
- package/reference/sdlc/decide.playbook/decide.fsm.js +21 -14
- package/reference/sdlc/decide.playbook/decide.fsm.ts +27 -23
- package/reference/sdlc/decide.playbook/decide.gears.md +3 -5
- package/reference/sdlc/decide.playbook/decide.playbook.d.ts +9 -13
- package/reference/sdlc/decide.playbook/decide.playbook.js +171 -134
- package/reference/sdlc/decide.playbook/decide.playbook.ts +238 -162
- package/reference/sdlc/decide.playbook/decide.registry.d.ts +5 -13
- package/reference/sdlc/decide.playbook/decide.registry.js +3 -9
- package/reference/sdlc/decide.playbook/decide.registry.ts +7 -31
- package/reference/sdlc/review.md +4 -5
- package/reference/sdlc/review.playbook/review.fsm.d.ts +9 -11
- package/reference/sdlc/review.playbook/review.fsm.js +30 -24
- package/reference/sdlc/review.playbook/review.fsm.ts +39 -35
- package/reference/sdlc/review.playbook/review.gears.md +6 -5
- package/reference/sdlc/review.playbook/review.playbook.d.ts +2 -1
- package/reference/sdlc/review.playbook/review.playbook.js +16 -21
- package/reference/sdlc/review.playbook/review.playbook.ts +26 -26
- package/reference/sdlc/review.playbook/review.registry.d.ts +5 -13
- package/reference/sdlc/review.playbook/review.registry.js +3 -16
- package/reference/sdlc/review.playbook/review.registry.ts +7 -38
- package/slc/gears2fsm.md +27 -23
- package/slc/link.md +113 -93
- package/slc/text2gears.md +19 -18
- package/src/runtime.d.ts +20 -16
- package/src/runtime.ts +19 -23
- package/src/xstate-playbook-runtime.d.ts +21 -17
- package/src/xstate-playbook-runtime.js +241 -149
- package/src/xstate-playbook-runtime.ts +331 -178
- package/src/xstate-runtime.js +63 -24
- package/src/xstate-runtime.ts +96 -28
package/README.md
CHANGED
|
@@ -19,7 +19,11 @@ SubLang Playbook addresses both:
|
|
|
19
19
|
|
|
20
20
|

|
|
21
21
|
|
|
22
|
-
Vocabulary: the **Boss** is you; the **Captain** is the coordinating agent you
|
|
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
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
|
|
|
@@ -28,7 +32,10 @@ Run `playbook` for an interactive tmux UI powered by [cligent](https://github.co
|
|
|
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 shared starter config uses Claude as both Captain and
|
|
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
|
|
@@ -44,7 +51,7 @@ Prerequisites:
|
|
|
44
51
|
- Authenticated [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) or `ANTHROPIC_API_KEY`
|
|
45
52
|
- Authenticated [Codex CLI](https://github.com/openai/codex) or `OPENAI_API_KEY`
|
|
46
53
|
|
|
47
|
-
Interactive `playbook` additionally needs
|
|
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.
|
|
48
55
|
|
|
49
56
|
CODE works in the current directory and can edit and commit autonomously, so use a clean branch or worktree.
|
|
50
57
|
|
|
@@ -58,12 +65,18 @@ Type a task, enter `/code <task>` for implementation, or enter
|
|
|
58
65
|
|
|
59
66
|
On first launch, Playbook writes its config to `${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml`.
|
|
60
67
|
|
|
61
|
-
The same config, compiled Captain, enabled playbooks, players, and
|
|
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.
|
|
62
72
|
Run REVIEW explicitly, or pipe a longer request to Captain:
|
|
63
73
|
|
|
64
74
|
```sh
|
|
65
75
|
playbook run "/review review the latest commit"
|
|
66
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"
|
|
67
80
|
```
|
|
68
81
|
|
|
69
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.
|
package/docs/cli.md
CHANGED
|
@@ -8,6 +8,9 @@ interactive tmux-play UI and a headless `playbook run` turn for scripts and
|
|
|
8
8
|
CI. Both use the same compiled Captain, enabled catalog, players, nested
|
|
9
9
|
stack, and [config](configuration.md); only presentation differs.
|
|
10
10
|
|
|
11
|
+
The interactive form requires tmux 3.3 or newer and `glow` on `PATH`;
|
|
12
|
+
the headless form requires neither presentation tool.
|
|
13
|
+
|
|
11
14
|
## Installing agent SDKs
|
|
12
15
|
|
|
13
16
|
Each adapter is backed by a vendor runtime that installing
|
|
@@ -56,9 +59,11 @@ following it cannot install a version the gate refuses again
|
|
|
56
59
|
## Interactive
|
|
57
60
|
|
|
58
61
|
```sh
|
|
59
|
-
playbook
|
|
60
|
-
playbook --
|
|
61
|
-
playbook --
|
|
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
|
|
62
67
|
```
|
|
63
68
|
|
|
64
69
|
Without a global install, `npx` runs the same bin — but name each
|
|
@@ -78,10 +83,21 @@ already present, since each distinct package set is a distinct tree —
|
|
|
78
83
|
and replaying your original arguments, so the printed command works in
|
|
79
84
|
one hop.
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
85
101
|
([[playbook-cli-1](../specs/packages/playbook-cli.md#playbook-cli-1)],
|
|
86
102
|
[[playbook-cli-2](../specs/packages/playbook-cli.md#playbook-cli-2)]).
|
|
87
103
|
|
|
@@ -106,10 +122,12 @@ untouched
|
|
|
106
122
|
[[playbook-captain-2](../specs/packages/playbook-captain.md#playbook-captain-2)]).
|
|
107
123
|
|
|
108
124
|
The current CODE, REVIEW, and DECIDE workflows take their deterministic
|
|
109
|
-
initial event from the selecting Boss turn. CODE and DECIDE then call
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
113
131
|
clarifying question the FSM parks, the pane shows the question, and a
|
|
114
132
|
judge classifies your next turn as its reply or a fresh directive that
|
|
115
133
|
abandons it
|
|
@@ -147,7 +165,7 @@ stderr, and `--verbose` adds only telemetry topic names to stderr.
|
|
|
147
165
|
|
|
148
166
|
| Flag | Meaning |
|
|
149
167
|
| --- | --- |
|
|
150
|
-
| `--with <path>` | overlay
|
|
168
|
+
| `--with <path>` | overlay current config for a fresh session or compatible ordinary reopen; repeatable |
|
|
151
169
|
| `--no-provision` | do not create missing engine links for configured filesystem registries |
|
|
152
170
|
| `--json` | print exactly one `sessionId` / `reply` object |
|
|
153
171
|
| `--verbose` | add Captain telemetry topic names to stderr |
|
|
@@ -168,9 +186,14 @@ uncertain boundary, withhold stdout, and are re-raised after lease retirement
|
|
|
168
186
|
|
|
169
187
|
The former positional `<from>`, `resume`, `--player`, `--captain`,
|
|
170
188
|
`--option`, `--cwd`, `--last`, run-only `--config`, and top-level `run:`
|
|
171
|
-
config are removed
|
|
172
|
-
|
|
173
|
-
|
|
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).
|
|
174
197
|
|
|
175
198
|
### Piping a Spex update prompt
|
|
176
199
|
|
|
@@ -208,23 +231,38 @@ module's directory is a git repository, add `node_modules/` to its
|
|
|
208
231
|
|
|
209
232
|
### Continuing a Captain session
|
|
210
233
|
|
|
211
|
-
|
|
212
|
-
`${XDG_STATE_HOME:-$HOME/.local/state}/playbook/sessions
|
|
213
|
-
|
|
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:
|
|
214
240
|
|
|
215
241
|
```sh
|
|
242
|
+
# Reopen the latest settled session headlessly:
|
|
216
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
|
|
217
247
|
playbook run --session 4f2c0000-0000-4000-8000-000000009ab1
|
|
218
248
|
```
|
|
219
249
|
|
|
220
|
-
A missing reply is read verbatim from stdin.
|
|
250
|
+
A missing headless reply is read verbatim from stdin. Reopening restores the
|
|
221
251
|
compiled Captain conversation, engagement stack, nested child boundary,
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
|
226
264
|
([[playbook-cli-22](../specs/packages/playbook-cli.md#playbook-cli-22)],
|
|
227
|
-
[DR-
|
|
265
|
+
[DR-032](../specs/decisions/032-explicit-roles-session-players.md)).
|
|
228
266
|
|
|
229
267
|
### Recovering an uncertain turn
|
|
230
268
|
|
|
@@ -238,8 +276,15 @@ playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --retry-uncertain
|
|
|
238
276
|
playbook run --session 4f2c0000-0000-4000-8000-000000009ab1 --discard-uncertain
|
|
239
277
|
```
|
|
240
278
|
|
|
241
|
-
Retry reads no input and reuses the byte-exact recorded turn
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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.
|
package/docs/configuration.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# Configuring agents
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Fresh launches and ordinary reopens 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.
|
|
@@ -14,28 +14,35 @@ $EDITOR "${XDG_CONFIG_HOME:-$HOME/.config}/playbook/playbook.config.yaml"
|
|
|
14
14
|
|
|
15
15
|
## Anatomy
|
|
16
16
|
|
|
17
|
-
The config is top-level (no `config:` wrapper): a `captain` agent
|
|
18
|
-
|
|
19
|
-
and
|
|
20
|
-
`
|
|
21
|
-
|
|
22
|
-
headless runs ignore them.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
`
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
17
|
+
The config is top-level (no `config:` wrapper): a `captain` agent, one flat
|
|
18
|
+
`players` map of stable Captain-session agents, a `playbooks` map of enabled
|
|
19
|
+
workflows and their explicit role bindings, and optional `layout` /
|
|
20
|
+
`notifications` / `theme`. The Captain runs hidden control and judge calls and
|
|
21
|
+
writes the replies you see in the Captain pane or on headless stdout. The three
|
|
22
|
+
presentation fields apply only to interactive tmux; headless runs ignore them.
|
|
23
|
+
|
|
24
|
+
A **role** is local to a playbook artifact: CODE's `coder` and REVIEW's `coder`
|
|
25
|
+
have the same semantic name but remain separate declarations. A **player** is
|
|
26
|
+
a stable session-wide provider conversation with an exact ID such as
|
|
27
|
+
`dev.coder`. A role uses only the player named by its binding; matching role
|
|
28
|
+
names, nesting, and ancestry never infer a binding.
|
|
29
|
+
|
|
30
|
+
Each `captain` or `players.<player-id>` value is either an adapter shorthand
|
|
31
|
+
(`claude`, `codex`) or a block carrying that agent's own `adapter`, `model`,
|
|
32
|
+
`effort`, `instruction`, and `permissions`. Settings are inline per stable
|
|
33
|
+
agent ([DR-021](../specs/decisions/021-inline-agent-settings.md)). Dots in a
|
|
34
|
+
player ID are literal characters, not YAML hierarchy. Other adapter IDs pass
|
|
35
|
+
through to `tmux-play` with a warning because `playbook` cannot preflight their
|
|
36
|
+
auth.
|
|
37
|
+
|
|
38
|
+
Within a `playbooks.<id>` block, `from` (the registry module), `command` (an
|
|
39
|
+
optional slash-command override), and `roles` are launcher-owned; every other
|
|
40
|
+
key is that playbook's option slice. Every manifest role must be present
|
|
41
|
+
exactly once. The launcher injects the rest — you do not write host wiring by
|
|
42
|
+
hand.
|
|
43
|
+
|
|
44
|
+
The seeded config runs the stable Coder player on Claude Opus 4.8 1m and the
|
|
45
|
+
stable Reviewer player on GPT-5.5:
|
|
39
46
|
|
|
40
47
|
```yaml
|
|
41
48
|
captain:
|
|
@@ -45,86 +52,116 @@ captain:
|
|
|
45
52
|
permissions:
|
|
46
53
|
mode: auto # protected auto mode for the Claude Captain
|
|
47
54
|
|
|
55
|
+
players:
|
|
56
|
+
dev.coder:
|
|
57
|
+
adapter: claude
|
|
58
|
+
model: claude-opus-4-8[1m]
|
|
59
|
+
effort: xhigh
|
|
60
|
+
permissions:
|
|
61
|
+
mode: auto # protected auto mode for the Claude Coder
|
|
62
|
+
|
|
63
|
+
dev.reviewer:
|
|
64
|
+
adapter: codex
|
|
65
|
+
model: gpt-5.5
|
|
66
|
+
effort: xhigh
|
|
67
|
+
permissions:
|
|
68
|
+
mode: auto
|
|
69
|
+
writablePaths:
|
|
70
|
+
- .git # allow git metadata writes under Codex auto mode
|
|
71
|
+
|
|
48
72
|
playbooks:
|
|
49
73
|
code:
|
|
50
74
|
from: '@sublang/playbook/code/registry'
|
|
51
|
-
|
|
52
|
-
coder:
|
|
53
|
-
adapter: claude
|
|
54
|
-
model: claude-opus-4-8[1m]
|
|
55
|
-
effort: xhigh
|
|
56
|
-
permissions:
|
|
57
|
-
mode: auto # protected auto mode for the Claude Coder
|
|
75
|
+
roles:
|
|
76
|
+
coder: dev.coder
|
|
58
77
|
|
|
59
78
|
review:
|
|
60
79
|
from: '@sublang/playbook/review/registry'
|
|
61
|
-
|
|
62
|
-
coder:
|
|
63
|
-
|
|
64
|
-
model: claude-opus-4-8[1m]
|
|
65
|
-
effort: xhigh
|
|
66
|
-
permissions:
|
|
67
|
-
mode: auto
|
|
68
|
-
reviewer:
|
|
69
|
-
adapter: codex
|
|
70
|
-
model: gpt-5.5
|
|
71
|
-
effort: xhigh
|
|
72
|
-
permissions:
|
|
73
|
-
mode: auto
|
|
74
|
-
writablePaths:
|
|
75
|
-
- .git # allow git metadata writes under Codex auto mode
|
|
80
|
+
roles:
|
|
81
|
+
coder: dev.coder
|
|
82
|
+
reviewer: dev.reviewer
|
|
76
83
|
|
|
77
84
|
decide:
|
|
78
85
|
from: '@sublang/playbook/decide/registry'
|
|
79
|
-
|
|
80
|
-
coder:
|
|
81
|
-
|
|
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
|
|
86
|
+
roles:
|
|
87
|
+
coder: dev.coder
|
|
88
|
+
reviewer: dev.reviewer
|
|
94
89
|
```
|
|
95
90
|
|
|
96
91
|
The current bundled workflows accept no workflow-specific options.
|
|
97
|
-
Each role's per-
|
|
92
|
+
Each role's per-call prompt names its current `model`, else its player's
|
|
93
|
+
`adapter`
|
|
98
94
|
([[playbook-runtime-4](../specs/packages/playbook-runtime.md#playbook-runtime-4)]),
|
|
99
95
|
so commit trailers credit the concrete model rather than the adapter
|
|
100
96
|
family.
|
|
101
97
|
|
|
102
|
-
##
|
|
98
|
+
## Role binding forms
|
|
99
|
+
|
|
100
|
+
The shortest binding is a scalar stable player ID:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
roles:
|
|
104
|
+
coder: dev.coder
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use a block to override only that role invocation's model or effort:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
roles:
|
|
111
|
+
coder:
|
|
112
|
+
player: dev.coder
|
|
113
|
+
model: claude-opus-4-8[1m]
|
|
114
|
+
effort: false # explicitly reset to this provider's default
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Omitting `model` or `effort` inherits that player's top-level default. The
|
|
118
|
+
boolean `false` is different: it selects the provider default explicitly, so a
|
|
119
|
+
resumed conversation cannot accidentally retain an earlier selection. A role
|
|
120
|
+
binding cannot override adapter, instruction, permissions, workspace, or tool
|
|
121
|
+
posture; those define the stable player envelope.
|
|
122
|
+
|
|
123
|
+
## Sharing, isolation, and concurrency
|
|
103
124
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
players, and every new root engagement starts fresh
|
|
111
|
-
([DR-030](../specs/decisions/030-shared-mapped-player-continuity.md)).
|
|
125
|
+
Two bindings that name the same player ID deliberately share one sequential
|
|
126
|
+
provider conversation throughout the logical Captain session — across nested
|
|
127
|
+
calls, returns, and later root engagements. CODE's and REVIEW's `coder` roles
|
|
128
|
+
therefore share `dev.coder` in the starter, and DECIDE and its nested REVIEW
|
|
129
|
+
share both starter players. Disposal of one playbook frame does not clear that
|
|
130
|
+
session ledger.
|
|
112
131
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
132
|
+
Two distinct player IDs stay isolated even when their agent blocks are
|
|
133
|
+
byte-for-byte equal. To give standalone REVIEW an independent Coder, define a
|
|
134
|
+
second top-level player and change only its binding:
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
players:
|
|
138
|
+
review.coder:
|
|
139
|
+
adapter: claude
|
|
140
|
+
model: claude-opus-4-8[1m]
|
|
141
|
+
effort: xhigh
|
|
142
|
+
|
|
143
|
+
playbooks:
|
|
144
|
+
review:
|
|
145
|
+
from: '@sublang/playbook/review/registry'
|
|
146
|
+
roles:
|
|
147
|
+
coder: review.coder
|
|
148
|
+
reviewer: dev.reviewer
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Roles a manifest may run concurrently must bind to distinct IDs. DECIDE's
|
|
152
|
+
`coder` and `reviewer` are concurrent, so aliasing both to one player rejects
|
|
153
|
+
before registry import, host creation, or agent work.
|
|
117
154
|
|
|
118
155
|
## Choosing the Captain agent
|
|
119
156
|
|
|
120
157
|
Every session-Captain call and adjudication call is hidden and runs
|
|
121
158
|
tool-free, which is what keeps the Captain deciding and reporting
|
|
122
|
-
instead of doing the work itself. Claude
|
|
123
|
-
|
|
124
|
-
tool list — so a `captain:`
|
|
125
|
-
restriction
|
|
159
|
+
instead of doing the work itself. Claude and Gemini enforce that at the
|
|
160
|
+
provider level. The Codex, Kimi, and OpenCode adapters cannot — they
|
|
161
|
+
reject any tool list — so a `captain:` using one of them falls back to a
|
|
162
|
+
prompt-level restriction
|
|
126
163
|
([DR-013](../specs/decisions/013-routing-only-captain-control.md) A1).
|
|
127
|
-
|
|
164
|
+
Those adapters remain good choices for *players*, where full tools are wanted.
|
|
128
165
|
|
|
129
166
|
Adapter readiness is intentionally light: `claude` is ready with local
|
|
130
167
|
Claude Code auth or `ANTHROPIC_API_KEY`; `codex` with local Codex CLI
|
|
@@ -143,40 +180,52 @@ playbook run --with fast-lineup.yaml "/code implement the approved change"
|
|
|
143
180
|
```
|
|
144
181
|
|
|
145
182
|
```yaml
|
|
146
|
-
# fast-lineup.yaml —
|
|
183
|
+
# fast-lineup.yaml — retune the shared Coder; nothing is written back.
|
|
184
|
+
players:
|
|
185
|
+
dev.coder:
|
|
186
|
+
model: claude-opus-4-8
|
|
187
|
+
effort: medium
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Fragments merge into the agent block rather than replacing it, so
|
|
191
|
+
settings the base defines and the fragment omits — here the adapter,
|
|
192
|
+
instruction, and permissions — survive. Retuning a top-level player affects
|
|
193
|
+
every bound role that does not override that field. To retune only one role,
|
|
194
|
+
overlay its binding instead:
|
|
195
|
+
|
|
196
|
+
```yaml
|
|
147
197
|
playbooks:
|
|
148
198
|
code:
|
|
149
|
-
|
|
199
|
+
roles:
|
|
150
200
|
coder:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
effort: medium
|
|
154
|
-
permissions:
|
|
155
|
-
mode: auto
|
|
156
|
-
# CODE's Coder commits, so Codex needs the `.git` grant to write
|
|
157
|
-
# repository metadata.
|
|
158
|
-
writablePaths:
|
|
159
|
-
- .git
|
|
201
|
+
player: dev.coder
|
|
202
|
+
effort: low
|
|
160
203
|
```
|
|
161
204
|
|
|
162
|
-
Fragments merge into the agent block rather than replacing it, so
|
|
163
|
-
settings the base defines and the fragment omits — here `mode: auto` —
|
|
164
|
-
survive. Anything the adapter itself requires must still be stated: a
|
|
165
|
-
role switched to `codex` needs its own `writablePaths` grant, because
|
|
166
|
-
the base Claude block had no reason to carry one.
|
|
167
|
-
|
|
168
205
|
The global file is never modified, and `--with` is not forwarded to
|
|
169
206
|
`tmux-play` ([[playbook-cli-25](../specs/packages/playbook-cli.md#playbook-cli-25)]).
|
|
170
|
-
Overlays apply
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
207
|
+
Overlays apply when creating a fresh session and as current-config input for a
|
|
208
|
+
compatible ordinary reopen. A selected session keeps its stored catalog,
|
|
209
|
+
player roster, role bindings, adapter, instruction, permissions, and working
|
|
210
|
+
directory; only model and effort may change. The next call reapplies both
|
|
211
|
+
complete selections. An uncertain retry accepts no tuning overlay and uses the
|
|
212
|
+
exact attempted selections already stored with that turn.
|
|
213
|
+
|
|
214
|
+
## Durable shared configuration
|
|
215
|
+
|
|
216
|
+
Fresh interactive and headless sessions use the same top-level Captain,
|
|
217
|
+
players, role bindings, and playbooks. Both persist the same logical-session
|
|
218
|
+
record, shell snapshot, player ledger, normalized catalog, structural agent
|
|
219
|
+
envelopes, last-applied tuning, and absolute working directory. A session
|
|
220
|
+
created by either front end can reopen through either front end with the same
|
|
221
|
+
public UUID. Presentation-only fields are inert headlessly.
|
|
222
|
+
|
|
223
|
+
An ordinary reopen reads current config and opening overlays, but first
|
|
224
|
+
projects them to the stored playbooks and referenced players. An unrelated new
|
|
225
|
+
entry cannot enter or invalidate the session. Structural drift fails closed;
|
|
226
|
+
compatible model or effort changes apply on the next provider call. Legacy
|
|
227
|
+
record, shell, runtime-snapshot, and trace schemas are rejected rather than
|
|
228
|
+
having role or player identity guessed.
|
|
180
229
|
|
|
181
230
|
## External playbooks
|
|
182
231
|
|
|
@@ -187,11 +236,14 @@ and `createRuntime`. Enable it under `playbooks`, bind every role listed in
|
|
|
187
236
|
its `requiredRoleIds`, and invoke its effective slash command through Captain:
|
|
188
237
|
|
|
189
238
|
```yaml
|
|
239
|
+
players:
|
|
240
|
+
my.worker: claude
|
|
241
|
+
|
|
190
242
|
playbooks:
|
|
191
243
|
my-workflow:
|
|
192
244
|
from: /absolute/path/to/my-workflow.ts
|
|
193
|
-
|
|
194
|
-
worker:
|
|
245
|
+
roles:
|
|
246
|
+
worker: my.worker
|
|
195
247
|
```
|
|
196
248
|
|
|
197
249
|
```sh
|
|
@@ -205,15 +257,60 @@ Before either front end imports a filesystem registry, the shared launcher
|
|
|
205
257
|
checks and, unless `--no-provision` is set, provisions its runtime engine
|
|
206
258
|
links as described in [Using the CLI](cli.md#external-playbooks-and-engine-provisioning).
|
|
207
259
|
|
|
260
|
+
## Migrating per-playbook players
|
|
261
|
+
|
|
262
|
+
The former `playbooks.<id>.players` shape made agent configuration and local
|
|
263
|
+
workflow roles the same thing. It is removed. For example, this legacy config
|
|
264
|
+
gave CODE and REVIEW two separately configured `coder` entries:
|
|
265
|
+
|
|
266
|
+
```yaml
|
|
267
|
+
playbooks:
|
|
268
|
+
code:
|
|
269
|
+
from: '@sublang/playbook/code/registry'
|
|
270
|
+
players:
|
|
271
|
+
coder: { adapter: claude, model: claude-opus-4-8[1m] }
|
|
272
|
+
review:
|
|
273
|
+
from: '@sublang/playbook/review/registry'
|
|
274
|
+
players:
|
|
275
|
+
coder: { adapter: claude, model: claude-opus-4-8[1m] }
|
|
276
|
+
reviewer: { adapter: codex, model: gpt-5.5 }
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Move each provider agent into the flat top-level map, choose stable IDs, and
|
|
280
|
+
bind the local roles explicitly:
|
|
281
|
+
|
|
282
|
+
```yaml
|
|
283
|
+
players:
|
|
284
|
+
dev.coder: { adapter: claude, model: claude-opus-4-8[1m] }
|
|
285
|
+
dev.reviewer: { adapter: codex, model: gpt-5.5 }
|
|
286
|
+
|
|
287
|
+
playbooks:
|
|
288
|
+
code:
|
|
289
|
+
from: '@sublang/playbook/code/registry'
|
|
290
|
+
roles: { coder: dev.coder }
|
|
291
|
+
review:
|
|
292
|
+
from: '@sublang/playbook/review/registry'
|
|
293
|
+
roles:
|
|
294
|
+
coder: dev.coder
|
|
295
|
+
reviewer: dev.reviewer
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
The launcher intentionally does **not** perform this migration for you. It
|
|
299
|
+
cannot know whether the two old `coder` blocks were meant to share one
|
|
300
|
+
conversation or remain isolated. Reusing `dev.coder` above chooses sharing;
|
|
301
|
+
using `code.coder` and `review.coder` would choose isolation. A surviving
|
|
302
|
+
per-playbook `players` block therefore rejects before profile migration,
|
|
303
|
+
registry preparation, or agent work.
|
|
304
|
+
|
|
208
305
|
## Migrating direct runs from 6.x
|
|
209
306
|
|
|
210
307
|
The top-level `run:` block is deliberately rejected rather than silently
|
|
211
308
|
ignored or rewritten, because doing otherwise could change the agents after
|
|
212
309
|
an upgrade. Re-express `run.captain`, `run.players`, and former `--player`
|
|
213
|
-
bindings as
|
|
214
|
-
no shared equivalent, so configure every
|
|
215
|
-
`playbooks.<id>.
|
|
216
|
-
|
|
310
|
+
bindings as top-level stable player blocks and explicit role bindings above;
|
|
311
|
+
the old `run.player` catch-all has no shared equivalent, so configure every
|
|
312
|
+
required role at `playbooks.<id>.roles.<role>`. Use a `--with` fragment for
|
|
313
|
+
temporary compatible tuning changes. Move former `--option` values into their `playbooks.<id>`
|
|
217
314
|
block, run from the desired directory instead of passing `--cwd`, enable a
|
|
218
315
|
former positional `<from>` as a configured registry, and quote or pipe one
|
|
219
316
|
`/command task` Boss message. Replace `resume` and `--last` with `--continue`
|