From 9d430f663713c12ae6084e8fee78b801dca9b438 Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Thu, 2 Apr 2026 04:16:24 -0700 Subject: [PATCH] feat(workflows): adaptive context enrichment for 1M models Read context_window config (default 200000) in execute-phase and plan-phase workflows. When >= 500000 (1M-class models), subagent prompts include richer context: executor agents receive CONTEXT.md, RESEARCH.md, and prior wave SUMMARYs; verifier agents receive all PLANs, SUMMARYs, and REQUIREMENTS.md; planner receives prior phase CONTEXT.md for cross-phase decision consistency. At 200k (default), behavior is unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) --- get-shit-done/workflows/execute-phase.md | 28 +++++ get-shit-done/workflows/plan-phase.md | 8 ++ tests/context-enrichment.test.cjs | 145 +++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 tests/context-enrichment.test.cjs diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index 2db0e2f29..1b9fc43fb 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -76,6 +76,17 @@ USE_WORKTREES=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get When `USE_WORKTREES` is `false`, all executor agents run without `isolation="worktree"` — they execute sequentially on the main working tree instead of in parallel worktrees. +Read context window size for adaptive prompt enrichment: + +```bash +CONTEXT_WINDOW=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get context_window 2>/dev/null || echo "200000") +``` + +When `CONTEXT_WINDOW >= 500000` (1M-class models), subagent prompts include richer context: +- Executor agents receive prior wave SUMMARY.md files and the phase CONTEXT.md/RESEARCH.md +- Verifier agents receive all PLAN.md, SUMMARY.md, CONTEXT.md files plus REQUIREMENTS.md +- This enables cross-phase awareness and history-aware verification + **If `phase_found` is false:** Error — phase directory not found. **If `plan_count` is 0:** Error — no plans found in phase. **If `state_exists` is false but `.planning/` exists:** Offer reconstruct or continue. @@ -265,6 +276,11 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT - .planning/PROJECT.md (Project context — core value, requirements, evolution rules) - .planning/STATE.md (State) - .planning/config.json (Config, if exists) + ${CONTEXT_WINDOW >= 500000 ? ` + - ${phase_dir}/*-CONTEXT.md (User decisions from discuss-phase — honors locked choices) + - ${phase_dir}/*-RESEARCH.md (Technical research — pitfalls and patterns to follow) + - ${prior_wave_summaries} (SUMMARY.md files from earlier waves in this phase — what was already built) + ` : ''} - ./CLAUDE.md (Project instructions, if exists — follow project-specific guidelines and coding conventions) - .claude/skills/ or .agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation) @@ -739,6 +755,18 @@ Phase requirement IDs: {phase_req_ids} Check must_haves against actual codebase. Cross-reference requirement IDs from PLAN frontmatter against REQUIREMENTS.md — every ID MUST be accounted for. Create VERIFICATION.md. + + +Read these files before verification: +- {phase_dir}/*-PLAN.md (All plans — understand intent, check must_haves) +- {phase_dir}/*-SUMMARY.md (All summaries — cross-reference claimed vs actual) +- .planning/REQUIREMENTS.md (Requirement traceability) +${CONTEXT_WINDOW >= 500000 ? `- {phase_dir}/*-CONTEXT.md (User decisions — verify they were honored) +- {phase_dir}/*-RESEARCH.md (Known pitfalls — check for traps) +- Prior VERIFICATION.md files from earlier phases (regression check) +` : ''} + + ${VERIFIER_SKILLS}", subagent_type="gsd-verifier", model="{verifier_model}" diff --git a/get-shit-done/workflows/plan-phase.md b/get-shit-done/workflows/plan-phase.md index 361b676d8..3fd5d7f88 100644 --- a/get-shit-done/workflows/plan-phase.md +++ b/get-shit-done/workflows/plan-phase.md @@ -27,8 +27,11 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi AGENT_SKILLS_RESEARCHER=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" agent-skills gsd-researcher 2>/dev/null) AGENT_SKILLS_PLANNER=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" agent-skills gsd-planner 2>/dev/null) AGENT_SKILLS_CHECKER=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" agent-skills gsd-checker 2>/dev/null) +CONTEXT_WINDOW=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get context_window 2>/dev/null || echo "200000") ``` +When `CONTEXT_WINDOW >= 500000`, the planner prompt includes prior phase CONTEXT.md files so cross-phase decisions are consistent (e.g., "use library X for all data fetching" from Phase 2 is visible to Phase 5's planner). + Parse JSON for: `researcher_model`, `planner_model`, `checker_model`, `research_enabled`, `plan_checker_enabled`, `nyquist_validation_enabled`, `commit_docs`, `text_mode`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_reviews`, `has_plans`, `plan_count`, `planning_exists`, `roadmap_exists`, `phase_req_ids`. **File paths (for blocks):** `state_path`, `roadmap_path`, `requirements_path`, `context_path`, `research_path`, `verification_path`, `uat_path`, `reviews_path`. These are null if files don't exist. @@ -576,6 +579,11 @@ Planner prompt: - {uat_path} (UAT Gaps - if --gaps) - {reviews_path} (Cross-AI Review Feedback - if --reviews) - {UI_SPEC_PATH} (UI Design Contract — visual/interaction specs, if exists) +${CONTEXT_WINDOW >= 500000 ? ` +**Cross-phase context (1M model enrichment):** +- Prior phase CONTEXT.md files (locked decisions from earlier phases — maintain consistency) +- Prior phase SUMMARY.md files (what was actually built — reuse patterns, avoid duplication) +` : ''} ${AGENT_SKILLS_PLANNER} diff --git a/tests/context-enrichment.test.cjs b/tests/context-enrichment.test.cjs new file mode 100644 index 000000000..71d35fab3 --- /dev/null +++ b/tests/context-enrichment.test.cjs @@ -0,0 +1,145 @@ +/** + * GSD Tools Tests - Adaptive Context Enrichment for 1M Models + * + * Tests for feat/1m-context-enrichment-1473b: + * - Workflow template syntax validation (CONTEXT_WINDOW conditionals) + * - execute-phase.md enrichment blocks (executor + verifier) + * - plan-phase.md cross-phase context gating + */ + +const { test, describe } = require('node:test'); +const assert = require('node:assert'); +const fs = require('fs'); +const path = require('path'); + +// ───────────────────────────────────────────────────────────────────────────── +// Workflow template syntax validation +// ───────────────────────────────────────────────────────────────────────────── + +describe('execute-phase.md context enrichment', () => { + const EXECUTE_WORKFLOW_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'execute-phase.md'); + + test('contains CONTEXT_WINDOW config-get command', () => { + const content = fs.readFileSync(EXECUTE_WORKFLOW_PATH, 'utf-8'); + assert.ok( + content.includes('CONTEXT_WINDOW'), + 'execute-phase.md should reference CONTEXT_WINDOW variable' + ); + assert.ok( + content.includes('config-get context_window'), + 'execute-phase.md should read context_window via config-get' + ); + assert.ok( + content.includes('|| echo "200000"'), + 'execute-phase.md should default CONTEXT_WINDOW to 200000' + ); + }); + + test('contains conditional prior_wave_summaries in executor prompt', () => { + const content = fs.readFileSync(EXECUTE_WORKFLOW_PATH, 'utf-8'); + assert.ok( + content.includes('CONTEXT_WINDOW >= 500000'), + 'execute-phase.md should gate enrichment on CONTEXT_WINDOW >= 500000' + ); + assert.ok( + content.includes('prior_wave_summaries'), + 'execute-phase.md should include prior_wave_summaries in enrichment block' + ); + assert.ok( + content.includes('CONTEXT.md'), + 'execute-phase.md should reference CONTEXT.md in conditional enrichment' + ); + assert.ok( + content.includes('RESEARCH.md'), + 'execute-phase.md should reference RESEARCH.md in conditional enrichment' + ); + }); + + test('verifier prompt includes files_to_read block', () => { + const content = fs.readFileSync(EXECUTE_WORKFLOW_PATH, 'utf-8'); + assert.ok( + content.includes(''), + 'execute-phase.md should contain opening tag' + ); + assert.ok( + content.includes(''), + 'execute-phase.md should contain closing tag' + ); + const verifierSection = content.substring(content.lastIndexOf('')); + assert.ok( + verifierSection.includes('PLAN.md'), + 'verifier files_to_read should reference PLAN.md' + ); + assert.ok( + verifierSection.includes('SUMMARY.md'), + 'verifier files_to_read should reference SUMMARY.md' + ); + assert.ok( + verifierSection.includes('REQUIREMENTS.md'), + 'verifier files_to_read should reference REQUIREMENTS.md' + ); + }); + + test('executor enrichment block includes CONTEXT.md and RESEARCH.md for 1M models', () => { + const content = fs.readFileSync(EXECUTE_WORKFLOW_PATH, 'utf-8'); + // Find the executor section's enrichment block + const executorIdx = content.indexOf('CONTEXT_WINDOW >= 500000'); + assert.ok(executorIdx > -1, 'Should find CONTEXT_WINDOW >= 500000 conditional'); + + // Extract ~500 chars after the conditional to check what's included + const enrichmentBlock = content.substring(executorIdx, executorIdx + 500); + assert.ok( + enrichmentBlock.includes('CONTEXT.md'), + 'executor enrichment should include CONTEXT.md' + ); + assert.ok( + enrichmentBlock.includes('RESEARCH.md'), + 'executor enrichment should include RESEARCH.md' + ); + }); +}); + +describe('plan-phase.md context enrichment', () => { + const PLAN_WORKFLOW_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'plan-phase.md'); + + test('contains CONTEXT_WINDOW conditional for prior CONTEXT.md', () => { + const content = fs.readFileSync(PLAN_WORKFLOW_PATH, 'utf-8'); + assert.ok( + content.includes('CONTEXT_WINDOW'), + 'plan-phase.md should reference CONTEXT_WINDOW variable' + ); + assert.ok( + content.includes('config-get context_window'), + 'plan-phase.md should read context_window via config-get' + ); + assert.ok( + content.includes('CONTEXT_WINDOW >= 500000'), + 'plan-phase.md should gate cross-phase context on CONTEXT_WINDOW >= 500000' + ); + assert.ok( + content.includes('CONTEXT.md'), + 'plan-phase.md should reference CONTEXT.md in cross-phase enrichment' + ); + }); + + test('enrichment block mentions cross-phase decision consistency', () => { + const content = fs.readFileSync(PLAN_WORKFLOW_PATH, 'utf-8'); + // The enrichment should explain why prior context matters + assert.ok( + content.includes('cross-phase') || content.includes('Cross-phase'), + 'plan-phase.md should mention cross-phase context' + ); + assert.ok( + content.includes('SUMMARY.md'), + 'plan-phase.md should reference prior SUMMARY.md files' + ); + }); + + test('default CONTEXT_WINDOW fallback is 200000', () => { + const content = fs.readFileSync(PLAN_WORKFLOW_PATH, 'utf-8'); + assert.ok( + content.includes('|| echo "200000"'), + 'plan-phase.md should default CONTEXT_WINDOW to 200000' + ); + }); +});