Skip to content

feat: Implement ArchitectureDecisionsAssessor #81

Description

@jeremyeder

feat: Implement ArchitectureDecisionsAssessor

Attribute Definition

Attribute ID: architecture_decisions (Attribute #20 - Tier 3)

Definition: Lightweight documents capturing architectural decisions with context, decision, and consequences (ADRs).

Why It Matters: ADRs provide historical context for "why" decisions were made. When AI encounters patterns or constraints, ADRs explain rationale, preventing counter-productive suggestions.

Impact on Agent Behavior:

  • Understanding project evolution and design philosophy
  • Avoiding proposing previously rejected alternatives
  • Aligning suggestions with established architectural principles
  • Better context for refactoring recommendations

Measurable Criteria:

  • Store in docs/adr/ or .adr/ directory
  • Use consistent template (Michael Nygard or MADR)
  • Each ADR includes: Title, Status, Context, Decision, Consequences
  • Status values: Proposed, Accepted, Deprecated, Superseded
  • One decision per ADR
  • Sequential numbering (ADR-001, ADR-002...)

Implementation Requirements

File Location: src/agentready/assessors/documentation.py

Class Name: ArchitectureDecisionsAssessor

Tier: 3 (Important)

Default Weight: 0.015 (1.5% of total score)

Assessment Logic

Scoring Approach: Check for ADR directory and validate ADR format

Evidence to Check (score components):

  1. ADR directory exists (40%)

    • Check for: docs/adr/, .adr/, adr/, decisions/
    • Must contain at least one .md file
  2. ADR count and quality (40%)

    • Count ADR files
    • Check for consistent naming (0001-.md, ADR-001-.md)
    • Verify Markdown format
  3. ADR template compliance (20%)

    • Sample ADRs for required sections
    • Check for: Title, Status, Context, Decision, Consequences
    • Verify status field (Accepted, Proposed, etc.)

Scoring Logic:

if adr_dir_exists and adr_count > 0:
    dir_score = 40

    # Score based on ADR count
    if adr_count >= 5:
        count_score = 40
    else:
        count_score = adr_count * 8  # 8 points per ADR, up to 5

    # Sample ADRs for template compliance
    template_score = validate_adr_templates(sample_adrs)

    total_score = dir_score + count_score + template_score
else:
    total_score = 0

status = "pass" if total_score >= 75 else "fail"

Code Pattern to Follow

Reference: PreCommitHooksAssessor for directory/file existence check

Pattern:

  1. Check for ADR directory in common locations
  2. Count .md files in ADR directory
  3. Sample 2-3 ADRs to validate template compliance
  4. Check for required sections in ADR content
  5. Calculate score and provide remediation

Example Finding Responses

Pass (Score: 95)

Finding(
    attribute=self.attribute,
    status="pass",
    score=95.0,
    measured_value="8 ADRs",
    threshold="≥3 ADRs with template",
    evidence=[
        "ADR directory found: docs/adr/",
        "8 architecture decision records",
        "Consistent naming: 0001-use-postgresql.md",
        "Sampled 3 ADRs: all follow template",
        "Required sections present: Status, Context, Decision, Consequences",
    ],
    remediation=None,
    error_message=None,
)

Fail (Score: 40)

Finding(
    attribute=self.attribute,
    status="fail",
    score=40.0,
    measured_value="1 ADR (incomplete)",
    threshold="≥3 ADRs with template",
    evidence=[
        "ADR directory found: docs/adr/",
        "Only 1 ADR file",
        "ADR missing required sections (no Consequences)",
        "Inconsistent format",
    ],
    remediation=self._create_remediation(),
    error_message=None,
)

Not Applicable

Finding.not_applicable(
    self.attribute,
    reason="Small project (<1000 lines) may not need formal ADRs"
)

Registration

Add to src/agentready/services/scanner.py in create_all_assessors():

from ..assessors.documentation import (
    CLAUDEmdAssessor,
    READMEAssessor,
    OpenAPISpecsAssessor,
    ArchitectureDecisionsAssessor,  # Add this import
)

def create_all_assessors() -> List[BaseAssessor]:
    return [
        # ... existing assessors ...
        ArchitectureDecisionsAssessor(),  # Add this line
    ]

Testing Guidance

Test File: tests/unit/test_assessors_documentation.py

Test Cases to Add:

  1. test_adr_pass_multiple_records: Repository with 5+ well-formatted ADRs
  2. test_adr_fail_no_directory: No ADR directory found
  3. test_adr_partial_incomplete_template: ADRs exist but missing sections
  4. test_adr_fail_empty_directory: ADR directory exists but empty
  5. test_adr_not_applicable: Very small project (<1000 lines)

Note: AgentReady doesn't have ADRs yet (opportunity for improvement), will likely fail.

Dependencies

External Tools: None (file system and Markdown parsing)

Python Standard Library:

  • pathlib.Path for directory/file operations
  • re for parsing ADR sections

Remediation Steps

def _create_remediation(self) -> Remediation:
    return Remediation(
        summary="Create architecture decision records for major design choices",
        steps=[
            "Create docs/adr/ directory",
            "Start with ADR template (Michael Nygard or MADR format)",
            "Document significant architectural decisions",
            "Include: Status, Context, Decision, Consequences",
            "Use sequential numbering: 0001-decision-name.md",
            "Update ADRs when decisions change (add Superseded status)",
        ],
        tools=["adr-tools", "log4brains"],
        commands=[
            "# Install ADR tools",
            "npm install -g adr-log",
            "",
            "# Initialize ADR directory",
            "mkdir -p docs/adr",
            "",
            "# Create first ADR",
            "adr new 'Use PostgreSQL for primary database'",
        ],
        examples=[
            """# docs/adr/0001-use-postgresql.md

# ADR-001: Use PostgreSQL for Primary Database

**Status**: Accepted

**Date**: 2025-01-15

## Context

Need persistent storage supporting ACID transactions, complex queries, and JSON data.

Considered alternatives:
- MongoDB (NoSQL, flexible schema)
- MySQL (relational, widely supported)
- PostgreSQL (relational, advanced features)

## Decision

Use PostgreSQL 14+ as primary database.

## Consequences

**Positive**:
- Strong ACID guarantees
- Rich query capabilities (joins, window functions, CTEs)
- JSON support via jsonb for semi-structured data
- Excellent ecosystem and tooling
- Proven at scale

**Negative**:
- More operational complexity than managed NoSQL
- Requires schema migration planning
- Horizontal scaling more complex than cloud-native databases

**Neutral**:
- Team needs PostgreSQL training
- Development environment requires PostgreSQL installation
""",
        ],
        citations=[
            Citation(
                source="AWS Prescriptive Guidance",
                title="Architecture Decision Records",
                url="https://docs.aws.amazon.com/prescriptive-guidance/latest/architectural-decision-records/",
                relevance="Guide to creating and maintaining ADRs",
            ),
            Citation(
                source="GitHub",
                title="ADR Template Collection",
                url="https://github.com/joelparkerhenderson/architecture-decision-record",
                relevance="Templates and examples for ADRs",
            ),
        ],
    )

Implementation Notes

  1. Directory Detection: Check docs/adr/, .adr/, adr/, decisions/
  2. File Counting: Use .glob("*.md") to find ADR files
  3. Naming Validation: Regex for sequential numbering: r'^\d{4}-.*\.md$' or r'^ADR-\d{3}-.*\.md$'
  4. Template Validation: Search for keywords in content: "Status:", "Context", "Decision", "Consequences"
  5. Sampling: Read 2-3 ADRs to validate format (not all, for performance)
  6. Not Applicable: Small projects (<1000 LOC) don't need formal ADRs
  7. Edge Cases: Empty ADR directory scores 0, not not_applicable

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions