Skip to main content

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​

  1. Review the patterns and examples below
  2. Apply the relevant patterns to your implementation
  3. Follow the best practices outlined in this skill

Architecture Decision Record creation, review, and compliance checking.

Core Capabilities​

  1. ADR Creation - Generate ADRs from MADR template
  2. Review & Validation - Ensure ADR quality and completeness
  3. Compliance Checking - Validate against organizational standards
  4. Cross-ADR Consistency - Detect conflicts between decisions
  5. 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-PatternProblemSolution
Creating ADR for every decisionNoise drowns out important decisionsReserve ADRs for significant architectural changes
Skipping "Considered Options"Looks like decision was predeterminedAlways document at least 2 alternatives considered
Placeholder text in productionIncomplete ADR provides no valueReplace all {...} placeholders before accepting
Missing justificationCan't understand why option was chosenAlways explain "because..." in Decision Outcome
No cross-ADR linksDecisions appear in isolationLink related ADRs in Links section
Ignoring validation warningsLow-quality ADRs accumulateAddress all warnings before merging
Changing accepted ADRsLost historical contextSupersede 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