Skip to content

Extracting Architecture ADRs for Full Traceability

How we resolved an ADR naming conflict and established bidirectional traceability between requirements, decisions, and implementation.

Context

Our docs/architecture/index.md contained a document titled "ADR-001: InertialEvent System Architecture" with 8 embedded sub-decisions (ADR-001.1 through ADR-001.8). This created several problems:

  1. Naming conflict: docs/adrs/001-connectivity-check.md already existed as the "real" ADR-001
  2. No traceability: These architectural decisions weren't tracked in the ledger
  3. No spec mapping: Requirements didn't reference these ADRs
  4. Discoverability: Decisions buried in a large document are hard to find

Decision

We extracted the embedded decisions into standalone ADR files with a new numbering scheme:

Old Number New Number Title
ADR-001.1 ADR-004 Core Engine in Rust
ADR-001.2 ADR-005 Actor Model with Message Passing
ADR-001.3 ADR-006 Lock-Free Orderbook Cache
ADR-001.4 ADR-007 Execution State Machine (Saga Pattern)
ADR-001.5 ADR-008 Control Interface Architecture
ADR-001.6 ADR-009 Multi-Platform Credential Management
ADR-001.7 ADR-010 Deployment Architecture
ADR-001.8 ADR-011 Multi-Tenancy Model

Each standalone ADR includes:

  • Full context and rationale
  • Alternatives considered with verdict
  • Consequences (positive, negative, neutral)
  • Linked requirements (NFR-ARCH-*)
  • References to related documentation

Implementation

ADR Format

Each extracted ADR follows this structure:

# ADR NNN: Title

## Status
Accepted

## Context
Why this decision was needed...

## Decision
What was decided and how...

## Alternatives Considered
| Approach | Pros | Cons | Verdict |
|----------|------|------|---------|
...

## Consequences
### Positive
### Negative
### Neutral

## References
- Links to related docs
- Linked Requirements (NFR-ARCH-*)

New Requirements

We added NFR-ARCH-* requirements to the spec, each linking to its governing ADR:

- [ ] NFR-ARCH-001: Core engine in Rust - [ADR-004](../adrs/004-rust-core-engine.md)
- [ ] NFR-ARCH-002: Actor model - [ADR-005](../adrs/005-actor-model.md)
...

Traceability Matrix

The ledger now tracks both ADR status and requirement implementation:

Req ID Description Status ADR Implementation
NFR-ARCH-001 Core engine in Rust Partial ADR-004 arbiter-engine/
NFR-ARCH-004 Saga pattern Partial ADR-007 src/execution/state_machine.rs

Architecture Document Update

The architecture index was streamlined:

Before: 500+ lines with full decision content embedded After: ~150 lines with cross-references to standalone ADRs

Each section now links to its detailed ADR:

### Core Technology ([ADR-004](../adrs/004-rust-core-engine.md))
**Decision:** Implement the trading core in Rust...

Verification

  1. Build passes: mkdocs build --strict
  2. Navigation works: All 11 ADRs accessible from ADRs tab
  3. Cross-references valid: Links between architecture doc and ADRs work
  4. Ledger complete: All ADRs tracked with status
  5. Requirements linked: NFR-ARCH-* documented in spec

Lessons Learned

  1. Flat numbering is cleaner - ADR-004 is easier to reference than ADR-001.4
  2. Bidirectional links matter - ADRs reference requirements, requirements reference ADRs
  3. Ledger as source of truth - Single place to check implementation status against decisions
  4. Extract early - Embedded decisions are harder to find and maintain

The full ADR inventory is now available at ADRs Index.