diff --git a/.agents/skills/docs-governance/scripts/audit-docs.py b/.agents/skills/docs-governance/scripts/audit-docs.py index 15f6c3468..ea3a791b4 100644 --- a/.agents/skills/docs-governance/scripts/audit-docs.py +++ b/.agents/skills/docs-governance/scripts/audit-docs.py @@ -535,7 +535,12 @@ def check_adr_lifecycle( f"{diagnostic(path.relative_to(root))} -> {status}" ) successor = inline_adr_successor(text) - if successor and successor not in { + if status == "superseded" and successor is None: + report.fail( + "Superseded ADR is missing an inline successor: " + f"{diagnostic(path.relative_to(root))}" + ) + elif successor and successor not in { identifier for source_text in sources.values() if (identifier := adr_identifier(source_text)) is not None diff --git a/skills/docs-governance/scripts/audit-docs.py b/skills/docs-governance/scripts/audit-docs.py index 15f6c3468..ea3a791b4 100644 --- a/skills/docs-governance/scripts/audit-docs.py +++ b/skills/docs-governance/scripts/audit-docs.py @@ -535,7 +535,12 @@ def check_adr_lifecycle( f"{diagnostic(path.relative_to(root))} -> {status}" ) successor = inline_adr_successor(text) - if successor and successor not in { + if status == "superseded" and successor is None: + report.fail( + "Superseded ADR is missing an inline successor: " + f"{diagnostic(path.relative_to(root))}" + ) + elif successor and successor not in { identifier for source_text in sources.values() if (identifier := adr_identifier(source_text)) is not None diff --git a/tests/test_docs_governance_audit.py b/tests/test_docs_governance_audit.py index d7f8b1ee8..c62b5a921 100644 --- a/tests/test_docs_governance_audit.py +++ b/tests/test_docs_governance_audit.py @@ -400,6 +400,22 @@ def test_adr_scope_rejects_missing_inline_superseded_successor(project: Path) -> assert "ADR inline successor does not exist" in result.stdout +def test_adr_scope_rejects_superseded_status_without_successor(project: Path) -> None: + adr_dir = project / "docs" / "adr" + adr_dir.mkdir(parents=True) + (adr_dir / "README.md").write_text( + "[decision](0001-storage.md)\n", encoding="utf-8" + ) + (adr_dir / "0001-storage.md").write_text( + "# ADR-0001\n\n**Status**: superseded\n", encoding="utf-8" + ) + + result = run_audit(project, "adr") + + assert result.returncode == 1 + assert "Superseded ADR is missing an inline successor" in result.stdout + + def test_adr_scope_rejects_short_inline_superseded_successor(project: Path) -> None: adr_dir = project / "docs" / "adr" adr_dir.mkdir(parents=True)