Skip to content

Check_adr

FieldValue
TypeSkill Resource
Source~/.copilot/skills/adr/scripts/check_adr.py
DescriptionNot specified

Source Content

#!/usr/bin/env python3
"""Check an ADR file matches templates/adr-template.md's section skeleton.
Usage: check_adr.py <adr-file.md>
"""
import re
import sys
REQUIRED_SECTIONS = ["Decision", "Key rules", "Why", "Applies when", "Related"]
VALID_STATUSES = {"proposed", "accepted", "deprecated", "superseded"}
def main() -> int:
if len(sys.argv) != 2:
print("Usage: check_adr.py <adr-file.md>", file=sys.stderr)
return 2
text = open(sys.argv[1], encoding="utf-8").read()
fail = 0
fm = re.match(r"^---\n(.*?)\n---\n", text, re.DOTALL)
if not fm:
print("❌ no YAML frontmatter found (expected --- id/status/collection ... ---)")
fail = 1
else:
frontmatter = fm.group(1)
status_match = re.search(r"^status:\s*(\S+)", frontmatter, re.MULTILINE)
status = status_match.group(1).strip('"\'') if status_match else None
if status is None:
print("❌ frontmatter has no 'status' field")
fail = 1
elif status.lower() not in VALID_STATUSES:
print(f"❌ status '{status}' is not one of {sorted(VALID_STATUSES)}")
fail = 1
else:
print(f"✅ status: {status}")
if status and status.lower() == "superseded" and "ZZ-deprecated" not in sys.argv[1]:
print("❌ status is 'superseded' but the file is not under references/ZZ-deprecated/ — move it")
fail = 1
for section in REQUIRED_SECTIONS:
if re.search(rf"^##\s+{re.escape(section)}\b", text, re.MULTILINE):
print(f"✅ section '## {section}' present")
else:
print(f"❌ missing section: '## {section}'")
fail = 1
if re.search(r"\{\{.*?\}\}", text):
print("❌ found unfilled template placeholder(s) like {{...}} — this ADR isn't finished")
fail = 1
else:
print("✅ no unfilled {{...}} template placeholders")
return fail
if __name__ == "__main__":
raise SystemExit(main())