chore(#3421): delete orphan verify-phase workflow, migrate live gates to verifier (#3422)

* chore(#1892): delete orphan verify-phase workflow, migrate live gates to verifier reference

* test(#1892): retarget structural suites from verify-phase.md to verifier-phase-gates.md

* chore(#1892): reword retired-workflow mentions for removed-but-needed lint

* test(#1892): correct stale surface labels in retargeted suites

* docs(#1892): add verifier-phase-gates row to locale inventories

* chore(#3421): backfill changeset pr number

---------

Co-authored-by: sim <sim@local>
This commit is contained in:
Tom Boucher
2026-08-13 21:22:03 -04:00
committed by GitHub
parent b77b7f8e56
commit d30c99bc92
52 changed files with 313 additions and 752 deletions

View File

@@ -1,6 +1,6 @@
{
"version": 1,
"paths": {
"gsd-verifier.md": "#1955: Step 3 gains sub-step 5c (the coincidental-reliance advisory), one Step 9 score bullet, one Observable Truths example row, and the coincidental_reliance_items frontmatter block. Growth is those four additions only — no existing text was rewritten. Deliberately dense rather than extracted: the issue's approved scope says 'No new files', and ADR-1610 Decision 4 / tests/workflow-size-budget.test.cjs:32-40 name eager @-import relocation as gaming the size proxy (it shrinks the measured file while total loaded context is unchanged or larger); this agent has no lazy-read seam. After the change the file sits at 48994 bytes against the LARGE tier hard cap of 49152 (tests/agent-size-budget.test.cjs), i.e. 158 bytes of headroom. That is deliberate and disclosed: the cap is not crossed and is not raised, but the next contributor who needs room in this agent must do a lazy extraction rather than add prose. Content justification: the verifier's goal-backward pass grades THAT a truth holds and never WHY, so a truth can read VERIFIED while resting on a coincidence — a precondition nothing guarantees, an ordering nothing enforces, or a fixture-only truth. 5c classifies the evidence already recorded rather than asking for a confidence rating, but it is honestly an endogenous check and so weaker than the exogenous backstop tag gsd-core/references/honest-verifier.md routes on — which is exactly why it is advisory only: it changes no score, no status, and emits no human-verification item, so a passing phase still passes. gsd-core/workflows/verify-phase.md is deliberately NOT edited (it has 29 bytes under its DEFAULT tier cap); it receives the rule through its existing eager @-import of gsd-core/templates/verification-report.md, whose Guidelines now carry the imperative check rather than only the row shape. tests/verifier-coincidental-reliance.test.cjs asserts both halves of that route and locks out a silent second copy appearing in the workflow."
"gsd-verifier.md": "#1955: Step 3 gains sub-step 5c (the coincidental-reliance advisory), one Step 9 score bullet, one Observable Truths example row, and the coincidental_reliance_items frontmatter block. Growth is those four additions only — no existing text was rewritten. Deliberately dense rather than extracted: the issue's approved scope says 'No new files', and ADR-1610 Decision 4 / tests/workflow-size-budget.test.cjs:32-40 name eager @-import relocation as gaming the size proxy (it shrinks the measured file while total loaded context is unchanged or larger); this agent has no lazy-read seam. After the change the file sits at 48994 bytes against the LARGE tier hard cap of 49152 (tests/agent-size-budget.test.cjs), i.e. 158 bytes of headroom. That is deliberate and disclosed: the cap is not crossed and is not raised, but the next contributor who needs room in this agent must do a lazy extraction rather than add prose. Content justification: the verifier's goal-backward pass grades THAT a truth holds and never WHY, so a truth can read VERIFIED while resting on a coincidence — a precondition nothing guarantees, an ordering nothing enforces, or a fixture-only truth. 5c classifies the evidence already recorded rather than asking it to rate its own confidence — but it is honestly an endogenous check and so weaker than the exogenous backstop tag gsd-core/references/honest-verifier.md routes on — which is exactly why it is advisory only: it changes no score, no status, and emits no human-verification item, so a passing phase still passes. gsd-core/workflows/verify-phase.md is deliberately NOT edited (it has 29 bytes under its DEFAULT tier cap); it receives the rule through its existing eager @-import of gsd-core/templates/verification-report.md, whose Guidelines now carry the imperative check rather than only the row shape. tests/verifier-coincidental-reliance.test.cjs asserts both halves of that route and locks out a silent second copy appearing in the workflow. — #1892 append (epic #1891 F7, merged into this fragment because two ack sources may never name the same path): +55 bytes, one required_reading line (@~/.claude/gsd-core/references/verifier-phase-gates.md) so the verifier eagerly loads the three verification-time gates migrated out of the now-DELETED orphan workflow gsd-core/workflows/verify-phase.md (decision-coverage validation #2492, test-quality audit, infrastructure-phase human-verification scoping #2504) — the #1955-era routing through that workflow's template import retired with it. Net loaded context shrinks ~30 KB (40,931-byte orphan stops shipping and loading, replaced by a 9,951-byte reference plus this line); not proxy-gaming per ADR-1610 D4 — no existing prose was relocated out of the measured file, live behavior that previously reached no runtime is restored. Agent sits at 49,049 of 49,152 bytes (103 bytes of headroom), cap unchanged."
}
}

View File

@@ -82,7 +82,7 @@ describe('execute-phase command: active flags are explicit', () => {
* Regression test for #2396: hardcoded host-level test commands bypass
* container-only project Makefiles.
*
* Fix: execute-phase.md, verify-phase.md, and audit-fix.md must check for
* Fix: execute-phase.md and audit-fix.md must check for
* Makefile with a test target (and other wrappers) before falling through
* to hardcoded language-sniffed commands.
*/
@@ -95,7 +95,6 @@ const fs = require('fs');
const path = require('path');
const EXECUTE_PHASE_PATH = path.join(__dirname, '..', 'gsd-core', 'workflows', 'execute-phase.md');
const VERIFY_PHASE_PATH = path.join(__dirname, '..', 'gsd-core', 'workflows', 'verify-phase.md');
const AUDIT_FIX_PATH = path.join(__dirname, '..', 'gsd-core', 'workflows', 'audit-fix.md');
// #1857: execute-phase's regression-gate test-command resolution was extracted
// to this step file (execute-phase.md is size-frozen — phase-6 capstone).
@@ -164,10 +163,6 @@ describe('bug-2396: Makefile test target must take priority over hardcoded comma
assert.ok(fs.existsSync(EXECUTE_PHASE_PATH), 'execute-phase.md should exist');
});
test('verify-phase.md exists', () => {
assert.ok(fs.existsSync(VERIFY_PHASE_PATH), 'verify-phase.md should exist');
});
test('audit-fix.md exists', () => {
assert.ok(fs.existsSync(AUDIT_FIX_PATH), 'audit-fix.md should exist');
});
@@ -176,10 +171,6 @@ describe('bug-2396: Makefile test target must take priority over hardcoded comma
assertMakefileCheckBeforeNpmTest(REGRESSION_GATE_PATH, 'regression-gate.md');
});
test('verify-phase.md: Makefile check precedes npm test', () => {
assertMakefileCheckBeforeNpmTest(VERIFY_PHASE_PATH, 'verify-phase.md');
});
test('audit-fix.md: Makefile check precedes npm test', () => {
assertMakefileCheckBeforeNpmTest(AUDIT_FIX_PATH, 'audit-fix.md');
});
@@ -188,10 +179,6 @@ describe('bug-2396: Makefile test target must take priority over hardcoded comma
assertConfigGetBeforeMakefile(REGRESSION_GATE_PATH, 'regression-gate.md');
});
test('verify-phase.md: workflow.test_command config checked first (within bash block)', () => {
assertConfigGetBeforeMakefile(VERIFY_PHASE_PATH, 'verify-phase.md');
});
test('audit-fix.md: workflow.test_command config checked first (within bash block)', () => {
assertConfigGetBeforeMakefile(AUDIT_FIX_PATH, 'audit-fix.md');
});

View File

@@ -163,6 +163,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -366,7 +367,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -234,6 +234,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -437,7 +438,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -233,6 +233,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -436,7 +437,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -162,6 +162,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -365,7 +366,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -166,6 +166,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -369,7 +370,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -234,6 +234,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -437,7 +438,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -269,6 +269,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -472,7 +473,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -164,6 +164,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -367,7 +368,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -163,6 +163,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -366,7 +367,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -163,6 +163,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -366,7 +367,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -234,6 +234,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -437,7 +438,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -195,6 +195,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -398,7 +399,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -231,6 +231,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -434,7 +435,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -234,6 +234,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -437,7 +438,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -131,6 +131,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -334,7 +335,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -163,6 +163,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -366,7 +367,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -163,6 +163,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -366,7 +367,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -163,6 +163,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -366,7 +367,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -234,6 +234,7 @@
"gsd-core/references/user-story-template.md",
"gsd-core/references/verification-overrides.md",
"gsd-core/references/verification-patterns.md",
"gsd-core/references/verifier-phase-gates.md",
"gsd-core/references/verifier-wiring-patterns.md",
"gsd-core/references/verify-mvp-mode.md",
"gsd-core/references/workstream-flag.md",
@@ -437,7 +438,6 @@
"gsd-core/workflows/update.md",
"gsd-core/workflows/update/steps/channel-banner.md",
"gsd-core/workflows/validate-phase.md",
"gsd-core/workflows/verify-phase.md",
"gsd-core/workflows/verify-work.md",
"gsd-core/workflows/verify-work/steps/automated-ui-verification.md",
"gsd-core/workflows/verify-work/steps/mvp-uat-framing.md",

View File

@@ -1589,7 +1589,7 @@ describe('enh-2430 — INVENTORY sync', () => {
/**
* Bug #2492: Add gates to ensure discuss-phase decisions are translated to
* plans (plan-phase, BLOCKING) and verified against shipped artifacts
* (verify-phase, NON-BLOCKING).
* (verifier-phase-gates reference, NON-BLOCKING).
*
* These workflow files are loaded as prompts by the corresponding subagents.
* The tests below verify that the prompt text contains the gate steps and
@@ -1603,7 +1603,7 @@ const fs = require('fs');
const path = require('path');
const PLAN_PHASE = path.join(__dirname, '..', 'gsd-core', 'workflows', 'plan-phase.md');
const VERIFY_PHASE = path.join(__dirname, '..', 'gsd-core', 'workflows', 'verify-phase.md');
const VERIFY_GATES = path.join(__dirname, '..', 'gsd-core', 'references', 'verifier-phase-gates.md');
const SCHEMA_MANIFEST_JSON = path.join(__dirname, '..', 'gsd-core', 'bin', 'shared', 'config-schema.manifest.json');
describe('plan-phase decision-coverage gate (#2492)', () => {
@@ -1700,20 +1700,20 @@ describe('plan-phase decision-coverage gate (#2492)', () => {
});
});
describe('verify-phase decision-coverage gate (#2492)', () => {
const md = fs.readFileSync(VERIFY_PHASE, 'utf-8');
describe('verifier-phase-gates decision-coverage gate (#2492)', () => {
const md = fs.readFileSync(VERIFY_GATES, 'utf-8');
test('contains a verify_decisions step', () => {
assert.ok(
/verify_decisions/.test(md),
'verify-phase.md must define a verify_decisions step',
'verifier-phase-gates.md must define a verify_decisions step',
);
});
test('invokes the check.decision-coverage-verify handler', () => {
assert.ok(
md.includes('check.decision-coverage-verify'),
'verify-phase.md must call gsd-sdk query check.decision-coverage-verify',
'verifier-phase-gates.md must call gsd-sdk query check.decision-coverage-verify',
);
});
@@ -1721,14 +1721,14 @@ describe('verify-phase decision-coverage gate (#2492)', () => {
const lower = md.toLowerCase();
assert.ok(
lower.includes('non-blocking') || lower.includes('warning only') || lower.includes('not block'),
'verify-phase.md must declare the decision gate is non-blocking',
'verifier-phase-gates.md must declare the decision gate is non-blocking',
);
});
test('mentions workflow.context_coverage_gate skip clause', () => {
assert.ok(
md.includes('workflow.context_coverage_gate'),
'verify-phase.md must reference workflow.context_coverage_gate to allow skipping',
'verifier-phase-gates.md must reference workflow.context_coverage_gate to allow skipping',
);
});
});
@@ -1741,6 +1741,21 @@ describe('runtime wiring for #2492 gates', () => {
'workflow.context_coverage_gate must be present in config-schema manifest',
);
});
test('gsd-verifier eagerly imports verifier-phase-gates.md (#1892)', () => {
// The decision-coverage gate (and the other migrated verify-time gates) only
// reach the runtime if the verifier agent actually loads the reference that
// now carries them — a reference nothing imports is the exact orphan class
// epic #1891 exists to remove.
const agent = fs.readFileSync(
path.join(__dirname, '..', 'agents', 'gsd-verifier.md'),
'utf-8',
);
assert.ok(
agent.includes('@~/.claude/gsd-core/references/verifier-phase-gates.md'),
'agents/gsd-verifier.md must @-import references/verifier-phase-gates.md in required_reading',
);
});
});
});
}

View File

@@ -124,8 +124,6 @@ const ALLOWLIST = {
'fast.md': ['time_sizing'],
// Execute-phase uses a configurable test-gate timeout (workflow.test_gate_timeout, #1857)
'execute-phase.md': ['time_sizing'],
// Verify-phase uses a configurable test-gate timeout (workflow.test_gate_timeout, #1857)
'verify-phase.md': ['time_sizing'],
// Map-codebase documents subagent_timeout
'map-codebase.md': ['time_sizing'],
// Help documents CodeRabbit timing

View File

@@ -8,7 +8,7 @@
// (resolution: null; the checkable content is `statement`). The prior config required a
// non-empty `resolution` and threw on 100% of the fixtures.
// WR-01 — dispositionForProhibition must NEVER return a silent green for a judgment-tier item,
// regardless of enforcement evidence (ADR-550 D4 / verify-phase.md).
// regardless of enforcement evidence (ADR-550 D4 / gsd-verifier.md).
//
// Fixture-driven on purpose: the validators are exercised against the SAME expected.json files the
// docs-fixtures parity test pins, so the validator and the corpus can never silently diverge.

View File

@@ -12,9 +12,8 @@
* - surface a timeout (exit 124) with a watch-mode hint — the regression gate
* ABORTS, the others surface clearly (never silently ignored).
*
* verify-phase's gate was ALREADY bounded (a fixed `run-with-timeout 300`, not a hang), so
* it only needs the normalizer (so a watch runner exits fast) and keeps its own
* fixed 5-minute bound — asserted separately below.
* verify-phase's gate (a fourth, already-bounded surface) was deleted with its orphan
* workflow in #1892; the gates above are the complete live set.
*/
'use strict';
@@ -33,7 +32,6 @@ const REGRESSION_GATE = path.join(ROOT, 'gsd-core', 'workflows', 'execute-phase'
const REGRESSION_GATE_RUN = path.join(ROOT, 'gsd-core', 'workflows', 'execute-phase', 'steps', 'regression-gate-run.md');
const POST_MERGE_GATE = path.join(ROOT, 'gsd-core', 'workflows', 'execute-phase', 'steps', 'post-merge-gate.md');
const AUDIT_FIX = path.join(ROOT, 'gsd-core', 'workflows', 'audit-fix.md');
const VERIFY_PHASE = path.join(ROOT, 'gsd-core', 'workflows', 'verify-phase.md');
const EXECUTE_PHASE = path.join(ROOT, 'gsd-core', 'workflows', 'execute-phase.md');
function read(p) { return fs.readFileSync(p, 'utf-8'); }
@@ -66,18 +64,7 @@ describe('#1857: test gates normalize to one-shot and bound with a timeout', ()
});
}
// verify-phase is already bounded (fixed `run-with-timeout 300`, not a hang); it only
// needs the normalizer so a watch runner exits fast, and names watch mode on 124.
describe('verify-phase gate (already bounded — normalize-only)', () => {
test('routes the resolved command through the shared normalize-test-command helper', () => {
assert.match(read(VERIFY_PHASE), /normalize-test-command/, 'verify-phase must call the shared normalize-test-command helper');
});
test('surfaces its fixed timeout (exit 124) naming watch/dev mode', () => {
const c = read(VERIFY_PHASE);
assert.match(c, /-eq 124/, 'verify-phase must handle the timeout exit code (124)');
assert.match(c, /watch\/dev mode/, 'verify-phase must name watch/dev mode as the likely cause on timeout');
});
});
// verify-phase's normalize-only block was removed with the orphan workflow (#1892).
test('the regression gate ABORTS (halts) on a watch-mode timeout', () => {
const c = read(REGRESSION_GATE);
@@ -92,7 +79,7 @@ describe('#1857: test gates normalize to one-shot and bound with a timeout', ()
test('the gates share ONE normalizer — the helper is a single source of truth', () => {
// The behaviour lives in src/normalize-test-command.cts; every gate invokes it
// by the same verb name, so a change to watch-defeat logic touches one place.
for (const file of [REGRESSION_GATE_RUN, POST_MERGE_GATE, AUDIT_FIX, VERIFY_PHASE]) {
for (const file of [REGRESSION_GATE_RUN, POST_MERGE_GATE, AUDIT_FIX]) {
assert.match(read(file), /gsd_run query normalize-test-command/);
}
});
@@ -107,8 +94,9 @@ describe('#1857: test gates normalize to one-shot and bound with a timeout', ()
// first build file). Every gate that resolves a build/test command this way MUST
// pass `--raw` so an unset key is a genuinely empty bash string the `-z` guard
// catches. This is a defect CLASS — post-merge-gate.md was the reported instance,
// but regression-gate.md, verify-phase.md, and audit-fix.md shared it, so the
// guard sweeps all of them (a single-file check gave false confidence). config-get's
// but regression-gate.md and audit-fix.md shared it, so the guard sweeps them (a
// single-file check gave false confidence; the fourth original member,
// verify-phase.md, was deleted as an orphan in #1892). config-get's
// own `--raw` behaviour is covered in config-get-default.test.cjs.
describe('#2350: every gate resolves build/test commands with --raw', () => {
// Each gate file that reads workflow.build_command / workflow.test_command to
@@ -116,7 +104,6 @@ describe('#2350: every gate resolves build/test commands with --raw', () => {
const GATE_FILES = [
['post-merge gate', POST_MERGE_GATE],
['regression gate', REGRESSION_GATE_RUN],
['verify-phase gate', VERIFY_PHASE],
['audit-fix gate', AUDIT_FIX],
];

View File

@@ -98,10 +98,10 @@ test('VERIFICATION.md templates carry behavior_unverified + the new truth-state'
assert.match(standalone, /behavior_unverified_items/);
});
const verifyPhase = fs.readFileSync(path.join(ROOT, 'gsd-core', 'workflows', 'verify-phase.md'), 'utf-8');
const verifyPhase = fs.readFileSync(path.join(ROOT, 'gsd-core', 'references', 'verifier-phase-gates.md'), 'utf-8');
const planningArtifacts = fs.readFileSync(path.join(ROOT, 'docs', 'reference', 'planning-artifacts.md'), 'utf-8');
test('shipped verify-phase workflow mirrors the behavior-unverified calibration', () => {
test('shipped verifier-phase-gates reference mirrors the behavior-unverified calibration', () => {
assert.match(verifyPhase, /PRESENT_BEHAVIOR_UNVERIFIED/);
assert.match(verifyPhase, /behavior_unverified/);
assert.match(verifyPhase, /state transition/i);

View File

@@ -51,7 +51,7 @@ const read = (...p) => fs.readFileSync(path.join(ROOT, ...p), 'utf-8');
const verifier = read('agents', 'gsd-verifier.md');
const template = read('gsd-core', 'templates', 'verification-report.md');
const agentsDoc = read('docs', 'AGENTS.md');
const verifyPhase = read('gsd-core', 'workflows', 'verify-phase.md');
const verifyPhase = read('gsd-core', 'references', 'verifier-phase-gates.md');
const QUALIFIER = '✓ VERIFIED (coincidental-reliance)';
const REASONS = ['undeclared-precondition', 'incidental-ordering', 'fixture-only'];
@@ -225,7 +225,7 @@ describe('#1955: coincidental-reliance advisory — the report surface', () => {
});
});
describe('#1955: cross-surface parity (agent, template, verify-phase workflow)', () => {
describe('#1955: cross-surface parity (agent, template, verifier gate reference)', () => {
test('PARITY: agent and standalone template agree on the advisory vocabulary', () => {
// Generative-fix-divergence gate: two surfaces render the same report, so a
// token added to one and not the other is the defect this test exists for.
@@ -245,20 +245,19 @@ describe('#1955: cross-surface parity (agent, template, verify-phase workflow)',
assert.match(guidelines, /coincidental-reliance/);
});
test('verify-phase workflow reaches the rule through its eager template import', () => {
// The third surface. `gsd-core/workflows/verify-phase.md` is the
// non-subagent verification path and reimplements the truth rubric inline,
// but it sits 29 bytes under the DEFAULT tier hard cap in
// tests/workflow-size-budget.test.cjs, so the rule is NOT duplicated into
// it. It reaches the rule instead through the eager `@`-import of the
// template, whose Guidelines carry the instruction — not merely the output
// shape. Both halves of that claim are asserted here, because either one
// silently failing turns the workflow surface into an undetected
// divergence.
test('verifier gate reference reaches the rule through the canonical template', () => {
// The third surface. `gsd-core/references/verifier-phase-gates.md` is the
// verifier agent's eagerly-imported gate reference (migrated from the
// retired workflows/verify-phase.md in #1892). It does NOT reimplement the
// truth rubric — the rule is NOT duplicated into it. It reaches the rule
// instead through its pointer to the canonical report template, whose
// Guidelines carry the instruction — not merely the output shape. Both
// halves of that claim are asserted here, because either one silently
// failing turns the reference surface into an undetected divergence.
assert.match(
verifyPhase,
/@[^\n]*gsd-core\/templates\/verification-report\.md/,
'verify-phase.md must eagerly import the verification-report template',
'verifier-phase-gates.md must point at the verification-report template',
);
const guidelines = template.slice(template.indexOf('**Per-truth states'));
assert.match(
@@ -269,16 +268,16 @@ describe('#1955: cross-surface parity (agent, template, verify-phase workflow)',
});
test('the workflow surface carries no divergent copy of the rule', () => {
// Characterization, not aspiration: verify-phase.md deliberately holds NO
// copy of the detection prose today. If a future change adds one, this
// assertion fails and forces a decision — duplicate it deliberately and
// update this test, or keep the single template-carried source. Silent
// partial duplication across the two surfaces is the failure mode
// Characterization, not aspiration: verifier-phase-gates.md deliberately
// holds NO copy of the detection prose today. If a future change adds one,
// this assertion fails and forces a decision — duplicate it deliberately
// and update this test, or keep the single template-carried source. Silent
// partial duplication across the surfaces is the failure mode
// (generative fix divergence) this locks out.
assert.doesNotMatch(
verifyPhase,
/coincidental-reliance/,
'verify-phase.md must not grow a second copy of the rule without a deliberate decision',
'verifier-phase-gates.md must not grow a second copy of the rule without a deliberate decision',
);
});

View File

@@ -112,43 +112,10 @@ describe('verifier deferred-items filtering (#1624)', () => {
});
});
// ── verify-phase.md (workflow) ─────────────────────────────────────────────
describe('gsd-core/workflows/verify-phase.md', () => {
const workflowPath = path.join(ROOT, 'gsd-core', 'workflows', 'verify-phase.md');
let workflowContent;
test('file exists', () => {
assert.ok(fs.existsSync(workflowPath), 'verify-phase.md should exist');
workflowContent = fs.readFileSync(workflowPath, 'utf-8');
});
test('loads roadmap analyze in context step', () => {
workflowContent = workflowContent || fs.readFileSync(workflowPath, 'utf-8');
assert.ok(
workflowContent.includes('roadmap analyze'),
'verify-phase.md should load roadmap analyze in its context step'
);
});
test('contains filter_deferred_items step', () => {
workflowContent = workflowContent || fs.readFileSync(workflowPath, 'utf-8');
assert.ok(
workflowContent.includes('filter_deferred_items') ||
workflowContent.includes('Filter Deferred'),
'verify-phase.md should contain a deferred-item filtering step'
);
});
test('success criteria mentions deferred filtering', () => {
workflowContent = workflowContent || fs.readFileSync(workflowPath, 'utf-8');
assert.ok(
workflowContent.includes('Deferred items filtered') ||
workflowContent.includes('deferred items filtered'),
'success criteria should mention deferred item filtering'
);
});
});
// ── verify-phase.md (workflow) — DELETED #1892 ─────────────────────────────
// The orphan workflow gsd-core/workflows/verify-phase.md was removed (0 loaders;
// live deferred-item filtering is carried by gsd-verifier.md Step 9b, asserted
// in the describe block above).
// sdk/prompts/workflows/verify-phase.md removed in 377a6d2 — SDK loads installed workflow directly.

View File

@@ -90,7 +90,7 @@ describe('verify-work — MVP mode UAT framing', () => {
* "manually invoke methods", "manually check database state" — and left
* work half-finished specifically to create things for a human to do.
*
* Fix: The verify-phase workflow's identify_human_verification step must
* Fix: The verifier reference's identify_human_verification step must
* explicitly handle phases with no user-facing elements by auto-passing UAT
* with a logged rationale instead of inventing manual steps.
*/
@@ -103,7 +103,7 @@ const fs = require('fs');
const path = require('path');
const VERIFY_PHASE_PATH = path.join(
__dirname, '..', 'gsd-core', 'workflows', 'verify-phase.md'
__dirname, '..', 'gsd-core', 'references', 'verifier-phase-gates.md'
);
/**
@@ -119,10 +119,10 @@ function extractSection(content, heading) {
}
describe('bug #2504: UAT auto-pass for foundation/infrastructure phases', () => {
test('verify-phase workflow file exists', () => {
test('verifier-phase-gates reference file exists', () => {
assert.ok(
fs.existsSync(VERIFY_PHASE_PATH),
'gsd-core/workflows/verify-phase.md should exist'
'gsd-core/references/verifier-phase-gates.md should exist'
);
});
@@ -142,7 +142,7 @@ describe('bug #2504: UAT auto-pass for foundation/infrastructure phases', () =>
assert.ok(
hasInfrastructureHandling,
'verify-phase.md identify_human_verification step must explicitly handle ' +
'verifier-phase-gates.md identify_human_verification step must explicitly handle ' +
'infrastructure/foundation phases that have no user-facing elements. Without ' +
'this, agents invent artificial manual steps to satisfy UAT requirements ' +
'(root cause of #2504).'
@@ -164,7 +164,7 @@ describe('bug #2504: UAT auto-pass for foundation/infrastructure phases', () =>
assert.ok(
hasAutoPass,
'verify-phase.md identify_human_verification step must contain language about ' +
'verifier-phase-gates.md identify_human_verification step must contain language about ' +
'auto-passing or skipping UAT for phases without user-facing elements. Agents ' +
'must not invent manual steps when there is nothing user-facing to test ' +
'(root cause of #2504).'
@@ -196,7 +196,7 @@ describe('bug #2504: UAT auto-pass for foundation/infrastructure phases', () =>
assert.ok(
hasProhibition,
'verify-phase.md identify_human_verification step must explicitly prohibit ' +
'verifier-phase-gates.md identify_human_verification step must explicitly prohibit ' +
'inventing artificial manual UAT steps for infrastructure phases. The current ' +
'wording causes agents to create fake "manually run git commits" steps to ' +
'satisfy UAT mandates (root cause of #2504).'
@@ -217,7 +217,7 @@ describe('bug #2504: UAT auto-pass for foundation/infrastructure phases', () =>
assert.ok(
hasNaState,
'verify-phase.md identify_human_verification step must include some concept of ' +
'verifier-phase-gates.md identify_human_verification step must include some concept of ' +
'a "not applicable" or N/A UAT state for phases with no user-facing elements. ' +
'This prevents agents from blocking phase completion on invented manual steps ' +
'(root cause of #2504).'

View File

@@ -1,8 +1,11 @@
// allow-test-rule: source-text-is-the-product
// Structural guard: reads gsd-core/workflows/verify-phase.md and asserts that
// the audit_test_quality step contains the skip-pattern marker, circular-detection
// marker, provenance-classification contract, and assertion-strength table markers.
// Goes red if that workflow guidance is removed or the step is renamed/deleted.
// Structural guard: reads gsd-core/references/verifier-phase-gates.md (the
// gsd-verifier agent's eagerly-imported gate reference; its content was
// migrated from the retired workflows/verify-phase.md orphan in #1892) and
// asserts that the audit_test_quality step contains the skip-pattern marker,
// circular-detection marker, provenance-classification contract, and
// assertion-strength table markers.
// Goes red if that guidance is removed or the step is renamed/deleted.
'use strict';
@@ -15,8 +18,8 @@ const WORKFLOW_PATH = path.join(
__dirname,
'..',
'gsd-core',
'workflows',
'verify-phase.md'
'references',
'verifier-phase-gates.md'
);
// Locate the audit_test_quality step boundaries so sub-assertions are scoped
@@ -33,7 +36,7 @@ function extractAuditStep(src) {
}
// workflowSrc and auditStepSrc are populated in the before() hook so that a
// missing or renamed verify-phase.md produces a descriptive test FAILURE rather
// missing or renamed verifier-phase-gates.md produces a descriptive test FAILURE rather
// than a module-load crash that prevents any test from registering.
let workflowSrc = null;
let auditStepSrc = null;
@@ -41,22 +44,22 @@ let auditStepSrc = null;
before(() => {
assert.ok(
fs.existsSync(WORKFLOW_PATH),
`verify-phase.md not found at expected path: ${WORKFLOW_PATH} — ` +
`verifier-phase-gates.md not found at expected path: ${WORKFLOW_PATH} — ` +
'the file may have been renamed or moved'
);
workflowSrc = fs.readFileSync(WORKFLOW_PATH, 'utf8');
auditStepSrc = extractAuditStep(workflowSrc);
});
describe('verify-phase.md audit_test_quality structural guard', () => {
test('verify-phase.md exists at gsd-core/workflows/verify-phase.md', () => {
describe('verifier-phase-gates.md audit_test_quality structural guard', () => {
test('verifier-phase-gates.md exists at gsd-core/references/verifier-phase-gates.md', () => {
assert.ok(
fs.existsSync(WORKFLOW_PATH),
`missing workflow file: ${WORKFLOW_PATH}`
);
});
test('audit_test_quality step is present in verify-phase.md', () => {
test('audit_test_quality step is present in verifier-phase-gates.md', () => {
assert.ok(
auditStepSrc !== null,
`<step name="audit_test_quality"> not found in ${WORKFLOW_PATH} — the step ` +

View File

@@ -90,7 +90,6 @@ describe('workflow shell robustness', () => {
'resume-project.md',
'progress.md',
'transition.md',
'verify-phase.md',
'verify-work.md',
'discuss-phase.md',
'plan-phase.md',

View File

@@ -91,14 +91,14 @@ const WORKFLOWS_DIR = path.join(__dirname, '..', 'gsd-core', 'workflows');
// headroom (vs the old GRACE=3000 hug):
// XL 96 KiB — high-water execute-phase.md 93,400 → ~4.8 KB headroom
// LARGE 60 KiB — high-water docs-update.md 55,468 → ~5.8 KB headroom
// DEFAULT 40 KiB — high-water verify-phase.md 40,931 → 29 BYTES headroom
// DEFAULT 40 KiB — high-water settings.md 40,352 → ~608 B headroom
// (DEFAULT is deliberately the tightest: a single-purpose workflow approaching
// 40 KiB is the strongest extraction signal of the three. verify-phase.md is
// effectively AT the red line — the next edit to it must be preceded by a lazy
// extraction, not absorbed. Measured 2026-08-09 via measureWorkflows(); the
// previous note here named settings-advanced.md at 39,160 with ~1.8 KB of
// headroom, which was stale on both the file and the number and invited an
// edit that would have crossed the cap.)
// 40 KiB is the strongest extraction signal of the three. The previous DEFAULT
// high-water, verify-phase.md at 40,931 (29 bytes of headroom), was deleted as
// an orphan in #1892 — 0 loaders, with its still-live gates migrated to
// gsd-core/references/verifier-phase-gates.md behind the gsd-verifier agent.
// Measured 2026-08-13 via measureWorkflows() after that deletion; the note
// before that named settings-advanced.md at 39,160, stale on both counts.)
const XL_CAP = 98304; // 96 KiB
const LARGE_CAP = 61440; // 60 KiB
const DEFAULT_CAP = 40960; // 40 KiB