This is the full developer documentation for Structured MADR # Structured MADR > The decision a person writes and the metadata a parser filters on — one record, both readers, gate-checked before it merges. Structured MADR is an extension of [MADR](https://adr.github.io/madr/) (Markdown Architectural Decision Records) that adds YAML frontmatter for machine-readable metadata, comprehensive option analysis with risk assessments, and required audit sections for compliance tracking. ## Why Structured MADR? [Section titled “Why Structured MADR?”](#why-structured-madr) Traditional ADR formats were designed for human readers. While they capture decisions effectively, they lack machine-readable metadata for programmatic access, structured risk assessment for option evaluation, audit trails for compliance verification, and explicit relationships between decisions. Structured MADR addresses these gaps while remaining fully human-readable and compatible with existing ADR workflows. ## Key Features [Section titled “Key Features”](#key-features) YAML Frontmatter Machine-parseable metadata for tooling integration. Filter, search, and query your decisions programmatically. Risk Assessment Evaluate technical, schedule, and ecosystem risk for every considered option with a structured three-dimension model. Audit Trail Built-in compliance tracking with findings tables. Meet SOC2, HIPAA, and ISO 27001 requirements. AI-Ready Structured metadata enables AI tools like Claude Code, GitHub Copilot, and Cursor to filter, understand, and surface relevant decisions. ## Quick Links [Section titled “Quick Links”](#quick-links) [Getting Started](/tutorials/getting-started/)Create your first Structured MADR in under 5 minutes [Schema Reference](/reference/schema/)Complete JSON Schema field reference [GitHub Action](/reference/github-action/)Automated CI/CD validation for your ADRs [Templates](/reference/templates/)Full and bare templates ready to use [Why Structured MADR](/explanation/why-structured-madr/)Motivation and ideal use cases [Format Comparison](/explanation/format-comparison/)How Structured MADR compares to other ADR formats ## At a Glance [Section titled “At a Glance”](#at-a-glance) | Feature | Description | | -------------------------- | -------------------------------------------------- | | **YAML Frontmatter** | Machine-parseable metadata for tooling integration | | **Hierarchical Drivers** | Primary and secondary decision drivers | | **Risk Assessment** | Technical, schedule, and ecosystem risk per option | | **Split Consequences** | Positive, negative, and neutral outcomes | | **Audit Section** | Built-in compliance tracking with findings tables | | **Explicit Relationships** | Typed links between related decisions | ## Current Version [Section titled “Current Version”](#current-version) * **Specification:** 1.0.0 * **Schema:** 1.0.0 * **Project:** 2.0.0 # Design Decisions > Key design decisions behind the Structured MADR specification This page summarizes the architectural decisions that shaped Structured MADR. Each decision is documented as a formal ADR in the project’s [`docs/decisions/`](https://github.com/modeled-information-format/structured-madr/tree/main/docs/decisions) directory, following the Structured MADR format itself (dogfooding). ## Why YAML Frontmatter [Section titled “Why YAML Frontmatter”](#why-yaml-frontmatter) **Decision:** Require YAML frontmatter for machine-readable metadata in every ADR. YAML was chosen over alternatives (JSON, TOML, custom syntax) because of its broad tooling support. Nearly every programming language has a YAML parser, and YAML frontmatter is already a convention in static site generators (Jekyll, Hugo, Astro), documentation tools, and content management systems. The frontmatter block serves as a structured index for each ADR. Tools can read metadata – status, category, tags, technologies, dates, relationships – without parsing the markdown body. This enables programmatic filtering, search, reporting, and AI-assisted discovery. All 10 required fields were chosen to provide the minimum metadata needed for effective tooling while avoiding excessive overhead for authors. ## Why a Required Audit Section [Section titled “Why a Required Audit Section”](#why-a-required-audit-section) **Decision:** Make the Audit section mandatory in every ADR. The audit section exists to bridge the gap between “decision made” and “decision implemented correctly.” In compliance-driven environments (SOC2, HIPAA, ISO 27001), auditors need evidence that architectural decisions were followed through. The findings table provides that evidence by linking assessments to specific files and line numbers. Even outside regulated industries, the audit section serves as a lightweight implementation checklist. Teams can use it to track whether a decision has been implemented, partially implemented, or deferred. The section is required rather than optional because making it optional would mean most teams skip it entirely, losing the compliance and tracking benefits that distinguish Structured MADR from other formats. ## Why Three-Dimension Risk Assessment [Section titled “Why Three-Dimension Risk Assessment”](#why-three-dimension-risk-assessment) **Decision:** Evaluate each considered option across Technical Risk, Schedule Risk, and Ecosystem Risk. Traditional ADR formats use informal pros and cons lists. While useful, these lists do not provide a consistent framework for comparing options. The three-dimension risk model addresses this: * **Technical Risk** captures implementation complexity, performance concerns, and reliability unknowns. * **Schedule Risk** captures time-to-implement, learning curve, and delivery uncertainty. * **Ecosystem Risk** captures dependency health, community support, and long-term viability. Each dimension is rated Low, Medium, or High with a brief explanation. This provides enough structure for meaningful comparison without turning every ADR into a formal risk register. ## Why Categorized Consequences [Section titled “Why Categorized Consequences”](#why-categorized-consequences) **Decision:** Split consequences into Positive, Negative, and Neutral categories instead of a single list. A single consequences list makes it difficult to quickly assess the trade-offs of a decision. By separating consequences into three categories, readers can immediately see what the decision gains, what it costs, and what changes without clear directional impact. This categorization also forces authors to think more carefully about trade-offs. A decision with no listed negative consequences is likely missing something. The structure prompts honest assessment. ## Why MADR Compatibility [Section titled “Why MADR Compatibility”](#why-madr-compatibility) **Decision:** Follow MADR 4.0.0 section conventions as the base structure. Structured MADR is designed as an extension of MADR, not a replacement. The section structure deliberately mirrors MADR conventions so that teams familiar with MADR can adopt Structured MADR with minimal adjustment. Key compatibility decisions: * Section headings match MADR naming conventions * Status values (`proposed`, `accepted`, `deprecated`, `superseded`) are the same as MADR * The overall flow (Context, Drivers, Options, Decision, Consequences) follows MADR ordering * Additional sections (Risk Assessment, Audit) are additive rather than replacing existing MADR sections This compatibility also means that migration from MADR to Structured MADR is straightforward: add frontmatter, expand consequences into categories, add risk assessments, and include an audit section. ## Why Dogfooding [Section titled “Why Dogfooding”](#why-dogfooding) **Decision:** Use Structured MADR for the project’s own architectural decisions (ADR-0001). A project that defines an ADR format but does not use it lacks credibility. Dogfooding serves three purposes: 1. **Validation** – Real usage surfaces specification issues that review alone cannot find. 2. **Exemplars** – Project ADRs serve as reference implementations for users to study. 3. **Testing** – The project’s validation tooling is tested against its own documents. The project currently maintains ADRs documenting the adoption of the format itself (ADR-0001) and the creation of the GitHub Action validator (ADR-0002). ## Why a GitHub Action Validator [Section titled “Why a GitHub Action Validator”](#why-a-github-action-validator) **Decision:** Provide an official composite GitHub Action for ADR validation (ADR-0002). Specification adoption correlates directly with tooling availability. Without easy-to-use validation, teams either skip validation entirely or implement incomplete custom solutions. The GitHub Action was chosen as the primary distribution mechanism because GitHub Actions is the dominant CI platform for open-source projects. The action uses a composite design with a Node.js validator, leveraging the `ajv` library for JSON Schema validation and custom logic for body structure checks. Key design choices: * **Composite action** over Docker for faster startup and simpler maintenance * **Node.js runtime** for cross-platform compatibility and rich JSON Schema support via ajv * **Configurable inputs** for path, pattern, schema, strictness, and failure behavior * **GitHub annotations** for inline PR feedback pointing to specific validation errors * **Semantic versioning** so consuming projects can pin to stable releases # Format Comparison > How Structured MADR compares to other ADR formats Several ADR formats exist, each designed for different contexts and levels of formality. This page compares Structured MADR with the most widely used alternatives to help you choose the right format. ## Comparison Table [Section titled “Comparison Table”](#comparison-table) | Aspect | Structured MADR | MADR | Nygard | Y-Statement | Tyree-Akerman | | ---------------- | ---------------- | ----------- | -------- | ----------- | --------------- | | Sections | 12+ | 10 | 5 | 1 | 15+ | | Frontmatter | Required YAML | None | None | None | None | | Options Detail | Narrative + Risk | Pros/Cons | Implicit | Single | Detailed | | Consequences | Pos/Neg/Neutral | Single list | Prose | Implicit | Impact analysis | | Audit Trail | Required | None | None | None | None | | Machine-Readable | Full metadata | Limited | Limited | Limited | Limited | ## Format Profiles [Section titled “Format Profiles”](#format-profiles) ### Nygard (2011) [Section titled “Nygard (2011)”](#nygard-2011) Michael Nygard’s [original ADR format](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) is the simplest and most widely recognized. It uses five sections: Title, Status, Context, Decision, and Consequences. **Strengths:** Minimal ceremony. Easy to adopt. Well-known in the industry. Can be written in minutes. **Limitations:** No structured metadata. No option comparison. No risk assessment. Consequences are a single undifferentiated list. **Best for:** Teams that want lightweight decision capture without process overhead. Quick decisions where the context is well-understood and the options are obvious. ### Y-Statement [Section titled “Y-Statement”](#y-statement) The [Y-Statement format](https://medium.com/olzzio/y-statements-10eb07b5a177) captures a decision in a single structured sentence: “In the context of \[situation], facing \[concern], we decided \[option], to achieve \[quality], accepting \[downside].” **Strengths:** Extremely concise. Forces clarity. Good for decision logs and summaries. **Limitations:** No room for detailed analysis. No option comparison. No audit capability. Insufficient for complex decisions with multiple trade-offs. **Best for:** Decision registers, summary documents, and situations where you need a quick record without detailed analysis. ### MADR (Markdown ADR) [Section titled “MADR (Markdown ADR)”](#madr-markdown-adr) [MADR](https://adr.github.io/madr/) extends Nygard’s format with structured sections for decision drivers, considered options with pros and cons, and links. It is the direct ancestor of Structured MADR. **Strengths:** Good balance of structure and simplicity. Active community. Well-documented. Includes option analysis with pros and cons. **Limitations:** No machine-readable frontmatter. No risk assessment. No audit trail. Consequences are a single list without categorization. **Best for:** Teams that want more structure than Nygard but do not need compliance tracking or machine-readable metadata. ### Tyree-Akerman [Section titled “Tyree-Akerman”](#tyree-akerman) The [Tyree-Akerman format](https://personal.utdallas.edu/~chung/SA/zz-Misc-from-Mail/09.02.02/Tyree05.pdf) is the most comprehensive traditional format, with 15+ sections covering assumptions, constraints, implications, related decisions, and notes. **Strengths:** Extremely thorough. Covers assumptions and constraints explicitly. Good for enterprise governance. **Limitations:** Heavy overhead. No machine-readable metadata. Can feel bureaucratic for smaller decisions. Rarely used outside enterprise contexts. **Best for:** Large enterprise environments with formal governance processes where comprehensive documentation is required for every decision. ### Structured MADR [Section titled “Structured MADR”](#structured-madr) Structured MADR builds on MADR by adding YAML frontmatter, three-dimension risk assessment, categorized consequences, and a required audit section. **Strengths:** Machine-readable metadata for tooling and AI integration. Structured risk evaluation. Built-in compliance tracking. JSON Schema validation. **Limitations:** More sections than MADR or Nygard. Requires YAML frontmatter knowledge. Audit section adds maintenance overhead. **Best for:** Compliance-driven projects, AI-assisted development, large codebases, and long-lived projects where structured metadata and audit trails provide value. ## Choosing a Format [Section titled “Choosing a Format”](#choosing-a-format) | Your Situation | Recommended Format | | --------------------------------------- | ------------------ | | Quick decisions, small team | Nygard | | Decision summary or register | Y-Statement | | Moderate structure, no compliance needs | MADR | | Enterprise governance, formal process | Tyree-Akerman | | Compliance, AI tooling, large codebase | Structured MADR | If you are unsure, start with MADR. You can migrate to Structured MADR later by adding frontmatter and audit sections to existing documents – the section structure is intentionally compatible. # Why Structured MADR > Motivation, goals, and ideal use cases for Structured MADR ## The Problem with Traditional ADRs [Section titled “The Problem with Traditional ADRs”](#the-problem-with-traditional-adrs) Architectural Decision Records have been a cornerstone of software documentation since Michael Nygard introduced the concept in 2011. Formats like Nygard’s original, MADR, Y-Statements, and Tyree-Akerman each bring different strengths. However, all share a common limitation: they were designed exclusively for human readers. As codebases grow and AI-assisted development becomes standard practice, this limitation creates real friction: * **No machine-readable metadata.** Tools cannot programmatically filter, search, or classify decisions without parsing free-form prose. * **No structured risk assessment.** Option evaluation is informal, making it difficult to compare trade-offs systematically. * **No audit trail.** Compliance-driven organizations have no built-in mechanism to track whether decisions were implemented correctly. * **No explicit relationships.** Connections between decisions are buried in prose rather than expressed as queryable data. ## What Structured MADR Adds [Section titled “What Structured MADR Adds”](#what-structured-madr-adds) Structured MADR extends the MADR format with four key capabilities: ### YAML Frontmatter [Section titled “YAML Frontmatter”](#yaml-frontmatter) Every ADR begins with a YAML block containing standardized metadata: title, description, status, dates, author, project, category, tags, technologies, audience, and relationships. This metadata is validated against a JSON Schema and can be parsed by any tool that reads YAML. ### Risk Assessment [Section titled “Risk Assessment”](#risk-assessment) Each considered option includes a three-dimension risk assessment covering technical risk, schedule risk, and ecosystem risk. Each dimension is rated Low, Medium, or High with a brief explanation. This structured approach replaces informal “pros and cons” with a consistent evaluation framework. ### Categorized Consequences [Section titled “Categorized Consequences”](#categorized-consequences) Instead of a single list of consequences, Structured MADR separates them into positive, negative, and neutral outcomes. This forces authors to think through trade-offs explicitly and makes it easier for readers to quickly assess impact. ### Required Audit Section [Section titled “Required Audit Section”](#required-audit-section) Every ADR includes a mandatory Audit section with dated entries, compliance status, and a findings table linking assessments to specific files and line numbers. This supports organizations that need to demonstrate decision compliance for SOC2, HIPAA, ISO 27001, or similar frameworks. ## Ideal Use Cases [Section titled “Ideal Use Cases”](#ideal-use-cases) ### Compliance-Driven Projects [Section titled “Compliance-Driven Projects”](#compliance-driven-projects) If your organization operates under regulatory requirements (SOC2, HIPAA, ISO 27001, FedRAMP), the audit section provides built-in compliance tracking. Auditors can review the findings table to verify that decisions were implemented as documented. ### AI-Assisted Development [Section titled “AI-Assisted Development”](#ai-assisted-development) Tools like Claude Code, GitHub Copilot, and Cursor can leverage YAML frontmatter to filter relevant decisions without parsing prose. The `category`, `tags`, `technologies`, and `project` fields let AI tools scope their context to decisions that matter for the current task. ### Large Codebases [Section titled “Large Codebases”](#large-codebases) When a project has dozens or hundreds of ADRs, discovery becomes a challenge. Machine-readable metadata enables search and filtering by status, category, technology, author, or date range – capabilities that are impossible with unstructured formats. ### Long-Lived Projects [Section titled “Long-Lived Projects”](#long-lived-projects) Projects that span years accumulate decisions that outlive the people who made them. The audit trail and explicit relationships help new team members understand not just what was decided, but whether it was implemented correctly and how it connects to other decisions. ### Enterprise Architecture [Section titled “Enterprise Architecture”](#enterprise-architecture) Organizations with governance requirements benefit from structured metadata, status tracking, and the ability to programmatically report on decision status across multiple projects. ## When to Consider Alternatives [Section titled “When to Consider Alternatives”](#when-to-consider-alternatives) Structured MADR is not the right choice for every situation: * **Quick, informal decisions** – Use [Nygard’s original format](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) for lightweight capture with minimal ceremony. * **Single-sentence capture** – Use [Y-Statements](https://medium.com/olzzio/y-statements-10eb07b5a177) when you need just one sentence documenting the decision. * **Minimal overhead** – Use [MADR Minimal](https://adr.github.io/madr/) when the full Structured MADR template feels like too much for the decision at hand. * **Prototypes or throwaway projects** – If the project will not outlive the current sprint, formal ADRs add overhead without proportional value. The right format depends on your team’s needs. Structured MADR is designed for situations where the additional structure pays for itself through better tooling, compliance, and long-term maintainability. # Integrate with AI Tools > Leverage Structured MADR frontmatter to enhance AI-assisted development workflows. Structured MADR was designed with AI tooling in mind. The YAML frontmatter provides machine-readable metadata that AI coding assistants can parse, filter, and reason about without scanning full document prose. ## How Frontmatter Enables AI Tools [Section titled “How Frontmatter Enables AI Tools”](#how-frontmatter-enables-ai-tools) Traditional ADRs store all information in unstructured prose. An AI tool must read the entire document to determine basic facts like status, technologies, or relationships. Structured MADR solves this with typed frontmatter fields: | Capability | Frontmatter Field | | ------------------------- | --------------------- | | Filter relevant decisions | `tags`, `category` | | Understand relationships | `related` | | Track freshness | `created`, `updated` | | Scope by context | `project`, `category` | | Surface by technology | `technologies` | | Identify audience | `audience` | | Check decision status | `status` | An AI assistant can scan frontmatter across dozens of ADRs in milliseconds, then read the full body only for the relevant documents. ## Integration Patterns [Section titled “Integration Patterns”](#integration-patterns) ### Claude Code [Section titled “Claude Code”](#claude-code) [Claude Code](https://docs.anthropic.com/en/docs/claude-code) can reference your ADRs as project context. With Structured MADR, Claude can efficiently filter decisions by technology, status, or project. **Recommended setup**: Add an instruction in your `CLAUDE.md` that points to your ADR directory: ```markdown ## Architecture Decisions ADRs are stored in `docs/decisions/` using the Structured MADR format. Before proposing architectural changes, check existing ADRs for relevant context. Filter by the `technologies` and `tags` frontmatter fields to find related decisions. ``` Claude Code can then: * Search ADRs by `technologies` field to find decisions about specific tools * Check `status` to know which decisions are active vs. deprecated * Follow `related` links to understand decision chains * Read audit sections to verify implementation compliance ### ADR Plugin for Claude Code [Section titled “ADR Plugin for Claude Code”](#adr-plugin-for-claude-code) The [ADR Plugin for Claude Code](https://github.com/modeled-information-format/marketplace/tree/main/plugins/adr) provides full lifecycle management of Structured MADR documents: * Create new ADRs from templates * Search and filter existing decisions * Update status and audit entries * Validate documents against the schema Install the plugin to give Claude Code native commands for ADR management. ### GitHub Copilot [Section titled “GitHub Copilot”](#github-copilot) GitHub Copilot can use your ADRs as context when suggesting code. Structured frontmatter helps Copilot understand which decisions apply to the file being edited. **Tips for Copilot integration**: * Keep ADRs in a well-known directory (`docs/decisions/`) * Use descriptive `tags` and `technologies` values that match your codebase terminology * Ensure `status` is current so Copilot does not reference deprecated decisions ### Cursor [Section titled “Cursor”](#cursor) [Cursor](https://cursor.com) indexes project files for its AI features. Structured MADR frontmatter improves Cursor’s ability to surface relevant decisions. **Recommended setup**: Add your ADR directory to Cursor’s context with a `.cursorrules` file: ```plaintext When making architectural decisions, reference existing ADRs in docs/decisions/. ADRs use Structured MADR format with YAML frontmatter containing status, tags, technologies, and related fields. ``` ## Optimizing Your ADRs for AI Consumption [Section titled “Optimizing Your ADRs for AI Consumption”](#optimizing-your-adrs-for-ai-consumption) ### Use specific, consistent tags [Section titled “Use specific, consistent tags”](#use-specific-consistent-tags) Tags are the primary filter mechanism for AI tools. Use consistent terminology: ```yaml # Good -- specific and consistent tags: - authentication - oauth2 - identity-provider # Avoid -- vague and inconsistent tags: - auth - security stuff ``` ### Keep the technologies field accurate [Section titled “Keep the technologies field accurate”](#keep-the-technologies-field-accurate) List all technologies evaluated, not just the chosen one. This ensures the ADR surfaces when an AI tool searches for any of the evaluated options: ```yaml technologies: - postgresql - mysql - mongodb ``` ### Maintain the related field [Section titled “Maintain the related field”](#maintain-the-related-field) Explicit relationships help AI tools build a graph of connected decisions: ```yaml related: - 0001-select-primary-database.md - 0003-caching-strategy.md ``` Without `related`, AI tools must infer connections from prose, which is slower and less reliable. ### Update status promptly [Section titled “Update status promptly”](#update-status-promptly) An outdated `status` field causes AI tools to recommend deprecated approaches: | Status | AI behavior | | ------------ | ---------------------------------------- | | `proposed` | May suggest alternatives or improvements | | `accepted` | References as current guidance | | `deprecated` | Warns against following this approach | | `superseded` | Points to the replacement decision | ### Write clear descriptions [Section titled “Write clear descriptions”](#write-clear-descriptions) The `description` field is a one-sentence summary that AI tools use for quick triage: ```yaml # Good -- specific and actionable description: "Adopt PostgreSQL over MySQL for JSONB support and advanced indexing." # Avoid -- too vague description: "Database decision." ``` ## Querying ADRs Programmatically [Section titled “Querying ADRs Programmatically”](#querying-adrs-programmatically) Because frontmatter is valid YAML, you can query it with standard tools: ```bash # Find all accepted ADRs about authentication grep -l "status: accepted" docs/decisions/*.md | \ xargs grep -l "authentication" # List all technologies across ADRs grep "^ - " docs/decisions/*.md | \ sed -n '/^.*technologies:/,/^[^ ]/p' ``` AI tools perform similar queries internally. The more consistent your frontmatter, the more accurately tools can filter and surface relevant decisions. # Set Up CI Validation > Automatically validate Structured MADR documents in your CI/CD pipeline. The Structured MADR GitHub Action validates your ADR files on every push or pull request, catching formatting errors and missing fields before they reach your main branch. ## Basic Setup [Section titled “Basic Setup”](#basic-setup) Create a workflow file at `.github/workflows/validate-adrs.yml`: ```yaml name: Validate ADRs on: push: paths: - 'docs/decisions/**' pull_request: paths: - 'docs/decisions/**' jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Validate Structured MADR uses: modeled-information-format/structured-madr@v2 with: path: docs/decisions pattern: '**/*.md' strict: 'false' fail-on-error: 'true' ``` This workflow runs whenever markdown files under `docs/decisions/` change. ## Action Inputs [Section titled “Action Inputs”](#action-inputs) | Input | Description | Default | | --------------- | ------------------------------------------------------ | ---------------- | | `path` | Directory containing ADR files (relative to repo root) | `docs/decisions` | | `pattern` | Glob pattern for matching ADR files | `**/*.md` | | `schema` | Path to a custom JSON Schema file | Built-in schema | | `strict` | Fail on warnings in addition to errors | `false` | | `fail-on-error` | Fail the workflow when validation errors are found | `true` | ### Notes on inputs [Section titled “Notes on inputs”](#notes-on-inputs) * **path**: Must be relative to the repository root. The action scans this directory recursively. * **pattern**: Use this to filter files within the path directory. For example, `ADR-*.md` would only match files starting with `ADR-`. * **schema**: Leave empty to use the built-in Structured MADR schema. Provide a path to override with your organization’s custom schema. * **strict**: When enabled, warnings (such as missing optional fields) are treated as errors. Useful for teams that want to enforce complete metadata. ## Action Outputs [Section titled “Action Outputs”](#action-outputs) The action exposes outputs you can reference in subsequent workflow steps: | Output | Description | | ---------- | ---------------------------------- | | `valid` | Whether all ADRs passed validation | | `total` | Total number of ADR files checked | | `passed` | Number of files that passed | | `failed` | Number of files that failed | | `warnings` | Number of warnings generated | ### Using outputs in subsequent steps [Section titled “Using outputs in subsequent steps”](#using-outputs-in-subsequent-steps) ```yaml - name: Validate Structured MADR id: adr-check uses: modeled-information-format/structured-madr@v2 with: path: docs/decisions - name: Report results if: always() run: | echo "Valid: ${{ steps.adr-check.outputs.valid }}" echo "Checked ${{ steps.adr-check.outputs.total }} files" echo "Passed: ${{ steps.adr-check.outputs.passed }}" echo "Failed: ${{ steps.adr-check.outputs.failed }}" echo "Warnings: ${{ steps.adr-check.outputs.warnings }}" ``` ## Configuration Examples [Section titled “Configuration Examples”](#configuration-examples) ### Strict mode for regulated projects [Section titled “Strict mode for regulated projects”](#strict-mode-for-regulated-projects) For compliance-driven teams that need every field populated: ```yaml - name: Validate Structured MADR (strict) uses: modeled-information-format/structured-madr@v2 with: path: docs/decisions strict: 'true' fail-on-error: 'true' ``` ### Custom ADR directory [Section titled “Custom ADR directory”](#custom-adr-directory) If your ADRs live somewhere other than `docs/decisions/`: ```yaml - name: Validate Structured MADR uses: modeled-information-format/structured-madr@v2 with: path: architecture/adrs pattern: '*.md' ``` ### Non-blocking validation [Section titled “Non-blocking validation”](#non-blocking-validation) Run validation as an informational check without blocking merges: ```yaml - name: Validate Structured MADR uses: modeled-information-format/structured-madr@v2 with: path: docs/decisions fail-on-error: 'false' ``` ### Custom schema [Section titled “Custom schema”](#custom-schema) Use your organization’s extended schema: ```yaml - name: Validate Structured MADR uses: modeled-information-format/structured-madr@v2 with: path: docs/decisions schema: '.github/schemas/custom-adr-schema.json' ``` ### Validate on schedule [Section titled “Validate on schedule”](#validate-on-schedule) Run periodic validation to catch drift, even when ADR files have not changed: ```yaml name: Weekly ADR Audit on: schedule: - cron: '0 9 * * 1' # Every Monday at 9 AM UTC workflow_dispatch: jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Validate Structured MADR uses: modeled-information-format/structured-madr@v2 with: path: docs/decisions strict: 'true' ``` ## Troubleshooting [Section titled “Troubleshooting”](#troubleshooting) ### Action does not trigger [Section titled “Action does not trigger”](#action-does-not-trigger) Verify the `paths` filter matches your ADR directory. If your ADRs are in `architecture/decisions/`, update the workflow trigger accordingly: ```yaml on: push: paths: - 'architecture/decisions/**' ``` ### Validation passes locally but fails in CI [Section titled “Validation passes locally but fails in CI”](#validation-passes-locally-but-fails-in-ci) The CI environment checks out a clean copy of your repository. Ensure all ADR files are committed and not listed in `.gitignore`. ### Schema validation errors on optional fields [Section titled “Schema validation errors on optional fields”](#schema-validation-errors-on-optional-fields) If you see errors about `technologies` or `audience`, ensure these fields are arrays (even if empty). The schema requires the correct type when the field is present: ```yaml # Correct technologies: [] # Incorrect -- do not use null technologies: null ``` # Validate Locally > Validate your Structured MADR documents before committing using CLI tools. Running validation locally catches errors before they reach CI. Structured MADR supports three validation approaches: the built-in CLI validator, `ajv-cli` for JSON Schema checks, and `check-jsonschema` for Python-based environments. ## Built-in CLI Validator [Section titled “Built-in CLI Validator”](#built-in-cli-validator) The project includes a Node.js-based validator that checks both frontmatter schema compliance and document structure. ### Setup [Section titled “Setup”](#setup) ```bash git clone https://github.com/modeled-information-format/structured-madr.git cd structured-madr npm install ``` ### Run validation [Section titled “Run validation”](#run-validation) Point the validator at your ADR directory using the `INPUT_PATH` environment variable: ```bash INPUT_PATH=/path/to/your/docs/decisions npm run validate ``` The validator checks every markdown file in the specified directory and reports: * Missing or malformed YAML frontmatter * Required fields that are absent or have incorrect types * Invalid `status` values * Structural issues in the document body ### Example output [Section titled “Example output”](#example-output) ```plaintext Checking: 0001-select-primary-database.md PASS Frontmatter is valid PASS All required sections present PASS Audit section found Checking: 0002-caching-strategy.md FAIL Missing required field: author WARN Optional field 'technologies' is empty Results: 1 passed, 1 failed, 1 warning ``` ## Schema Validation with ajv-cli [Section titled “Schema Validation with ajv-cli”](#schema-validation-with-ajv-cli) For teams that prefer validating just the frontmatter against the JSON Schema, `ajv-cli` provides a lightweight option. ### Install [Section titled “Install”](#install) ```bash npm install -g ajv-cli ``` ### Validate a single file [Section titled “Validate a single file”](#validate-a-single-file) ```bash npx ajv validate \ -s schemas/structured-madr.schema.json \ -d docs/decisions/0001-select-primary-database.md ``` ### Validate all ADRs [Section titled “Validate all ADRs”](#validate-all-adrs) ```bash npx ajv validate \ -s schemas/structured-madr.schema.json \ -d "docs/decisions/*.md" ``` ### Notes [Section titled “Notes”](#notes) * `ajv-cli` validates the YAML frontmatter against the JSON Schema only. It does not check the markdown body structure. * The schema file is located at `schemas/structured-madr.schema.json` in the Structured MADR repository. ## Schema Validation with check-jsonschema [Section titled “Schema Validation with check-jsonschema”](#schema-validation-with-check-jsonschema) If your team uses Python tooling, `check-jsonschema` is an alternative that works without Node.js. ### Install [Section titled “Install”](#install-1) ```bash pip install check-jsonschema ``` ### Validate [Section titled “Validate”](#validate) ```bash check-jsonschema \ --schemafile schemas/structured-madr.schema.json \ docs/decisions/0001-select-primary-database.md ``` ### Validate multiple files [Section titled “Validate multiple files”](#validate-multiple-files) ```bash check-jsonschema \ --schemafile schemas/structured-madr.schema.json \ docs/decisions/*.md ``` ## Adding Validation to Git Hooks [Section titled “Adding Validation to Git Hooks”](#adding-validation-to-git-hooks) Catch errors before they leave your machine by adding a pre-commit hook. ### Using a shell script [Section titled “Using a shell script”](#using-a-shell-script) Create `.git/hooks/pre-commit`: ```bash #!/bin/bash # Validate any staged ADR files STAGED_ADRS=$(git diff --cached --name-only --diff-filter=ACM -- 'docs/decisions/*.md') if [ -n "$STAGED_ADRS" ]; then echo "Validating staged ADR files..." INPUT_PATH=docs/decisions npm run validate --prefix /path/to/structured-madr if [ $? -ne 0 ]; then echo "ADR validation failed. Fix errors before committing." exit 1 fi fi ``` Make it executable: ```bash chmod +x .git/hooks/pre-commit ``` ### Using pre-commit framework [Section titled “Using pre-commit framework”](#using-pre-commit-framework) If your project uses the [pre-commit](https://pre-commit.com/) framework, add a local hook in `.pre-commit-config.yaml`: ```yaml repos: - repo: local hooks: - id: validate-adrs name: Validate Structured MADR entry: bash -c 'INPUT_PATH=docs/decisions npm run validate --prefix /path/to/structured-madr' language: system files: 'docs/decisions/.*\.md$' ``` ## Choosing a Validation Approach [Section titled “Choosing a Validation Approach”](#choosing-a-validation-approach) | Approach | Checks frontmatter | Checks structure | Requires | | ---------------- | ------------------ | ---------------- | -------- | | Built-in CLI | Yes | Yes | Node.js | | ajv-cli | Yes | No | Node.js | | check-jsonschema | Yes | No | Python | For the most thorough local validation, use the built-in CLI. For quick frontmatter-only checks, either `ajv-cli` or `check-jsonschema` will work depending on your toolchain. # Changelog > All notable changes to the Structured MADR project All notable changes to Structured MADR are documented here. 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). ## \[2.0.0] - 2026-10-08 [Section titled “\[2.0.0\] - 2026-10-08”](#200---2026-10-08) This release is breaking for consumers of `mode: mif`: projected concept `@id`s change from `urn:mif:smadr::` to `urn:mif:` (see the projected-ids entry under **Changed**). Reference the Action as `@v2`. ### Changed [Section titled “Changed”](#changed) * **MIF Compliance**: aligned with MIF specification **1.4.2**. The vendored schemas come from the immutable `https://mif-spec.dev/schema/1.4.2/` mirror (were pinned to MIF `develop/v1.0.0` at `e597da69`, whose schemas match MIF 1.2.1); `config.yml` `mifVersion` is 1.4.2 (was 1.0.0), and `vendor-check` fails if it disagrees with `VENDOR.lock`’s `mifSpecVersion`. The MIF gate warns when a consumer’s `mifVersion` differs from the vendored release. * **MIF Compliance**: the vendor pin moved from MIF 1.4.1 to **1.4.2**, the coordinated MIF release with published artifacts. The 1.4.2 schemas are byte-identical to 1.4.1 and 1.4.0, so the `VENDOR.lock` sha256s are unchanged. * **MIF Compliance** (breaking for consumers of projected ids): MIF 1.4.0+ requires a concept `@id` of `urn:mif:`. The projector uses a UUID `id` as is (lowercased; bare, `urn:mif:`, `urn:uuid:` or `{…}`) and turns a slug, a legacy `urn:mif:smadr:…` id, or a missing `id` into a deterministic UUIDv5 of the id the old projector emitted (`smadr::`) in the MIF namespace `uuid5(NAMESPACE_URL, "https://mif-spec.dev")`, keeping the replaced id in `aliases`. The gate fails when two ADRs project to the same `@id`. A `memoryType`-only ADR projects with `memoryType` and no synthesized `conceptType`, which satisfies Level 1. * **Versioning**: usage examples reference the Action as `@v2` (were `@v1`); the `structured-madr-mif` plugin version follows the project version (2.0.0). * **Project**: repository, docs and package metadata now point at the `modeled-information-format` org and its canonical domains. * **CI**: adopted the org’s attested quality-gate backbone, gated on every PR; `npm run lint` now has an ESLint flat config and runs in CI; Node is pinned to 24. ### Security [Section titled “Security”](#security) * **Deps**: `osv-scanner.toml` records braces GHSA-vfj7-8cjw-p6xm (no fixed release; build-time only) as the one remaining accepted advisory. * **Deps**: postcss-selector-parser GHSA-rj75-hqrm-r3gf is fixed rather than waived: an npm `overrides` entry forces `^7.1.6` past postcss-nested’s `^6` range, and its `osv-scanner.toml` waiver is removed. ### Fixed [Section titled “Fixed”](#fixed) * **MIF Compliance**: `x-superseded-by: B` on ADR A projects as `superseded-by` → B; it was `supersedes` → B, the reverse of the fact. ### Added [Section titled “Added”](#added) * **MIF Compliance**: validate ADRs as MIF (Modeled Information Format) at a user-selected level (`.github/config.yml` `mifConformanceLevel: 1|2|3`, default 2). Markdown stays canonical; a MIF JSON-LD object is derived from frontmatter + body and validated against per-level profiles. * Self-contained Claude Code plugin homed at `.github/` (plugin root with `.claude-plugin/plugin.json`, `commands/`, `agents/`, `skills/`, `hooks/`, plus vendored + checksum-pinned MIF schemas, config, projector, validator, ADR-typing ontology). * Installable: the repository is a plugin marketplace (`.claude-plugin/marketplace.json`, `source: ./.github`); `.claude/settings.json` registers it and enables the plugin at project scope, so `/plugin install structured-madr-mif@structured-madr` works. * `npm run validate:mif`; composite action gains `mode: mif` for downstream consumers. * CI gates: `mif-vendor-check` (schema drift) and dogfooded `validate-mif`. * ADR-0003 records the decision and is itself MIF-conformant (dogfooded). * **Docs Site**: `llms.txt` is generated at build time (starlight-llms-txt). ## \[1.2.0] - 2026-04-09 [Section titled “\[1.2.0\] - 2026-04-09”](#120---2026-04-09) Reconstructed from the v1.2.0 release notes and `git log v1.1.0..v1.2.0`; this section was not written when 1.2.0 was tagged. ### Added [Section titled “Added”](#added-1) * **GitHub Action**: configurable body structure via the JSON schema’s `body` key (required and optional sections, subsections, title pattern, option heading requirements). Without a `body` key the validator falls back to the structured-madr defaults. * **Project**: `CITATION.cff` with academic citation metadata. ### Fixed [Section titled “Fixed”](#fixed-1) * **GitHub Action**: headings inside fenced code blocks no longer count as body sections (false positives). ### Changed [Section titled “Changed”](#changed-1) * **Deps**: astro 5.17.2 → 6.1.3, @astrojs/starlight 0.37.6 → 0.38.2, eslint 9.39.2 → 10.2.0, ajv 8.17.1 → 8.18.0, glob 11.1.0 → 13.0.6, yaml 2.8.2 → 2.8.3; GitHub Actions updated to current majors. ## \[1.1.0] - 2026-01-15 [Section titled “\[1.1.0\] - 2026-01-15”](#110---2026-01-15) ### Added [Section titled “Added”](#added-2) * **GitHub Action**: Shareable validation action for CI/CD pipelines * Composite action with configurable inputs (`path`, `pattern`, `schema`, `strict`, `fail-on-error`) * Node.js validator with JSON Schema (ajv) and body structure validation * GitHub-compatible annotations for PR feedback * Outputs for workflow integration (`valid`, `total`, `passed`, `failed`, `warnings`) * **Project ADRs**: Exemplar ADRs demonstrating the format (dogfooding) * ADR-0001: Adopt Structured MADR Format for Project Documentation * ADR-0002: Shareable GitHub Action for Structured MADR Validation * **CI/CD**: GitHub workflow to validate project and example ADRs * **Documentation**: README updated with action usage, inputs/outputs, and local validation instructions ### Changed [Section titled “Changed”](#changed-2) * **Tooling**: Added npm package.json with validation dependencies (ajv, ajv-formats, glob, yaml) ## \[1.0.0] - 2026-01-15 [Section titled “\[1.0.0\] - 2026-01-15”](#100---2026-01-15) ### Added [Section titled “Added”](#added-3) * Initial release of Structured MADR specification * YAML frontmatter schema with required and optional fields * Hierarchical decision drivers (Primary/Secondary) * Per-option risk assessment (Technical/Schedule/Ecosystem) * Categorized consequences (Positive/Negative/Neutral) * Required Audit section with compliance tracking * JSON Schema for frontmatter validation (`schemas/structured-madr.schema.json`) * Full template with guidance text (`templates/template.md`) * Bare template for experienced users (`templates/template-bare.md`) * Real-world example ADR (`examples/0001-use-rust-implementation-language.md`) * Formal specification document (`SPECIFICATION.md`) * Contributing guidelines ### Design Decisions [Section titled “Design Decisions”](#design-decisions) * **MADR Compatibility**: Section structure follows MADR 4.0.0 conventions for familiarity * **Machine-Readable Frontmatter**: YAML chosen for broad tooling support * **Audit Requirements**: Mandatory audit section ensures decisions are tracked and validated * **Risk Assessment**: Three-dimension risk model (Technical/Schedule/Ecosystem) provides comprehensive evaluation * **Status Values**: Limited to MADR-compatible values (proposed, accepted, deprecated, superseded) ## Links [Section titled “Links”](#links) * [Unreleased changes](https://github.com/modeled-information-format/structured-madr/compare/v2.0.0...HEAD) * [2.0.0 release](https://github.com/modeled-information-format/structured-madr/compare/v1.2.0...v2.0.0) * [1.2.0 release](https://github.com/modeled-information-format/structured-madr/compare/v1.1.0...v1.2.0) * [1.1.0 release](https://github.com/modeled-information-format/structured-madr/compare/v1.0.0...v1.1.0) * [1.0.0 release](https://github.com/modeled-information-format/structured-madr/releases/tag/v1.0.0) # GitHub Action > Complete reference for the Structured MADR validation GitHub Action The Structured MADR Validator is a composite GitHub Action that validates your Architectural Decision Records against the Structured MADR specification. It checks both YAML frontmatter (via JSON Schema) and body structure (required sections, ordering). ## Basic Usage [Section titled “Basic Usage”](#basic-usage) .github/workflows/validate-adrs.yml ```yaml name: Validate ADRs on: push: paths: - 'docs/decisions/**' pull_request: paths: - 'docs/decisions/**' jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Validate Structured MADR uses: modeled-information-format/structured-madr@v2 with: path: docs/decisions ``` `@v2` is a moving major-version tag that follows the latest 2.x release. Pin an exact release (`@v2.0.0`) or a commit SHA if you need a fixed version. Version 2 changes the `@id` that `mode: mif` projects (`urn:mif:`, not `urn:mif:smadr::`); see the [changelog](/reference/changelog/). ## Inputs [Section titled “Inputs”](#inputs) All inputs are optional. The action uses sensible defaults that work for most projects. | Input | Type | Default | Description | | --------------- | -------- | ---------------- | ----------------------------------------------------------------------------- | | `path` | `string` | `docs/decisions` | Path to the directory containing ADR files, relative to repository root | | `pattern` | `string` | `**/*.md` | Glob pattern for matching ADR files within the path | | `schema` | `string` | *(built-in)* | Path to a custom JSON Schema. Omit to use the built-in Structured MADR schema | | `strict` | `string` | `false` | Enable strict mode: fail the check on warnings in addition to errors | | `fail-on-error` | `string` | `true` | Whether to fail the workflow step when validation errors are found | ## Outputs [Section titled “Outputs”](#outputs) The action sets these outputs for use in subsequent workflow steps. | Output | Type | Description | | ---------- | -------- | ----------------------------------------------------------- | | `valid` | `string` | `"true"` if all ADRs passed validation, `"false"` otherwise | | `total` | `string` | Total number of ADR files checked | | `passed` | `string` | Number of files that passed validation | | `failed` | `string` | Number of files that failed validation | | `warnings` | `string` | Number of warnings generated | ## MIF conformance mode [Section titled “MIF conformance mode”](#mif-conformance-mode) Set `mode: mif` to validate ADRs as MIF (Modeled Information Format) instead of the MADR frontmatter check. Each invocation runs exactly one mode: `smadr` (default) or `mif`. To run both, add two separate steps — one with `mode: smadr` and one with `mode: mif`. The level is read from the consumer repo’s `.github/config.yml` unless overridden. | Input | Type | Default | Description | | ------------ | -------- | -------------------- | -------------------------------------------------------- | | `mode` | `string` | `smadr` | `smadr` (MADR frontmatter) or `mif` (MIF conformance) | | `mif-level` | `string` | `""` | Override the MIF level (1/2/3); empty reads `mif-config` | | `mif-config` | `string` | `.github/config.yml` | Path to the MIF config in the consumer repo | ```yaml - uses: modeled-information-format/structured-madr@v2 with: mode: mif path: docs/decisions # mif-level: 3 ``` Outputs in this mode: `mif-valid`, `mif-total`, `mif-passed`, `mif-failed`. The standard outputs (`valid`, `total`, `passed`, `failed`, `warnings`) are **not** set in `mode: mif` — the MADR validation step is skipped — so read the `mif-*` outputs instead. See the [MIF Compliance reference](/reference/mif-compliance/) for the level model and field mapping. ## Configuration Examples [Section titled “Configuration Examples”](#configuration-examples) ### Strict Mode [Section titled “Strict Mode”](#strict-mode) Fail the workflow on any warnings, not just errors: ```yaml - uses: modeled-information-format/structured-madr@v2 with: strict: 'true' ``` ### Custom ADR Directory [Section titled “Custom ADR Directory”](#custom-adr-directory) If your ADRs live in a non-default location: ```yaml - uses: modeled-information-format/structured-madr@v2 with: path: architecture/decisions ``` ### Custom Schema [Section titled “Custom Schema”](#custom-schema) Validate against your own extended schema: ```yaml - uses: modeled-information-format/structured-madr@v2 with: schema: .github/schemas/custom-madr.schema.json ``` ### Non-blocking Validation [Section titled “Non-blocking Validation”](#non-blocking-validation) Report validation results without failing the workflow: ```yaml - uses: modeled-information-format/structured-madr@v2 id: adr-check with: fail-on-error: 'false' - name: Report results run: | echo "Valid: ${{ steps.adr-check.outputs.valid }}" echo "Passed: ${{ steps.adr-check.outputs.passed }}/${{ steps.adr-check.outputs.total }}" ``` ### Using Outputs in Conditional Steps [Section titled “Using Outputs in Conditional Steps”](#using-outputs-in-conditional-steps) ```yaml - uses: modeled-information-format/structured-madr@v2 id: validate with: fail-on-error: 'false' - name: Comment on PR if: steps.validate.outputs.valid == 'false' uses: actions/github-script@v7 with: script: | github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: `ADR validation failed: ${context.steps.validate.outputs.failed} of ${context.steps.validate.outputs.total} files have errors.` }) ``` ## What Gets Validated [Section titled “What Gets Validated”](#what-gets-validated) The action performs two categories of validation: 1. **Frontmatter validation** – Checks YAML frontmatter against the JSON Schema, verifying required fields, types, formats, and constraints. 2. **Body structure validation** – Checks that the markdown body contains required sections in the correct order, including Status, Context, Decision Drivers, Considered Options, Decision, Consequences, and Audit. Validation errors appear as GitHub annotations on the pull request, pointing to specific lines in the file. ## Local Validation [Section titled “Local Validation”](#local-validation) You can run the same validation locally: ```bash git clone https://github.com/modeled-information-format/structured-madr.git cd structured-madr npm install INPUT_PATH=/path/to/your/docs/decisions npm run validate ``` # MIF Compliance > Validate structured-MADR ADRs as MIF (Modeled Information Format) at a user-selected conformance level. structured-MADR ADRs can be validated as **MIF (Modeled Information Format)** at a level you select. The markdown stays canonical; a MIF JSON-LD object is **derived** from each ADR’s frontmatter and body and validated against the chosen level. You do not write JSON-LD — you fill frontmatter, and the projector assembles and checks it. The capability ships as a self-contained Claude Code plugin homed at `.github/` (its root holds `.claude-plugin/plugin.json`, `commands/`, `agents/`, `skills/`, and `hooks/`), with vendored, checksum-pinned MIF schemas. The repository is also a plugin marketplace (`.claude-plugin/marketplace.json`), so the plugin is installable. ## Use it as a Claude Code plugin [Section titled “Use it as a Claude Code plugin”](#use-it-as-a-claude-code-plugin) The `mif-compliance` skill, the `/mif-validate` and `/mif-project` commands, the `adr-mif-author` agent, and an authoring-time `PostToolUse` hook load once the plugin is installed: ```text /plugin marketplace add modeled-information-format/structured-madr /plugin install structured-madr-mif@structured-madr ``` Contributors who clone this repository are prompted to enable it automatically once they trust the folder — `.claude/settings.json` registers the marketplace and enables the plugin at project scope. The PostToolUse hook is advisory (it warns, it does not block) unless `MIF_HOOK_STRICT=1` is set. ## Select the level [Section titled “Select the level”](#select-the-level) Edit the one config file, `.github/config.yml`: ```yaml version: 1.0.0 mifVersion: 1.4.2 mifConformanceLevel: 2 # 1 (core) | 2 (standard, default) | 3 (full) adrPath: docs/decisions ontologies: - id: structured-madr enabled: false extensions: [] ``` | Level | Adds (always-derivable) | Optional (validated only when present) | | ---------------- | ----------------------------------------------------------------------------- | -------------------------------------- | | **1 — Core** | `@id` (`urn:mif:`), `conceptType`, `content` (body), `created`, `title` | — | | **2 — Standard** | `namespace`, `modified`, `temporal` | `relationships`, `entities` | | **3 — Full** | `provenance`, `temporal.validFrom` | `citations`, `extensions`, `summary` | A sparse ADR (no `technologies`, no `related`) still passes every level — optional collections are validated only when present. ## How frontmatter maps to MIF [Section titled “How frontmatter maps to MIF”](#how-frontmatter-maps-to-mif) | Frontmatter | MIF field | | ---------------------------------------------------- | --------------------------------------------------------------- | | `title`, `created`, `updated`, `description`, `tags` | `title`, `created`, `modified`, `summary`, `tags` | | `category` | `namespace` = `_semantic/decisions/` | | `technologies` | `entities[]` (EntityReference, `Technology`) | | `related` | `relationships[] {type: relates-to, target: /decisions/}` | | `x-superseded-by` | `relationships[] {type: supersedes, target: /decisions/}` | | `author`, `project` | `provenance` (`sourceType: user_explicit`) | | body `[label](https://…)` | `citations[]` (Level 3) | You may also author MIF-native keys (`conceptType`, `namespace`, `relationships`, `entities`, `temporal`, `provenance`, `citations`, `id`) directly in frontmatter to override the derivation; they are deep-validated against the MIF schema after projection. ## Run the gate [Section titled “Run the gate”](#run-the-gate) ```bash npm run validate:mif # uses .github/config.yml npm run validate:mif -- --level 3 # override the level ``` The gate is fail-closed at the configured level and emits GitHub annotations naming any missing or invalid MIF field. ## In CI / downstream [Section titled “In CI / downstream”](#in-ci--downstream) The composite GitHub Action exposes a `mode: mif`, so any repository can validate its ADRs as MIF from the same Action it already uses (see [GitHub Action](/reference/github-action/)): ```yaml - uses: modeled-information-format/structured-madr@v2 with: mode: mif path: docs/decisions # mif-level: 3 # optional override ``` ## Concept ids [Section titled “Concept ids”](#concept-ids) MIF 1.4.0+ requires a concept `@id` of the form `urn:mif:`. The projector uses an ADR’s frontmatter `id` as is (lowercased) when it already holds a UUID (bare, `urn:mif:`, `urn:uuid:` or `{…}`). Otherwise (a slug, a legacy `urn:mif:smadr:…` id, or no `id`) it derives a deterministic UUIDv5 of the id the pre-1.4 projector emitted, `smadr::`, in the MIF namespace `uuid5(NAMESPACE_URL, "https://mif-spec.dev")`. Re-projecting an ADR keeps its `@id`, and the replaced id is kept in `aliases`. The gate fails when two ADRs project to the same `@id`, and warns when `config.yml`’s `mifVersion` differs from the MIF release this Action vendors. ## Vendored schemas [Section titled “Vendored schemas”](#vendored-schemas) `.github/schema/` is vendored verbatim from the immutable MIF 1.4.2 release mirror (`https://mif-spec.dev/schema/1.4.2/`); `.github/VENDOR.lock` pins `mifSpecVersion` and a per-file SHA-256, and `config.yml`’s `mifVersion` must match it. A `vendor-check` CI gate fails if any vendored file drifts. Do not hand-edit vendored schemas — re-vendor and regenerate the lock. # Schema > JSON Schema reference for Structured MADR frontmatter validation Structured MADR uses a [JSON Schema (Draft-07)](http://json-schema.org/draft-07/schema#) to validate the YAML frontmatter in every ADR. The schema enforces required fields, value constraints, and format rules. ## Required Fields [Section titled “Required Fields”](#required-fields) Every Structured MADR document must include the following fields in its YAML frontmatter: | Field | Type | Constraints | Description | | ------------- | -------- | ------------------ | ----------------------------------------------------------- | | `title` | `string` | 1-100 characters | Short descriptive title for the decision | | `description` | `string` | 1-300 characters | One-sentence summary of the decision | | `type` | `string` | Must be `"adr"` | Document type identifier | | `category` | `string` | Min 1 character | Decision category (e.g., `architecture`, `security`, `api`) | | `tags` | `array` | Min 1 item, unique | Keywords for categorization and search | | `status` | `enum` | See status values | Current status of the decision | | `created` | `string` | ISO 8601 date | Creation date (`YYYY-MM-DD`) | | `updated` | `string` | ISO 8601 date | Last update date (`YYYY-MM-DD`) | | `author` | `string` | Min 1 character | Decision author or team | | `project` | `string` | Min 1 character | Project identifier | ## Optional Fields [Section titled “Optional Fields”](#optional-fields) | Field | Type | Constraints | Description | | -------------- | ------- | -------------------------------------- | ---------------------------------------------------- | | `technologies` | `array` | Unique items | Technologies referenced or affected by this decision | | `audience` | `array` | Unique items | Intended readers of this ADR | | `related` | `array` | Unique, pattern `^[a-zA-Z0-9_-]+\.md$` | Filenames of related ADRs | ## Status Values [Section titled “Status Values”](#status-values) The `status` field must be one of: | Status | Description | Transitions To | | ------------ | ----------------------- | -------------------------- | | `proposed` | Under consideration | `accepted`, `superseded` | | `accepted` | Approved and active | `deprecated`, `superseded` | | `deprecated` | No longer recommended | `superseded` | | `superseded` | Replaced by another ADR | (terminal) | ## Tag Format [Section titled “Tag Format”](#tag-format) Tags must match the pattern `^[a-z0-9][a-z0-9-]*[a-z0-9]$` or be a single lowercase alphanumeric character. This enforces lowercase, hyphen-separated identifiers (e.g., `api-design`, `postgresql`, `ci-cd`). ## Extension Fields [Section titled “Extension Fields”](#extension-fields) The schema supports custom extension fields prefixed with `x-`. This allows teams to add project-specific metadata without violating validation: ```yaml --- title: "My Decision" x-team: platform x-priority: high --- ``` ## Example Frontmatter [Section titled “Example Frontmatter”](#example-frontmatter) ```yaml --- title: "Use PostgreSQL for Primary Storage" description: "Decision to adopt PostgreSQL as the primary database" type: adr category: architecture tags: - database - postgresql - storage status: accepted created: 2025-01-15 updated: 2025-01-20 author: Architecture Team project: my-application technologies: - postgresql - rust audience: - developers - architects related: - adr_0001.md --- ``` ## Using the Schema [Section titled “Using the Schema”](#using-the-schema) ### With ajv-cli [Section titled “With ajv-cli”](#with-ajv-cli) ```bash npx ajv validate -s schemas/structured-madr.schema.json -d your-adr.md ``` ### With check-jsonschema [Section titled “With check-jsonschema”](#with-check-jsonschema) ```bash check-jsonschema --schemafile schemas/structured-madr.schema.json your-adr.md ``` ### Programmatically [Section titled “Programmatically”](#programmatically) ```javascript import Ajv from "ajv"; import addFormats from "ajv-formats"; import schema from "./schemas/structured-madr.schema.json"; const ajv = new Ajv(); addFormats(ajv); const validate = ajv.compile(schema); const valid = validate(frontmatterObject); ``` ## Raw Schema [Section titled “Raw Schema”](#raw-schema) The full JSON Schema file is available at [`schemas/structured-madr.schema.json`](https://github.com/modeled-information-format/structured-madr/blob/main/schemas/structured-madr.schema.json) in the repository. # Body Sections > Required body sections including title, status, context, decision drivers, options, consequences, and audit. # 4. Body Sections [Section titled “4. Body Sections”](#4-body-sections) ## 4.1 Title [Section titled “4.1 Title”](#41-title) The document title MUST be an H1 heading in the format: ```markdown # ADR-{NUMBER}: {TITLE} ``` Where: * `{NUMBER}` is a unique identifier (typically zero-padded, e.g., `0001`) * `{TITLE}` matches the frontmatter `title` field ## 4.2 Status Section [Section titled “4.2 Status Section”](#42-status-section) The status section MUST be an H2 heading containing the current status. ```markdown ## Status Accepted ``` If the ADR supersedes another, this SHOULD be noted: ```markdown ## Status Accepted Supersedes ADR-0003 ``` ## 4.3 Context Section [Section titled “4.3 Context Section”](#43-context-section) The context section MUST be an H2 heading with the following subsections: ### 4.3.1 Background and Problem Statement [Section titled “4.3.1 Background and Problem Statement”](#431-background-and-problem-statement) An H3 subsection describing the situation requiring a decision. ```markdown ## Context ### Background and Problem Statement {Description of the context and the problem being solved} ``` ### 4.3.2 Current Limitations (Optional) [Section titled “4.3.2 Current Limitations (Optional)”](#432-current-limitations-optional) An H3 subsection listing limitations of the current approach. ```markdown ### Current Limitations {Numbered or bulleted list of limitations} ``` ## 4.4 Decision Drivers Section [Section titled “4.4 Decision Drivers Section”](#44-decision-drivers-section) The decision drivers section MUST be an H2 heading with hierarchical subsections: ### 4.4.1 Primary Decision Drivers [Section titled “4.4.1 Primary Decision Drivers”](#441-primary-decision-drivers) An H3 subsection listing the most important factors. ```markdown ## Decision Drivers ### Primary Decision Drivers 1. **{Driver Name}**: {Explanation} 2. **{Driver Name}**: {Explanation} ``` ### 4.4.2 Secondary Decision Drivers [Section titled “4.4.2 Secondary Decision Drivers”](#442-secondary-decision-drivers) An H3 subsection listing influential but non-decisive factors. ```markdown ### Secondary Decision Drivers 1. **{Driver Name}**: {Explanation} ``` ## 4.5 Considered Options Section [Section titled “4.5 Considered Options Section”](#45-considered-options-section) The options section MUST be an H2 heading with an H3 subsection for each option. ### 4.5.1 Option Structure [Section titled “4.5.1 Option Structure”](#451-option-structure) Each option MUST include: 1. **Description** - Brief overview 2. **Technical Characteristics** - Key technical attributes 3. **Advantages** - Benefits of this option 4. **Disadvantages** - Drawbacks of this option Each option SHOULD include: 5. **Risk Assessment** - Technical, schedule, and ecosystem risk ratings Each option MAY include: 6. **Disqualifying Factor** - Reason for rejection (if applicable) ```markdown ## Considered Options ### Option 1: {Title} **Description**: {Brief description} **Technical Characteristics**: - {Characteristic 1} - {Characteristic 2} **Advantages**: - {Advantage 1} - {Advantage 2} **Disadvantages**: - {Disadvantage 1} - {Disadvantage 2} **Risk Assessment**: - **Technical Risk**: {Low|Medium|High}. {Explanation} - **Schedule Risk**: {Low|Medium|High}. {Explanation} - **Ecosystem Risk**: {Low|Medium|High}. {Explanation} ``` ## 4.6 Decision Section [Section titled “4.6 Decision Section”](#46-decision-section) The decision section MUST be an H2 heading stating the chosen option and implementation details. ```markdown ## Decision {Clear statement of the decision} The implementation will use: - **{Component}** for {purpose} - **{Component}** for {purpose} ``` ## 4.7 Consequences Section [Section titled “4.7 Consequences Section”](#47-consequences-section) The consequences section MUST be an H2 heading with three subsections: ```markdown ## Consequences ### Positive 1. **{Title}**: {Description} ### Negative 1. **{Title}**: {Description} ### Neutral 1. **{Title}**: {Description} ``` ## 4.8 Decision Outcome Section [Section titled “4.8 Decision Outcome Section”](#48-decision-outcome-section) The outcome section MUST be an H2 heading summarizing results and mitigations. ```markdown ## Decision Outcome {Summary of how objectives are achieved} Mitigations: - {Mitigation for negative consequence} ``` ## 4.9 Related Decisions Section [Section titled “4.9 Related Decisions Section”](#49-related-decisions-section) The related decisions section MUST be an H2 heading linking to related ADRs. ```markdown ## Related Decisions - [ADR-{NUMBER}: {Title}]({filename}) - {Relationship description} ``` ## 4.10 Links Section [Section titled “4.10 Links Section”](#410-links-section) The links section MUST be an H2 heading with external resources. ```markdown ## Links - [{Resource Name}]({URL}) - {Description} ``` ## 4.11 More Information Section [Section titled “4.11 More Information Section”](#411-more-information-section) The more information section MUST be an H2 heading with metadata. ```markdown ## More Information - **Date:** {DATE} - **Source:** {Reference} - **Related ADRs:** {List} ``` ## 4.12 Audit Section [Section titled “4.12 Audit Section”](#412-audit-section) The audit section MUST be an H2 heading and MUST be present in all Structured MADR documents. ### 4.12.1 Audit Entry Structure [Section titled “4.12.1 Audit Entry Structure”](#4121-audit-entry-structure) Each audit entry MUST be an H3 heading with the audit date and contain: 1. **Status** - Audit result 2. **Findings** - Table of specific findings 3. **Summary** - Brief summary 4. **Action Required** - Required remediation ```markdown ## Audit ### {YYYY-MM-DD} **Status:** {Pending|Compliant|Non-Compliant|Partial} **Findings:** | Finding | Files | Lines | Assessment | |---------|-------|-------|------------| | {Description} | `{file}` | L{n}-L{m} | {compliant|non-compliant|partial} | **Summary:** {Brief summary} **Action Required:** {None|Description of required actions} ``` ### 4.12.2 Initial Audit Entry [Section titled “4.12.2 Initial Audit Entry”](#4122-initial-audit-entry) New ADRs SHOULD have an initial audit entry with status `Pending`: ```markdown ## Audit ### {DATE} **Status:** Pending **Findings:** | Finding | Files | Lines | Assessment | |---------|-------|-------|------------| | Awaiting implementation | - | - | pending | **Summary:** ADR created, awaiting implementation. **Action Required:** Implement decision and audit ``` # Extensions & Appendices > Custom extensions, MIME type, security considerations, and appendices for the Structured MADR specification. # 7. Extensions [Section titled “7. Extensions”](#7-extensions) ## 7.1 Custom Frontmatter Fields [Section titled “7.1 Custom Frontmatter Fields”](#71-custom-frontmatter-fields) Implementations MAY add custom frontmatter fields prefixed with `x-`: ```yaml x-review-board: ["alice", "bob"] x-implementation-phase: 2 ``` Custom fields MUST NOT conflict with reserved field names. ## 7.2 Custom Sections [Section titled “7.2 Custom Sections”](#72-custom-sections) Implementations MAY add custom sections after the Audit section. *** # 8. MIME Type [Section titled “8. MIME Type”](#8-mime-type) The RECOMMENDED MIME type for Structured MADR documents is: ```plaintext text/markdown; variant=structured-madr ``` *** # 9. Security Considerations [Section titled “9. Security Considerations”](#9-security-considerations) * Frontmatter SHOULD NOT contain sensitive information * File paths in audit findings SHOULD be relative * External links SHOULD use HTTPS *** # Appendix A: Complete Example [Section titled “Appendix A: Complete Example”](#appendix-a-complete-example) See `examples/complete-example.md` for a fully compliant example. *** # Appendix B: Changelog [Section titled “Appendix B: Changelog”](#appendix-b-changelog) ## Version 1.0.0 (2026-01-15) [Section titled “Version 1.0.0 (2026-01-15)”](#version-100-2026-01-15) * Initial release * YAML frontmatter specification * Body section requirements * Audit section specification * JSON Schema definition # File Naming & Validation > File naming conventions and validation requirements for Structured MADR documents. # 5. File Naming [Section titled “5. File Naming”](#5-file-naming) Structured MADR files SHOULD follow the naming convention: ```plaintext {NUMBER}-{slug}.md ``` Or: ```plaintext adr_{NUMBER}.md ``` Where: * `{NUMBER}` is a zero-padded identifier (e.g., `0001`, `0042`) * `{slug}` is a URL-friendly version of the title Examples: * `0001-use-postgresql-for-primary-storage.md` * `adr_0001.md` *** # 6. Validation [Section titled “6. Validation”](#6-validation) A Structured MADR document is valid if: 1. The YAML frontmatter is syntactically valid YAML 2. All required frontmatter fields are present with valid values 3. All required body sections are present 4. The audit section contains at least one entry 5. The document conforms to the JSON Schema in `schemas/structured-madr.schema.json` # YAML Frontmatter > Required and optional YAML frontmatter fields for Structured MADR documents. # 3. YAML Frontmatter [Section titled “3. YAML Frontmatter”](#3-yaml-frontmatter) ## 3.1 Format [Section titled “3.1 Format”](#31-format) The frontmatter MUST be enclosed in YAML document markers (`---`) at the beginning of the file. ```yaml --- # Frontmatter content --- ``` ## 3.2 Required Fields [Section titled “3.2 Required Fields”](#32-required-fields) The following fields MUST be present in every Structured MADR document: ### 3.2.1 `title` [Section titled “3.2.1 title”](#321-title) * **Type:** string * **Description:** A short, descriptive title for the decision * **Constraints:** * MUST be non-empty * SHOULD be 60 characters or fewer * SHOULD use title case ```yaml title: "Use PostgreSQL for Primary Storage" ``` ### 3.2.2 `description` [Section titled “3.2.2 description”](#322-description) * **Type:** string * **Description:** A one-sentence summary of the decision * **Constraints:** * MUST be non-empty * SHOULD be 160 characters or fewer ```yaml description: "Decision to adopt PostgreSQL as the primary database for the application" ``` ### 3.2.3 `type` [Section titled “3.2.3 type”](#323-type) * **Type:** string * **Description:** Document type identifier * **Constraints:** * MUST be exactly `"adr"` ```yaml type: adr ``` ### 3.2.4 `category` [Section titled “3.2.4 category”](#324-category) * **Type:** string * **Description:** The category of decision * **Constraints:** * MUST be non-empty * RECOMMENDED values: `architecture`, `api`, `security`, `performance`, `infrastructure`, `migration`, `integration`, `data`, `testing` ```yaml category: architecture ``` ### 3.2.5 `tags` [Section titled “3.2.5 tags”](#325-tags) * **Type:** array of strings * **Description:** Keywords for categorization and search * **Constraints:** * MUST contain at least one tag * Tags SHOULD be lowercase with hyphens for multi-word tags ```yaml tags: - database - postgresql - storage ``` ### 3.2.6 `status` [Section titled “3.2.6 status”](#326-status) * **Type:** string (enum) * **Description:** Current status of the decision * **Allowed Values:** * `proposed` - Decision is under consideration * `accepted` - Decision has been approved and is in effect * `deprecated` - Decision is no longer recommended * `superseded` - Decision has been replaced by another ADR * **Constraints:** * MUST be one of the allowed values ```yaml status: accepted ``` ### 3.2.7 `created` [Section titled “3.2.7 created”](#327-created) * **Type:** date * **Description:** Date the ADR was created * **Format:** ISO 8601 date (YYYY-MM-DD) ```yaml created: 2025-01-15 ``` ### 3.2.8 `updated` [Section titled “3.2.8 updated”](#328-updated) * **Type:** date * **Description:** Date the ADR was last modified * **Format:** ISO 8601 date (YYYY-MM-DD) * **Constraints:** * MUST be greater than or equal to `created` ```yaml updated: 2025-01-20 ``` ### 3.2.9 `author` [Section titled “3.2.9 author”](#329-author) * **Type:** string * **Description:** The author or team responsible for the decision * **Constraints:** * MUST be non-empty ```yaml author: Architecture Team ``` ### 3.2.10 `project` [Section titled “3.2.10 project”](#3210-project) * **Type:** string * **Description:** The project this decision applies to * **Constraints:** * MUST be non-empty * SHOULD be a consistent identifier across all project ADRs ```yaml project: my-application ``` ## 3.3 Optional Fields [Section titled “3.3 Optional Fields”](#33-optional-fields) The following fields MAY be present: ### 3.3.1 `technologies` [Section titled “3.3.1 technologies”](#331-technologies) * **Type:** array of strings * **Description:** Technologies referenced or affected by this decision ```yaml technologies: - postgresql - rust - tokio ``` ### 3.3.2 `audience` [Section titled “3.3.2 audience”](#332-audience) * **Type:** array of strings * **Description:** Intended readers of this ADR * **RECOMMENDED values:** `developers`, `architects`, `operators`, `stakeholders` ```yaml audience: - developers - architects ``` ### 3.3.3 `related` [Section titled “3.3.3 related”](#333-related) * **Type:** array of strings * **Description:** Filenames of related ADRs * **Constraints:** * SHOULD be relative filenames within the same ADR directory ```yaml related: - adr_0001.md - adr_0005.md ``` # Overview > Introduction to the Structured MADR specification, purpose, design goals, and document structure. # Structured MADR Specification [Section titled “Structured MADR Specification”](#structured-madr-specification) **Version:** 1.0.0 **Status:** Stable **Last Updated:** 2026-01-15 ## Abstract [Section titled “Abstract”](#abstract) This document specifies the Structured MADR format, an extension of MADR (Markdown Architectural Decision Records) that adds machine-readable YAML frontmatter, comprehensive option analysis with risk assessments, and required audit sections for compliance tracking. *** ## Status of This Document [Section titled “Status of This Document”](#status-of-this-document) This is the official specification for Structured MADR version 1.0.0. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). *** ## 1. Introduction [Section titled “1. Introduction”](#1-introduction) ### 1.1 Purpose [Section titled “1.1 Purpose”](#11-purpose) Structured MADR provides a standardized format for documenting architectural decisions that is: 1. **Human-readable** - Clear prose documentation for developers 2. **Machine-parseable** - Structured metadata for tooling 3. **Auditable** - Built-in compliance tracking 4. **Comprehensive** - Complete option analysis with risk assessment ### 1.2 Relationship to MADR [Section titled “1.2 Relationship to MADR”](#12-relationship-to-madr) Structured MADR is a superset of MADR 4.0.0. Any valid MADR document can be converted to Structured MADR by adding the required frontmatter and audit section. The body sections follow MADR conventions with extensions for hierarchical organization. ### 1.3 Design Goals [Section titled “1.3 Design Goals”](#13-design-goals) 1. **Backward Compatibility** - MADR-compatible section structure 2. **Forward Compatibility** - Extensible frontmatter schema 3. **Tool Interoperability** - Standard YAML and Markdown 4. **AI Optimization** - Metadata designed for LLM context injection *** ## 2. Document Structure [Section titled “2. Document Structure”](#2-document-structure) A Structured MADR document MUST contain the following components in order: 1. YAML Frontmatter (Section 3) 2. Title (Section 4.1) 3. Status Section (Section 4.2) 4. Context Section (Section 4.3) 5. Decision Drivers Section (Section 4.4) 6. Considered Options Section (Section 4.5) 7. Decision Section (Section 4.6) 8. Consequences Section (Section 4.7) 9. Decision Outcome Section (Section 4.8) 10. Related Decisions Section (Section 4.9) 11. Links Section (Section 4.10) 12. More Information Section (Section 4.11) 13. Audit Section (Section 4.12) # Templates > Full and bare Structured MADR templates for creating new ADRs Structured MADR provides two templates to help you get started quickly. Both templates include all required frontmatter fields and body sections. ## Full Template [Section titled “Full Template”](#full-template) The full template includes guidance text in each section, explaining what to write and how to structure the content. Use this template when you are new to Structured MADR or want reminders about what each section should contain. **File:** [`templates/template.md`](https://github.com/modeled-information-format/structured-madr/blob/main/templates/template.md) ### Frontmatter [Section titled “Frontmatter”](#frontmatter) ```yaml --- title: "{TITLE}" description: "{DESCRIPTION}" type: adr category: {CATEGORY} tags: - {tag} status: proposed created: {DATE} updated: {DATE} author: {AUTHOR} project: {PROJECT} technologies: - {technology} audience: - developers related: - {related_adr} --- ``` ### Sections Included [Section titled “Sections Included”](#sections-included) The full template provides placeholder text and guidance for every section: 1. **Status** – Current decision status 2. **Context** – Background, problem statement, and current limitations 3. **Decision Drivers** – Primary and secondary factors influencing the decision 4. **Considered Options** – Each option with description, characteristics, advantages, disadvantages, and a three-dimension risk assessment (Technical, Schedule, Ecosystem) 5. **Decision** – The chosen approach with implementation details 6. **Consequences** – Categorized as positive, negative, and neutral 7. **Decision Outcome** – Summary with mitigations for negative consequences 8. **Related Decisions** – Links to related ADRs 9. **Links** – External resources 10. **More Information** – Date, source, references 11. **Audit** – Compliance tracking with findings table ### Risk Assessment Format [Section titled “Risk Assessment Format”](#risk-assessment-format) Each considered option includes a structured risk assessment: ```markdown **Risk Assessment**: - **Technical Risk**: {Low|Medium|High}. {Explanation} - **Schedule Risk**: {Low|Medium|High}. {Explanation} - **Ecosystem Risk**: {Low|Medium|High}. {Explanation} ``` ## Bare Template [Section titled “Bare Template”](#bare-template) The bare template contains only the structural skeleton – section headings and empty fields – without guidance text. Use this template when you are comfortable with the format and want a clean starting point. **File:** [`templates/template-bare.md`](https://github.com/modeled-information-format/structured-madr/blob/main/templates/template-bare.md) ### What Is Included [Section titled “What Is Included”](#what-is-included) * Empty YAML frontmatter with all required fields * All section headings in the correct order * Empty risk assessment structure for two options * Empty audit findings table ### What Is Omitted [Section titled “What Is Omitted”](#what-is-omitted) * Guidance text explaining each section * Example values and placeholder descriptions * Instructional comments ## Downloading Templates [Section titled “Downloading Templates”](#downloading-templates) ### Using curl [Section titled “Using curl”](#using-curl) ```bash # Full template curl -O https://raw.githubusercontent.com/modeled-information-format/structured-madr/main/templates/template.md # Bare template curl -O https://raw.githubusercontent.com/modeled-information-format/structured-madr/main/templates/template-bare.md ``` ### Using wget [Section titled “Using wget”](#using-wget) ```bash wget https://raw.githubusercontent.com/modeled-information-format/structured-madr/main/templates/template.md wget https://raw.githubusercontent.com/modeled-information-format/structured-madr/main/templates/template-bare.md ``` ### Renaming for Your Project [Section titled “Renaming for Your Project”](#renaming-for-your-project) After downloading, rename the file to follow the ADR naming convention: ```bash mv template.md docs/decisions/0001-your-decision-title.md ``` ## Choosing a Template [Section titled “Choosing a Template”](#choosing-a-template) | Scenario | Recommended Template | | -------------------------------- | -------------------- | | First time using Structured MADR | Full template | | Experienced with the format | Bare template | | Onboarding new team members | Full template | | Rapid ADR creation | Bare template | | Learning what each section means | Full template | # Your First ADR > Walk through creating a complete Structured MADR document from scratch. This tutorial walks you through writing a complete Architectural Decision Record using Structured MADR. We will use a realistic scenario: choosing a database for a new web application. ## The Scenario [Section titled “The Scenario”](#the-scenario) Your team is building an order management system. You need to decide on a primary database. The candidates are PostgreSQL, MySQL, and MongoDB. Let’s document this decision properly. ## Create the File [Section titled “Create the File”](#create-the-file) ```bash touch docs/decisions/0001-select-primary-database.md ``` ## Write the Frontmatter [Section titled “Write the Frontmatter”](#write-the-frontmatter) Start with the YAML metadata block. This is the machine-readable part that enables tooling and AI integration: ```yaml --- title: "Select Primary Database" description: "Choose the primary database for the order management system." type: adr category: architecture tags: - database - storage - infrastructure status: proposed created: 2026-02-16 updated: 2026-02-16 author: Platform Team project: order-management technologies: - postgresql - mysql - mongodb audience: - developers - architects - devops --- ``` Notice that `technologies` lists all candidates, not just the winner. This helps tools surface the ADR when anyone searches for any of the evaluated technologies. ## Write the Heading and Status [Section titled “Write the Heading and Status”](#write-the-heading-and-status) ```markdown # ADR-0001: Select Primary Database ## Status Proposed ``` Keep the status in sync with the frontmatter `status` field. ## Describe the Context [Section titled “Describe the Context”](#describe-the-context) Explain why this decision needs to be made now: ```markdown ## Context ### Background and Problem Statement The order management system requires a persistent data store for orders, customers, inventory, and audit logs. The system must support ACID transactions for order processing and handle approximately 500 orders per minute at peak load. ### Current Limitations 1. **No existing database**: This is a greenfield project without an incumbent system. 2. **Multi-team access**: Three teams will query the database, requiring standard SQL interfaces. ``` Be specific about constraints and numbers. Vague context leads to vague decisions. ## List Decision Drivers [Section titled “List Decision Drivers”](#list-decision-drivers) Separate primary drivers (deal-breakers) from secondary drivers (nice-to-haves): ```markdown ## Decision Drivers ### Primary Decision Drivers 1. **ACID transactions**: Order processing requires strong consistency guarantees. 2. **SQL compatibility**: Multiple teams rely on SQL for analytics and reporting. 3. **Operational maturity**: The team has deep experience with relational databases. ### Secondary Decision Drivers 1. **JSON support**: Some order metadata is semi-structured. 2. **Managed service availability**: Prefer a database with managed hosting options on AWS and GCP. ``` ## Document Considered Options [Section titled “Document Considered Options”](#document-considered-options) This is the most detailed section. For each option, provide a structured evaluation: ```markdown ## Considered Options ### Option 1: PostgreSQL **Description**: Open-source relational database with extensive feature set. **Technical Characteristics**: - Full ACID compliance with MVCC - Native JSONB column type for semi-structured data - Row-level security and robust permission model **Advantages**: - Advanced indexing (B-tree, GIN, GiST, BRIN) - Mature replication and high-availability tooling - Strong JSON querying eliminates need for a separate document store **Disadvantages**: - Vertical scaling has practical limits before sharding is needed - Write-heavy workloads may require tuning **Risk Assessment**: - **Technical Risk**: Low. PostgreSQL is proven at this scale. - **Schedule Risk**: Low. Team has prior experience. - **Ecosystem Risk**: Low. Available as managed service on all major clouds. ### Option 2: MySQL **Description**: Widely-used open-source relational database. **Technical Characteristics**: - ACID compliance with InnoDB engine - Proven at large scale (Meta, GitHub) **Advantages**: - Extremely well-documented and widely understood - Fast read performance for simple queries **Disadvantages**: - JSON support is less mature than PostgreSQL - Fewer advanced indexing options - Window functions and CTEs added only in MySQL 8.0 **Risk Assessment**: - **Technical Risk**: Low. Mature and battle-tested. - **Schedule Risk**: Low. Familiar to most developers. - **Ecosystem Risk**: Low. Widely available as managed service. ### Option 3: MongoDB **Description**: Document-oriented NoSQL database. **Technical Characteristics**: - Document model with flexible schemas - Horizontal scaling via native sharding **Advantages**: - Flexible schema suits evolving data models - Built-in horizontal scaling **Disadvantages**: - No multi-document ACID transactions until v4.0, with performance overhead - Requires learning a non-SQL query language - Analytics teams would need adapters or ETL pipelines **Disqualifying Factor**: The requirement for multi-team SQL access and ACID transactions makes a document store a poor fit for the primary database. **Risk Assessment**: - **Technical Risk**: Medium. Transaction support is newer and less proven. - **Schedule Risk**: High. Team lacks MongoDB experience. - **Ecosystem Risk**: Low. Managed services widely available. ``` Notice the **Disqualifying Factor** on Option 3. When an option clearly fails a primary driver, call it out explicitly. ## State the Decision [Section titled “State the Decision”](#state-the-decision) ```markdown ## Decision We will use PostgreSQL as the primary database for the order management system. The implementation will use: - **Amazon RDS for PostgreSQL** for managed hosting with automated backups - **JSONB columns** for semi-structured order metadata - **pgAudit** for compliance-grade audit logging ``` ## Document Consequences [Section titled “Document Consequences”](#document-consequences) Split consequences into three categories: ```markdown ## Consequences ### Positive 1. **Strong consistency**: ACID transactions ensure order integrity across all operations. 2. **Single query language**: All teams use standard SQL without adapters. 3. **Operational confidence**: Team has five years of PostgreSQL production experience. ### Negative 1. **Vertical scaling ceiling**: If load exceeds single-instance capacity, sharding adds complexity. 2. **Managed service cost**: RDS pricing is higher than self-hosted for equivalent compute. ### Neutral 1. **Schema migrations required**: Relational schemas require explicit migrations, adding process but also providing an audit trail of data model changes. ``` ## Summarize and Add Audit [Section titled “Summarize and Add Audit”](#summarize-and-add-audit) ```markdown ## Decision Outcome PostgreSQL satisfies all primary decision drivers with low risk across all dimensions. The team's existing expertise minimizes onboarding time. Mitigations: - Monitor query performance and set up read replicas before reaching capacity limits - Evaluate Citus extension if horizontal scaling becomes necessary ## Related Decisions - [ADR-0002: Caching Strategy](0002-caching-strategy.md) - Cache layer to reduce database load ## Links - [PostgreSQL Documentation](https://www.postgresql.org/docs/) - Official reference - [pgAudit Extension](https://www.pgaudit.org/) - Audit logging for PostgreSQL ## More Information - **Date:** 2026-02-16 - **Source:** Platform Team architecture review meeting - **Related ADRs:** ADR-0002 ## Audit ### 2026-02-16 **Status:** Pending **Findings:** | Finding | Files | Lines | Assessment | |--------------------------|-------|-------|------------| | Awaiting implementation | - | - | pending | **Summary:** ADR created, awaiting implementation. **Action Required:** Implement decision and audit after deployment. ``` ## Updating the Status [Section titled “Updating the Status”](#updating-the-status) Once stakeholders approve, update both the frontmatter `status` field and the Status section: ```yaml status: accepted ``` ```markdown ## Status Accepted ``` When the implementation is complete, add a new audit entry with findings that reference specific files and line numbers in your codebase. # Getting Started > Install and configure Structured MADR for your project in minutes. Structured MADR extends the popular [MADR](https://adr.github.io/madr/) format with YAML frontmatter, risk assessments, and audit trails. This guide walks you through adopting it in an existing project. ## Prerequisites [Section titled “Prerequisites”](#prerequisites) * A project repository (Git recommended) * A directory for architectural decisions (e.g., `docs/decisions/`) ## Step 1: Get the Template [Section titled “Step 1: Get the Template”](#step-1-get-the-template) Download the Structured MADR template directly into your project: ```bash mkdir -p docs/decisions curl -o docs/decisions/0001-your-decision.md \ https://raw.githubusercontent.com/modeled-information-format/structured-madr/main/templates/template.md ``` Alternatively, if you prefer a minimal starting point, use the bare template: ```bash curl -o docs/decisions/0001-your-decision.md \ https://raw.githubusercontent.com/modeled-information-format/structured-madr/main/templates/template-bare.md ``` The full template includes placeholder text explaining each section. The bare template provides just the section headings so you can fill them in from scratch. ## Step 2: Fill in the Frontmatter [Section titled “Step 2: Fill in the Frontmatter”](#step-2-fill-in-the-frontmatter) Every Structured MADR document starts with a YAML frontmatter block. This metadata is what makes your ADRs machine-readable. Open the file and replace the placeholders: ```yaml --- title: "Use PostgreSQL for Primary Storage" description: "Decision to adopt PostgreSQL as the application database" type: adr category: architecture tags: - database - postgresql status: proposed created: 2025-01-15 updated: 2025-01-15 author: Architecture Team project: my-application technologies: - postgresql audience: - developers - architects --- ``` ### Required fields [Section titled “Required fields”](#required-fields) | Field | Purpose | | ------------- | ---------------------------------------------------------- | | `title` | Short descriptive title for the decision | | `description` | One-sentence summary | | `type` | Always `"adr"` | | `category` | Decision category (e.g., architecture, security) | | `tags` | Keywords for filtering and search | | `status` | One of: `proposed`, `accepted`, `deprecated`, `superseded` | | `created` | Creation date in `YYYY-MM-DD` format | | `updated` | Last update date in `YYYY-MM-DD` format | | `author` | Person or team making the decision | | `project` | Project identifier | ### Optional fields [Section titled “Optional fields”](#optional-fields) | Field | Purpose | | -------------- | ------------------------------------- | | `technologies` | Technologies involved in the decision | | `audience` | Who should read this ADR | | `related` | Filenames of related ADRs | ## Step 3: Document Your Decision [Section titled “Step 3: Document Your Decision”](#step-3-document-your-decision) Follow the template sections in order. Each section serves a specific purpose: 1. **Status** – Mirror the frontmatter status value in prose. 2. **Context** – Describe the background, problem statement, and current limitations. 3. **Decision Drivers** – List primary and secondary factors influencing the decision. 4. **Considered Options** – Document each option with technical characteristics, advantages, disadvantages, and a risk assessment. 5. **Decision** – State the chosen approach clearly and directly. 6. **Consequences** – Split into positive, negative, and neutral outcomes. 7. **Decision Outcome** – Summarize results and list mitigations for negative consequences. 8. **Related Decisions** – Link to other ADRs in your project. 9. **Links** – External resources and references. ## Step 4: Add the Audit Trail [Section titled “Step 4: Add the Audit Trail”](#step-4-add-the-audit-trail) The audit section is what sets Structured MADR apart for compliance-driven teams. After implementation, add an audit entry: ```markdown ## Audit ### 2025-02-01 **Status:** Compliant **Findings:** | Finding | Files | Lines | Assessment | |-----------------------|--------------------|----------|------------| | PostgreSQL configured | `src/db/config.rs` | L15-L45 | compliant | **Summary:** Implementation follows ADR specifications. **Action Required:** None ``` Each audit entry records: * The date of the audit * Whether the implementation is compliant * Specific findings mapped to files and line numbers * Any required follow-up actions ## Step 5: Number Your ADRs [Section titled “Step 5: Number Your ADRs”](#step-5-number-your-adrs) Use a consistent numbering scheme. The recommended pattern is: ```plaintext docs/decisions/ 0001-use-postgresql-for-storage.md 0002-adopt-rest-api-pattern.md 0003-switch-to-event-sourcing.md ``` Use zero-padded four-digit numbers to keep files sorted correctly. ## Next Steps [Section titled “Next Steps”](#next-steps) * [Write your first ADR](/tutorials/first-adr) with a step-by-step walkthrough * [Set up CI validation](/guides/ci-validation) to catch formatting errors automatically * [Validate locally](/guides/local-validation) before pushing changes * [Integrate with AI tools](/guides/ai-integration) to get the most from your structured metadata