diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68fc974..d4f6ca3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,20 +7,15 @@ on: branches: [ main ] jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - python-version: ["3.10", "3.11", "3.12", "3.13"] - + lint: + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - name: Set up Python ${{ matrix.python-version }} + + - name: Set up Python 3.11 uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python-version }} + python-version: "3.11" - name: Install uv uses: astral-sh/setup-uv@v6 @@ -30,61 +25,55 @@ jobs: - name: Install dependencies run: | uv pip install --system -e ".[dev]" - + - name: Run linting with ruff run: | ruff check adr_kit/ tests/ - + - name: Check code formatting with black run: | black --check adr_kit/ tests/ - + - name: Run type checking with mypy run: | mypy adr_kit/ - - - name: Run tests with pytest - run: | - pytest tests/ --cov=adr_kit --cov-report=xml --cov-report=term-missing - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' - with: - file: ./coverage.xml - flags: unittests - name: codecov-umbrella + test: + needs: lint + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + python-version: ["3.10", "3.11", "3.12", "3.13"] + exclude: + - os: macos-latest + python-version: "3.10" - validate-adrs: - runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Python + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: ${{ matrix.python-version }} - name: Install uv uses: astral-sh/setup-uv@v6 with: enable-cache: true - - name: Install ADR Kit - run: | - uv pip install --system -e . - - - name: Validate project ADRs - run: | - adr-kit validate --adr-dir docs/adr || echo "ADR validation completed with issues" - - - name: Generate ADR index + - name: Install dependencies run: | - adr-kit index --out docs/adr/adr-index.json --adr-dir docs/adr --no-validate - - - name: Check ADR index was updated + uv pip install --system -e ".[dev]" + + - name: Run tests with pytest run: | - if [ ! -f "docs/adr/adr-index.json" ]; then - echo "ADR index was not generated" - exit 1 - fi \ No newline at end of file + pytest tests/ --cov=adr_kit --cov-report=xml --cov-report=term-missing + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' + with: + file: ./coverage.xml + flags: unittests + name: codecov-umbrella diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..e7350fa --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,43 @@ +name: Release + +on: + push: + tags: + - 'v*' + +jobs: + release: + runs-on: ubuntu-latest + permissions: + contents: write # Create GitHub Release + id-token: write # PyPI Trusted Publishing (OIDC) + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install dependencies + run: uv pip install --system -e ".[dev]" + + - name: Run tests + run: pytest tests/ + + - name: Build + run: uv build + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f7cc33e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,105 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- `CHANGELOG.md` with full version history +- `TECHNICAL.md` with implementation details for each layer +- `CONTRIBUTING.md` with development environment setup +- `SECURITY.md` with supported versions and vulnerability reporting +- Release CI workflow (`.github/workflows/release.yml`) with PyPI Trusted Publishing and automated GitHub Release creation +- "Releasing" section in `CLAUDE.md` documenting the tag-based release process + +### Changed +- README rewritten for user focus: problem statement, quick start, tool reference, FAQ +- `ROADMAP.md` "Recent Additions" section replaced with link to this changelog +- CI workflow consolidated from 13 to 8 checks: dedicated lint job (blocks tests), trimmed test matrix to `(ubuntu + macOS) × (3.11–3.13) + ubuntu-only 3.10` + +### Fixed +- `pyproject.toml` project URLs updated from placeholder `your-org` to correct `kschlt` +- Added Python 3.13 classifier to package metadata + +--- + +## [0.2.7] - 2026-02-10 + +### Added +- Decision quality guidance system: two-phase ADR creation with structured reasoning steps, quality criteria, and anti-pattern examples +- Pre-validation quality gate: quality check runs before file creation, enabling correction loop without partial files — ADRs below B-grade threshold (75 pts) return `REQUIRES_ACTION` with improvement guidance +- `skip_quality_gate` parameter on `adr_create` for test overrides +- Pattern policy models (`PatternRule`, `PatternPolicy`) with JSON schema +- Architecture policy models (`LayerBoundaryRule`, `RequiredStructure`, `ArchitecturePolicy`) with JSON schema +- Config enforcement models (`TypeScriptConfig`, `PythonConfig`, `ConfigEnforcementPolicy`) with JSON schema +- `adr_create` policy suggestion engine: auto-detects policy candidates from decision text and returns a structured promptlet guiding policy construction +- AI warning extraction in `adr_planning_context`: consequences containing warnings are surfaced for relevant decisions +- Domain filtering in `adr_planning_context` for 60–80% context reduction + +### Changed +- Integration test architecture: replaced ~308 lines of regex extraction with a reasoning-agent promptlet. Agents reason about policies from their own decision text rather than ADR Kit extracting via pattern matching +- MCP tool documentation moved from static docstrings to just-in-time response payloads (context-efficient ping-pong pattern) + +### Fixed +- `adr_create` content generation simplified to prevent empty sections + +--- + +## [0.2.6] - 2025-12-15 + +### Added +- Policy validation warnings for ADR creation — front-matter policy blocks are validated on `adr_create` +- Constraint extraction guide and example ADR fixtures +- MCP server configuration for development (`.mcp.json`) +- Middleware to fix stringified JSON parameters from buggy MCP clients + +### Changed +- Project structure refactored and developer documentation improved +- Version read dynamically from package metadata + +### Fixed +- CLI version detection with semantic comparison +- `uv run` prefix added to all Makefile tool commands + +--- + +## [0.2.5] - 2025-11-01 + +### Added +- Complete MCP server redesign with clean entry points and comprehensive tests +- Strict mypy type safety configuration +- Full test suite reorganization (unit / integration / MCP server) +- Python 3.10 compatibility fixes (`datetime.timezone.utc`) + +### Changed +- Migrated from pipx to uv for package installation +- CI Python version matrix updated to match package requirements (`3.10+`) +- `setup-uv` action upgraded from v4 to v6 + +### Fixed +- MCP server startup `TypeError` (Rich console parameter) +- MCP server `next_steps` type compatibility +- Windows-specific test failures +- All deprecation warnings eliminated + +--- + +## [0.1.0] - 2025-09-03 + +Initial release. + +- 6 MCP tools: `adr_analyze_project`, `adr_preflight`, `adr_create`, `adr_approve`, `adr_supersede`, `adr_planning_context` +- MADR format with optional `policy` block for enforcement +- ESLint and Ruff rule generation from import policies +- Selective context loading by task relevance +- Local semantic search via sentence-transformers and FAISS +- `adr-kit init`, `setup-cursor`, `setup-claude` CLI commands + +[Unreleased]: https://github.com/kschlt/adr-kit/compare/v0.2.7...HEAD +[0.2.7]: https://github.com/kschlt/adr-kit/compare/v0.2.6...v0.2.7 +[0.2.6]: https://github.com/kschlt/adr-kit/compare/v0.2.5...v0.2.6 +[0.2.5]: https://github.com/kschlt/adr-kit/compare/v0.1.0...v0.2.5 +[0.1.0]: https://github.com/kschlt/adr-kit/releases/tag/v0.1.0 diff --git a/CLAUDE.md b/CLAUDE.md index a999eb7..0bd8b18 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,3 +1,19 @@ +## Releasing + +1. Bump version in `pyproject.toml` +2. Update `CHANGELOG.md` — move items from `[Unreleased]` to new `[X.Y.Z]` section with today's date +3. Commit: `git commit -m "chore: bump version to X.Y.Z"` +4. Tag: `git tag vX.Y.Z` +5. Push tag: `git push origin vX.Y.Z` +6. CI runs automatically: tests → build → PyPI publish → GitHub Release + +**PyPI Trusted Publishing** is configured (kschlt/adr-kit, workflow: `release.yml`). +No tokens needed. If CI publish fails, fallback: `scripts/publish.sh` (requires `~/.pypirc`). + +> **One-time setup** (already done): pypi.org → adr-kit project → Manage → Publishing → add trusted publisher: owner `kschlt`, repo `adr-kit`, workflow `release.yml`. + +--- + # Project Context: What You're Building **You are developing ADR Kit** - a Python library and CLI tool that other projects install to manage their Architectural Decision Records. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..93f7d18 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,77 @@ +# Contributing to ADR Kit + +Thank you for your interest in contributing to ADR Kit. + +## Getting Started + +**Prerequisites**: Python 3.10+, [uv](https://github.com/astral-sh/uv) + +```bash +git clone https://github.com/kschlt/adr-kit.git +cd adr-kit +uv pip install -e ".[dev]" +``` + +## Development Workflow + +### Running Tests + +```bash +# Unit tests (fast) +pytest tests/unit/ + +# All tests +pytest tests/ + +# With coverage +pytest tests/ --cov=adr_kit +``` + +### Quality Checks + +```bash +ruff check adr_kit/ tests/ # Linting +black adr_kit/ tests/ # Formatting +mypy adr_kit/ # Type checking +``` + +Or use the Makefile: + +```bash +make lint # ruff + mypy +make format # black + ruff +make test-all # all tests +``` + +### MCP Server + +ADR Kit's primary interface is an MCP server. To test it manually: + +```bash +uv run adr-kit mcp-server +``` + +Always use `uv run adr-kit` (not a bare `adr-kit`) to ensure you're running the local editable install, not a system-wide version. + +**Detailed developer documentation:** See [CLAUDE.md](CLAUDE.md) for comprehensive instructions, including: +- The three versions of ADR Kit (source, local install, system install) and which to use when +- Development workflow (Edit → Test → Verify) +- Testing the MCP server with local changes +- Project structure and what gets packaged vs what's dev-only + +## Submitting Changes + +1. Fork the repository and create a branch from `main` +2. Make your changes with tests +3. Ensure all quality checks pass (`make lint && make test-all`) +4. Open a pull request against `main` + +Please keep PRs focused — one concern per PR. Large refactors should be discussed in an issue first. + +## Reporting Issues + +Use [GitHub Issues](https://github.com/kschlt/adr-kit/issues). Include: +- ADR Kit version (`adr-kit --version`) +- Python version +- Steps to reproduce +- Expected vs actual behaviour diff --git a/README.md b/README.md index 35d1b8b..e493ad7 100644 --- a/README.md +++ b/README.md @@ -4,128 +4,28 @@ Keep AI agents architecturally consistent. [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Tests](https://img.shields.io/badge/tests-comprehensive-green)](#reliability--testing) -> **👥 For users:** Install ADR Kit in your project → [Quick Start](#quick-start) -> **🔧 For contributors:** Develop on ADR Kit itself → [Development](#development) +## The Problem -## The Concept of Architectural Decision Records +Each new chat with your AI agent (Cursor, Claude Code, Copilot) starts with blank context: -**The core idea**: When multiple people work on the same project, they need to align on significant technical choices. When the team agrees on a decision—React over Vue, PostgreSQL over MongoDB, microservices over monolith—they document it as an Architectural Decision Record: +- **Monday**: "Use React Query" → implements with React Query +- **Wednesday**: New chat → uses axios (no memory of Monday) +- **Friday**: Different conversation → uses fetch() again -- **Context**: Why was this decision needed? -- **Decision**: What did we choose? -- **Consequences**: What are the trade-offs? -- **Alternatives**: What did we reject and why? +The standard solution — Architectural Decision Records (ADRs) — doesn't transfer directly. An agent can't read all your ADRs upfront without burning the context window before the actual work begins. And most projects don't have ADRs at all, because manual maintenance was too much overhead. -**The team alignment mechanism**: Once a decision is recorded, everyone must either follow it or propose a new decision to be discussed with the team. ADRs also maintain a track record of how decisions evolved—when they were superseded, why they changed. +**ADR Kit bridges the gap**: AI agents create and maintain ADRs automatically. Relevant decisions are loaded into context selectively, only when needed. Violations are caught by lint rules generated directly from your ADRs. -**How this works in practice**: New team members read the ADRs once during onboarding to understand what was agreed upon. Existing members don't read them every morning—they just know the decisions exist and can check back when needed because they've been working in the codebase for a while. +## How It Works -**The problem this concept solves**: Without written agreements, architectural consistency erodes. Team members make conflicting choices because they don't know what was already decided. +ADR Kit operates in three layers: -**The benefit**: ADRs create explicit team agreements with historical context that survive beyond individual memory and onboard new members effectively. +**1. Lifecycle Management** — AI detects when a decision has architectural relevance, checks for existing ADRs, and either applies them or proposes a new one. Quality gate: vague decisions ("use a modern framework") are rejected before any file is created. When a decision evolves, the old ADR is superseded — never edited — preserving the full history. -This concept has proven valuable for human teams. Now we're in the era of AI-driven development, where the problem is similar but fundamentally different in how it needs to be solved. +**2. Context at the Right Time** — Before implementing a feature, ADR Kit surfaces only the relevant decisions. Out of 50 ADRs, 3–5 relevant ones reach the agent's context. Right information, right time, without flooding the context window. -## The AI-Driven Development Challenge - -**The similar problem**: Like human teams, we need architectural consistency across work sessions. Each new chat with your AI agent (Cursor, Claude Code, Copilot) is like onboarding a fresh team member with blank context. - -**The key difference from human teams**: - -In a **human team**, new members: -- Read all ADRs once during onboarding -- Remember they exist from working in the codebase -- Check back when needed because they have context - -In **AI-driven development**, each chat: -- Starts with blank context (sometimes project info is preloaded, but generally it's a fresh start) -- Cannot read all ADRs like a human—that would waste valuable context window -- Would be "tired by the end of the context window" before even starting to solve the actual problem -- Needs only the relevant decisions for the current challenge, at the right point in time - -**The second problem: ADRs don't exist yet**: Most projects don't have Architectural Decision Records at all. They were never created because manual ADR maintenance was too much overhead for human teams. - -**Result without selective context loading**: -- **Monday**: "Use React Query" → Implements with React Query -- **Wednesday**: New chat, new context → Uses axios (no memory of Monday) -- **Friday**: Different conversation → Uses fetch() (different approach again) - -The ADR concept solves the alignment problem, but AI-driven development requires a different approach: decisions must be created automatically, maintained as they evolve, and loaded selectively into context only when needed for the current challenge. - -## ADR Kit: Introducing ADRs for AI-Driven Development - -ADR Kit brings the proven ADR concept to AI-driven development, adapting how it works to solve the challenges we just outlined: - -Instead of humans reading all ADRs once during onboarding, ADR Kit **selectively loads only relevant ADRs** into AI context at decision time. Instead of humans maintaining ADRs manually, **AI agents create and maintain them automatically**. The concept stays the same—session alignment on architectural decisions—but the implementation changes for the reality of AI agents. - -**Works for both existing and new projects**: Whether you're working with an existing codebase (brownfield) or starting fresh (greenfield), ADR Kit adapts to your situation. Brownfield projects need initial discovery of implicit decisions and may require migration work for conflicts. Greenfield projects can create ADRs from the start, avoiding drift entirely. Both use the same three-layer mechanism. - -Here's how ADR Kit solves three interconnected problems: - -**1. ADR Lifecycle Management** - During every chat session, AI detects when a decision has architectural relevance. It checks: "Do we have an ADR for this?" If not, it proposes creating one. If yes, it loads the context to apply it—or challenges whether the decision needs to evolve. The AI manages the full lifecycle: create new ADRs, supersede outdated ones, and maintain them as your architecture evolves. This happens continuously, not just during initial setup. - -**2. Context at the Right Time** - No matter how good the AI model, it needs the right context at the right time to make decisions. ADR Kit surfaces relevant ADRs automatically when needed—before the AI reasons about solutions. Not all ADRs dumped into context, only the relevant ones, only when needed. This is fundamental to AI-driven development. - -**3. Enforcement with Feedback Loop** - Even when AI receives context, it can make mistakes or ignore constraints. Automated enforcement (linting, CI checks) catches violations and provides direct feedback explaining why it violates the agreed-upon decision. This triggers management: either fix the code to comply, or supersede the ADR with a new decision if it needs to evolve. The whole mechanism—create, maintain, enforce, feedback—is baked into ADR Kit. - -### How This Works: Three-Layer Approach - -ADR Kit introduces ADRs to your project with three active layers: - -**Layer 1: ADR Lifecycle Management** - Continuous detection and management during chat sessions -- AI detects architectural relevance: "This decision seems architecturally significant" -- Checks: "Do we have an ADR for this already?" -- If not: Proposes creating new ADR -- If yes: Loads context to apply it, or challenges if decision needs to evolve -- Manages full lifecycle: Create, supersede outdated decisions, maintain as architecture evolves -- Quality gate: Reject vague decisions ("use a modern framework") that can't be enforced -- Works continuously: Not just initial setup, but every chat session where architectural decisions emerge - -**Layer 2: Context at the Right Time** - Surface relevant information when decisions are being made -- Task: "Implement authentication" → Automatically loads ADR-0005 (Auth0), ADR-0008 (JWT structure) -- Filters by relevance: Only 3-5 relevant ADRs, never all 50—don't blow the context window -- Timing: Before AI reasons about solutions, while it's making decisions -- Automation: ADR Kit ensures relevant context is always surfaced when needed, regardless of which AI agent you use -- Goal: Right information, right time, every time—no matter how good the model is - -**Layer 3: Enforcement with Feedback Loop** - Catch violations and trigger management -- Approved ADRs → ESLint/Ruff rules automatically generated -- Developer (or AI) violates constraint → Linter blocks with ADR reference and explanation -- Feedback triggers decision: Fix code to comply, or supersede the ADR if decision needs to evolve -- Works independent of whether context was loaded or AI made a mistake -- Completes the cycle: violations feed back into management (maintain or supersede) - -### Integration into AI-Driven Development Cycle - -ADR Kit integrates into your AI development workflow at critical decision points: - -```mermaid -graph TD - Request[Feature request] --> Context[adr_planning_context] - Context -->|Loads relevant ADRs| Choice[AI proposes technical choice] - Choice --> Preflight[adr_preflight] - Preflight -->|Decision exists| Implement[AI implements feature] - Preflight -->|New decision needed| Create[adr_create] - Create -->|Proposes ADR| Review[You review proposed ADR] - Review --> Approve[adr_approve] - Approve -->|Generates enforcement rules| Implement - Implement --> Linter[Linter runs] - Linter -->|No violations| Done[Done] - Linter -->|Violation detected| Feedback{Fix or evolve?} - Feedback -->|Fix code| Implement - Feedback -->|Supersede ADR| Create - - style Context fill:#90EE90 - style Preflight fill:#90EE90 - style Create fill:#90EE90 - style Approve fill:#FFE4B5 - style Linter fill:#FFE4B5 - style Feedback fill:#FFB6C1 -``` - -**The complete cycle**: Violations aren't dead ends—they feed back into ADR management. Either fix the code to comply, or supersede the decision with a new ADR. The whole mechanism—create, serve context, enforce, provide feedback—is baked into one system. +**3. Enforcement** — Approved ADRs automatically generate ESLint and Ruff lint rules. Violations are blocked with a clear reference to the decision they violate, triggering a choice: fix the code, or supersede the ADR if the decision needs to evolve. ## Quick Start @@ -135,250 +35,69 @@ graph TD uv tool install adr-kit ``` -### Setup Your Project +Or try without installing: + +```bash +uvx adr-kit --help +``` + +### Connect to Your AI Agent ```bash cd your-project -adr-kit init # Creates docs/adr/ directory -adr-kit setup-cursor # or setup-claude for Claude Code +adr-kit init # Creates docs/adr/ +adr-kit setup-cursor # or: adr-kit setup-claude ``` -This connects ADR Kit to your AI agent via MCP (Model Context Protocol). +This connects ADR Kit to your AI agent via MCP. -### Start Using It +### Start Working -Once set up, ADR Kit works in every chat session — whether your project is new or established: +ADR Kit works in every chat session, whether your project is new or established: ``` You: "Let's use FastAPI for the backend API" AI: [Calls adr_preflight({choice: "fastapi"})] -AI: "No existing ADR. I'll propose one for FastAPI." +AI: "No existing ADR. I'll propose one." AI: [Calls adr_create()] → Proposes ADR-0001 (status: proposed) -AI: "Here's the proposed ADR-0001. Review it?" +AI: "Here's the proposed ADR. Review it?" You: "Looks good, approve it" AI: [Calls adr_approve()] → Enforcement now active ``` -The AI detects architectural decisions as you work, proposes ADRs, and you review and approve. It also catches decisions made implicitly — like noticing you're importing React everywhere and suggesting to document it. -
-Existing codebase? Start with project analysis +Starting with an existing codebase? -If you have an existing project, let the AI discover the architectural decisions already baked into your code: +Let the AI discover the architectural decisions already baked into your code: ``` You: "Analyze my project for architectural decisions" AI: [Calls adr_analyze_project()] -AI: "If I'm reading this correctly, you're using React, TypeScript, PostgreSQL, Docker" -AI: "I also found a potential conflict: PostgreSQL is used in 80% of the code, - but MySQL appears in the legacy module. Should I document both or propose - migrating to consistent PostgreSQL usage?" +AI: "You're using React, TypeScript, PostgreSQL, Docker." +AI: "Found a conflict: PostgreSQL in 80% of code, MySQL in the legacy module. + Document both, or propose migrating to consistent PostgreSQL usage?" ``` -Review the proposed ADRs, approve the ones that accurately reflect your decisions: - -``` -You: "Approve ADR-0001 through ADR-0003. For the database conflict, let's - document PostgreSQL as the standard and create a migration plan for the - legacy module." -AI: [Calls adr_approve() for each, notes the migration decision] -``` - -Now your implicit decisions are explicit, documented, and enforced. From this point forward, the workflow is the same as above — AI references these ADRs when implementing features and ADR Kit blocks violations. +Review and approve the proposed ADRs. Your implicit decisions are now explicit, documented, and enforced.
-## How It Works: Technical Deep Dive - -This section explains the mechanics of each layer with concrete examples. - -### Layer 1: ADR Lifecycle Management (Continuous Detection & Evolution) - -**The Problem**: Architectural decisions emerge during development, but without active management they're never documented or maintained as they evolve. - -**The Solution**: AI continuously detects architectural relevance during chat sessions → Checks for existing ADRs → Proposes creating them. The creation flow is covered in [Quick Start](#quick-start) above. This section focuses on what happens after: evolution and quality control. - -**When a decision needs to evolve** (supersede, never update): - -ADRs are immutable records. When a decision needs to change, you supersede it with a new ADR — the old one stays as historical record. - -``` -You: "Actually, we need axios for this specific external API integration" -AI: [Detects conflict with ADR-0003: Use React Query] -AI: "This conflicts with ADR-0003. ADRs are immutable records, so we have two options: - A) Find a React Query solution that works here - B) Supersede ADR-0003 with a new decision that allows axios for external APIs" -You: "Option B" -AI: [Calls adr_supersede()] → Proposes ADR-0015, marks ADR-0003 as superseded -AI: "ADR-0015 allows axios for external API integrations while keeping React Query - as default. Note: 3 existing files use React Query for external calls — - these would need to migrate to axios for consistency with the new decision." -``` - -Superseding always surfaces migration implications — the AI identifies what existing code needs to change to align with the new decision. - -**Quality Gate**: ADR Kit ensures decisions are specific enough to enforce: -- ❌ "Use a modern framework" → Rejected (too vague) -- ✅ "Use React 18. Don't use Vue or Angular." → Accepted (specific, has constraints) - -**Continuous operation**: This layer works throughout development, not just during initial setup. Every chat session where architectural decisions emerge triggers this detection and management cycle. - -### Layer 2: Context Loading (Right Information, Right Time) - -**The Problem**: AI can't remember decisions from previous conversations. - -**The Solution**: Before implementing features, AI asks "what architectural constraints apply here?" - -``` -Task: "Implement user authentication" -Domain: backend, security - -ADR Kit returns: -✅ ADR-0005: Use Auth0 for Authentication - - Constraint: Don't implement custom auth - - Warning: ⚠️ Rate limiting required on auth endpoints - -✅ ADR-0008: JWT Token Structure - - Constraint: Access tokens expire in 1 hour - - Constraint: Refresh tokens stored in httpOnly cookies - -Filtered out (not relevant): -❌ ADR-0001: React Query (frontend) -❌ ADR-0012: CSS-in-JS (styling) -``` - -**How**: `adr_planning_context` tool filters ADRs by task relevance, surfaces warnings from ADR consequences, returns only 3-5 relevant decisions instead of flooding context with all 50 ADRs. - -### Layer 3: Enforcement with Feedback Loop - -**The Problem**: Even with documentation, AI can make mistakes or forget context. - -**The Solution**: Approved ADRs become automated lint rules that provide feedback. - -```yaml -# ADR-0003: Use React Query for data fetching -policy: - imports: - prefer: [react-query, @tanstack/react-query] - disallow: [axios] -``` - -Automatically generates: - -```json -// .eslintrc.adrs.json (auto-generated, don't edit) -{ - "rules": { - "no-restricted-imports": [ - "error", - { - "paths": [{ - "name": "axios", - "message": "Use React Query instead (ADR-0003)" - }] - } - ] - } -} -``` - -**Enforcement with Feedback**: -```javascript -import axios from 'axios'; // ❌ ESLint error: Use React Query instead (ADR-0003) -``` - -When this violation is caught, it triggers a decision: -- **Fix the code**: Change to React Query (maintain consistency) -- **Supersede the ADR**: If the decision needs to evolve — create a new ADR that replaces the old one (e.g., "Allow axios for external API integrations"), then migrate existing code to match the new decision - -The feedback loop is complete: violations aren't dead ends—they feed back into ADR management. Either fix to comply, or supersede the architectural decision. ADRs are immutable records — they're never edited, only superseded by new decisions. - -**Current Support**: ESLint (JavaScript/TypeScript), Ruff (Python) -**Future**: More linters, runtime checks, CI gates - ## The 6 MCP Tools -AI agents interact with ADR Kit through 6 tools. Each tool implements one part of the three-layer system: - -| Tool | Layer | When AI Uses It | What It Does | -|------|-------|-----------------|--------------| -| `adr_analyze_project` | Layer 1 | Starting with existing codebase | Detects tech stack, proposes ADRs for existing decisions | -| `adr_preflight` | Layer 1 | Before making technical choice | Returns ALLOWED/REQUIRES_ADR/BLOCKED based on existing decisions | -| `adr_create` | Layer 1 | Documenting a decision | Proposes ADR file (status: proposed) with quality validation and conflict detection | -| `adr_approve` | Layer 3 | After human review | Activates enforcement: generates lint rules, updates indexes | -| `adr_supersede` | Layer 1 | Replacing existing decision | Creates new ADR, marks old one as superseded | -| `adr_planning_context` | Layer 2 | Before implementing feature | Returns relevant ADRs filtered by task + domain, includes warnings | - -### The Approval Automation Pipeline - -When you approve an ADR, this happens automatically: - -```mermaid -graph LR - Approve[adr_approve] --> Validate[Validate ADR] - Validate --> Status[Update status to accepted] - Status --> Contract[Rebuild constraints contract] - Contract --> Guardrails[Apply guardrails] - Guardrails --> ESLint[Generate ESLint rules] - Guardrails --> Ruff[Generate Ruff rules] - ESLint --> Index[Update indexes] - Ruff --> Index - Index --> Done[Enforcement active] - - style Contract fill:#90EE90 - style Guardrails fill:#90EE90 - style ESLint fill:#FFE4B5 - style Ruff fill:#FFE4B5 - style Index fill:#FFE4B5 -``` - -**No manual steps required**. Index generation, lint rule creation, and config updates all happen automatically. - -### Decision Quality Assistance - -ADR Kit helps you write better architectural decisions by providing guidance **before** creating ADR files: - -**The Problem**: Vague decisions like "use a modern framework" can't be enforced. Without specificity and explicit constraints, your ADRs become documentation-only. - -**The Solution**: ADR Kit evaluates decision quality and provides specific feedback: - -``` -❌ Vague: "Use a modern framework with good performance" - → Feedback: "Specify exact framework name and version" - -✅ Specific: "Use React 18 with TypeScript 5.0" -``` - -**What Gets Evaluated**: -- **Specificity**: Are technologies and versions named concretely? -- **Trade-offs**: Are both pros AND cons documented? -- **Context**: Why is this decision needed right now? -- **Constraints**: Are there explicit "don't use X" policies? -- **Alternatives**: What options were rejected and why? - -**User Experience**: -1. AI agent drafts an ADR based on your requirements -2. ADR Kit provides quality feedback with specific suggestions -3. Agent revises and improves the decision -4. Once quality passes, the ADR file is created - -**How This Helps**: +AI agents interact with ADR Kit through 6 tools: -Weak ADRs can't be enforced. "Use a modern framework" doesn't tell a linter what to block. ADR Kit's quality feedback pushes toward specific, actionable decisions that can be translated into automated policies. +| Tool | When AI Uses It | What It Does | +|------|-----------------|--------------| +| `adr_analyze_project` | Starting with existing codebase | Detects tech stack, proposes ADRs for discovered decisions | +| `adr_preflight` | Before making a technical choice | Returns ALLOWED / REQUIRES_ADR / BLOCKED | +| `adr_create` | Documenting a decision | Proposes ADR with quality validation and conflict detection | +| `adr_approve` | After your review | Activates enforcement: generates lint rules, updates indexes | +| `adr_supersede` | Replacing an existing decision | Creates new ADR, marks old as superseded | +| `adr_planning_context` | Before implementing a feature | Returns relevant ADRs filtered by task and domain | -## How ADRs Get Their Policies +## ADR Format -ADR Kit uses a **two-step creation flow**. You don't write ADRs or policies manually — the AI agent handles both, guided by ADR Kit: - -**Step 1 — Decision Quality**: When the agent calls `adr_create`, ADR Kit evaluates the decision for specificity, trade-offs, and enforceability. Vague decisions ("use a modern framework") are rejected with actionable feedback before any file is created. - -**Step 2 — Policy Construction**: ADR Kit returns a `policy_guidance` promptlet that walks the agent through mapping the decision text into structured policies. The agent reasons about what constraints to extract and constructs the policy block. - -The result is an ADR with both human-readable documentation and machine-readable enforcement policies — written by the AI, reviewed by you. - -### ADR Format - -ADRs use [MADR format](https://adr.github.io/madr/) with a `policy` block in the front-matter for enforcement: +ADRs use [MADR format](https://adr.github.io/madr/) with an optional `policy` block for enforcement: ```markdown --- @@ -386,14 +105,11 @@ id: ADR-0001 title: Use React Query for data fetching status: proposed date: 2025-10-01 -deciders: [frontend-team, tech-lead] tags: [frontend, data-fetching] policy: imports: prefer: [react-query, @tanstack/react-query] disallow: [axios] - rationales: - - "Standardize data fetching patterns" --- ## Context @@ -409,379 +125,52 @@ Use React Query for all data fetching. Don't use axios directly. - Additional dependency, learning curve ``` -After approval, this automatically generates lint rules: - -```json -// .eslintrc.adrs.json (auto-generated, don't edit) -{ - "rules": { - "no-restricted-imports": ["error", { - "paths": [{ - "name": "axios", - "message": "Use React Query instead (ADR-0001)" - }] - }] - } -} -``` - -### Policy Types - -The `policy` block supports five types of enforcement: - -| Type | What It Enforces | Example | -|------|-----------------|---------| -| `imports` | Library restrictions | `disallow: [axios]`, `prefer: [react-query]` | -| `python` | Python-specific imports | `disallow_imports: [flask, django]` | -| `patterns` | Code pattern rules | Named rules with regex or structured queries, severity levels | -| `architecture` | Layer boundaries + required structure | `rule: "ui -> database"`, `action: block` | -| `config_enforcement` | Tool configuration | TypeScript tsconfig settings, Python ruff/mypy settings | -| `rationales` | Reasons for policies | `["Native async support required"]` | +After approval, the `policy` block automatically generates lint rules that block violations: -
-Full policy schema reference - -```yaml -policy: - imports: - disallow: [string] # Libraries/packages to ban - prefer: [string] # Recommended alternatives - - python: - disallow_imports: [string] # Python-specific module bans - - patterns: - patterns: - rule_name: # Named pattern rules (dict) - description: string # Human-readable description - language: string # python, typescript, etc. - rule: string | object # Regex string or structured query - severity: error | warning | info - autofix: boolean # Whether autofix is available - - architecture: - layer_boundaries: # Access control between layers - - rule: string # Format: "layer -> layer" (e.g., "ui -> database") - check: string # Path pattern to check (glob) - action: block | warn # How to enforce - message: string # Custom error message - required_structure: # Required files/directories - - path: string # Required path (glob supported) - description: string # Why this is required - - config_enforcement: - typescript: - tsconfig: object # Required tsconfig.json settings - python: - ruff: object # Required Ruff configuration - mypy: object # Required mypy configuration - - rationales: [string] # Reasons for the policies -``` - -
- -### Example ADRs - -See [tests/fixtures/examples/](tests/fixtures/examples/) for complete examples: -- `good-adr-with-structured-policy.md` — Full policy block in front-matter -- `bad-adr-no-policy.md` — No enforceable constraints (triggers quality gate) - -## AI Agent Integration - -### Setup for Cursor IDE - -```bash -# Automatic configuration -adr-kit setup-cursor -``` - -Or manually add to `.cursor/mcp.json`: -```json -{ - "mcpServers": { - "adr-kit": { - "command": "adr-kit", - "args": ["mcp-server"] - } - } -} -``` - -### Setup for Claude Code - -```bash -# Automatic configuration -adr-kit setup-claude -``` - -Or manually add to Claude Code MCP settings. - -## Manual CLI Usage (Without AI) - -For direct usage without AI agents: - -```bash -# Validation -adr-kit validate # Validate all ADRs -adr-kit validate --id ADR-0001 # Validate specific ADR - -# Policy management -adr-kit contract-build # Build constraints contract -adr-kit contract-status # View current contract -adr-kit preflight postgresql # Manual preflight check - -# Enforcement -adr-kit guardrail-apply # Apply lint rules -adr-kit guardrail-status # Check guardrail status - -# Maintenance -adr-kit update # Check for updates -adr-kit mcp-health # Test MCP server -``` - -## Advanced: What's Automatic vs Manual - -### Automatic (Triggered by Approval) - -When you call `adr_approve()` or AI agent approves an ADR: -- ✅ Index generation (`generate_adr_index()`) -- ✅ ESLint rule generation (`generate_eslint_config()`) -- ✅ Ruff rule generation (`generate_ruff_config()`) -- ✅ Guardrail application (`GuardrailManager.apply_guardrails()`) -- ✅ Constraints contract rebuild (`ConstraintsContractBuilder.build()`) -- ✅ Codebase validation - -**You never manually call these functions**. They're internal to the approval workflow. - -### Manual (When Needed) - -- 🔧 Project initialization (`adr-kit init`) -- 🔧 Validation (`adr-kit validate`) -- 🔧 Health checks (`adr-kit mcp-health`) -- 🔧 Manual preflight checks (`adr-kit preflight `) - -## Advanced: Semantic Search - -ADR Kit includes built-in semantic search for finding related ADRs: - -**Status**: Fully implemented, currently used as optional fallback -- Uses sentence-transformers (`all-MiniLM-L6-v2`) -- Stores embeddings in `.project-index/adr-vectors/` -- Finds ADRs by meaning, not just keywords - -**Current behavior**: Primary method is keyword matching, semantic search available as enhancement - -**Future**: Will become primary method for conflict detection - -## Directory Structure - -``` -your-project/ -├── docs/adr/ # ADR files -│ ├── ADR-0001-react-query.md -│ ├── ADR-0002-typescript.md -│ └── adr-index.json # Auto-generated index -├── .adr-kit/ # System files -│ └── constraints_accepted.json # Merged policies -├── .project-index/ # Indexes -│ └── adr-vectors/ # Semantic search embeddings (optional) -├── .eslintrc.adrs.json # Auto-generated lint rules -└── pyproject.toml # Auto-managed [tool.ruff] section -``` - -**Important**: Files in `.adr-kit/` and `.eslintrc.adrs.json` are auto-generated. Don't edit them manually. - -## Installation Options - -### Recommended: Global Install - -```bash -uv tool install adr-kit -``` - -Use ADR Kit across all your projects. The `adr-kit` command is available system-wide. - -### Virtual Environment Install - -```bash -cd your-project -uv venv -source .venv/bin/activate -uv pip install adr-kit -``` - -Project-specific installation. - -### Quick Trial (No Install) - -```bash -uvx adr-kit --help -uvx adr-kit init -``` - -Try ADR Kit without installing. - -## CI/CD Integration - -```yaml -# .github/workflows/adr.yml -name: ADR Validation - -on: [push, pull_request] - -jobs: - validate: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Install uv - uses: astral-sh/setup-uv@v4 - with: - enable-cache: true - - - name: Install ADR Kit - run: uv tool install adr-kit - - - name: Validate ADRs - run: adr-kit validate - - - name: Check lint rules are current - run: git diff --exit-code .eslintrc.adrs.json -``` - -## Testing & Validation - -ADR Kit includes comprehensive test coverage: - -### Quick Health Check - -```bash -adr-kit mcp-health +```javascript +import axios from 'axios'; // ❌ ESLint: Use React Query instead (ADR-0001) ``` -Expected output: -- ✅ FastMCP dependency: OK -- ✅ MCP server: OK -- ✅ Workflow backend system: OK -- 📡 6 MCP Tools available - -### Reliability & Testing - -ADR Kit is thoroughly tested across multiple scenarios: - -- **Complete lifecycle flows**: Analyze → create → approve → enforce -- **Error handling**: Permission issues, malformed input, conflicts -- **Performance**: Large projects, memory efficiency -- **MCP integration**: AI agent communication - -Each workflow is designed for predictable, reliable behavior. - ## FAQ -**Q: I don't use AI agents. Is this useful for me?** -A: ADR Kit works standalone for documentation and manual enforcement setup. But it's designed for the AI development workflow. The CLI exists for testing and CI/CD, but the real value comes from AI integration. - -**Q: Does this replace code reviews?** -A: No. ADR Kit catches architectural violations automatically (Layer 3), but code reviews catch logic errors, security issues, and design problems that lint rules can't detect. Think of it as an additional safety net. - -**Q: What languages/frameworks are supported?** -A: **Layer 1 (lifecycle management)** and **Layer 2 (context loading)** are language-agnostic. **Layer 3 (enforcement)** currently supports JavaScript/TypeScript (ESLint) and Python (Ruff). Other languages require manual policy application until more linters are supported. +**Q: What languages are supported?** +A: Lifecycle management and context loading are language-agnostic. Enforcement currently generates ESLint rules (JavaScript/TypeScript) and Ruff rules (Python). Other languages require manual policy application for now. **Q: Can I use this with existing ADRs?** -A: Yes. ADR Kit reads standard MADR format. Add a `policy:` section to existing ADRs to enable automated enforcement. - -**Q: What if my ADR doesn't map to lint rules?** -A: Not all architectural decisions can be enforced with linters. Example: "Use microservices architecture" can't become an ESLint rule. These decisions work at Layer 1 (lifecycle management) and Layer 2 (context loading) but not Layer 3 (enforcement). ADR Kit focuses on decisions that CAN be enforced: library choices, coding patterns, file structure. +A: Yes. ADR Kit reads standard MADR format. Add a `policy:` block to existing ADRs to enable enforcement. **Q: Does this work offline?** -A: Yes. No external API calls. Semantic search uses local models (sentence-transformers). Your ADRs and policies stay on your machine. +A: Yes. No external API calls. Semantic search uses local models. Your ADRs and policies stay on your machine. -**Q: What's the difference between MCP tools and CLI commands?** -A: **MCP tools** (6) are the AI interface—how agents interact with ADR Kit. **CLI commands** (20+) are for manual operations, debugging, and CI/CD. Most users interact through AI; the CLI exists for edge cases. +**Q: What if a decision can't be expressed as a lint rule?** +A: Not all decisions map to lint rules — "use microservices" can't become an ESLint rule. These decisions still benefit from lifecycle management and context loading (layers 1 and 2). Enforcement only applies to decisions with concrete, checkable constraints: library choices, coding patterns, file structure. -## Current Capabilities - -**What ADR Kit Does Today:** - -- ✅ **Context loading**: Filters ADRs by relevance to current task (planning_context tool) -- ✅ **Implicit decision discovery**: Reads codebase to discover architectural decisions already made but never documented (analyze_project tool) -- ✅ **Conflict detection**: Analyzes whether discovered decisions are consistently followed or violated in some cases -- ✅ **Greenfield support**: Create ADRs before or as you implement for strong foundation from the start -- ✅ **Policy extraction**: Converts decision text into enforceable policies (import restrictions) -- ✅ **ESLint/Ruff generation**: Creates lint rules from policies automatically -- ✅ **Quality gate**: Prevents vague decisions that can't be enforced - -**Current Limitations:** - -- Policy types: Import restrictions work well. Pattern policies, architecture boundaries, and config enforcement are defined but not yet enforced. -- Language support: JavaScript/TypeScript (ESLint) and Python (Ruff) today. Other languages require manual policy application. -- Enforcement: Linter-based only. Runtime enforcement and CI gates are planned. - -## What's Coming +**Q: Does this replace code reviews?** +A: No. ADR Kit catches architectural violations automatically, but code reviews catch logic errors, security issues, and design problems that lint rules can't detect. -**Enforcement Pipeline** (High Priority): -- Staged enforcement system (warn → block transitions) -- Complete enforcement loop with automated code scanning -- Import-linter template generation for Python projects +## Current Status -**Developer Experience**: -- Enhanced semantic search as primary conflict detection method -- ADR templates for common decision types -- Static site generation for ADR documentation (Log4brains integration) +**Working today:** +- Selective context loading by task relevance (`adr_planning_context`) +- Implicit decision discovery in existing codebases (`adr_analyze_project`) +- ADR creation with quality gate — rejects vague decisions before file creation +- ESLint and Ruff rule generation from import policies -**Recent Additions** (Since Feb 2026): -- Decision quality guidance system -- Expanded policy types: patterns, architecture rules, config enforcement -- AI warning extraction for task-specific guidance -- Policy suggestion engine with auto-detection +**Current limitations:** +- Enforcement is linter-based only. Pattern policies, architecture boundaries, and config enforcement are modelled but not yet active. +- Language support: JavaScript/TypeScript (ESLint) and Python (Ruff). Other languages require manual policy application. -See [.agent/task-tracking.md](.agent/task-tracking.md) for detailed feature status and priority queue. +See [ROADMAP.md](ROADMAP.md) for what's planned and why. ## Learn More -- **MADR Format**: [Markdown ADR Specification](https://adr.github.io/madr/) -- **MCP Protocol**: [Model Context Protocol](https://modelcontextprotocol.io) -- **Getting Started Guide**: [GETTING_STARTED.md](GETTING_STARTED.md) *(coming soon)* -- **Workflows Deep Dive**: [WORKFLOWS.md](WORKFLOWS.md) *(coming soon)* -- **AI Integration Guide**: [AI_INTEGRATION.md](AI_INTEGRATION.md) *(coming soon)* -- **Core Concepts**: [CONCEPTS.md](CONCEPTS.md) *(coming soon)* +- [TECHNICAL.md](TECHNICAL.md) — How each layer works in detail, with examples +- [ROADMAP.md](ROADMAP.md) — What's coming and in what order +- [CHANGELOG.md](CHANGELOG.md) — Release history +- [CONTRIBUTING.md](CONTRIBUTING.md) — Set up the dev environment +- [MADR Format](https://adr.github.io/madr/) — The ADR specification ADR Kit builds on +- [MCP Protocol](https://modelcontextprotocol.io) — How AI agents connect to external tools --- -# Development - -**This section is for developers working on ADR Kit itself, not for users installing it.** - -If you're looking to **use** ADR Kit in your project, see [Quick Start](#quick-start) above. - -## Contributing to ADR Kit - -```bash -# Clone the repository -git clone https://github.com/yourusername/adr-kit -cd adr-kit - -# Install in editable mode with development dependencies -uv pip install -e ".[dev]" - -# Run tests -pytest - -# Development commands (see Makefile for full list) -make dev-setup # Initial setup with guidance -make test-all # Run all tests including MCP server -make quality # Format + lint + test -make reinstall # Clean install (recommended when testing changes) -``` - -**Detailed developer documentation:** See [CLAUDE.md](CLAUDE.md) for comprehensive development instructions, including: -- Understanding the three versions of ADR Kit (source, local install, system install) -- Development workflow (Edit → Test → Verify) -- Testing the MCP server with local changes -- Project structure and what gets packaged vs what's dev-only - -## License - -MIT License - see [LICENSE](LICENSE) file for details. +MIT License — see [LICENSE](LICENSE) diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..e0d8c5d --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,41 @@ +# ADR Kit — Roadmap + +This document tracks what's planned, in what order, and why. Priorities reflect what most directly unblocks the core value of ADR Kit. + +→ For current capabilities and limitations, see [README.md](README.md#current-status) +→ For technical implementation details, see [TECHNICAL.md](TECHNICAL.md) + +--- + +## Up Next + +### Staged Enforcement + +**Why:** Import restrictions currently either block immediately or warn. Real projects need a transition period — warn on existing violations, block new ones. Without staged enforcement, teams can't adopt ADR Kit on a codebase that already has violations. + +**What:** A warn → block enforcement pipeline with thresholds, so teams can clean up existing violations incrementally without being blocked from day one. + +### Complete Enforcement Loop + +**Why:** Pattern policies, architecture boundaries, and config enforcement are fully modelled in the schema but don't yet generate lint rules. The enforcement story is incomplete until all policy types produce real output. + +**What:** Extend the guardrail generator to cover pattern rules (regex), architecture layer boundaries, and tool configuration enforcement (tsconfig, ruff/mypy settings). + +### DX Polish + +**Why:** Several rough edges in the day-to-day workflow slow down adoption: error messages that don't suggest next steps, missing `--adr-dir` defaults, gaps in CLI output. + +**What:** Targeted improvements to error messages, CLI UX, and feedback quality across the MCP tools. + +--- + +## Later + +- **Semantic search as primary conflict detection** — Currently keyword-based. Semantic search (sentence-transformers) is implemented but used as optional fallback. Making it primary improves conflict detection for conceptually related ADRs that don't share keywords. +- **ADR templates** — Common decision types (library choice, architecture pattern, API design) as starting templates to reduce ADR creation friction. +- **Log4brains integration** — Static site generation for browsing ADRs with history and status tracking. +- **Import-linter support** — Python enforcement via import-linter in addition to Ruff, for more expressive architecture boundary rules. + +--- + +For release history, see [CHANGELOG.md](CHANGELOG.md). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..7bb9c8b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,31 @@ +# Security Policy + +## Supported Versions + +Only the latest release of ADR Kit receives security fixes. + +| Version | Supported | +|---------|-----------| +| Latest | Yes | +| Older | No | + +## Reporting a Vulnerability + +**Do not open a public GitHub issue for security vulnerabilities.** + +To report a vulnerability, please contact the maintainer directly via GitHub: [@kschlt](https://github.com/kschlt). Include: + +- A description of the vulnerability and its potential impact +- Steps to reproduce +- Any suggested fixes if you have them + +You can expect an acknowledgement within 7 days. We will work with you to understand the issue and coordinate a fix before any public disclosure. + +## Scope + +ADR Kit is a local developer tool — it reads and writes files in your project directory and runs an MCP server on localhost. It makes no outbound network requests in normal operation (except optional Log4brains site generation). There are no user accounts, authentication systems, or remote data storage. + +The most relevant security concerns are: +- Path traversal when reading/writing ADR files +- Command injection via ADR content passed to external tools +- Dependency vulnerabilities in the package supply chain diff --git a/TECHNICAL.md b/TECHNICAL.md new file mode 100644 index 0000000..80239f4 --- /dev/null +++ b/TECHNICAL.md @@ -0,0 +1,311 @@ +# ADR Kit — Technical Reference + +This document explains how each layer of ADR Kit works in detail, with concrete examples, configuration reference, and operational notes. + +→ For a product overview and quick start, see [README.md](README.md) +→ For what's planned, see [ROADMAP.md](ROADMAP.md) + +--- + +## Layer 1: ADR Lifecycle Management + +### The Problem It Solves + +Architectural decisions emerge continuously during development — when you pick a library, define a pattern, or decide what to avoid. Without active management, they're never documented, and when they need to evolve, there's no historical record of what was decided before. + +### How It Works + +During every chat session, the AI checks: "Does this choice have architectural relevance?" If yes, it calls `adr_preflight` to see if an ADR exists. If not, it proposes one via `adr_create`. Once you approve, the ADR is active and enforced. + +**Proposing a new ADR:** + +``` +You: "Let's use FastAPI for the backend API" +AI: [adr_preflight({choice: "fastapi"})] → REQUIRES_ADR +AI: [adr_create({decision: "Use FastAPI...", context: "..."})] +AI: "Here's ADR-0001. Review it?" +You: "Approved" +AI: [adr_approve({id: "ADR-0001"})] → Enforcement active +``` + +### Decision Quality Gate + +Vague decisions can't be enforced. ADR Kit evaluates quality before creating any file: + +``` +❌ "Use a modern framework with good performance" + → Rejected: specify exact framework name and version + +✅ "Use FastAPI 0.100+. Don't use Flask or Django." + → Accepted: specific, has explicit constraints +``` + +**What gets evaluated:** +- **Specificity**: Are technologies named concretely? +- **Trade-offs**: Are both pros and cons documented? +- **Context**: Why is this decision needed now? +- **Constraints**: Are there explicit "don't use X" policies? +- **Alternatives**: What options were rejected and why? + +If the quality score is below threshold, the agent receives structured feedback and revises the decision before any file is created — no partial ADR files accumulate in your repository. + +### Superseding Decisions + +ADRs are immutable records. When a decision needs to change, you supersede it — the old ADR stays as historical record. + +``` +You: "We need axios for this specific external API integration" +AI: [adr_preflight({choice: "axios"})] → BLOCKED (conflicts with ADR-0003: Use React Query) +AI: "Two options: + A) Find a React Query solution for this case + B) Supersede ADR-0003 to allow axios for external APIs" +You: "Option B" +AI: [adr_supersede({supersedes: "ADR-0003", decision: "Allow axios for external APIs..."})] +AI: "ADR-0015 created. ADR-0003 marked superseded. + Note: 3 files use React Query for external calls — they'd need migrating." +``` + +Superseding always surfaces migration implications — the AI identifies what existing code conflicts with the new decision. + +--- + +## Layer 2: Context Loading + +### The Problem It Solves + +AI agents can't remember decisions from previous conversations. Loading all ADRs upfront wastes context window before any real work begins. + +### How It Works + +Before implementing a feature, the AI calls `adr_planning_context` with the current task description. ADR Kit filters by relevance and returns only the decisions that apply: + +``` +Task: "Implement user authentication" +Domain: backend, security + +ADR Kit returns: +✅ ADR-0005: Use Auth0 for Authentication + - Constraint: Don't implement custom auth + - Warning: ⚠️ Rate limiting required on auth endpoints + +✅ ADR-0008: JWT Token Structure + - Constraint: Access tokens expire in 1 hour + - Constraint: Refresh tokens stored in httpOnly cookies + +Filtered out (not relevant): +❌ ADR-0001: React Query (frontend) +❌ ADR-0012: CSS-in-JS (styling) +``` + +**How filtering works:** Primary method is keyword and tag matching. Semantic search (sentence-transformers, `all-MiniLM-L6-v2`) is available as an enhancement for finding conceptually related ADRs that don't share keywords. AI warnings from ADR consequences are surfaced for any moderately relevant decision (relevance ≥ 0.4). + +--- + +## Layer 3: Enforcement + +### The Problem It Solves + +Even with relevant context loaded, agents make mistakes or skip constraints under time pressure. Enforcement works independently of context loading — violations are caught regardless. + +### How It Works + +Approved ADRs with a `policy` block automatically generate lint rules: + +```yaml +# ADR-0003: Use React Query for data fetching +policy: + imports: + prefer: [react-query, @tanstack/react-query] + disallow: [axios] +``` + +Generates `.eslintrc.adrs.json`: + +```json +{ + "rules": { + "no-restricted-imports": ["error", { + "paths": [{ + "name": "axios", + "message": "Use React Query instead (ADR-0003). To change this decision, supersede the ADR." + }] + }] + } +} +``` + +And for Python, updates `pyproject.toml` under `[tool.ruff]`. + +**The feedback loop:** Violations aren't dead ends. The error message tells the developer (or agent) which ADR is being violated — feeding back into lifecycle management. Either fix the code to comply, or supersede the ADR if the decision needs to evolve. + +### What's Automatic on Approval + +When you call `adr_approve`, this happens without any manual steps: + +1. ADR status updated to `accepted` +2. Constraints contract rebuilt +3. ESLint rules generated (if JS/TS policy present) +4. Ruff rules generated (if Python policy present) +5. ADR index updated +6. Codebase validated against new constraints + +--- + +## Policy Schema + +The `policy` block in ADR front-matter supports five enforcement types: + +| Type | What It Enforces | Status | +|------|-----------------|--------| +| `imports` | Library restrictions (JS/TS) | Active | +| `python` | Module restrictions (Python) | Active | +| `patterns` | Code pattern rules with regex | Defined, not yet enforced | +| `architecture` | Layer boundaries + required structure | Defined, not yet enforced | +| `config_enforcement` | Tool configuration (tsconfig, ruff, mypy) | Defined, not yet enforced | + +
+Full policy schema reference + +```yaml +policy: + imports: + disallow: [string] # Libraries/packages to ban (JS/TS) + prefer: [string] # Recommended alternatives + + python: + disallow_imports: [string] # Python module bans + + patterns: + patterns: + rule_name: # Named pattern rules + description: string + language: string # python, typescript, etc. + rule: string | object # Regex or structured query + severity: error | warning | info + autofix: boolean + + architecture: + layer_boundaries: + - rule: string # "layer -> layer" (e.g., "ui -> database") + check: string # Path pattern (glob) + action: block | warn + message: string + required_structure: + - path: string # Required path (glob supported) + description: string + + config_enforcement: + typescript: + tsconfig: object # Required tsconfig.json settings + python: + ruff: object # Required Ruff configuration + mypy: object # Required mypy configuration + + rationales: [string] # Human-readable reasons for the policies +``` + +
+ +See [tests/fixtures/examples/](tests/fixtures/examples/) for complete ADR examples with policy blocks. + +--- + +## Directory Structure + +After `adr-kit init`, your project looks like: + +``` +your-project/ +├── docs/adr/ # ADR files +│ ├── ADR-0001-react-query.md +│ ├── ADR-0002-typescript.md +│ └── adr-index.json # Auto-generated — don't edit +├── .adr-kit/ +│ └── constraints_accepted.json # Merged policies — auto-generated +├── .project-index/ +│ └── adr-vectors/ # Semantic search embeddings +├── .eslintrc.adrs.json # Auto-generated lint rules — don't edit +└── pyproject.toml # [tool.ruff] section managed by ADR Kit +``` + +Files in `.adr-kit/`, `.project-index/`, and `.eslintrc.adrs.json` are auto-generated. Add them to `.gitignore` or commit them — both are valid depending on your workflow. + +--- + +## Manual CLI Usage + +Most users interact with ADR Kit through AI agents. The CLI exists for manual operations and CI/CD: + +```bash +# Validation +adr-kit validate # Validate all ADRs +adr-kit validate --id ADR-0001 # Validate a specific ADR + +# Policy management +adr-kit contract-build # Rebuild constraints contract +adr-kit contract-status # View current contract + +# Enforcement +adr-kit guardrail-apply # Apply lint rules manually +adr-kit guardrail-status # Check guardrail status +adr-kit preflight postgresql # Manual preflight check + +# Maintenance +adr-kit mcp-health # Test MCP server connectivity +adr-kit update # Check for updates +``` + +--- + +## CI/CD Integration + +```yaml +# .github/workflows/adr.yml +name: ADR Validation + +on: [push, pull_request] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install ADR Kit + run: uv tool install adr-kit + + - name: Validate ADRs + run: adr-kit validate + + - name: Check lint rules are current + run: git diff --exit-code .eslintrc.adrs.json +``` + +--- + +## Health Check + +After installation, verify the MCP server is working: + +```bash +adr-kit mcp-health +``` + +Expected output: +- ✅ FastMCP dependency: OK +- ✅ MCP server: OK +- ✅ Workflow backend system: OK +- 📡 6 MCP Tools available + +--- + +## Project Status + +ADR Kit is under active development. Test coverage: 187 tests (144 unit + 43 integration) across the core workflows, MCP server integration, and quality assessment system. + +See [ROADMAP.md](ROADMAP.md) for what's planned and [CONTRIBUTING.md](CONTRIBUTING.md) to contribute. diff --git a/pyproject.toml b/pyproject.toml index fe836f2..ac247b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,9 +14,10 @@ classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "pydantic>=2.0.0", @@ -55,8 +56,8 @@ dev = [ adr-kit = "adr_kit.cli:app" [project.urls] -Homepage = "https://github.com/your-org/adr-kit" -Repository = "https://github.com/your-org/adr-kit" +Homepage = "https://github.com/kschlt/adr-kit" +Repository = "https://github.com/kschlt/adr-kit" [tool.setuptools.packages.find] where = ["."]