Merge branch 'next' into fix/2009-load-failed-capability-injects-blocking-
This commit is contained in:
273
tests/api-coverage-gate-e2e.test.cjs
Normal file
273
tests/api-coverage-gate-e2e.test.cjs
Normal file
@@ -0,0 +1,273 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* E2E capability-wiring tests for the API-coverage gate (#1562).
|
||||
*
|
||||
* Drives the real CLI subprocess (`loop render-hooks verify:pre` and
|
||||
* `check api-coverage.verify-pre`) against temp projects to prove:
|
||||
* - the gate is data-driven (activates/deactivates by config) — acceptance #5
|
||||
* - the seal contract (block / pass) — acceptance #1, #2, #4
|
||||
* - the matrix persists on disk and is read at seal time — acceptance #6
|
||||
*
|
||||
* CONTENT/E2E only: every test drives a real CLI subprocess. No readFileSync
|
||||
* source-grep. Genuine assertions: each case asserts the SPECIFIC differing
|
||||
* value (block true/false, capId presence), not a count.
|
||||
*/
|
||||
|
||||
const { describe, test, afterEach } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { execFileSync } = require('node:child_process');
|
||||
|
||||
const { cleanup } = require('./helpers.cjs');
|
||||
|
||||
const TOOLS_PATH = path.join(__dirname, '..', 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
const TEST_ENV_BASE = {
|
||||
GSD_SESSION_KEY: '',
|
||||
CODEX_THREAD_ID: '',
|
||||
CLAUDE_SESSION_ID: '',
|
||||
CLAUDE_CODE_SSE_PORT: '',
|
||||
OPENCODE_SESSION_ID: '',
|
||||
GEMINI_SESSION_ID: '',
|
||||
CURSOR_SESSION_ID: '',
|
||||
WINDSURF_SESSION_ID: '',
|
||||
TERM_SESSION: '',
|
||||
WT_SESSION: '',
|
||||
TMUX_PANE: '',
|
||||
ZELLIJ_SESSION_NAME: '',
|
||||
TTY: '',
|
||||
SSH_TTY: '',
|
||||
};
|
||||
|
||||
function runTools(args, cwd) {
|
||||
const argv = Array.isArray(args)
|
||||
? args
|
||||
: (args.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [])
|
||||
.map((t) => t.replace(/"([^"]*)"/g, '$1').replace(/'([^']*)'/g, '$1'));
|
||||
try {
|
||||
const stdout = execFileSync(process.execPath, [TOOLS_PATH, ...argv], {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
env: { ...process.env, ...TEST_ENV_BASE },
|
||||
timeout: 60000,
|
||||
});
|
||||
return { success: true, output: stdout.trim(), exitCode: 0, error: '' };
|
||||
} catch (err) {
|
||||
return {
|
||||
success: false,
|
||||
output: err.stdout?.toString().trim() || '',
|
||||
error: err.stderr?.toString().trim() || err.message,
|
||||
exitCode: err.status ?? 1,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function makeProject(workflow) {
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-apicov-'));
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning'), { recursive: true });
|
||||
fs.mkdirSync(path.join(tmpDir, '.planning', 'phases'), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'config.json'),
|
||||
JSON.stringify({ workflow }),
|
||||
'utf8'
|
||||
);
|
||||
return tmpDir;
|
||||
}
|
||||
|
||||
function makePhaseDir(projectDir, phaseSlug) {
|
||||
const dir = path.join(projectDir, '.planning', 'phases', phaseSlug);
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
return dir;
|
||||
}
|
||||
|
||||
function writePlan(phaseDir, planFile, body) {
|
||||
fs.writeFileSync(path.join(phaseDir, planFile), body, 'utf8');
|
||||
}
|
||||
|
||||
function writeCoverage(phaseDir, body) {
|
||||
fs.writeFileSync(path.join(phaseDir, 'COVERAGE.md'), body, 'utf8');
|
||||
}
|
||||
|
||||
function verifyPreHooks(cwd) {
|
||||
const result = runTools('loop render-hooks verify:pre --raw', cwd);
|
||||
assert.ok(result.success, `render-hooks verify:pre should succeed. stderr: ${result.error}`);
|
||||
const envelope = JSON.parse(result.output);
|
||||
assert.strictEqual(envelope.point, 'verify:pre', 'point field must be verify:pre');
|
||||
assert.ok(Array.isArray(envelope.activeHooks), 'activeHooks must be an array');
|
||||
return envelope;
|
||||
}
|
||||
|
||||
function findCap(envelope, capId) {
|
||||
return envelope.activeHooks.find((h) => h.capId === capId) || null;
|
||||
}
|
||||
|
||||
function runGate(cwd, phaseDir) {
|
||||
return runTools(['check', 'api-coverage.verify-pre', phaseDir, '--raw'], cwd);
|
||||
}
|
||||
|
||||
// ─── Capability wiring: data-driven activation (acceptance #5) ───────────────
|
||||
|
||||
describe('api-coverage verify:pre gate — capability wiring (#1562 acceptance #5)', () => {
|
||||
let tmpDir;
|
||||
afterEach(() => { if (tmpDir) { cleanup(tmpDir); tmpDir = null; } });
|
||||
|
||||
test('gate is ACTIVE when workflow.api_coverage_gate is true', () => {
|
||||
tmpDir = makeProject({ api_coverage_gate: true });
|
||||
const env = verifyPreHooks(tmpDir);
|
||||
const hook = findCap(env, 'ai-integration');
|
||||
assert.ok(hook, 'ai-integration gate must register at verify:pre when enabled');
|
||||
assert.strictEqual(hook.kind, 'gate');
|
||||
assert.strictEqual(hook.blocking, true);
|
||||
assert.strictEqual(hook.check.query, 'api-coverage.verify-pre');
|
||||
});
|
||||
|
||||
test('gate is ABSENT when workflow.api_coverage_gate is false', () => {
|
||||
tmpDir = makeProject({ api_coverage_gate: false });
|
||||
const env = verifyPreHooks(tmpDir);
|
||||
assert.strictEqual(findCap(env, 'ai-integration'), null, 'gate must not register when disabled');
|
||||
});
|
||||
|
||||
test('gate is ACTIVE by default when the key is absent (opt-out, not opt-in)', () => {
|
||||
tmpDir = makeProject({});
|
||||
const env = verifyPreHooks(tmpDir);
|
||||
assert.ok(findCap(env, 'ai-integration'), 'gate must default ON (full-coverage-by-default)');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Seal contract: block / pass (acceptance #1, #2, #4, #6) ──────────────────
|
||||
|
||||
describe('api-coverage.verify-pre — seal contract (#1562 acceptance #1,#2,#4,#6)', () => {
|
||||
let tmpDir;
|
||||
let phaseDir;
|
||||
afterEach(() => { if (tmpDir) { cleanup(tmpDir); tmpDir = null; } });
|
||||
|
||||
function fresh() {
|
||||
tmpDir = makeProject({ api_coverage_gate: true });
|
||||
phaseDir = makePhaseDir(tmpDir, '01-pay');
|
||||
return phaseDir;
|
||||
}
|
||||
|
||||
test('#1 API phase without a matrix → BLOCKS the seal', () => {
|
||||
fresh();
|
||||
writePlan(phaseDir, '01-PLAN.md', '# Plan\nIntegrate the Stripe API for payment processing.');
|
||||
const r = runGate(tmpDir, phaseDir);
|
||||
assert.ok(r.success, `gate should succeed (JSON). stderr: ${r.error}`);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, true, 'must block when API integration has no matrix');
|
||||
assert.strictEqual(j.detected, true);
|
||||
assert.strictEqual(j.coverage_present, false);
|
||||
});
|
||||
|
||||
test('#4 non-API phase without a matrix → does NOT block', () => {
|
||||
fresh();
|
||||
writePlan(phaseDir, '01-PLAN.md', '# Plan\nRefactor the auth helper to use bcrypt.');
|
||||
const r = runGate(tmpDir, phaseDir);
|
||||
assert.ok(r.success, `gate should succeed. stderr: ${r.error}`);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, false, 'must not block a non-API phase');
|
||||
assert.strictEqual(j.detected, false);
|
||||
});
|
||||
|
||||
test('#1/#6 API phase WITH a valid matrix → passes (matrix persists on disk)', () => {
|
||||
fresh();
|
||||
writePlan(phaseDir, '01-PLAN.md', '# Plan\nIntegrate the Stripe API for payment processing.');
|
||||
writeCoverage(
|
||||
phaseDir,
|
||||
'| capability | decision | reason |\n|---|---|---|\n' +
|
||||
'| charge | INTEGRATE | |\n| refund | OPT-OUT | not needed yet |\n'
|
||||
);
|
||||
const r = runGate(tmpDir, phaseDir);
|
||||
assert.ok(r.success, `gate should succeed. stderr: ${r.error}`);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, false);
|
||||
assert.strictEqual(j.coverage_present, true);
|
||||
assert.strictEqual(j.counts.surface, 2);
|
||||
assert.strictEqual(j.counts.optout, 1);
|
||||
});
|
||||
|
||||
test('#2 OPT-OUT without a reason → BLOCKS (un-decided hole)', () => {
|
||||
fresh();
|
||||
writePlan(phaseDir, '01-PLAN.md', '# Plan\nIntegrate the Stripe API.');
|
||||
writeCoverage(
|
||||
phaseDir,
|
||||
'| capability | decision | reason |\n|---|---|---|\n| refund | OPT-OUT | |\n'
|
||||
);
|
||||
const r = runGate(tmpDir, phaseDir);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, true, 'opt-out without reason must block');
|
||||
assert.ok(j.errors.some((e) => /missing reason/i.test(e)));
|
||||
});
|
||||
|
||||
test('#2 empty matrix → BLOCKS (surface must be enumerated)', () => {
|
||||
fresh();
|
||||
writePlan(phaseDir, '01-PLAN.md', '# Plan\nIntegrate the Stripe API.');
|
||||
writeCoverage(phaseDir, '| capability | decision | reason |\n|---|---|---|\n');
|
||||
const r = runGate(tmpDir, phaseDir);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, true);
|
||||
assert.ok(j.errors.some((e) => /empty/i.test(e)));
|
||||
});
|
||||
|
||||
test('#3 a second platform with full-coverage baseline is accepted (no asymmetry)', () => {
|
||||
fresh();
|
||||
writePlan(phaseDir, '01-PLAN.md', '# Plan\nAdd a YouTube SDK as a second media platform.');
|
||||
// Full-coverage baseline for the second platform: every capability decided.
|
||||
writeCoverage(
|
||||
phaseDir,
|
||||
'| capability | decision | reason |\n|---|---|---|\n' +
|
||||
'| search | INTEGRATE | |\n| playlists | INTEGRATE | |\n| skip | INTEGRATE | |\n'
|
||||
);
|
||||
const r = runGate(tmpDir, phaseDir);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, false, 'a fully-decided second platform seals clean');
|
||||
assert.strictEqual(j.counts.surface, 3);
|
||||
});
|
||||
|
||||
test('JSON-fenced matrix is accepted (machine-generated form)', () => {
|
||||
fresh();
|
||||
writePlan(phaseDir, '01-PLAN.md', '# Plan\nIntegrate the Stripe API.');
|
||||
writeCoverage(
|
||||
phaseDir,
|
||||
'```coverage\n[{"capability":"charge","decision":"INTEGRATE","reason":""}]\n```\n'
|
||||
);
|
||||
const r = runGate(tmpDir, phaseDir);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, false);
|
||||
assert.strictEqual(j.counts.surface, 1);
|
||||
});
|
||||
|
||||
// ── Security (#1562 security review S1/S2): the phase arg is taken only as a
|
||||
// token resolved under .planning/phases/. Traversal / unresolvable args must
|
||||
// NOT read files outside the phase dir, and — since the phases tree exists —
|
||||
// must fail CLOSED (a blocking gate must not silently bypass on a bad arg).
|
||||
test('path-traversal arg is contained and fails CLOSED (phases tree exists)', () => {
|
||||
fresh(); // creates .planning/phases/01-pay
|
||||
const r = runTools(['check', 'api-coverage.verify-pre', '../../etc', '--raw'], tmpDir);
|
||||
assert.ok(r.success, `gate should succeed (JSON). stderr: ${r.error}`);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, true, 'unresolvable phase under an existing phases tree must block');
|
||||
assert.strictEqual(j.phase_lookup_failed, true);
|
||||
});
|
||||
|
||||
test('no .planning/phases at all → fail-open (genuine non-GSD project)', () => {
|
||||
// A project with .planning/config.json but no phases directory.
|
||||
const noPhases = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-apicov-nophase-'));
|
||||
try {
|
||||
fs.mkdirSync(path.join(noPhases, '.planning'), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(noPhases, '.planning', 'config.json'),
|
||||
JSON.stringify({ workflow: { api_coverage_gate: true } }),
|
||||
'utf8'
|
||||
);
|
||||
const r = runTools(['check', 'api-coverage.verify-pre', '01-pay', '--raw'], noPhases);
|
||||
assert.ok(r.success);
|
||||
const j = JSON.parse(r.output);
|
||||
assert.strictEqual(j.block, false, 'no phases tree → pass (not a GSD project)');
|
||||
} finally {
|
||||
cleanup(noPhases);
|
||||
}
|
||||
});
|
||||
});
|
||||
410
tests/api-coverage.test.cjs
Normal file
410
tests/api-coverage.test.cjs
Normal file
@@ -0,0 +1,410 @@
|
||||
/**
|
||||
* Tests for the API-coverage detector + matrix validator (#1562).
|
||||
*
|
||||
* Two pure functions under test, both returning typed IR (asserted, never
|
||||
* text-matched on prose):
|
||||
* - detectApiIntegration(text) -> { detected, signals, terms }
|
||||
* - validateCoverageMatrix(text) -> { valid, errors, counts }
|
||||
*
|
||||
* Acceptance-criterion mapping:
|
||||
* #2 (opt-out needs reason; un-enumerated blocks) → validateCoverageMatrix suite
|
||||
* #4 (non-API phases unaffected, low false-positive) → false-positive suite
|
||||
* Matrix parse/render bijectivity → fast-check property
|
||||
*/
|
||||
|
||||
const { describe, test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
const path = require('node:path');
|
||||
const fc = require('fast-check');
|
||||
|
||||
const MODULE_PATH = path.join(__dirname, '..', 'gsd-core', 'bin', 'lib', 'api-coverage.cjs');
|
||||
|
||||
describe('detectApiIntegration — pure detector (#1562)', () => {
|
||||
let mod;
|
||||
try {
|
||||
mod = require(MODULE_PATH);
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`Could not require ${MODULE_PATH}. Run "npm run build:lib" first. Underlying: ${err.message}`
|
||||
);
|
||||
}
|
||||
const { detectApiIntegration, DEFAULT_API_COVERAGE_TERMS } = mod;
|
||||
|
||||
test('result shape — always carries detected, signals[], terms', () => {
|
||||
const r = detectApiIntegration('refactor the login function');
|
||||
assert.strictEqual(r.detected, false);
|
||||
assert(Array.isArray(r.signals));
|
||||
assert.strictEqual(r.signals.length, 0);
|
||||
assert.ok(r.terms && Array.isArray(r.terms.verbs));
|
||||
assert.ok(Array.isArray(r.terms.nouns));
|
||||
});
|
||||
|
||||
test('non-string input degrades to {detected:false} without throwing', () => {
|
||||
assert.strictEqual(detectApiIntegration(undefined).detected, false);
|
||||
assert.strictEqual(detectApiIntegration(null).detected, false);
|
||||
assert.strictEqual(detectApiIntegration(42).detected, false);
|
||||
assert.strictEqual(detectApiIntegration({}).detected, false);
|
||||
});
|
||||
|
||||
test('empty / whitespace-only input does not fire', () => {
|
||||
assert.strictEqual(detectApiIntegration('').detected, false);
|
||||
assert.strictEqual(detectApiIntegration(' \n\t ').detected, false);
|
||||
});
|
||||
|
||||
test('terms echo is the effective set actually used', () => {
|
||||
const r = detectApiIntegration('nothing relevant here');
|
||||
assert.deepStrictEqual(r.terms.verbs, [...DEFAULT_API_COVERAGE_TERMS.verbs]);
|
||||
assert.deepStrictEqual(r.terms.nouns, [...DEFAULT_API_COVERAGE_TERMS.nouns]);
|
||||
});
|
||||
|
||||
test('terms override — explicit verbs+nouns replace defaults', () => {
|
||||
const r = detectApiIntegration('xyzzy the frobninator', { verbs: ['xyzzy'], nouns: ['frobninator'] });
|
||||
assert.deepStrictEqual(r.terms.verbs, ['xyzzy']);
|
||||
assert.deepStrictEqual(r.terms.nouns, ['frobninator']);
|
||||
assert.strictEqual(r.detected, true);
|
||||
});
|
||||
|
||||
// ── Positive: compound verb+noun (acceptance #1 trigger) ─────────────────
|
||||
for (const scope of [
|
||||
'Integrate the Stripe API for payment processing',
|
||||
'Wrap the GitHub GraphQL API for issue triage',
|
||||
'Connect to the SendGrid REST endpoint for transactional email',
|
||||
'Consume the billing service over gRPC',
|
||||
'Wire up the Slack webhook for deploy notifications',
|
||||
'Onboard the Twilio SDK for SMS',
|
||||
'integrate oauth for login',
|
||||
]) {
|
||||
test(`POSITIVE fires on: "${scope}"`, () => {
|
||||
const r = detectApiIntegration(scope);
|
||||
assert.strictEqual(r.detected, true, `expected detection for: ${scope}`);
|
||||
assert.ok(r.signals.length > 0);
|
||||
assert.ok(r.signals.every((s) => s.snippet.length > 0));
|
||||
});
|
||||
}
|
||||
|
||||
// ── Positive: explicit <Service> API|SDK surface (no verb needed) ────────
|
||||
for (const scope of ['Add a Spotify API client', 'Ship the Notion SDK helper']) {
|
||||
test(`POSITIVE (surface) fires on: "${scope}"`, () => {
|
||||
const r = detectApiIntegration(scope);
|
||||
assert.strictEqual(r.detected, true);
|
||||
assert.ok(r.signals.some((s) => s.verb === '(surface)'));
|
||||
});
|
||||
}
|
||||
|
||||
// ── Negative: false-positive guards (acceptance #4 — the crux) ───────────
|
||||
// Each of these is a phase that is NOT an external-API integration. The
|
||||
// detector must stay silent. The "public API of UserController" case is the
|
||||
// canonical FP trap: "api" is present but there is no integration verb.
|
||||
for (const [label, scope] of [
|
||||
['internal API mention', 'The public API of the UserController should accept pagination params'],
|
||||
['refactor', 'Refactor the authentication module to use bcrypt'],
|
||||
['feature toggle', 'Add a dark mode toggle to the settings page'],
|
||||
['bug fix', 'Fix the off-by-one error in the pagination helper'],
|
||||
['docs', 'Update the README to document the config options'],
|
||||
['internal client code', 'Add a client-side helper to debounce input'],
|
||||
['bare noun no verb', 'We expose a REST-ish JSON shape already'],
|
||||
['bare verb no noun', 'We will integrate the new design system tokens'],
|
||||
]) {
|
||||
test(`NEGATIVE does not fire (${label}): "${scope}"`, () => {
|
||||
const r = detectApiIntegration(scope);
|
||||
assert.strictEqual(r.detected, false, `unexpected detection for [${label}]: ${scope}`);
|
||||
});
|
||||
}
|
||||
|
||||
test('fenced code blocks are stripped — trigger inside a code fence does not fire', () => {
|
||||
const scope = [
|
||||
'Refactor the helpers.',
|
||||
'',
|
||||
'```bash',
|
||||
'# integrate the Stripe API (example command in docs)',
|
||||
'```',
|
||||
'',
|
||||
'No integration in this phase.',
|
||||
].join('\n');
|
||||
assert.strictEqual(detectApiIntegration(scope).detected, false);
|
||||
});
|
||||
|
||||
// ── H1 fix (#1562 code review): capitalized sentence starters must not fire
|
||||
// the <Service> API/SDK surface rule. These are common English, not services.
|
||||
for (const [label, scope] of [
|
||||
['The API', 'The API documentation needs updating.'],
|
||||
['An SDK', 'An SDK is already present in the repo.'],
|
||||
['Our REST', 'Our REST endpoints return JSON.'],
|
||||
['This GraphQL', 'This GraphQL schema is internal.'],
|
||||
['New API', 'New API surface was added by the refactor.'],
|
||||
]) {
|
||||
test(`NEGATIVE (stopword) does not fire (${label}): "${scope}"`, () => {
|
||||
assert.strictEqual(detectApiIntegration(scope).detected, false);
|
||||
});
|
||||
}
|
||||
|
||||
test('compound signal fires when verb and noun are on the same line only', () => {
|
||||
const sameLine = 'Phase A integrates things.\nLater we mention an api.';
|
||||
const splitLine = 'Phase A integrates things.\nLater we mention an api here too.';
|
||||
assert.strictEqual(detectApiIntegration(sameLine).detected, false);
|
||||
assert.strictEqual(detectApiIntegration(splitLine).detected, false);
|
||||
assert.strictEqual(detectApiIntegration('integrates the api').detected, true);
|
||||
});
|
||||
});
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Matrix parse / validate / render
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('coverage matrix — parse / validate (#1562 acceptance #2)', () => {
|
||||
let mod;
|
||||
try {
|
||||
mod = require(MODULE_PATH);
|
||||
} catch (err) {
|
||||
throw new Error(`Could not require ${MODULE_PATH}. Run "npm run build:lib". Underlying: ${err.message}`);
|
||||
}
|
||||
const { parseCoverageMatrix, validateCoverageMatrix, renderCoverageMatrix } = mod;
|
||||
|
||||
test('parse markdown table — header + 2 rows', () => {
|
||||
const md = [
|
||||
'| capability | decision | reason |',
|
||||
'|---|---|---|',
|
||||
'| search | INTEGRATE | |',
|
||||
'| playlists | OPT-OUT | not needed yet |',
|
||||
].join('\n');
|
||||
const p = parseCoverageMatrix(md);
|
||||
assert.strictEqual(p.format, 'table');
|
||||
assert.strictEqual(p.rows.length, 2);
|
||||
assert.strictEqual(p.rows[0].capability, 'search');
|
||||
assert.strictEqual(p.rows[0].decision, 'INTEGRATE');
|
||||
assert.strictEqual(p.rows[1].decision, 'OPT-OUT');
|
||||
assert.strictEqual(p.rows[1].reason, 'not needed yet');
|
||||
assert.strictEqual(p.errors.length, 0);
|
||||
});
|
||||
|
||||
test('parse fenced ```coverage JSON block', () => {
|
||||
const md = [
|
||||
'Some prose.',
|
||||
'',
|
||||
'```coverage',
|
||||
'[{"capability":"search","decision":"INTEGRATE","reason":""},',
|
||||
' {"capability":"skip","decision":"OPT-OUT","reason":"out of scope"}]',
|
||||
'```',
|
||||
].join('\n');
|
||||
const p = parseCoverageMatrix(md);
|
||||
assert.strictEqual(p.format, 'json');
|
||||
assert.strictEqual(p.rows.length, 2);
|
||||
assert.strictEqual(p.errors.length, 0);
|
||||
});
|
||||
|
||||
test('parse empty / non-matrix input → format none, no rows, no errors', () => {
|
||||
const p = parseCoverageMatrix('# Notes\n\nNothing here.');
|
||||
assert.strictEqual(p.format, 'none');
|
||||
assert.strictEqual(p.rows.length, 0);
|
||||
assert.strictEqual(p.errors.length, 0);
|
||||
});
|
||||
|
||||
test('parse non-string → empty result, no throw', () => {
|
||||
const p = parseCoverageMatrix(undefined);
|
||||
assert.strictEqual(p.rows.length, 0);
|
||||
});
|
||||
|
||||
test('parse rejects malformed fenced JSON with an error', () => {
|
||||
const md = '```coverage\n{not json}\n```';
|
||||
const p = parseCoverageMatrix(md);
|
||||
assert.strictEqual(p.format, 'json');
|
||||
assert.ok(p.errors.length > 0);
|
||||
assert.strictEqual(p.rows.length, 0);
|
||||
});
|
||||
|
||||
// ── validate: boundaries 0 / 1 / 2 rows (limit-1, limit, limit+1) ────────
|
||||
test('validate — empty matrix is invalid (acceptance #1: surface must be enumerated)', () => {
|
||||
const v = validateCoverageMatrix('| capability | decision | reason |\n|---|---|---|');
|
||||
assert.strictEqual(v.valid, false);
|
||||
assert.ok(v.errors.some((e) => /empty/i.test(e)));
|
||||
assert.strictEqual(v.counts.surface, 0);
|
||||
});
|
||||
|
||||
test('validate — single INTEGRATE row is valid (limit)', () => {
|
||||
const md = '| capability | decision | reason |\n|---|---|---|\n| search | INTEGRATE | |';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, true);
|
||||
assert.strictEqual(v.counts.surface, 1);
|
||||
assert.strictEqual(v.counts.integrate, 1);
|
||||
assert.strictEqual(v.counts.optout, 0);
|
||||
});
|
||||
|
||||
test('validate — two rows valid (limit+1)', () => {
|
||||
const md = [
|
||||
'| capability | decision | reason |',
|
||||
'|---|---|---|',
|
||||
'| search | INTEGRATE | |',
|
||||
'| playlists | OPT-OUT | not needed |',
|
||||
].join('\n');
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, true);
|
||||
assert.strictEqual(v.counts.surface, 2);
|
||||
assert.strictEqual(v.counts.optout, 1);
|
||||
});
|
||||
|
||||
// ── acceptance #2: every OPT-OUT must carry a reason ─────────────────────
|
||||
test('validate — OPT-OUT without reason is INVALID (acceptance #2)', () => {
|
||||
const md = '| capability | decision | reason |\n|---|---|---|\n| skip | OPT-OUT | |';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, false);
|
||||
assert.ok(v.errors.some((e) => /missing reason/i.test(e)));
|
||||
});
|
||||
|
||||
test('validate — OPT-OUT with one-char reason is valid (boundary)', () => {
|
||||
const md = '| capability | decision | reason |\n|---|---|---|\n| skip | OPT-OUT | x |';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, true);
|
||||
});
|
||||
|
||||
test('validate — duplicate capability is invalid (matrix is a set of decisions)', () => {
|
||||
const md = [
|
||||
'| capability | decision | reason |',
|
||||
'|---|---|---|',
|
||||
'| search | INTEGRATE | |',
|
||||
'| Search | OPT-OUT | dup |',
|
||||
].join('\n');
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, false);
|
||||
assert.ok(v.errors.some((e) => /duplicate/i.test(e)));
|
||||
});
|
||||
|
||||
test('validate — empty capability name is invalid', () => {
|
||||
const md = '| capability | decision | reason |\n|---|---|---|\n| | INTEGRATE | |';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, false);
|
||||
assert.ok(v.errors.some((e) => /empty capability/i.test(e)));
|
||||
});
|
||||
|
||||
// ── review-fix coverage: parser robustness (#1562 code review M1/M2/L1/L2) ──
|
||||
test('validate — invalid decision cell in a table row is an error, not silently dropped (M1)', () => {
|
||||
const md = '| capability | decision | reason |\n|---|---|---|\n| x | INTEGRAT | |';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, false);
|
||||
assert.ok(v.errors.some((e) => /not in \{INTEGRATE, OPT-OUT\}/i.test(e)));
|
||||
});
|
||||
|
||||
test('validate — a pipe in a cell adds extra columns → invalid (M2)', () => {
|
||||
const md = '| capability | decision | reason |\n|---|---|---|\n| x | OPT-OUT | a|b |';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, false);
|
||||
assert.ok(v.errors.some((e) => /columns|pipe/i.test(e)));
|
||||
});
|
||||
|
||||
test('validate — a pipe in a JSON-fence reason → invalid (M2)', () => {
|
||||
const md = '```coverage\n[{"capability":"x","decision":"OPT-OUT","reason":"a|b"}]\n```';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, false);
|
||||
});
|
||||
|
||||
test('validate — capability over the length cap → invalid (S3 bound)', () => {
|
||||
const longCap = 'x'.repeat(81);
|
||||
const md = `| capability | decision | reason |\n|---|---|---|\n| ${longCap} | INTEGRATE | |`;
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.valid, false);
|
||||
assert.ok(v.errors.some((e) => /exceeds/i.test(e)));
|
||||
});
|
||||
|
||||
test('parse — case-insensitive ```Coverage fence is accepted (L1)', () => {
|
||||
const md = '```Coverage\n[{"capability":"a","decision":"INTEGRATE","reason":""}]\n```';
|
||||
const p = parseCoverageMatrix(md);
|
||||
assert.strictEqual(p.format, 'json');
|
||||
assert.strictEqual(p.rows.length, 1);
|
||||
});
|
||||
|
||||
test('parse — a single-dash cell is not mistaken for a separator (L2)', () => {
|
||||
const md = '| capability | decision | reason |\n|---|---|---|\n| - | INTEGRATE | |';
|
||||
const v = validateCoverageMatrix(md);
|
||||
assert.strictEqual(v.counts.surface, 1);
|
||||
assert.ok(v.valid, 'a capability named "-" is legal');
|
||||
});
|
||||
|
||||
// ── render round-trip (manual) ───────────────────────────────────────────
|
||||
test('render → parse round-trips a valid matrix', () => {
|
||||
const rows = [
|
||||
{ capability: 'search', decision: 'INTEGRATE', reason: '' },
|
||||
{ capability: 'playlists', decision: 'OPT-OUT', reason: 'not needed yet' },
|
||||
];
|
||||
const rendered = renderCoverageMatrix(rows);
|
||||
const v = validateCoverageMatrix(rendered);
|
||||
assert.strictEqual(v.valid, true);
|
||||
assert.strictEqual(v.counts.surface, 2);
|
||||
});
|
||||
});
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// Property test: parse/render bijectivity (RULESET.TESTS property-based)
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('coverage matrix — parse/render bijection (fast-check)', () => {
|
||||
let mod;
|
||||
try {
|
||||
mod = require(MODULE_PATH);
|
||||
} catch (err) {
|
||||
throw new Error(`Could not require ${MODULE_PATH}. Run "npm run build:lib". Underlying: ${err.message}`);
|
||||
}
|
||||
const { renderCoverageMatrix, validateCoverageMatrix } = mod;
|
||||
|
||||
test('any valid row set renders and re-validates to the same counts', () => {
|
||||
const capabilityGen = fc.stringMatching(/^[a-z][a-z0-9-]{0,14}$/);
|
||||
const rowGen = fc.record({
|
||||
capability: capabilityGen,
|
||||
decision: fc.constantFrom('INTEGRATE', 'OPT-OUT'),
|
||||
// Reasons are short prose (e.g. "not needed yet"). The matrix is a
|
||||
// markdown table, so cell text is format-safe: no pipes / newlines.
|
||||
reason: fc.stringMatching(/^[a-z0-9 ,.\-!?]{0,20}$/),
|
||||
});
|
||||
// OPT-OUT rows must carry a non-empty reason for the round-trip to validate.
|
||||
const validRowGen = rowGen.map((r) =>
|
||||
r.decision === 'OPT-OUT' && r.reason.trim() === ''
|
||||
? { ...r, reason: 'because' }
|
||||
: { ...r, reason: r.reason.trim() }
|
||||
);
|
||||
const matrixGen = fc.uniqueArray(validRowGen, {
|
||||
minLength: 1,
|
||||
maxLength: 8,
|
||||
selector: (r) => r.capability.toLowerCase(),
|
||||
});
|
||||
fc.assert(
|
||||
fc.property(matrixGen, (rows) => {
|
||||
const rendered = renderCoverageMatrix(rows);
|
||||
const v = validateCoverageMatrix(rendered);
|
||||
// Injected reason guarantees validity; any invalid result is a parser bug.
|
||||
assert.strictEqual(v.valid, true);
|
||||
assert.strictEqual(v.counts.surface, rows.length);
|
||||
return true;
|
||||
}),
|
||||
{ numRuns: 100 }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
// CLI entry point (STDIN → exit codes mirror grep, like assumption-delta)
|
||||
// ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('api-coverage CLI — STDIN + exit codes', () => {
|
||||
const CLI = path.join(__dirname, '..', 'gsd-core', 'bin', 'lib', 'api-coverage.cjs');
|
||||
|
||||
function runCli(stdin) {
|
||||
const r = spawnSync(process.execPath, [CLI, '--json'], {
|
||||
input: stdin,
|
||||
encoding: 'utf-8',
|
||||
timeout: 15000,
|
||||
});
|
||||
return { exitCode: r.status, stdout: r.stdout, stderr: r.stderr };
|
||||
}
|
||||
|
||||
test('exit 0 + JSON IR when integration detected', () => {
|
||||
const r = runCli('Integrate the Stripe API for payments');
|
||||
assert.strictEqual(r.exitCode, 0);
|
||||
const body = JSON.parse(r.stdout);
|
||||
assert.strictEqual(body.detected, true);
|
||||
assert.ok(Array.isArray(body.signals));
|
||||
});
|
||||
|
||||
test('exit 1 when no integration', () => {
|
||||
const r = runCli('Refactor the login helper');
|
||||
assert.strictEqual(r.exitCode, 1);
|
||||
});
|
||||
});
|
||||
@@ -81,6 +81,7 @@ describe('config-field-docs', () => {
|
||||
verifier: 'workflow.verifier',
|
||||
nyquist_validation: 'workflow.nyquist_validation',
|
||||
ai_integration_phase: 'workflow.ai_integration_phase',
|
||||
api_coverage_gate: 'workflow.api_coverage_gate',
|
||||
text_mode: 'workflow.text_mode',
|
||||
subagent_timeout: 'workflow.subagent_timeout',
|
||||
branching_strategy: 'git.branching_strategy',
|
||||
|
||||
72
tests/effort-sync-installed-runtime.test.cjs
Normal file
72
tests/effort-sync-installed-runtime.test.cjs
Normal file
@@ -0,0 +1,72 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* #2071 — `gsd-tools effort sync` crashed in an INSTALLED runtime because
|
||||
* commands.cjs did `require('../../../bin/install.js')`, but the installer only
|
||||
* copies the `gsd-core/` subtree into a runtime home — the package-root
|
||||
* `bin/install.js` is never present there, so the require threw MODULE_NOT_FOUND.
|
||||
*
|
||||
* This does a real minimal install into a temp home (the same helper the
|
||||
* golden-parity suite uses) and runs the exact repro from the issue against the
|
||||
* installed shim: `node <configDir>/gsd-core/bin/gsd-tools.cjs effort sync`. Pre-fix
|
||||
* this throws `Cannot find module '../../../bin/install.js'`; post-fix the
|
||||
* install-time resolvers live in the shipped sibling
|
||||
* `gsd-core/bin/lib/install-effort-resolver.cjs` and the require resolves.
|
||||
*
|
||||
* `--config-dir <temp>` keeps it hermetic (targets the temp install, never the
|
||||
* developer's real ~/.claude); effort sync defaults to dry-run so nothing is written.
|
||||
*/
|
||||
|
||||
const { test, describe } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const { execFileSync } = require('node:child_process');
|
||||
|
||||
const { runMinimalInstall } = require('./helpers/install-shared.cjs');
|
||||
const { cleanup } = require('./helpers.cjs');
|
||||
|
||||
describe('#2071: effort sync runs in an installed runtime (no package-root bin/install.js)', () => {
|
||||
test('effort sync does not crash reaching for the un-shipped bin/install.js', () => {
|
||||
if (process.platform === 'win32') return; // install layout is POSIX-path-shaped
|
||||
|
||||
const { configDir, root } = runMinimalInstall({ runtime: 'claude', scope: 'global' });
|
||||
try {
|
||||
// Installed layout invariant: the package-root installer is never copied in.
|
||||
assert.ok(!fs.existsSync(path.join(root, 'bin', 'install.js')), 'installed home must not contain bin/install.js');
|
||||
assert.ok(!fs.existsSync(path.join(configDir, 'bin', 'install.js')), 'no bin/install.js beside gsd-core');
|
||||
|
||||
// A project effort config gives the sync something to resolve.
|
||||
fs.mkdirSync(path.join(root, '.planning'), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(root, '.planning', 'config.json'),
|
||||
JSON.stringify({ effort: { default: 'high' } }),
|
||||
);
|
||||
|
||||
const gsdTools = path.join(configDir, 'gsd-core', 'bin', 'gsd-tools.cjs');
|
||||
let combined = '';
|
||||
try {
|
||||
combined = execFileSync(
|
||||
process.execPath,
|
||||
[gsdTools, 'effort', 'sync', '--config-dir', configDir],
|
||||
{ cwd: root, encoding: 'utf-8', env: { ...process.env, HOME: root } },
|
||||
);
|
||||
} catch (e) {
|
||||
combined = `${e.stdout || ''}${e.stderr || ''}${e.message || ''}`;
|
||||
}
|
||||
|
||||
assert.doesNotMatch(
|
||||
combined,
|
||||
/Cannot find module[^\n]*install\.js|'\.\.\/\.\.\/\.\.\/bin\/install\.js'/,
|
||||
`effort sync must not reach for the un-shipped bin/install.js:\n${combined}`,
|
||||
);
|
||||
assert.doesNotMatch(
|
||||
combined,
|
||||
/MODULE_NOT_FOUND/,
|
||||
`effort sync must not crash on module resolution in an installed runtime:\n${combined}`,
|
||||
);
|
||||
} finally {
|
||||
cleanup(root);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -52,6 +52,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "51b5d0ba5b1e98d9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "425dd69c629230e7",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "e176817364a7cbf4",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "efd80aca449032ad",
|
||||
"gsd-core/references/checkpoints.md": "2de680837faa9752",
|
||||
@@ -93,7 +94,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "de81380316d8a37f",
|
||||
"gsd-core/references/model-profiles.md": "d6ed560db6357ad2",
|
||||
"gsd-core/references/model-profiles.md": "6568ca29b6ee00d8",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "2459c40bfc8a0ea8",
|
||||
@@ -108,7 +109,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "b0e55e9d585f90c1",
|
||||
"gsd-core/references/planning-config.md": "2e2f418328e52f6a",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -206,13 +207,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "603ce2019835f00e",
|
||||
"gsd-core/workflows/check-todos.md": "5a62092df800ad7c",
|
||||
"gsd-core/workflows/cleanup.md": "12c8fd85d3010fe6",
|
||||
"gsd-core/workflows/code-review-fix.md": "5738cb929c995008",
|
||||
"gsd-core/workflows/code-review.md": "d454365f1704d0bc",
|
||||
"gsd-core/workflows/code-review-fix.md": "60640e633b0a124b",
|
||||
"gsd-core/workflows/code-review.md": "5c40505c01871153",
|
||||
"gsd-core/workflows/complete-milestone.md": "aaf272074acec69d",
|
||||
"gsd-core/workflows/debug.md": "68f1ddc74886ebe5",
|
||||
"gsd-core/workflows/diagnose-issues.md": "c8c41993c277363c",
|
||||
"gsd-core/workflows/discovery-phase.md": "3de990caffdde4f8",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "42210a0cbe1bac70",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "8581fd77def7ce84",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "5c0d1ca6abda0383",
|
||||
"gsd-core/workflows/discuss-phase.md": "c0a977154470b7f5",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "ab0c68941386998b",
|
||||
@@ -278,7 +279,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "dc5598ae8accdecd",
|
||||
"gsd-core/workflows/profile-user.md": "355af92ac285567f",
|
||||
"gsd-core/workflows/progress.md": "79a11ce798082054",
|
||||
"gsd-core/workflows/quick.md": "35582887917ef938",
|
||||
"gsd-core/workflows/quick.md": "7108075f69e88e7c",
|
||||
"gsd-core/workflows/reapply-patches.md": "4dcd6117d0a507ca",
|
||||
"gsd-core/workflows/remove-phase.md": "23b9eb0858a2535e",
|
||||
"gsd-core/workflows/remove-workspace.md": "d0bd7e0601138798",
|
||||
@@ -308,7 +309,7 @@
|
||||
"gsd-core/workflows/update.md": "2c58df5e21c41c31",
|
||||
"gsd-core/workflows/validate-phase.md": "6c0ab739d15709fa",
|
||||
"gsd-core/workflows/verify-phase.md": "0eefbb6bb1b0bed6",
|
||||
"gsd-core/workflows/verify-work.md": "be699ed7920f61b0",
|
||||
"gsd-core/workflows/verify-work.md": "59276d94999ee022",
|
||||
"hooks/gsd-check-update-worker.js": "fa301e6366270d5f",
|
||||
"hooks/gsd-check-update.js": "4617a98bf529e4c3",
|
||||
"hooks/gsd-config-reload.js": "96546e0e8bb47904",
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "5ab875054b1adda9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "66264d41dfd9154a",
|
||||
"gsd-core/references/artifact-types.md": "a6d2e1f9453ffbf5",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "6aa620c6ca38bdf0",
|
||||
@@ -164,7 +165,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "8484ad9799b7f680",
|
||||
"gsd-core/references/model-profiles.md": "e067ad3df6770db1",
|
||||
"gsd-core/references/mvp-concepts.md": "72f7e8b1f8ae7118",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -179,7 +180,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "eb168188abd00101",
|
||||
"gsd-core/references/planning-config.md": "ac409835e8260a3e",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -277,13 +278,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "7e5683728ef33707",
|
||||
"gsd-core/workflows/check-todos.md": "bdeaf43f9c61e0cc",
|
||||
"gsd-core/workflows/cleanup.md": "0daa2f2720c111f1",
|
||||
"gsd-core/workflows/code-review-fix.md": "c323f7098b671bd6",
|
||||
"gsd-core/workflows/code-review.md": "ad450c6ef8459dad",
|
||||
"gsd-core/workflows/code-review-fix.md": "2e113d1f4350a075",
|
||||
"gsd-core/workflows/code-review.md": "334c90c401f291f8",
|
||||
"gsd-core/workflows/complete-milestone.md": "c1f91b77f4ace7f2",
|
||||
"gsd-core/workflows/debug.md": "849d7e5b9c12dcae",
|
||||
"gsd-core/workflows/diagnose-issues.md": "6cc3900891dfb927",
|
||||
"gsd-core/workflows/discovery-phase.md": "3ba7cfb89fb1e761",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "1e229f6d21831d60",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "f5b765d33eba4f88",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "0841f7dc6e9a054a",
|
||||
"gsd-core/workflows/discuss-phase.md": "5c5e8d8c2c9d95aa",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "db488d74d080c653",
|
||||
@@ -349,7 +350,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "c87db7ac8c28be1b",
|
||||
"gsd-core/workflows/profile-user.md": "14263db831230142",
|
||||
"gsd-core/workflows/progress.md": "893aa3c36983f74b",
|
||||
"gsd-core/workflows/quick.md": "5790ceb09aa685be",
|
||||
"gsd-core/workflows/quick.md": "069fe37d083a94a3",
|
||||
"gsd-core/workflows/reapply-patches.md": "39050f72601aec89",
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c",
|
||||
@@ -379,7 +380,7 @@
|
||||
"gsd-core/workflows/update.md": "fd160e13f8b7e83c",
|
||||
"gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa",
|
||||
"gsd-core/workflows/verify-phase.md": "22f18492581f1da5",
|
||||
"gsd-core/workflows/verify-work.md": "34e980a6950cd83c",
|
||||
"gsd-core/workflows/verify-work.md": "63b3f680d8f0a6f3",
|
||||
"hooks/gsd-check-update-worker.js": "cc1ef5f840f9dfc9",
|
||||
"hooks/gsd-check-update.js": "7b3a7983d5f1f5d3",
|
||||
"hooks/gsd-config-reload.js": "96546e0e8bb47904",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/claude.json
vendored
15
tests/fixtures/golden-install-parity/claude.json
vendored
@@ -51,6 +51,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "5ab875054b1adda9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "8bd01fd75a2ba70e",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "6aa620c6ca38bdf0",
|
||||
@@ -92,7 +93,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "90e2c9bc577278fd",
|
||||
"gsd-core/references/model-profiles.md": "c249163663bbea53",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -107,7 +108,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "99c46b7d318adf1a",
|
||||
"gsd-core/references/planning-config.md": "b025429fc72f9285",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -205,13 +206,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "722397c04272dfaa",
|
||||
"gsd-core/workflows/check-todos.md": "6c2a43d1d3e86589",
|
||||
"gsd-core/workflows/cleanup.md": "0daa2f2720c111f1",
|
||||
"gsd-core/workflows/code-review-fix.md": "adb62c695b39ef61",
|
||||
"gsd-core/workflows/code-review.md": "6c40b95e799907d0",
|
||||
"gsd-core/workflows/code-review-fix.md": "722416b71b31c5fc",
|
||||
"gsd-core/workflows/code-review.md": "506412604f767adc",
|
||||
"gsd-core/workflows/complete-milestone.md": "dcf1182398efb1ca",
|
||||
"gsd-core/workflows/debug.md": "a9397fd35cca2240",
|
||||
"gsd-core/workflows/diagnose-issues.md": "75ffc381ac3059ff",
|
||||
"gsd-core/workflows/discovery-phase.md": "6161c60d752d0058",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "46876f83547db40a",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "a8cd1db094fefd35",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "290c0d83d783f9f6",
|
||||
"gsd-core/workflows/discuss-phase.md": "df56c8cd170b2150",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "db488d74d080c653",
|
||||
@@ -277,7 +278,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "ab157cd8e49621dd",
|
||||
"gsd-core/workflows/profile-user.md": "ff3820a27731ceb8",
|
||||
"gsd-core/workflows/progress.md": "bd1ecf9207331bda",
|
||||
"gsd-core/workflows/quick.md": "da83b1a15b7f1bf7",
|
||||
"gsd-core/workflows/quick.md": "3363bdfefd403686",
|
||||
"gsd-core/workflows/reapply-patches.md": "ba9406b60f2c4041",
|
||||
"gsd-core/workflows/remove-phase.md": "ada8a0546c686483",
|
||||
"gsd-core/workflows/remove-workspace.md": "f3ab3a88a7e9e1ed",
|
||||
@@ -307,7 +308,7 @@
|
||||
"gsd-core/workflows/update.md": "f9e7d8a760d0d3c8",
|
||||
"gsd-core/workflows/validate-phase.md": "2ac231dc541441c2",
|
||||
"gsd-core/workflows/verify-phase.md": "e0957e153788a222",
|
||||
"gsd-core/workflows/verify-work.md": "efe57bdbbb3af03f",
|
||||
"gsd-core/workflows/verify-work.md": "c8ffee621e7319de",
|
||||
"hooks/gsd-check-update-worker.js": "a530efdb5fdc0da3",
|
||||
"hooks/gsd-check-update.js": "25cde66a12d6b886",
|
||||
"hooks/gsd-config-reload.js": "96546e0e8bb47904",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/cline.json
vendored
15
tests/fixtures/golden-install-parity/cline.json
vendored
@@ -55,6 +55,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "59f782556e4e611f",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "66264d41dfd9154a",
|
||||
"gsd-core/references/artifact-types.md": "a6d2e1f9453ffbf5",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "9a7ba3a17ece1698",
|
||||
@@ -96,7 +97,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "eb144b83e31196b8",
|
||||
"gsd-core/references/model-profiles.md": "1794ad3d9854129e",
|
||||
"gsd-core/references/mvp-concepts.md": "72f7e8b1f8ae7118",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -111,7 +112,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "a0dc2dddb953b22c",
|
||||
"gsd-core/references/planning-config.md": "5a40b2934db6a321",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -209,13 +210,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "cc5217b1b2238a4c",
|
||||
"gsd-core/workflows/check-todos.md": "32fdf33f5dc8bdde",
|
||||
"gsd-core/workflows/cleanup.md": "b0ebfc48792b407b",
|
||||
"gsd-core/workflows/code-review-fix.md": "b946fe7bcb303852",
|
||||
"gsd-core/workflows/code-review.md": "0b24efcfa71a2ed2",
|
||||
"gsd-core/workflows/code-review-fix.md": "e4549af672e74e6f",
|
||||
"gsd-core/workflows/code-review.md": "a65e3e869508f89e",
|
||||
"gsd-core/workflows/complete-milestone.md": "c0808127038a8f86",
|
||||
"gsd-core/workflows/debug.md": "f42e8e3cbc298694",
|
||||
"gsd-core/workflows/diagnose-issues.md": "e616d0d730328d68",
|
||||
"gsd-core/workflows/discovery-phase.md": "3ba7cfb89fb1e761",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "89987fd183e0d552",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "9efcb2ef6a9245b3",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "0841f7dc6e9a054a",
|
||||
"gsd-core/workflows/discuss-phase.md": "a290d5ee19607bb7",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "250de9aae90daebc",
|
||||
@@ -281,7 +282,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "9923878a4f6a2d91",
|
||||
"gsd-core/workflows/profile-user.md": "26f74db0a7fcd268",
|
||||
"gsd-core/workflows/progress.md": "9f326d63afb4b76b",
|
||||
"gsd-core/workflows/quick.md": "68a9dfcd53f0859f",
|
||||
"gsd-core/workflows/quick.md": "2afc046e94daad0a",
|
||||
"gsd-core/workflows/reapply-patches.md": "eb4272145a117904",
|
||||
"gsd-core/workflows/remove-phase.md": "e336350f8113a328",
|
||||
"gsd-core/workflows/remove-workspace.md": "e685dfbd736dfd90",
|
||||
@@ -311,7 +312,7 @@
|
||||
"gsd-core/workflows/update.md": "165beec33490bd28",
|
||||
"gsd-core/workflows/validate-phase.md": "5b4ae14c87859bd2",
|
||||
"gsd-core/workflows/verify-phase.md": "a4f918c92c927268",
|
||||
"gsd-core/workflows/verify-work.md": "6fa216623778c541",
|
||||
"gsd-core/workflows/verify-work.md": "3fb282f2bce34a79",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
"scripts/changeset/cli.cjs": "68f92a344b199271",
|
||||
"scripts/changeset/github-release-notes.cjs": "795677f0c009b132",
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "5ab875054b1adda9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "66264d41dfd9154a",
|
||||
"gsd-core/references/artifact-types.md": "a6d2e1f9453ffbf5",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "6aa620c6ca38bdf0",
|
||||
@@ -164,7 +165,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "8484ad9799b7f680",
|
||||
"gsd-core/references/model-profiles.md": "e067ad3df6770db1",
|
||||
"gsd-core/references/mvp-concepts.md": "72f7e8b1f8ae7118",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -179,7 +180,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "eb168188abd00101",
|
||||
"gsd-core/references/planning-config.md": "ac409835e8260a3e",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -277,13 +278,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "7e5683728ef33707",
|
||||
"gsd-core/workflows/check-todos.md": "bdeaf43f9c61e0cc",
|
||||
"gsd-core/workflows/cleanup.md": "0daa2f2720c111f1",
|
||||
"gsd-core/workflows/code-review-fix.md": "c323f7098b671bd6",
|
||||
"gsd-core/workflows/code-review.md": "ad450c6ef8459dad",
|
||||
"gsd-core/workflows/code-review-fix.md": "2e113d1f4350a075",
|
||||
"gsd-core/workflows/code-review.md": "334c90c401f291f8",
|
||||
"gsd-core/workflows/complete-milestone.md": "c1f91b77f4ace7f2",
|
||||
"gsd-core/workflows/debug.md": "849d7e5b9c12dcae",
|
||||
"gsd-core/workflows/diagnose-issues.md": "77d98ac07c4a26ff",
|
||||
"gsd-core/workflows/discovery-phase.md": "3ba7cfb89fb1e761",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "1e229f6d21831d60",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "f5b765d33eba4f88",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "0841f7dc6e9a054a",
|
||||
"gsd-core/workflows/discuss-phase.md": "02a5381c9a2173be",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "db488d74d080c653",
|
||||
@@ -349,7 +350,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "c87db7ac8c28be1b",
|
||||
"gsd-core/workflows/profile-user.md": "4fa910d15dea5695",
|
||||
"gsd-core/workflows/progress.md": "893aa3c36983f74b",
|
||||
"gsd-core/workflows/quick.md": "9033dbe58443af36",
|
||||
"gsd-core/workflows/quick.md": "cc530299ba461539",
|
||||
"gsd-core/workflows/reapply-patches.md": "39050f72601aec89",
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c",
|
||||
@@ -379,7 +380,7 @@
|
||||
"gsd-core/workflows/update.md": "5ff1f77222977648",
|
||||
"gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa",
|
||||
"gsd-core/workflows/verify-phase.md": "22f18492581f1da5",
|
||||
"gsd-core/workflows/verify-work.md": "34e980a6950cd83c",
|
||||
"gsd-core/workflows/verify-work.md": "63b3f680d8f0a6f3",
|
||||
"hooks/gsd-check-update-worker.js": "bdc9324a2f080ddd",
|
||||
"hooks/gsd-check-update.js": "b7669f605631e506",
|
||||
"hooks/gsd-config-reload.js": "96546e0e8bb47904",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/codex.json
vendored
15
tests/fixtures/golden-install-parity/codex.json
vendored
@@ -87,6 +87,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "51b5d0ba5b1e98d9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "425dd69c629230e7",
|
||||
"gsd-core/references/api-coverage.md": "524382216a8e713f",
|
||||
"gsd-core/references/artifact-types.md": "3218cafb0c92dc32",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "4156025334411073",
|
||||
"gsd-core/references/checkpoints.md": "9feb961f644afa96",
|
||||
@@ -128,7 +129,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "86e81f17c2f23fff",
|
||||
"gsd-core/references/model-profiles.md": "bd90862f68007f2e",
|
||||
"gsd-core/references/mvp-concepts.md": "23201c8118fb074a",
|
||||
"gsd-core/references/phase-argument-parsing.md": "531176f66da49c98",
|
||||
"gsd-core/references/planner-antipatterns.md": "2459c40bfc8a0ea8",
|
||||
@@ -143,7 +144,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "7889bfa28e82156b",
|
||||
"gsd-core/references/planner-revision.md": "2ebf1a714d1ec4bf",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "40d4abb1ed0f3723",
|
||||
"gsd-core/references/planning-config.md": "b01856d7a63e73a2",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -241,13 +242,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "92f08626d4aea668",
|
||||
"gsd-core/workflows/check-todos.md": "b2b103e8638e760a",
|
||||
"gsd-core/workflows/cleanup.md": "5d48d64664222a3e",
|
||||
"gsd-core/workflows/code-review-fix.md": "3ff5f7eac2269ca3",
|
||||
"gsd-core/workflows/code-review.md": "82858ab037b9176e",
|
||||
"gsd-core/workflows/code-review-fix.md": "ae7f9c6b39a23c12",
|
||||
"gsd-core/workflows/code-review.md": "eadada9e0a89adf2",
|
||||
"gsd-core/workflows/complete-milestone.md": "017df7443bd08da5",
|
||||
"gsd-core/workflows/debug.md": "cc7b2d2fd4307a78",
|
||||
"gsd-core/workflows/diagnose-issues.md": "e38bb21d06dff077",
|
||||
"gsd-core/workflows/discovery-phase.md": "71a4b78ff876a854",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "f23abfe76623ed63",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "0d936ec25299917c",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "3f8b83dc6be2e9d5",
|
||||
"gsd-core/workflows/discuss-phase.md": "7c9df6656b81fda9",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "db488d74d080c653",
|
||||
@@ -313,7 +314,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "d13e1cc81de40896",
|
||||
"gsd-core/workflows/profile-user.md": "05828c8cc61ef384",
|
||||
"gsd-core/workflows/progress.md": "7bedc431bb55edb8",
|
||||
"gsd-core/workflows/quick.md": "3e7686705da2af19",
|
||||
"gsd-core/workflows/quick.md": "62b9e138dc70b479",
|
||||
"gsd-core/workflows/reapply-patches.md": "26297b84736e66a4",
|
||||
"gsd-core/workflows/remove-phase.md": "9ee0fddd11a0d9d4",
|
||||
"gsd-core/workflows/remove-workspace.md": "19d7465aaa50cb62",
|
||||
@@ -343,7 +344,7 @@
|
||||
"gsd-core/workflows/update.md": "5c35c0ec0f462ea6",
|
||||
"gsd-core/workflows/validate-phase.md": "020201a41049679f",
|
||||
"gsd-core/workflows/verify-phase.md": "2e12c3cb97a9122a",
|
||||
"gsd-core/workflows/verify-work.md": "69e27f6f419d0bba",
|
||||
"gsd-core/workflows/verify-work.md": "5b348e73fc0d0829",
|
||||
"hooks/gsd-check-update.js": "ef48957eb6ac6a10",
|
||||
"hooks/gsd-context-monitor.js": "76fecaaa2babd6c1",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "51b5d0ba5b1e98d9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "425dd69c629230e7",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "f992de8b2b1a4420",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "efd80aca449032ad",
|
||||
"gsd-core/references/checkpoints.md": "c70b323dcb1583d5",
|
||||
@@ -94,7 +95,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "1d392e37a746742a",
|
||||
"gsd-core/references/model-profiles.md": "d6ed560db6357ad2",
|
||||
"gsd-core/references/model-profiles.md": "6568ca29b6ee00d8",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "2459c40bfc8a0ea8",
|
||||
@@ -109,7 +110,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "fd81dd276828eab4",
|
||||
"gsd-core/references/planning-config.md": "309a566a0e13e43e",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -207,13 +208,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "dd972ddde9663295",
|
||||
"gsd-core/workflows/check-todos.md": "be9b50b5f28d7504",
|
||||
"gsd-core/workflows/cleanup.md": "8233b05ebf011bec",
|
||||
"gsd-core/workflows/code-review-fix.md": "ab2b467b41522c10",
|
||||
"gsd-core/workflows/code-review.md": "1bbbe61f45fccf4c",
|
||||
"gsd-core/workflows/code-review-fix.md": "fda53892ae4b17fc",
|
||||
"gsd-core/workflows/code-review.md": "f1c045ec4d33abc8",
|
||||
"gsd-core/workflows/complete-milestone.md": "470cf39261400ee2",
|
||||
"gsd-core/workflows/debug.md": "36cb536be452d79e",
|
||||
"gsd-core/workflows/diagnose-issues.md": "42acbe2a43fc886e",
|
||||
"gsd-core/workflows/discovery-phase.md": "8e99da61fb2b7074",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "ab2d26b194805ac1",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "ab0c432b84038681",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "5c0d1ca6abda0383",
|
||||
"gsd-core/workflows/discuss-phase.md": "31a79ea11c1cdd5f",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "654cdaf1138d5e27",
|
||||
@@ -279,7 +280,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "2833905f119b5722",
|
||||
"gsd-core/workflows/profile-user.md": "5cc032206c99ef71",
|
||||
"gsd-core/workflows/progress.md": "6b9a84a43dc55af5",
|
||||
"gsd-core/workflows/quick.md": "7ddfe17f048541ec",
|
||||
"gsd-core/workflows/quick.md": "eb68ea8748546331",
|
||||
"gsd-core/workflows/reapply-patches.md": "8fd59e24b486f180",
|
||||
"gsd-core/workflows/remove-phase.md": "e262654e319d1bc4",
|
||||
"gsd-core/workflows/remove-workspace.md": "ceddfeef5f2d6754",
|
||||
@@ -309,7 +310,7 @@
|
||||
"gsd-core/workflows/update.md": "f444a7cfcd246cfb",
|
||||
"gsd-core/workflows/validate-phase.md": "2f705775a4b76d42",
|
||||
"gsd-core/workflows/verify-phase.md": "5c72780e34214e27",
|
||||
"gsd-core/workflows/verify-work.md": "58e9b1b16f773b53",
|
||||
"gsd-core/workflows/verify-work.md": "c966971a3cbd1d71",
|
||||
"hooks/gsd-session.json": "0a462834f2a28fee",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
"scripts/changeset/cli.cjs": "68f92a344b199271",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/cursor.json
vendored
15
tests/fixtures/golden-install-parity/cursor.json
vendored
@@ -123,6 +123,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "3d62d178004db5cc",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "8bd01fd75a2ba70e",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "273b371c5751f35a",
|
||||
"gsd-core/references/checkpoints.md": "3001eeccb319781b",
|
||||
@@ -164,7 +165,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "f4c013e700c52b08",
|
||||
"gsd-core/references/model-profiles.md": "5452b2e19e19f77e",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e562947d1bf5c5a4",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -179,7 +180,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "8af05de88771e9f4",
|
||||
"gsd-core/references/planning-config.md": "a3f1b4aca291db59",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -277,13 +278,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "4b20eda9a0b587ce",
|
||||
"gsd-core/workflows/check-todos.md": "1a67337d1630848f",
|
||||
"gsd-core/workflows/cleanup.md": "db47963f103c2748",
|
||||
"gsd-core/workflows/code-review-fix.md": "49e7f024c551b3a5",
|
||||
"gsd-core/workflows/code-review.md": "6a9fd2996a6b600e",
|
||||
"gsd-core/workflows/code-review-fix.md": "c57af378033b1b58",
|
||||
"gsd-core/workflows/code-review.md": "32c37bcbec8b8698",
|
||||
"gsd-core/workflows/complete-milestone.md": "1400a4856f592f3e",
|
||||
"gsd-core/workflows/debug.md": "a73d8018986131ba",
|
||||
"gsd-core/workflows/diagnose-issues.md": "cd582747131726e3",
|
||||
"gsd-core/workflows/discovery-phase.md": "7dcf150998559c11",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "373788c6b7eab272",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "c25c6a6c633d71b6",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "290c0d83d783f9f6",
|
||||
"gsd-core/workflows/discuss-phase.md": "14688ff19ce2184c",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "30612a2de153cb5b",
|
||||
@@ -349,7 +350,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "c67d90c65da47168",
|
||||
"gsd-core/workflows/profile-user.md": "8c943983241260b5",
|
||||
"gsd-core/workflows/progress.md": "65aabee5e8a6dd82",
|
||||
"gsd-core/workflows/quick.md": "762256cf6d177c06",
|
||||
"gsd-core/workflows/quick.md": "32a71f62041c8510",
|
||||
"gsd-core/workflows/reapply-patches.md": "ba9406b60f2c4041",
|
||||
"gsd-core/workflows/remove-phase.md": "ada8a0546c686483",
|
||||
"gsd-core/workflows/remove-workspace.md": "433affcd1a200826",
|
||||
@@ -379,7 +380,7 @@
|
||||
"gsd-core/workflows/update.md": "23e294ba707c3580",
|
||||
"gsd-core/workflows/validate-phase.md": "2df0c6e298a5f249",
|
||||
"gsd-core/workflows/verify-phase.md": "e0957e153788a222",
|
||||
"gsd-core/workflows/verify-work.md": "145596b2542c457a",
|
||||
"gsd-core/workflows/verify-work.md": "e7e7e900c4874490",
|
||||
"hooks/gsd-cursor-post-tool.js": "019d503aee8b4a3f",
|
||||
"hooks/gsd-cursor-session-start.js": "c6e04ed597ea7020",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/hermes.json
vendored
15
tests/fixtures/golden-install-parity/hermes.json
vendored
@@ -52,6 +52,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "892f086e846cd8e4",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "8bd01fd75a2ba70e",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "db8a7425ed808e24",
|
||||
@@ -93,7 +94,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "8472d453a325cc1b",
|
||||
"gsd-core/references/model-profiles.md": "6012c3b53473f04f",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -108,7 +109,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "1358a14bded944f5",
|
||||
"gsd-core/references/planning-config.md": "831d626c214d92e4",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -206,13 +207,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "dd572ca89862e5ec",
|
||||
"gsd-core/workflows/check-todos.md": "ea9a303c48a5d752",
|
||||
"gsd-core/workflows/cleanup.md": "6c488059fc152a49",
|
||||
"gsd-core/workflows/code-review-fix.md": "04b143a963067236",
|
||||
"gsd-core/workflows/code-review.md": "ff28724fc216972c",
|
||||
"gsd-core/workflows/code-review-fix.md": "e829d3baf9901b54",
|
||||
"gsd-core/workflows/code-review.md": "50a05ab8957bd05f",
|
||||
"gsd-core/workflows/complete-milestone.md": "f1866541148dc291",
|
||||
"gsd-core/workflows/debug.md": "15cf6999e85dcc8c",
|
||||
"gsd-core/workflows/diagnose-issues.md": "16f2d2a85335641f",
|
||||
"gsd-core/workflows/discovery-phase.md": "6161c60d752d0058",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "db60ec68b59a40eb",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "3a1e215890d2b3f4",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "290c0d83d783f9f6",
|
||||
"gsd-core/workflows/discuss-phase.md": "0aa052ae4ee70bf6",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "536e2fa842f1bc95",
|
||||
@@ -278,7 +279,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "ecabd55e4eabf229",
|
||||
"gsd-core/workflows/profile-user.md": "de5030437226cf2c",
|
||||
"gsd-core/workflows/progress.md": "f18db000584d9cb1",
|
||||
"gsd-core/workflows/quick.md": "5044ce4e7512e174",
|
||||
"gsd-core/workflows/quick.md": "e7a395b9e7786b56",
|
||||
"gsd-core/workflows/reapply-patches.md": "158083a310859594",
|
||||
"gsd-core/workflows/remove-phase.md": "fce799aae3ab2715",
|
||||
"gsd-core/workflows/remove-workspace.md": "8facde381657dd71",
|
||||
@@ -308,7 +309,7 @@
|
||||
"gsd-core/workflows/update.md": "7499bb4cb2a3ce6f",
|
||||
"gsd-core/workflows/validate-phase.md": "75e8971d3981d06b",
|
||||
"gsd-core/workflows/verify-phase.md": "5c8d1305b47fbef4",
|
||||
"gsd-core/workflows/verify-work.md": "e56e07475d5eb51e",
|
||||
"gsd-core/workflows/verify-work.md": "7a9c9541d2d73fdc",
|
||||
"hooks/gsd-check-update-worker.js": "7989cc2bedd1138d",
|
||||
"hooks/gsd-check-update.js": "25f5ad726f76fc11",
|
||||
"hooks/gsd-config-reload.js": "880b696458e85e9b",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/kilo.json
vendored
15
tests/fixtures/golden-install-parity/kilo.json
vendored
@@ -123,6 +123,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "51b5d0ba5b1e98d9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "425dd69c629230e7",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "8bd01fd75a2ba70e",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "3986d58011bf9006",
|
||||
"gsd-core/references/checkpoints.md": "9feb961f644afa96",
|
||||
@@ -164,7 +165,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "d6ed560db6357ad2",
|
||||
"gsd-core/references/model-profiles.md": "6568ca29b6ee00d8",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "2459c40bfc8a0ea8",
|
||||
@@ -179,7 +180,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "aad463ddda23dbaf",
|
||||
"gsd-core/references/planning-config.md": "37ab69107a2f7dc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -277,13 +278,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "73f429f7472c9949",
|
||||
"gsd-core/workflows/check-todos.md": "ed4b4eb12be222d7",
|
||||
"gsd-core/workflows/cleanup.md": "c5f1bf186395d67d",
|
||||
"gsd-core/workflows/code-review-fix.md": "adb62c695b39ef61",
|
||||
"gsd-core/workflows/code-review.md": "6c40b95e799907d0",
|
||||
"gsd-core/workflows/code-review-fix.md": "722416b71b31c5fc",
|
||||
"gsd-core/workflows/code-review.md": "506412604f767adc",
|
||||
"gsd-core/workflows/complete-milestone.md": "59753bf44d4300da",
|
||||
"gsd-core/workflows/debug.md": "a72d830ac3df74aa",
|
||||
"gsd-core/workflows/diagnose-issues.md": "210b5b313e8a559a",
|
||||
"gsd-core/workflows/discovery-phase.md": "ca7b2be46e59e862",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "36f7edcb666745f2",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "3ef1df313e715387",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "5c0d1ca6abda0383",
|
||||
"gsd-core/workflows/discuss-phase.md": "bd4b26ba168bb51f",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "f8ae26ba4e07672b",
|
||||
@@ -349,7 +350,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "ab157cd8e49621dd",
|
||||
"gsd-core/workflows/profile-user.md": "203ebe3f8f3876a8",
|
||||
"gsd-core/workflows/progress.md": "9381c59676ccb937",
|
||||
"gsd-core/workflows/quick.md": "fd7461e5a92fe450",
|
||||
"gsd-core/workflows/quick.md": "e71c92cf0463a461",
|
||||
"gsd-core/workflows/reapply-patches.md": "becf9728cdb124c4",
|
||||
"gsd-core/workflows/remove-phase.md": "ada8a0546c686483",
|
||||
"gsd-core/workflows/remove-workspace.md": "fc83f362a2d0a1b7",
|
||||
@@ -379,7 +380,7 @@
|
||||
"gsd-core/workflows/update.md": "07dc2fba78ad1865",
|
||||
"gsd-core/workflows/validate-phase.md": "557e3251e3b9349a",
|
||||
"gsd-core/workflows/verify-phase.md": "e0957e153788a222",
|
||||
"gsd-core/workflows/verify-work.md": "b68ac37f6301a3b5",
|
||||
"gsd-core/workflows/verify-work.md": "9fc717845828c6e3",
|
||||
"kilo.json": "13151e97ff23c1aa",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
"scripts/changeset/cli.cjs": "68f92a344b199271",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/kimi.json
vendored
15
tests/fixtures/golden-install-parity/kimi.json
vendored
@@ -88,6 +88,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "5ab875054b1adda9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "66264d41dfd9154a",
|
||||
"gsd-core/references/artifact-types.md": "a6d2e1f9453ffbf5",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "6aa620c6ca38bdf0",
|
||||
@@ -129,7 +130,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "8484ad9799b7f680",
|
||||
"gsd-core/references/model-profiles.md": "e067ad3df6770db1",
|
||||
"gsd-core/references/mvp-concepts.md": "72f7e8b1f8ae7118",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -144,7 +145,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "eb168188abd00101",
|
||||
"gsd-core/references/planning-config.md": "ac409835e8260a3e",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -242,13 +243,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "7e5683728ef33707",
|
||||
"gsd-core/workflows/check-todos.md": "bdeaf43f9c61e0cc",
|
||||
"gsd-core/workflows/cleanup.md": "0daa2f2720c111f1",
|
||||
"gsd-core/workflows/code-review-fix.md": "c323f7098b671bd6",
|
||||
"gsd-core/workflows/code-review.md": "ad450c6ef8459dad",
|
||||
"gsd-core/workflows/code-review-fix.md": "2e113d1f4350a075",
|
||||
"gsd-core/workflows/code-review.md": "334c90c401f291f8",
|
||||
"gsd-core/workflows/complete-milestone.md": "c1f91b77f4ace7f2",
|
||||
"gsd-core/workflows/debug.md": "849d7e5b9c12dcae",
|
||||
"gsd-core/workflows/diagnose-issues.md": "67c058fc7ae6026b",
|
||||
"gsd-core/workflows/discovery-phase.md": "3ba7cfb89fb1e761",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "1e229f6d21831d60",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "f5b765d33eba4f88",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "0841f7dc6e9a054a",
|
||||
"gsd-core/workflows/discuss-phase.md": "0c0465ba668adb33",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "db488d74d080c653",
|
||||
@@ -314,7 +315,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "c87db7ac8c28be1b",
|
||||
"gsd-core/workflows/profile-user.md": "5abfae83739fa978",
|
||||
"gsd-core/workflows/progress.md": "893aa3c36983f74b",
|
||||
"gsd-core/workflows/quick.md": "e265e01cfe117215",
|
||||
"gsd-core/workflows/quick.md": "09d88dd1c0b3e03a",
|
||||
"gsd-core/workflows/reapply-patches.md": "39050f72601aec89",
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c",
|
||||
@@ -344,7 +345,7 @@
|
||||
"gsd-core/workflows/update.md": "6718e0632bba26ca",
|
||||
"gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa",
|
||||
"gsd-core/workflows/verify-phase.md": "22f18492581f1da5",
|
||||
"gsd-core/workflows/verify-work.md": "34e980a6950cd83c",
|
||||
"gsd-core/workflows/verify-work.md": "63b3f680d8f0a6f3",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
"scripts/changeset/cli.cjs": "68f92a344b199271",
|
||||
"scripts/changeset/github-release-notes.cjs": "795677f0c009b132",
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "51b5d0ba5b1e98d9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "425dd69c629230e7",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "218c55caf8aff6df",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "3986d58011bf9006",
|
||||
"gsd-core/references/checkpoints.md": "9feb961f644afa96",
|
||||
@@ -164,7 +165,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "858c16730df68ac2",
|
||||
"gsd-core/references/model-profiles.md": "d6ed560db6357ad2",
|
||||
"gsd-core/references/model-profiles.md": "6568ca29b6ee00d8",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "2459c40bfc8a0ea8",
|
||||
@@ -179,7 +180,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "aad463ddda23dbaf",
|
||||
"gsd-core/references/planning-config.md": "37ab69107a2f7dc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -277,13 +278,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "6cb0c014f5f56965",
|
||||
"gsd-core/workflows/check-todos.md": "6526b64ee88c7d2e",
|
||||
"gsd-core/workflows/cleanup.md": "94d771d26f62dc86",
|
||||
"gsd-core/workflows/code-review-fix.md": "5d97b960da4fef73",
|
||||
"gsd-core/workflows/code-review.md": "aec8ef4de1829607",
|
||||
"gsd-core/workflows/code-review-fix.md": "adb9388bb157610c",
|
||||
"gsd-core/workflows/code-review.md": "ae6bcbd1575aeec4",
|
||||
"gsd-core/workflows/complete-milestone.md": "614299b2c08e66c3",
|
||||
"gsd-core/workflows/debug.md": "9d4a8afc8d36be93",
|
||||
"gsd-core/workflows/diagnose-issues.md": "2971c699d52f1b85",
|
||||
"gsd-core/workflows/discovery-phase.md": "724408336596c50c",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "310b08dc31710cbc",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "92e43cd12200c610",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "5c0d1ca6abda0383",
|
||||
"gsd-core/workflows/discuss-phase.md": "3a62a8d4c374c69f",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "83ca3ea4fac785af",
|
||||
@@ -349,7 +350,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "929b7cb0c99c7b9e",
|
||||
"gsd-core/workflows/profile-user.md": "248d59a31948e0ed",
|
||||
"gsd-core/workflows/progress.md": "8fc3404087f50b95",
|
||||
"gsd-core/workflows/quick.md": "10cc8ddd4bc3f0ee",
|
||||
"gsd-core/workflows/quick.md": "9bdccb7c6a5530c9",
|
||||
"gsd-core/workflows/reapply-patches.md": "a0e9b53f90abceb2",
|
||||
"gsd-core/workflows/remove-phase.md": "dea4661e8f89596f",
|
||||
"gsd-core/workflows/remove-workspace.md": "446847e71aa52504",
|
||||
@@ -379,7 +380,7 @@
|
||||
"gsd-core/workflows/update.md": "71b6cd852f38b4bc",
|
||||
"gsd-core/workflows/validate-phase.md": "abcdbc1b56780565",
|
||||
"gsd-core/workflows/verify-phase.md": "126be1d026900102",
|
||||
"gsd-core/workflows/verify-work.md": "f0d205568abfaf74",
|
||||
"gsd-core/workflows/verify-work.md": "ae07b3fa8b6f864e",
|
||||
"hooks/gsd-check-update-worker.js": "385fb7c67810baf6",
|
||||
"hooks/gsd-check-update.js": "4549451414ffa7d7",
|
||||
"hooks/gsd-config-reload.js": "96546e0e8bb47904",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/qwen.json
vendored
15
tests/fixtures/golden-install-parity/qwen.json
vendored
@@ -52,6 +52,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "be09755fed7ad856",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "8bd01fd75a2ba70e",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "046171320f816346",
|
||||
@@ -93,7 +94,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "cc1efc2942164744",
|
||||
"gsd-core/references/model-profiles.md": "0b7e06ed2e4abac8",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -108,7 +109,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "0037314fe38ca55c",
|
||||
"gsd-core/references/planning-config.md": "4c6de9b6d66aca73",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -206,13 +207,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "3014ff90115f0daf",
|
||||
"gsd-core/workflows/check-todos.md": "ec8c22920f6b2df1",
|
||||
"gsd-core/workflows/cleanup.md": "6a18b165752e3087",
|
||||
"gsd-core/workflows/code-review-fix.md": "e14afce87cf0d420",
|
||||
"gsd-core/workflows/code-review.md": "d6d385b6dadae5a0",
|
||||
"gsd-core/workflows/code-review-fix.md": "f3725ae9d685bed2",
|
||||
"gsd-core/workflows/code-review.md": "29125604bed2c467",
|
||||
"gsd-core/workflows/complete-milestone.md": "40085d32b15805c8",
|
||||
"gsd-core/workflows/debug.md": "c23d067580b09f63",
|
||||
"gsd-core/workflows/diagnose-issues.md": "652ae26975f82242",
|
||||
"gsd-core/workflows/discovery-phase.md": "6161c60d752d0058",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "3865afc23e9cd46a",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "18712f78bb960ec8",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "290c0d83d783f9f6",
|
||||
"gsd-core/workflows/discuss-phase.md": "8644b72386a51241",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "3102430dfad9c012",
|
||||
@@ -278,7 +279,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "cef0f65b16d500b4",
|
||||
"gsd-core/workflows/profile-user.md": "263c0693563d98da",
|
||||
"gsd-core/workflows/progress.md": "3b1b2142a74af85c",
|
||||
"gsd-core/workflows/quick.md": "0a9a7dacc73f8e53",
|
||||
"gsd-core/workflows/quick.md": "bb9a4a145a7edc36",
|
||||
"gsd-core/workflows/reapply-patches.md": "de0ee8acfe7245b2",
|
||||
"gsd-core/workflows/remove-phase.md": "e8ae4fbbfac700f0",
|
||||
"gsd-core/workflows/remove-workspace.md": "4ac64de862dc650e",
|
||||
@@ -308,7 +309,7 @@
|
||||
"gsd-core/workflows/update.md": "b34cb866152d4de3",
|
||||
"gsd-core/workflows/validate-phase.md": "e989cbaa4228564c",
|
||||
"gsd-core/workflows/verify-phase.md": "0dc52b9e629a5f5a",
|
||||
"gsd-core/workflows/verify-work.md": "b5afb65fdf311301",
|
||||
"gsd-core/workflows/verify-work.md": "3355ddc14f052fff",
|
||||
"hooks/gsd-check-update-worker.js": "4bb354044e0dff91",
|
||||
"hooks/gsd-check-update.js": "d2065cb3e725a42a",
|
||||
"hooks/gsd-config-reload.js": "4f52b8a0120bb1b8",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/trae.json
vendored
15
tests/fixtures/golden-install-parity/trae.json
vendored
@@ -52,6 +52,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "18d1ff7c7fa0bab1",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "8bd01fd75a2ba70e",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "4b8c645ffa695067",
|
||||
@@ -93,7 +94,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "41b0af6f5f77af81",
|
||||
"gsd-core/references/model-profiles.md": "b4527b0f255d193f",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e562947d1bf5c5a4",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -108,7 +109,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "e47cdb2337e10dac",
|
||||
"gsd-core/references/planning-config.md": "a686c1363ae626c5",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -206,13 +207,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "c482645c5d1ead46",
|
||||
"gsd-core/workflows/check-todos.md": "0dda8236355e8c9c",
|
||||
"gsd-core/workflows/cleanup.md": "82f65f5214ecd748",
|
||||
"gsd-core/workflows/code-review-fix.md": "959a65773b325ed2",
|
||||
"gsd-core/workflows/code-review.md": "b31bbd7dbe5ed303",
|
||||
"gsd-core/workflows/code-review-fix.md": "f2761f7f8c4a5674",
|
||||
"gsd-core/workflows/code-review.md": "47663a2922756c5e",
|
||||
"gsd-core/workflows/complete-milestone.md": "6e918b72bd885426",
|
||||
"gsd-core/workflows/debug.md": "197d3642a6704de5",
|
||||
"gsd-core/workflows/diagnose-issues.md": "9274b11a3db98c65",
|
||||
"gsd-core/workflows/discovery-phase.md": "b32b6197b66c9a13",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "3d05b08eae75c7bd",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "e376b1cf29379df4",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "290c0d83d783f9f6",
|
||||
"gsd-core/workflows/discuss-phase.md": "4509657816c5566a",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "c9cd7db62e76ebcb",
|
||||
@@ -278,7 +279,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "79fd55b88ea2db9c",
|
||||
"gsd-core/workflows/profile-user.md": "672821e6b1266645",
|
||||
"gsd-core/workflows/progress.md": "94768f835b0b8908",
|
||||
"gsd-core/workflows/quick.md": "9bbf907e39688638",
|
||||
"gsd-core/workflows/quick.md": "a568015cccb53615",
|
||||
"gsd-core/workflows/reapply-patches.md": "21b38c374f19fd78",
|
||||
"gsd-core/workflows/remove-phase.md": "a46c2fe853bf4e86",
|
||||
"gsd-core/workflows/remove-workspace.md": "ae0e1c6d4438d663",
|
||||
@@ -308,7 +309,7 @@
|
||||
"gsd-core/workflows/update.md": "1f935251fca1f276",
|
||||
"gsd-core/workflows/validate-phase.md": "1c0ebe56d96a14d1",
|
||||
"gsd-core/workflows/verify-phase.md": "a151ed36eb51813b",
|
||||
"gsd-core/workflows/verify-work.md": "d3a0970205acc6a5",
|
||||
"gsd-core/workflows/verify-work.md": "dde2a42a56c27c4e",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
"scripts/changeset/cli.cjs": "68f92a344b199271",
|
||||
"scripts/changeset/github-release-notes.cjs": "795677f0c009b132",
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "849977da771f2b06",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "205a43c5fa7c221c",
|
||||
"gsd-core/references/artifact-types.md": "8bd01fd75a2ba70e",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "273b371c5751f35a",
|
||||
"gsd-core/references/checkpoints.md": "808e4fcaa2fda15c",
|
||||
@@ -93,7 +94,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "b3ac5dc094bce1dc",
|
||||
"gsd-core/references/model-profiles.md": "09aa53e3f1764a41",
|
||||
"gsd-core/references/mvp-concepts.md": "3464783eaaef5c10",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e562947d1bf5c5a4",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -108,7 +109,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "da39eace09a10743",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "aafbfc62a3bb84b1",
|
||||
"gsd-core/references/planning-config.md": "1fc70920778d7c8e",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -206,13 +207,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "fe7bb7c978f305a2",
|
||||
"gsd-core/workflows/check-todos.md": "afc840fceb07bf99",
|
||||
"gsd-core/workflows/cleanup.md": "93c14107979a4428",
|
||||
"gsd-core/workflows/code-review-fix.md": "9b2de93a6087774d",
|
||||
"gsd-core/workflows/code-review.md": "2f0ebfb7a2e33764",
|
||||
"gsd-core/workflows/code-review-fix.md": "b99b1f20bb27c291",
|
||||
"gsd-core/workflows/code-review.md": "faa87faf07ae765a",
|
||||
"gsd-core/workflows/complete-milestone.md": "f463bf4e86ac26f6",
|
||||
"gsd-core/workflows/debug.md": "52243eb936a43150",
|
||||
"gsd-core/workflows/diagnose-issues.md": "447072aa72385271",
|
||||
"gsd-core/workflows/discovery-phase.md": "7dcf150998559c11",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "f57000d5c5fb178a",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "b091b3d3e580dd29",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "290c0d83d783f9f6",
|
||||
"gsd-core/workflows/discuss-phase.md": "ce4e6abce9cb2d4e",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "cb49f485c4a1f09e",
|
||||
@@ -278,7 +279,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "acd59f915d018ad4",
|
||||
"gsd-core/workflows/profile-user.md": "c4313672b81b5bcd",
|
||||
"gsd-core/workflows/progress.md": "18813a345bd2343a",
|
||||
"gsd-core/workflows/quick.md": "3acd391cc0c3813a",
|
||||
"gsd-core/workflows/quick.md": "b7813e1810c683e1",
|
||||
"gsd-core/workflows/reapply-patches.md": "d449a23d3acf6379",
|
||||
"gsd-core/workflows/remove-phase.md": "e7a6af429b36e77b",
|
||||
"gsd-core/workflows/remove-workspace.md": "b5e60fbb33b3e33a",
|
||||
@@ -308,7 +309,7 @@
|
||||
"gsd-core/workflows/update.md": "79aaf4b8f1f83045",
|
||||
"gsd-core/workflows/validate-phase.md": "2db47bf5547d7b9d",
|
||||
"gsd-core/workflows/verify-phase.md": "f961cdb3ef03ff05",
|
||||
"gsd-core/workflows/verify-work.md": "5ad63a5edfb6acac",
|
||||
"gsd-core/workflows/verify-work.md": "cce8ae44b30957f1",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
"scripts/changeset/cli.cjs": "68f92a344b199271",
|
||||
"scripts/changeset/github-release-notes.cjs": "795677f0c009b132",
|
||||
|
||||
15
tests/fixtures/golden-install-parity/zcode.json
vendored
15
tests/fixtures/golden-install-parity/zcode.json
vendored
@@ -123,6 +123,7 @@
|
||||
"gsd-core/references/agent-skills-bootstrap.md": "5ab875054b1adda9",
|
||||
"gsd-core/references/ai-evals.md": "b5afa786b938671e",
|
||||
"gsd-core/references/ai-frameworks.md": "f827de93dde124eb",
|
||||
"gsd-core/references/api-coverage.md": "66264d41dfd9154a",
|
||||
"gsd-core/references/artifact-types.md": "a6d2e1f9453ffbf5",
|
||||
"gsd-core/references/autonomous-smart-discuss.md": "2fc710cde0ec7785",
|
||||
"gsd-core/references/checkpoints.md": "6aa620c6ca38bdf0",
|
||||
@@ -164,7 +165,7 @@
|
||||
"gsd-core/references/loop-hook-dispatch.md": "32e5dfb4dba76987",
|
||||
"gsd-core/references/mandatory-initial-read.md": "fe59abce693717cf",
|
||||
"gsd-core/references/model-profile-resolution.md": "f32bb05102839767",
|
||||
"gsd-core/references/model-profiles.md": "8484ad9799b7f680",
|
||||
"gsd-core/references/model-profiles.md": "e067ad3df6770db1",
|
||||
"gsd-core/references/mvp-concepts.md": "72f7e8b1f8ae7118",
|
||||
"gsd-core/references/phase-argument-parsing.md": "e5bbb985f3bc3e34",
|
||||
"gsd-core/references/planner-antipatterns.md": "7ed54ec1e2cc54ac",
|
||||
@@ -179,7 +180,7 @@
|
||||
"gsd-core/references/planner-reviews.md": "dda0193a0fbd4947",
|
||||
"gsd-core/references/planner-revision.md": "86ba8a511f081f05",
|
||||
"gsd-core/references/planner-source-audit.md": "7de5bdb07232ce0b",
|
||||
"gsd-core/references/planning-config.md": "eb168188abd00101",
|
||||
"gsd-core/references/planning-config.md": "ac409835e8260a3e",
|
||||
"gsd-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json": "f10df472f2846cc6",
|
||||
"gsd-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json": "31e8a781eeffe020",
|
||||
"gsd-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json": "70a532a7cc1b6ae8",
|
||||
@@ -277,13 +278,13 @@
|
||||
"gsd-core/workflows/autonomous.md": "7e5683728ef33707",
|
||||
"gsd-core/workflows/check-todos.md": "bdeaf43f9c61e0cc",
|
||||
"gsd-core/workflows/cleanup.md": "0daa2f2720c111f1",
|
||||
"gsd-core/workflows/code-review-fix.md": "c323f7098b671bd6",
|
||||
"gsd-core/workflows/code-review.md": "ad450c6ef8459dad",
|
||||
"gsd-core/workflows/code-review-fix.md": "2e113d1f4350a075",
|
||||
"gsd-core/workflows/code-review.md": "334c90c401f291f8",
|
||||
"gsd-core/workflows/complete-milestone.md": "c1f91b77f4ace7f2",
|
||||
"gsd-core/workflows/debug.md": "849d7e5b9c12dcae",
|
||||
"gsd-core/workflows/diagnose-issues.md": "aa8d787db8f3c46c",
|
||||
"gsd-core/workflows/discovery-phase.md": "3ba7cfb89fb1e761",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "1e229f6d21831d60",
|
||||
"gsd-core/workflows/discuss-phase-assumptions.md": "f5b765d33eba4f88",
|
||||
"gsd-core/workflows/discuss-phase-power.md": "0841f7dc6e9a054a",
|
||||
"gsd-core/workflows/discuss-phase.md": "d0a67b6f77b4d339",
|
||||
"gsd-core/workflows/discuss-phase/modes/advisor.md": "db488d74d080c653",
|
||||
@@ -349,7 +350,7 @@
|
||||
"gsd-core/workflows/pr-branch.md": "c87db7ac8c28be1b",
|
||||
"gsd-core/workflows/profile-user.md": "e23bea0a69c0bb4b",
|
||||
"gsd-core/workflows/progress.md": "893aa3c36983f74b",
|
||||
"gsd-core/workflows/quick.md": "5747c2d8a37affbb",
|
||||
"gsd-core/workflows/quick.md": "12917fdc9a624a0c",
|
||||
"gsd-core/workflows/reapply-patches.md": "39050f72601aec89",
|
||||
"gsd-core/workflows/remove-phase.md": "df9a45f0b1880999",
|
||||
"gsd-core/workflows/remove-workspace.md": "a7ca66db6b7c132c",
|
||||
@@ -379,7 +380,7 @@
|
||||
"gsd-core/workflows/update.md": "dc580dee13f881a6",
|
||||
"gsd-core/workflows/validate-phase.md": "2c6d7671fcaabcaa",
|
||||
"gsd-core/workflows/verify-phase.md": "22f18492581f1da5",
|
||||
"gsd-core/workflows/verify-work.md": "34e980a6950cd83c",
|
||||
"gsd-core/workflows/verify-work.md": "63b3f680d8f0a6f3",
|
||||
"scripts/changeset/README.md": "86ff89331dfd94b2",
|
||||
"scripts/changeset/cli.cjs": "68f92a344b199271",
|
||||
"scripts/changeset/github-release-notes.cjs": "795677f0c009b132",
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
* Hook points tested: discuss:pre, discuss:post, execute:pre, execute:wave:pre,
|
||||
* verify:pre, ship:post
|
||||
*
|
||||
* All 6 points have zero hooks in the real registry by design.
|
||||
* 5 of these points have zero hooks in the real registry by design.
|
||||
* verify:pre graduated out of the empty set in #1562 (it now carries the
|
||||
* ai-integration `api-coverage.verify-pre` blocking gate); SECTION 5 pins the
|
||||
* new contract + retains synthetic extension-point-mechanics coverage.
|
||||
* Tests pin: exact envelope shape, placeholder string contract (Hyrum's Law),
|
||||
* resolver-filter mechanics (schema default / config-override / capabilityStatesById),
|
||||
* CLI contract (missing-arg, invalid-point), and Postel-leniency (malformed config).
|
||||
@@ -481,8 +484,13 @@ describe('execute:wave:pre — real registry empty-resolution + synthetic mechan
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SECTION 5: verify:pre
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// NOTE: verify:pre was an empty extension point until #1562 added the
|
||||
// ai-integration `api-coverage.verify-pre` blocking gate (default-on, opt-out
|
||||
// via workflow.api_coverage_gate=false). The real-registry assertions below pin
|
||||
// the NEW contract; the synthetic BVA tests retain extension-point-mechanics
|
||||
// coverage. Empty-point coverage for the other 5 points is unaffected.
|
||||
|
||||
describe('verify:pre — real registry empty-resolution + synthetic extension-point readiness', () => {
|
||||
describe('verify:pre — real registry carries the api-coverage gate (#1562); synthetic mechanics', () => {
|
||||
let tmpEmptyProjectDir;
|
||||
let tmpProjectDirAllOn;
|
||||
before(() => {
|
||||
@@ -494,29 +502,47 @@ describe('verify:pre — real registry empty-resolution + synthetic extension-po
|
||||
cleanup(tmpProjectDirAllOn);
|
||||
});
|
||||
|
||||
it('[empty-resolution] verify:pre with real registry and no config yields empty activeHooks and exact placeholder (Gall\'s Law)', () => {
|
||||
it('[default-on] verify:pre with real registry and no config yields the api-coverage blocking gate (full-coverage-by-default)', () => {
|
||||
const resolved = resolveLoopHooks({ point: 'verify:pre', registry: realRegistry, config: {} });
|
||||
assert.strictEqual(resolved.activeHooks.length, 0);
|
||||
assert.strictEqual(renderLoopHooks(resolved), '_No active hooks at verify:pre._');
|
||||
const gate = resolved.activeHooks.find((h) => h.capId === 'ai-integration' && h.kind === 'gate');
|
||||
assert.ok(gate, 'ai-integration api-coverage gate must register at verify:pre by default');
|
||||
assert.strictEqual(gate.blocking, true);
|
||||
assert.strictEqual(gate.check.query, 'api-coverage.verify-pre');
|
||||
});
|
||||
|
||||
it('[happy] verify:pre E2E subprocess returns well-formed 3-key JSON envelope with empty activeHooks (Hyrum\'s Law contract pin)', () => {
|
||||
it('[happy] verify:pre E2E subprocess returns a well-formed envelope carrying the gate (Hyrum\'s Law contract pin)', () => {
|
||||
const result = spawnGsd(['loop', 'render-hooks', 'verify:pre', '--cwd', tmpEmptyProjectDir, '--raw'], tmpEmptyProjectDir);
|
||||
assert.strictEqual(result.status, 0, `expected exit 0. stderr: ${result.stderr}`);
|
||||
const envelope = JSON.parse(result.stdout.trim());
|
||||
assert.strictEqual(envelope.point, 'verify:pre');
|
||||
assert.deepEqual(envelope.activeHooks, []);
|
||||
assert.strictEqual(envelope.rendered, '_No active hooks at verify:pre._');
|
||||
assert.ok(Array.isArray(envelope.activeHooks));
|
||||
assert.ok(envelope.activeHooks.some((h) => h.capId === 'ai-integration' && h.kind === 'gate'));
|
||||
assert.deepEqual(Object.keys(envelope).sort(), ['activeHooks', 'point', 'rendered']);
|
||||
});
|
||||
|
||||
it('[negative] verify:pre with all capability config keys set to true still yields empty activeHooks — no leakage from other points', () => {
|
||||
it('[opt-out] verify:pre with workflow.api_coverage_gate=false yields NO ai-integration gate — config opt-out empties the point', () => {
|
||||
const resolved = resolveLoopHooks({
|
||||
point: 'verify:pre',
|
||||
registry: realRegistry,
|
||||
config: { workflow: { api_coverage_gate: false } },
|
||||
});
|
||||
assert.strictEqual(
|
||||
resolved.activeHooks.find((h) => h.capId === 'ai-integration'),
|
||||
undefined,
|
||||
'opting out api_coverage_gate must remove the gate from verify:pre'
|
||||
);
|
||||
});
|
||||
|
||||
it('[negative] verify:pre with unrelated capability keys on does not bleed non-verify:pre hooks into the point', () => {
|
||||
const resolved = resolveLoopHooks({
|
||||
point: 'verify:pre',
|
||||
registry: realRegistry,
|
||||
config: { workflow: { ui_phase: true, ui_review: true, ui_safety_gate: true } },
|
||||
});
|
||||
assert.strictEqual(resolved.activeHooks.length, 0, 'UI and other capabilities must not bleed through to verify:pre');
|
||||
// The only verify:pre hook is the api-coverage gate; UI/other hooks must not bleed in.
|
||||
for (const h of resolved.activeHooks) {
|
||||
assert.notStrictEqual(h.capId, 'ui', 'UI capability must not bleed through to verify:pre');
|
||||
}
|
||||
});
|
||||
|
||||
it('[bva] Synthetic step at verify:pre with configSchema default=true fires correctly — extension point readiness', () => {
|
||||
@@ -547,7 +573,10 @@ describe('verify:pre — real registry empty-resolution + synthetic extension-po
|
||||
const result = spawnGsd(['loop', 'render-hooks', 'verify:pre', '--cwd', malformedDir, '--raw'], malformedDir);
|
||||
assert.strictEqual(result.status, 0, `must not crash on malformed config. stderr: ${result.stderr}`);
|
||||
const envelope = JSON.parse(result.stdout.trim());
|
||||
assert.deepEqual(envelope.activeHooks, []);
|
||||
// Malformed config degrades to defaults (gate default-on); the contract
|
||||
// here is leniency (exit 0, well-formed envelope), not emptiness.
|
||||
assert.strictEqual(envelope.point, 'verify:pre');
|
||||
assert.ok(Array.isArray(envelope.activeHooks));
|
||||
} finally {
|
||||
cleanup(malformedDir);
|
||||
}
|
||||
@@ -720,13 +749,12 @@ describe('CLI contract — missing/invalid point argument (shared across all 6 e
|
||||
// SECTION 8: Parametric empty-point sweep across all 6 points (E2E regression guard)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('Parametric E2E sweep — 5 empty points return correct envelope shape via real registry (ship:post excluded — mempalace registers 1 step there)', () => {
|
||||
describe('Parametric E2E sweep — 4 empty points return correct envelope shape via real registry (ship:post excluded — mempalace registers 1 step there; verify:pre excluded since #1562 added the api-coverage gate)', () => {
|
||||
const EMPTY_POINTS = [
|
||||
'discuss:pre',
|
||||
'discuss:post',
|
||||
'execute:pre',
|
||||
'execute:wave:pre',
|
||||
'verify:pre',
|
||||
];
|
||||
|
||||
for (const point of EMPTY_POINTS) {
|
||||
|
||||
@@ -120,6 +120,36 @@ describe('resolveModelInternal', () => {
|
||||
assert.ok(typeof model === 'string' && model.length > 0);
|
||||
});
|
||||
|
||||
// #2072 acceptance: these two catalog agents' config MUST resolve — the bug was
|
||||
// that the workflows never threaded the resolved value, not that the resolver
|
||||
// ignored it. These assert the value the (now-threaded) spawns receive.
|
||||
test('#2072: model_overrides applies to gsd-code-reviewer', () => {
|
||||
writeConfig(tmpDir, { model_overrides: { 'gsd-code-reviewer': 'my-custom-model' } });
|
||||
assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-code-reviewer'), 'my-custom-model');
|
||||
});
|
||||
|
||||
test('#2072: model_overrides applies to gsd-assumptions-analyzer', () => {
|
||||
writeConfig(tmpDir, { model_overrides: { 'gsd-assumptions-analyzer': 'my-custom-model' } });
|
||||
assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-assumptions-analyzer'), 'my-custom-model');
|
||||
});
|
||||
|
||||
test('#2072: models.verification tier applies to gsd-code-reviewer', () => {
|
||||
writeConfig(tmpDir, { models: { verification: 'opus' } });
|
||||
assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-code-reviewer'), 'opus');
|
||||
});
|
||||
|
||||
test('#2072: models.discuss tier applies to gsd-assumptions-analyzer', () => {
|
||||
writeConfig(tmpDir, { models: { discuss: 'opus' } });
|
||||
assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-assumptions-analyzer'), 'opus');
|
||||
});
|
||||
|
||||
test('#2072: model_overrides + models.execution apply to gsd-code-fixer', () => {
|
||||
writeConfig(tmpDir, { model_overrides: { 'gsd-code-fixer': 'my-custom-model' } });
|
||||
assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-code-fixer'), 'my-custom-model');
|
||||
writeConfig(tmpDir, { models: { execution: 'opus' } });
|
||||
assert.strictEqual(resolveModelInternal(tmpDir, 'gsd-code-fixer'), 'opus');
|
||||
});
|
||||
|
||||
test('runtime non-claude + model_profile_overrides for runtime tier', () => {
|
||||
writeConfig(tmpDir, {
|
||||
runtime: 'codex',
|
||||
|
||||
150
tests/model-routing-spawn-threading.test.cjs
Normal file
150
tests/model-routing-spawn-threading.test.cjs
Normal file
@@ -0,0 +1,150 @@
|
||||
// allow-test-rule: source-text-is-the-product #2072
|
||||
// Workflow .md files ARE the deployed orchestration contract the runtime executes;
|
||||
// asserting that a spawn threads a resolved model= is asserting the deployed contract.
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* #2072 — model_overrides / models.<phaseType> were silently inert for
|
||||
* gsd-assumptions-analyzer and gsd-code-reviewer on Claude: the resolver honored
|
||||
* them, but the workflows spawned the agents with NO model= param, so the resolved
|
||||
* value never reached the Agent tool and the agents inherited the session model.
|
||||
*
|
||||
* Fix contract: every spawn of these two catalog agents must thread a resolved
|
||||
* model=, and the workflow must obtain that model (inline `resolve-model` for the
|
||||
* single-agent workflows, or the `reviewer_model` field of the init.quick bundle).
|
||||
*/
|
||||
|
||||
const { test, describe } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const WF = path.join(__dirname, '..', 'gsd-core', 'workflows');
|
||||
const read = (rel) => fs.readFileSync(path.join(WF, rel), 'utf-8');
|
||||
|
||||
// Every .md under gsd-core/workflows (incl. nested steps/ and modes/).
|
||||
function allWorkflowMd() {
|
||||
const out = [];
|
||||
(function walk(dir, rel) {
|
||||
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
if (e.isDirectory()) walk(path.join(dir, e.name), path.join(rel, e.name));
|
||||
else if (e.name.endsWith('.md')) out.push(path.join(rel, e.name));
|
||||
}
|
||||
})(WF, '');
|
||||
return out;
|
||||
}
|
||||
|
||||
// Return the full text of every `Agent( … )` call in `content`, tracking string
|
||||
// state (triple- and single-double-quoted) and paren depth so a prompt body's own
|
||||
// parens/quotes don't end the call early. Order-independent: a call's params are
|
||||
// captured whether subagent_type= appears before or after the prompt.
|
||||
function agentCalls(content) {
|
||||
const calls = [];
|
||||
const re = /Agent\(/g;
|
||||
let m;
|
||||
while ((m = re.exec(content)) !== null) {
|
||||
let i = m.index + m[0].length;
|
||||
let depth = 1;
|
||||
let tq = false; // inside """ … """
|
||||
let sq = false; // inside " … "
|
||||
while (i < content.length && depth > 0) {
|
||||
if (tq) {
|
||||
if (content.startsWith('"""', i)) { tq = false; i += 3; continue; }
|
||||
i++; continue;
|
||||
}
|
||||
if (sq) {
|
||||
if (content[i] === '\\') { i += 2; continue; }
|
||||
if (content[i] === '"') { sq = false; }
|
||||
i++; continue;
|
||||
}
|
||||
if (content.startsWith('"""', i)) { tq = true; i += 3; continue; }
|
||||
if (content[i] === '"') { sq = true; i++; continue; }
|
||||
if (content[i] === '(') { depth++; }
|
||||
else if (content[i] === ')') { depth--; }
|
||||
i++;
|
||||
}
|
||||
calls.push(content.slice(m.index, i));
|
||||
re.lastIndex = i; // don't re-scan inside this call
|
||||
}
|
||||
return calls;
|
||||
}
|
||||
|
||||
describe('#2072: routed-agent spawns thread the resolved model', () => {
|
||||
test('discuss-phase-assumptions.md resolves + threads gsd-assumptions-analyzer model', () => {
|
||||
const c = read('discuss-phase-assumptions.md');
|
||||
assert.match(c, /resolve-model gsd-assumptions-analyzer/, 'must resolve the routed model');
|
||||
assert.match(
|
||||
c,
|
||||
/subagent_type="gsd-assumptions-analyzer",\s*model="\{ANALYZER_MODEL\}"/,
|
||||
'spawn must thread the resolved model=',
|
||||
);
|
||||
});
|
||||
|
||||
test('code-review.md resolves + threads gsd-code-reviewer model', () => {
|
||||
const c = read('code-review.md');
|
||||
assert.match(c, /resolve-model gsd-code-reviewer/);
|
||||
assert.match(c, /subagent_type="gsd-code-reviewer",\s*model="\{REVIEWER_MODEL\}"/);
|
||||
});
|
||||
|
||||
test('code-review-fix.md re-review resolves + threads gsd-code-reviewer model', () => {
|
||||
const c = read('code-review-fix.md');
|
||||
assert.match(c, /resolve-model gsd-code-reviewer/);
|
||||
assert.match(c, /subagent_type="gsd-code-reviewer",\s*model="\{REVIEWER_MODEL\}"/);
|
||||
});
|
||||
|
||||
test('quick.md review step threads gsd-code-reviewer own model (not executor_model)', () => {
|
||||
const c = read('quick.md');
|
||||
// reviewer_model comes from the init.quick bundle; the spawn must use it.
|
||||
assert.match(c, /subagent_type="gsd-code-reviewer",\s*\n\s*model="\{reviewer_model\}"/);
|
||||
assert.doesNotMatch(
|
||||
c,
|
||||
/subagent_type="gsd-code-reviewer",\s*\n\s*model="\{executor_model\}"/,
|
||||
'reviewer must not reuse the executor model (own model_overrides would be ignored)',
|
||||
);
|
||||
});
|
||||
|
||||
test('code-review-fix.md threads gsd-code-fixer model at both fixer spawns', () => {
|
||||
const c = read('code-review-fix.md');
|
||||
assert.match(c, /resolve-model gsd-code-fixer/, 'must resolve the fixer model');
|
||||
const fixerSpawns = c.match(/subagent_type="gsd-code-fixer", model="\{FIXER_MODEL\}"/g) || [];
|
||||
assert.strictEqual(fixerSpawns.length, 2, 'both gsd-code-fixer spawns must thread FIXER_MODEL');
|
||||
});
|
||||
|
||||
// Parity guard: EVERY spawn of the fixed routed agents across ALL workflows must
|
||||
// carry a model= in its Agent(...) call, so a new silently-inert spawn cannot
|
||||
// regress. Uses a quote/paren-aware scan of the WHOLE Agent(...) call, so it holds
|
||||
// for single-line and multi-line calls, multiple spawns per file, and either param
|
||||
// ordering (subagent_type= before OR after the prompt body).
|
||||
test('no spawn of the fixed routed agents is missing a model= (parity guard)', () => {
|
||||
const ROUTED = /subagent_type="(gsd-code-reviewer|gsd-assumptions-analyzer|gsd-code-fixer)"/;
|
||||
const offenders = [];
|
||||
for (const rel of allWorkflowMd()) {
|
||||
for (const call of agentCalls(read(rel))) {
|
||||
const routed = call.match(ROUTED);
|
||||
if (routed && !/\bmodel\s*=/.test(call)) {
|
||||
offenders.push(`${rel}: ${routed[1]} spawn missing model=`);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.deepEqual(offenders, [], `routed-agent spawn(s) missing model=:\n${offenders.join('\n')}`);
|
||||
});
|
||||
|
||||
// The scanner itself must catch a prompt-first, un-threaded spawn (the exact blind
|
||||
// spot a naive "params before prompt=" heuristic misses) — otherwise the guard
|
||||
// above could pass vacuously.
|
||||
test('parity guard detects a prompt-first spawn that omits model=', () => {
|
||||
const synthetic = [
|
||||
'Agent(',
|
||||
' prompt="""do the thing (with parens) and a " quote""",',
|
||||
' subagent_type="gsd-code-reviewer"',
|
||||
')',
|
||||
].join('\n');
|
||||
const [call] = agentCalls(synthetic);
|
||||
assert.ok(/subagent_type="gsd-code-reviewer"/.test(call), 'scanner must capture the prompt-first subagent_type');
|
||||
assert.ok(!/\bmodel\s*=/.test(call), 'and correctly see that model= is absent');
|
||||
// A well-formed prompt-first spawn WITH model= must be accepted.
|
||||
const ok = agentCalls(synthetic.replace(')', ' model="{reviewer_model}"\n)'))[0];
|
||||
assert.ok(/\bmodel\s*=/.test(ok));
|
||||
});
|
||||
});
|
||||
@@ -246,6 +246,7 @@ describe('plan:pre all-off — empty resolution', () => {
|
||||
tmpDir = makeProject({
|
||||
workflow: {
|
||||
ai_integration_phase: false,
|
||||
api_coverage_gate: false,
|
||||
tdd_mode: false,
|
||||
security_enforcement: false,
|
||||
ui_phase: false,
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
"autonomous.md": 42474,
|
||||
"check-todos.md": 9475,
|
||||
"cleanup.md": 9941,
|
||||
"code-review-fix.md": 23934,
|
||||
"code-review.md": 31646,
|
||||
"code-review-fix.md": 24320,
|
||||
"code-review.md": 31916,
|
||||
"complete-milestone.md": 31071,
|
||||
"debug.md": 13549,
|
||||
"diagnose-issues.md": 12864,
|
||||
"discovery-phase.md": 8651,
|
||||
"discuss-phase-assumptions.md": 27028,
|
||||
"discuss-phase-assumptions.md": 27302,
|
||||
"discuss-phase-power.md": 11273,
|
||||
"discuss-phase.md": 31986,
|
||||
"do.md": 10353,
|
||||
@@ -59,7 +59,7 @@
|
||||
"pr-branch.md": 15963,
|
||||
"profile-user.md": 21246,
|
||||
"progress.md": 30599,
|
||||
"quick.md": 50452,
|
||||
"quick.md": 50470,
|
||||
"reapply-patches.md": 20312,
|
||||
"remove-phase.md": 8513,
|
||||
"remove-workspace.md": 7551,
|
||||
@@ -89,5 +89,5 @@
|
||||
"update.md": 20914,
|
||||
"validate-phase.md": 10789,
|
||||
"verify-phase.md": 40923,
|
||||
"verify-work.md": 38267
|
||||
"verify-work.md": 40247
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user