@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,245 +1,195 @@
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: ./dev.fsm.ts
6
- // Role metadata: Analyst→analyst (canonical local role)
7
- // Boss event: deterministic START_DEV entry; exact Boss text becomes
8
- // developmentRequest; pending Analyst questions retain
9
- // BOSS_REPLY
10
- // Adjudication: LLM judge for the one Analyst state; planningResult is
11
- // carried verbatim
12
- // Nested calls: literal code, decide, branch, and pr targets through the
13
- // shared bridge; branch, revision, commit, and pull-request
14
- // identities enter only from canonical child results
15
- // Compat: artifact schema 3 / runtime ABI 1
16
-
3
+ // Generated by slc/materialize-link.mjs; governed by the complete slc/link.md.
4
+ // FSM: "./dev.fsm.js"; export: devMachine; strategies: shared defaults with labelled string relays and nested actors.
5
+ import { devMachine as machine } from "./dev.fsm.js";
6
+ import type { PlayerInput as SourcePlayerInput } from "./dev.fsm.js";
17
7
  import {
18
- createXStatePlaybookRuntime,
19
- composePlayerContinuation,
20
- snapshotJsonValue,
8
+ createXStatePlaybookRuntime, snapshotJsonValue,
9
+ composePlayerContinuation, type XStatePromptIdentity,
21
10
  type PlaybookPlayerInput,
22
- type XStatePlaybookRuntimeFactory,
23
11
  type XStatePlaybookRuntimeConstruction,
12
+ type XStatePlaybookRuntimeFactory,
24
13
  type XStatePlaybookRuntimeSpecV3,
25
14
  } from '@sublang/playbook/xstate-runtime';
26
- import {
27
- devMachine,
28
- type DevInput,
29
- type PlayerInput,
30
- } from './dev.fsm.js';
31
- import type { PlaybookHostConstructionCapabilities } from '../code.playbook/playbook-captain.js';
32
- import type {
33
- CaptainCallOptions,
34
- CaptainResult,
35
- JsonValue,
36
- NormalizedError,
37
- PlayerCallOptions,
38
- PlaybookCallRequest,
39
- PlaybookCallResult,
40
- PlaybookCallStart,
41
- PlaybookControlReceipt,
42
- PlaybookControlView,
43
- PlaybookPendingCall,
44
- PlaybookPorts,
45
- PlaybookRunResult,
46
- PlaybookRuntime,
47
- PlaybookRuntimeFactory,
48
- PlaybookRuntimeSnapshot,
49
- PlaybookSession,
50
- PlaybookState,
51
- PlaybookStateValue,
52
- PlaybookTraceEvent,
53
- PlaybookTraceType,
15
+ export type {
54
16
  PlayerResult,
17
+ PlayerCallOptions,
55
18
  PlayerSessionStore,
56
- } from '@sublang/playbook/runtime';
57
-
58
- export type {
59
- CaptainCallOptions,
60
19
  CaptainResult,
20
+ CaptainCallOptions,
61
21
  JsonValue,
62
22
  NormalizedError,
63
- PlayerCallOptions,
64
23
  PlaybookCallRequest,
65
24
  PlaybookCallResult,
66
25
  PlaybookCallStart,
67
- PlaybookControlReceipt,
68
- PlaybookControlView,
26
+ PlaybookStateValue,
27
+ PlaybookState,
69
28
  PlaybookPendingCall,
70
- PlaybookPorts,
71
29
  PlaybookRunResult,
72
30
  PlaybookRuntime,
73
31
  PlaybookRuntimeFactory,
74
32
  PlaybookRuntimeSnapshot,
75
33
  PlaybookSession,
76
- PlaybookState,
77
- PlaybookStateValue,
34
+ PlaybookPorts,
78
35
  PlaybookTraceEvent,
79
36
  PlaybookTraceType,
80
- PlayerResult,
81
- PlayerSessionStore,
82
- };
83
-
84
- export type DevPlaybookOptions = DevInput;
85
- export type DevPlaybookHostCapabilities =
86
- PlaybookHostConstructionCapabilities &
87
- XStatePlaybookRuntimeConstruction<DevPlaybookOptions, object>['hostCapabilities'];
37
+ PlaybookControlReceipt,
38
+ PlaybookControlView,
39
+ } from '@sublang/playbook/runtime';
88
40
 
89
- const OPTION_KEYS = new Set(['runResults']);
90
- 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'];
91
47
 
92
- const VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string> = new Set([
93
- 'planningResult',
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
+ "planAnalysis"
94
59
  ]);
95
60
  const UNFINISHED_FINAL_STATE_IDS: ReadonlySet<string> = new Set([
96
- 'reportedChildFailure',
61
+ "reportedChildFailure"
97
62
  ]);
98
-
99
- function snapshotDevOptions(value: unknown): DevPlaybookOptions {
100
- const captured = snapshotJsonValue(value, 'DEV runtime options');
101
- if (
102
- captured === null ||
103
- typeof captured !== 'object' ||
104
- Array.isArray(captured)
105
- ) {
106
- throw new TypeError('DEV runtime options must be an object');
63
+ const VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string> = new Set([
64
+ "planningResult"
65
+ ]);
66
+ export function validateOptions(value: unknown): PlaybookRuntimeOptions {
67
+ const captured = snapshotJsonValue(value === undefined ? {} : value, "DEV runtime options");
68
+ if (captured === null || typeof captured !== 'object' || Array.isArray(captured)) {
69
+ throw new TypeError("DEV runtime options must be an object");
107
70
  }
108
- const record = captured as Readonly<Record<string, JsonValue>>;
109
- for (const [key, option] of Object.entries(record)) {
110
- if (!OPTION_KEYS.has(key)) {
111
- throw new TypeError(`DEV runtime options.${key} is not declared`);
112
- }
113
- if (typeof option !== 'string') {
114
- throw new TypeError(`DEV runtime options.${key} must be a string`);
71
+ const fields = captured as Readonly<Record<string, unknown>>;
72
+ for (const key of Object.keys(captured)) {
73
+ if (!Object.hasOwn(OPTION_SCHEMA, key)) throw new TypeError("DEV runtime options." + key + ' is not declared');
74
+ }
75
+ for (const [key, schema] of Object.entries(OPTION_SCHEMA) as [string, { type: string; required: boolean }][]) {
76
+ if (!Object.hasOwn(captured, key)) {
77
+ if (schema.required) throw new TypeError("DEV runtime options." + key + ' is required');
78
+ } else if (typeof fields[key] !== schema.type || (schema.type === 'number' && !Number.isFinite(fields[key]))) {
79
+ throw new TypeError("DEV runtime options." + key + ' must be a ' + schema.type);
115
80
  }
116
81
  }
117
- return captured as unknown as DevPlaybookOptions;
82
+ return captured as unknown as PlaybookRuntimeOptions;
118
83
  }
119
-
120
- function placeholderField(token: string): string {
121
- if (token === '#') return 'irNumber';
122
- return token.replace(/-([A-Za-z0-9_$])/g, (_match, next: string) =>
123
- next.toUpperCase(),
124
- );
125
- }
126
-
127
- function quotedContinuation(value: string): string {
128
- return value.replaceAll('\n', '\n> ');
129
- }
130
-
131
- /**
132
- * Preserve authored Markdown quote markers around every line of relayed
133
- * runtime text. The generic composer preserves the marker itself; DEV's
134
- * override additionally keeps a multiline value inside that quote and drops
135
- * the optional relays that have no value yet.
136
- */
137
- function composePlayerPrompt(input: PlayerInput, resuming = false): string {
138
- const fields = input as unknown as Record<string, unknown>;
139
- const template = input.prompt
140
- .split('\n')
141
- .filter(
142
- (line) =>
143
- !(
144
- line === '> Prior discussion: <discussion-context>' &&
145
- input.discussionContext.length === 0
146
- ) &&
147
- !(line === '> Run results: <run-results>' && input.runResults.length === 0),
148
- )
149
- .join('\n');
150
- const body = template.replace(
151
- PLACEHOLDER,
152
- (match: string, token: string, offset: number, source: string) => {
153
- const value = fields[placeholderField(token)];
84
+ function renderPlayerPrompt(input: SourcePlayerInput, promptIdentity: XStatePromptIdentity, resuming = false): string {
85
+ const fields = input as unknown as Readonly<Record<string, unknown>>;
86
+ const mapping: Readonly<Record<string, string>> = {};
87
+ const identities: Readonly<Record<string, string>> = {};
88
+ const omitted = new Set<string>(["> Prior discussion: <discussion-context>","> Run results: <run-results>"]);
89
+ 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()));
90
+ const parts = input.prompt.split(/(\r?\n)/);
91
+ let body = '';
92
+ for (let index = 0; index < parts.length; index += 2) {
93
+ const line = parts[index]!;
94
+ if (omitted.has(line)) {
95
+ const token = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>$/.exec(line)![1]!;
96
+ if (fields[fieldFor(token)] === '') continue;
97
+ }
98
+ body += line.replace(/<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g, (match: string, token: string): string => {
99
+ const value = Object.hasOwn(identities, token) ? promptIdentity(identities[token]!) : fields[fieldFor(token)];
154
100
  if (typeof value !== 'string') return match;
155
- const lineStart = source.lastIndexOf('\n', offset - 1) + 1;
156
- const literal = source.slice(lineStart, offset);
157
- return literal.startsWith('> ') ? quotedContinuation(value) : value;
158
- },
159
- );
101
+ return line.startsWith('> ') ? value.replace(/\r?\n/g, (ending: string) => ending + '> ') : value;
102
+ }) + (parts[index + 1] ?? '');
103
+ }
160
104
  return composePlayerContinuation(input, body, resuming);
161
105
  }
162
-
106
+ const composePlayerPrompt = (input: PlaybookPlayerInput, promptIdentity: XStatePromptIdentity, resuming?: boolean): string =>
107
+ renderPlayerPrompt(input as SourcePlayerInput, promptIdentity, resuming);
163
108
  const runtimeSpec = {
164
- label: 'DEV',
165
- // DR-022 / slc/link.md: the declaration carries the value current at link
166
- // time — a literal, never the loading engine's RUNTIME_ABI self-report,
167
- // which would follow whatever engine loads the module and make the
168
- // factory's skew check compare that engine with itself.
169
- compat: { artifactSchema: 3, runtimeAbi: 1 },
170
- snapshotOptions: snapshotDevOptions,
171
- entryEvent: {
172
- type: 'START_DEV',
173
- textField: 'developmentRequest',
174
- // `startDev` copies the entry text here, so the failure-state retry
175
- // reads it back from the persisted machine snapshot and survives a
176
- // continued session (DR-034).
177
- contextField: 'developmentRequest',
109
+ composePlayerPrompt,
110
+ ...{
111
+ "label": "DEV",
112
+ "compat": {
113
+ "artifactSchema": 3,
114
+ "runtimeAbi": 1
178
115
  },
179
- roleStates: {
180
- planAnalysis: {
181
- role: 'analyst',
182
- label: 'Analyst is choosing the development path.',
183
- },
116
+ "entryEvent": {
117
+ "type": "START_DEV",
118
+ "textField": "developmentRequest",
119
+ "contextField": "developmentRequest"
184
120
  },
185
- // DR-044: DEV owns no repository commit — every Analyst outcome is
186
- // governed with the `unchanged` repository disposition, so planning that
187
- // mutates the repository fails authority instead of being adopted.
188
- outcomeAuthority: {
189
- governedPlayerStates: {
190
- planAnalysis: {
191
- discussionComplete: {
192
- fields: {},
193
- repositoryDisposition: 'unchanged',
194
- },
195
- code: {
196
- fields: { planningResult: 'presentation' },
197
- repositoryDisposition: 'unchanged',
121
+ "bossEvents": [],
122
+ "roleStates": {
123
+ "planAnalysis": {
124
+ "role": "analyst",
125
+ "label": "Analyst chooses the development path in a short planning note."
126
+ }
127
+ },
128
+ "outcomeAuthority": {
129
+ "governedPlayerStates": {
130
+ "planAnalysis": {
131
+ "discussionComplete": {
132
+ "fields": {},
133
+ "repositoryDisposition": "unchanged"
198
134
  },
199
- decideThenCode: {
200
- fields: { planningResult: 'presentation' },
201
- repositoryDisposition: 'unchanged',
135
+ "code": {
136
+ "fields": {
137
+ "planningResult": "presentation"
138
+ },
139
+ "repositoryDisposition": "unchanged"
202
140
  },
203
- // DR-050: reading a GitHub issue during planning is not an effect, so
204
- // the two pull-request outcomes stay `unchanged` like the plain ones.
205
- codeViaPullRequest: {
206
- fields: { planningResult: 'presentation' },
207
- repositoryDisposition: 'unchanged',
141
+ "decideThenCode": {
142
+ "fields": {
143
+ "planningResult": "presentation"
144
+ },
145
+ "repositoryDisposition": "unchanged"
208
146
  },
209
- decideThenCodeViaPullRequest: {
210
- fields: { planningResult: 'presentation' },
211
- repositoryDisposition: 'unchanged',
147
+ "codeViaPullRequest": {
148
+ "fields": {
149
+ "planningResult": "presentation"
150
+ },
151
+ "repositoryDisposition": "unchanged"
212
152
  },
213
- needsBossReply: {
214
- fields: { question: 'presentation' },
215
- repositoryDisposition: 'unchanged',
153
+ "decideThenCodeViaPullRequest": {
154
+ "fields": {
155
+ "planningResult": "presentation"
156
+ },
157
+ "repositoryDisposition": "unchanged"
216
158
  },
217
- },
218
- },
159
+ "needsBossReply": {
160
+ "fields": {
161
+ "question": "presentation"
162
+ },
163
+ "repositoryDisposition": "unchanged"
164
+ }
165
+ }
166
+ }
219
167
  },
220
- composePlayerPrompt: (input: PlaybookPlayerInput, _identity, resuming?: boolean) =>
221
- composePlayerPrompt(input as PlayerInput, resuming),
168
+ "placeholderFields": {},
169
+ "transitionEventFields": [
170
+ "developmentRequest",
171
+ "answer",
172
+ "questionId"
173
+ ],
174
+ "controlContextFields": []
175
+ },
176
+ snapshotOptions: validateOptions,
177
+ machineInput: (options: PlaybookRuntimeOptions) => Object.fromEntries(
178
+ Object.entries(INPUT_MAPPING).filter(([, key]) => options[key as keyof PlaybookRuntimeOptions] !== undefined)
179
+ .map(([field, key]) => [field, options[key as keyof PlaybookRuntimeOptions]]),
180
+ ),
222
181
  verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
223
- controlContextFields: [],
182
+ resumableStateIds: RESUMABLE_STATE_IDS,
224
183
  unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
225
- transitionEventFields: ['developmentRequest', 'answer', 'questionId'],
226
- } satisfies XStatePlaybookRuntimeSpecV3<DevPlaybookOptions>;
184
+ } satisfies XStatePlaybookRuntimeSpecV3<PlaybookRuntimeOptions>;
227
185
 
228
186
  export const _internal = {
229
- composePlayerPrompt: runtimeSpec.composePlayerPrompt,
230
- VERBATIM_PAYLOAD_FIELDS,
187
+ composePlayerPrompt,
188
+ RESUMABLE_STATE_IDS,
231
189
  UNFINISHED_FINAL_STATE_IDS,
190
+ VERBATIM_PAYLOAD_FIELDS,
232
191
  };
233
-
234
192
  const createPlaybookRuntime: XStatePlaybookRuntimeFactory<
235
- XStatePlaybookRuntimeConstruction<
236
- DevPlaybookOptions,
237
- DevPlaybookHostCapabilities
238
- >,
239
- 3
240
- > = createXStatePlaybookRuntime<
241
- DevPlaybookOptions,
242
- DevPlaybookHostCapabilities
243
- >(devMachine, runtimeSpec);
244
-
193
+ XStatePlaybookRuntimeConstruction<PlaybookRuntimeOptions, PlaybookHostCapabilities>, 3
194
+ > = createXStatePlaybookRuntime<PlaybookRuntimeOptions, PlaybookHostCapabilities>(machine, runtimeSpec);
245
195
  export default createPlaybookRuntime;
@@ -1,4 +1,5 @@
1
- import { type DevPlaybookHostCapabilities, type PlaybookRuntime } from './dev.playbook.js';
1
+ import type { PlaybookHostConstructionCapabilities } from '../code.playbook/playbook-captain.js';
2
+ import { type PlaybookHostCapabilities, type PlaybookRuntime } from './dev.playbook.js';
2
3
  export interface PlaybookSummaryPolicy {
3
4
  stateCountLabels: Readonly<Record<string, string>>;
4
5
  copyPasteGuardNames: readonly string[];
@@ -24,7 +25,7 @@ export interface DevPlaybookRegistryEntry {
24
25
  concurrentRoleSets: readonly [];
25
26
  summaryPolicy: PlaybookSummaryPolicy;
26
27
  validateOptions(optionSlice: unknown): DevOptions;
27
- createRuntime(options: DevOptions, hostCapabilities: DevPlaybookHostCapabilities): PlaybookRuntime;
28
+ createRuntime(options: DevOptions, hostCapabilities: PlaybookHostConstructionCapabilities & PlaybookHostCapabilities): PlaybookRuntime;
28
29
  }
29
30
  export declare const devStateCountLabels: {
30
31
  readonly planAnalysis: "planning round";
@@ -1,8 +1,9 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
3
 
4
+ import type { PlaybookHostConstructionCapabilities } from '../code.playbook/playbook-captain.js';
4
5
  import createPlaybookRuntime, {
5
- type DevPlaybookHostCapabilities,
6
+ type PlaybookHostCapabilities,
6
7
  type PlaybookRuntime,
7
8
  } from './dev.playbook.js';
8
9
 
@@ -33,9 +34,12 @@ export interface DevPlaybookRegistryEntry {
33
34
  concurrentRoleSets: readonly [];
34
35
  summaryPolicy: PlaybookSummaryPolicy;
35
36
  validateOptions(optionSlice: unknown): DevOptions;
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: DevOptions,
38
- hostCapabilities: DevPlaybookHostCapabilities,
41
+ hostCapabilities: PlaybookHostConstructionCapabilities &
42
+ PlaybookHostCapabilities,
39
43
  ): PlaybookRuntime;
40
44
  }
41
45