Topic: ADR template for Azure DevOps
ADR Template for Azure DevOps — Repos, Wiki, and Work Items
Azure DevOps gives engineering teams three places to put architecture decision records — Repos (Markdown files in the code repository), Wiki (a separate editable knowledge base), and Work Items (structured metadata). Only one of those locations gives you the immutability guarantee that ADRs require. This page explains which one, how to wire up the ADO Work Item integration for lifecycle tracking, and how to configure Azure Pipelines as the CI validation gate for your decision directory.
TL;DR
Put canonical ADRs in ADO Repos as Markdown files at /docs/decisions/NNNN-title.md, protected by a branch policy that requires PR review before merging. Use ADO Work Items with a custom Architecture Decision Work Item type to track ADR lifecycle status (Proposed → Accepted → Superseded) and link decisions to the Epics or User Stories they govern. Use ADO Wiki for drafting and stakeholder review only — not as the canonical archive, because Wiki pages have no PR gate and can be edited by any Contributor. Add an Azure Pipelines Build Validation policy to enforce ADR structure on pull requests. The ADO export story for Repo files is excellent — git clone gets you everything, already in Markdown, with full history.
The three Azure DevOps surfaces for ADRs
ADO provides three storage surfaces, each with a different fidelity–accessibility trade-off for architecture decision records:
- ADO Repos (Markdown files in a code repository). Commits are immutable. Every change requires a pull request with branch policy enforcement. The file is co-located with the code it governs. Cloning the repository gives you the complete ADR archive in native Markdown with full history. This is the correct canonical location for ADRs.
- ADO Wiki. A separate wiki repository inside the ADO project, rendered as a navigable knowledge base. Readable by stakeholders without repository access. Editable by any Contributor without a PR. Useful for drafting and non-engineer review, but lacks the immutability constraint that makes ADRs authoritative. The correct use is as a drafting surface before graduation to Repos.
- ADO Work Items. Structured metadata tracker. The right place to store ADR lifecycle fields (Status, Decider, Date Decided), link decisions to the Epics and User Stories they govern, and surface ADR status in board and query views. Not the right place for the ADR body text — Work Item Description fields export as plain text with formatting stripped and are editable by anyone with Basic access.
The correct ADO ADR architecture uses all three surfaces in sequence: draft in Wiki, track lifecycle in Work Items, commit the canonical body in Repos. The Repos file is the primary artifact; Wiki and Work Items are the supporting provenance layer.
Setting up ADO Repos for ADRs
The minimal Repos configuration for ADR storage requires choosing a file location, establishing a naming convention, and setting a branch policy that enforces review before ADR changes are merged.
Directory location and naming convention
Place ADR Markdown files in a directory that is co-located with the code they govern, not in a separate documentation repository. The most common conventions by codebase type are:
- Single-service repository:
/docs/decisions/— directly in the repository root. Discoverable by any engineer who explores the/docs/directory. - Monorepo: Either a central
/docs/decisions/directory for cross-service decisions and per-service/services/{name}/docs/decisions/directories for service-scoped decisions, or per-service only with a/docs/decisions/index page that links to service-specific directories. See ADR directory structure in a monorepo for the trade-offs.
Use the four-digit-padded numbered filename convention: 0042-use-postgresql-full-text-search.md. Pad to four digits to survive growth past 999 ADRs without renaming. Kebab-case the title. Never change the filename after the ADR is Accepted — the filename is the stable identifier that all cross-references use.
The YAML frontmatter for each ADR file should include the fields that the Azure Pipelines validation script will check:
---
title: "Use PostgreSQL full-text search instead of Elasticsearch"
status: Accepted
date: 2026-05-14
deciders: ["@alice", "@bob"]
supersedes: ""
superseded-by: ""
work-item: "https://dev.azure.com/{org}/{project}/_workitems/edit/2042"
---
## Context
[Two to four sentences. What forced this decision? What constraints exist?
What would happen without this change?]
## Decision
We will use PostgreSQL full-text search instead of introducing an Elasticsearch cluster.
## Consequences
**Positive:**
- No additional infrastructure to operate or monitor.
- Full-text search is co-located with relational queries — a single transaction can combine both.
**Negative (trade-offs):**
- PostgreSQL full-text ranking is less sophisticated than Elasticsearch's BM25 with field boosting.
- Migrating to Elasticsearch later requires a new cluster rollout and a data migration.
**Neutral:**
- The search API surface stays unchanged — the implementation change is internal.
## Alternatives considered
| Option | Why rejected |
|---|---|
| Elasticsearch | Operational overhead disproportionate to search volume at current scale. |
| MeiliSearch | Mature for product search, less proven for technical document retrieval at our query pattern. |
## Deliberation record
Work Item: [ADR-2042](https://dev.azure.com/{org}/{project}/_workitems/edit/2042)
AI chat session: see WhyChose export for the 2026-05-12 Claude session that compared the indexing strategies.
Branch policy for the decisions directory
A branch policy on the main branch ensures that no ADR can be merged to the canonical archive without peer review. To configure this in Azure DevOps:
- Navigate to Project Settings → Repos → Repositories → [repo] → Policies, or to Project Settings → Repos → Branches → [main] → Branch Policies.
- Under Require a minimum number of reviewers, set minimum reviewers to 1. Enable Allow requestors to approve their own changes to Off for the ADR path (this prevents the author from self-approving without a second review).
- Under Build Validation, add the Azure Pipelines ADR validation pipeline (configured below) and set it to Required. Set the path filter to
/docs/decisions/*.mdso the pipeline only triggers on changes to ADR files — not every commit to main. - Under Automatically included reviewers, add a security group (
architecture-reviewers) as an optional reviewer on the/docs/decisions/path. This notifies the group on every ADR PR without making them a required approver — useful for teams where architecture review is a courtesy copy, not a gate.
Azure Pipelines validation pipeline
The pipeline YAML below validates ADR Markdown files on every pull request that touches the /docs/decisions/ path. It checks the YAML frontmatter fields that define a well-formed ADR, not the prose content — CI can enforce structure but not quality:
trigger: none
pr:
paths:
include:
- docs/decisions/**
pool:
vmImage: ubuntu-latest
steps:
- script: |
pip install python-frontmatter pyyaml
displayName: Install dependencies
- script: |
python - <<'EOF'
import frontmatter, sys, os, glob
REQUIRED_FIELDS = ["title", "status", "date", "deciders"]
VALID_STATUSES = {"Proposed", "Under Review", "Accepted",
"Superseded", "Deprecated"}
errors = []
for path in glob.glob("docs/decisions/*.md"):
post = frontmatter.load(path)
name = os.path.basename(path)
for field in REQUIRED_FIELDS:
if not post.get(field):
errors.append(f"{name}: missing required field '{field}'")
status = post.get("status", "")
if status not in VALID_STATUSES:
errors.append(f"{name}: invalid status '{status}'")
if status == "Superseded":
sup = post.get("superseded-by", "")
if not sup:
errors.append(f"{name}: status Superseded requires non-empty 'superseded-by'")
else:
target = os.path.join("docs/decisions", sup)
if not os.path.isfile(target) and not os.path.isfile(target + ".md"):
errors.append(f"{name}: superseded-by '{sup}' does not resolve to a file")
if errors:
for e in errors:
print(f"FAIL: {e}")
sys.exit(1)
print(f"OK: {len(list(glob.glob('docs/decisions/*.md')))} ADR files validated")
EOF
displayName: Validate ADR frontmatter
This pipeline is the Azure DevOps equivalent of the ADR GitHub Action. Both enforce the same structural invariants — required frontmatter fields, controlled status vocabulary, and the superseded-by file pointer resolution — using the platform's native CI mechanism instead of the other.
Setting up ADO Work Items for ADR lifecycle tracking
Work Items are the right place to store ADR metadata — lifecycle status, the identity of the engineer who made the call, and the links to other Work Items the decision governs. The ADR body text lives in Repos; the ADR lifecycle metadata lives in Work Items.
Creating the Architecture Decision Work Item type
Azure DevOps allows custom Work Item types at the process template level. The steps differ slightly between Agile, Scrum, and CMMI process templates, but the principle is the same across all three:
- Navigate to Organization Settings → Boards → Process → [your process] → Work Item Types → New Work Item Type.
- Name it
Architecture Decision. Select the Epic icon (or a custom icon if your organization uses them) to make it visually distinct in board and backlog views. - Add the custom fields described in the table below.
- Apply the process customization to the target project under Organization Settings → Boards → Process → [your process] → Projects.
Custom fields for the Architecture Decision Work Item type
| Field name | Type | Values / notes | When to populate |
|---|---|---|---|
| ADR Status | Picklist (single) | Proposed / Under Review / Accepted / Superseded / Deprecated | At creation (Proposed). Keep distinct from the standard State field — ADR Status tracks decision lifecycle, not implementation workflow. |
| Decider | Identity (single) | The engineer or EM who made the final call — not the Work Item creator | When Status moves to Under Review. Prevents "who owns this?" during handoffs. |
| Date Decided | Date/time | When ADR Status moved to Accepted — not the Work Item creation date | At graduation. The gap between Created and Date Decided reveals how long decisions take to formalize — a useful team health metric. |
| Supersedes | Integer (Work Item ID) | Work Item ID of the ADR this one replaces (e.g., 2038) | Only when this ADR replaces a prior decision. Enables querying the supersession chain in Work Item queries. |
| Repo File | URL (or text) | Direct URL to the committed Markdown file in the ADO Repos browser | Added at graduation. Turns the Work Item into a pointer to the canonical Markdown file — the Work Item becomes the provenance record, the file is the ADR. |
Linking Architecture Decision Work Items to implementation work
ADO Work Items support several link types. The most useful for ADRs are:
- Related — link the Architecture Decision Work Item to the Epic or Feature it governs. Use the "Related" link type from the ADR Work Item to the implementation Epic. When engineers open the Epic during sprint planning, the linked ADR is visible in the Related section — the rationale is one click away.
- Predecessor / Successor — if a previous Architecture Decision is being superseded, link the new ADR as Successor to the old ADR. This creates a navigable timeline of the decision evolution without requiring engineers to read the Supersedes field.
- Duplicate — for cases where a decision was proposed twice before consensus: link the draft duplicate to the canonical ADR Work Item and close the duplicate. Keeps the Work Item board clean without losing the proposal history.
Name Architecture Decision Work Items using the convention ADR-NNNN: [Title — name the decision, not the problem] — for example, ADR-0042: Use PostgreSQL full-text search instead of Elasticsearch. This makes ADR Work Items scannable in the backlog and searchable by number in PR comments across the entire project. Teams with hundreds of Work Items often set up a dedicated Architecture area path and a dedicated Architecture Decisions board to surface ADR Work Items separately from sprint work.
Using ADO Wiki for drafting
ADO Wiki is useful for drafting ADRs before they are ready for the formal review cycle, and for publishing a human-readable index of accepted decisions for stakeholders who do not navigate the code repository. The key constraint to communicate to your team: the Wiki page is a draft surface, not the canonical ADR.
Setting up the Architecture Decisions section in ADO Wiki
- In the ADO project Wiki, create a top-level page called Architecture Decisions. Add a child page called Index that lists all ADRs by number with their status — this is the human-readable register your non-engineer stakeholders will reference.
- Create a page template (a page named
_ADR-Templateor similar) that engineers copy when drafting a new ADR. The template should contain the full Nygard-format structure with guidance comments in each section. - Wire the Wiki index page to the committed Markdown files in Repos: for each Accepted ADR, the Wiki index entry links to the file in the Repos browser (the URL follows the pattern
https://dev.azure.com/{org}/{project}/_git/{repo}?path=/docs/decisions/NNNN-title.md). Engineers click through from the Wiki index to the authoritative file.
Because the ADO Wiki is stored as a separate git repository, you can clone it locally: find the clone URL under Wiki → More options → Clone wiki. This means Wiki pages are recoverable via git clone even without the ADO interface — a significantly better export story than Confluence or Notion for teams migrating off ADO.
ADO export — the best story of any PM tool for ADR archival
Understanding what Azure DevOps exports determines your migration risk. ADO's export story is the strongest of any project management tool for ADR storage:
| Item | Export path | Format recovered | Notes |
|---|---|---|---|
| ADR Markdown files in Repos | git clone — the complete repository with full history |
Native Markdown, all YAML frontmatter, complete commit log | The strongest export story — no API conversion required. Survives any ADO subscription change. |
| ADO Wiki pages | git clone of the wiki repository (separate clone URL in Wiki settings) |
Markdown files with complete edit history | ADO Wiki pages are Markdown files in a git repo — clone and you have the full content. Significantly better than Confluence HTML export. |
| Architecture Decision Work Items | Boards → Work Items → Export to CSV; or REST API at /wit/workitems?ids=… |
CSV (custom fields included); JSON via REST API | Custom fields like ADR Status, Decider, Date Decided are included in both CSV and API responses. Description field is plain text in CSV, HTML in API responses. |
| Work Item links (Related, Predecessor, Successor) | REST API at /wit/workitems/{id}?$expand=relations |
JSON with rel type and url for each linked Work Item |
The relational ADR-to-Epic link graph is only fully recoverable via the API. CSV export does not include Work Item link metadata. |
| Azure Pipelines ADR validation history | Build results in ADO Pipelines UI; REST API at /build/builds?definitionId=… |
Build logs and test results per run | The pipeline run history shows which ADR PRs passed or failed validation and why — useful for an ADR quality audit trail. |
The git-based export for both Repos and Wiki is what makes ADO a migration-resilient ADR home compared to Jira and Confluence. A Jira export requires ADF-to-Markdown conversion that is lossy for tables and code blocks; an ADO Repos clone recovers the Markdown file unchanged. Teams migrating from ADO to GitHub get their entire ADR archive for free with git clone and git push.
Azure DevOps vs other platforms for ADR storage
| Platform | ADR body storage | Immutability | Export path | Work Item integration |
|---|---|---|---|---|
| Azure DevOps Repos | Markdown files in code repo, co-located with the code they govern | Full — git commit trail, branch policy enforces PR review | git clone — native Markdown, full history, no conversion |
Yes — link ADR Work Items to Epics/Features via Related link type; Build Validation pipeline enforces structure |
| GitHub | Markdown files in code repo, same pattern as ADO Repos | Full — git commit trail, branch protection rule enforces PR review | git clone — identical to ADO Repos export story |
Yes — link ADR PR to Issues via closing keywords; GitHub Actions CI for validation (see ADR GitHub Action) |
| Jira + Confluence | Confluence page (ADR body) + Jira Issue (metadata) | None — Confluence pages editable without PR; Jira descriptions editable by any project member | Confluence Space export (HTML, not native Markdown); Jira CSV (description as plain text, formatting stripped) | Yes — Jira Issues macro, Jira Issue Links, bidirectional via Jira Epic ↔ Confluence page |
| Linear | Linear Documents (drafting); Markdown files in repo (canonical) | None for Documents — editable by workspace members; full for graduated Markdown files | Linear Documents: GraphQL API only (body not Markdown, no CSV/file export); Markdown files: git clone | Yes — Relations feature links Documents to Issues and Projects; bidirectional navigation in Linear UI |
| Notion | Notion database page (drafting); Markdown files in repo (canonical) | None for Notion pages; full for graduated Markdown files | Notion Markdown export per page — closest to native Markdown of the non-git PM tools | Via Relation property between ADR database and tasks database; or via @mentions in page body |
| Obsidian (git-backed vault) | Obsidian notes (drafting + canonical, if vault is git-backed) | Full if vault is git-backed — same git immutability as ADO Repos | Native Markdown files — git clone of the vault repository |
Via wikilinks and YAML frontmatter fields; Dataview queries for ADR status dashboards |
Why this matters for decision capture
The Azure DevOps ADR workflow — Repos for the canonical file, Work Items for lifecycle metadata, Wiki for drafting — solves the storage and tracking problem for decisions that are written down. But it does not solve the upstream gap: decisions that were made in AI chat sessions before anyone opened ADO.
In practice, significant architecture decisions are often worked through in ChatGPT or Claude before the engineer creates a Work Item or writes the first line of an ADR. The trade-off analysis, the alternatives comparison, the constraints that ruled out the second option — that reasoning lives in an AI chat session. The Work Item that follows captures "we decided to use PostgreSQL FTS," but not why Elasticsearch was rejected or what the conversation thread looked like when the team reached consensus.
For decisions already captured in AI chat history, the WhyChose extractor reads your ChatGPT or Claude conversations.json export and surfaces the architecture calls inside as structured decision records — with Context, Decision, and Consequences sections reconstructed from the conversation thread. The output is Nygard-compatible Markdown ready to drop into /docs/decisions/, with the frontmatter fields pre-populated for the Azure Pipelines validation pipeline. Paste the extracted ADR into an Architecture Decision Work Item description during the review cycle, merge it via the branch policy PR, and update the Repo File field to point at the committed file. The ADO Work Item becomes the provenance record; the committed Markdown file is the canonical ADR.
Related questions
Should I put ADRs in the ADO Repo or the ADO Wiki?
ADO Repos is the right location for canonical ADRs. Markdown files committed to a code repository carry the immutability guarantee ADRs require: every change is a commit with author, timestamp, and diff; the PR branch policy enforces review before any change is merged; and the file survives project renaming or archiving. ADO Wiki is editable by any Contributor without a PR gate — it is useful for drafting and stakeholder review, but it cannot serve as the authoritative archive. Draft in ADO Wiki, then graduate to a committed Markdown file in /docs/decisions/ via a pull request with the branch policy applied.
What Work Item fields are most useful for ADR tracking in Azure DevOps?
The four most useful custom fields for an Architecture Decision Work Item type are: ADR Status (picklist: Proposed / Under Review / Accepted / Superseded / Deprecated — distinct from the standard State field so it does not disrupt the standard Active/Resolved/Closed workflow), Decider (identity field — the engineer who made the final call, not the Work Item creator), Date Decided (date field — when Status moved to Accepted, not when the Work Item was created), and Repo File (URL field — the path to the committed Markdown file in the Repos browser, added at graduation). A fifth field, Supersedes (integer — the Work Item ID of the ADR this one replaces), is useful for teams with an active supersession cycle. Do not add more than five fields initially — schema inflation makes the Work Item type feel bureaucratic and engineers stop filling in metadata consistently.
How do I set up Azure Pipelines validation for ADR files?
The pipeline YAML is triggered on pull requests that touch the /docs/decisions/ path. It runs a Python script that checks every Markdown file in the directory for required frontmatter fields (title, status, date, deciders), valid status vocabulary (Proposed / Under Review / Accepted / Superseded / Deprecated), and a non-empty superseded-by field whose value resolves to a file in the same directory for any Superseded ADR. The pipeline is added as a required Build Validation in the target branch's Branch Policies under Project Settings → Repos → Branches → [main] → Build Validation. Pull requests that modify ADR files cannot be completed until the pipeline passes.
Does the Azure DevOps export include ADR Markdown files?
Yes — and this is the strongest export story of any PM tool for ADR storage. Markdown files committed to an ADO Repos repository are exported via git clone: the full file content, complete commit history, and all branch and tag metadata are available locally without any API conversion step. The files are already Markdown, already version-controlled, and already immutable. For ADO Wiki, the wiki content is stored as a separate git repository cloneable from the Wiki's clone URL. Work Item data exports via the ADO CSV export or the Azure DevOps REST API (/wit/workitems), with custom fields included in the API response.
Further reading
- The ADR GitHub Action — a CI pipeline for architecture decision records — the GitHub-native equivalent of the Azure Pipelines validation pipeline. The same structural checks (required frontmatter, status vocabulary, superseded-by resolution) implemented as a GitHub Actions workflow triggered on pull requests to the
/docs/decisions/path. Useful reference if your team is considering a migration from ADO to GitHub, or if you want to compare the two CI approaches. - ADR template for Jira — custom fields, Confluence integration, and the graduated handoff — the Atlassian equivalent of the ADO Work Item integration. The same graduated handoff pattern (draft in Confluence, track lifecycle in Jira Issues with custom fields, graduate to committed Markdown) described for the Atlassian stack. The export gap analysis for Jira and Confluence is significantly worse than for ADO — Jira CSV strips formatting from description fields, and Confluence HTML export requires conversion to Markdown.
- ADR template in Linear — Documents, custom properties, and the graduated handoff — the Linear equivalent. Linear Documents for drafting, custom properties for lifecycle tracking, and the graduated handoff to committed Markdown. The Linear export gap (GraphQL API only for Document bodies, no native Markdown export) is worse than both ADO and GitHub.
- ADR directory structure in a monorepo — per-service vs central, numbering, and CI — directly applicable to large ADO Repos monorepos. The per-service vs central ADR directory decision, how to number ADRs without collisions across services, and how to configure the Azure Pipelines path filter to validate only the service-specific ADR directory on each PR.
- ADR tooling comparison — adr-tools vs Log4Brains vs adr-log vs hand-rolled — the broader evaluation of ADR creation and publication tooling. adr-tools (Bash CLI for creating ADR Markdown files) and Log4Brains (Node.js site generator for publishing the ADR directory as a searchable web UI) both integrate with ADO Repos without modification — they work against local file paths and push via the standard git workflow. The comparison table covers all four options across 12 dimensions.
- ADR review checklist — what to look for before merging an architecture decision record — the 12-item checklist for reviewing a graduated ADR Markdown file in a pull request. The checklist applies identically to ADO Repos PRs and GitHub PRs — the structural requirements (Title names the decision not the problem, Decision is one active-voice sentence, Consequences includes at least one downside) do not depend on which platform hosts the repository.
- ADR template for Microsoft Teams — Loop, Planner, and channel-based review — the non-code-adjacent alternative for ADRs that require non-technical stakeholder participation: Microsoft Loop as the document surface, Teams channels for the announce-then-silence ceremony, and Planner for status tracking. The graduation path described there (Loop draft → committed ADO Repos Markdown) is the bridge between the two approaches on this page.
- The open-source extractor — reads your ChatGPT or Claude conversations.json export and surfaces the architecture decisions inside as Nygard-compatible Markdown with YAML frontmatter pre-populated for the ADO Pipelines validation check. The extracted records are ready to drop into
/docs/decisions/, open a PR against the branch policy, and wire the Repo File field in the ADO Work Item.