* feat(#1190): wire --converge primary surface into /gsd:progress --next (ADR-15) ADR-15 designates /gsd-progress --next --auto --converge as the PRIMARY plan-convergence surface, but only the secondary surface (autonomous.md) was wired. next.md now parses --converge/--cross-ai into a plan strategy, gates on workflow.plan_review_convergence, forwards reviewer flags + --max-cycles, and routes Route-3 planning through /gsd:plan-review-convergence (mirroring autonomous.md); --auto chaining preserves converge mode. Adds argument-hint + help/full.md + COMMANDS.md + how-to parity and a structural regression test. Closes #1190 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#1190): add changeset for progress --converge surface (#1237) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(#1190): keep progress --converge docs skill-dep-clean + regen workflow size baseline CI surfaced two ripples from the ADR-15 workflow edits: (1) lint-skill-deps + profile-closure flagged /gsd:plan-phase and /gsd:plan-review-convergence SlashCommand tokens in progress.md's flag docs as undeclared deps — reworded to plain prose since progress.md only advertises the flag (the real invocation lives in next.md); (2) the per-file workflow size baseline needed regenerating after the next.md/help edits. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
180 lines
6.3 KiB
JavaScript
180 lines
6.3 KiB
JavaScript
// allow-test-rule: source-text-is-the-product #1190
|
|
// The progress command and next workflow markdown are runtime-loaded contracts.
|
|
// Checking their text verifies the shipped slash-command behavior.
|
|
|
|
'use strict';
|
|
|
|
const { describe, test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const REPO_ROOT = path.join(__dirname, '..');
|
|
const COMMAND_PATH = path.join(REPO_ROOT, 'commands', 'gsd', 'progress.md');
|
|
const WORKFLOW_PATH = path.join(REPO_ROOT, 'gsd-core', 'workflows', 'next.md');
|
|
const FULL_MD_PATH = path.join(REPO_ROOT, 'gsd-core', 'workflows', 'help', 'modes', 'full.md');
|
|
const COMMANDS_DOC_PATH = path.join(REPO_ROOT, 'docs', 'COMMANDS.md');
|
|
const HOW_TO_PATH = path.join(REPO_ROOT, 'docs', 'how-to', 'run-phases-autonomously.md');
|
|
|
|
function read(filePath) {
|
|
return fs.readFileSync(filePath, 'utf8');
|
|
}
|
|
|
|
describe('ADR-15: /gsd:progress --next --auto --converge (#1190)', () => {
|
|
test('progress command advertises --converge, --auto, and notes --cross-ai alias', () => {
|
|
const command = read(COMMAND_PATH);
|
|
|
|
assert.match(
|
|
command,
|
|
/^argument-hint:.*--converge/m,
|
|
'progress command should advertise --converge in argument-hint',
|
|
);
|
|
assert.match(
|
|
command,
|
|
/^argument-hint:.*--auto/m,
|
|
'progress command should advertise --auto in argument-hint',
|
|
);
|
|
assert.match(command, /--cross-ai/, 'progress command should document --cross-ai alias');
|
|
assert.match(
|
|
command,
|
|
/workflow\.plan_review_convergence=true/,
|
|
'progress command should mention the convergence feature gate',
|
|
);
|
|
});
|
|
|
|
test('next workflow parses converge aliases into a plan strategy', () => {
|
|
const workflow = read(WORKFLOW_PATH);
|
|
|
|
assert.match(workflow, /PLAN_STRATEGY="local"/, 'workflow should default to local planning');
|
|
assert.match(workflow, /PLAN_STRATEGY="converge"/, 'workflow should opt into converge planning');
|
|
assert.match(workflow, /converge\|cross-ai/, 'workflow should accept --converge and --cross-ai');
|
|
});
|
|
|
|
test('next workflow fails fast when convergence is requested but disabled', () => {
|
|
const workflow = read(WORKFLOW_PATH);
|
|
|
|
assert.match(
|
|
workflow,
|
|
/config-get workflow\.plan_review_convergence/,
|
|
'workflow should check workflow.plan_review_convergence before planning',
|
|
);
|
|
assert.match(
|
|
workflow,
|
|
/gsd config-set workflow\.plan_review_convergence true/,
|
|
'workflow should print the enable command instead of silently downgrading',
|
|
);
|
|
});
|
|
|
|
test('next workflow routes Route 3 through plan-review-convergence when PLAN_STRATEGY=converge', () => {
|
|
const workflow = read(WORKFLOW_PATH);
|
|
|
|
assert.match(
|
|
workflow,
|
|
/\/gsd:plan-review-convergence/,
|
|
'next workflow should reference /gsd:plan-review-convergence for the converge route',
|
|
);
|
|
assert.match(
|
|
workflow,
|
|
/PLAN_STRATEGY=converge/,
|
|
'next workflow should check PLAN_STRATEGY for the converge override',
|
|
);
|
|
assert.match(
|
|
workflow,
|
|
/gsd:plan-phase/,
|
|
'local planning path should remain available for default next runs',
|
|
);
|
|
// Args-forwarding contract: Route 3 invocation must pass ${CONVERGENCE_ARGS} to the convergence
|
|
// command — not just route to the command name but actually forward the built args variable.
|
|
assert.match(
|
|
workflow,
|
|
/\/gsd:plan-review-convergence[^\n]*\$\{CONVERGENCE_ARGS\}/,
|
|
'Route 3 convergence invocation must include ${CONVERGENCE_ARGS} on the same line as the command',
|
|
);
|
|
});
|
|
|
|
test('next workflow forwards reviewer flags and max cycles to convergence', () => {
|
|
const workflow = read(WORKFLOW_PATH);
|
|
const reviewerFlags = [
|
|
'--codex',
|
|
'--gemini',
|
|
'--claude',
|
|
'--opencode',
|
|
'--ollama',
|
|
'--lm-studio',
|
|
'--llama-cpp',
|
|
'--all',
|
|
'--text',
|
|
];
|
|
|
|
assert.match(workflow, /CONVERGENCE_ARGS/, 'workflow should build convergence pass-through args');
|
|
for (const flag of reviewerFlags) {
|
|
assert.ok(workflow.includes(flag), `workflow should pass through ${flag}`);
|
|
}
|
|
assert.match(workflow, /--max-cycles/, 'workflow should pass through --max-cycles N');
|
|
});
|
|
|
|
test('next workflow preserves --auto re-invocation chaining', () => {
|
|
const workflow = read(WORKFLOW_PATH);
|
|
|
|
assert.match(
|
|
workflow,
|
|
/--auto/,
|
|
'workflow should document the --auto chaining behavior',
|
|
);
|
|
assert.match(
|
|
workflow,
|
|
/\/gsd:progress --next --auto/,
|
|
'workflow should re-invoke /gsd:progress --next --auto for chaining',
|
|
);
|
|
// Forwarding contract: the --auto re-invocation must explicitly state that --converge/--cross-ai
|
|
// and reviewer flags are forwarded — not just re-invoke --auto alone.
|
|
assert.match(
|
|
workflow,
|
|
/\/gsd:progress --next --auto[^\n]*(forwarding|--converge)/,
|
|
'workflow --auto re-invocation should document forwarding --converge/--cross-ai and reviewer flags',
|
|
);
|
|
});
|
|
|
|
test('full.md documents --converge, --auto, and --cross-ai for /gsd:progress', () => {
|
|
const fullMd = read(FULL_MD_PATH);
|
|
|
|
assert.match(
|
|
fullMd,
|
|
/\/gsd:progress --next --auto --converge/,
|
|
'full.md should show /gsd:progress --next --auto --converge usage',
|
|
);
|
|
assert.match(
|
|
fullMd,
|
|
/--auto/,
|
|
'full.md should document --auto for progress',
|
|
);
|
|
assert.match(
|
|
fullMd,
|
|
/--cross-ai/,
|
|
'full.md should mention --cross-ai alias for convergence',
|
|
);
|
|
});
|
|
|
|
test('COMMANDS.md documents progress convergence flags and usage', () => {
|
|
const commandsDoc = read(COMMANDS_DOC_PATH);
|
|
|
|
assert.match(
|
|
commandsDoc,
|
|
/\/gsd-progress --next --auto --converge/,
|
|
'COMMANDS.md should show /gsd-progress --next --auto --converge usage example',
|
|
);
|
|
assert.match(commandsDoc, /--converge/, 'COMMANDS.md should document --converge for progress');
|
|
assert.match(commandsDoc, /--cross-ai/, 'COMMANDS.md should document --cross-ai alias for progress');
|
|
});
|
|
|
|
test('how-to shows /gsd-progress --next --auto --converge usage', () => {
|
|
const howTo = read(HOW_TO_PATH);
|
|
|
|
assert.match(
|
|
howTo,
|
|
/\/gsd-progress --next --auto --converge/,
|
|
'how-to should show /gsd-progress --next --auto --converge usage',
|
|
);
|
|
});
|
|
});
|