@sublang/playbook 15.0.0 → 16.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 (81) hide show
  1. package/README.md +1 -1
  2. package/docs/embedding.md +9 -7
  3. package/package.json +3 -1
  4. package/reference/sdlc/branch.playbook/branch.fsm.d.ts +63 -33
  5. package/reference/sdlc/branch.playbook/branch.fsm.js +190 -108
  6. package/reference/sdlc/branch.playbook/branch.fsm.ts +269 -147
  7. package/reference/sdlc/branch.playbook/branch.gears.md +7 -17
  8. package/reference/sdlc/branch.playbook/branch.playbook.d.ts +12 -16
  9. package/reference/sdlc/branch.playbook/branch.playbook.js +112 -101
  10. package/reference/sdlc/branch.playbook/branch.playbook.ts +128 -171
  11. package/reference/sdlc/branch.playbook/branch.registry.d.ts +3 -2
  12. package/reference/sdlc/branch.playbook/branch.registry.ts +6 -2
  13. package/reference/sdlc/code.playbook/bin/repository-effects.js +54 -13
  14. package/reference/sdlc/code.playbook/code.fsm.d.ts +143 -90
  15. package/reference/sdlc/code.playbook/code.fsm.introspect.d.ts +8 -8
  16. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +13 -13
  17. package/reference/sdlc/code.playbook/code.fsm.js +609 -649
  18. package/reference/sdlc/code.playbook/code.fsm.ts +890 -821
  19. package/reference/sdlc/code.playbook/code.gears.md +39 -29
  20. package/reference/sdlc/code.playbook/code.playbook.d.ts +13 -16
  21. package/reference/sdlc/code.playbook/code.playbook.js +166 -147
  22. package/reference/sdlc/code.playbook/code.playbook.ts +180 -229
  23. package/reference/sdlc/code.playbook/code.registry.d.ts +3 -2
  24. package/reference/sdlc/code.playbook/code.registry.ts +6 -2
  25. package/reference/sdlc/code.playbook/playbook-captain.d.ts +42 -0
  26. package/reference/sdlc/code.playbook/playbook-captain.js +829 -194
  27. package/reference/sdlc/code.playbook/playbook-captain.ts +1227 -220
  28. package/reference/sdlc/decide.md +1 -0
  29. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +270 -154
  30. package/reference/sdlc/decide.playbook/decide.fsm.js +765 -732
  31. package/reference/sdlc/decide.playbook/decide.fsm.ts +1167 -945
  32. package/reference/sdlc/decide.playbook/decide.gears.md +28 -21
  33. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +11 -67
  34. package/reference/sdlc/decide.playbook/decide.playbook.js +155 -3570
  35. package/reference/sdlc/decide.playbook/decide.playbook.ts +186 -5061
  36. package/reference/sdlc/decide.playbook/decide.registry.d.ts +8 -4
  37. package/reference/sdlc/decide.playbook/decide.registry.js +2 -2
  38. package/reference/sdlc/decide.playbook/decide.registry.ts +13 -6
  39. package/reference/sdlc/dev.playbook/dev.fsm.d.ts +113 -131
  40. package/reference/sdlc/dev.playbook/dev.fsm.js +517 -575
  41. package/reference/sdlc/dev.playbook/dev.fsm.ts +667 -787
  42. package/reference/sdlc/dev.playbook/dev.gears.md +52 -54
  43. package/reference/sdlc/dev.playbook/dev.playbook.d.ts +13 -10
  44. package/reference/sdlc/dev.playbook/dev.playbook.js +128 -120
  45. package/reference/sdlc/dev.playbook/dev.playbook.ts +143 -193
  46. package/reference/sdlc/dev.playbook/dev.registry.d.ts +3 -2
  47. package/reference/sdlc/dev.playbook/dev.registry.ts +6 -2
  48. package/reference/sdlc/pr.playbook/pr.fsm.d.ts +92 -85
  49. package/reference/sdlc/pr.playbook/pr.fsm.js +461 -518
  50. package/reference/sdlc/pr.playbook/pr.fsm.ts +533 -663
  51. package/reference/sdlc/pr.playbook/pr.gears.md +47 -63
  52. package/reference/sdlc/pr.playbook/pr.playbook.d.ts +13 -23
  53. package/reference/sdlc/pr.playbook/pr.playbook.js +118 -112
  54. package/reference/sdlc/pr.playbook/pr.playbook.ts +136 -190
  55. package/reference/sdlc/pr.playbook/pr.registry.d.ts +3 -2
  56. package/reference/sdlc/pr.playbook/pr.registry.ts +4 -2
  57. package/reference/sdlc/review.md +3 -3
  58. package/reference/sdlc/review.playbook/review.fsm.d.ts +150 -116
  59. package/reference/sdlc/review.playbook/review.fsm.js +479 -550
  60. package/reference/sdlc/review.playbook/review.fsm.ts +717 -662
  61. package/reference/sdlc/review.playbook/review.gears.md +32 -29
  62. package/reference/sdlc/review.playbook/review.playbook.d.ts +12 -12
  63. package/reference/sdlc/review.playbook/review.playbook.js +180 -155
  64. package/reference/sdlc/review.playbook/review.playbook.ts +190 -230
  65. package/reference/sdlc/review.playbook/review.registry.d.ts +6 -5
  66. package/reference/sdlc/review.playbook/review.registry.js +3 -3
  67. package/reference/sdlc/review.playbook/review.registry.ts +9 -5
  68. package/slc/gears2fsm.md +72 -3
  69. package/slc/link.md +50 -27
  70. package/slc/materialize-link.mjs +51 -13
  71. package/slc/optimize.md +4 -1
  72. package/slc/prefix-prompts.mjs +191 -0
  73. package/slc/prefix.md +203 -0
  74. package/slc/slc.pin-inputs.json +11 -1
  75. package/slc/text2gears.md +71 -11
  76. package/src/xstate-playbook-runtime.d.ts +82 -9
  77. package/src/xstate-playbook-runtime.js +1224 -283
  78. package/src/xstate-playbook-runtime.ts +1671 -338
  79. package/src/xstate-runtime.d.ts +3 -1
  80. package/src/xstate-runtime.js +9 -2
  81. package/src/xstate-runtime.ts +12 -2
@@ -1,287 +1,238 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
- //
4
- // Generated by slc/link.md (FSM-to-Runtime linker).
5
- // Source FSM: ./code.fsm.ts
6
- // Role metadata: Coder→coder (canonical local role)
7
- // Boss event: deterministic START_CODE entry; exact Boss text becomes
8
- // callerInput; pending Coder questions retain BOSS_REPLY
9
- // Adjudication: LLM judge per player state; coderOutput is carried verbatim;
10
- // the first phase decides among four semantic outcomes
11
- // Nested call: literal review target through the shared bridge
12
- // Compat: artifact schema 3 / runtime ABI 1
13
-
3
+ // Generated by slc/materialize-link.mjs; governed by the complete slc/link.md.
4
+ // FSM: "./code.fsm.js"; export: codeMachine; strategies: shared defaults with labelled string relays and nested actors.
5
+ import { codeMachine as machine } from "./code.fsm.js";
6
+ import type { PlayerInput as SourcePlayerInput } from "./code.fsm.js";
14
7
  import {
15
- createXStatePlaybookRuntime,
16
- composePlayerContinuation,
17
- snapshotJsonValue,
8
+ createXStatePlaybookRuntime, snapshotJsonValue,
9
+ composePlayerContinuation, type XStatePromptIdentity,
18
10
  type PlaybookPlayerInput,
19
- type XStatePlaybookRuntimeFactory,
20
11
  type XStatePlaybookRuntimeConstruction,
21
- type XStatePromptIdentity,
12
+ type XStatePlaybookRuntimeFactory,
22
13
  type XStatePlaybookRuntimeSpecV3,
23
14
  } from '@sublang/playbook/xstate-runtime';
24
- import {
25
- codingMachine,
26
- type CodingInput,
27
- type PlayerInput,
28
- } from './code.fsm.js';
29
- import type { PlaybookHostConstructionCapabilities } from './playbook-captain.js';
30
- import type {
31
- CaptainCallOptions,
32
- CaptainResult,
33
- JsonValue,
34
- NormalizedError,
35
- PlayerCallOptions,
36
- PlaybookCallRequest,
37
- PlaybookCallResult,
38
- PlaybookCallStart,
39
- PlaybookControlReceipt,
40
- PlaybookControlView,
41
- PlaybookPendingCall,
42
- PlaybookPorts,
43
- PlaybookRunResult,
44
- PlaybookRuntime,
45
- PlaybookRuntimeFactory,
46
- PlaybookRuntimeSnapshot,
47
- PlaybookSession,
48
- PlaybookState,
49
- PlaybookStateValue,
50
- PlaybookTraceEvent,
51
- PlaybookTraceType,
15
+ export type {
52
16
  PlayerResult,
17
+ PlayerCallOptions,
53
18
  PlayerSessionStore,
54
- } from '@sublang/playbook/runtime';
55
-
56
- export type {
57
- CaptainCallOptions,
58
19
  CaptainResult,
20
+ CaptainCallOptions,
59
21
  JsonValue,
60
22
  NormalizedError,
61
- PlayerCallOptions,
62
23
  PlaybookCallRequest,
63
24
  PlaybookCallResult,
64
25
  PlaybookCallStart,
65
- PlaybookControlReceipt,
66
- PlaybookControlView,
26
+ PlaybookStateValue,
27
+ PlaybookState,
67
28
  PlaybookPendingCall,
68
- PlaybookPorts,
69
29
  PlaybookRunResult,
70
30
  PlaybookRuntime,
71
31
  PlaybookRuntimeFactory,
72
32
  PlaybookRuntimeSnapshot,
73
33
  PlaybookSession,
74
- PlaybookState,
75
- PlaybookStateValue,
34
+ PlaybookPorts,
76
35
  PlaybookTraceEvent,
77
36
  PlaybookTraceType,
78
- PlayerResult,
79
- PlayerSessionStore,
80
- };
81
-
82
- export type CodePlaybookOptions = CodingInput;
83
- export type CodePlaybookHostCapabilities =
84
- PlaybookHostConstructionCapabilities &
85
- XStatePlaybookRuntimeConstruction<CodePlaybookOptions, object>['hostCapabilities'];
37
+ PlaybookControlReceipt,
38
+ PlaybookControlView,
39
+ } from '@sublang/playbook/runtime';
86
40
 
87
- const OPTION_KEYS = new Set(['runResults']);
88
- const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
41
+ export interface PlaybookRuntimeOptions {
42
+ readonly "runResults"?: string;
43
+ }
44
+ export type PlaybookHostCapabilities = XStatePlaybookRuntimeConstruction<
45
+ PlaybookRuntimeOptions, { readonly authority: object }
46
+ >['hostCapabilities'];
89
47
 
90
- const VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string> = new Set([
91
- 'coderOutput',
48
+ const OPTION_SCHEMA = {
49
+ "runResults": {
50
+ "type": "string",
51
+ "required": false
52
+ }
53
+ } as const;
54
+ const INPUT_MAPPING = {
55
+ "runResults": "runResults"
56
+ } as const;
57
+ const RESUMABLE_STATE_IDS: ReadonlySet<string> = new Set([
58
+ "firstPhase",
59
+ "irTaskPhase"
92
60
  ]);
93
61
  const UNFINISHED_FINAL_STATE_IDS: ReadonlySet<string> = new Set([
94
- 'reportedReviewFailure',
62
+ "reviewFailed"
95
63
  ]);
96
-
97
- function snapshotCodeOptions(value: unknown): CodePlaybookOptions {
98
- const captured = snapshotJsonValue(value, 'CODE runtime options');
99
- if (
100
- captured === null ||
101
- typeof captured !== 'object' ||
102
- Array.isArray(captured)
103
- ) {
104
- throw new TypeError('CODE runtime options must be an object');
64
+ const VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string> = new Set([
65
+ "coderOutput"
66
+ ]);
67
+ export function validateOptions(value: unknown): PlaybookRuntimeOptions {
68
+ const captured = snapshotJsonValue(value === undefined ? {} : value, "CODE runtime options");
69
+ if (captured === null || typeof captured !== 'object' || Array.isArray(captured)) {
70
+ throw new TypeError("CODE runtime options must be an object");
105
71
  }
106
- const record = captured as Readonly<Record<string, JsonValue>>;
107
- for (const [key, option] of Object.entries(record)) {
108
- if (!OPTION_KEYS.has(key)) {
109
- throw new TypeError(`CODE runtime options.${key} is not declared`);
110
- }
111
- if (typeof option !== 'string') {
112
- throw new TypeError(`CODE runtime options.${key} must be a string`);
72
+ const fields = captured as Readonly<Record<string, unknown>>;
73
+ for (const key of Object.keys(captured)) {
74
+ if (!Object.hasOwn(OPTION_SCHEMA, key)) throw new TypeError("CODE runtime options." + key + ' is not declared');
75
+ }
76
+ for (const [key, schema] of Object.entries(OPTION_SCHEMA) as [string, { type: string; required: boolean }][]) {
77
+ if (!Object.hasOwn(captured, key)) {
78
+ if (schema.required) throw new TypeError("CODE runtime options." + key + ' is required');
79
+ } else if (typeof fields[key] !== schema.type || (schema.type === 'number' && !Number.isFinite(fields[key]))) {
80
+ throw new TypeError("CODE runtime options." + key + ' must be a ' + schema.type);
113
81
  }
114
82
  }
115
- return captured as unknown as CodePlaybookOptions;
116
- }
117
-
118
- function placeholderField(token: string): string {
119
- if (token === '#') return 'irNumber';
120
- return token.replace(/-([A-Za-z0-9_$])/g, (_match, next: string) =>
121
- next.toUpperCase(),
122
- );
83
+ return captured as unknown as PlaybookRuntimeOptions;
123
84
  }
124
-
125
- function quoteContinuation(value: string): string {
126
- return value.replaceAll('\n', '\n> ');
127
- }
128
-
129
- /**
130
- * Preserve authored Markdown quote markers around every line of relayed
131
- * runtime text. The generic composer preserves the marker itself; CODE's
132
- * override additionally keeps a multiline value inside that quote.
133
- */
134
- function composePlayerPrompt(
135
- input: PlayerInput,
136
- promptIdentity: XStatePromptIdentity,
137
- resuming = false,
138
- ): string {
139
- const fields = input as unknown as Record<string, unknown>;
140
- const template = input.prompt
141
- .split('\n')
142
- .filter(
143
- (line) => !(line === '> Run results: <run-results>' && input.runResults.length === 0),
144
- )
145
- .join('\n');
146
- const body = template.replace(
147
- PLACEHOLDER,
148
- (match: string, token: string, offset: number, source: string) => {
149
- const value =
150
- token === 'coder-llm'
151
- ? promptIdentity('coder')
152
- : fields[placeholderField(token)];
85
+ function renderPlayerPrompt(input: SourcePlayerInput, promptIdentity: XStatePromptIdentity, resuming = false): string {
86
+ const fields = input as unknown as Readonly<Record<string, unknown>>;
87
+ const mapping: Readonly<Record<string, string>> = {};
88
+ const identities: Readonly<Record<string, string>> = {"coder-llm":"coder"};
89
+ const omitted = new Set<string>(["> Run results: <run-results>"]);
90
+ const fieldFor = (token: string): string => Object.hasOwn(mapping, token) ? mapping[token]! : (token === '#' ? 'irNumber' : token.replace(/-([A-Za-z0-9_$])/g, (_match: string, next: string) => next.toUpperCase()));
91
+ const parts = input.prompt.split(/(\r?\n)/);
92
+ let body = '';
93
+ for (let index = 0; index < parts.length; index += 2) {
94
+ const line = parts[index]!;
95
+ if (omitted.has(line)) {
96
+ const token = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>$/.exec(line)![1]!;
97
+ if (fields[fieldFor(token)] === '') continue;
98
+ }
99
+ body += line.replace(/<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g, (match: string, token: string): string => {
100
+ const value = Object.hasOwn(identities, token) ? promptIdentity(identities[token]!) : fields[fieldFor(token)];
153
101
  if (typeof value !== 'string') return match;
154
- const lineStart = source.lastIndexOf('\n', offset - 1) + 1;
155
- const literal = source.slice(lineStart, offset);
156
- return literal.startsWith('> ') ? quoteContinuation(value) : value;
157
- },
158
- );
102
+ return line.startsWith('> ') ? value.replace(/\r?\n/g, (ending: string) => ending + '> ') : value;
103
+ }) + (parts[index + 1] ?? '');
104
+ }
159
105
  return composePlayerContinuation(input, body, resuming);
160
106
  }
161
-
162
- export const _internal = {
163
- composePlayerPrompt,
164
- VERBATIM_PAYLOAD_FIELDS,
165
- UNFINISHED_FINAL_STATE_IDS,
166
- };
167
-
107
+ const composePlayerPrompt = (input: PlaybookPlayerInput, promptIdentity: XStatePromptIdentity, resuming?: boolean): string =>
108
+ renderPlayerPrompt(input as SourcePlayerInput, promptIdentity, resuming);
168
109
  const runtimeSpec = {
169
- label: 'CODE',
170
- // DR-022 / slc/link.md: the declaration carries the value current at link
171
- // time — a literal, never the loading engine's RUNTIME_ABI self-report,
172
- // which would follow whatever engine loads the module and make the
173
- // factory's skew check compare that engine with itself.
174
- compat: { artifactSchema: 3, runtimeAbi: 1 },
175
- snapshotOptions: snapshotCodeOptions,
176
- entryEvent: {
177
- type: 'START_CODE',
178
- textField: 'callerInput',
179
- // `startCoding` copies the entry text here, so the failure-state retry
180
- // reads it back from the persisted machine snapshot and survives a
181
- // continued session (DR-034).
182
- contextField: 'callerInput',
110
+ composePlayerPrompt,
111
+ ...{
112
+ "label": "CODE",
113
+ "compat": {
114
+ "artifactSchema": 3,
115
+ "runtimeAbi": 1
183
116
  },
184
- roleStates: {
185
- runFirstPhase: {
186
- role: 'coder',
187
- label:
188
- 'Coder is running the first coding phase: a direct implementation, a new intent record, or an existing intent-record task.',
189
- },
190
- runIrTask: {
191
- role: 'coder',
192
- label: 'Coder is implementing exactly one unfinished intent-record task.',
117
+ "entryEvent": {
118
+ "type": "START_CODE",
119
+ "textField": "callerInput",
120
+ "contextField": "callerInput"
121
+ },
122
+ "bossEvents": [],
123
+ "roleStates": {
124
+ "firstPhase": {
125
+ "role": "coder",
126
+ "label": "Coder runs the first coding phase: a direct implementation, a new IR, or the next task of an existing IR."
193
127
  },
128
+ "irTaskPhase": {
129
+ "role": "coder",
130
+ "label": "Coder implements the identified IR's next unfinished task."
131
+ }
194
132
  },
195
- outcomeAuthority: {
196
- governedPlayerStates: {
197
- runFirstPhase: {
198
- directCommit: {
199
- fields: {
200
- coderOutput: 'presentation',
201
- latestCommit: 'effect',
133
+ "outcomeAuthority": {
134
+ "governedPlayerStates": {
135
+ "firstPhase": {
136
+ "directCommit": {
137
+ "fields": {
138
+ "coderOutput": "presentation",
139
+ "latestCommit": "effect"
202
140
  },
203
- repositoryDisposition: 'one-descendant-commit',
141
+ "repositoryDisposition": "one-descendant-commit"
204
142
  },
205
- irCommit: {
206
- fields: {
207
- coderOutput: 'presentation',
208
- latestCommit: 'effect',
209
- irNumber: 'semantic',
143
+ "irCommit": {
144
+ "fields": {
145
+ "coderOutput": "presentation",
146
+ "latestCommit": "effect",
147
+ "irNumber": "semantic"
210
148
  },
211
- repositoryDisposition: 'one-descendant-commit',
149
+ "repositoryDisposition": "one-descendant-commit"
212
150
  },
213
- moreTasks: {
214
- fields: {
215
- coderOutput: 'presentation',
216
- latestCommit: 'effect',
217
- irNumber: 'semantic',
218
- irTask: 'semantic',
151
+ "moreTasks": {
152
+ "fields": {
153
+ "coderOutput": "presentation",
154
+ "latestCommit": "effect",
155
+ "irNumber": "semantic",
156
+ "irTask": "semantic"
219
157
  },
220
- repositoryDisposition: 'one-descendant-commit',
158
+ "repositoryDisposition": "one-descendant-commit"
221
159
  },
222
- finalTask: {
223
- fields: {
224
- coderOutput: 'presentation',
225
- latestCommit: 'effect',
226
- irNumber: 'semantic',
227
- irTask: 'semantic',
160
+ "finalTask": {
161
+ "fields": {
162
+ "coderOutput": "presentation",
163
+ "latestCommit": "effect",
164
+ "irNumber": "semantic",
165
+ "irTask": "semantic"
228
166
  },
229
- repositoryDisposition: 'one-descendant-commit',
230
- },
231
- needsBossReply: {
232
- fields: { question: 'presentation' },
233
- repositoryDisposition: 'deferred',
167
+ "repositoryDisposition": "one-descendant-commit"
234
168
  },
169
+ "needsBossReply": {
170
+ "fields": {
171
+ "question": "presentation"
172
+ },
173
+ "repositoryDisposition": "deferred"
174
+ }
235
175
  },
236
- runIrTask: {
237
- moreTasks: {
238
- fields: {
239
- coderOutput: 'presentation',
240
- latestCommit: 'effect',
241
- irNumber: 'semantic',
242
- irTask: 'semantic',
176
+ "irTaskPhase": {
177
+ "moreTasks": {
178
+ "fields": {
179
+ "coderOutput": "presentation",
180
+ "latestCommit": "effect",
181
+ "irNumber": "semantic",
182
+ "irTask": "semantic"
243
183
  },
244
- repositoryDisposition: 'one-descendant-commit',
184
+ "repositoryDisposition": "one-descendant-commit"
245
185
  },
246
- finalTask: {
247
- fields: {
248
- coderOutput: 'presentation',
249
- latestCommit: 'effect',
250
- irNumber: 'semantic',
251
- irTask: 'semantic',
186
+ "finalTask": {
187
+ "fields": {
188
+ "coderOutput": "presentation",
189
+ "latestCommit": "effect",
190
+ "irNumber": "semantic",
191
+ "irTask": "semantic"
252
192
  },
253
- repositoryDisposition: 'one-descendant-commit',
193
+ "repositoryDisposition": "one-descendant-commit"
254
194
  },
255
- needsBossReply: {
256
- fields: { question: 'presentation' },
257
- repositoryDisposition: 'deferred',
258
- },
259
- },
260
- },
195
+ "needsBossReply": {
196
+ "fields": {
197
+ "question": "presentation"
198
+ },
199
+ "repositoryDisposition": "deferred"
200
+ }
201
+ }
202
+ }
261
203
  },
262
- composePlayerPrompt: (
263
- input: PlaybookPlayerInput,
264
- promptIdentity: XStatePromptIdentity,
265
- resuming?: boolean,
266
- ) => composePlayerPrompt(input as PlayerInput, promptIdentity, resuming),
204
+ "placeholderFields": {},
205
+ "transitionEventFields": [
206
+ "callerInput",
207
+ "runResults",
208
+ "targetId",
209
+ "answer",
210
+ "questionId"
211
+ ],
212
+ "controlContextFields": [
213
+ "phaseOutcome",
214
+ "irNumber",
215
+ "codeCommit",
216
+ "evaluatedRevision"
217
+ ]
218
+ },
219
+ snapshotOptions: validateOptions,
220
+ machineInput: (options: PlaybookRuntimeOptions) => Object.fromEntries(
221
+ Object.entries(INPUT_MAPPING).filter(([, key]) => options[key as keyof PlaybookRuntimeOptions] !== undefined)
222
+ .map(([field, key]) => [field, options[key as keyof PlaybookRuntimeOptions]]),
223
+ ),
267
224
  verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
268
- controlContextFields: ['phase'],
225
+ resumableStateIds: RESUMABLE_STATE_IDS,
269
226
  unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
270
- transitionEventFields: ['callerInput', 'answer', 'questionId'],
271
- } satisfies XStatePlaybookRuntimeSpecV3<CodePlaybookOptions>;
227
+ } satisfies XStatePlaybookRuntimeSpecV3<PlaybookRuntimeOptions>;
272
228
 
229
+ export const _internal = {
230
+ composePlayerPrompt,
231
+ RESUMABLE_STATE_IDS,
232
+ UNFINISHED_FINAL_STATE_IDS,
233
+ VERBATIM_PAYLOAD_FIELDS,
234
+ };
273
235
  const createPlaybookRuntime: XStatePlaybookRuntimeFactory<
274
- XStatePlaybookRuntimeConstruction<
275
- CodePlaybookOptions,
276
- CodePlaybookHostCapabilities
277
- >,
278
- 3
279
- > = createXStatePlaybookRuntime<
280
- CodePlaybookOptions,
281
- CodePlaybookHostCapabilities
282
- >(
283
- codingMachine,
284
- runtimeSpec,
285
- );
286
-
236
+ XStatePlaybookRuntimeConstruction<PlaybookRuntimeOptions, PlaybookHostCapabilities>, 3
237
+ > = createXStatePlaybookRuntime<PlaybookRuntimeOptions, PlaybookHostCapabilities>(machine, runtimeSpec);
287
238
  export default createPlaybookRuntime;
@@ -1,4 +1,5 @@
1
- import { type CodePlaybookHostCapabilities, type PlaybookRuntime } from './code.playbook.js';
1
+ import { type PlaybookHostCapabilities, type PlaybookRuntime } from './code.playbook.js';
2
+ import type { PlaybookHostConstructionCapabilities } from './playbook-captain.js';
2
3
  export interface PlaybookSummaryPolicy {
3
4
  stateCountLabels: Readonly<Record<string, string>>;
4
5
  copyPasteGuardNames: readonly string[];
@@ -24,7 +25,7 @@ export interface CodePlaybookRegistryEntry {
24
25
  concurrentRoleSets: readonly [];
25
26
  summaryPolicy: PlaybookSummaryPolicy;
26
27
  validateOptions(optionSlice: unknown): CodeOptions;
27
- createRuntime(options: CodeOptions, hostCapabilities: CodePlaybookHostCapabilities): PlaybookRuntime;
28
+ createRuntime(options: CodeOptions, hostCapabilities: PlaybookHostConstructionCapabilities & PlaybookHostCapabilities): PlaybookRuntime;
28
29
  }
29
30
  export declare const codeStateCountLabels: {};
30
31
  export declare const codeCopyPasteGuardNames: readonly ["directCommit", "irCommit", "moreTasks", "finalTask"];
@@ -2,9 +2,10 @@
2
2
  // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
3
 
4
4
  import createPlaybookRuntime, {
5
- type CodePlaybookHostCapabilities,
5
+ type PlaybookHostCapabilities,
6
6
  type PlaybookRuntime,
7
7
  } from './code.playbook.js';
8
+ import type { PlaybookHostConstructionCapabilities } from './playbook-captain.js';
8
9
 
9
10
  export interface PlaybookSummaryPolicy {
10
11
  stateCountLabels: Readonly<Record<string, string>>;
@@ -33,9 +34,12 @@ export interface CodePlaybookRegistryEntry {
33
34
  concurrentRoleSets: readonly [];
34
35
  summaryPolicy: PlaybookSummaryPolicy;
35
36
  validateOptions(optionSlice: unknown): CodeOptions;
37
+ // The linked module types live authority as opaque (link-materialization);
38
+ // the Captain entry binds its own construction capabilities here.
36
39
  createRuntime(
37
40
  options: CodeOptions,
38
- hostCapabilities: CodePlaybookHostCapabilities,
41
+ hostCapabilities: PlaybookHostConstructionCapabilities &
42
+ PlaybookHostCapabilities,
39
43
  ): PlaybookRuntime;
40
44
  }
41
45
 
@@ -243,8 +243,50 @@ export interface PlaybookCaptainShell extends Captain {
243
243
  */
244
244
  submitShellAction?(actionId: string): string;
245
245
  }
246
+ /**
247
+ * Whether words may stand outside a code span in a statement the shell says
248
+ * (CAPTAIN-9); the pure renderer accepts everything, and the shell passes its
249
+ * guard.
250
+ */
251
+ type Speakable = (text: string) => boolean;
252
+ /**
253
+ * What the shell recorded of a failure: an error, which may carry the cause
254
+ * the runtime decided (DR-063 §2), or that cause alone.
255
+ */
256
+ interface RecordedFailure {
257
+ readonly message?: string;
258
+ readonly cause?: unknown;
259
+ }
260
+ type DescribePlaybook = (playbookId: string) => string;
261
+ /**
262
+ * CAPTAIN-71: the one way a failure is put into words — `<Subject> failed:
263
+ * <reason>.` — `subject` naming what failed in the Boss's words and `failure`
264
+ * the error or cause the shell recorded.
265
+ */
266
+ declare function failureStatement(subject: string, failure: RecordedFailure | undefined, describePlaybook?: DescribePlaybook, speakable?: Speakable): string;
267
+ /**
268
+ * The three kinds of statement a report the shell says holds (CAPTAIN-69):
269
+ * a listed fact, a numbered unresolved-effect entry, and the `Failure:` line.
270
+ */
271
+ type StatementKind = 'fact' | 'entry' | 'failure';
272
+ /** A statement the report assembly weighs. */
273
+ interface BossStatement {
274
+ readonly text: string;
275
+ /** Its kind, which decides what may drop it; a fact where absent. */
276
+ readonly kind?: StatementKind;
277
+ /** The reason a `Failure:` line states (CAPTAIN-67). */
278
+ readonly reason?: string;
279
+ }
280
+ /** The statements of `statements` that stay, as CAPTAIN-69 assembles them. */
281
+ declare function bossReport(statements: readonly (string | BossStatement)[], reasons?: Iterable<string>): string[];
246
282
  export declare function assertPlaybookCaptainUnresolvedEffects(value: unknown): readonly PlaybookCaptainUnresolvedEffect[];
247
283
  /** Validate, detach, and freeze one untrusted shell snapshot. */
248
284
  export declare function assertPlaybookCaptainShellSnapshot(value: unknown): PlaybookCaptainShellSnapshot;
249
285
  export declare function createPlaybookCaptainShell(options: unknown, deps?: PlaybookCaptainDeps): PlaybookCaptainShell;
286
+ export declare const _internal: {
287
+ failureStatement: typeof failureStatement;
288
+ bossReport: typeof bossReport;
289
+ RUNTIME_REASON_PHRASES: Readonly<Record<string, string>>;
290
+ LABELLED_RUNTIME_REASONS: readonly (readonly [RegExp, string])[];
291
+ };
250
292
  export default createPlaybookCaptainShell;