Agent Skills Framework Extension
ADR Compliance Skill
When to Use This Skillâ
Use this skill when implementing adr compliance patterns in your codebase.
How to Use This Skillâ
- Review the patterns and examples below
- Apply the relevant patterns to your implementation
- Follow the best practices outlined in this skill
Architecture Decision Record creation, review, and compliance checking.
Core Capabilitiesâ
- ADR Creation - Generate ADRs from MADR template
- Review & Validation - Ensure ADR quality and completeness
- Compliance Checking - Validate against organizational standards
- Cross-ADR Consistency - Detect conflicts between decisions
- Lifecycle Management - Track status, supersession, deprecation
MADR Templateâ
# ADR-{NUMBER}: {TITLE}
**Status:** {Proposed | Accepted | Deprecated | Superseded}
**Date:** {YYYY-MM-DD}
**Deciders:** {List of decision makers}
**Technical Story:** {Link to issue/story if applicable}
## Context and Problem Statement
{Describe the context and problem that needs to be addressed.}
## Decision Drivers
* {Driver 1: e.g., scalability requirements}
* {Driver 2: e.g., team expertise}
* {Driver 3: e.g., cost constraints}
* {Driver 4: e.g., timeline pressure}
## Considered Options
1. {Option 1}
2. {Option 2}
3. {Option 3}
## Decision Outcome
**Chosen option:** "{Option X}", because {justification}.
### Positive Consequences
* {Positive consequence 1}
* {Positive consequence 2}
### Negative Consequences
* {Negative consequence 1}
* {Negative consequence 2}
## Pros and Cons of the Options
### {Option 1}
{Brief description}
* Good, because {argument a}
* Good, because {argument b}
* Bad, because {argument c}
* Bad, because {argument d}
### {Option 2}
{Brief description}
* Good, because {argument a}
* Bad, because {argument b}
### {Option 3}
{Brief description}
* Good, because {argument a}
* Bad, because {argument b}
## Links
* {Link to related ADR: [ADR-XXX](#)}
* {Link to related documentation}
* {Link to implementation PR}
## Implementation Notes
{Any notes about implementing this decision}
---
**Last Updated:** {YYYY-MM-DD}
ADR Validation Scriptâ
#!/usr/bin/env python3
"""
ADR Compliance Validator
Validates ADR files against MADR template and organizational standards.
"""
import re
import sys
from pathlib import Path
from dataclasses import dataclass, field
from typing import List, Optional
from enum import Enum
class Severity(Enum):
ERROR = "error"
WARNING = "warning"
INFO = "info"
@dataclass
class ValidationIssue:
severity: Severity
message: str
line: Optional[int] = None
section: Optional[str] = None
@dataclass
class ValidationResult:
file_path: Path
is_valid: bool
score: float # 0-100
issues: List[ValidationIssue] = field(default_factory=list)
REQUIRED_SECTIONS = [
"Status",
"Date",
"Context and Problem Statement",
"Decision Drivers",
"Considered Options",
"Decision Outcome",
"Pros and Cons of the Options",
]
OPTIONAL_SECTIONS = [
"Deciders",
"Technical Story",
"Positive Consequences",
"Negative Consequences",
"Links",
"Implementation Notes",
]
VALID_STATUSES = ["Proposed", "Accepted", "Deprecated", "Superseded"]
def validate_adr(file_path: Path) -> ValidationResult:
"""Validate an ADR file against MADR template."""
issues: List[ValidationIssue] = []
content = file_path.read_text()
lines = content.split('\n')
# Check title format
title_match = re.match(r'^# ADR-(\d+): (.+)$', lines[0] if lines else '')
if not title_match:
issues.append(ValidationIssue(
severity=Severity.ERROR,
message="Title must follow format: # ADR-{NUMBER}: {TITLE}",
line=1,
section="Title"
))
# Check status
status_match = re.search(r'\*\*Status:\*\* (.+)', content)
if not status_match:
issues.append(ValidationIssue(
severity=Severity.ERROR,
message="Missing Status field",
section="Status"
))
elif status_match.group(1).strip() not in VALID_STATUSES:
issues.append(ValidationIssue(
severity=Severity.ERROR,
message=f"Invalid status. Must be one of: {', '.join(VALID_STATUSES)}",
section="Status"
))
# Check date format
date_match = re.search(r'\*\*Date:\*\* (\d{4}-\d{2}-\d{2})', content)
if not date_match:
issues.append(ValidationIssue(
severity=Severity.ERROR,
message="Missing or invalid Date field. Use YYYY-MM-DD format",
section="Date"
))
# Check required sections
for section in REQUIRED_SECTIONS:
if section not in ["Status", "Date"]: # Already checked above
pattern = rf'^##\s+{re.escape(section)}'
if not re.search(pattern, content, re.MULTILINE):
issues.append(ValidationIssue(
severity=Severity.ERROR,
message=f"Missing required section: {section}",
section=section
))
# Check Decision Outcome has chosen option
decision_section = re.search(
r'## Decision Outcome\s+\*\*Chosen option:\*\* "(.+?)"',
content, re.DOTALL
)
if not decision_section:
issues.append(ValidationIssue(
severity=Severity.ERROR,
message="Decision Outcome must specify chosen option",
section="Decision Outcome"
))
# Check at least 2 options considered
options = re.findall(r'^### (.+)$', content, re.MULTILINE)
# Filter out standard sections
option_headers = [o for o in options if o not in REQUIRED_SECTIONS + OPTIONAL_SECTIONS]
if len(option_headers) < 2:
issues.append(ValidationIssue(
severity=Severity.WARNING,
message="Should consider at least 2 options",
section="Considered Options"
))
# Check for placeholder text
placeholders = re.findall(r'\{[^}]+\}', content)
if placeholders:
issues.append(ValidationIssue(
severity=Severity.WARNING,
message=f"Contains placeholder text: {placeholders[:3]}...",
section="Content"
))
# Check content length (not too short)
word_count = len(content.split())
if word_count < 200:
issues.append(ValidationIssue(
severity=Severity.WARNING,
message=f"ADR seems too brief ({word_count} words). Consider adding more detail",
section="Content"
))
# Calculate score
error_count = sum(1 for i in issues if i.severity == Severity.ERROR)
warning_count = sum(1 for i in issues if i.severity == Severity.WARNING)
score = max(0, 100 - (error_count * 15) - (warning_count * 5))
return ValidationResult(
file_path=file_path,
is_valid=error_count == 0,
score=score,
issues=issues
)
def validate_adr_directory(adr_dir: Path) -> List[ValidationResult]:
"""Validate all ADRs in a directory."""
results = []
for adr_file in sorted(adr_dir.glob("ADR-*.md")):
results.append(validate_adr(adr_file))
return results
def check_cross_adr_consistency(results: List[ValidationResult], adr_dir: Path) -> List[ValidationIssue]:
"""Check for consistency issues across ADRs."""
issues = []
adrs = {}
for result in results:
content = result.file_path.read_text()
# Extract ADR number
match = re.match(r'^# ADR-(\d+)', content)
if match:
adr_num = int(match.group(1))
adrs[adr_num] = {
'path': result.file_path,
'content': content,
'status': re.search(r'\*\*Status:\*\* (.+)', content)
}
# Check for gaps in numbering
if adrs:
numbers = sorted(adrs.keys())
for i in range(numbers[0], numbers[-1]):
if i not in numbers:
issues.append(ValidationIssue(
severity=Severity.WARNING,
message=f"Gap in ADR numbering: ADR-{i} is missing"
))
# Check superseded ADRs reference new ADR
for num, adr in adrs.items():
if adr['status'] and 'Superseded' in adr['status'].group(1):
if 'superseded by' not in adr['content'].lower():
issues.append(ValidationIssue(
severity=Severity.WARNING,
message=f"ADR-{num} is superseded but doesn't reference replacement",
section="Status"
))
return issues
def print_report(results: List[ValidationResult], cross_issues: List[ValidationIssue]):
"""Print validation report."""
print("=" * 60)
print("ADR COMPLIANCE REPORT")
print("=" * 60)
valid_count = sum(1 for r in results if r.is_valid)
total_count = len(results)
avg_score = sum(r.score for r in results) / total_count if results else 0
print(f"\nSummary: {valid_count}/{total_count} ADRs valid")
print(f"Average Score: {avg_score:.1f}/100")
print("-" * 60)
for result in results:
status = "â
" if result.is_valid else "â"
print(f"\n{status} {result.file_path.name} (Score: {result.score:.0f}/100)")
for issue in result.issues:
icon = {"error": "đ´", "warning": "đĄ", "info": "âšī¸"}[issue.severity.value]
section = f"[{issue.section}] " if issue.section else ""
print(f" {icon} {section}{issue.message}")
if cross_issues:
print("\n" + "-" * 60)
print("Cross-ADR Issues:")
for issue in cross_issues:
icon = {"error": "đ´", "warning": "đĄ", "info": "âšī¸"}[issue.severity.value]
print(f" {icon} {issue.message}")
print("\n" + "=" * 60)
if __name__ == "__main__":
adr_dir = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("docs/adrs")
if not adr_dir.exists():
print(f"Error: ADR directory not found: {adr_dir}")
sys.exit(1)
results = validate_adr_directory(adr_dir)
cross_issues = check_cross_adr_consistency(results, adr_dir)
print_report(results, cross_issues)
# Exit with error if any ADR is invalid
if not all(r.is_valid for r in results):
sys.exit(1)
ADR Status Workflowâ
âââââââââââââ Review âââââââââââââ
â Proposed âââââââââââââââ>â Accepted â
âââââââââââââ âââââââŦââââââ
â
âââââââââââââââââââââââŧââââââââââââââââââââââ
â â â
v v v
âââââââââââââââââ âââââââââââââââ âââââââââââââââ
â Deprecated â â Superseded â â Active â
âââââââââââââââââ âââââââââââââââ âââââââââââââââ
â â
â â
v v
âââââââââââââââââââââââââââââââââââââââ
â Archive â
âââââââââââââââââââââââââââââââââââââââ
Compliance Checklistâ
## ADR Compliance Checklist
### Structure (Required)
- [ ] Title follows format: ADR-{NUMBER}: {TITLE}
- [ ] Status field present (Proposed/Accepted/Deprecated/Superseded)
- [ ] Date in YYYY-MM-DD format
- [ ] Context and Problem Statement section
- [ ] Decision Drivers listed
- [ ] At least 2 options considered
- [ ] Decision Outcome with chosen option and justification
- [ ] Pros and Cons for each option
### Content Quality
- [ ] Problem statement is clear and specific
- [ ] Decision drivers are measurable where possible
- [ ] Options are genuinely different approaches
- [ ] Justification explains why chosen option best meets drivers
- [ ] Consequences (positive and negative) are realistic
- [ ] No placeholder text remaining
### Consistency
- [ ] ADR number is unique and sequential
- [ ] Links to related ADRs are valid
- [ ] Technical terms are consistent with glossary
- [ ] Superseded ADRs reference this ADR
### Review
- [ ] Reviewed by at least one other team member
- [ ] Implementation notes are actionable
- [ ] Links to implementation PRs (after implementation)
Usage Examplesâ
Create New ADRâ
Apply adr-compliance skill to create ADR-018 for selecting a message queue technology
Validate ADR Directoryâ
Apply adr-compliance skill to validate all ADRs in docs/03-architecture/adrs/
Check Compliance Scoreâ
Apply adr-compliance skill to generate compliance report for architecture decisions
Integration Pointsâ
- system-architecture-design - Architectural context for decisions
- code-review-patterns - ADR review workflow
- documentation-automation - ADR generation and indexing
Success Outputâ
When successful, this skill MUST output:
â
SKILL COMPLETE: adr-compliance
Completed:
- [x] ADR files validated against MADR template
- [x] All required sections present
- [x] Status and date fields formatted correctly
- [x] At least 2 options considered
- [x] Decision outcome specified with justification
- [x] Cross-ADR consistency checked
- [x] Compliance report generated
Validation Results:
- Total ADRs: {COUNT}
- Valid: {VALID_COUNT}
- Average score: {AVG_SCORE}/100
- Compliance level: {PERCENTAGE}%
Outputs:
- docs/adrs/ validated
- Compliance report: adr-compliance-report.txt
- Issues identified: {ISSUE_COUNT}
Completion Checklistâ
Before marking this skill as complete, verify:
- All ADR files follow ADR-{NUMBER}: {TITLE} format
- All ADRs have valid Status field (Proposed/Accepted/Deprecated/Superseded)
- All ADRs have Date in YYYY-MM-DD format
- All ADRs include required sections (7+ sections)
- All ADRs specify chosen option with justification
- At least 2 options considered in each ADR
- No placeholder text remaining ({...})
- Word count >= 200 for each ADR
- No gaps in ADR numbering sequence
- Superseded ADRs reference replacement ADR
- Validation script runs without errors
- Compliance score calculated for each ADR
Failure Indicatorsâ
This skill has FAILED if:
- â ADR title doesn't match format: ADR-{NUMBER}: {TITLE}
- â Status field missing or contains invalid value
- â Date field missing or wrong format
- â Required sections (Context, Drivers, Options, Outcome) missing
- â Decision outcome doesn't specify chosen option
- â Only 1 option considered (should be 2+)
- â Placeholder text still present: {driver 1}, {option X}
- â ADR too brief (<200 words)
- â Validation script exits with non-zero code
- â Python script has syntax errors
When NOT to Useâ
Do NOT use this skill when:
- Simple documentation updates - Use standard doc review for non-architectural changes
- Quick notes or drafts - ADR format is too formal for brainstorming
- Implementation details - Use code comments or design docs for low-level decisions
- Reversible decisions - ADRs are for significant, hard-to-reverse architectural choices
- Missing context - Can't validate ADR without understanding the problem domain
- Pre-proposal stage - Wait until options are identified before creating ADR
- Non-architectural decisions - Don't use ADR for process, policy, or business decisions
Anti-Patterns (Avoid)â
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Creating ADR for every decision | Noise drowns out important decisions | Reserve ADRs for significant architectural changes |
| Skipping "Considered Options" | Looks like decision was predetermined | Always document at least 2 alternatives considered |
| Placeholder text in production | Incomplete ADR provides no value | Replace all {...} placeholders before accepting |
| Missing justification | Can't understand why option was chosen | Always explain "because..." in Decision Outcome |
| No cross-ADR links | Decisions appear in isolation | Link related ADRs in Links section |
| Ignoring validation warnings | Low-quality ADRs accumulate | Address all warnings before merging |
| Changing accepted ADRs | Lost historical context | Supersede old ADRs, don't edit them |
Principlesâ
This skill embodies:
- #5 Eliminate Ambiguity - Clear status, date, and decision criteria
- #6 Clear, Understandable, Explainable - Structured template ensures consistency
- #8 No Assumptions - Validation checks enforce completeness
- #10 Security First - Compliance reviewer checks data handling and access control
- #11 Quality is Non-Negotiable - Score must be >= 70/100 for acceptance
- #12 Transparent Documentation - All decisions and rationale documented
Full Standard: CODITECT-STANDARD-AUTOMATION.md