@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
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
// callerInput; pending player questions retain BOSS_REPLY
|
|
9
9
|
// Adjudication: LLM judge per state; coderOutput and reviewerOutput are
|
|
10
10
|
// carried verbatim
|
|
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 { reviewMachine, } from './review.fsm.js';
|
|
14
14
|
const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
|
|
15
15
|
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,6 +17,7 @@ const VERBATIM_PAYLOAD_FIELDS = new Set([
|
|
|
17
17
|
'reviewerOutput',
|
|
18
18
|
'coderOutput',
|
|
19
19
|
]);
|
|
20
|
+
const UNFINISHED_FINAL_STATE_IDS = new Set();
|
|
20
21
|
function snapshotReviewOptions(value) {
|
|
21
22
|
const captured = snapshotJsonValue(value, 'REVIEW runtime options');
|
|
22
23
|
if (captured === null ||
|
|
@@ -68,12 +69,24 @@ function composePlayerPrompt(input, promptIdentity) {
|
|
|
68
69
|
export const _internal = {
|
|
69
70
|
composePlayerPrompt,
|
|
70
71
|
VERBATIM_PAYLOAD_FIELDS,
|
|
72
|
+
UNFINISHED_FINAL_STATE_IDS,
|
|
71
73
|
};
|
|
72
74
|
const runtimeSpec = {
|
|
73
75
|
label: 'REVIEW',
|
|
74
|
-
|
|
76
|
+
// DR-022 / slc/link.md: the declaration carries the value current at link
|
|
77
|
+
// time — a literal, never the loading engine's RUNTIME_ABI self-report,
|
|
78
|
+
// which would follow whatever engine loads the module and make the
|
|
79
|
+
// factory's skew check compare that engine with itself.
|
|
80
|
+
compat: { artifactSchema: 3, runtimeAbi: 1 },
|
|
75
81
|
snapshotOptions: snapshotReviewOptions,
|
|
76
|
-
entryEvent: {
|
|
82
|
+
entryEvent: {
|
|
83
|
+
type: 'START_REVIEW',
|
|
84
|
+
textField: 'callerInput',
|
|
85
|
+
// `copyStartInput` copies the entry text here, so the failure-state
|
|
86
|
+
// retry reads it back from the persisted machine snapshot and survives
|
|
87
|
+
// a continued session (DR-034).
|
|
88
|
+
contextField: 'callerInput',
|
|
89
|
+
},
|
|
77
90
|
roleStates: {
|
|
78
91
|
reviewInitial: {
|
|
79
92
|
role: 'reviewer',
|
|
@@ -92,9 +105,70 @@ const runtimeSpec = {
|
|
|
92
105
|
label: 'REVIEW-4: Reviewer adjudicates an all-rejected Coder disposition.',
|
|
93
106
|
},
|
|
94
107
|
},
|
|
108
|
+
outcomeAuthority: {
|
|
109
|
+
governedPlayerStates: {
|
|
110
|
+
reviewInitial: {
|
|
111
|
+
hasFindings: {
|
|
112
|
+
fields: { reviewerOutput: 'presentation' },
|
|
113
|
+
repositoryDisposition: 'unchanged',
|
|
114
|
+
},
|
|
115
|
+
noFindings: {
|
|
116
|
+
fields: {},
|
|
117
|
+
repositoryDisposition: 'unchanged',
|
|
118
|
+
},
|
|
119
|
+
needsBossReply: {
|
|
120
|
+
fields: { question: 'presentation' },
|
|
121
|
+
repositoryDisposition: 'unchanged',
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
addressFindings: {
|
|
125
|
+
committed: {
|
|
126
|
+
fields: { coderOutput: 'presentation' },
|
|
127
|
+
repositoryDisposition: 'one-descendant-commit',
|
|
128
|
+
},
|
|
129
|
+
rejectedAll: {
|
|
130
|
+
fields: { coderOutput: 'presentation' },
|
|
131
|
+
repositoryDisposition: 'unchanged',
|
|
132
|
+
},
|
|
133
|
+
needsBossReply: {
|
|
134
|
+
fields: { question: 'presentation' },
|
|
135
|
+
repositoryDisposition: 'deferred',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
reviewAfterCommit: {
|
|
139
|
+
hasFindings: {
|
|
140
|
+
fields: { reviewerOutput: 'presentation' },
|
|
141
|
+
repositoryDisposition: 'unchanged',
|
|
142
|
+
},
|
|
143
|
+
noFindings: {
|
|
144
|
+
fields: {},
|
|
145
|
+
repositoryDisposition: 'unchanged',
|
|
146
|
+
},
|
|
147
|
+
needsBossReply: {
|
|
148
|
+
fields: { question: 'presentation' },
|
|
149
|
+
repositoryDisposition: 'unchanged',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
reviewAfterRebuttal: {
|
|
153
|
+
hasFindings: {
|
|
154
|
+
fields: { reviewerOutput: 'presentation' },
|
|
155
|
+
repositoryDisposition: 'unchanged',
|
|
156
|
+
},
|
|
157
|
+
noFindings: {
|
|
158
|
+
fields: {},
|
|
159
|
+
repositoryDisposition: 'unchanged',
|
|
160
|
+
},
|
|
161
|
+
needsBossReply: {
|
|
162
|
+
fields: { question: 'presentation' },
|
|
163
|
+
repositoryDisposition: 'unchanged',
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
95
168
|
composePlayerPrompt: (input, promptIdentity) => composePlayerPrompt(input, promptIdentity),
|
|
96
169
|
verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
|
|
97
170
|
controlContextFields: [],
|
|
171
|
+
unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
|
|
98
172
|
transitionEventFields: [
|
|
99
173
|
'callerInput',
|
|
100
174
|
'bossIntent',
|
|
@@ -8,21 +8,23 @@
|
|
|
8
8
|
// callerInput; pending player questions retain BOSS_REPLY
|
|
9
9
|
// Adjudication: LLM judge per state; coderOutput and reviewerOutput are
|
|
10
10
|
// carried verbatim
|
|
11
|
-
// Compat: artifact schema
|
|
11
|
+
// Compat: artifact schema 3 / runtime ABI 1
|
|
12
12
|
|
|
13
13
|
import {
|
|
14
|
-
RUNTIME_ABI,
|
|
15
14
|
createXStatePlaybookRuntime,
|
|
16
15
|
snapshotJsonValue,
|
|
17
16
|
type PlaybookPlayerInput,
|
|
17
|
+
type XStatePlaybookRuntimeFactory,
|
|
18
|
+
type XStatePlaybookRuntimeConstruction,
|
|
18
19
|
type XStatePromptIdentity,
|
|
19
|
-
type
|
|
20
|
+
type XStatePlaybookRuntimeSpecV3,
|
|
20
21
|
} from '@sublang/playbook/xstate-runtime';
|
|
21
22
|
import {
|
|
22
23
|
reviewMachine,
|
|
23
24
|
type PlayerInput,
|
|
24
25
|
type ReviewInput,
|
|
25
26
|
} from './review.fsm.js';
|
|
27
|
+
import type { PlaybookHostConstructionCapabilities } from '../code.playbook/playbook-captain.js';
|
|
26
28
|
import type {
|
|
27
29
|
CaptainCallOptions,
|
|
28
30
|
CaptainResult,
|
|
@@ -76,6 +78,9 @@ export type {
|
|
|
76
78
|
};
|
|
77
79
|
|
|
78
80
|
export type ReviewPlaybookOptions = ReviewInput;
|
|
81
|
+
export type ReviewPlaybookHostCapabilities =
|
|
82
|
+
PlaybookHostConstructionCapabilities &
|
|
83
|
+
XStatePlaybookRuntimeConstruction<ReviewPlaybookOptions, object>['hostCapabilities'];
|
|
79
84
|
|
|
80
85
|
const PLACEHOLDER = /<(#|[A-Za-z_$][A-Za-z0-9_$-]*)>/g;
|
|
81
86
|
const CONTINUATION_PREAMBLE =
|
|
@@ -85,6 +90,7 @@ const VERBATIM_PAYLOAD_FIELDS: ReadonlySet<string> = new Set([
|
|
|
85
90
|
'reviewerOutput',
|
|
86
91
|
'coderOutput',
|
|
87
92
|
]);
|
|
93
|
+
const UNFINISHED_FINAL_STATE_IDS: ReadonlySet<string> = new Set();
|
|
88
94
|
|
|
89
95
|
function snapshotReviewOptions(value: unknown): ReviewPlaybookOptions {
|
|
90
96
|
const captured = snapshotJsonValue(value, 'REVIEW runtime options');
|
|
@@ -152,13 +158,25 @@ function composePlayerPrompt(
|
|
|
152
158
|
export const _internal = {
|
|
153
159
|
composePlayerPrompt,
|
|
154
160
|
VERBATIM_PAYLOAD_FIELDS,
|
|
161
|
+
UNFINISHED_FINAL_STATE_IDS,
|
|
155
162
|
};
|
|
156
163
|
|
|
157
164
|
const runtimeSpec = {
|
|
158
165
|
label: 'REVIEW',
|
|
159
|
-
|
|
166
|
+
// DR-022 / slc/link.md: the declaration carries the value current at link
|
|
167
|
+
// time — a literal, never the loading engine's RUNTIME_ABI self-report,
|
|
168
|
+
// which would follow whatever engine loads the module and make the
|
|
169
|
+
// factory's skew check compare that engine with itself.
|
|
170
|
+
compat: { artifactSchema: 3, runtimeAbi: 1 },
|
|
160
171
|
snapshotOptions: snapshotReviewOptions,
|
|
161
|
-
entryEvent: {
|
|
172
|
+
entryEvent: {
|
|
173
|
+
type: 'START_REVIEW',
|
|
174
|
+
textField: 'callerInput',
|
|
175
|
+
// `copyStartInput` copies the entry text here, so the failure-state
|
|
176
|
+
// retry reads it back from the persisted machine snapshot and survives
|
|
177
|
+
// a continued session (DR-034).
|
|
178
|
+
contextField: 'callerInput',
|
|
179
|
+
},
|
|
162
180
|
roleStates: {
|
|
163
181
|
reviewInitial: {
|
|
164
182
|
role: 'reviewer',
|
|
@@ -180,12 +198,73 @@ const runtimeSpec = {
|
|
|
180
198
|
'REVIEW-4: Reviewer adjudicates an all-rejected Coder disposition.',
|
|
181
199
|
},
|
|
182
200
|
},
|
|
201
|
+
outcomeAuthority: {
|
|
202
|
+
governedPlayerStates: {
|
|
203
|
+
reviewInitial: {
|
|
204
|
+
hasFindings: {
|
|
205
|
+
fields: { reviewerOutput: 'presentation' },
|
|
206
|
+
repositoryDisposition: 'unchanged',
|
|
207
|
+
},
|
|
208
|
+
noFindings: {
|
|
209
|
+
fields: {},
|
|
210
|
+
repositoryDisposition: 'unchanged',
|
|
211
|
+
},
|
|
212
|
+
needsBossReply: {
|
|
213
|
+
fields: { question: 'presentation' },
|
|
214
|
+
repositoryDisposition: 'unchanged',
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
addressFindings: {
|
|
218
|
+
committed: {
|
|
219
|
+
fields: { coderOutput: 'presentation' },
|
|
220
|
+
repositoryDisposition: 'one-descendant-commit',
|
|
221
|
+
},
|
|
222
|
+
rejectedAll: {
|
|
223
|
+
fields: { coderOutput: 'presentation' },
|
|
224
|
+
repositoryDisposition: 'unchanged',
|
|
225
|
+
},
|
|
226
|
+
needsBossReply: {
|
|
227
|
+
fields: { question: 'presentation' },
|
|
228
|
+
repositoryDisposition: 'deferred',
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
reviewAfterCommit: {
|
|
232
|
+
hasFindings: {
|
|
233
|
+
fields: { reviewerOutput: 'presentation' },
|
|
234
|
+
repositoryDisposition: 'unchanged',
|
|
235
|
+
},
|
|
236
|
+
noFindings: {
|
|
237
|
+
fields: {},
|
|
238
|
+
repositoryDisposition: 'unchanged',
|
|
239
|
+
},
|
|
240
|
+
needsBossReply: {
|
|
241
|
+
fields: { question: 'presentation' },
|
|
242
|
+
repositoryDisposition: 'unchanged',
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
reviewAfterRebuttal: {
|
|
246
|
+
hasFindings: {
|
|
247
|
+
fields: { reviewerOutput: 'presentation' },
|
|
248
|
+
repositoryDisposition: 'unchanged',
|
|
249
|
+
},
|
|
250
|
+
noFindings: {
|
|
251
|
+
fields: {},
|
|
252
|
+
repositoryDisposition: 'unchanged',
|
|
253
|
+
},
|
|
254
|
+
needsBossReply: {
|
|
255
|
+
fields: { question: 'presentation' },
|
|
256
|
+
repositoryDisposition: 'unchanged',
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
},
|
|
183
261
|
composePlayerPrompt: (
|
|
184
262
|
input: PlaybookPlayerInput,
|
|
185
263
|
promptIdentity: XStatePromptIdentity,
|
|
186
264
|
) => composePlayerPrompt(input as PlayerInput, promptIdentity),
|
|
187
265
|
verbatimPayloadFields: VERBATIM_PAYLOAD_FIELDS,
|
|
188
266
|
controlContextFields: [],
|
|
267
|
+
unfinishedFinalStateIds: UNFINISHED_FINAL_STATE_IDS,
|
|
189
268
|
transitionEventFields: [
|
|
190
269
|
'callerInput',
|
|
191
270
|
'bossIntent',
|
|
@@ -193,9 +272,17 @@ const runtimeSpec = {
|
|
|
193
272
|
'answer',
|
|
194
273
|
'questionId',
|
|
195
274
|
],
|
|
196
|
-
} satisfies
|
|
275
|
+
} satisfies XStatePlaybookRuntimeSpecV3<ReviewPlaybookOptions>;
|
|
197
276
|
|
|
198
|
-
const createPlaybookRuntime:
|
|
199
|
-
|
|
277
|
+
const createPlaybookRuntime: XStatePlaybookRuntimeFactory<
|
|
278
|
+
XStatePlaybookRuntimeConstruction<
|
|
279
|
+
ReviewPlaybookOptions,
|
|
280
|
+
ReviewPlaybookHostCapabilities
|
|
281
|
+
>,
|
|
282
|
+
3
|
|
283
|
+
> = createXStatePlaybookRuntime<
|
|
284
|
+
ReviewPlaybookOptions,
|
|
285
|
+
ReviewPlaybookHostCapabilities
|
|
286
|
+
>(reviewMachine, runtimeSpec);
|
|
200
287
|
|
|
201
288
|
export default createPlaybookRuntime;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PlaybookRuntime } from './review.playbook.js';
|
|
1
|
+
import { type ReviewPlaybookHostCapabilities, type PlaybookRuntime } from './review.playbook.js';
|
|
2
2
|
export interface PlaybookSummaryPolicy {
|
|
3
3
|
stateCountLabels: Readonly<Record<string, string>>;
|
|
4
4
|
copyPasteGuardNames: readonly string[];
|
|
@@ -12,12 +12,19 @@ export interface ReviewPlaybookRegistryEntry {
|
|
|
12
12
|
id: 'review';
|
|
13
13
|
command: 'review';
|
|
14
14
|
intent: string;
|
|
15
|
-
artifactSchema:
|
|
15
|
+
artifactSchema: 3;
|
|
16
|
+
runtimeProfile: {
|
|
17
|
+
readonly kind: 'shared-factory';
|
|
18
|
+
readonly compat: {
|
|
19
|
+
readonly artifactSchema: 3;
|
|
20
|
+
readonly runtimeAbi: number;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
16
23
|
requiredRoleIds: readonly ['coder', 'reviewer'];
|
|
17
24
|
concurrentRoleSets: readonly [];
|
|
18
25
|
summaryPolicy: PlaybookSummaryPolicy;
|
|
19
26
|
validateOptions(optionSlice: unknown): ReviewOptions;
|
|
20
|
-
createRuntime(options: ReviewOptions): PlaybookRuntime;
|
|
27
|
+
createRuntime(options: ReviewOptions, hostCapabilities: ReviewPlaybookHostCapabilities): PlaybookRuntime;
|
|
21
28
|
}
|
|
22
29
|
export declare const reviewStateCountLabels: {
|
|
23
30
|
readonly reviewInitial: "review round";
|
|
@@ -48,13 +48,20 @@ export const reviewPlaybookRegistryEntry = {
|
|
|
48
48
|
id: 'review',
|
|
49
49
|
command: 'review',
|
|
50
50
|
intent: 'review the latest commit until no material correctness or spec findings remain',
|
|
51
|
-
artifactSchema:
|
|
51
|
+
artifactSchema: 3,
|
|
52
|
+
runtimeProfile: Object.freeze({
|
|
53
|
+
kind: 'shared-factory',
|
|
54
|
+
compat: createPlaybookRuntime.compat,
|
|
55
|
+
}),
|
|
52
56
|
requiredRoleIds: ['coder', 'reviewer'],
|
|
53
57
|
concurrentRoleSets: [],
|
|
54
58
|
summaryPolicy: reviewSummaryPolicy,
|
|
55
59
|
validateOptions: validateReviewOptions,
|
|
56
|
-
createRuntime(options) {
|
|
57
|
-
return createPlaybookRuntime(
|
|
60
|
+
createRuntime(options, hostCapabilities) {
|
|
61
|
+
return createPlaybookRuntime({
|
|
62
|
+
configuredOptions: options,
|
|
63
|
+
hostCapabilities,
|
|
64
|
+
});
|
|
58
65
|
},
|
|
59
66
|
};
|
|
60
67
|
export default reviewPlaybookRegistryEntry;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
|
|
3
3
|
|
|
4
4
|
import createPlaybookRuntime, {
|
|
5
|
+
type ReviewPlaybookHostCapabilities,
|
|
5
6
|
type PlaybookRuntime,
|
|
6
7
|
} from './review.playbook.js';
|
|
7
8
|
|
|
@@ -20,12 +21,22 @@ export interface ReviewPlaybookRegistryEntry {
|
|
|
20
21
|
id: 'review';
|
|
21
22
|
command: 'review';
|
|
22
23
|
intent: string;
|
|
23
|
-
artifactSchema:
|
|
24
|
+
artifactSchema: 3;
|
|
25
|
+
runtimeProfile: {
|
|
26
|
+
readonly kind: 'shared-factory';
|
|
27
|
+
readonly compat: {
|
|
28
|
+
readonly artifactSchema: 3;
|
|
29
|
+
readonly runtimeAbi: number;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
24
32
|
requiredRoleIds: readonly ['coder', 'reviewer'];
|
|
25
33
|
concurrentRoleSets: readonly [];
|
|
26
34
|
summaryPolicy: PlaybookSummaryPolicy;
|
|
27
35
|
validateOptions(optionSlice: unknown): ReviewOptions;
|
|
28
|
-
createRuntime(
|
|
36
|
+
createRuntime(
|
|
37
|
+
options: ReviewOptions,
|
|
38
|
+
hostCapabilities: ReviewPlaybookHostCapabilities,
|
|
39
|
+
): PlaybookRuntime;
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
export const reviewStateCountLabels = {
|
|
@@ -94,13 +105,20 @@ export const reviewPlaybookRegistryEntry: ReviewPlaybookRegistryEntry = {
|
|
|
94
105
|
command: 'review',
|
|
95
106
|
intent:
|
|
96
107
|
'review the latest commit until no material correctness or spec findings remain',
|
|
97
|
-
artifactSchema:
|
|
108
|
+
artifactSchema: 3,
|
|
109
|
+
runtimeProfile: Object.freeze({
|
|
110
|
+
kind: 'shared-factory',
|
|
111
|
+
compat: createPlaybookRuntime.compat,
|
|
112
|
+
}),
|
|
98
113
|
requiredRoleIds: ['coder', 'reviewer'],
|
|
99
114
|
concurrentRoleSets: [],
|
|
100
115
|
summaryPolicy: reviewSummaryPolicy,
|
|
101
116
|
validateOptions: validateReviewOptions,
|
|
102
|
-
createRuntime(options) {
|
|
103
|
-
return createPlaybookRuntime(
|
|
117
|
+
createRuntime(options, hostCapabilities) {
|
|
118
|
+
return createPlaybookRuntime({
|
|
119
|
+
configuredOptions: options,
|
|
120
|
+
hostCapabilities,
|
|
121
|
+
});
|
|
104
122
|
},
|
|
105
123
|
};
|
|
106
124
|
|
package/slc/gears2fsm.md
CHANGED
|
@@ -222,12 +222,13 @@ teardown event. The completion rule of
|
|
|
222
222
|
output clause binds only where Source declares a terminal result, which a
|
|
223
223
|
controller Source does not.
|
|
224
224
|
The controller decision state's direct-Captain result contract discriminates
|
|
225
|
-
the closed action set of DR-029. Its guard discriminants
|
|
226
|
-
compiler contract, not names the compiler may invent — `respond`, `
|
|
227
|
-
`switch`, `dismiss`, `deliver`, and `runtime` — with each guard's
|
|
228
|
-
payload fields:
|
|
225
|
+
the closed action set of DR-029 as extended by DR-038. Its guard discriminants
|
|
226
|
+
are a stable compiler contract, not names the compiler may invent — `respond`, `resume`,
|
|
227
|
+
`start`, `switch`, `dismiss`, `deliver`, and `runtime` — with each guard's
|
|
228
|
+
required payload fields:
|
|
229
229
|
|
|
230
230
|
- `respond` requires `text`;
|
|
231
|
+
- `resume` requires `playbookId` and carries no `input`;
|
|
231
232
|
- `start` and `switch` each require `playbookId` and `input`;
|
|
232
233
|
- `runtime` requires `actionId`;
|
|
233
234
|
- `dismiss` and `deliver` require none — a `deliver` result in particular
|
|
@@ -244,8 +245,9 @@ Each state shall declare:
|
|
|
244
245
|
- a stable `id` (for `#id` targeting and Boss interrupts);
|
|
245
246
|
- an intuitive state key (the property name under `states: { ... }`);
|
|
246
247
|
- a one-line `description` (for inspector tools and documentation);
|
|
247
|
-
- JSON-safe `meta: { playbook: { stateId, description, role? } }`
|
|
248
|
-
|
|
248
|
+
- JSON-safe `meta: { playbook: { stateId, description, role? } }` naming the
|
|
249
|
+
state's public playbook identity per the identity rule below and repeating
|
|
250
|
+
its description so linked runtimes can discover active public
|
|
249
251
|
identities through `snapshot.getMeta()` without private XState nodes. A
|
|
250
252
|
delegated-role state shall also carry the canonical lowercase source role id in
|
|
251
253
|
`meta.playbook.role`; every other state shall omit `role`;
|
|
@@ -258,6 +260,8 @@ Each state shall declare:
|
|
|
258
260
|
and no `role`.
|
|
259
261
|
|
|
260
262
|
The source item ID shall live in `invoke.input.sourceItem`, not in a comment — this keeps the GEARS-to-state mapping machine-readable.
|
|
263
|
+
|
|
264
|
+
Outside a parallel group's regions, a state's `meta.playbook.stateId` shall equal its state key — the one identity a factory-backed linked runtime indexes by.
|
|
261
265
|
A delegated state's `invoke.input.role` shall match the canonical lowercase id of its source item's named role.
|
|
262
266
|
A direct Captain state shall not invent a `Captain` role binding.
|
|
263
267
|
|
|
@@ -650,7 +654,7 @@ Boss-reply suspension, because its hub already receives every Boss turn and a
|
|
|
650
654
|
clarifying question to Boss is a `respond` selection over the closed action
|
|
651
655
|
set. The rule below is therefore universal over workflow states and silent
|
|
652
656
|
about that class; in particular, adding `needsBossReply` to the controller
|
|
653
|
-
decision state would add
|
|
657
|
+
decision state would add an eighth outcome to a closed seven-action contract
|
|
654
658
|
whose guard discriminants [Setup](#setup) fixes, and is nonconformant.
|
|
655
659
|
There is no source-level opt-in annotation and no `needsBossReply` result metadata in GEARS output.
|
|
656
660
|
The FSM compiler shall preserve the GEARS blockquote as the state's domain `prompt` body and shall not inject any Boss-question instruction into `invoke.input.prompt`.
|
|
@@ -748,6 +752,20 @@ an unhandled runtime error.
|
|
|
748
752
|
Every machine shall declare at least one `type: 'final'` state (typically `done`) reachable on completion.
|
|
749
753
|
A never-terminating machine is a defect: the runner has no completion signal.
|
|
750
754
|
|
|
755
|
+
At least one is a floor, not a ceiling. A final state's `description` is the
|
|
756
|
+
machine's published terminal meaning: a host that cannot read the machine's
|
|
757
|
+
output quotes that description to report what the run did. It shall therefore
|
|
758
|
+
be true of every arm that enters the state and of no other terminal outcome.
|
|
759
|
+
Where Source declares more than one terminal outcome — an approval that
|
|
760
|
+
completes the workflow and a failure the workflow reports to its caller
|
|
761
|
+
instead of parking — each outcome shall get its own `type: 'final'` state
|
|
762
|
+
whose description names it. Routing an approval arm and a failure, abort, or
|
|
763
|
+
invalid-result arm into one final state is a defect of the same kind as a
|
|
764
|
+
wrong result field, because the quoting host cannot detect the difference.
|
|
765
|
+
This constrains only published meaning: the declared machine `output` still
|
|
766
|
+
derives its status and fields from typed context, so a caller that does read
|
|
767
|
+
the output is unaffected.
|
|
768
|
+
|
|
751
769
|
Where Source declares a JSON-safe terminal result, the setup types shall
|
|
752
770
|
declare that output and the root machine shall derive it from typed context
|
|
753
771
|
through XState's machine `output` function. A final-state transition alone does
|