@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.
Files changed (61) hide show
  1. package/README.md +17 -4
  2. package/docs/cli.md +74 -29
  3. package/docs/configuration.md +209 -112
  4. package/docs/embedding.md +71 -25
  5. package/package.json +4 -3
  6. package/reference/sdlc/captain.playbook/captain.playbook.js +3 -3
  7. package/reference/sdlc/captain.playbook/captain.playbook.ts +3 -3
  8. package/reference/sdlc/code.md +1 -1
  9. package/reference/sdlc/code.playbook/bin/interactive-session.js +816 -0
  10. package/reference/sdlc/code.playbook/bin/launch-config.js +1078 -116
  11. package/reference/sdlc/code.playbook/bin/playbook.js +489 -34
  12. package/reference/sdlc/code.playbook/bin/run.js +283 -298
  13. package/reference/sdlc/code.playbook/bin/session-store.js +818 -26
  14. package/reference/sdlc/code.playbook/code.fsm.d.ts +5 -5
  15. package/reference/sdlc/code.playbook/code.fsm.introspect.js +2 -2
  16. package/reference/sdlc/code.playbook/code.fsm.introspect.ts +2 -2
  17. package/reference/sdlc/code.playbook/code.fsm.js +7 -11
  18. package/reference/sdlc/code.playbook/code.fsm.ts +9 -17
  19. package/reference/sdlc/code.playbook/code.gears.md +1 -1
  20. package/reference/sdlc/code.playbook/code.playbook.d.ts +2 -1
  21. package/reference/sdlc/code.playbook/code.playbook.js +12 -13
  22. package/reference/sdlc/code.playbook/code.playbook.ts +22 -15
  23. package/reference/sdlc/code.playbook/code.registry.d.ts +5 -13
  24. package/reference/sdlc/code.playbook/code.registry.js +3 -10
  25. package/reference/sdlc/code.playbook/code.registry.ts +7 -32
  26. package/reference/sdlc/code.playbook/playbook-captain.d.ts +39 -14
  27. package/reference/sdlc/code.playbook/playbook-captain.js +970 -289
  28. package/reference/sdlc/code.playbook/playbook-captain.ts +1403 -396
  29. package/reference/sdlc/code.playbook/playbook.config.template.yaml +41 -49
  30. package/reference/sdlc/decide.md +4 -4
  31. package/reference/sdlc/decide.playbook/decide.fsm.d.ts +9 -9
  32. package/reference/sdlc/decide.playbook/decide.fsm.js +21 -14
  33. package/reference/sdlc/decide.playbook/decide.fsm.ts +27 -23
  34. package/reference/sdlc/decide.playbook/decide.gears.md +3 -5
  35. package/reference/sdlc/decide.playbook/decide.playbook.d.ts +9 -13
  36. package/reference/sdlc/decide.playbook/decide.playbook.js +171 -134
  37. package/reference/sdlc/decide.playbook/decide.playbook.ts +238 -162
  38. package/reference/sdlc/decide.playbook/decide.registry.d.ts +5 -13
  39. package/reference/sdlc/decide.playbook/decide.registry.js +3 -9
  40. package/reference/sdlc/decide.playbook/decide.registry.ts +7 -31
  41. package/reference/sdlc/review.md +4 -5
  42. package/reference/sdlc/review.playbook/review.fsm.d.ts +9 -11
  43. package/reference/sdlc/review.playbook/review.fsm.js +30 -24
  44. package/reference/sdlc/review.playbook/review.fsm.ts +39 -35
  45. package/reference/sdlc/review.playbook/review.gears.md +6 -5
  46. package/reference/sdlc/review.playbook/review.playbook.d.ts +2 -1
  47. package/reference/sdlc/review.playbook/review.playbook.js +16 -21
  48. package/reference/sdlc/review.playbook/review.playbook.ts +26 -26
  49. package/reference/sdlc/review.playbook/review.registry.d.ts +5 -13
  50. package/reference/sdlc/review.playbook/review.registry.js +3 -16
  51. package/reference/sdlc/review.playbook/review.registry.ts +7 -38
  52. package/slc/gears2fsm.md +27 -23
  53. package/slc/link.md +113 -93
  54. package/slc/text2gears.md +19 -18
  55. package/src/runtime.d.ts +20 -16
  56. package/src/runtime.ts +19 -23
  57. package/src/xstate-playbook-runtime.d.ts +21 -17
  58. package/src/xstate-playbook-runtime.js +241 -149
  59. package/src/xstate-playbook-runtime.ts +331 -178
  60. package/src/xstate-runtime.js +63 -24
  61. package/src/xstate-runtime.ts +96 -28
package/src/runtime.ts CHANGED
@@ -19,17 +19,22 @@ export interface PlayerCallOptions {
19
19
  resume: string | false;
20
20
  }
21
21
 
22
- // DR-030: a composing host may supply one frame-local view of the root
23
- // engagement's player continuation. The runtime selects through this store
22
+ // DR-032: a composing host may supply one frame-local role view of the
23
+ // Captain session's player continuation. The runtime selects through this store
24
24
  // before tracing/calling and updates it from the validated result. Hosts that
25
25
  // omit it retain the runtime's private per-session store.
26
26
  export interface PlayerSessionStore {
27
- select(playerId: string): string | false;
28
- update(playerId: string, resumeToken?: string): void;
27
+ select(roleId: string): string | false;
28
+ update(roleId: string, resumeToken?: string): void;
29
29
  snapshot(): Readonly<Record<string, string>>;
30
30
  restore(tokens: Readonly<Record<string, string>>): void;
31
31
  }
32
32
 
33
+ export interface PlaybookRoleBinding {
34
+ readonly playerId: string;
35
+ readonly promptIdentity: string;
36
+ }
37
+
33
38
  export interface CaptainCallOptions {
34
39
  visibility: 'visible' | 'hidden';
35
40
  resume: string | false;
@@ -137,7 +142,7 @@ export type PlaybookRunResult =
137
142
 
138
143
  export interface PlaybookPorts {
139
144
  callPlayer(
140
- playerId: string,
145
+ roleId: string,
141
146
  prompt: string,
142
147
  signal: AbortSignal,
143
148
  options: PlayerCallOptions,
@@ -163,6 +168,7 @@ export interface PlaybookSession {
163
168
  parentSessionId?: string;
164
169
  parentCallId?: string;
165
170
  depth: number;
171
+ roleBindings?: Readonly<Record<string, PlaybookRoleBinding>>;
166
172
  playerSessions?: PlayerSessionStore;
167
173
  ports: PlaybookPorts;
168
174
  }
@@ -186,7 +192,7 @@ export type PlaybookTraceType =
186
192
  | 'session.disposed';
187
193
 
188
194
  export interface PlaybookTraceEvent {
189
- schemaVersion: 2;
195
+ schemaVersion: 3;
190
196
  sessionId: string;
191
197
  playbookId: string;
192
198
  rootSessionId: string;
@@ -203,19 +209,20 @@ export interface PlaybookTraceEvent {
203
209
 
204
210
  export interface PlaybookPendingBossQuestion {
205
211
  questionId: string;
206
- player: string;
212
+ asker: { kind: 'captain' } | { kind: 'role'; roleId: string };
207
213
  question: string;
208
214
  sourceItem?: string;
209
215
  }
210
216
 
211
- // DR-014 §1 / DR-031 §5: JSON-safe capture of a parked or nested-call
217
+ // DR-014 §1 / DR-031 §5 / DR-032: JSON-safe capture of a parked or nested-call
212
218
  // suspended session. `machine` is the opaque XState persisted snapshot;
213
- // pending Boss questions and a schema-2 suspended call are first-class so a
219
+ // pending Boss questions and a suspended call are first-class so a
214
220
  // host never has to reconstruct durable ownership from presentation records.
215
- interface PlaybookRuntimeSnapshotFields {
221
+ export interface PlaybookRuntimeSnapshot {
222
+ schemaVersion: 3;
216
223
  playbookId: string;
217
224
  machine: JsonValue;
218
- playerResumeTokens: { readonly [playerId: string]: string };
225
+ roleResumeTokens: { readonly [roleId: string]: string };
219
226
  sequences: {
220
227
  trace: number;
221
228
  turn: number;
@@ -226,20 +233,9 @@ interface PlaybookRuntimeSnapshotFields {
226
233
  };
227
234
  state: PlaybookState;
228
235
  pendingBossQuestions: readonly PlaybookPendingBossQuestion[];
236
+ suspendedCall?: PlaybookSuspendedCall;
229
237
  }
230
238
 
231
- export type PlaybookRuntimeSnapshot = PlaybookRuntimeSnapshotFields &
232
- (
233
- | {
234
- schemaVersion: 1;
235
- suspendedCall?: never;
236
- }
237
- | {
238
- schemaVersion: 2;
239
- suspendedCall?: PlaybookSuspendedCall;
240
- }
241
- );
242
-
243
239
  // DR-029: one currently valid, runtime-advertised control action. The id
244
240
  // is stable within the returned view; the label is runtime-written,
245
241
  // Boss-appropriate text derived from source state descriptions.
@@ -4,12 +4,17 @@ export interface PlaybookPendingBossQuestionContext {
4
4
  questionId: string;
5
5
  resumeStateId: string;
6
6
  sourceItem: string;
7
- player: string;
7
+ asker: {
8
+ kind: 'captain';
9
+ } | {
10
+ kind: 'role';
11
+ roleId: string;
12
+ };
8
13
  question: string;
9
14
  }
10
15
  export interface PlaybookPlayerInput {
11
16
  stateId: string;
12
- player: string;
17
+ role: string;
13
18
  sourceItem: string;
14
19
  prompt: string;
15
20
  result: Readonly<Record<string, string>>;
@@ -46,7 +51,7 @@ export type JudgePurpose = 'boss-input-classification' | 'player-output-adjudica
46
51
  * exercise composition/adjudication without a live runtime.
47
52
  */
48
53
  export interface RuntimeBoundaryCalls {
49
- callPlayer(input: PlaybookPlayerInput, playerId: string, prompt: string, signal: AbortSignal): Promise<PlayerResult>;
54
+ callPlayer(input: PlaybookPlayerInput, roleId: string, prompt: string, signal: AbortSignal): Promise<PlayerResult>;
50
55
  callJudge(purpose: JudgePurpose, stateId: string | undefined, prompt: string, signal: AbortSignal): Promise<string>;
51
56
  callCaptain?(input: PlaybookCaptainInput, prompt: string, signal: AbortSignal, callOptions?: XStateCaptainCallOptions): Promise<CaptainResult>;
52
57
  }
@@ -68,10 +73,12 @@ export interface ScheduledStatus {
68
73
  data?: JsonValue;
69
74
  }
70
75
  /** Boss-facing identity for one FSM state whose invoked actor is `player`. */
71
- export interface XStatePlayerStateStatus {
72
- player: string;
76
+ export interface XStateRoleStateStatus {
77
+ role: string;
73
78
  label: string;
74
79
  }
80
+ /** Invocation-scoped lookup exposed only while composing a player prompt. */
81
+ export type XStatePromptIdentity = (roleId: string) => string;
75
82
  export interface XStateBossEventFieldSpec {
76
83
  /** The judge supplies routing data; the runtime supplies exact Boss text. */
77
84
  source: 'judge' | 'text';
@@ -144,8 +151,8 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
144
151
  label?: string;
145
152
  /**
146
153
  * Link-time compatibility declaration checked at construction against the
147
- * loaded engine's self-report (DR-022). Absent: a legacy artifact emitted
148
- * before the contract constructed with no compatibility check.
154
+ * loaded engine's self-report (DR-022). Absent declarations reject because
155
+ * their overloaded player metadata has no safe local-role interpretation.
149
156
  */
150
157
  compat?: XStatePlaybookRuntimeCompat;
151
158
  /** Validate and JSON-snapshot the caller's per-run options. */
@@ -182,14 +189,12 @@ export interface XStatePlaybookRuntimeSpec<TOptions> {
182
189
  * recoverable FSM-result failures instead.
183
190
  */
184
191
  captainStrategy?: XStateCaptainStrategy<TOptions>;
185
- /** Status line emitted after classification; canonical metadata defaults to the event type, legacy artifacts to none. */
192
+ /** Status line emitted after classification; metadata defaults to the event type. */
186
193
  classificationStatus?: (event: EventObject) => string | undefined;
187
- /** Complete FSM-derived Boss-facing metadata for every `player` state; its presence selects the canonical status profile. */
188
- playerStates?: Readonly<Record<string, XStatePlayerStateStatus>>;
189
- /** Map a player-invoking state's input to the host player id. Default: lowercased player name. */
190
- resolvePlayerId?: (input: PlaybookPlayerInput, options: TOptions) => string;
194
+ /** Complete FSM-derived Boss-facing metadata for every `player` state. */
195
+ roleStates?: Readonly<Record<string, XStateRoleStateStatus>>;
191
196
  /** Compose the player prompt. Default: continuation blocks + `<field>` placeholder substitution. */
192
- composePlayerPrompt?: (input: PlaybookPlayerInput) => string;
197
+ composePlayerPrompt?: (input: PlaybookPlayerInput, promptIdentity: XStatePromptIdentity) => string;
193
198
  /** Compose the direct-Captain prompt. Default: continuation blocks + placeholder substitution with deterministic JSON rendering. */
194
199
  composeCaptainPrompt?: (input: PlaybookCaptainInput) => string;
195
200
  /** Linker-known exceptions to the default kebab-token → camel-field mapping. */
@@ -253,8 +258,6 @@ export declare function defaultComposePlayerPrompt(input: PlaybookPlayerInput, p
253
258
  * with lexicographically sorted keys at every depth.
254
259
  */
255
260
  export declare function defaultComposeCaptainPrompt(input: PlaybookCaptainInput, placeholderFields?: Readonly<Record<string, string>>): string;
256
- /** Default player binding: each player to its lowercased name. */
257
- export declare function defaultResolvePlayerId(input: PlaybookPlayerInput): string;
258
261
  /**
259
262
  * Default required-field extraction (slc/link.md §Captain adjudication).
260
263
  * Limited to the description's `Output shall include` / `输出应包含` clause;
@@ -278,8 +281,8 @@ export interface PlayerAdjudicationSpec {
278
281
  * long-form prose through judge JSON.
279
282
  */
280
283
  export declare function adjudicatePlayerOutput(spec: PlayerAdjudicationSpec, input: PlaybookPlayerInput, finalText: string, ports: PlaybookPorts, signal: AbortSignal, boundary?: RuntimeBoundaryCalls): Promise<PlaybookActorOutput>;
281
- export interface PlayerBridgeSpec {
282
- resolvePlayerId: (input: PlaybookPlayerInput) => string;
284
+ interface PlayerBridgeSpec {
285
+ resolveRoleId: (input: PlaybookPlayerInput) => string;
283
286
  composePlayerPrompt: (input: PlaybookPlayerInput) => string;
284
287
  adjudication: PlayerAdjudicationSpec;
285
288
  resumableStateIds: ReadonlySet<string>;
@@ -315,3 +318,4 @@ export declare function stateDescriptionsFromMachine(machine: AnyStateMachine):
315
318
  * runtimes.
316
319
  */
317
320
  export declare function createXStatePlaybookRuntime<TOptions>(machine: AnyStateMachine, spec: XStatePlaybookRuntimeSpec<TOptions>): PlaybookRuntimeFactory<TOptions>;
321
+ export {};