@sublang/playbook 11.0.0 → 12.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/docs/cli.md +9 -6
- package/docs/configuration.md +15 -1
- package/package.json +22 -3
- package/reference/sdlc/code.playbook/code.fsm.d.ts +22 -19
- package/reference/sdlc/code.playbook/code.fsm.js +116 -52
- package/reference/sdlc/code.playbook/code.fsm.ts +149 -64
- package/reference/sdlc/code.playbook/code.gears.md +40 -20
- package/reference/sdlc/code.playbook/code.playbook.js +23 -2
- package/reference/sdlc/code.playbook/code.playbook.ts +23 -2
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +18 -2
- package/reference/sdlc/decide.playbook/decide.fsm.d.ts +13 -6
- package/reference/sdlc/decide.playbook/decide.fsm.js +54 -27
- package/reference/sdlc/decide.playbook/decide.fsm.ts +68 -29
- package/reference/sdlc/decide.playbook/decide.gears.md +25 -19
- package/reference/sdlc/decide.playbook/decide.playbook.js +11 -3
- package/reference/sdlc/decide.playbook/decide.playbook.ts +11 -3
- package/reference/sdlc/decide.playbook/decide.registry.js +1 -1
- package/reference/sdlc/decide.playbook/decide.registry.ts +1 -1
- package/reference/sdlc/dev.md +52 -0
- package/reference/sdlc/dev.playbook/dev.fsm.d.ts +261 -0
- package/reference/sdlc/dev.playbook/dev.fsm.js +723 -0
- package/reference/sdlc/dev.playbook/dev.fsm.ts +988 -0
- package/reference/sdlc/dev.playbook/dev.gears.md +91 -0
- package/reference/sdlc/dev.playbook/dev.playbook.d.ts +21 -0
- package/reference/sdlc/dev.playbook/dev.playbook.js +143 -0
- package/reference/sdlc/dev.playbook/dev.playbook.ts +246 -0
- package/reference/sdlc/dev.playbook/dev.registry.d.ts +40 -0
- package/reference/sdlc/dev.playbook/dev.registry.js +64 -0
- package/reference/sdlc/dev.playbook/dev.registry.ts +120 -0
- package/reference/sdlc/review.playbook/review.fsm.d.ts +15 -2
- package/reference/sdlc/review.playbook/review.fsm.js +77 -27
- package/reference/sdlc/review.playbook/review.fsm.ts +96 -30
- package/reference/sdlc/review.playbook/review.gears.md +52 -26
- package/reference/sdlc/review.playbook/review.playbook.js +17 -7
- package/reference/sdlc/review.playbook/review.playbook.ts +17 -7
- package/reference/sdlc/review.playbook/review.registry.js +1 -1
- package/reference/sdlc/review.playbook/review.registry.ts +1 -1
- package/slc/link.md +12 -5
- package/slc/text2gears.md +3 -0
- package/src/xstate-playbook-runtime.js +5 -2
- package/src/xstate-playbook-runtime.ts +5 -2
- package/src/xstate-runtime.js +13 -1
- package/src/xstate-runtime.ts +13 -1
|
@@ -25,8 +25,14 @@ export interface PendingBossQuestion {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export interface ReviewOutput {
|
|
28
|
-
approvedCommit: 'latest';
|
|
29
28
|
noUnsettledFindings: true;
|
|
29
|
+
/**
|
|
30
|
+
* Exact receipt-derived repository revision at which the review scope was
|
|
31
|
+
* evaluated: the closing clean round's `unchanged` receipt observes it as
|
|
32
|
+
* HEAD — the last review-fix commit when one landed, or the caller-supplied
|
|
33
|
+
* scope revision when none did (DR-045).
|
|
34
|
+
*/
|
|
35
|
+
evaluatedRevision: string;
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
export type ReviewInput = Readonly<Record<string, never>>;
|
|
@@ -35,6 +41,10 @@ export interface ReviewContext {
|
|
|
35
41
|
callerInput?: string;
|
|
36
42
|
reviewerOutput?: string;
|
|
37
43
|
coderOutput?: string;
|
|
44
|
+
/** Receipt-derived OID of the latest review-fix commit (never player prose). */
|
|
45
|
+
latestCommit?: string;
|
|
46
|
+
/** Observed HEAD of the closing clean round's unchanged receipt (DR-045). */
|
|
47
|
+
evaluatedRevision?: string;
|
|
38
48
|
lastError?: unknown;
|
|
39
49
|
pendingBossQuestion?: PendingBossQuestion;
|
|
40
50
|
bossReply?: string;
|
|
@@ -62,14 +72,15 @@ export interface PlayerInput {
|
|
|
62
72
|
callerInput?: string;
|
|
63
73
|
reviewerOutput?: string;
|
|
64
74
|
coderOutput?: string;
|
|
75
|
+
latestCommit?: string;
|
|
65
76
|
pendingBossQuestion?: PendingBossQuestion;
|
|
66
77
|
bossReply?: string;
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
export type PlayerOutput =
|
|
70
81
|
| { guard: 'hasFindings'; reviewerOutput: string }
|
|
71
|
-
| { guard: 'noFindings' }
|
|
72
|
-
| { guard: 'committed'; coderOutput: string }
|
|
82
|
+
| { guard: 'noFindings'; evaluatedRevision: string }
|
|
83
|
+
| { guard: 'committed'; coderOutput: string; latestCommit: string }
|
|
73
84
|
| { guard: 'rejectedAll'; coderOutput: string }
|
|
74
85
|
| { guard: 'needsBossReply'; question: string };
|
|
75
86
|
|
|
@@ -80,13 +91,16 @@ const NEEDS_BOSS_REPLY_DESCRIPTION =
|
|
|
80
91
|
|
|
81
92
|
const SHARED_REVIEW_INSTRUCTION = [
|
|
82
93
|
'Understand the full picture and think systematically about the underlying design.',
|
|
83
|
-
'Continue to identify issues or improvements, if any
|
|
84
|
-
'
|
|
85
|
-
'Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.',
|
|
94
|
+
'Continue to identify issues or improvements, if any, without duplication.',
|
|
95
|
+
'Number the findings consistently across rounds.',
|
|
86
96
|
'Flag only what materially affects correctness, behavior, or spec quality — not style, equally valid alternatives, or theoretical threats.',
|
|
87
|
-
'For specs, flag stale, missing, over-specified, or under-specified ones.',
|
|
97
|
+
'For specs, flag stale, missing, over-specified, or under-specified ones, if any.',
|
|
88
98
|
'Avoid unnecessary complexity in code or tests, but flag any fundamental design flaw when leaving it would cost more in later patches than fixing it now.',
|
|
89
99
|
'',
|
|
100
|
+
'If an issue represents a class of defect, find every instance within the review scope worth fixing rather than surfacing one or two per round, which drags out the review.',
|
|
101
|
+
'For any rebuttal, accept or challenge it.',
|
|
102
|
+
'Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.',
|
|
103
|
+
'',
|
|
90
104
|
'Do not re-run tests or builds whose inputs have not changed since any previous reported run.',
|
|
91
105
|
'Do not edit files or commit; report findings only.',
|
|
92
106
|
'',
|
|
@@ -95,8 +109,9 @@ const SHARED_REVIEW_INSTRUCTION = [
|
|
|
95
109
|
].join('\n');
|
|
96
110
|
|
|
97
111
|
const INITIAL_REVIEW_PROMPT = [
|
|
98
|
-
'A new review begins
|
|
99
|
-
'
|
|
112
|
+
'A new review begins for the review scope.',
|
|
113
|
+
'Keep to the original intent and follow what it asks.',
|
|
114
|
+
'When the scope names commits, read each commit message for its context and rationale; otherwise use repository history and commit messages wherever they help establish that context.',
|
|
100
115
|
'',
|
|
101
116
|
'> <caller-input>',
|
|
102
117
|
'',
|
|
@@ -104,8 +119,12 @@ const INITIAL_REVIEW_PROMPT = [
|
|
|
104
119
|
].join('\n');
|
|
105
120
|
|
|
106
121
|
const POST_COMMIT_REVIEW_PROMPT = [
|
|
107
|
-
'
|
|
122
|
+
'A new review round begins for the review scope in the cumulative committed state, with particular attention to the latest review-fix commit.',
|
|
123
|
+
'Keep to the original intent and follow what it asks.',
|
|
124
|
+
"Read the latest review-fix commit's message and see Coder's feedback below.",
|
|
108
125
|
'',
|
|
126
|
+
'> <caller-input>',
|
|
127
|
+
'> <latest-commit>',
|
|
109
128
|
'> <coder-output>',
|
|
110
129
|
'',
|
|
111
130
|
SHARED_REVIEW_INSTRUCTION,
|
|
@@ -113,26 +132,31 @@ const POST_COMMIT_REVIEW_PROMPT = [
|
|
|
113
132
|
|
|
114
133
|
const REBUTTAL_REVIEW_PROMPT = [
|
|
115
134
|
'No new commit was made because Coder rejected every finding.',
|
|
135
|
+
"See Coder's feedback below.",
|
|
116
136
|
'',
|
|
137
|
+
'> <caller-input>',
|
|
117
138
|
'> <coder-output>',
|
|
118
139
|
'',
|
|
119
140
|
SHARED_REVIEW_INSTRUCTION,
|
|
120
141
|
].join('\n');
|
|
121
142
|
|
|
122
143
|
const CODER_DISPOSITION_PROMPT = [
|
|
144
|
+
'> <caller-input>',
|
|
123
145
|
'> <reviewer-output>',
|
|
124
146
|
'',
|
|
125
147
|
'For each review item, accept or reject it.',
|
|
126
148
|
'Before deciding, understand the full picture and think systematically about the underlying design.',
|
|
149
|
+
'Keep to the original intent and follow what it asks.',
|
|
127
150
|
'Reject anything that is not essential or is not worth fixing now.',
|
|
128
|
-
'If you accept an item, fix its root cause, including any fundamental design flaw
|
|
151
|
+
'If you accept an item, fix its root cause, including any fundamental design flaw — do not patch around it; if it represents a class of defect, find every instance within the review scope worth fixing rather than addressing one or two per round, which drags out the review.',
|
|
129
152
|
'If you reject an item, give the reasoning and cite code or test output that supports it.',
|
|
130
153
|
'Do not re-run tests or builds whose inputs have not changed since any previous reported run.',
|
|
131
154
|
'',
|
|
132
|
-
'If you accept any item, make minimal changes and
|
|
155
|
+
'If you accept any item, make minimal changes and add one new review-fix commit; never rewrite any existing commit.',
|
|
133
156
|
'Follow @specs/packages/git.md.',
|
|
134
157
|
'Make the commit message explain concisely what changed and why, including relevant verification.',
|
|
135
|
-
'
|
|
158
|
+
'Identify every new commit you make.',
|
|
159
|
+
'Coder is <coder-llm>; Reviewer is <reviewer-llm>.',
|
|
136
160
|
'',
|
|
137
161
|
'If you reject every item, change nothing and make no commit.',
|
|
138
162
|
'Report every disposition, all relevant run results, and every rebuttal.',
|
|
@@ -141,7 +165,8 @@ const CODER_DISPOSITION_PROMPT = [
|
|
|
141
165
|
const REVIEW_RESULTS = {
|
|
142
166
|
hasFindings:
|
|
143
167
|
'Reviewer raised one or more unsettled findings. Output shall include `reviewerOutput: <verbatim final text>`.',
|
|
144
|
-
noFindings:
|
|
168
|
+
noFindings:
|
|
169
|
+
'Reviewer affirmatively reported the requested review complete with no unsettled findings remaining; a progress report, status update, or promise of a later result supports no review outcome. Output shall include `evaluatedRevision: <repository revision>`.',
|
|
145
170
|
needsBossReply: NEEDS_BOSS_REPLY_DESCRIPTION,
|
|
146
171
|
} as const;
|
|
147
172
|
|
|
@@ -149,31 +174,31 @@ const REBUTTAL_RESULTS = {
|
|
|
149
174
|
hasFindings:
|
|
150
175
|
'Reviewer kept one or more unsettled findings. Output shall include `reviewerOutput: <verbatim final text>`.',
|
|
151
176
|
noFindings:
|
|
152
|
-
'Reviewer accepted the rebuttals and no unsettled findings
|
|
177
|
+
'Reviewer accepted the rebuttals and affirmatively reported the requested review complete with no unsettled findings remaining; a progress report, status update, or promise of a later result supports no review outcome. Output shall include `evaluatedRevision: <repository revision>`.',
|
|
153
178
|
needsBossReply: NEEDS_BOSS_REPLY_DESCRIPTION,
|
|
154
179
|
} as const;
|
|
155
180
|
|
|
156
181
|
const CODER_RESULTS = {
|
|
157
182
|
committed:
|
|
158
|
-
'Coder accepted at least one item and
|
|
183
|
+
'Coder accepted at least one item and added one new review-fix commit. Output shall include `coderOutput: <verbatim final text>` and `latestCommit: <commit identity>`.',
|
|
159
184
|
rejectedAll:
|
|
160
185
|
'Coder rejected every item and made no commit. Output shall include `coderOutput: <verbatim final text>`.',
|
|
161
186
|
needsBossReply: NEEDS_BOSS_REPLY_DESCRIPTION,
|
|
162
187
|
} as const;
|
|
163
188
|
|
|
164
189
|
const stateDescriptions = {
|
|
165
|
-
ready: 'Waits for a caller to start a committed-work review.',
|
|
190
|
+
ready: 'Waits for a caller to start a scoped committed-work review.',
|
|
166
191
|
reviewInitial:
|
|
167
|
-
|
|
192
|
+
"REVIEW-1: Reviewer reviews the caller's review scope against the original intent.",
|
|
168
193
|
addressFindings:
|
|
169
194
|
'REVIEW-2: Coder accepts or rejects every current review finding.',
|
|
170
195
|
reviewAfterCommit:
|
|
171
|
-
'REVIEW-3: Reviewer
|
|
196
|
+
'REVIEW-3: Reviewer reviews the cumulative committed state after a review-fix commit.',
|
|
172
197
|
reviewAfterRebuttal:
|
|
173
198
|
'REVIEW-4: Reviewer adjudicates an all-rejected Coder disposition.',
|
|
174
199
|
awaitBossReply: 'Waits for Boss to answer the active player question.',
|
|
175
200
|
failed: 'Retains a recoverable REVIEW failure for the caller.',
|
|
176
|
-
done: 'The
|
|
201
|
+
done: 'The requested review is complete: no unsettled findings remain within the review scope.',
|
|
177
202
|
} as const;
|
|
178
203
|
|
|
179
204
|
const playbookMeta = <StateId extends keyof typeof stateDescriptions>(
|
|
@@ -240,11 +265,19 @@ export const reviewMachine = setup({
|
|
|
240
265
|
isNonEmptyString(output.reviewerOutput)
|
|
241
266
|
);
|
|
242
267
|
},
|
|
243
|
-
noFindings: ({ event }) =>
|
|
268
|
+
noFindings: ({ event }) => {
|
|
269
|
+
const output = outputOf(event);
|
|
270
|
+
return (
|
|
271
|
+
output.guard === 'noFindings' &&
|
|
272
|
+
isNonEmptyString(output.evaluatedRevision)
|
|
273
|
+
);
|
|
274
|
+
},
|
|
244
275
|
committed: ({ event }) => {
|
|
245
276
|
const output = outputOf(event);
|
|
246
277
|
return (
|
|
247
|
-
output.guard === 'committed' &&
|
|
278
|
+
output.guard === 'committed' &&
|
|
279
|
+
isNonEmptyString(output.coderOutput) &&
|
|
280
|
+
isNonEmptyString(output.latestCommit)
|
|
248
281
|
);
|
|
249
282
|
},
|
|
250
283
|
rejectedAll: ({ event }) => {
|
|
@@ -305,6 +338,8 @@ export const reviewMachine = setup({
|
|
|
305
338
|
event.type === 'START_REVIEW' ? event.callerInput : undefined,
|
|
306
339
|
reviewerOutput: undefined,
|
|
307
340
|
coderOutput: undefined,
|
|
341
|
+
latestCommit: undefined,
|
|
342
|
+
evaluatedRevision: undefined,
|
|
308
343
|
lastError: undefined,
|
|
309
344
|
pendingBossQuestion: undefined,
|
|
310
345
|
bossReply: undefined,
|
|
@@ -314,6 +349,8 @@ export const reviewMachine = setup({
|
|
|
314
349
|
event.type === 'BOSS_INTERRUPT' ? event.bossIntent : undefined,
|
|
315
350
|
reviewerOutput: undefined,
|
|
316
351
|
coderOutput: undefined,
|
|
352
|
+
latestCommit: undefined,
|
|
353
|
+
evaluatedRevision: undefined,
|
|
317
354
|
lastError: undefined,
|
|
318
355
|
pendingBossQuestion: undefined,
|
|
319
356
|
bossReply: undefined,
|
|
@@ -336,11 +373,29 @@ export const reviewMachine = setup({
|
|
|
336
373
|
? output.coderOutput
|
|
337
374
|
: undefined;
|
|
338
375
|
},
|
|
376
|
+
// The receipt-derived review-fix commit identity replaces the prior one
|
|
377
|
+
// only when Coder committed; an all-rejected round leaves the evaluated
|
|
378
|
+
// revision unchanged.
|
|
379
|
+
latestCommit: ({ context, event }) => {
|
|
380
|
+
const output = outputOf(event);
|
|
381
|
+
return output.guard === 'committed'
|
|
382
|
+
? output.latestCommit
|
|
383
|
+
: context.latestCommit;
|
|
384
|
+
},
|
|
339
385
|
lastError: undefined,
|
|
340
386
|
pendingBossQuestion: undefined,
|
|
341
387
|
bossReply: undefined,
|
|
342
388
|
}),
|
|
343
|
-
|
|
389
|
+
rememberEvaluatedRevision: assign({
|
|
390
|
+
// DR-045: the closing clean round's unchanged receipt observes the
|
|
391
|
+
// exact revision the review scope was evaluated at.
|
|
392
|
+
evaluatedRevision: ({ context, event }) => {
|
|
393
|
+
const output = outputOf(event);
|
|
394
|
+
return output.guard === 'noFindings'
|
|
395
|
+
? output.evaluatedRevision
|
|
396
|
+
: context.evaluatedRevision;
|
|
397
|
+
},
|
|
398
|
+
lastError: undefined,
|
|
344
399
|
pendingBossQuestion: undefined,
|
|
345
400
|
bossReply: undefined,
|
|
346
401
|
}),
|
|
@@ -478,7 +533,7 @@ export const reviewMachine = setup({
|
|
|
478
533
|
acceptedOutcome: 'noFindings',
|
|
479
534
|
},
|
|
480
535
|
},
|
|
481
|
-
'
|
|
536
|
+
'rememberEvaluatedRevision',
|
|
482
537
|
],
|
|
483
538
|
},
|
|
484
539
|
{
|
|
@@ -516,6 +571,7 @@ export const reviewMachine = setup({
|
|
|
516
571
|
role: 'coder',
|
|
517
572
|
prompt: CODER_DISPOSITION_PROMPT,
|
|
518
573
|
result: CODER_RESULTS,
|
|
574
|
+
callerInput: context.callerInput,
|
|
519
575
|
reviewerOutput: context.reviewerOutput,
|
|
520
576
|
pendingBossQuestion: context.pendingBossQuestion,
|
|
521
577
|
bossReply: context.bossReply,
|
|
@@ -586,6 +642,8 @@ export const reviewMachine = setup({
|
|
|
586
642
|
role: 'reviewer',
|
|
587
643
|
prompt: POST_COMMIT_REVIEW_PROMPT,
|
|
588
644
|
result: REVIEW_RESULTS,
|
|
645
|
+
callerInput: context.callerInput,
|
|
646
|
+
latestCommit: context.latestCommit,
|
|
589
647
|
coderOutput: context.coderOutput,
|
|
590
648
|
pendingBossQuestion: context.pendingBossQuestion,
|
|
591
649
|
bossReply: context.bossReply,
|
|
@@ -618,7 +676,7 @@ export const reviewMachine = setup({
|
|
|
618
676
|
acceptedOutcome: 'noFindings',
|
|
619
677
|
},
|
|
620
678
|
},
|
|
621
|
-
'
|
|
679
|
+
'rememberEvaluatedRevision',
|
|
622
680
|
],
|
|
623
681
|
},
|
|
624
682
|
{
|
|
@@ -656,6 +714,7 @@ export const reviewMachine = setup({
|
|
|
656
714
|
role: 'reviewer',
|
|
657
715
|
prompt: REBUTTAL_REVIEW_PROMPT,
|
|
658
716
|
result: REBUTTAL_RESULTS,
|
|
717
|
+
callerInput: context.callerInput,
|
|
659
718
|
coderOutput: context.coderOutput,
|
|
660
719
|
pendingBossQuestion: context.pendingBossQuestion,
|
|
661
720
|
bossReply: context.bossReply,
|
|
@@ -688,7 +747,7 @@ export const reviewMachine = setup({
|
|
|
688
747
|
acceptedOutcome: 'noFindings',
|
|
689
748
|
},
|
|
690
749
|
},
|
|
691
|
-
'
|
|
750
|
+
'rememberEvaluatedRevision',
|
|
692
751
|
],
|
|
693
752
|
},
|
|
694
753
|
{
|
|
@@ -777,8 +836,15 @@ export const reviewMachine = setup({
|
|
|
777
836
|
type: 'final',
|
|
778
837
|
},
|
|
779
838
|
},
|
|
780
|
-
output: (): ReviewOutput =>
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
839
|
+
output: ({ context }): ReviewOutput => {
|
|
840
|
+
if (!isNonEmptyString(context.evaluatedRevision)) {
|
|
841
|
+
throw new Error(
|
|
842
|
+
'REVIEW reached done without a receipt-observed evaluated revision',
|
|
843
|
+
);
|
|
844
|
+
}
|
|
845
|
+
return {
|
|
846
|
+
noUnsettledFindings: true,
|
|
847
|
+
evaluatedRevision: context.evaluatedRevision,
|
|
848
|
+
};
|
|
849
|
+
},
|
|
784
850
|
});
|
|
@@ -1,30 +1,41 @@
|
|
|
1
1
|
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
2
2
|
<!-- SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai> -->
|
|
3
3
|
|
|
4
|
-
# REVIEW:
|
|
4
|
+
# REVIEW: Scoped Committed-Work Review Workflow
|
|
5
5
|
|
|
6
6
|
Roles:
|
|
7
7
|
|
|
8
8
|
- Coder
|
|
9
9
|
- Reviewer
|
|
10
10
|
|
|
11
|
+
The caller supplies one caller input carrying the original intent, the review scope in the caller's own words, and optional relevant context and run results.
|
|
12
|
+
The caller's review scope is the baseline for every round, and each review-fix commit joins that scope as it lands, so every later round reviews the cumulative committed state.
|
|
13
|
+
`review` examines committed work only.
|
|
14
|
+
Captain takes the evaluated repository revision from repository authority, not from either player's prose: the repository-effect receipt is the authoritative identity of any review-fix commit, and a clean round's `unchanged` receipt proves the observed revision it evaluated.
|
|
15
|
+
Finding numbers are references within this review only; no review transition depends on numbering or any fixed presentation format of either player's reply.
|
|
16
|
+
Rounds continue until Reviewer affirmatively reports that the requested review is complete and no unsettled findings remain; `review` then returns the exact repository revision at which the review scope was evaluated and the fact that no unsettled findings remain within that scope.
|
|
17
|
+
|
|
11
18
|
### REVIEW-1
|
|
12
19
|
|
|
13
20
|
When the caller starts a review, Captain shall relay the complete caller input to Reviewer with the first-round and shared review instructions:
|
|
14
21
|
|
|
15
|
-
> A new review begins
|
|
16
|
-
>
|
|
22
|
+
> A new review begins for the review scope.
|
|
23
|
+
> Keep to the original intent and follow what it asks.
|
|
24
|
+
> When the scope names commits, read each commit message for its context and rationale; otherwise use repository history and commit messages wherever they help establish that context.
|
|
17
25
|
>
|
|
18
26
|
> > <caller-input>
|
|
19
27
|
>
|
|
20
28
|
> Understand the full picture and think systematically about the underlying design.
|
|
21
|
-
> Continue to identify issues or improvements, if any
|
|
22
|
-
>
|
|
23
|
-
> Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.
|
|
29
|
+
> Continue to identify issues or improvements, if any, without duplication.
|
|
30
|
+
> Number the findings consistently across rounds.
|
|
24
31
|
> Flag only what materially affects correctness, behavior, or spec quality — not style, equally valid alternatives, or theoretical threats.
|
|
25
|
-
> For specs, flag stale, missing, over-specified, or under-specified ones.
|
|
32
|
+
> For specs, flag stale, missing, over-specified, or under-specified ones, if any.
|
|
26
33
|
> Avoid unnecessary complexity in code or tests, but flag any fundamental design flaw when leaving it would cost more in later patches than fixing it now.
|
|
27
34
|
>
|
|
35
|
+
> If an issue represents a class of defect, find every instance within the review scope worth fixing rather than surfacing one or two per round, which drags out the review.
|
|
36
|
+
> For any rebuttal, accept or challenge it.
|
|
37
|
+
> Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.
|
|
38
|
+
>
|
|
28
39
|
> Do not re-run tests or builds whose inputs have not changed since any previous reported run.
|
|
29
40
|
> Do not edit files or commit; report findings only.
|
|
30
41
|
>
|
|
@@ -33,49 +44,59 @@ When the caller starts a review, Captain shall relay the complete caller input t
|
|
|
33
44
|
|
|
34
45
|
Results:
|
|
35
46
|
- `hasFindings`: Reviewer raised one or more unsettled findings. Output shall include `reviewerOutput: <verbatim final text>`.
|
|
36
|
-
- `noFindings`: Reviewer
|
|
47
|
+
- `noFindings`: Reviewer affirmatively reported the requested review complete with no unsettled findings remaining; a progress report, status update, or promise of a later result supports no review outcome. Output shall include `evaluatedRevision: <repository revision>`.
|
|
37
48
|
|
|
38
49
|
### REVIEW-2
|
|
39
50
|
|
|
40
|
-
When Reviewer raises or keeps any finding, Captain shall relay Reviewer's
|
|
51
|
+
When Reviewer raises or keeps any finding, Captain shall relay the caller input and Reviewer's findings to Coder with the disposition prompt:
|
|
41
52
|
|
|
53
|
+
> > <caller-input>
|
|
42
54
|
> > <reviewer-output>
|
|
43
55
|
>
|
|
44
56
|
> For each review item, accept or reject it.
|
|
45
57
|
> Before deciding, understand the full picture and think systematically about the underlying design.
|
|
58
|
+
> Keep to the original intent and follow what it asks.
|
|
46
59
|
> Reject anything that is not essential or is not worth fixing now.
|
|
47
|
-
> If you accept an item, fix its root cause, including any fundamental design flaw
|
|
60
|
+
> If you accept an item, fix its root cause, including any fundamental design flaw — do not patch around it; if it represents a class of defect, find every instance within the review scope worth fixing rather than addressing one or two per round, which drags out the review.
|
|
48
61
|
> If you reject an item, give the reasoning and cite code or test output that supports it.
|
|
49
62
|
> Do not re-run tests or builds whose inputs have not changed since any previous reported run.
|
|
50
63
|
>
|
|
51
|
-
> If you accept any item, make minimal changes and
|
|
64
|
+
> If you accept any item, make minimal changes and add one new review-fix commit; never rewrite any existing commit.
|
|
52
65
|
> Follow @specs/packages/git.md.
|
|
53
66
|
> Make the commit message explain concisely what changed and why, including relevant verification.
|
|
54
|
-
>
|
|
67
|
+
> Identify every new commit you make.
|
|
68
|
+
> Coder is <coder-llm>; Reviewer is <reviewer-llm>.
|
|
55
69
|
>
|
|
56
70
|
> If you reject every item, change nothing and make no commit.
|
|
57
71
|
> Report every disposition, all relevant run results, and every rebuttal.
|
|
58
72
|
|
|
59
73
|
Results:
|
|
60
|
-
- `committed`: Coder accepted at least one item and
|
|
74
|
+
- `committed`: Coder accepted at least one item and added one new review-fix commit. Output shall include `coderOutput: <verbatim final text>` and `latestCommit: <commit identity>`.
|
|
61
75
|
- `rejectedAll`: Coder rejected every item and made no commit. Output shall include `coderOutput: <verbatim final text>`.
|
|
62
76
|
|
|
63
77
|
### REVIEW-3
|
|
64
78
|
|
|
65
|
-
When Coder makes a review-fix commit, Captain shall relay Coder's
|
|
79
|
+
When Coder makes a review-fix commit, Captain shall relay the caller input, the review-fix commit, and Coder's feedback to Reviewer with the next-round and shared review instructions:
|
|
66
80
|
|
|
67
|
-
>
|
|
81
|
+
> A new review round begins for the review scope in the cumulative committed state, with particular attention to the latest review-fix commit.
|
|
82
|
+
> Keep to the original intent and follow what it asks.
|
|
83
|
+
> Read the latest review-fix commit's message and see Coder's feedback below.
|
|
68
84
|
>
|
|
85
|
+
> > <caller-input>
|
|
86
|
+
> > <latest-commit>
|
|
69
87
|
> > <coder-output>
|
|
70
88
|
>
|
|
71
89
|
> Understand the full picture and think systematically about the underlying design.
|
|
72
|
-
> Continue to identify issues or improvements, if any
|
|
73
|
-
>
|
|
74
|
-
> Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.
|
|
90
|
+
> Continue to identify issues or improvements, if any, without duplication.
|
|
91
|
+
> Number the findings consistently across rounds.
|
|
75
92
|
> Flag only what materially affects correctness, behavior, or spec quality — not style, equally valid alternatives, or theoretical threats.
|
|
76
|
-
> For specs, flag stale, missing, over-specified, or under-specified ones.
|
|
93
|
+
> For specs, flag stale, missing, over-specified, or under-specified ones, if any.
|
|
77
94
|
> Avoid unnecessary complexity in code or tests, but flag any fundamental design flaw when leaving it would cost more in later patches than fixing it now.
|
|
78
95
|
>
|
|
96
|
+
> If an issue represents a class of defect, find every instance within the review scope worth fixing rather than surfacing one or two per round, which drags out the review.
|
|
97
|
+
> For any rebuttal, accept or challenge it.
|
|
98
|
+
> Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.
|
|
99
|
+
>
|
|
79
100
|
> Do not re-run tests or builds whose inputs have not changed since any previous reported run.
|
|
80
101
|
> Do not edit files or commit; report findings only.
|
|
81
102
|
>
|
|
@@ -84,24 +105,29 @@ When Coder makes a review-fix commit, Captain shall relay Coder's output to Revi
|
|
|
84
105
|
|
|
85
106
|
Results:
|
|
86
107
|
- `hasFindings`: Reviewer raised one or more unsettled findings. Output shall include `reviewerOutput: <verbatim final text>`.
|
|
87
|
-
- `noFindings`: Reviewer
|
|
108
|
+
- `noFindings`: Reviewer affirmatively reported the requested review complete with no unsettled findings remaining; a progress report, status update, or promise of a later result supports no review outcome. Output shall include `evaluatedRevision: <repository revision>`.
|
|
88
109
|
|
|
89
110
|
### REVIEW-4
|
|
90
111
|
|
|
91
|
-
When Coder rejects every finding and makes no commit, Captain shall relay Coder's
|
|
112
|
+
When Coder rejects every finding and makes no commit, Captain shall relay the caller input and Coder's feedback to Reviewer with the rebuttal and shared review instructions:
|
|
92
113
|
|
|
93
114
|
> No new commit was made because Coder rejected every finding.
|
|
115
|
+
> See Coder's feedback below.
|
|
94
116
|
>
|
|
117
|
+
> > <caller-input>
|
|
95
118
|
> > <coder-output>
|
|
96
119
|
>
|
|
97
120
|
> Understand the full picture and think systematically about the underlying design.
|
|
98
|
-
> Continue to identify issues or improvements, if any
|
|
99
|
-
>
|
|
100
|
-
> Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.
|
|
121
|
+
> Continue to identify issues or improvements, if any, without duplication.
|
|
122
|
+
> Number the findings consistently across rounds.
|
|
101
123
|
> Flag only what materially affects correctness, behavior, or spec quality — not style, equally valid alternatives, or theoretical threats.
|
|
102
|
-
> For specs, flag stale, missing, over-specified, or under-specified ones.
|
|
124
|
+
> For specs, flag stale, missing, over-specified, or under-specified ones, if any.
|
|
103
125
|
> Avoid unnecessary complexity in code or tests, but flag any fundamental design flaw when leaving it would cost more in later patches than fixing it now.
|
|
104
126
|
>
|
|
127
|
+
> If an issue represents a class of defect, find every instance within the review scope worth fixing rather than surfacing one or two per round, which drags out the review.
|
|
128
|
+
> For any rebuttal, accept or challenge it.
|
|
129
|
+
> Treat as settled, and do not raise again, any finding in this review rejected twice with reasoning.
|
|
130
|
+
>
|
|
105
131
|
> Do not re-run tests or builds whose inputs have not changed since any previous reported run.
|
|
106
132
|
> Do not edit files or commit; report findings only.
|
|
107
133
|
>
|
|
@@ -110,4 +136,4 @@ When Coder rejects every finding and makes no commit, Captain shall relay Coder'
|
|
|
110
136
|
|
|
111
137
|
Results:
|
|
112
138
|
- `hasFindings`: Reviewer kept one or more unsettled findings. Output shall include `reviewerOutput: <verbatim final text>`.
|
|
113
|
-
- `noFindings`: Reviewer accepted the rebuttals and no unsettled findings
|
|
139
|
+
- `noFindings`: Reviewer accepted the rebuttals and affirmatively reported the requested review complete with no unsettled findings remaining; a progress report, status update, or promise of a later result supports no review outcome. Output shall include `evaluatedRevision: <repository revision>`.
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
// Boss event: deterministic START_REVIEW entry; exact Boss text becomes
|
|
8
8
|
// callerInput; pending player questions retain BOSS_REPLY
|
|
9
9
|
// Adjudication: LLM judge per state; coderOutput and reviewerOutput are
|
|
10
|
-
// carried verbatim
|
|
10
|
+
// carried verbatim; latestCommit is receipt-owned effect
|
|
11
|
+
// evidence, never taken from either player's prose
|
|
11
12
|
// Compat: artifact schema 3 / runtime ABI 1
|
|
12
13
|
import { createXStatePlaybookRuntime, snapshotJsonValue, } from '@sublang/playbook/xstate-runtime';
|
|
13
14
|
import { reviewMachine, } from './review.fsm.js';
|
|
@@ -90,7 +91,7 @@ const runtimeSpec = {
|
|
|
90
91
|
roleStates: {
|
|
91
92
|
reviewInitial: {
|
|
92
93
|
role: 'reviewer',
|
|
93
|
-
label:
|
|
94
|
+
label: "REVIEW-1: Reviewer reviews the caller's review scope against the original intent.",
|
|
94
95
|
},
|
|
95
96
|
addressFindings: {
|
|
96
97
|
role: 'coder',
|
|
@@ -98,7 +99,7 @@ const runtimeSpec = {
|
|
|
98
99
|
},
|
|
99
100
|
reviewAfterCommit: {
|
|
100
101
|
role: 'reviewer',
|
|
101
|
-
label: 'REVIEW-3: Reviewer
|
|
102
|
+
label: 'REVIEW-3: Reviewer reviews the cumulative committed state after a review-fix commit.',
|
|
102
103
|
},
|
|
103
104
|
reviewAfterRebuttal: {
|
|
104
105
|
role: 'reviewer',
|
|
@@ -113,7 +114,9 @@ const runtimeSpec = {
|
|
|
113
114
|
repositoryDisposition: 'unchanged',
|
|
114
115
|
},
|
|
115
116
|
noFindings: {
|
|
116
|
-
|
|
117
|
+
// DR-045: the clean round's unchanged receipt observes the exact
|
|
118
|
+
// evaluated revision as HEAD; the reconciler injects it here.
|
|
119
|
+
fields: { evaluatedRevision: 'effect' },
|
|
117
120
|
repositoryDisposition: 'unchanged',
|
|
118
121
|
},
|
|
119
122
|
needsBossReply: {
|
|
@@ -123,7 +126,10 @@ const runtimeSpec = {
|
|
|
123
126
|
},
|
|
124
127
|
addressFindings: {
|
|
125
128
|
committed: {
|
|
126
|
-
fields: {
|
|
129
|
+
fields: {
|
|
130
|
+
coderOutput: 'presentation',
|
|
131
|
+
latestCommit: 'effect',
|
|
132
|
+
},
|
|
127
133
|
repositoryDisposition: 'one-descendant-commit',
|
|
128
134
|
},
|
|
129
135
|
rejectedAll: {
|
|
@@ -141,7 +147,9 @@ const runtimeSpec = {
|
|
|
141
147
|
repositoryDisposition: 'unchanged',
|
|
142
148
|
},
|
|
143
149
|
noFindings: {
|
|
144
|
-
|
|
150
|
+
// DR-045: the clean round's unchanged receipt observes the exact
|
|
151
|
+
// evaluated revision as HEAD; the reconciler injects it here.
|
|
152
|
+
fields: { evaluatedRevision: 'effect' },
|
|
145
153
|
repositoryDisposition: 'unchanged',
|
|
146
154
|
},
|
|
147
155
|
needsBossReply: {
|
|
@@ -155,7 +163,9 @@ const runtimeSpec = {
|
|
|
155
163
|
repositoryDisposition: 'unchanged',
|
|
156
164
|
},
|
|
157
165
|
noFindings: {
|
|
158
|
-
|
|
166
|
+
// DR-045: the clean round's unchanged receipt observes the exact
|
|
167
|
+
// evaluated revision as HEAD; the reconciler injects it here.
|
|
168
|
+
fields: { evaluatedRevision: 'effect' },
|
|
159
169
|
repositoryDisposition: 'unchanged',
|
|
160
170
|
},
|
|
161
171
|
needsBossReply: {
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
// Boss event: deterministic START_REVIEW entry; exact Boss text becomes
|
|
8
8
|
// callerInput; pending player questions retain BOSS_REPLY
|
|
9
9
|
// Adjudication: LLM judge per state; coderOutput and reviewerOutput are
|
|
10
|
-
// carried verbatim
|
|
10
|
+
// carried verbatim; latestCommit is receipt-owned effect
|
|
11
|
+
// evidence, never taken from either player's prose
|
|
11
12
|
// Compat: artifact schema 3 / runtime ABI 1
|
|
12
13
|
|
|
13
14
|
import {
|
|
@@ -181,7 +182,7 @@ const runtimeSpec = {
|
|
|
181
182
|
reviewInitial: {
|
|
182
183
|
role: 'reviewer',
|
|
183
184
|
label:
|
|
184
|
-
|
|
185
|
+
"REVIEW-1: Reviewer reviews the caller's review scope against the original intent.",
|
|
185
186
|
},
|
|
186
187
|
addressFindings: {
|
|
187
188
|
role: 'coder',
|
|
@@ -190,7 +191,7 @@ const runtimeSpec = {
|
|
|
190
191
|
reviewAfterCommit: {
|
|
191
192
|
role: 'reviewer',
|
|
192
193
|
label:
|
|
193
|
-
'REVIEW-3: Reviewer
|
|
194
|
+
'REVIEW-3: Reviewer reviews the cumulative committed state after a review-fix commit.',
|
|
194
195
|
},
|
|
195
196
|
reviewAfterRebuttal: {
|
|
196
197
|
role: 'reviewer',
|
|
@@ -206,7 +207,9 @@ const runtimeSpec = {
|
|
|
206
207
|
repositoryDisposition: 'unchanged',
|
|
207
208
|
},
|
|
208
209
|
noFindings: {
|
|
209
|
-
|
|
210
|
+
// DR-045: the clean round's unchanged receipt observes the exact
|
|
211
|
+
// evaluated revision as HEAD; the reconciler injects it here.
|
|
212
|
+
fields: { evaluatedRevision: 'effect' },
|
|
210
213
|
repositoryDisposition: 'unchanged',
|
|
211
214
|
},
|
|
212
215
|
needsBossReply: {
|
|
@@ -216,7 +219,10 @@ const runtimeSpec = {
|
|
|
216
219
|
},
|
|
217
220
|
addressFindings: {
|
|
218
221
|
committed: {
|
|
219
|
-
fields: {
|
|
222
|
+
fields: {
|
|
223
|
+
coderOutput: 'presentation',
|
|
224
|
+
latestCommit: 'effect',
|
|
225
|
+
},
|
|
220
226
|
repositoryDisposition: 'one-descendant-commit',
|
|
221
227
|
},
|
|
222
228
|
rejectedAll: {
|
|
@@ -234,7 +240,9 @@ const runtimeSpec = {
|
|
|
234
240
|
repositoryDisposition: 'unchanged',
|
|
235
241
|
},
|
|
236
242
|
noFindings: {
|
|
237
|
-
|
|
243
|
+
// DR-045: the clean round's unchanged receipt observes the exact
|
|
244
|
+
// evaluated revision as HEAD; the reconciler injects it here.
|
|
245
|
+
fields: { evaluatedRevision: 'effect' },
|
|
238
246
|
repositoryDisposition: 'unchanged',
|
|
239
247
|
},
|
|
240
248
|
needsBossReply: {
|
|
@@ -248,7 +256,9 @@ const runtimeSpec = {
|
|
|
248
256
|
repositoryDisposition: 'unchanged',
|
|
249
257
|
},
|
|
250
258
|
noFindings: {
|
|
251
|
-
|
|
259
|
+
// DR-045: the clean round's unchanged receipt observes the exact
|
|
260
|
+
// evaluated revision as HEAD; the reconciler injects it here.
|
|
261
|
+
fields: { evaluatedRevision: 'effect' },
|
|
252
262
|
repositoryDisposition: 'unchanged',
|
|
253
263
|
},
|
|
254
264
|
needsBossReply: {
|
|
@@ -47,7 +47,7 @@ export function validateReviewOptions(optionSlice) {
|
|
|
47
47
|
export const reviewPlaybookRegistryEntry = {
|
|
48
48
|
id: 'review',
|
|
49
49
|
command: 'review',
|
|
50
|
-
intent: 'review
|
|
50
|
+
intent: 'review a supplied scope of committed work until no unsettled findings remain',
|
|
51
51
|
artifactSchema: 3,
|
|
52
52
|
runtimeProfile: Object.freeze({
|
|
53
53
|
kind: 'shared-factory',
|
|
@@ -104,7 +104,7 @@ export const reviewPlaybookRegistryEntry: ReviewPlaybookRegistryEntry = {
|
|
|
104
104
|
id: 'review',
|
|
105
105
|
command: 'review',
|
|
106
106
|
intent:
|
|
107
|
-
'review
|
|
107
|
+
'review a supplied scope of committed work until no unsettled findings remain',
|
|
108
108
|
artifactSchema: 3,
|
|
109
109
|
runtimeProfile: Object.freeze({
|
|
110
110
|
kind: 'shared-factory',
|