diff --git a/docs/INVENTORY-MANIFEST.json b/docs/INVENTORY-MANIFEST.json index a08c253ea..3a0826733 100644 --- a/docs/INVENTORY-MANIFEST.json +++ b/docs/INVENTORY-MANIFEST.json @@ -214,6 +214,7 @@ "edge-probe.md", "execute-mvp-tdd.md", "execute-phase-between-wave-reset.md", + "execute-phase-context-guard.md", "execute-phase-wave-guard.md", "executor-examples.md", "gate-prompts.md", diff --git a/docs/INVENTORY.md b/docs/INVENTORY.md index a81c459ec..8d22872ed 100644 --- a/docs/INVENTORY.md +++ b/docs/INVENTORY.md @@ -301,6 +301,7 @@ Full roster at `gsd-core/references/*.md`. References are shared knowledge docum |-----------|------| | `agent-contracts.md` | Formal interface between orchestrators and agents. | | `context-budget.md` | Context window budget allocation rules. | +| `execute-phase-context-guard.md` | Context exhaustion guard step for `execute-phase` wave loop — `workflow.context_guard_mode` dispatch table (warn/auto/off) and POOR-tier pause-work trigger (#1452). | | `continuation-format.md` | Session continuation/resume format. | | `domain-probes.md` | Domain-specific probing questions for discuss-phase. | | `edge-probe.md` | Spec-phase edge-completeness probe — 8-category edge taxonomy, shape classification, and the `requirements → checks → verifier` resolution model (Step 5.5). | diff --git a/gsd-core/references/execute-phase-context-guard.md b/gsd-core/references/execute-phase-context-guard.md new file mode 100644 index 000000000..97b86021b --- /dev/null +++ b/gsd-core/references/execute-phase-context-guard.md @@ -0,0 +1,16 @@ +0. **Context exhaustion guard — `context_guard` (BEFORE spawning, #1452):** + + Before spawning any agents for this wave, self-assess context pressure using the + degradation signals in `references/context-budget.md`. Signs of POOR tier (70%+): + increasing vagueness, skipped steps, silent partial completion. + + Read `workflow.context_guard_mode` from `.planning/config.json` (default `warn`). + + | Tier | `warn` (default) | `auto` | `off` | + |------|-----------------|--------|-------| + | PEAK / GOOD | No output | No output | No output | + | DEGRADING (50-70%) | Emit: "⚠ Context pressure DEGRADING — switching to frontmatter-only reads for remaining waves." Continue. | Same as warn | Skip | + | POOR (70%+) | Emit: "🛑 Context pressure POOR — risk of context exhaustion. Run `/gsd:pause-work` to checkpoint before this wave, then resume in a fresh session." Continue (user decides). | Invoke `/gsd:pause-work` immediately and halt. Do NOT spawn wave agents. | Skip | + + The guard is heuristic — no programmatic context-percentage API exists. Use your + assessment of degradation signals, not a fixed token count. diff --git a/gsd-core/workflows/execute-phase.md b/gsd-core/workflows/execute-phase.md index ee14707c6..07af88c7d 100644 --- a/gsd-core/workflows/execute-phase.md +++ b/gsd-core/workflows/execute-phase.md @@ -493,22 +493,7 @@ increases monotonically across waves. `{status}` is `complete` (success), @~/.claude/gsd-core/references/execute-phase-wave-guard.md -0. **Context exhaustion guard — `context_guard` (BEFORE spawning, #1452):** - - Before spawning any agents for this wave, self-assess context pressure using the - degradation signals in `references/context-budget.md`. Signs of POOR tier (70%+): - increasing vagueness, skipped steps, silent partial completion. - - Read `workflow.context_guard_mode` from `.planning/config.json` (default `warn`). - - | Tier | `warn` (default) | `auto` | `off` | - |------|-----------------|--------|-------| - | PEAK / GOOD | No output | No output | No output | - | DEGRADING (50-70%) | Emit: "⚠ Context pressure DEGRADING — switching to frontmatter-only reads for remaining waves." Continue. | Same as warn | Skip | - | POOR (70%+) | Emit: "🛑 Context pressure POOR — risk of context exhaustion. Run `/gsd:pause-work` to checkpoint before this wave, then resume in a fresh session." Continue (user decides). | Invoke `/gsd:pause-work` immediately and halt. Do NOT spawn wave agents. | Skip | - - The guard is heuristic — no programmatic context-percentage API exists. Use your - assessment of degradation signals, not a fixed token count. +@~/.claude/gsd-core/references/execute-phase-context-guard.md 1. **Intra-wave files_modified overlap check (BEFORE spawning):** diff --git a/tests/feat-1452-context-guard-mode.test.cjs b/tests/feat-1452-context-guard-mode.test.cjs index 0e7031016..7d19d4619 100644 --- a/tests/feat-1452-context-guard-mode.test.cjs +++ b/tests/feat-1452-context-guard-mode.test.cjs @@ -1,4 +1,4 @@ -// allow-test-rule: source-text-is-the-product +// allow-test-rule: source-text-is-the-product see #1452 // The execute-phase.md workflow and context-budget.md reference ARE the runtime // contract loaded by AI runtimes. Asserting that the canonical wording for // `workflow.context_guard_mode` is present in those files is the only way to @@ -126,32 +126,39 @@ describe('workflow.context_guard_mode config round-trip', () => { describe('execute-phase.md documents the context_guard step', () => { let executePhase; + let contextGuardRef; beforeEach(() => { executePhase = fs.readFileSync( path.join(REPO_ROOT, 'gsd-core', 'workflows', 'execute-phase.md'), 'utf-8', ); + // The step body is extracted to a reference file loaded via @-ref in execute-phase.md. + // Both files together constitute the execute-phase wave-boundary contract. + const refPath = path.join(REPO_ROOT, 'gsd-core', 'references', 'execute-phase-context-guard.md'); + contextGuardRef = fs.existsSync(refPath) ? fs.readFileSync(refPath, 'utf-8') : ''; }); test('references workflow.context_guard_mode by canonical name', () => { + const combined = executePhase + '\n' + contextGuardRef; assert.ok( - executePhase.includes('workflow.context_guard_mode'), - 'execute-phase.md must reference workflow.context_guard_mode so runtimes resolve the config-driven behavior', + combined.includes('workflow.context_guard_mode'), + 'execute-phase.md (or its @-referenced execute-phase-context-guard.md) must reference workflow.context_guard_mode so runtimes resolve the config-driven behavior', ); }); test('defines context_guard step at wave boundaries', () => { assert.ok( executePhase.includes('context_guard') || executePhase.includes('context-guard'), - 'execute-phase.md must define a context_guard step that fires before each wave', + 'execute-phase.md must define a context_guard step (or @-ref to it) that fires before each wave', ); }); test('references context-budget.md tiers in the guard step', () => { + const combined = executePhase + '\n' + contextGuardRef; assert.ok( - executePhase.includes('context-budget') || executePhase.includes('POOR') || executePhase.includes('DEGRADING'), - 'execute-phase.md context_guard must reference context-budget.md degradation tiers', + combined.includes('context-budget') || combined.includes('POOR') || combined.includes('DEGRADING'), + 'execute-phase.md context_guard (or its @-referenced file) must reference context-budget.md degradation tiers', ); }); }); diff --git a/tests/workflow-size-baseline.json b/tests/workflow-size-baseline.json index 80f23b7d2..3f880b5cd 100644 --- a/tests/workflow-size-baseline.json +++ b/tests/workflow-size-baseline.json @@ -24,7 +24,7 @@ "docs-update.md": 55662, "edit-phase.md": 12883, "eval-review.md": 9923, - "execute-phase.md": 93995, + "execute-phase.md": 92914, "execute-plan.md": 31365, "explore.md": 10497, "extract-learnings.md": 12849,