@sublang/playbook 7.0.0 → 9.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 (62) hide show
  1. package/README.md +20 -7
  2. package/docs/cli.md +88 -43
  3. package/docs/configuration.md +221 -119
  4. package/docs/embedding.md +78 -27
  5. package/package.json +4 -3
  6. package/reference/sdlc/captain.playbook/captain.playbook.js +16 -5
  7. package/reference/sdlc/captain.playbook/captain.playbook.ts +20 -6
  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 +9 -6
  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 +18 -15
  18. package/reference/sdlc/code.playbook/code.fsm.ts +21 -21
  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 +25 -15
  22. package/reference/sdlc/code.playbook/code.playbook.ts +34 -17
  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 +1014 -299
  28. package/reference/sdlc/code.playbook/playbook-captain.ts +1450 -406
  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 +10 -10
  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 +11 -13
  36. package/reference/sdlc/decide.playbook/decide.playbook.js +465 -246
  37. package/reference/sdlc/decide.playbook/decide.playbook.ts +623 -283
  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 +29 -23
  48. package/reference/sdlc/review.playbook/review.playbook.ts +38 -28
  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 +45 -24
  53. package/slc/link.md +297 -135
  54. package/slc/text2gears.md +19 -18
  55. package/src/runtime.d.ts +21 -16
  56. package/src/runtime.ts +20 -23
  57. package/src/xstate-playbook-runtime.d.ts +34 -20
  58. package/src/xstate-playbook-runtime.js +973 -400
  59. package/src/xstate-playbook-runtime.ts +1203 -457
  60. package/src/xstate-runtime.d.ts +17 -7
  61. package/src/xstate-runtime.js +198 -81
  62. package/src/xstate-runtime.ts +339 -112
@@ -8,18 +8,20 @@ export type PendingBossQuestion = {
8
8
  readonly questionId: 'runFirstPhase' | 'runIrTask';
9
9
  readonly resumeStateId: 'runFirstPhase' | 'runIrTask';
10
10
  readonly sourceItem: 'CODE-1' | 'CODE-3';
11
- readonly player: 'Coder';
11
+ readonly asker: {
12
+ readonly kind: 'role';
13
+ readonly roleId: 'coder';
14
+ };
12
15
  readonly question: string;
13
16
  };
14
17
  export type PlayerInput = {
15
18
  readonly stateId: 'runFirstPhase' | 'runIrTask';
16
- readonly player: 'Coder';
19
+ readonly role: 'coder';
17
20
  readonly sourceItem: 'CODE-1' | 'CODE-3';
18
21
  readonly prompt: string;
19
22
  readonly result: Readonly<Record<string, string>>;
20
23
  readonly callerInput: string;
21
24
  readonly runResults: string;
22
- readonly coderPlayer: string;
23
25
  readonly irNumber?: string;
24
26
  readonly irTask?: string;
25
27
  readonly pendingBossQuestion?: PendingBossQuestion;
@@ -77,11 +79,9 @@ export type CodePlaybookOutput = {
77
79
  readonly error: CompactError;
78
80
  };
79
81
  export type CodingInput = {
80
- readonly coderPlayer?: string;
81
82
  readonly runResults?: string;
82
83
  };
83
84
  export type CodingContext = {
84
- readonly coderPlayer: string;
85
85
  readonly runResults: string;
86
86
  readonly callerInput?: string;
87
87
  readonly coderOutput?: string;
@@ -202,7 +202,7 @@ export declare const codingMachine: import("xstate").StateMachine<CodingContext,
202
202
  } | {
203
203
  type: "resumesIrTask";
204
204
  params: unknown;
205
- }, never, "done" | "failed" | "awaitBossReply" | "ready" | "runFirstPhase" | "reviewFirstCommit" | "runIrTask" | "reviewIrTask", string, CodingInput, {
205
+ }, never, "done" | "failed" | "awaitBossReply" | "ready" | "runFirstPhase" | "reviewFirstCommit" | "runIrTask" | "reviewIrTask" | "reportedReviewFailure", string, CodingInput, {
206
206
  readonly status: "complete";
207
207
  /** Exact identity of the latest CODE-owned commit. */
208
208
  readonly lastCodeCommit: string;
@@ -239,6 +239,9 @@ export declare const codingMachine: import("xstate").StateMachine<CodingContext,
239
239
  readonly failed: {
240
240
  id: "failed";
241
241
  };
242
+ readonly reportedReviewFailure: {
243
+ id: "reportedReviewFailure";
244
+ };
242
245
  readonly done: {
243
246
  id: "done";
244
247
  };
@@ -27,7 +27,7 @@ export function enumeratePlayerStates(machine) {
27
27
  if (invoke?.src !== 'player' || invoke.input === undefined)
28
28
  return [];
29
29
  const getInput = (context) => invoke.input?.({ context });
30
- const input = getInput({ coderPlayer: 'Coder', runResults: '' });
30
+ const input = getInput({ runResults: '' });
31
31
  return [
32
32
  {
33
33
  stateId,
@@ -47,7 +47,7 @@ export function enumerateNestedPlaybookStates(machine) {
47
47
  if (invoke?.src !== 'playbook' || invoke.input === undefined)
48
48
  return [];
49
49
  const getInput = (context) => invoke.input?.({ context });
50
- const input = getInput({ coderPlayer: 'Coder', runResults: '' });
50
+ const input = getInput({ runResults: '' });
51
51
  return [
52
52
  {
53
53
  stateId,
@@ -92,7 +92,7 @@ export function enumeratePlayerStates(
92
92
  if (invoke?.src !== 'player' || invoke.input === undefined) return [];
93
93
  const getInput = (context: CodingContext): PlayerInput =>
94
94
  invoke.input?.({ context }) as PlayerInput;
95
- const input = getInput({ coderPlayer: 'Coder', runResults: '' });
95
+ const input = getInput({ runResults: '' });
96
96
  return [
97
97
  {
98
98
  stateId,
@@ -116,7 +116,7 @@ export function enumerateNestedPlaybookStates(
116
116
  if (invoke?.src !== 'playbook' || invoke.input === undefined) return [];
117
117
  const getInput = (context: CodingContext): PlaybookInput =>
118
118
  invoke.input?.({ context }) as PlaybookInput;
119
- const input = getInput({ coderPlayer: 'Coder', runResults: '' });
119
+ const input = getInput({ runResults: '' });
120
120
  return [
121
121
  {
122
122
  stateId,
@@ -53,14 +53,15 @@ const STATE_DESCRIPTIONS = {
53
53
  reviewIrTask: 'The REVIEW playbook is checking the latest task commit.',
54
54
  awaitBossReply: 'Waiting for Boss to answer Coder.',
55
55
  failed: 'The coding workflow failed and is waiting for a new coding intent.',
56
+ reportedReviewFailure: 'The coding workflow reported a REVIEW failure and the last code-owned commit.',
56
57
  done: 'The coding workflow completed after REVIEW found no unsettled findings.',
57
58
  };
58
- function playbookMeta(stateId, player) {
59
+ function playbookMeta(stateId, role) {
59
60
  return {
60
61
  playbook: {
61
62
  stateId,
62
63
  description: STATE_DESCRIPTIONS[stateId],
63
- ...(player === undefined ? {} : { player }),
64
+ ...(role === undefined ? {} : { role }),
64
65
  },
65
66
  };
66
67
  }
@@ -324,7 +325,6 @@ const machineSetup = setup({
324
325
  if (event.type !== 'START_CODE')
325
326
  return {};
326
327
  return {
327
- coderPlayer: context.coderPlayer,
328
328
  runResults: context.runResults,
329
329
  callerInput: event.callerInput,
330
330
  coderOutput: undefined,
@@ -389,7 +389,7 @@ const machineSetup = setup({
389
389
  questionId: stateId,
390
390
  resumeStateId: stateId,
391
391
  sourceItem: stateId === 'runFirstPhase' ? 'CODE-1' : 'CODE-3',
392
- player: 'Coder',
392
+ asker: { kind: 'role', roleId: 'coder' },
393
393
  question,
394
394
  },
395
395
  bossReply: undefined,
@@ -430,7 +430,6 @@ export const codingMachine = machineSetup.createMachine({
430
430
  id: 'code',
431
431
  initial: 'ready',
432
432
  context: ({ input }) => ({
433
- coderPlayer: isNonEmptyString(input.coderPlayer) ? input.coderPlayer : 'Coder',
434
433
  runResults: typeof input.runResults === 'string' ? input.runResults : '',
435
434
  }),
436
435
  output: ({ context }) => {
@@ -465,19 +464,18 @@ export const codingMachine = machineSetup.createMachine({
465
464
  runFirstPhase: {
466
465
  id: 'runFirstPhase',
467
466
  description: STATE_DESCRIPTIONS.runFirstPhase,
468
- meta: playbookMeta('runFirstPhase', 'Coder'),
467
+ meta: playbookMeta('runFirstPhase', 'coder'),
469
468
  tags: ['playbook.busy'],
470
469
  invoke: {
471
470
  src: 'player',
472
471
  input: ({ context }) => ({
473
472
  stateId: 'runFirstPhase',
474
- player: 'Coder',
473
+ role: 'coder',
475
474
  sourceItem: 'CODE-1',
476
475
  prompt: FIRST_PHASE_PROMPT,
477
476
  result: FIRST_PHASE_RESULTS,
478
477
  callerInput: context.callerInput ?? '',
479
478
  runResults: context.runResults,
480
- coderPlayer: context.coderPlayer,
481
479
  ...(context.pendingBossQuestion === undefined
482
480
  ? {}
483
481
  : { pendingBossQuestion: context.pendingBossQuestion }),
@@ -533,14 +531,14 @@ export const codingMachine = machineSetup.createMachine({
533
531
  target: 'runIrTask',
534
532
  },
535
533
  {
536
- target: 'done',
534
+ target: 'reportedReviewFailure',
537
535
  actions: 'completeWithInvalidReviewOutput',
538
536
  },
539
537
  ],
540
538
  onError: [
541
539
  {
542
540
  guard: 'authoredReviewFailure',
543
- target: 'done',
541
+ target: 'reportedReviewFailure',
544
542
  actions: 'completeWithReviewFailure',
545
543
  },
546
544
  { target: 'failed', actions: 'rememberActorError' },
@@ -550,19 +548,18 @@ export const codingMachine = machineSetup.createMachine({
550
548
  runIrTask: {
551
549
  id: 'runIrTask',
552
550
  description: STATE_DESCRIPTIONS.runIrTask,
553
- meta: playbookMeta('runIrTask', 'Coder'),
551
+ meta: playbookMeta('runIrTask', 'coder'),
554
552
  tags: ['playbook.busy'],
555
553
  invoke: {
556
554
  src: 'player',
557
555
  input: ({ context }) => ({
558
556
  stateId: 'runIrTask',
559
- player: 'Coder',
557
+ role: 'coder',
560
558
  sourceItem: 'CODE-3',
561
559
  prompt: IR_TASK_PROMPT,
562
560
  result: IR_TASK_RESULTS,
563
561
  callerInput: context.callerInput ?? '',
564
562
  runResults: context.runResults,
565
- coderPlayer: context.coderPlayer,
566
563
  ...(context.irNumber === undefined
567
564
  ? {}
568
565
  : { irNumber: context.irNumber }),
@@ -623,14 +620,14 @@ export const codingMachine = machineSetup.createMachine({
623
620
  actions: 'completeSuccessfully',
624
621
  },
625
622
  {
626
- target: 'done',
623
+ target: 'reportedReviewFailure',
627
624
  actions: 'completeWithInvalidReviewOutput',
628
625
  },
629
626
  ],
630
627
  onError: [
631
628
  {
632
629
  guard: 'authoredReviewFailure',
633
- target: 'done',
630
+ target: 'reportedReviewFailure',
634
631
  actions: 'completeWithReviewFailure',
635
632
  },
636
633
  { target: 'failed', actions: 'rememberActorError' },
@@ -674,6 +671,12 @@ export const codingMachine = machineSetup.createMachine({
674
671
  START_CODE: { target: 'runFirstPhase', actions: 'startCoding' },
675
672
  },
676
673
  },
674
+ reportedReviewFailure: {
675
+ id: 'reportedReviewFailure',
676
+ description: STATE_DESCRIPTIONS.reportedReviewFailure,
677
+ meta: playbookMeta('reportedReviewFailure'),
678
+ type: 'final',
679
+ },
677
680
  done: {
678
681
  id: 'done',
679
682
  description: STATE_DESCRIPTIONS.done,
@@ -31,19 +31,18 @@ export type PendingBossQuestion = {
31
31
  readonly questionId: 'runFirstPhase' | 'runIrTask';
32
32
  readonly resumeStateId: 'runFirstPhase' | 'runIrTask';
33
33
  readonly sourceItem: 'CODE-1' | 'CODE-3';
34
- readonly player: 'Coder';
34
+ readonly asker: { readonly kind: 'role'; readonly roleId: 'coder' };
35
35
  readonly question: string;
36
36
  };
37
37
 
38
38
  export type PlayerInput = {
39
39
  readonly stateId: 'runFirstPhase' | 'runIrTask';
40
- readonly player: 'Coder';
40
+ readonly role: 'coder';
41
41
  readonly sourceItem: 'CODE-1' | 'CODE-3';
42
42
  readonly prompt: string;
43
43
  readonly result: Readonly<Record<string, string>>;
44
44
  readonly callerInput: string;
45
45
  readonly runResults: string;
46
- readonly coderPlayer: string;
47
46
  readonly irNumber?: string;
48
47
  readonly irTask?: string;
49
48
  readonly pendingBossQuestion?: PendingBossQuestion;
@@ -114,12 +113,10 @@ export type CodePlaybookOutput =
114
113
  };
115
114
 
116
115
  export type CodingInput = {
117
- readonly coderPlayer?: string;
118
116
  readonly runResults?: string;
119
117
  };
120
118
 
121
119
  export type CodingContext = {
122
- readonly coderPlayer: string;
123
120
  readonly runResults: string;
124
121
  readonly callerInput?: string;
125
122
  readonly coderOutput?: string;
@@ -205,18 +202,20 @@ const STATE_DESCRIPTIONS = {
205
202
  reviewIrTask: 'The REVIEW playbook is checking the latest task commit.',
206
203
  awaitBossReply: 'Waiting for Boss to answer Coder.',
207
204
  failed: 'The coding workflow failed and is waiting for a new coding intent.',
205
+ reportedReviewFailure:
206
+ 'The coding workflow reported a REVIEW failure and the last code-owned commit.',
208
207
  done: 'The coding workflow completed after REVIEW found no unsettled findings.',
209
208
  } as const;
210
209
 
211
210
  function playbookMeta<StateId extends keyof typeof STATE_DESCRIPTIONS>(
212
211
  stateId: StateId,
213
- player?: 'Coder',
212
+ role?: 'coder',
214
213
  ) {
215
214
  return {
216
215
  playbook: {
217
216
  stateId,
218
217
  description: STATE_DESCRIPTIONS[stateId],
219
- ...(player === undefined ? {} : { player }),
218
+ ...(role === undefined ? {} : { role }),
220
219
  },
221
220
  };
222
221
  }
@@ -557,7 +556,6 @@ const machineSetup = setup({
557
556
  startCoding: assign(({ context, event }) => {
558
557
  if (event.type !== 'START_CODE') return {};
559
558
  return {
560
- coderPlayer: context.coderPlayer,
561
559
  runResults: context.runResults,
562
560
  callerInput: event.callerInput,
563
561
  coderOutput: undefined,
@@ -623,7 +621,7 @@ const machineSetup = setup({
623
621
  questionId: stateId,
624
622
  resumeStateId: stateId,
625
623
  sourceItem: stateId === 'runFirstPhase' ? 'CODE-1' : 'CODE-3',
626
- player: 'Coder',
624
+ asker: { kind: 'role', roleId: 'coder' },
627
625
  question,
628
626
  },
629
627
  bossReply: undefined,
@@ -670,8 +668,6 @@ export const codingMachine = machineSetup.createMachine({
670
668
  id: 'code',
671
669
  initial: 'ready',
672
670
  context: ({ input }) => ({
673
- coderPlayer:
674
- isNonEmptyString(input.coderPlayer) ? input.coderPlayer : 'Coder',
675
671
  runResults: typeof input.runResults === 'string' ? input.runResults : '',
676
672
  }),
677
673
  output: ({ context }): CodePlaybookOutput => {
@@ -707,19 +703,18 @@ export const codingMachine = machineSetup.createMachine({
707
703
  runFirstPhase: {
708
704
  id: 'runFirstPhase',
709
705
  description: STATE_DESCRIPTIONS.runFirstPhase,
710
- meta: playbookMeta('runFirstPhase', 'Coder'),
706
+ meta: playbookMeta('runFirstPhase', 'coder'),
711
707
  tags: ['playbook.busy'],
712
708
  invoke: {
713
709
  src: 'player',
714
710
  input: ({ context }): PlayerInput => ({
715
711
  stateId: 'runFirstPhase',
716
- player: 'Coder',
712
+ role: 'coder',
717
713
  sourceItem: 'CODE-1',
718
714
  prompt: FIRST_PHASE_PROMPT,
719
715
  result: FIRST_PHASE_RESULTS,
720
716
  callerInput: context.callerInput ?? '',
721
717
  runResults: context.runResults,
722
- coderPlayer: context.coderPlayer,
723
718
  ...(context.pendingBossQuestion === undefined
724
719
  ? {}
725
720
  : { pendingBossQuestion: context.pendingBossQuestion }),
@@ -775,14 +770,14 @@ export const codingMachine = machineSetup.createMachine({
775
770
  target: 'runIrTask',
776
771
  },
777
772
  {
778
- target: 'done',
773
+ target: 'reportedReviewFailure',
779
774
  actions: 'completeWithInvalidReviewOutput',
780
775
  },
781
776
  ],
782
777
  onError: [
783
778
  {
784
779
  guard: 'authoredReviewFailure',
785
- target: 'done',
780
+ target: 'reportedReviewFailure',
786
781
  actions: 'completeWithReviewFailure',
787
782
  },
788
783
  { target: 'failed', actions: 'rememberActorError' },
@@ -792,19 +787,18 @@ export const codingMachine = machineSetup.createMachine({
792
787
  runIrTask: {
793
788
  id: 'runIrTask',
794
789
  description: STATE_DESCRIPTIONS.runIrTask,
795
- meta: playbookMeta('runIrTask', 'Coder'),
790
+ meta: playbookMeta('runIrTask', 'coder'),
796
791
  tags: ['playbook.busy'],
797
792
  invoke: {
798
793
  src: 'player',
799
794
  input: ({ context }): PlayerInput => ({
800
795
  stateId: 'runIrTask',
801
- player: 'Coder',
796
+ role: 'coder',
802
797
  sourceItem: 'CODE-3',
803
798
  prompt: IR_TASK_PROMPT,
804
799
  result: IR_TASK_RESULTS,
805
800
  callerInput: context.callerInput ?? '',
806
801
  runResults: context.runResults,
807
- coderPlayer: context.coderPlayer,
808
802
  ...(context.irNumber === undefined
809
803
  ? {}
810
804
  : { irNumber: context.irNumber }),
@@ -865,14 +859,14 @@ export const codingMachine = machineSetup.createMachine({
865
859
  actions: 'completeSuccessfully',
866
860
  },
867
861
  {
868
- target: 'done',
862
+ target: 'reportedReviewFailure',
869
863
  actions: 'completeWithInvalidReviewOutput',
870
864
  },
871
865
  ],
872
866
  onError: [
873
867
  {
874
868
  guard: 'authoredReviewFailure',
875
- target: 'done',
869
+ target: 'reportedReviewFailure',
876
870
  actions: 'completeWithReviewFailure',
877
871
  },
878
872
  { target: 'failed', actions: 'rememberActorError' },
@@ -916,6 +910,12 @@ export const codingMachine = machineSetup.createMachine({
916
910
  START_CODE: { target: 'runFirstPhase', actions: 'startCoding' },
917
911
  },
918
912
  },
913
+ reportedReviewFailure: {
914
+ id: 'reportedReviewFailure',
915
+ description: STATE_DESCRIPTIONS.reportedReviewFailure,
916
+ meta: playbookMeta('reportedReviewFailure'),
917
+ type: 'final',
918
+ },
919
919
  done: {
920
920
  id: 'done',
921
921
  description: STATE_DESCRIPTIONS.done,
@@ -3,7 +3,7 @@
3
3
 
4
4
  # CODE: Commit-Based Coding Workflow
5
5
 
6
- Players:
6
+ Roles:
7
7
 
8
8
  - Coder
9
9
 
@@ -1,3 +1,4 @@
1
+ import { type XStatePromptIdentity } from '@sublang/playbook/xstate-runtime';
1
2
  import { type CodingInput, type PlayerInput } from './code.fsm.js';
2
3
  import type { CaptainCallOptions, CaptainResult, JsonValue, NormalizedError, PlayerCallOptions, PlaybookCallRequest, PlaybookCallResult, PlaybookCallStart, PlaybookControlReceipt, PlaybookControlView, PlaybookPendingCall, PlaybookPorts, PlaybookRunResult, PlaybookRuntime, PlaybookRuntimeFactory, PlaybookRuntimeSnapshot, PlaybookSession, PlaybookState, PlaybookStateValue, PlaybookTraceEvent, PlaybookTraceType, PlayerResult, PlayerSessionStore } from '@sublang/playbook/runtime';
3
4
  export type { CaptainCallOptions, CaptainResult, JsonValue, NormalizedError, PlayerCallOptions, PlaybookCallRequest, PlaybookCallResult, PlaybookCallStart, PlaybookControlReceipt, PlaybookControlView, PlaybookPendingCall, PlaybookPorts, PlaybookRunResult, PlaybookRuntime, PlaybookRuntimeFactory, PlaybookRuntimeSnapshot, PlaybookSession, PlaybookState, PlaybookStateValue, PlaybookTraceEvent, PlaybookTraceType, PlayerResult, PlayerSessionStore, };
@@ -7,7 +8,7 @@ export type CodePlaybookOptions = CodingInput;
7
8
  * runtime text. The generic composer preserves the marker itself; CODE's
8
9
  * override additionally keeps a multiline value inside that quote.
9
10
  */
10
- declare function composePlayerPrompt(input: PlayerInput): string;
11
+ declare function composePlayerPrompt(input: PlayerInput, promptIdentity: XStatePromptIdentity): string;
11
12
  export declare const _internal: {
12
13
  composePlayerPrompt: typeof composePlayerPrompt;
13
14
  VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string>;
@@ -3,15 +3,15 @@
3
3
  //
4
4
  // Generated by slc/link.md (FSM-to-Runtime linker).
5
5
  // Source FSM: ./code.fsm.ts
6
- // Player bind: Coder→coder (default lowercased binding)
6
+ // Role metadata: Coder→coder (canonical local role)
7
7
  // Boss event: deterministic START_CODE entry; exact Boss text becomes
8
8
  // callerInput; pending Coder questions retain BOSS_REPLY
9
9
  // Adjudication: LLM judge per player state; coderOutput is carried verbatim
10
10
  // Nested call: literal review target through the shared bridge
11
- // Compat: artifact schema 1 / runtime ABI 1
12
- import { RUNTIME_ABI, createXStatePlaybookRuntime, snapshotJsonValue, } from '@sublang/playbook/xstate-runtime';
11
+ // Compat: artifact schema 2 / runtime ABI 1
12
+ import { createXStatePlaybookRuntime, snapshotJsonValue, } from '@sublang/playbook/xstate-runtime';
13
13
  import { codingMachine, } from './code.fsm.js';
14
- const OPTION_KEYS = new Set(['coderPlayer', 'runResults']);
14
+ const OPTION_KEYS = new Set(['runResults']);
15
15
  const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
16
16
  const CONTINUATION_PREAMBLE = 'You previously paused this task to ask Boss a question; Boss has now replied. Continue the same task using the reply below.';
17
17
  const VERBATIM_PAYLOAD_FIELDS = new Set([
@@ -38,8 +38,6 @@ function snapshotCodeOptions(value) {
38
38
  function placeholderField(token) {
39
39
  if (token === '#')
40
40
  return 'irNumber';
41
- if (token === 'coder-llm')
42
- return 'coderPlayer';
43
41
  return token.replace(/-([A-Za-z0-9_$])/g, (_match, next) => next.toUpperCase());
44
42
  }
45
43
  function quoteContinuation(value) {
@@ -50,14 +48,16 @@ function quoteContinuation(value) {
50
48
  * runtime text. The generic composer preserves the marker itself; CODE's
51
49
  * override additionally keeps a multiline value inside that quote.
52
50
  */
53
- function composePlayerPrompt(input) {
51
+ function composePlayerPrompt(input, promptIdentity) {
54
52
  const fields = input;
55
53
  const template = input.prompt
56
54
  .split('\n')
57
55
  .filter((line) => !(line === '> <run-results>' && input.runResults.length === 0))
58
56
  .join('\n');
59
57
  const body = template.replace(PLACEHOLDER, (match, token, offset, source) => {
60
- const value = fields[placeholderField(token)];
58
+ const value = token === 'coder-llm'
59
+ ? promptIdentity('coder')
60
+ : fields[placeholderField(token)];
61
61
  if (typeof value !== 'string')
62
62
  return match;
63
63
  const lineStart = source.lastIndexOf('\n', offset - 1) + 1;
@@ -81,21 +81,31 @@ export const _internal = {
81
81
  };
82
82
  const runtimeSpec = {
83
83
  label: 'CODE',
84
- compat: { artifactSchema: 1, runtimeAbi: RUNTIME_ABI },
84
+ // DR-022 / slc/link.md: the declaration carries the value current at link
85
+ // time — a literal, never the loading engine's RUNTIME_ABI self-report,
86
+ // which would follow whatever engine loads the module and make the
87
+ // factory's skew check compare that engine with itself.
88
+ compat: { artifactSchema: 2, runtimeAbi: 1 },
85
89
  snapshotOptions: snapshotCodeOptions,
86
- entryEvent: { type: 'START_CODE', textField: 'callerInput' },
87
- playerStates: {
90
+ entryEvent: {
91
+ type: 'START_CODE',
92
+ textField: 'callerInput',
93
+ // `startCoding` copies the entry text here, so the failure-state retry
94
+ // reads it back from the persisted machine snapshot and survives a
95
+ // continued session (DR-034).
96
+ contextField: 'callerInput',
97
+ },
98
+ roleStates: {
88
99
  runFirstPhase: {
89
- player: 'Coder',
100
+ role: 'coder',
90
101
  label: 'Coder is implementing one direct phase or committing a new intent record.',
91
102
  },
92
103
  runIrTask: {
93
- player: 'Coder',
104
+ role: 'coder',
94
105
  label: 'Coder is implementing exactly one unfinished intent-record task.',
95
106
  },
96
107
  },
97
- placeholderFields: { 'coder-llm': 'coderPlayer' },
98
- composePlayerPrompt: (input) => composePlayerPrompt(input),
108
+ composePlayerPrompt: (input, promptIdentity) => composePlayerPrompt(input, promptIdentity),
99
109
  verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
100
110
  controlContextFields: ['phase'],
101
111
  transitionEventFields: ['callerInput', 'answer', 'questionId'],
@@ -3,18 +3,18 @@
3
3
  //
4
4
  // Generated by slc/link.md (FSM-to-Runtime linker).
5
5
  // Source FSM: ./code.fsm.ts
6
- // Player bind: Coder→coder (default lowercased binding)
6
+ // Role metadata: Coder→coder (canonical local role)
7
7
  // Boss event: deterministic START_CODE entry; exact Boss text becomes
8
8
  // callerInput; pending Coder questions retain BOSS_REPLY
9
9
  // Adjudication: LLM judge per player state; coderOutput is carried verbatim
10
10
  // Nested call: literal review target through the shared bridge
11
- // Compat: artifact schema 1 / runtime ABI 1
11
+ // Compat: artifact schema 2 / runtime ABI 1
12
12
 
13
13
  import {
14
- RUNTIME_ABI,
15
14
  createXStatePlaybookRuntime,
16
15
  snapshotJsonValue,
17
16
  type PlaybookPlayerInput,
17
+ type XStatePromptIdentity,
18
18
  type XStatePlaybookRuntimeSpec,
19
19
  } from '@sublang/playbook/xstate-runtime';
20
20
  import {
@@ -76,7 +76,7 @@ export type {
76
76
 
77
77
  export type CodePlaybookOptions = CodingInput;
78
78
 
79
- const OPTION_KEYS = new Set(['coderPlayer', 'runResults']);
79
+ const OPTION_KEYS = new Set(['runResults']);
80
80
  const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
81
81
  const CONTINUATION_PREAMBLE =
82
82
  'You previously paused this task to ask Boss a question; Boss has now replied. Continue the same task using the reply below.';
@@ -108,7 +108,6 @@ function snapshotCodeOptions(value: unknown): CodePlaybookOptions {
108
108
 
109
109
  function placeholderField(token: string): string {
110
110
  if (token === '#') return 'irNumber';
111
- if (token === 'coder-llm') return 'coderPlayer';
112
111
  return token.replace(/-([A-Za-z0-9_$])/g, (_match, next: string) =>
113
112
  next.toUpperCase(),
114
113
  );
@@ -123,7 +122,10 @@ function quoteContinuation(value: string): string {
123
122
  * runtime text. The generic composer preserves the marker itself; CODE's
124
123
  * override additionally keeps a multiline value inside that quote.
125
124
  */
126
- function composePlayerPrompt(input: PlayerInput): string {
125
+ function composePlayerPrompt(
126
+ input: PlayerInput,
127
+ promptIdentity: XStatePromptIdentity,
128
+ ): string {
127
129
  const fields = input as unknown as Record<string, unknown>;
128
130
  const template = input.prompt
129
131
  .split('\n')
@@ -134,7 +136,10 @@ function composePlayerPrompt(input: PlayerInput): string {
134
136
  const body = template.replace(
135
137
  PLACEHOLDER,
136
138
  (match: string, token: string, offset: number, source: string) => {
137
- const value = fields[placeholderField(token)];
139
+ const value =
140
+ token === 'coder-llm'
141
+ ? promptIdentity('coder')
142
+ : fields[placeholderField(token)];
138
143
  if (typeof value !== 'string') return match;
139
144
  const lineStart = source.lastIndexOf('\n', offset - 1) + 1;
140
145
  const literal = source.slice(lineStart, offset);
@@ -160,29 +165,41 @@ export const _internal = {
160
165
  VERBATIM_PAYLOAD_FIELDS,
161
166
  };
162
167
 
163
- const runtimeSpec: XStatePlaybookRuntimeSpec<CodePlaybookOptions> = {
168
+ const runtimeSpec = {
164
169
  label: 'CODE',
165
- compat: { artifactSchema: 1, runtimeAbi: RUNTIME_ABI },
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: 2, runtimeAbi: 1 },
166
175
  snapshotOptions: snapshotCodeOptions,
167
- entryEvent: { type: 'START_CODE', textField: 'callerInput' },
168
- playerStates: {
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',
183
+ },
184
+ roleStates: {
169
185
  runFirstPhase: {
170
- player: 'Coder',
186
+ role: 'coder',
171
187
  label:
172
188
  'Coder is implementing one direct phase or committing a new intent record.',
173
189
  },
174
190
  runIrTask: {
175
- player: 'Coder',
191
+ role: 'coder',
176
192
  label: 'Coder is implementing exactly one unfinished intent-record task.',
177
193
  },
178
194
  },
179
- placeholderFields: { 'coder-llm': 'coderPlayer' },
180
- composePlayerPrompt: (input: PlaybookPlayerInput) =>
181
- composePlayerPrompt(input as PlayerInput),
195
+ composePlayerPrompt: (
196
+ input: PlaybookPlayerInput,
197
+ promptIdentity: XStatePromptIdentity,
198
+ ) => composePlayerPrompt(input as PlayerInput, promptIdentity),
182
199
  verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
183
200
  controlContextFields: ['phase'],
184
201
  transitionEventFields: ['callerInput', 'answer', 'questionId'],
185
- };
202
+ } satisfies XStatePlaybookRuntimeSpec<CodePlaybookOptions>;
186
203
 
187
204
  const createPlaybookRuntime: PlaybookRuntimeFactory<CodePlaybookOptions> =
188
205
  createXStatePlaybookRuntime(codingMachine, runtimeSpec);
@@ -1,4 +1,4 @@
1
- import { type CodePlaybookOptions, type PlaybookRuntime } from './code.playbook.js';
1
+ import { type PlaybookRuntime } from './code.playbook.js';
2
2
  export interface PlaybookSummaryPolicy {
3
3
  stateCountLabels: Readonly<Record<string, string>>;
4
4
  copyPasteGuardNames: readonly string[];
@@ -7,24 +7,17 @@ export interface PlaybookSummaryPolicy {
7
7
  copyPastes: number;
8
8
  }, rounds: number): string;
9
9
  }
10
- export interface RegistryPlayer {
11
- id: string;
12
- adapter?: string;
13
- model?: string;
14
- }
15
- export interface CreateCodeRuntimeOptions {
16
- captainOptions: unknown;
17
- players: readonly RegistryPlayer[];
18
- }
19
10
  export type CodeOptions = Readonly<Record<string, never>>;
20
11
  export interface CodePlaybookRegistryEntry {
21
12
  id: 'code';
22
13
  command: 'code';
23
14
  intent: string;
15
+ artifactSchema: 2;
24
16
  requiredRoleIds: readonly ['coder'];
17
+ concurrentRoleSets: readonly [];
25
18
  summaryPolicy: PlaybookSummaryPolicy;
26
- validateOptions(captainOptions: unknown): CodeOptions;
27
- createRuntime(options: CreateCodeRuntimeOptions): PlaybookRuntime;
19
+ validateOptions(optionSlice: unknown): CodeOptions;
20
+ createRuntime(options: CodeOptions): PlaybookRuntime;
28
21
  }
29
22
  export declare const codeStateCountLabels: {};
30
23
  export declare const codeCopyPasteGuardNames: readonly ["directCommit", "irCommit", "moreTasks", "finalTask"];
@@ -34,6 +27,5 @@ export declare function codeSavedCountsLine(counts: {
34
27
  }, rounds: number): string;
35
28
  export declare const codeSummaryPolicy: PlaybookSummaryPolicy;
36
29
  export declare function validateCodeOptions(optionSlice: unknown): CodeOptions;
37
- export declare function createCodeRuntimeOptions({ captainOptions, players, }: CreateCodeRuntimeOptions): CodePlaybookOptions;
38
30
  export declare const codePlaybookRegistryEntry: CodePlaybookRegistryEntry;
39
31
  export default codePlaybookRegistryEntry;