From 2a3fe4fdb529fdae563d8ad5d3188bc78c14d58e Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Mon, 6 Apr 2026 12:19:46 -0700 Subject: [PATCH] feat(references): add gates taxonomy with 4 canonical gate types (#1781) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(references): add gates taxonomy with 4 canonical gate types Define pre-flight, revision, escalation, and abort gates as the canonical validation checkpoint types used across GSD workflows. Includes a gate matrix mapping each workflow phase to its gate type, checked artifacts, and failure behavior. Cross-referenced from plan-phase and execute-phase workflows. Closes #1715 Co-Authored-By: Claude Opus 4.6 * fix(agents): add gates.md reference to plan-checker and verifier per approved scope (#1715) Co-Authored-By: Claude Opus 4.6 (1M context) * fix(agents): move gates.md to required_reading blocks and add stall detection (#1715) - Move gates.md @-reference from prose into blocks in gsd-plan-checker.md and gsd-verifier.md so it loads as context - Add stall-detection to Revision Gate recovery description - Fix /gsd-next → next for consistent workflow naming in Gate Matrix - Update tests to verify required_reading placement and stall detection Co-Authored-By: Claude Opus 4.6 (1M context) --------- Co-authored-by: Claude Opus 4.6 --- agents/gsd-plan-checker.md | 6 ++ agents/gsd-verifier.md | 3 + get-shit-done/references/gates.md | 70 +++++++++++++ get-shit-done/workflows/execute-phase.md | 1 + get-shit-done/workflows/plan-phase.md | 1 + tests/gates-taxonomy.test.cjs | 124 +++++++++++++++++++++++ 6 files changed, 205 insertions(+) create mode 100644 get-shit-done/references/gates.md create mode 100644 tests/gates-taxonomy.test.cjs diff --git a/agents/gsd-plan-checker.md b/agents/gsd-plan-checker.md index 7b7275664..99fcfe1ef 100644 --- a/agents/gsd-plan-checker.md +++ b/agents/gsd-plan-checker.md @@ -26,6 +26,12 @@ If the prompt contains a `` block, you MUST use the `Read` tool t You are NOT the executor or verifier — you verify plans WILL work before execution burns context. + +@~/.claude/get-shit-done/references/gates.md + + +This agent implements the **Revision Gate** pattern (bounded quality loop with escalation on cap exhaustion). + Before verifying, discover project context: diff --git a/agents/gsd-verifier.md b/agents/gsd-verifier.md index 85e1efb6d..eb12f1ff6 100644 --- a/agents/gsd-verifier.md +++ b/agents/gsd-verifier.md @@ -20,12 +20,15 @@ Your job: Goal-backward verification. Start from what the phase SHOULD deliver, If the prompt contains a `` block, you MUST use the `Read` tool to load every file listed there before performing any other actions. This is your primary context. **Critical mindset:** Do NOT trust SUMMARY.md claims. SUMMARYs document what Claude SAID it did. You verify what ACTUALLY exists in the code. These often differ. + @~/.claude/get-shit-done/references/verification-overrides.md +@~/.claude/get-shit-done/references/gates.md +This agent implements the **Escalation Gate** pattern (surfaces unresolvable gaps to the developer for decision). Before verifying, discover project context: diff --git a/get-shit-done/references/gates.md b/get-shit-done/references/gates.md new file mode 100644 index 000000000..df43cf80a --- /dev/null +++ b/get-shit-done/references/gates.md @@ -0,0 +1,70 @@ +# Gates Taxonomy + +Canonical gate types used across GSD workflows. Every validation checkpoint maps to one of these four types. + +--- + +## Gate Types + +### Pre-flight Gate +**Purpose:** Validates preconditions before starting an operation. +**Behavior:** Blocks entry if conditions unmet. No partial work created. +**Recovery:** Fix the missing precondition, then retry. +**Examples:** +- Plan-phase checks for REQUIREMENTS.md before planning +- Execute-phase validates PLAN.md exists before execution +- Discuss-phase confirms phase exists in ROADMAP.md + +### Revision Gate +**Purpose:** Evaluates output quality and routes to revision if insufficient. +**Behavior:** Loops back to producer with specific feedback. Bounded by iteration cap. +**Recovery:** Producer addresses feedback; checker re-evaluates. The loop also escalates early if issue count does not decrease between consecutive iterations (stall detection). After max iterations, escalates unconditionally. +**Examples:** +- Plan-checker reviewing PLAN.md (max 3 iterations) +- Verifier checking phase deliverables against success criteria + +### Escalation Gate +**Purpose:** Surfaces unresolvable issues to the developer for a decision. +**Behavior:** Pauses workflow, presents options, waits for human input. +**Recovery:** Developer chooses action; workflow resumes on selected path. +**Examples:** +- Revision loop exhausted after 3 iterations +- Merge conflict during worktree cleanup +- Ambiguous requirement needing clarification + +### Abort Gate +**Purpose:** Terminates the operation to prevent damage or waste. +**Behavior:** Stops immediately, preserves state, reports reason. +**Recovery:** Developer investigates root cause, fixes, restarts from checkpoint. +**Examples:** +- Context window critically low during execution +- STATE.md in error state blocking /gsd-next +- Verification finds critical missing deliverables + +--- + +## Gate Matrix + +| Workflow | Phase | Gate Type | Artifacts Checked | Failure Behavior | +|----------|-------|-----------|-------------------|------------------| +| plan-phase | Entry | Pre-flight | REQUIREMENTS.md, ROADMAP.md | Block with missing-file message | +| plan-phase | Step 12 | Revision | PLAN.md quality | Loop to planner (max 3) | +| plan-phase | Post-revision | Escalation | Unresolved issues | Surface to developer | +| execute-phase | Entry | Pre-flight | PLAN.md | Block with missing-plan message | +| execute-phase | Completion | Revision | SUMMARY.md completeness | Re-run incomplete tasks | +| verify-work | Entry | Pre-flight | SUMMARY.md | Block with missing-summary | +| verify-work | Evaluation | Escalation | Failed criteria | Surface gaps to developer | +| next | Entry | Abort | Error state, checkpoints | Stop with diagnostic | + +--- + +## Implementing Gates + +Use this taxonomy when designing or auditing workflow validation points: + +- **Pre-flight** gates belong at workflow entry points. They are cheap, deterministic checks that prevent wasted work. If you can verify a precondition with a file-existence check or a config read, use a pre-flight gate. +- **Revision** gates belong after a producer step where quality varies. Always pair them with an iteration cap to prevent infinite loops. The cap should reflect the cost of each iteration -- expensive operations get fewer retries. +- **Escalation** gates belong wherever automated resolution is impossible or ambiguous. They are the safety valve between revision loops and abort. Present the developer with clear options and enough context to decide. +- **Abort** gates belong at points where continuing would cause damage, waste significant resources, or produce meaningless output. They should preserve state so work can resume after the root cause is fixed. + +**Selection heuristic:** Start with pre-flight. If the check happens after work is produced, it is a revision gate. If the revision loop cannot resolve the issue, escalate. If continuing is dangerous, abort. diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index db77efda6..649247f4f 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -28,6 +28,7 @@ Read STATE.md before any operation to load project context. @~/.claude/get-shit-done/references/agent-contracts.md @~/.claude/get-shit-done/references/context-budget.md +@~/.claude/get-shit-done/references/gates.md diff --git a/get-shit-done/workflows/plan-phase.md b/get-shit-done/workflows/plan-phase.md index ed18eb144..98dc98fb9 100644 --- a/get-shit-done/workflows/plan-phase.md +++ b/get-shit-done/workflows/plan-phase.md @@ -9,6 +9,7 @@ Read all files referenced by the invoking prompt's execution_context before star @~/.claude/get-shit-done/references/revision-loop.md @~/.claude/get-shit-done/references/gate-prompts.md @~/.claude/get-shit-done/references/agent-contracts.md +@~/.claude/get-shit-done/references/gates.md diff --git a/tests/gates-taxonomy.test.cjs b/tests/gates-taxonomy.test.cjs new file mode 100644 index 000000000..d8f543633 --- /dev/null +++ b/tests/gates-taxonomy.test.cjs @@ -0,0 +1,124 @@ +/** + * Validates the gates taxonomy reference document (#1715). + * + * Ensures the reference file exists, defines all 4 canonical gate types, + * includes the gate matrix table, and is cross-referenced from workflows. + */ +const { describe, test } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const path = require('path'); + +const ROOT = path.join(__dirname, '..'); +const GATES_REF = path.join(ROOT, 'get-shit-done', 'references', 'gates.md'); + +describe('gates taxonomy (#1715)', () => { + test('reference file exists', () => { + assert.ok( + fs.existsSync(GATES_REF), + 'get-shit-done/references/gates.md must exist' + ); + }); + + test('defines all 4 canonical gate types', () => { + const content = fs.readFileSync(GATES_REF, 'utf-8'); + const gateTypes = ['Pre-flight Gate', 'Revision Gate', 'Escalation Gate', 'Abort Gate']; + + for (const gate of gateTypes) { + assert.ok( + content.includes(`### ${gate}`), + `gates.md must define "${gate}" as an h3 heading` + ); + } + }); + + test('each gate type has Purpose, Behavior, Recovery, and Examples', () => { + const content = fs.readFileSync(GATES_REF, 'utf-8'); + const sections = content.split('### ').slice(1); // split by h3, drop preamble + + for (const section of sections) { + const name = section.split('\n')[0].trim(); + // Only check gate type sections (not other h3s if any) + if (!name.endsWith('Gate')) continue; + + for (const field of ['**Purpose:**', '**Behavior:**', '**Recovery:**', '**Examples:**']) { + assert.ok( + section.includes(field), + `Gate "${name}" must include ${field}` + ); + } + } + }); + + test('contains Gate Matrix table', () => { + const content = fs.readFileSync(GATES_REF, 'utf-8'); + assert.ok( + content.includes('## Gate Matrix'), + 'gates.md must include a "Gate Matrix" section' + ); + // Verify table header row + assert.ok( + content.includes('| Workflow |'), + 'Gate Matrix must contain a table with Workflow column' + ); + // Verify key workflow rows exist + assert.ok(content.includes('plan-phase'), 'Gate Matrix must reference plan-phase'); + assert.ok(content.includes('execute-phase'), 'Gate Matrix must reference execute-phase'); + assert.ok(content.includes('verify-work'), 'Gate Matrix must reference verify-work'); + assert.ok(content.includes('| next |'), 'Gate Matrix must reference next workflow'); + }); + + test('plan-phase.md references gates.md', () => { + const planPhase = path.join(ROOT, 'get-shit-done', 'workflows', 'plan-phase.md'); + const content = fs.readFileSync(planPhase, 'utf-8'); + assert.ok( + content.includes('references/gates.md'), + 'plan-phase.md must reference gates.md in its required_reading block' + ); + }); + + test('execute-phase.md references gates.md', () => { + const execPhase = path.join(ROOT, 'get-shit-done', 'workflows', 'execute-phase.md'); + const content = fs.readFileSync(execPhase, 'utf-8'); + assert.ok( + content.includes('references/gates.md'), + 'execute-phase.md must reference gates.md in its required_reading block' + ); + }); + + test('gsd-plan-checker.md references gates.md in required_reading block', () => { + const planChecker = path.join(ROOT, 'agents', 'gsd-plan-checker.md'); + const content = fs.readFileSync(planChecker, 'utf-8'); + assert.ok( + content.includes(''), + 'gsd-plan-checker.md must have a block' + ); + const reqBlock = content.split('')[1].split('')[0]; + assert.ok( + reqBlock.includes('references/gates.md'), + 'gsd-plan-checker.md must reference gates.md inside ' + ); + }); + + test('gsd-verifier.md references gates.md in required_reading block', () => { + const verifier = path.join(ROOT, 'agents', 'gsd-verifier.md'); + const content = fs.readFileSync(verifier, 'utf-8'); + assert.ok( + content.includes(''), + 'gsd-verifier.md must have a block' + ); + const reqBlock = content.split('')[1].split('')[0]; + assert.ok( + reqBlock.includes('references/gates.md'), + 'gsd-verifier.md must reference gates.md inside ' + ); + }); + + test('Revision Gate recovery mentions stall detection', () => { + const content = fs.readFileSync(GATES_REF, 'utf-8'); + assert.ok( + content.includes('stall detection'), + 'Revision Gate recovery must mention stall detection (early escalation when issues stop decreasing)' + ); + }); +});