@sublang/playbook 8.0.0 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/docs/cli.md +66 -23
- package/docs/configuration.md +13 -8
- package/docs/embedding.md +45 -14
- package/package.json +7 -3
- package/reference/sdlc/captain.md +14 -10
- package/reference/sdlc/captain.playbook/captain.fsm.d.ts +33 -13
- package/reference/sdlc/captain.playbook/captain.fsm.js +80 -9
- package/reference/sdlc/captain.playbook/captain.fsm.ts +137 -18
- package/reference/sdlc/captain.playbook/captain.gears.md +10 -6
- package/reference/sdlc/captain.playbook/captain.playbook.d.ts +5 -1
- package/reference/sdlc/captain.playbook/captain.playbook.js +151 -10
- package/reference/sdlc/captain.playbook/captain.playbook.ts +200 -14
- package/reference/sdlc/code.md +0 -1
- package/reference/sdlc/code.playbook/bin/interactive-session.js +170 -17
- package/reference/sdlc/code.playbook/bin/launch-config.js +136 -4
- package/reference/sdlc/code.playbook/bin/playbook.js +81 -4
- package/reference/sdlc/code.playbook/bin/repository-effects.js +2930 -0
- package/reference/sdlc/code.playbook/bin/run.js +365 -63
- package/reference/sdlc/code.playbook/bin/session-store.js +2877 -209
- package/reference/sdlc/code.playbook/code.fsm.d.ts +11 -1
- package/reference/sdlc/code.playbook/code.fsm.js +85 -29
- package/reference/sdlc/code.playbook/code.fsm.ts +95 -33
- package/reference/sdlc/code.playbook/code.gears.md +0 -2
- package/reference/sdlc/code.playbook/code.playbook.d.ts +5 -2
- package/reference/sdlc/code.playbook/code.playbook.js +67 -4
- package/reference/sdlc/code.playbook/code.playbook.ts +87 -8
- package/reference/sdlc/code.playbook/code.registry.d.ts +10 -3
- package/reference/sdlc/code.playbook/code.registry.js +10 -3
- package/reference/sdlc/code.playbook/code.registry.ts +23 -5
- package/reference/sdlc/code.playbook/playbook-captain.d.ts +99 -7
- package/reference/sdlc/code.playbook/playbook-captain.js +1894 -82
- package/reference/sdlc/code.playbook/playbook-captain.ts +2809 -109
- package/reference/sdlc/decide.md +0 -1
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +8 -1
- package/reference/sdlc/decide.playbook/decide.fsm.js +80 -29
- package/reference/sdlc/decide.playbook/decide.fsm.ts +89 -31
- package/reference/sdlc/decide.playbook/decide.gears.md +0 -1
- package/reference/sdlc/decide.playbook/decide.playbook.d.ts +15 -5
- package/reference/sdlc/decide.playbook/decide.playbook.js +1994 -191
- package/reference/sdlc/decide.playbook/decide.playbook.ts +3209 -404
- package/reference/sdlc/decide.playbook/decide.registry.d.ts +7 -3
- package/reference/sdlc/decide.playbook/decide.registry.js +10 -3
- package/reference/sdlc/decide.playbook/decide.registry.ts +20 -5
- package/reference/sdlc/review.playbook/review.fsm.d.ts +7 -0
- package/reference/sdlc/review.playbook/review.fsm.js +133 -12
- package/reference/sdlc/review.playbook/review.fsm.ts +140 -12
- package/reference/sdlc/review.playbook/review.playbook.d.ts +5 -2
- package/reference/sdlc/review.playbook/review.playbook.js +78 -4
- package/reference/sdlc/review.playbook/review.playbook.ts +95 -8
- package/reference/sdlc/review.playbook/review.registry.d.ts +10 -3
- package/reference/sdlc/review.playbook/review.registry.js +10 -3
- package/reference/sdlc/review.playbook/review.registry.ts +23 -5
- package/slc/gears2fsm.md +25 -7
- package/slc/link.md +727 -82
- package/src/accepted-outcome.d.ts +18 -0
- package/src/accepted-outcome.js +94 -0
- package/src/accepted-outcome.ts +140 -0
- package/src/runtime.d.ts +165 -3
- package/src/runtime.ts +214 -2
- package/src/xstate-playbook-runtime.d.ts +162 -13
- package/src/xstate-playbook-runtime.js +3344 -564
- package/src/xstate-playbook-runtime.ts +4873 -637
- package/src/xstate-runtime.d.ts +76 -8
- package/src/xstate-runtime.js +1001 -64
- package/src/xstate-runtime.ts +1640 -91
|
@@ -122,6 +122,13 @@ export declare const codingMachine: import("xstate").StateMachine<CodingContext,
|
|
|
122
122
|
logic: import("xstate").PromiseActorLogic<PlayerOutput, PlayerInput, import("xstate").EventObject>;
|
|
123
123
|
id: string | undefined;
|
|
124
124
|
}, {
|
|
125
|
+
type: "playbook.acceptedOutcome";
|
|
126
|
+
params: {
|
|
127
|
+
readonly source: string;
|
|
128
|
+
readonly target: string;
|
|
129
|
+
readonly acceptedOutcome: string;
|
|
130
|
+
};
|
|
131
|
+
} | {
|
|
125
132
|
type: "rememberActorError";
|
|
126
133
|
params: import("xstate").NonReducibleUnknown;
|
|
127
134
|
} | {
|
|
@@ -202,7 +209,7 @@ export declare const codingMachine: import("xstate").StateMachine<CodingContext,
|
|
|
202
209
|
} | {
|
|
203
210
|
type: "resumesIrTask";
|
|
204
211
|
params: unknown;
|
|
205
|
-
}, never, "done" | "failed" | "awaitBossReply" | "ready" | "runFirstPhase" | "reviewFirstCommit" | "runIrTask" | "reviewIrTask", string, CodingInput, {
|
|
212
|
+
}, never, "done" | "failed" | "awaitBossReply" | "ready" | "runFirstPhase" | "reviewFirstCommit" | "runIrTask" | "reviewIrTask" | "reportedReviewFailure", string, CodingInput, {
|
|
206
213
|
readonly status: "complete";
|
|
207
214
|
/** Exact identity of the latest CODE-owned commit. */
|
|
208
215
|
readonly lastCodeCommit: string;
|
|
@@ -239,6 +246,9 @@ export declare const codingMachine: import("xstate").StateMachine<CodingContext,
|
|
|
239
246
|
readonly failed: {
|
|
240
247
|
id: "failed";
|
|
241
248
|
};
|
|
249
|
+
readonly reportedReviewFailure: {
|
|
250
|
+
id: "reportedReviewFailure";
|
|
251
|
+
};
|
|
242
252
|
readonly done: {
|
|
243
253
|
id: "done";
|
|
244
254
|
};
|
|
@@ -17,7 +17,6 @@ const FIRST_PHASE_PROMPT = [
|
|
|
17
17
|
'Do not re-run tests or builds whose inputs have not changed since any previous reported run.',
|
|
18
18
|
"Make the phase's minimal changes and then one new commit, following @specs/packages/git.md; never amend an existing commit.",
|
|
19
19
|
'Make the commit message explain concisely what changed and why, including relevant verification.',
|
|
20
|
-
'Report it as exactly one final-response line beginning `Commit: `, followed only by the exact commit identity.',
|
|
21
20
|
'Coder is <coder-llm>; format the model token in conventional human form.',
|
|
22
21
|
].join('\n');
|
|
23
22
|
const IR_TASK_PROMPT = [
|
|
@@ -32,7 +31,6 @@ const IR_TASK_PROMPT = [
|
|
|
32
31
|
'Do not re-run tests or builds whose inputs have not changed since any previous reported run.',
|
|
33
32
|
"Make the phase's minimal changes and then one new commit, following @specs/packages/git.md; never amend an existing commit.",
|
|
34
33
|
'Make the commit message explain concisely what changed and why, including relevant verification.',
|
|
35
|
-
'Report it as exactly one final-response line beginning `Commit: `, followed only by the exact commit identity.',
|
|
36
34
|
'Coder is <coder-llm>; format the model token in conventional human form.',
|
|
37
35
|
].join('\n');
|
|
38
36
|
const FIRST_PHASE_RESULTS = {
|
|
@@ -53,6 +51,7 @@ const STATE_DESCRIPTIONS = {
|
|
|
53
51
|
reviewIrTask: 'The REVIEW playbook is checking the latest task commit.',
|
|
54
52
|
awaitBossReply: 'Waiting for Boss to answer Coder.',
|
|
55
53
|
failed: 'The coding workflow failed and is waiting for a new coding intent.',
|
|
54
|
+
reportedReviewFailure: 'The coding workflow reported a REVIEW failure and the last code-owned commit.',
|
|
56
55
|
done: 'The coding workflow completed after REVIEW found no unsettled findings.',
|
|
57
56
|
};
|
|
58
57
|
function playbookMeta(stateId, role) {
|
|
@@ -86,38 +85,28 @@ function outputString(event, field) {
|
|
|
86
85
|
const value = playerOutput(event)?.[field];
|
|
87
86
|
return isNonEmptyString(value) ? value : undefined;
|
|
88
87
|
}
|
|
89
|
-
function
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const commitLines = coderOutput
|
|
93
|
-
?.split('\n')
|
|
94
|
-
.filter((line) => line.startsWith('Commit: '));
|
|
95
|
-
if (coderOutput === undefined ||
|
|
96
|
-
latestCommit === undefined ||
|
|
97
|
-
commitLines?.length !== 1 ||
|
|
98
|
-
commitLines[0] !== `Commit: ${latestCommit}`) {
|
|
99
|
-
return undefined;
|
|
100
|
-
}
|
|
101
|
-
return { coderOutput, latestCommit };
|
|
88
|
+
function hasCommittedOutput(event) {
|
|
89
|
+
return (outputString(event, 'coderOutput') !== undefined &&
|
|
90
|
+
outputString(event, 'latestCommit') !== undefined);
|
|
102
91
|
}
|
|
103
92
|
function isDirectCommit({ event }) {
|
|
104
93
|
return (outputGuard(event, 'directCommit') &&
|
|
105
|
-
|
|
94
|
+
hasCommittedOutput(event));
|
|
106
95
|
}
|
|
107
96
|
function isIrCommit({ event }) {
|
|
108
97
|
return (outputGuard(event, 'irCommit') &&
|
|
109
|
-
|
|
98
|
+
hasCommittedOutput(event) &&
|
|
110
99
|
outputString(event, 'irNumber') !== undefined &&
|
|
111
100
|
outputString(event, 'irTask') !== undefined);
|
|
112
101
|
}
|
|
113
102
|
function isMoreTasks({ event }) {
|
|
114
103
|
return (outputGuard(event, 'moreTasks') &&
|
|
115
|
-
|
|
104
|
+
hasCommittedOutput(event) &&
|
|
116
105
|
outputString(event, 'irTask') !== undefined);
|
|
117
106
|
}
|
|
118
107
|
function isFinalTask({ event }) {
|
|
119
108
|
return (outputGuard(event, 'finalTask') &&
|
|
120
|
-
|
|
109
|
+
hasCommittedOutput(event));
|
|
121
110
|
}
|
|
122
111
|
function needsBossReply({ event }) {
|
|
123
112
|
return (outputGuard(event, 'needsBossReply') &&
|
|
@@ -320,6 +309,7 @@ const machineSetup = setup({
|
|
|
320
309
|
(event.questionId === undefined || event.questionId === 'runIrTask'),
|
|
321
310
|
},
|
|
322
311
|
actions: {
|
|
312
|
+
'playbook.acceptedOutcome': (_args, _params) => undefined,
|
|
323
313
|
startCoding: assign(({ context, event }) => {
|
|
324
314
|
if (event.type !== 'START_CODE')
|
|
325
315
|
return {};
|
|
@@ -486,17 +476,47 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
486
476
|
{
|
|
487
477
|
guard: 'isDirectCommit',
|
|
488
478
|
target: 'reviewFirstCommit',
|
|
489
|
-
actions:
|
|
479
|
+
actions: [
|
|
480
|
+
{
|
|
481
|
+
type: 'playbook.acceptedOutcome',
|
|
482
|
+
params: {
|
|
483
|
+
source: 'runFirstPhase',
|
|
484
|
+
target: 'reviewFirstCommit',
|
|
485
|
+
acceptedOutcome: 'directCommit',
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
'rememberDirectCommit',
|
|
489
|
+
],
|
|
490
490
|
},
|
|
491
491
|
{
|
|
492
492
|
guard: 'isIrCommit',
|
|
493
493
|
target: 'reviewFirstCommit',
|
|
494
|
-
actions:
|
|
494
|
+
actions: [
|
|
495
|
+
{
|
|
496
|
+
type: 'playbook.acceptedOutcome',
|
|
497
|
+
params: {
|
|
498
|
+
source: 'runFirstPhase',
|
|
499
|
+
target: 'reviewFirstCommit',
|
|
500
|
+
acceptedOutcome: 'irCommit',
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
'rememberIrCommit',
|
|
504
|
+
],
|
|
495
505
|
},
|
|
496
506
|
{
|
|
497
507
|
guard: 'needsBossReply',
|
|
498
508
|
target: 'awaitBossReply',
|
|
499
|
-
actions:
|
|
509
|
+
actions: [
|
|
510
|
+
{
|
|
511
|
+
type: 'playbook.acceptedOutcome',
|
|
512
|
+
params: {
|
|
513
|
+
source: 'runFirstPhase',
|
|
514
|
+
target: 'awaitBossReply',
|
|
515
|
+
acceptedOutcome: 'needsBossReply',
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
'rememberPendingQuestion',
|
|
519
|
+
],
|
|
500
520
|
},
|
|
501
521
|
{
|
|
502
522
|
target: 'failed',
|
|
@@ -530,14 +550,14 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
530
550
|
target: 'runIrTask',
|
|
531
551
|
},
|
|
532
552
|
{
|
|
533
|
-
target: '
|
|
553
|
+
target: 'reportedReviewFailure',
|
|
534
554
|
actions: 'completeWithInvalidReviewOutput',
|
|
535
555
|
},
|
|
536
556
|
],
|
|
537
557
|
onError: [
|
|
538
558
|
{
|
|
539
559
|
guard: 'authoredReviewFailure',
|
|
540
|
-
target: '
|
|
560
|
+
target: 'reportedReviewFailure',
|
|
541
561
|
actions: 'completeWithReviewFailure',
|
|
542
562
|
},
|
|
543
563
|
{ target: 'failed', actions: 'rememberActorError' },
|
|
@@ -574,17 +594,47 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
574
594
|
{
|
|
575
595
|
guard: 'isMoreTasks',
|
|
576
596
|
target: 'reviewIrTask',
|
|
577
|
-
actions:
|
|
597
|
+
actions: [
|
|
598
|
+
{
|
|
599
|
+
type: 'playbook.acceptedOutcome',
|
|
600
|
+
params: {
|
|
601
|
+
source: 'runIrTask',
|
|
602
|
+
target: 'reviewIrTask',
|
|
603
|
+
acceptedOutcome: 'moreTasks',
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
'rememberMoreTasks',
|
|
607
|
+
],
|
|
578
608
|
},
|
|
579
609
|
{
|
|
580
610
|
guard: 'isFinalTask',
|
|
581
611
|
target: 'reviewIrTask',
|
|
582
|
-
actions:
|
|
612
|
+
actions: [
|
|
613
|
+
{
|
|
614
|
+
type: 'playbook.acceptedOutcome',
|
|
615
|
+
params: {
|
|
616
|
+
source: 'runIrTask',
|
|
617
|
+
target: 'reviewIrTask',
|
|
618
|
+
acceptedOutcome: 'finalTask',
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
'rememberFinalTask',
|
|
622
|
+
],
|
|
583
623
|
},
|
|
584
624
|
{
|
|
585
625
|
guard: 'needsBossReply',
|
|
586
626
|
target: 'awaitBossReply',
|
|
587
|
-
actions:
|
|
627
|
+
actions: [
|
|
628
|
+
{
|
|
629
|
+
type: 'playbook.acceptedOutcome',
|
|
630
|
+
params: {
|
|
631
|
+
source: 'runIrTask',
|
|
632
|
+
target: 'awaitBossReply',
|
|
633
|
+
acceptedOutcome: 'needsBossReply',
|
|
634
|
+
},
|
|
635
|
+
},
|
|
636
|
+
'rememberPendingQuestion',
|
|
637
|
+
],
|
|
588
638
|
},
|
|
589
639
|
{
|
|
590
640
|
target: 'failed',
|
|
@@ -619,14 +669,14 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
619
669
|
actions: 'completeSuccessfully',
|
|
620
670
|
},
|
|
621
671
|
{
|
|
622
|
-
target: '
|
|
672
|
+
target: 'reportedReviewFailure',
|
|
623
673
|
actions: 'completeWithInvalidReviewOutput',
|
|
624
674
|
},
|
|
625
675
|
],
|
|
626
676
|
onError: [
|
|
627
677
|
{
|
|
628
678
|
guard: 'authoredReviewFailure',
|
|
629
|
-
target: '
|
|
679
|
+
target: 'reportedReviewFailure',
|
|
630
680
|
actions: 'completeWithReviewFailure',
|
|
631
681
|
},
|
|
632
682
|
{ target: 'failed', actions: 'rememberActorError' },
|
|
@@ -670,6 +720,12 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
670
720
|
START_CODE: { target: 'runFirstPhase', actions: 'startCoding' },
|
|
671
721
|
},
|
|
672
722
|
},
|
|
723
|
+
reportedReviewFailure: {
|
|
724
|
+
id: 'reportedReviewFailure',
|
|
725
|
+
description: STATE_DESCRIPTIONS.reportedReviewFailure,
|
|
726
|
+
meta: playbookMeta('reportedReviewFailure'),
|
|
727
|
+
type: 'final',
|
|
728
|
+
},
|
|
673
729
|
done: {
|
|
674
730
|
id: 'done',
|
|
675
731
|
description: STATE_DESCRIPTIONS.done,
|
|
@@ -154,7 +154,6 @@ const FIRST_PHASE_PROMPT = [
|
|
|
154
154
|
'Do not re-run tests or builds whose inputs have not changed since any previous reported run.',
|
|
155
155
|
"Make the phase's minimal changes and then one new commit, following @specs/packages/git.md; never amend an existing commit.",
|
|
156
156
|
'Make the commit message explain concisely what changed and why, including relevant verification.',
|
|
157
|
-
'Report it as exactly one final-response line beginning `Commit: `, followed only by the exact commit identity.',
|
|
158
157
|
'Coder is <coder-llm>; format the model token in conventional human form.',
|
|
159
158
|
].join('\n');
|
|
160
159
|
|
|
@@ -170,7 +169,6 @@ const IR_TASK_PROMPT = [
|
|
|
170
169
|
'Do not re-run tests or builds whose inputs have not changed since any previous reported run.',
|
|
171
170
|
"Make the phase's minimal changes and then one new commit, following @specs/packages/git.md; never amend an existing commit.",
|
|
172
171
|
'Make the commit message explain concisely what changed and why, including relevant verification.',
|
|
173
|
-
'Report it as exactly one final-response line beginning `Commit: `, followed only by the exact commit identity.',
|
|
174
172
|
'Coder is <coder-llm>; format the model token in conventional human form.',
|
|
175
173
|
].join('\n');
|
|
176
174
|
|
|
@@ -202,6 +200,8 @@ const STATE_DESCRIPTIONS = {
|
|
|
202
200
|
reviewIrTask: 'The REVIEW playbook is checking the latest task commit.',
|
|
203
201
|
awaitBossReply: 'Waiting for Boss to answer Coder.',
|
|
204
202
|
failed: 'The coding workflow failed and is waiting for a new coding intent.',
|
|
203
|
+
reportedReviewFailure:
|
|
204
|
+
'The coding workflow reported a REVIEW failure and the last code-owned commit.',
|
|
205
205
|
done: 'The coding workflow completed after REVIEW found no unsettled findings.',
|
|
206
206
|
} as const;
|
|
207
207
|
|
|
@@ -244,36 +244,24 @@ function outputString(event: unknown, field: string): string | undefined {
|
|
|
244
244
|
return isNonEmptyString(value) ? value : undefined;
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
function
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const commitLines = coderOutput
|
|
253
|
-
?.split('\n')
|
|
254
|
-
.filter((line) => line.startsWith('Commit: '));
|
|
255
|
-
if (
|
|
256
|
-
coderOutput === undefined ||
|
|
257
|
-
latestCommit === undefined ||
|
|
258
|
-
commitLines?.length !== 1 ||
|
|
259
|
-
commitLines[0] !== `Commit: ${latestCommit}`
|
|
260
|
-
) {
|
|
261
|
-
return undefined;
|
|
262
|
-
}
|
|
263
|
-
return { coderOutput, latestCommit };
|
|
247
|
+
function hasCommittedOutput(event: unknown): boolean {
|
|
248
|
+
return (
|
|
249
|
+
outputString(event, 'coderOutput') !== undefined &&
|
|
250
|
+
outputString(event, 'latestCommit') !== undefined
|
|
251
|
+
);
|
|
264
252
|
}
|
|
265
253
|
|
|
266
254
|
function isDirectCommit({ event }: { event: unknown }): boolean {
|
|
267
255
|
return (
|
|
268
256
|
outputGuard(event, 'directCommit') &&
|
|
269
|
-
|
|
257
|
+
hasCommittedOutput(event)
|
|
270
258
|
);
|
|
271
259
|
}
|
|
272
260
|
|
|
273
261
|
function isIrCommit({ event }: { event: unknown }): boolean {
|
|
274
262
|
return (
|
|
275
263
|
outputGuard(event, 'irCommit') &&
|
|
276
|
-
|
|
264
|
+
hasCommittedOutput(event) &&
|
|
277
265
|
outputString(event, 'irNumber') !== undefined &&
|
|
278
266
|
outputString(event, 'irTask') !== undefined
|
|
279
267
|
);
|
|
@@ -282,7 +270,7 @@ function isIrCommit({ event }: { event: unknown }): boolean {
|
|
|
282
270
|
function isMoreTasks({ event }: { event: unknown }): boolean {
|
|
283
271
|
return (
|
|
284
272
|
outputGuard(event, 'moreTasks') &&
|
|
285
|
-
|
|
273
|
+
hasCommittedOutput(event) &&
|
|
286
274
|
outputString(event, 'irTask') !== undefined
|
|
287
275
|
);
|
|
288
276
|
}
|
|
@@ -290,7 +278,7 @@ function isMoreTasks({ event }: { event: unknown }): boolean {
|
|
|
290
278
|
function isFinalTask({ event }: { event: unknown }): boolean {
|
|
291
279
|
return (
|
|
292
280
|
outputGuard(event, 'finalTask') &&
|
|
293
|
-
|
|
281
|
+
hasCommittedOutput(event)
|
|
294
282
|
);
|
|
295
283
|
}
|
|
296
284
|
|
|
@@ -551,6 +539,14 @@ const machineSetup = setup({
|
|
|
551
539
|
(event.questionId === undefined || event.questionId === 'runIrTask'),
|
|
552
540
|
},
|
|
553
541
|
actions: {
|
|
542
|
+
'playbook.acceptedOutcome': (
|
|
543
|
+
_args,
|
|
544
|
+
_params: {
|
|
545
|
+
readonly source: string;
|
|
546
|
+
readonly target: string;
|
|
547
|
+
readonly acceptedOutcome: string;
|
|
548
|
+
},
|
|
549
|
+
) => undefined,
|
|
554
550
|
startCoding: assign(({ context, event }) => {
|
|
555
551
|
if (event.type !== 'START_CODE') return {};
|
|
556
552
|
return {
|
|
@@ -724,17 +720,47 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
724
720
|
{
|
|
725
721
|
guard: 'isDirectCommit',
|
|
726
722
|
target: 'reviewFirstCommit',
|
|
727
|
-
actions:
|
|
723
|
+
actions: [
|
|
724
|
+
{
|
|
725
|
+
type: 'playbook.acceptedOutcome',
|
|
726
|
+
params: {
|
|
727
|
+
source: 'runFirstPhase',
|
|
728
|
+
target: 'reviewFirstCommit',
|
|
729
|
+
acceptedOutcome: 'directCommit',
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
'rememberDirectCommit',
|
|
733
|
+
],
|
|
728
734
|
},
|
|
729
735
|
{
|
|
730
736
|
guard: 'isIrCommit',
|
|
731
737
|
target: 'reviewFirstCommit',
|
|
732
|
-
actions:
|
|
738
|
+
actions: [
|
|
739
|
+
{
|
|
740
|
+
type: 'playbook.acceptedOutcome',
|
|
741
|
+
params: {
|
|
742
|
+
source: 'runFirstPhase',
|
|
743
|
+
target: 'reviewFirstCommit',
|
|
744
|
+
acceptedOutcome: 'irCommit',
|
|
745
|
+
},
|
|
746
|
+
},
|
|
747
|
+
'rememberIrCommit',
|
|
748
|
+
],
|
|
733
749
|
},
|
|
734
750
|
{
|
|
735
751
|
guard: 'needsBossReply',
|
|
736
752
|
target: 'awaitBossReply',
|
|
737
|
-
actions:
|
|
753
|
+
actions: [
|
|
754
|
+
{
|
|
755
|
+
type: 'playbook.acceptedOutcome',
|
|
756
|
+
params: {
|
|
757
|
+
source: 'runFirstPhase',
|
|
758
|
+
target: 'awaitBossReply',
|
|
759
|
+
acceptedOutcome: 'needsBossReply',
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
'rememberPendingQuestion',
|
|
763
|
+
],
|
|
738
764
|
},
|
|
739
765
|
{
|
|
740
766
|
target: 'failed',
|
|
@@ -768,14 +794,14 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
768
794
|
target: 'runIrTask',
|
|
769
795
|
},
|
|
770
796
|
{
|
|
771
|
-
target: '
|
|
797
|
+
target: 'reportedReviewFailure',
|
|
772
798
|
actions: 'completeWithInvalidReviewOutput',
|
|
773
799
|
},
|
|
774
800
|
],
|
|
775
801
|
onError: [
|
|
776
802
|
{
|
|
777
803
|
guard: 'authoredReviewFailure',
|
|
778
|
-
target: '
|
|
804
|
+
target: 'reportedReviewFailure',
|
|
779
805
|
actions: 'completeWithReviewFailure',
|
|
780
806
|
},
|
|
781
807
|
{ target: 'failed', actions: 'rememberActorError' },
|
|
@@ -812,17 +838,47 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
812
838
|
{
|
|
813
839
|
guard: 'isMoreTasks',
|
|
814
840
|
target: 'reviewIrTask',
|
|
815
|
-
actions:
|
|
841
|
+
actions: [
|
|
842
|
+
{
|
|
843
|
+
type: 'playbook.acceptedOutcome',
|
|
844
|
+
params: {
|
|
845
|
+
source: 'runIrTask',
|
|
846
|
+
target: 'reviewIrTask',
|
|
847
|
+
acceptedOutcome: 'moreTasks',
|
|
848
|
+
},
|
|
849
|
+
},
|
|
850
|
+
'rememberMoreTasks',
|
|
851
|
+
],
|
|
816
852
|
},
|
|
817
853
|
{
|
|
818
854
|
guard: 'isFinalTask',
|
|
819
855
|
target: 'reviewIrTask',
|
|
820
|
-
actions:
|
|
856
|
+
actions: [
|
|
857
|
+
{
|
|
858
|
+
type: 'playbook.acceptedOutcome',
|
|
859
|
+
params: {
|
|
860
|
+
source: 'runIrTask',
|
|
861
|
+
target: 'reviewIrTask',
|
|
862
|
+
acceptedOutcome: 'finalTask',
|
|
863
|
+
},
|
|
864
|
+
},
|
|
865
|
+
'rememberFinalTask',
|
|
866
|
+
],
|
|
821
867
|
},
|
|
822
868
|
{
|
|
823
869
|
guard: 'needsBossReply',
|
|
824
870
|
target: 'awaitBossReply',
|
|
825
|
-
actions:
|
|
871
|
+
actions: [
|
|
872
|
+
{
|
|
873
|
+
type: 'playbook.acceptedOutcome',
|
|
874
|
+
params: {
|
|
875
|
+
source: 'runIrTask',
|
|
876
|
+
target: 'awaitBossReply',
|
|
877
|
+
acceptedOutcome: 'needsBossReply',
|
|
878
|
+
},
|
|
879
|
+
},
|
|
880
|
+
'rememberPendingQuestion',
|
|
881
|
+
],
|
|
826
882
|
},
|
|
827
883
|
{
|
|
828
884
|
target: 'failed',
|
|
@@ -857,14 +913,14 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
857
913
|
actions: 'completeSuccessfully',
|
|
858
914
|
},
|
|
859
915
|
{
|
|
860
|
-
target: '
|
|
916
|
+
target: 'reportedReviewFailure',
|
|
861
917
|
actions: 'completeWithInvalidReviewOutput',
|
|
862
918
|
},
|
|
863
919
|
],
|
|
864
920
|
onError: [
|
|
865
921
|
{
|
|
866
922
|
guard: 'authoredReviewFailure',
|
|
867
|
-
target: '
|
|
923
|
+
target: 'reportedReviewFailure',
|
|
868
924
|
actions: 'completeWithReviewFailure',
|
|
869
925
|
},
|
|
870
926
|
{ target: 'failed', actions: 'rememberActorError' },
|
|
@@ -908,6 +964,12 @@ export const codingMachine = machineSetup.createMachine({
|
|
|
908
964
|
START_CODE: { target: 'runFirstPhase', actions: 'startCoding' },
|
|
909
965
|
},
|
|
910
966
|
},
|
|
967
|
+
reportedReviewFailure: {
|
|
968
|
+
id: 'reportedReviewFailure',
|
|
969
|
+
description: STATE_DESCRIPTIONS.reportedReviewFailure,
|
|
970
|
+
meta: playbookMeta('reportedReviewFailure'),
|
|
971
|
+
type: 'final',
|
|
972
|
+
},
|
|
911
973
|
done: {
|
|
912
974
|
id: 'done',
|
|
913
975
|
description: STATE_DESCRIPTIONS.done,
|
|
@@ -26,7 +26,6 @@ When the first coding phase begins, Captain shall prompt Coder:
|
|
|
26
26
|
> Do not re-run tests or builds whose inputs have not changed since any previous reported run.
|
|
27
27
|
> Make the phase's minimal changes and then one new commit, following @specs/packages/git.md; never amend an existing commit.
|
|
28
28
|
> Make the commit message explain concisely what changed and why, including relevant verification.
|
|
29
|
-
> Report it as exactly one final-response line beginning `Commit: `, followed only by the exact commit identity.
|
|
30
29
|
> Coder is <coder-llm>; format the model token in conventional human form.
|
|
31
30
|
|
|
32
31
|
Results:
|
|
@@ -61,7 +60,6 @@ When a reviewed IR has a next unfinished task, Captain shall prompt Coder:
|
|
|
61
60
|
> Do not re-run tests or builds whose inputs have not changed since any previous reported run.
|
|
62
61
|
> Make the phase's minimal changes and then one new commit, following @specs/packages/git.md; never amend an existing commit.
|
|
63
62
|
> Make the commit message explain concisely what changed and why, including relevant verification.
|
|
64
|
-
> Report it as exactly one final-response line beginning `Commit: `, followed only by the exact commit identity.
|
|
65
63
|
> Coder is <coder-llm>; format the model token in conventional human form.
|
|
66
64
|
|
|
67
65
|
Results:
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { type XStatePromptIdentity } from '@sublang/playbook/xstate-runtime';
|
|
1
|
+
import { type XStatePlaybookRuntimeFactory, type XStatePlaybookRuntimeConstruction, type XStatePromptIdentity } from '@sublang/playbook/xstate-runtime';
|
|
2
2
|
import { type CodingInput, type PlayerInput } from './code.fsm.js';
|
|
3
|
+
import type { PlaybookHostConstructionCapabilities } from './playbook-captain.js';
|
|
3
4
|
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';
|
|
4
5
|
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, };
|
|
5
6
|
export type CodePlaybookOptions = CodingInput;
|
|
7
|
+
export type CodePlaybookHostCapabilities = PlaybookHostConstructionCapabilities & XStatePlaybookRuntimeConstruction<CodePlaybookOptions, object>['hostCapabilities'];
|
|
6
8
|
/**
|
|
7
9
|
* Preserve authored Markdown quote markers around every line of relayed
|
|
8
10
|
* runtime text. The generic composer preserves the marker itself; CODE's
|
|
@@ -12,6 +14,7 @@ declare function composePlayerPrompt(input: PlayerInput, promptIdentity: XStateP
|
|
|
12
14
|
export declare const _internal: {
|
|
13
15
|
composePlayerPrompt: typeof composePlayerPrompt;
|
|
14
16
|
VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string>;
|
|
17
|
+
UNFINISHED_FINAL_STATE_IDS: ReadonlySet<string>;
|
|
15
18
|
};
|
|
16
|
-
declare const createPlaybookRuntime:
|
|
19
|
+
declare const createPlaybookRuntime: XStatePlaybookRuntimeFactory<XStatePlaybookRuntimeConstruction<CodePlaybookOptions, CodePlaybookHostCapabilities>, 3>;
|
|
17
20
|
export default createPlaybookRuntime;
|
|
@@ -8,8 +8,8 @@
|
|
|
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
|
|
12
|
-
import {
|
|
11
|
+
// Compat: artifact schema 3 / runtime ABI 1
|
|
12
|
+
import { createXStatePlaybookRuntime, snapshotJsonValue, } from '@sublang/playbook/xstate-runtime';
|
|
13
13
|
import { codingMachine, } from './code.fsm.js';
|
|
14
14
|
const OPTION_KEYS = new Set(['runResults']);
|
|
15
15
|
const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
|
|
@@ -17,6 +17,9 @@ const CONTINUATION_PREAMBLE = 'You previously paused this task to ask Boss a que
|
|
|
17
17
|
const VERBATIM_PAYLOAD_FIELDS = new Set([
|
|
18
18
|
'coderOutput',
|
|
19
19
|
]);
|
|
20
|
+
const UNFINISHED_FINAL_STATE_IDS = new Set([
|
|
21
|
+
'reportedReviewFailure',
|
|
22
|
+
]);
|
|
20
23
|
function snapshotCodeOptions(value) {
|
|
21
24
|
const captured = snapshotJsonValue(value, 'CODE runtime options');
|
|
22
25
|
if (captured === null ||
|
|
@@ -78,12 +81,24 @@ function composePlayerPrompt(input, promptIdentity) {
|
|
|
78
81
|
export const _internal = {
|
|
79
82
|
composePlayerPrompt,
|
|
80
83
|
VERBATIM_PAYLOAD_FIELDS,
|
|
84
|
+
UNFINISHED_FINAL_STATE_IDS,
|
|
81
85
|
};
|
|
82
86
|
const runtimeSpec = {
|
|
83
87
|
label: 'CODE',
|
|
84
|
-
|
|
88
|
+
// DR-022 / slc/link.md: the declaration carries the value current at link
|
|
89
|
+
// time — a literal, never the loading engine's RUNTIME_ABI self-report,
|
|
90
|
+
// which would follow whatever engine loads the module and make the
|
|
91
|
+
// factory's skew check compare that engine with itself.
|
|
92
|
+
compat: { artifactSchema: 3, runtimeAbi: 1 },
|
|
85
93
|
snapshotOptions: snapshotCodeOptions,
|
|
86
|
-
entryEvent: {
|
|
94
|
+
entryEvent: {
|
|
95
|
+
type: 'START_CODE',
|
|
96
|
+
textField: 'callerInput',
|
|
97
|
+
// `startCoding` copies the entry text here, so the failure-state retry
|
|
98
|
+
// reads it back from the persisted machine snapshot and survives a
|
|
99
|
+
// continued session (DR-034).
|
|
100
|
+
contextField: 'callerInput',
|
|
101
|
+
},
|
|
87
102
|
roleStates: {
|
|
88
103
|
runFirstPhase: {
|
|
89
104
|
role: 'coder',
|
|
@@ -94,9 +109,57 @@ const runtimeSpec = {
|
|
|
94
109
|
label: 'Coder is implementing exactly one unfinished intent-record task.',
|
|
95
110
|
},
|
|
96
111
|
},
|
|
112
|
+
outcomeAuthority: {
|
|
113
|
+
governedPlayerStates: {
|
|
114
|
+
runFirstPhase: {
|
|
115
|
+
directCommit: {
|
|
116
|
+
fields: {
|
|
117
|
+
coderOutput: 'presentation',
|
|
118
|
+
latestCommit: 'effect',
|
|
119
|
+
},
|
|
120
|
+
repositoryDisposition: 'one-descendant-commit',
|
|
121
|
+
},
|
|
122
|
+
irCommit: {
|
|
123
|
+
fields: {
|
|
124
|
+
coderOutput: 'presentation',
|
|
125
|
+
latestCommit: 'effect',
|
|
126
|
+
irNumber: 'semantic',
|
|
127
|
+
irTask: 'semantic',
|
|
128
|
+
},
|
|
129
|
+
repositoryDisposition: 'one-descendant-commit',
|
|
130
|
+
},
|
|
131
|
+
needsBossReply: {
|
|
132
|
+
fields: { question: 'presentation' },
|
|
133
|
+
repositoryDisposition: 'deferred',
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
runIrTask: {
|
|
137
|
+
moreTasks: {
|
|
138
|
+
fields: {
|
|
139
|
+
coderOutput: 'presentation',
|
|
140
|
+
latestCommit: 'effect',
|
|
141
|
+
irTask: 'semantic',
|
|
142
|
+
},
|
|
143
|
+
repositoryDisposition: 'one-descendant-commit',
|
|
144
|
+
},
|
|
145
|
+
finalTask: {
|
|
146
|
+
fields: {
|
|
147
|
+
coderOutput: 'presentation',
|
|
148
|
+
latestCommit: 'effect',
|
|
149
|
+
},
|
|
150
|
+
repositoryDisposition: 'one-descendant-commit',
|
|
151
|
+
},
|
|
152
|
+
needsBossReply: {
|
|
153
|
+
fields: { question: 'presentation' },
|
|
154
|
+
repositoryDisposition: 'deferred',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
97
159
|
composePlayerPrompt: (input, promptIdentity) => composePlayerPrompt(input, promptIdentity),
|
|
98
160
|
verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
|
|
99
161
|
controlContextFields: ['phase'],
|
|
162
|
+
unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
|
|
100
163
|
transitionEventFields: ['callerInput', 'answer', 'questionId'],
|
|
101
164
|
};
|
|
102
165
|
const createPlaybookRuntime = createXStatePlaybookRuntime(codingMachine, runtimeSpec);
|