diff --git a/.changeset/4089-minimum-solution.md b/.changeset/4089-minimum-solution.md new file mode 100644 index 000000000..7acd3ff9b --- /dev/null +++ b/.changeset/4089-minimum-solution.md @@ -0,0 +1,5 @@ +--- +type: Changed +pr: 4118 +--- +**Planning guidance now prefers the first sufficient implementation option** — existing project behavior, standard-library or native platform capability, installed dependencies, and only then minimum new implementation, without reducing required scope or verification. diff --git a/docs/AGENTS.md b/docs/AGENTS.md index 44264bcdb..b5f0dcbd0 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -178,6 +178,7 @@ GSD uses a multi-agent architecture where thin orchestrators (workflow files) sp - Emits a `` sibling for every runnable `` verify command, naming what output constitutes failure (#3172) - Includes `read_first` and `acceptance_criteria` sections - Groups plans into dependency waves +- Applies an ordered minimum-solution check after preserving locked decisions and requirement coverage, preferring existing project behavior, standard-library or native-platform capability, and already-installed dependencies before new implementation (#4089) - Performs reachability check to validate plan steps reference accessible files and APIs (v1.32) - Enforces a comment-text discipline HARD GATE at plan-write time (`verify.plan-structure`): a literal that an acceptance criterion negative-greps for (`grep -c 'LIT' file == 0`) must not appear verbatim in an `` body; violations fail plan creation. Use `` to allowlist a legitimate occurrence. (#429) diff --git a/gsd-core/references/thinking-models-planning.md b/gsd-core/references/thinking-models-planning.md index 89f6cdba0..b3e210fb4 100644 --- a/gsd-core/references/thinking-models-planning.md +++ b/gsd-core/references/thinking-models-planning.md @@ -34,13 +34,29 @@ For each significant decision in this plan, ask what undoing it would cost three This is the reasoning step that produces the rating. The taxonomy itself, the emission rules, and the anti-patterns live in @~/.claude/gsd-core/references/planner-reversibility.md — do not maintain a second classification here. -## 5. Curse of Knowledge Counter +## 5. Occam's Razor + +**Counters:** Plans that prescribe avoidable dependencies, abstractions, files, or speculative flexibility before execution begins. + +This check complements the planner's RESEARCH.md `dont_hand_roll` guidance and the plan checker's Dimension 12 (Pattern Compliance): those sources identify capabilities and established patterns, while this check orders otherwise sufficient implementation choices. The executor applies the related check later in `thinking-models-execution.md`, after the plan has already selected an approach. + +After preserving locked user decisions and complete requirement coverage, choose the first option that is demonstrably sufficient for the task's `` condition: + +1. Existing project behavior, helper, or established pattern +2. Standard-library capability +3. Native platform capability +4. Already-installed dependency +5. Minimum new implementation + +This ordering is a sufficiency check, not permission to make the task smaller. It must never reduce requested scope or override locked user decisions, requirement coverage, security, validation, accessibility, error handling, or verification. The planner uses it when choosing implementation actions; the plan checker flags a new abstraction or dependency only when a higher rung is demonstrably sufficient. + +## 6. Curse of Knowledge Counter **Counters:** Plan-to-executor ambiguity from compressed instructions. For each `` step, re-read it as if you have NEVER seen this codebase. Is every noun unambiguous (which file? which function? which endpoint?)? Is every verb specific (add WHERE? modify HOW?)? If a step could be interpreted two ways, rewrite it. Include file paths, function names, and expected behavior in every action step. -## 6. Base Rate Neglect Counter +## 7. Base Rate Neglect Counter **Counters:** Planners ignoring low-confidence research caveats. diff --git a/tests/thinking-model-guidance.test.cjs b/tests/thinking-model-guidance.test.cjs index 383b0078f..4e393b1be 100644 --- a/tests/thinking-model-guidance.test.cjs +++ b/tests/thinking-model-guidance.test.cjs @@ -34,7 +34,7 @@ const UNIVERSAL_SECTIONS = [ const NAMED_MODELS = { 'debug': ['Fault Tree Analysis', 'Hypothesis-Driven Investigation', 'Occam\'s Razor', 'Counterfactual Thinking'], 'execution': ['Circle of Concern vs Circle of Control', 'Forcing Function', 'First Principles Thinking', 'Occam\'s Razor', 'Chesterton\'s Fence'], - 'planning': ['Pre-Mortem Analysis', 'MECE Decomposition', 'Constraint Analysis', 'Reversibility Test'], + 'planning': ['Pre-Mortem Analysis', 'MECE Decomposition', 'Constraint Analysis', 'Reversibility Test', 'Occam\'s Razor'], 'research': ['First Principles Thinking', 'Simpson\'s Paradox Awareness', 'Survivorship Bias', 'Confirmation Bias Counter', 'Steel Man'], 'verification': ['Inversion', 'Chesterton\'s Fence', 'Confirmation Bias Counter', 'Planning Fallacy Calibration', 'Counterfactual Thinking'], }; @@ -158,6 +158,62 @@ describe('thinking model reference files contain named reasoning models', () => } }); +// ─── Planning Minimum-Solution Contract ────────────────────────────────────── + +describe('thinking-models-planning.md defines the minimum-solution check', () => { + const filePath = path.join(REFERENCES_DIR, 'thinking-models-planning.md'); + const content = fs.readFileSync(filePath, 'utf-8'); + + test('orders sufficient options from existing behavior through minimal new implementation', () => { + const orderedOptions = [ + 'Existing project behavior, helper, or established pattern', + 'Standard-library capability', + 'Native platform capability', + 'Already-installed dependency', + 'Minimum new implementation', + ]; + let previousIndex = -1; + + for (const option of orderedOptions) { + const optionIndex = content.indexOf(option); + assert.ok(optionIndex >= 0, `planning Occam check missing option: ${option}`); + assert.ok(optionIndex > previousIndex, `planning Occam check has option out of order: ${option}`); + previousIndex = optionIndex; + } + }); + + test('distinguishes the check from adjacent planning and execution guidance', () => { + for (const existingGuidance of [ + 'dont_hand_roll', + 'Dimension 12 (Pattern Compliance)', + 'thinking-models-execution.md', + ]) { + assert.ok(content.includes(existingGuidance), `missing cross-reference to ${existingGuidance}`); + } + }); + + test('cannot reduce scope or override required planning constraints', () => { + for (const boundary of [ + 'locked user decisions', + 'requirement coverage', + 'security', + 'validation', + 'accessibility', + 'error handling', + 'verification', + ]) { + assert.ok(content.includes(boundary), `planning Occam check missing boundary: ${boundary}`); + } + assert.ok(content.includes('must never reduce requested scope')); + }); + + test('asks the plan checker to flag avoidable new surface only when a higher rung is sufficient', () => { + assert.ok(content.includes('plan checker')); + assert.ok(content.includes('demonstrably sufficient')); + assert.ok(content.includes('abstraction or dependency')); + }); +}); + // ─── Gap Closure Mode (planning only) ──────────────────────────────────────── describe('thinking-models-planning.md contains Gap Closure Mode section', () => {