Problem
SKILL.MD preflight says: "Note existing ADR slugs — skip any chunk whose diff is already covered by an existing ADR (match by commit hash in the Links section)." But analyze.py doesn't implement this — it only computes next_adr_number(). Dedup is left entirely to agent discipline, which is exactly the kind of step that gets skipped on re-runs, producing duplicate ADRs for the same decision with new numbers.
Re-running on a growing repo is the primary long-term usage pattern (generate once, re-run quarterly), so incremental behavior should be deterministic, not prose.
Fix
In analyze() preflight:
- Scan the scope-resolved
output_dir for NNNN-*.md files.
- Extract linked SHAs from each (the template's
## Links → Commits: line; tolerate short SHAs via prefix match).
- Mark any candidate whose commit set is fully covered ⇒
classification: "already_covered" (with the covering ADR's filename in signals). Partially covered ⇒ keep, but add a partially_covered_by note so the agent can extend the existing ADR instead of writing a new one.
- Report
covered_candidates count in preflight.
Acceptance
- Fixture repo with an existing ADR linking commits A,B: re-running analyze marks the A+B candidate
already_covered; a new candidate C is unaffected.
- Short-SHA links (7 chars) match full SHAs.
Problem
SKILL.MD preflight says: "Note existing ADR slugs — skip any chunk whose diff is already covered by an existing ADR (match by commit hash in the Links section)." But
analyze.pydoesn't implement this — it only computesnext_adr_number(). Dedup is left entirely to agent discipline, which is exactly the kind of step that gets skipped on re-runs, producing duplicate ADRs for the same decision with new numbers.Re-running on a growing repo is the primary long-term usage pattern (generate once, re-run quarterly), so incremental behavior should be deterministic, not prose.
Fix
In
analyze()preflight:output_dirforNNNN-*.mdfiles.## Links→Commits:line; tolerate short SHAs via prefix match).classification: "already_covered"(with the covering ADR's filename insignals). Partially covered ⇒ keep, but add apartially_covered_bynote so the agent can extend the existing ADR instead of writing a new one.covered_candidatescount in preflight.Acceptance
already_covered; a new candidate C is unaffected.