15 KiB
Architecture Decision Records
This directory contains the Architecture Decision Records (ADRs) for CleverAgents. Each ADR captures a single significant architectural decision — the context that motivated it, the decision itself, its design implications, constraints, consequences, and how compliance is verified.
The CleverAgents Specification evolves from ADRs, which is the sole source of truth for the system's architecture and behavior. An ADRs acceptance ultimately results in rewriting the specification to incorperate the new architectural decision. Architectural changes to the specification should only be possible through the introduction of new ADR.
What Is an ADR?
An Architecture Decision Record is a short document that records a significant architectural choice along with the context and consequences of that choice. ADRs provide a decision log that helps current and future contributors understand why the system is shaped the way it is — not just what was built, but the reasoning, trade-offs, and alternatives that led to each decision.
Front-Matter
Every ADR begins with a YAML front-matter block that provides structured metadata. This metadata drives the rendered header, status timeline, and the inventory tables below. The front-matter fields are:
| Field | Type | Required | Description |
|---|---|---|---|
adr_number |
integer | yes | Sequential ADR identifier (e.g., 1, 42). Used to generate the page title as ADR-NNN: <title>. |
title |
string | yes | Human-readable title. Combined with adr_number to produce the H1 heading automatically — do not add an # H1 line in the markdown body. |
status_history |
list | yes | Chronological list of status transitions. Each entry is a tuple of [date, status] or [date, status, person(s)]. See Status Lifecycle for valid statuses. |
tier |
integer | yes | Architectural tier (1–4). See Tier System. |
authors |
list of strings | no | Contributors who authored or substantially edited the ADR. |
superseded_by |
integer | no | ADR number of the decision that replaces this one. Only meaningful when the current status is Superseded. Renders as a link in the page header. |
related_adrs |
list of objects | no | Cross-references to other ADRs. Each entry has number (int), title (string), and relationship (string). The build system generates the Related ADRs table from this data. |
acceptance |
object | no | Governance voting record. Contains votes_for, votes_against, and abstentions — each a list of objects with voter (string) and comment (string). The build system generates the Acceptance section from this data. |
Example front-matter:
---
adr_number: 17
title: "Automation Profiles"
status_history:
- ["2026-02-16", "Draft", "Jeffrey Phillips Freeman"]
- ["2026-02-16", "Proposed", "Jeffrey Phillips Freeman"]
- ["2026-02-16", "Accepted", "Jeffrey Phillips Freeman"]
tier: 3
authors: ["Jeffrey Phillips Freeman"]
superseded_by:
related_adrs:
- number: 6
title: "Plan Lifecycle"
relationship: "Profiles control which lifecycle phase transitions require human approval"
- number: 7
title: "Decision Tree and Correction"
relationship: "Confidence thresholds determine which decisions require human intervention"
acceptance:
votes_for:
- voter: "Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>"
comment: "Named profiles with confidence thresholds provide a clean spectrum from full manual to full autonomous control"
votes_against: []
abstentions: []
---
The build system reads this front-matter to automatically generate:
- The page H1 title (e.g., "ADR-017: Automation Profiles")
- A subtitle header showing tier, drafted date, current status with date, and authors
- A status timeline in the sidebar (desktop) or at the end of the article (mobile)
- The Related ADRs table with links, titles, and relationship descriptions
- The Acceptance section with voting tallies
- The inventory tables on this page
Status Lifecycle
Each ADR progresses through a lifecycle tracked by the status_history front-matter field. The following diagram shows the valid state transitions:
The following statuses are recognized:
| Status | Meaning | What may change |
|---|---|---|
| Draft | The ADR is being written. It captures initial thinking but has not yet been formally proposed for review. Draft ADRs may be incomplete or contain open questions. | Everything. All content sections, front-matter fields, and structural decisions are open for revision. The only field that must not change is adr_number. |
| Proposed | The ADR is content-complete and has been submitted for review and voting. Reviewers evaluate the decision, its rationale, and its design. Discussion may surface clarifications, but the substantive content should be stable. | Content is mostly frozen. Only metadata changes are expected: votes are recorded in acceptance, minor wording clarifications may be applied, and status_history is updated. A Proposed ADR must resolve to either Accepted or Rejected — it cannot move back to Draft or skip to any other status. |
| Accepted | The ADR has been reviewed, voted on, and approved. It represents a binding architectural commitment that the project will follow. Implementation should conform to what the ADR specifies. | The ADR is immutable in substance. Only related_adrs may be updated as new ADRs are added that reference this one. If the decision needs material change, a new ADR should supersede it rather than editing the accepted text. |
| Rejected | The ADR was proposed but not accepted after review. The reasoning is preserved for historical reference so the same ground is not relitigated without new information. | The ADR is immutable. It remains in the record as evidence that the option was considered and declined. |
| Superseded | A previously accepted ADR that has been replaced by a newer decision. The superseded_by field links to the replacing ADR. The original remains in the record for historical context. |
Only the superseded_by field and status_history are updated when this transition occurs. |
| Deprecated | A previously accepted ADR that is no longer relevant — the feature, component, or concern it addressed has been removed or is no longer applicable. Unlike Superseded, there is no replacement decision. | Only status_history is updated when this transition occurs. |
Transition rules
- Draft → Proposed is the only way out of Draft. The author(s) must ensure all content sections are complete before proposing.
- Proposed → Accepted or Proposed → Rejected are the only valid transitions from Proposed. Voting determines the outcome.
- Accepted → Superseded occurs when a new ADR explicitly replaces this one.
- Accepted → Deprecated occurs when the decision is no longer applicable and no replacement is needed.
- There is no path back from Accepted, Rejected, Superseded, or Deprecated to an earlier status. If a rejected idea is revisited, a new ADR should be created.
The status_history field records every transition as a [date, status] or [date, status, person] tuple, forming a complete audit trail. The most recent entry determines the ADR's current status.
Tier System
ADRs are organized into four tiers that reflect their architectural scope and the breadth of their impact on the system:
| Tier | Name | Scope |
|---|---|---|
| 1 | Foundational | Structural and technological foundation upon which all other decisions rest. Changes here cascade across the entire system. |
| 2 | Core Domain | Domain model — the entities, lifecycles, and relationships that constitute the system's core logic. |
| 3 | Infrastructure and Behavior | Cross-cutting behavioral systems and infrastructure concerns that support the domain model. |
| 4 | Integration and Operations | External integrations, operational interfaces, and deployment concerns at the system boundary. |
Lower-numbered tiers are more foundational: a Tier 1 change is likely to affect decisions at every other tier, while a Tier 4 change is typically self-contained.
Content Sections
After the front-matter, each ADR contains the following standard sections. Authors may add sub-sections within any section to further organize complex material (e.g., ### Sequence Diagrams under Design, or ### Option A: Event Sourcing under Alternatives Considered). The standard sections themselves should not be removed or reordered.
Context
Describes the problem, situation, or forces that motivated the decision. This section explains why the ADR exists — what technical challenge, scaling concern, or design tension required an explicit architectural choice. It should give a reader who is unfamiliar with the project enough background to understand the decision without reading the full specification.
Decision Drivers
A short bulleted list of the key forces, requirements, and priorities that shaped the decision. Decision drivers are the specific, concrete factors that the decision must satisfy or balance — things like "must support offline operation," "latency under 100ms," or "must not break the existing REST API contract." Where Context tells the story, Decision Drivers distil it into a scannable checklist that reviewers can evaluate the decision against. This section corresponds to MADR's "Decision Drivers" and ensures the prioritized forces are explicit rather than buried in narrative.
Decision
States the architectural choice that was made, written in declarative form (e.g., "CleverAgents adopts X"). This is the core commitment of the ADR — a concise, authoritative statement of what was decided. Implementation details belong in Design; this section focuses on the what, not the how.
Design
Provides the structural details that realize the decision: components, interfaces, data models, patterns, protocols, and interaction flows. This is typically the longest section of an ADR and may include sub-headings, diagrams, and code-level specifics. The Design section should give an implementer enough information to build the feature correctly without inventing architectural choices on their own.
Constraints
Lists the explicit rules and restrictions the decision imposes on the codebase. Constraints are enforceable invariants — statements like "module X must never import from module Y" or "all domain models must use Pydantic strict mode." They serve as guardrails that CI checks, linters, and code review can verify mechanically.
Consequences
Documents the outcomes of the decision, organized into three categories: Positive (benefits gained), Negative (trade-offs accepted), and Risks (potential future problems). Honest accounting of trade-offs is essential — an ADR that lists only positive consequences is incomplete. This section helps future readers understand whether the decision's assumptions still hold.
Alternatives Considered
Describes other options that were evaluated and explains why they were not chosen. Each alternative should include enough detail for a reader to understand the rejected approach and the reasoning behind the rejection. Where practical, include a brief summary of the pros and cons for each option so that readers can understand the trade-off analysis that led to the final choice. When the decision is directly prescribed by the specification with no practical alternatives, this section may read "None — specification-driven requirement."
Compliance
Specifies how adherence to the decision is verified in practice. This includes CI checks, linting rules, architecture tests, code review expectations, and any other enforcement mechanisms. A decision without a compliance strategy is aspirational rather than architectural — this section ensures every ADR is backed by concrete verification.
Related ADRs
A table of cross-references to other ADRs that interact with this decision. Each entry includes a link to the related ADR, its title, and a brief description of the relationship. Cross-references are maintained in both directions — when a new ADR references an existing one, the existing ADR's related_adrs front-matter is updated as well. This section is generated automatically from the related_adrs front-matter field — do not write it by hand in the markdown body. It is always the second-to-last section.
Acceptance
Records the governance process for the ADR. Contains three sub-tables — Votes For, Votes Against, and Abstentions — each listing the voter's identity, an optional comment, and a total count. This section is generated automatically from the acceptance front-matter field — do not write it by hand in the markdown body. It is always the last section of every ADR.
ADR Inventory
ADR Timeline
A unified chronological view of every status transition across all architecture decisions.
Creating a New ADR
- Assign the next sequential number (e.g.,
ADR-044). - Create a file named
ADR-0NN-<kebab-case-title>.mdin this directory. - Copy the front-matter and section structure from any existing ADR.
- Set the front-matter fields:
adr_number: the assigned number (integer)title: a concise descriptive titlestatus_history: initialize with a single["YYYY-MM-DD", "Draft", "Your Name"]entrytier: the appropriate tier (1–4)authors: list of author namessuperseded_by: leave empty (or omit)related_adrs: list of related ADR entries (each withnumber,title,relationship)acceptance: initialize with emptyvotes_for: [],votes_against: [],abstentions: []
- Do not add an
# H1heading in the markdown body — the build system generates it fromadr_numberandtitle. - Do not write
## Related ADRsor## Acceptancesections in the markdown body — both are generated from front-matter. - Fill in all content sections (Context, Decision Drivers, Decision, Design, Constraints, Consequences, Alternatives Considered, Compliance). Every section is required — use "N/A" only if genuinely not applicable.
- Add the new ADR to the
navsection inmkdocs.yml. The inventory table on this page is generated automatically. - Cross-reference related ADRs in both directions (update existing ADRs'
related_adrsfront-matter). - Once voting concludes and the ADR is accepted, add a new
["YYYY-MM-DD", "Accepted", "Approver Name"]entry tostatus_historyand record votes in theacceptancefront-matter field.
