* test(#1963): add failing-first prevention/postmortem contract tests Epic #1957 Phase 3B. Source-text-is-the-product contract tests: blameless 5-Whys that BRANCHES per Phase 2A RCA (not a single-cause chain; treats agent error as 'why was that possible?'), the 'why wasn't this caught?' question, the recurrence-guard taxonomy (regression test / assertion / lint rule / KB pattern), the KB-entry why_not_caught + recurrence_guard fields with backward compat, the session-manager prevention summary line, and the Zawinski scope-boundary (a block, not a subsystem). Failing-first: reference, archive_session edit, KB schema extension, and session-manager summary do not yet exist. * feat(#1963): emit blameless-postmortem Prevention block at resolution Epic #1957 Phase 3B. At archive_session the debugger now produces a Prevention block with three blame-free components: a branching 5-Whys causal chain (branches per Phase 2A RCA, not a single chain; 'agent error' prompts 'why was that possible?', never blame), a 'why wasn't this caught?' answer naming the missed gate (test/typecheck/lint/review/verify), and a concrete recurrence guard (regression test / assertion / lint rule / KB pattern). The knowledge-base entry gains two structured fields (why_not_caught + recurrence_guard) so future Phase-0 recall surfaces the prior prevention, not just the prior fix. Additive: old entries without the fields still load. The session-manager compact summary surfaces a one-line prevention summary. Full rules extracted to gsd-core/references/debugger-prevention.md (slim archive_session step + 2 KB fields kept in the agent). INVENTORY + manifest + agent-size baseline + install-parity goldens + AGENTS.md updated. * fix(#1963): address orthogonal review (CRITICAL append-template drift + Phase-0 consumption + parity test) - CRITICAL: the archive_session KB append template omitted Why not caught + Recurrence guard (only the Entry Format had them) — the feature's core deliverable silently did not happen. Added both fields to the append template the agent actually follows (nearest-instruction wins). - HIGH: Phase 0 (KB read) only surfaced root_cause + fix; the new fields were dead data. Extended the Phase 0 Evidence line to consume why_not_caught + recurrence_guard when present (absent on old entries — backward compat holds). - MEDIUM: added a cross-section parity test (every Entry-Format field must also appear in the append template — the guard that would have caught the Critical) + a Phase-0-consumption assertion. - MEDIUM: the 'branches per Phase 2A' claim is now wired — reuses reasoning_checkpoint.candidate_causes across the four categories. - MEDIUM: recurrence-guard taxonomy gains type refinement + config-default change; LOW: added 'build' gate to both surfaces for parity. - NIT: compact-summary fallback shape ('no gate existed'); verify the guard artifact exists before recording it. * test(#1963): anchor Phase-0 consumption test on the specific heading The regex /Phase 0[\s\S]{0,1200}/ matched the first 'Phase 0' in the file (in knowledge_base_protocol prose), not the Phase 0 block in investigation_loop. Anchor on '**Phase 0: Check knowledge base**' and widen to 1500 chars. * chore(#1963): backfill changeset pr number (PR #2410)
This commit is contained in:
@@ -321,6 +321,7 @@ Return compact summary (terminal — investigation resolved):
|
||||
**Cycles:** {N} (investigation) + {M} (fix)
|
||||
**TDD:** {yes/no}
|
||||
**Specialist review:** {specialist_hint used, or "none"}
|
||||
**Prevention:** {one-line from the blameless postmortem — "why not caught: <gate, or 'none (no gate existed for this class)'>; guard: <artifact>"}
|
||||
```
|
||||
|
||||
If the session was abandoned by user choice, return (terminal — user stopped):
|
||||
|
||||
@@ -807,6 +807,8 @@ Each resolved session appends one entry:
|
||||
- **Root cause(s):** {from Resolution.root_cause — one cause, or a '; '-joined list when the AND-gate fired}
|
||||
- **Fix:** {from Resolution.fix}
|
||||
- **Files changed:** {from Resolution.files_changed}
|
||||
- **Why not caught:** {which existing gate (test/typecheck/lint/review/verify/build) should have caught it — or "no gate existed for this class"}
|
||||
- **Recurrence guard:** {the concrete artifact preventing this class from returning — regression test (path:name) / assertion / lint rule / type refinement / config-default change / KB pattern}
|
||||
---
|
||||
```
|
||||
|
||||
@@ -987,7 +989,7 @@ At investigation decision points, apply structured reasoning:
|
||||
- Scan knowledge base entries for 2+ keyword overlap (case-insensitive)
|
||||
- If match found:
|
||||
- Note in Current Focus: `known_pattern_candidate: "{matched slug} — {description}"`
|
||||
- Add to Evidence: `found: Knowledge base match on [{keywords}] → Root cause was: {root_cause}. Fix was: {fix}.`
|
||||
- Add to Evidence: `found: Knowledge base match on [{keywords}] → Root cause was: {root_cause}. Fix was: {fix}. Why not caught: {why_not_caught}. Recurrence guard: {recurrence_guard}.` (the last two are absent on old entries — that's fine; consume them when present)
|
||||
- Test this hypothesis FIRST in Phase 2 — but treat it as one hypothesis, not a certainty
|
||||
- If no match: proceed normally
|
||||
|
||||
@@ -1212,9 +1214,13 @@ Then commit planning docs via CLI (respects `commit_docs` config automatically):
|
||||
gsd_run query commit "docs: resolve debug {slug}" --files .planning/debug/resolved/{slug}.md
|
||||
```
|
||||
|
||||
**Append to knowledge base:**
|
||||
**Append to knowledge base (with the Prevention block):**
|
||||
|
||||
Read `.planning/debug/resolved/{slug}.md` to extract final `Resolution` values. Then append to `.planning/debug/knowledge-base.md` (create file with header if it doesn't exist):
|
||||
Read `.planning/debug/resolved/{slug}.md` to extract final `Resolution` values. Then produce the **Prevention block** — a blameless postmortem (branching 5-Whys per RCA, "why wasn't this caught?", and a concrete recurrence guard):
|
||||
|
||||
@~/.claude/gsd-core/references/debugger-prevention.md
|
||||
|
||||
Then append to `.planning/debug/knowledge-base.md` (create file with header if it doesn't exist):
|
||||
|
||||
If creating for the first time, write this header first:
|
||||
```markdown
|
||||
@@ -1234,6 +1240,8 @@ Then append the entry:
|
||||
- **Root cause(s):** {Resolution.root_cause — joined as '; ' when multiple contributing causes were confirmed}
|
||||
- **Fix:** {Resolution.fix}
|
||||
- **Files changed:** {Resolution.files_changed joined as comma list}
|
||||
- **Why not caught:** {which existing gate (test/typecheck/lint/review/verify/build) should have caught it — or "no gate existed for this class"}
|
||||
- **Recurrence guard:** {concrete artifact preventing this class from returning — regression test (path:name) / assertion / lint rule / KB pattern / type refinement / config-default change}
|
||||
---
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user