@sublang/playbook 2.0.0 → 3.1.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 +102 -338
- package/docs/cli.md +123 -0
- package/docs/configuration.md +158 -0
- package/docs/embedding.md +161 -0
- package/package.json +7 -2
- package/reference/sdlc/code.md +105 -0
- package/reference/sdlc/code.playbook/bin/playbook.js +237 -38
- package/reference/sdlc/code.playbook/bin/provision.js +228 -0
- package/reference/sdlc/code.playbook/bin/run.js +76 -3
- package/reference/sdlc/code.playbook/code.fsm.js +38 -36
- package/reference/sdlc/code.playbook/code.fsm.ts +38 -36
- package/reference/sdlc/code.playbook/code.gears.md +30 -26
- package/reference/sdlc/code.playbook/code.playbook.js +4 -0
- package/reference/sdlc/code.playbook/code.playbook.ts +6 -0
- package/reference/sdlc/code.playbook/playbook-captain.js +67 -8
- package/reference/sdlc/code.playbook/playbook-captain.ts +80 -9
- package/reference/sdlc/code.playbook/playbook.config.template.yaml +38 -32
- package/reference/sdlc/discuss.md +93 -0
- package/reference/sdlc/discuss.playbook/discuss.fsm.js +5 -4
- package/reference/sdlc/discuss.playbook/discuss.fsm.ts +5 -4
- package/reference/sdlc/discuss.playbook/discuss.gears.md +19 -12
- package/reference/sdlc/discuss.playbook/discuss.playbook.js +3 -0
- package/reference/sdlc/discuss.playbook/discuss.playbook.ts +5 -0
- package/slc/link.md +20 -3
- package/src/xstate-playbook-runtime.d.ts +17 -0
- package/src/xstate-playbook-runtime.js +49 -0
- package/src/xstate-playbook-runtime.ts +81 -4
- package/src/xstate-runtime.d.ts +1 -0
- package/src/xstate-runtime.js +19 -0
- package/src/xstate-runtime.ts +20 -0
|
@@ -21,13 +21,15 @@ import {
|
|
|
21
21
|
} from 'node:fs/promises';
|
|
22
22
|
import { homedir } from 'node:os';
|
|
23
23
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
24
|
-
import { pathToFileURL } from 'node:url';
|
|
24
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
25
25
|
import {
|
|
26
26
|
Cligent,
|
|
27
27
|
isEffortSupported,
|
|
28
28
|
supportedEffortValues,
|
|
29
29
|
} from '@sublang/cligent';
|
|
30
30
|
import { parse as parseYaml } from 'yaml';
|
|
31
|
+
import { hiddenControlEnvelope } from '../../../../src/xstate-runtime.js';
|
|
32
|
+
import { provisionEngine } from './provision.js';
|
|
31
33
|
|
|
32
34
|
// PBCLI-19: adapter shorthands the run host can construct.
|
|
33
35
|
const ADAPTER_LOADERS = {
|
|
@@ -75,6 +77,9 @@ export async function runPlaybookRun(options = {}) {
|
|
|
75
77
|
readStdin,
|
|
76
78
|
sessionsDir,
|
|
77
79
|
userConfigPath,
|
|
80
|
+
// PBCLI-37: injected host package roots let tests provision against
|
|
81
|
+
// synthetic trees, like the injected session store.
|
|
82
|
+
hostRoots: options.hostRoots,
|
|
78
83
|
};
|
|
79
84
|
|
|
80
85
|
let args;
|
|
@@ -100,6 +105,11 @@ async function runFirst(args, ctx) {
|
|
|
100
105
|
return { code: EXIT.arg };
|
|
101
106
|
}
|
|
102
107
|
|
|
108
|
+
// PBCLI-36/37 (DR-024): provision engine links for a filesystem module
|
|
109
|
+
// before importing it; a resolvable engine is never touched.
|
|
110
|
+
const provisioned = await maybeProvision(args.from, args, ctx);
|
|
111
|
+
if (provisioned.code !== undefined) return provisioned;
|
|
112
|
+
|
|
103
113
|
const loaded = await loadRegistryEntry(args.from, ctx);
|
|
104
114
|
if (loaded.code !== undefined) return loaded;
|
|
105
115
|
const { entry } = loaded;
|
|
@@ -245,6 +255,11 @@ async function runResume(args, ctx) {
|
|
|
245
255
|
return { code: EXIT.arg };
|
|
246
256
|
}
|
|
247
257
|
|
|
258
|
+
// PBCLI-37: a stored filesystem `from` (a file: URL) is probed and
|
|
259
|
+
// provisioned on resume exactly as on a first run.
|
|
260
|
+
const provisioned = await maybeProvision(record.from, args, ctx);
|
|
261
|
+
if (provisioned.code !== undefined) return provisioned;
|
|
262
|
+
|
|
248
263
|
const loaded = await loadRegistryEntry(record.from, ctx);
|
|
249
264
|
if (loaded.code !== undefined) return loaded;
|
|
250
265
|
const { entry } = loaded;
|
|
@@ -361,9 +376,19 @@ async function driveTurn({ ctx, runtime, store, text, json, verbose, restoreFrom
|
|
|
361
376
|
};
|
|
362
377
|
},
|
|
363
378
|
async callJudge(prompt, signal) {
|
|
364
|
-
|
|
379
|
+
// CAPTAIN-9 / DR-013 A1: wrap every judge prompt in the shared
|
|
380
|
+
// hidden-control envelope. Runtime judge prompts embed raw Boss text
|
|
381
|
+
// and quoted player output, so the envelope is what makes them
|
|
382
|
+
// delimited evidence rather than instructions — and it is the
|
|
383
|
+
// prompt-level isolation that stands in for provider enforcement
|
|
384
|
+
// when the tool allowlist below has to be omitted.
|
|
385
|
+
const result = await captainAgent.run(hiddenControlEnvelope(prompt), {
|
|
365
386
|
resume: false,
|
|
366
|
-
|
|
387
|
+
// An empty allowlist means "no tools" and is distinct from omission,
|
|
388
|
+
// which grants the adapter's full tool surface. Send it only where
|
|
389
|
+
// the adapter can enforce it; codex rejects any tool list outright,
|
|
390
|
+
// so requesting one would fail every judge call.
|
|
391
|
+
...controlCallToolOptions(store.captain.adapter),
|
|
367
392
|
signal,
|
|
368
393
|
});
|
|
369
394
|
if (result.status !== 'ok' || result.finalText === undefined) {
|
|
@@ -577,6 +602,20 @@ function playersFromSpecs(roleSpecs) {
|
|
|
577
602
|
}));
|
|
578
603
|
}
|
|
579
604
|
|
|
605
|
+
// DR-013 A1: adapters with no provider-enforced tool-restriction surface.
|
|
606
|
+
// Cligent's codex adapter rejects any allowedTools value — including the
|
|
607
|
+
// empty list that expresses tool-free — so a control call that requests one
|
|
608
|
+
// fails before the model is reached. Omission is the only way such an
|
|
609
|
+
// adapter can run a control call; isolation then rests on the prompt.
|
|
610
|
+
const ADAPTERS_WITHOUT_TOOL_ENFORCEMENT = new Set(['codex']);
|
|
611
|
+
|
|
612
|
+
// Keep requesting enforcement whenever the adapter is unknown, so the
|
|
613
|
+
// DR-013 guarantee holds by default.
|
|
614
|
+
function controlCallToolOptions(captainAdapter) {
|
|
615
|
+
if (ADAPTERS_WITHOUT_TOOL_ENFORCEMENT.has(captainAdapter)) return {};
|
|
616
|
+
return { allowedTools: [] };
|
|
617
|
+
}
|
|
618
|
+
|
|
580
619
|
// PBCLI-19/26: returns a diagnostic for the first invalid spec — an
|
|
581
620
|
// unknown adapter or an effort the adapter does not support — or
|
|
582
621
|
// undefined when every spec resolves. The caller must compare against
|
|
@@ -851,6 +890,7 @@ export function parseRunArgs(argv) {
|
|
|
851
890
|
cwd: undefined,
|
|
852
891
|
json: false,
|
|
853
892
|
verbose: false,
|
|
893
|
+
noProvision: false,
|
|
854
894
|
help: false,
|
|
855
895
|
};
|
|
856
896
|
const positionals = [];
|
|
@@ -859,6 +899,7 @@ export function parseRunArgs(argv) {
|
|
|
859
899
|
if (arg === '--help' || arg === '-h') args.help = true;
|
|
860
900
|
else if (arg === '--json') args.json = true;
|
|
861
901
|
else if (arg === '--verbose') args.verbose = true;
|
|
902
|
+
else if (arg === '--no-provision') args.noProvision = true;
|
|
862
903
|
else if (arg === '--last') args.last = true;
|
|
863
904
|
else if (arg === '--cwd') args.cwd = takeValue(argv, (i += 1), '--cwd');
|
|
864
905
|
else if (arg === '--captain')
|
|
@@ -936,6 +977,36 @@ function registryImportSpecifier(specifier, cwd) {
|
|
|
936
977
|
return specifier;
|
|
937
978
|
}
|
|
938
979
|
|
|
980
|
+
// PBCLI-37: the absolute file path of a filesystem `<from>` (path or
|
|
981
|
+
// file: URL), or undefined for a bare package specifier — those resolve
|
|
982
|
+
// from the host's own module tree and are neither probed nor provisioned.
|
|
983
|
+
function moduleFilePath(specifier, cwd) {
|
|
984
|
+
if (specifier.startsWith('file:')) return fileURLToPath(specifier);
|
|
985
|
+
if (
|
|
986
|
+
isAbsolute(specifier) ||
|
|
987
|
+
specifier.startsWith('./') ||
|
|
988
|
+
specifier.startsWith('../') ||
|
|
989
|
+
specifier.startsWith('.\\') ||
|
|
990
|
+
specifier.startsWith('..\\')
|
|
991
|
+
) {
|
|
992
|
+
return resolve(cwd, specifier);
|
|
993
|
+
}
|
|
994
|
+
return undefined;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// PBCLI-36/37: probe-and-provision for a filesystem registry module.
|
|
998
|
+
// Returns {} to proceed or { code } after a reported provisioning fault.
|
|
999
|
+
async function maybeProvision(specifier, args, ctx) {
|
|
1000
|
+
const modulePath = moduleFilePath(specifier, ctx.cwdDefault);
|
|
1001
|
+
if (modulePath === undefined) return {};
|
|
1002
|
+
return provisionEngine({
|
|
1003
|
+
modulePath,
|
|
1004
|
+
stderr: ctx.stderr,
|
|
1005
|
+
enabled: !args.noProvision,
|
|
1006
|
+
hostRoots: ctx.hostRoots,
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
|
|
939
1010
|
function isValidRegistryEntry(value) {
|
|
940
1011
|
return (
|
|
941
1012
|
typeof value === 'object' &&
|
|
@@ -975,6 +1046,8 @@ function runHelpText() {
|
|
|
975
1046
|
' output or questions) instead of plain text',
|
|
976
1047
|
' --last resume the most recently parked session',
|
|
977
1048
|
' --verbose forward telemetry topics to stderr',
|
|
1049
|
+
' --no-provision never create engine links beside a',
|
|
1050
|
+
' filesystem <from> module',
|
|
978
1051
|
' -h, --help print this help',
|
|
979
1052
|
'',
|
|
980
1053
|
' <agent> is <adapter>[:<model>][@<effort>] over the shorthands',
|
|
@@ -59,18 +59,18 @@ const stateDescriptions = {
|
|
|
59
59
|
respondToReview: 'CODE-2: Coder addresses or challenges Reviewer findings.',
|
|
60
60
|
continueIr: 'CODE-3: Coder continues an IR after the previous task or IR draft passed review.',
|
|
61
61
|
summarizeSpecs: 'CODE-4: Coder summarizes a completed IR into minimal spec items.',
|
|
62
|
-
reviewBossCommitSpecs: 'CODE-5: Reviewer reviews a Boss-intent commit whose changes are only in
|
|
63
|
-
reviewBossCommitCode: 'CODE-6: Reviewer reviews a Boss-intent commit whose changes are only outside
|
|
64
|
-
reviewBossCommitMixed: 'CODE-7: Reviewer reviews a Boss-intent commit whose changes span both
|
|
65
|
-
reviewIrTaskCommitSpecs: 'CODE-8: Reviewer reviews an IR-task commit whose changes are only in
|
|
66
|
-
reviewIrTaskCommitCode: 'CODE-9: Reviewer reviews an IR-task commit whose changes are only outside
|
|
67
|
-
reviewIrTaskCommitMixed: 'CODE-10: Reviewer reviews an IR-task commit whose changes span both
|
|
68
|
-
reviewChangesSpecs: 'CODE-11: Reviewer reviews uncommitted Coder changes that touch only
|
|
69
|
-
reviewChangesCode: 'CODE-12: Reviewer reviews uncommitted Coder changes that touch only files outside
|
|
70
|
-
reviewChangesMixed: 'CODE-13: Reviewer reviews uncommitted Coder changes that touch both
|
|
71
|
-
reviewChangesAndChallengesSpecs: 'CODE-15: Reviewer reviews uncommitted Coder changes that touch only
|
|
72
|
-
reviewChangesAndChallengesCode: 'CODE-16: Reviewer reviews uncommitted Coder changes that touch only files outside
|
|
73
|
-
reviewChangesAndChallengesMixed: 'CODE-17: Reviewer reviews uncommitted Coder changes that touch both
|
|
62
|
+
reviewBossCommitSpecs: 'CODE-5: Reviewer reviews a Boss-intent commit whose changes are only in spec item files.',
|
|
63
|
+
reviewBossCommitCode: 'CODE-6: Reviewer reviews a Boss-intent commit whose changes are only outside spec item files.',
|
|
64
|
+
reviewBossCommitMixed: 'CODE-7: Reviewer reviews a Boss-intent commit whose changes span both spec item files and other files.',
|
|
65
|
+
reviewIrTaskCommitSpecs: 'CODE-8: Reviewer reviews an IR-task commit whose changes are only in spec item files.',
|
|
66
|
+
reviewIrTaskCommitCode: 'CODE-9: Reviewer reviews an IR-task commit whose changes are only outside spec item files.',
|
|
67
|
+
reviewIrTaskCommitMixed: 'CODE-10: Reviewer reviews an IR-task commit whose changes span both spec item files and other files.',
|
|
68
|
+
reviewChangesSpecs: 'CODE-11: Reviewer reviews uncommitted Coder changes that touch only spec item files with no accompanying rebuttals.',
|
|
69
|
+
reviewChangesCode: 'CODE-12: Reviewer reviews uncommitted Coder changes that touch only files outside spec item files with no accompanying rebuttals.',
|
|
70
|
+
reviewChangesMixed: 'CODE-13: Reviewer reviews uncommitted Coder changes that touch both spec item files and other files with no accompanying rebuttals.',
|
|
71
|
+
reviewChangesAndChallengesSpecs: 'CODE-15: Reviewer reviews uncommitted Coder changes that touch only spec item files and adjudicates accompanying rebuttals in one round.',
|
|
72
|
+
reviewChangesAndChallengesCode: 'CODE-16: Reviewer reviews uncommitted Coder changes that touch only files outside spec item files and adjudicates accompanying rebuttals in one round.',
|
|
73
|
+
reviewChangesAndChallengesMixed: 'CODE-17: Reviewer reviews uncommitted Coder changes that touch both spec item files and other files and adjudicates accompanying rebuttals in one round.',
|
|
74
74
|
adjudicateChallenges: 'CODE-14: Reviewer adjudicates Coder rebuttals against the prior review when Coder produced no code edits this round.',
|
|
75
75
|
commitCoderInitial: 'CODE-18: Committer commits Coder Initial Changes when Reviewer has not played since the last commit.',
|
|
76
76
|
commitJoint: 'CODE-19: Committer commits changes when both Coder and Reviewer have played since the last commit.',
|
|
@@ -151,7 +151,7 @@ const planAndImplementInput = (context) => ({
|
|
|
151
151
|
...bossReplyInputFields(context),
|
|
152
152
|
prompt: [
|
|
153
153
|
'Assess whether this can be completed in a single commit, following best practices.',
|
|
154
|
-
'If yes, implement and test, updating both code and specs; otherwise, decompose into tasks as a new IR under @specs/iterations and stop without implementing any IR task.',
|
|
154
|
+
'If yes, implement and test, updating both code and specs; otherwise, decompose into tasks as a new IR under @specs/intents (or @specs/iterations in older scaffolds) and stop without implementing any IR task.',
|
|
155
155
|
'For context discovery, @specs/map.md indexes all spec files and @specs/meta.md describes the spec format.',
|
|
156
156
|
'Ensure @specs/map.md reflects the changes.',
|
|
157
157
|
'Do not commit.',
|
|
@@ -188,9 +188,9 @@ const summarizeSpecsInput = (context) => ({
|
|
|
188
188
|
'Read IR-<#> and corresponding commits.',
|
|
189
189
|
'According to @specs/meta.md, add or update spec items to fully capture:',
|
|
190
190
|
'',
|
|
191
|
-
'- the
|
|
192
|
-
'- the system behavior
|
|
193
|
-
'- the integration/system test cases
|
|
191
|
+
'- the external behavior users rely on,',
|
|
192
|
+
'- the internal system behavior, and',
|
|
193
|
+
'- the integration/system test cases.',
|
|
194
194
|
'',
|
|
195
195
|
'The spec items should be the *minimal* set needed to reimplement code without the IR.',
|
|
196
196
|
'The set should be complete and coherent.',
|
|
@@ -200,7 +200,7 @@ const summarizeSpecsInput = (context) => ({
|
|
|
200
200
|
].join('\n'),
|
|
201
201
|
result: withNeedsBossReply({
|
|
202
202
|
specsReady: 'Coder produced uncommitted spec updates (Initial Changes).',
|
|
203
|
-
noSpecChanges: 'Existing specs already capture the
|
|
203
|
+
noSpecChanges: 'Existing specs already capture the realized intent.',
|
|
204
204
|
}),
|
|
205
205
|
});
|
|
206
206
|
const setPendingBossQuestion = (resumeStateId) => assign({
|
|
@@ -396,12 +396,12 @@ export const codingMachine = setup({
|
|
|
396
396
|
'Stage all current changes that belong in the repo before making any edits, and leave your edits unstaged/untracked.',
|
|
397
397
|
].join('\n'),
|
|
398
398
|
result: {
|
|
399
|
-
changesMadeSpecs: 'Coder accepted items and produced unstaged/untracked edits in @specs/{user,dev,test}/
|
|
400
|
-
changesMadeCode: 'Coder accepted items and produced unstaged/untracked edits outside @specs/
|
|
401
|
-
changesMadeMixed: 'Coder accepted items and produced unstaged/untracked edits spanning both
|
|
402
|
-
changesMadeSpecsAndChallenged: 'Coder produced unstaged/untracked edits in @specs/{user,dev,test}/
|
|
403
|
-
changesMadeCodeAndChallenged: 'Coder produced unstaged/untracked edits outside
|
|
404
|
-
changesMadeMixedAndChallenged: 'Coder produced unstaged/untracked edits spanning both
|
|
399
|
+
changesMadeSpecs: 'Coder accepted items and produced unstaged/untracked edits only in spec item files (@specs/packages/, @specs/compositions/, or legacy @specs/{user,dev,test}/), without raising any rebuttals.',
|
|
400
|
+
changesMadeCode: 'Coder accepted items and produced unstaged/untracked edits only outside spec item files (any other files, including @specs/ decision, intent, or legacy iteration records, @specs/map.md, and @specs/meta.md), without raising any rebuttals.',
|
|
401
|
+
changesMadeMixed: 'Coder accepted items and produced unstaged/untracked edits spanning both spec item files and other files, without raising any rebuttals.',
|
|
402
|
+
changesMadeSpecsAndChallenged: 'Coder produced unstaged/untracked edits only in spec item files (@specs/packages/, @specs/compositions/, or legacy @specs/{user,dev,test}/) AND challenged one or more review items. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
403
|
+
changesMadeCodeAndChallenged: 'Coder produced unstaged/untracked edits only outside spec item files AND challenged one or more review items. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
404
|
+
changesMadeMixedAndChallenged: 'Coder produced unstaged/untracked edits spanning both spec item files and other files AND challenged one or more review items. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
405
405
|
challengesRaised: 'Coder challenged one or more review items without producing any code edits. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
406
406
|
accepted: 'Coder accepted the review outcome without further edits.',
|
|
407
407
|
needsBossReply: needsBossReplyDescription,
|
|
@@ -558,7 +558,7 @@ export const codingMachine = setup({
|
|
|
558
558
|
'Verify any affected spec items are:',
|
|
559
559
|
'',
|
|
560
560
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
561
|
-
'- Right level:
|
|
561
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
562
562
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
563
563
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
564
564
|
'',
|
|
@@ -680,7 +680,7 @@ export const codingMachine = setup({
|
|
|
680
680
|
'Verify any affected spec items are:',
|
|
681
681
|
'',
|
|
682
682
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
683
|
-
'- Right level:
|
|
683
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
684
684
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
685
685
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
686
686
|
'',
|
|
@@ -744,7 +744,7 @@ export const codingMachine = setup({
|
|
|
744
744
|
'Verify any affected spec items are:',
|
|
745
745
|
'',
|
|
746
746
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
747
|
-
'- Right level:
|
|
747
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
748
748
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
749
749
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
750
750
|
'',
|
|
@@ -868,7 +868,7 @@ export const codingMachine = setup({
|
|
|
868
868
|
'Verify any affected spec items are:',
|
|
869
869
|
'',
|
|
870
870
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
871
|
-
'- Right level:
|
|
871
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
872
872
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
873
873
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
874
874
|
'',
|
|
@@ -930,7 +930,7 @@ export const codingMachine = setup({
|
|
|
930
930
|
'Verify any affected spec items are:',
|
|
931
931
|
'',
|
|
932
932
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
933
|
-
'- Right level:
|
|
933
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
934
934
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
935
935
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
936
936
|
'',
|
|
@@ -1030,7 +1030,7 @@ export const codingMachine = setup({
|
|
|
1030
1030
|
'Verify any affected spec items are:',
|
|
1031
1031
|
'',
|
|
1032
1032
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1033
|
-
'- Right level:
|
|
1033
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1034
1034
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1035
1035
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1036
1036
|
'',
|
|
@@ -1084,7 +1084,7 @@ export const codingMachine = setup({
|
|
|
1084
1084
|
'Verify any affected spec items are:',
|
|
1085
1085
|
'',
|
|
1086
1086
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1087
|
-
'- Right level:
|
|
1087
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1088
1088
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1089
1089
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1090
1090
|
'',
|
|
@@ -1190,7 +1190,7 @@ export const codingMachine = setup({
|
|
|
1190
1190
|
'Verify any affected spec items are:',
|
|
1191
1191
|
'',
|
|
1192
1192
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1193
|
-
'- Right level:
|
|
1193
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1194
1194
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1195
1195
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1196
1196
|
'',
|
|
@@ -1306,15 +1306,16 @@ export const codingMachine = setup({
|
|
|
1306
1306
|
coderPlayer: context.coderPlayer,
|
|
1307
1307
|
committerPlayer: context.committerPlayer,
|
|
1308
1308
|
prompt: [
|
|
1309
|
-
'Make a commit of the changes that belong in the repo, following @specs/
|
|
1309
|
+
'Make a commit of the changes that belong in the repo, following @specs/packages/git.md (reread if necessary).',
|
|
1310
|
+
"If that spec is absent, follow the legacy @specs/dev/git.md; if neither exists, follow the repository's existing commit conventions and do not search elsewhere.",
|
|
1310
1311
|
'Write the commit message concisely.',
|
|
1311
1312
|
'Coder is <coder-llm>.',
|
|
1312
1313
|
'Format the `Co-authored-by` `<model>` token as the conventional human form of the substituted id (e.g., `claude-opus-4-7` → `Claude-Opus-4.7`, `gpt-5.5` → `GPT-5.5`).',
|
|
1313
1314
|
].join('\n'),
|
|
1314
1315
|
result: {
|
|
1315
|
-
committedSpecs: 'Committed changes that touch only @specs/{user,dev,test}
|
|
1316
|
-
committedCode: 'Committed changes that touch only files
|
|
1317
|
-
committedMixed: 'Committed changes that span both
|
|
1316
|
+
committedSpecs: 'Committed changes that touch only spec item files (@specs/packages/, @specs/compositions/, or legacy @specs/{user,dev,test}/).',
|
|
1317
|
+
committedCode: 'Committed changes that touch only files that are not spec item files (any other files, including @specs/ decision, intent, or legacy iteration records, @specs/map.md, and @specs/meta.md).',
|
|
1318
|
+
committedMixed: 'Committed changes that span both spec item files and other files.',
|
|
1318
1319
|
noRelevantChanges: 'There are no relevant changes to commit.',
|
|
1319
1320
|
needsBossInput: 'Committing requires additional Boss input.',
|
|
1320
1321
|
needsBossReply: needsBossReplyDescription,
|
|
@@ -1381,7 +1382,8 @@ export const codingMachine = setup({
|
|
|
1381
1382
|
reviewerPlayer: context.reviewerPlayer,
|
|
1382
1383
|
committerPlayer: context.committerPlayer,
|
|
1383
1384
|
prompt: [
|
|
1384
|
-
'Make a commit of the changes that belong in the repo, following @specs/
|
|
1385
|
+
'Make a commit of the changes that belong in the repo, following @specs/packages/git.md (reread if necessary).',
|
|
1386
|
+
"If that spec is absent, follow the legacy @specs/dev/git.md; if neither exists, follow the repository's existing commit conventions and do not search elsewhere.",
|
|
1385
1387
|
'Write the commit message concisely.',
|
|
1386
1388
|
'Coder is <coder-llm>; Reviewer is <reviewer-llm>.',
|
|
1387
1389
|
'Format the `Co-authored-by` `<model>` token as the conventional human form of the substituted id (e.g., `claude-opus-4-7` → `Claude-Opus-4.7`, `gpt-5.5` → `GPT-5.5`).',
|
|
@@ -191,29 +191,29 @@ const stateDescriptions = {
|
|
|
191
191
|
summarizeSpecs:
|
|
192
192
|
'CODE-4: Coder summarizes a completed IR into minimal spec items.',
|
|
193
193
|
reviewBossCommitSpecs:
|
|
194
|
-
'CODE-5: Reviewer reviews a Boss-intent commit whose changes are only in
|
|
194
|
+
'CODE-5: Reviewer reviews a Boss-intent commit whose changes are only in spec item files.',
|
|
195
195
|
reviewBossCommitCode:
|
|
196
|
-
'CODE-6: Reviewer reviews a Boss-intent commit whose changes are only outside
|
|
196
|
+
'CODE-6: Reviewer reviews a Boss-intent commit whose changes are only outside spec item files.',
|
|
197
197
|
reviewBossCommitMixed:
|
|
198
|
-
'CODE-7: Reviewer reviews a Boss-intent commit whose changes span both
|
|
198
|
+
'CODE-7: Reviewer reviews a Boss-intent commit whose changes span both spec item files and other files.',
|
|
199
199
|
reviewIrTaskCommitSpecs:
|
|
200
|
-
'CODE-8: Reviewer reviews an IR-task commit whose changes are only in
|
|
200
|
+
'CODE-8: Reviewer reviews an IR-task commit whose changes are only in spec item files.',
|
|
201
201
|
reviewIrTaskCommitCode:
|
|
202
|
-
'CODE-9: Reviewer reviews an IR-task commit whose changes are only outside
|
|
202
|
+
'CODE-9: Reviewer reviews an IR-task commit whose changes are only outside spec item files.',
|
|
203
203
|
reviewIrTaskCommitMixed:
|
|
204
|
-
'CODE-10: Reviewer reviews an IR-task commit whose changes span both
|
|
204
|
+
'CODE-10: Reviewer reviews an IR-task commit whose changes span both spec item files and other files.',
|
|
205
205
|
reviewChangesSpecs:
|
|
206
|
-
'CODE-11: Reviewer reviews uncommitted Coder changes that touch only
|
|
206
|
+
'CODE-11: Reviewer reviews uncommitted Coder changes that touch only spec item files with no accompanying rebuttals.',
|
|
207
207
|
reviewChangesCode:
|
|
208
|
-
'CODE-12: Reviewer reviews uncommitted Coder changes that touch only files outside
|
|
208
|
+
'CODE-12: Reviewer reviews uncommitted Coder changes that touch only files outside spec item files with no accompanying rebuttals.',
|
|
209
209
|
reviewChangesMixed:
|
|
210
|
-
'CODE-13: Reviewer reviews uncommitted Coder changes that touch both
|
|
210
|
+
'CODE-13: Reviewer reviews uncommitted Coder changes that touch both spec item files and other files with no accompanying rebuttals.',
|
|
211
211
|
reviewChangesAndChallengesSpecs:
|
|
212
|
-
'CODE-15: Reviewer reviews uncommitted Coder changes that touch only
|
|
212
|
+
'CODE-15: Reviewer reviews uncommitted Coder changes that touch only spec item files and adjudicates accompanying rebuttals in one round.',
|
|
213
213
|
reviewChangesAndChallengesCode:
|
|
214
|
-
'CODE-16: Reviewer reviews uncommitted Coder changes that touch only files outside
|
|
214
|
+
'CODE-16: Reviewer reviews uncommitted Coder changes that touch only files outside spec item files and adjudicates accompanying rebuttals in one round.',
|
|
215
215
|
reviewChangesAndChallengesMixed:
|
|
216
|
-
'CODE-17: Reviewer reviews uncommitted Coder changes that touch both
|
|
216
|
+
'CODE-17: Reviewer reviews uncommitted Coder changes that touch both spec item files and other files and adjudicates accompanying rebuttals in one round.',
|
|
217
217
|
adjudicateChallenges:
|
|
218
218
|
'CODE-14: Reviewer adjudicates Coder rebuttals against the prior review when Coder produced no code edits this round.',
|
|
219
219
|
commitCoderInitial:
|
|
@@ -354,7 +354,7 @@ const planAndImplementInput: PlayerInputFactory = (context) => ({
|
|
|
354
354
|
...bossReplyInputFields(context),
|
|
355
355
|
prompt: [
|
|
356
356
|
'Assess whether this can be completed in a single commit, following best practices.',
|
|
357
|
-
'If yes, implement and test, updating both code and specs; otherwise, decompose into tasks as a new IR under @specs/iterations and stop without implementing any IR task.',
|
|
357
|
+
'If yes, implement and test, updating both code and specs; otherwise, decompose into tasks as a new IR under @specs/intents (or @specs/iterations in older scaffolds) and stop without implementing any IR task.',
|
|
358
358
|
'For context discovery, @specs/map.md indexes all spec files and @specs/meta.md describes the spec format.',
|
|
359
359
|
'Ensure @specs/map.md reflects the changes.',
|
|
360
360
|
'Do not commit.',
|
|
@@ -396,9 +396,9 @@ const summarizeSpecsInput: PlayerInputFactory = (context) => ({
|
|
|
396
396
|
'Read IR-<#> and corresponding commits.',
|
|
397
397
|
'According to @specs/meta.md, add or update spec items to fully capture:',
|
|
398
398
|
'',
|
|
399
|
-
'- the
|
|
400
|
-
'- the system behavior
|
|
401
|
-
'- the integration/system test cases
|
|
399
|
+
'- the external behavior users rely on,',
|
|
400
|
+
'- the internal system behavior, and',
|
|
401
|
+
'- the integration/system test cases.',
|
|
402
402
|
'',
|
|
403
403
|
'The spec items should be the *minimal* set needed to reimplement code without the IR.',
|
|
404
404
|
'The set should be complete and coherent.',
|
|
@@ -408,7 +408,7 @@ const summarizeSpecsInput: PlayerInputFactory = (context) => ({
|
|
|
408
408
|
].join('\n'),
|
|
409
409
|
result: withNeedsBossReply({
|
|
410
410
|
specsReady: 'Coder produced uncommitted spec updates (Initial Changes).',
|
|
411
|
-
noSpecChanges: 'Existing specs already capture the
|
|
411
|
+
noSpecChanges: 'Existing specs already capture the realized intent.',
|
|
412
412
|
}),
|
|
413
413
|
});
|
|
414
414
|
|
|
@@ -656,17 +656,17 @@ export const codingMachine = setup({
|
|
|
656
656
|
].join('\n'),
|
|
657
657
|
result: {
|
|
658
658
|
changesMadeSpecs:
|
|
659
|
-
'Coder accepted items and produced unstaged/untracked edits in @specs/{user,dev,test}/
|
|
659
|
+
'Coder accepted items and produced unstaged/untracked edits only in spec item files (@specs/packages/, @specs/compositions/, or legacy @specs/{user,dev,test}/), without raising any rebuttals.',
|
|
660
660
|
changesMadeCode:
|
|
661
|
-
'Coder accepted items and produced unstaged/untracked edits outside @specs/
|
|
661
|
+
'Coder accepted items and produced unstaged/untracked edits only outside spec item files (any other files, including @specs/ decision, intent, or legacy iteration records, @specs/map.md, and @specs/meta.md), without raising any rebuttals.',
|
|
662
662
|
changesMadeMixed:
|
|
663
|
-
'Coder accepted items and produced unstaged/untracked edits spanning both
|
|
663
|
+
'Coder accepted items and produced unstaged/untracked edits spanning both spec item files and other files, without raising any rebuttals.',
|
|
664
664
|
changesMadeSpecsAndChallenged:
|
|
665
|
-
'Coder produced unstaged/untracked edits in @specs/{user,dev,test}/
|
|
665
|
+
'Coder produced unstaged/untracked edits only in spec item files (@specs/packages/, @specs/compositions/, or legacy @specs/{user,dev,test}/) AND challenged one or more review items. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
666
666
|
changesMadeCodeAndChallenged:
|
|
667
|
-
'Coder produced unstaged/untracked edits outside
|
|
667
|
+
'Coder produced unstaged/untracked edits only outside spec item files AND challenged one or more review items. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
668
668
|
changesMadeMixedAndChallenged:
|
|
669
|
-
'Coder produced unstaged/untracked edits spanning both
|
|
669
|
+
'Coder produced unstaged/untracked edits spanning both spec item files and other files AND challenged one or more review items. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
670
670
|
challengesRaised:
|
|
671
671
|
'Coder challenged one or more review items without producing any code edits. Output shall include `challenges: <numbered rebuttals, one per challenged item>`.',
|
|
672
672
|
accepted:
|
|
@@ -831,7 +831,7 @@ export const codingMachine = setup({
|
|
|
831
831
|
'Verify any affected spec items are:',
|
|
832
832
|
'',
|
|
833
833
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
834
|
-
'- Right level:
|
|
834
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
835
835
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
836
836
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
837
837
|
'',
|
|
@@ -957,7 +957,7 @@ export const codingMachine = setup({
|
|
|
957
957
|
'Verify any affected spec items are:',
|
|
958
958
|
'',
|
|
959
959
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
960
|
-
'- Right level:
|
|
960
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
961
961
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
962
962
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
963
963
|
'',
|
|
@@ -1023,7 +1023,7 @@ export const codingMachine = setup({
|
|
|
1023
1023
|
'Verify any affected spec items are:',
|
|
1024
1024
|
'',
|
|
1025
1025
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1026
|
-
'- Right level:
|
|
1026
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1027
1027
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1028
1028
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1029
1029
|
'',
|
|
@@ -1151,7 +1151,7 @@ export const codingMachine = setup({
|
|
|
1151
1151
|
'Verify any affected spec items are:',
|
|
1152
1152
|
'',
|
|
1153
1153
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1154
|
-
'- Right level:
|
|
1154
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1155
1155
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1156
1156
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1157
1157
|
'',
|
|
@@ -1215,7 +1215,7 @@ export const codingMachine = setup({
|
|
|
1215
1215
|
'Verify any affected spec items are:',
|
|
1216
1216
|
'',
|
|
1217
1217
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1218
|
-
'- Right level:
|
|
1218
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1219
1219
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1220
1220
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1221
1221
|
'',
|
|
@@ -1321,7 +1321,7 @@ export const codingMachine = setup({
|
|
|
1321
1321
|
'Verify any affected spec items are:',
|
|
1322
1322
|
'',
|
|
1323
1323
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1324
|
-
'- Right level:
|
|
1324
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1325
1325
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1326
1326
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1327
1327
|
'',
|
|
@@ -1377,7 +1377,7 @@ export const codingMachine = setup({
|
|
|
1377
1377
|
'Verify any affected spec items are:',
|
|
1378
1378
|
'',
|
|
1379
1379
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1380
|
-
'- Right level:
|
|
1380
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1381
1381
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1382
1382
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1383
1383
|
'',
|
|
@@ -1492,7 +1492,7 @@ export const codingMachine = setup({
|
|
|
1492
1492
|
'Verify any affected spec items are:',
|
|
1493
1493
|
'',
|
|
1494
1494
|
'- Complete & coherent: sufficient for you to reimplement code.',
|
|
1495
|
-
'- Right level:
|
|
1495
|
+
'- Right level: external behavior users rely on or internal system behavior (organized per @specs/meta.md), not implementation specifics; integration/system testing, not unit testing.',
|
|
1496
1496
|
'- Minimal: essential and concise; every item earns its place; also check with other items.',
|
|
1497
1497
|
'- Well organized: spec packages are finely scoped, with high cohesion and low coupling.',
|
|
1498
1498
|
'',
|
|
@@ -1621,18 +1621,19 @@ export const codingMachine = setup({
|
|
|
1621
1621
|
coderPlayer: context.coderPlayer,
|
|
1622
1622
|
committerPlayer: context.committerPlayer,
|
|
1623
1623
|
prompt: [
|
|
1624
|
-
'Make a commit of the changes that belong in the repo, following @specs/
|
|
1624
|
+
'Make a commit of the changes that belong in the repo, following @specs/packages/git.md (reread if necessary).',
|
|
1625
|
+
"If that spec is absent, follow the legacy @specs/dev/git.md; if neither exists, follow the repository's existing commit conventions and do not search elsewhere.",
|
|
1625
1626
|
'Write the commit message concisely.',
|
|
1626
1627
|
'Coder is <coder-llm>.',
|
|
1627
1628
|
'Format the `Co-authored-by` `<model>` token as the conventional human form of the substituted id (e.g., `claude-opus-4-7` → `Claude-Opus-4.7`, `gpt-5.5` → `GPT-5.5`).',
|
|
1628
1629
|
].join('\n'),
|
|
1629
1630
|
result: {
|
|
1630
1631
|
committedSpecs:
|
|
1631
|
-
'Committed changes that touch only @specs/{user,dev,test}
|
|
1632
|
+
'Committed changes that touch only spec item files (@specs/packages/, @specs/compositions/, or legacy @specs/{user,dev,test}/).',
|
|
1632
1633
|
committedCode:
|
|
1633
|
-
'Committed changes that touch only files
|
|
1634
|
+
'Committed changes that touch only files that are not spec item files (any other files, including @specs/ decision, intent, or legacy iteration records, @specs/map.md, and @specs/meta.md).',
|
|
1634
1635
|
committedMixed:
|
|
1635
|
-
'Committed changes that span both
|
|
1636
|
+
'Committed changes that span both spec item files and other files.',
|
|
1636
1637
|
noRelevantChanges: 'There are no relevant changes to commit.',
|
|
1637
1638
|
needsBossInput: 'Committing requires additional Boss input.',
|
|
1638
1639
|
needsBossReply: needsBossReplyDescription,
|
|
@@ -1700,7 +1701,8 @@ export const codingMachine = setup({
|
|
|
1700
1701
|
reviewerPlayer: context.reviewerPlayer,
|
|
1701
1702
|
committerPlayer: context.committerPlayer,
|
|
1702
1703
|
prompt: [
|
|
1703
|
-
'Make a commit of the changes that belong in the repo, following @specs/
|
|
1704
|
+
'Make a commit of the changes that belong in the repo, following @specs/packages/git.md (reread if necessary).',
|
|
1705
|
+
"If that spec is absent, follow the legacy @specs/dev/git.md; if neither exists, follow the repository's existing commit conventions and do not search elsewhere.",
|
|
1704
1706
|
'Write the commit message concisely.',
|
|
1705
1707
|
'Coder is <coder-llm>; Reviewer is <reviewer-llm>.',
|
|
1706
1708
|
'Format the `Co-authored-by` `<model>` token as the conventional human form of the substituted id (e.g., `claude-opus-4-7` → `Claude-Opus-4.7`, `gpt-5.5` → `GPT-5.5`).',
|