diff --git a/get-shit-done/workflows/discuss-phase.md b/get-shit-done/workflows/discuss-phase.md index 90a9f84ae..d77fdf93a 100644 --- a/get-shit-done/workflows/discuss-phase.md +++ b/get-shit-done/workflows/discuss-phase.md @@ -162,6 +162,30 @@ Exit workflow. - This is the middle ground: user controls the discuss decisions, then plan+execute run autonomously + +**MANDATORY — Check for blocking anti-patterns before any other work.** + +Look for a `.continue-here.md` in the current phase directory: + +```bash +ls ${phase_dir}/.continue-here.md 2>/dev/null || true +``` + +If `.continue-here.md` exists, parse its "Critical Anti-Patterns" table for rows with `severity` = `blocking`. + +**If one or more `blocking` anti-patterns are found:** + +This step cannot be skipped. Before proceeding to `check_existing` or any other step, the agent must demonstrate understanding of each blocking anti-pattern by answering all three questions for each one: + +1. **What is this anti-pattern?** — Describe it in your own words, not by quoting the handoff. +2. **How did it manifest?** — Explain the specific failure that caused it to be recorded. +3. **What structural mechanism (not acknowledgment) prevents it?** — Name the concrete step, checklist item, or enforcement mechanism that stops recurrence. + +Write these answers inline before continuing. If a blocking anti-pattern cannot be answered from the context in `.continue-here.md`, stop and ask the user for clarification. + +**If no `.continue-here.md` exists, or no `blocking` rows are found:** Proceed directly to `check_existing`. + + Check if CONTEXT.md already exists using `has_context` from init. diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index 888a7ba30..e8b49b4bf 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -110,6 +110,30 @@ fi ``` + +**MANDATORY — Check for blocking anti-patterns before any other work.** + +Look for a `.continue-here.md` in the current phase directory: + +```bash +ls ${phase_dir}/.continue-here.md 2>/dev/null || true +``` + +If `.continue-here.md` exists, parse its "Critical Anti-Patterns" table for rows with `severity` = `blocking`. + +**If one or more `blocking` anti-patterns are found:** + +This step cannot be skipped. Before proceeding to `check_interactive_mode` or any other step, the agent must demonstrate understanding of each blocking anti-pattern by answering all three questions for each one: + +1. **What is this anti-pattern?** — Describe it in your own words, not by quoting the handoff. +2. **How did it manifest?** — Explain the specific failure that caused it to be recorded. +3. **What structural mechanism (not acknowledgment) prevents it?** — Name the concrete step, checklist item, or enforcement mechanism that stops recurrence. + +Write these answers inline before continuing. If a blocking anti-pattern cannot be answered from the context in `.continue-here.md`, stop and ask the user for clarification. + +**If no `.continue-here.md` exists, or no `blocking` rows are found:** Proceed directly to `check_interactive_mode`. + + **Parse `--interactive` flag from $ARGUMENTS.** diff --git a/get-shit-done/workflows/pause-work.md b/get-shit-done/workflows/pause-work.md index 2442d4008..f9e41e53d 100644 --- a/get-shit-done/workflows/pause-work.md +++ b/get-shit-done/workflows/pause-work.md @@ -44,6 +44,9 @@ If phase is detected, proceed with phase handoff path. Otherwise use the first m 6. **Human actions pending**: Things that need manual intervention (MCP setup, API keys, approvals, manual testing) 7. **Background processes**: Any running servers/watchers that were part of the workflow 8. **Files modified**: What's changed but not committed +9. **Blocking constraints**: Anti-patterns or methodological failures encountered during this session that a resuming agent MUST be aware of before proceeding. Only include items discovered through actual failure — not warnings or predictions. Assign each constraint a `severity`: + - `blocking` — The resuming agent MUST demonstrate understanding before proceeding. The discuss-phase and execute-phase workflows will enforce a mandatory understanding check. + - `advisory` — Important context but does not gate resumption. Ask user for clarifications if needed via conversational questions. @@ -111,12 +114,35 @@ status: in_progress last_updated: [timestamp from current-timestamp] --- +# BLOCKING CONSTRAINTS — Read Before Anything Else + +> These are not suggestions. Each constraint below was discovered through failure. +> Acknowledge each one explicitly before proceeding. + +- [ ] CONSTRAINT: [name] — [what it is] — [structural mitigation required] + +**Do not proceed until all boxes are checked.** + +_If no constraints have been identified yet, remove this section._ + +## Critical Anti-Patterns + +| Pattern | Description | Severity | Prevention Mechanism | +|---------|-------------|----------|---------------------| +| [pattern name] | [what it is and how it manifested] | blocking | [structural step that prevents recurrence — not acknowledgment] | +| [pattern name] | [what it is and how it manifested] | advisory | [guidance for avoiding it] | + +**Severity values:** `blocking` — resuming agent must pass understanding check before proceeding. `advisory` — important context, does not gate resumption. + +_Remove rows that do not apply. The discuss-phase and execute-phase workflows parse this table and enforce a mandatory understanding check for any `blocking` rows._ + [Where exactly are we? Immediate context] +Completed Tasks: - Task 1: [name] - Done - Task 2: [name] - Done - Task 3: [name] - In progress, [what's done] diff --git a/tests/anti-pattern-enforcement.test.cjs b/tests/anti-pattern-enforcement.test.cjs new file mode 100644 index 000000000..10e2ed4da --- /dev/null +++ b/tests/anti-pattern-enforcement.test.cjs @@ -0,0 +1,176 @@ +'use strict'; + +/** + * Anti-Pattern Enforcement Tests (#1491) + * + * Validates that the handoff/resume system structurally enforces critical + * anti-patterns via severity levels and mandatory understanding checks. + */ + +const { test, describe } = require('node:test'); +const assert = require('node:assert'); +const fs = require('fs'); +const path = require('path'); + +const PAUSE_WORK = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'); +const DISCUSS_PHASE = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'discuss-phase.md'); +const EXECUTE_PHASE = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'execute-phase.md'); + +describe('pause-work.md — severity column in Critical Anti-Patterns template', () => { + test('template includes a Severity column header in the anti-patterns table', () => { + const content = fs.readFileSync(PAUSE_WORK, 'utf-8'); + assert.ok( + content.includes('Severity') || content.includes('severity'), + 'pause-work.md template must include a Severity column in the anti-patterns table' + ); + }); + + test('template documents "blocking" as a valid severity value', () => { + const content = fs.readFileSync(PAUSE_WORK, 'utf-8'); + assert.ok( + content.includes('blocking'), + 'pause-work.md must document "blocking" as a valid severity value' + ); + }); + + test('template documents "advisory" as a valid severity value', () => { + const content = fs.readFileSync(PAUSE_WORK, 'utf-8'); + assert.ok( + content.includes('advisory'), + 'pause-work.md must document "advisory" as a valid severity value' + ); + }); + + test('template explains that blocking anti-patterns trigger understanding check at resume', () => { + const content = fs.readFileSync(PAUSE_WORK, 'utf-8'); + const hasExplanation = + (content.includes('blocking') && content.includes('understanding check')) || + (content.includes('blocking') && content.includes('resume')) || + (content.includes('blocking') && content.includes('understanding')); + assert.ok( + hasExplanation, + 'pause-work.md must explain that blocking anti-patterns trigger an understanding check at resume' + ); + }); +}); + +describe('discuss-phase.md — blocking anti-pattern understanding check', () => { + test('workflow checks for .continue-here.md with blocking anti-patterns', () => { + const content = fs.readFileSync(DISCUSS_PHASE, 'utf-8'); + const hasCheck = + content.includes('.continue-here.md') && + (content.includes('blocking') || content.includes('anti-pattern')); + assert.ok( + hasCheck, + 'discuss-phase.md must check for .continue-here.md blocking anti-patterns before proceeding' + ); + }); + + test('workflow includes mandatory understanding verification for blocking anti-patterns', () => { + const content = fs.readFileSync(DISCUSS_PHASE, 'utf-8'); + const hasVerification = + content.includes('understanding') || + content.includes('understanding check') || + content.includes('demonstrate understanding'); + assert.ok( + hasVerification, + 'discuss-phase.md must include a mandatory understanding verification step for blocking anti-patterns' + ); + }); + + test('workflow specifies the three understanding check questions', () => { + const content = fs.readFileSync(DISCUSS_PHASE, 'utf-8'); + // The three questions required by the issue + const hasWhatIs = + content.includes('What is this anti-pattern') || + content.includes('what is this anti-pattern') || + content.includes('What is the anti-pattern'); + const hasHowManifest = + content.includes('How did it manifest') || + content.includes('how did it manifest') || + content.includes('manifest'); + const hasPreventMechanism = + content.includes('structural mechanism') || + content.includes('prevention') || + content.includes('Prevention'); + assert.ok( + hasWhatIs && hasHowManifest && hasPreventMechanism, + 'discuss-phase.md must include the three understanding check questions: ' + + '"What is this anti-pattern?", "How did it manifest?", "What structural mechanism prevents it?"' + ); + }); + + test('understanding check cannot be skipped (must be mandatory)', () => { + const content = fs.readFileSync(DISCUSS_PHASE, 'utf-8'); + const hasMandatory = + content.includes('cannot be skipped') || + content.includes('must not be skipped') || + content.includes('mandatory') || + content.includes('MANDATORY') || + content.includes('required before'); + assert.ok( + hasMandatory, + 'discuss-phase.md must indicate that the blocking anti-pattern understanding check cannot be skipped' + ); + }); +}); + +describe('execute-phase.md — blocking anti-pattern understanding check', () => { + test('workflow checks for .continue-here.md with blocking anti-patterns', () => { + const content = fs.readFileSync(EXECUTE_PHASE, 'utf-8'); + const hasCheck = + content.includes('.continue-here.md') && + (content.includes('blocking') || content.includes('anti-pattern')); + assert.ok( + hasCheck, + 'execute-phase.md must check for .continue-here.md blocking anti-patterns before proceeding' + ); + }); + + test('workflow includes mandatory understanding verification for blocking anti-patterns', () => { + const content = fs.readFileSync(EXECUTE_PHASE, 'utf-8'); + const hasVerification = + content.includes('understanding') || + content.includes('understanding check') || + content.includes('demonstrate understanding'); + assert.ok( + hasVerification, + 'execute-phase.md must include a mandatory understanding verification step for blocking anti-patterns' + ); + }); + + test('workflow specifies the three understanding check questions', () => { + const content = fs.readFileSync(EXECUTE_PHASE, 'utf-8'); + const hasWhatIs = + content.includes('What is this anti-pattern') || + content.includes('what is this anti-pattern') || + content.includes('What is the anti-pattern'); + const hasHowManifest = + content.includes('How did it manifest') || + content.includes('how did it manifest') || + content.includes('manifest'); + const hasPreventMechanism = + content.includes('structural mechanism') || + content.includes('prevention') || + content.includes('Prevention'); + assert.ok( + hasWhatIs && hasHowManifest && hasPreventMechanism, + 'execute-phase.md must include the three understanding check questions: ' + + '"What is this anti-pattern?", "How did it manifest?", "What structural mechanism prevents it?"' + ); + }); + + test('understanding check cannot be skipped (must be mandatory)', () => { + const content = fs.readFileSync(EXECUTE_PHASE, 'utf-8'); + const hasMandatory = + content.includes('cannot be skipped') || + content.includes('must not be skipped') || + content.includes('mandatory') || + content.includes('MANDATORY') || + content.includes('required before'); + assert.ok( + hasMandatory, + 'execute-phase.md must indicate that the blocking anti-pattern understanding check cannot be skipped' + ); + }); +});