Architecture Decision Records (ADR) Templates
Decision Records
FULL SUPPORT FOR ADRs IS UNDER DEVELOPMENT
Architecture Decision Records (ADRs) and technical decision documentation templates optimized for MSP. Never lose track of why your system is built the way it is.
What Are Decision Records?
Decision records capture:
- The decision made
- The context when it was made
- The alternatives considered
- The consequences expected
- The outcome (updated over time)
With MSP, decisions are:
- Automatically linked to sessions
- Tracked in your knowledge graph
- Searchable across projects
- Connected to implementation
Quick Start
Record a Decision During Development
# While coding, make a decision
msp decide "Using PostgreSQL for user data" `
--type "architecture" `
--because "Need ACID compliance for financial transactions" `
--alternatives "MongoDB,DynamoDB"
# Creates decision record and Neo4j node
Generate Decision Document
# Create formal ADR from session decision
msp decision formalize "Using PostgreSQL for user data"
# Generates: docs/decisions/ADR-001-postgresql-for-user-data.md
ADR Template
Standard MSP ADR Format
# ADR-{number}: {title}
**Status**: {Draft|Proposed|Accepted|Deprecated|Superseded}
**Date**: {YYYY-MM-DD}
**Deciders**: {list of people}
**Session**: {msp-session-id}
## Context
{What is the issue that we're seeing that is motivating this decision?}
### Technical Context
{Relevant technical details, constraints, requirements}
### Business Context
{Business requirements, timeline, budget considerations}
## Decision
{The decision that was made}
## Considered Alternatives
### Option 1: {alternative}
**Pros**:
- {benefit}
- {benefit}
**Cons**:
- {drawback}
- {drawback}
**Estimated Effort**: {time/complexity}
### Option 2: {alternative}
{same structure}
### Option 3: {alternative}
{same structure}
## Consequences
### Positive
- {expected benefit}
- {expected benefit}
### Negative
- {expected drawback}
- {expected drawback}
### Risks
- {risk and mitigation}
- {risk and mitigation}
## Implementation
### Phase 1: {what}
- {specific task}
- {specific task}
**Timeline**: {estimate}
### Phase 2: {what}
- {specific task}
**Timeline**: {estimate}
## Validation
How will we know this decision was correct?
- {metric or observation}
- {metric or observation}
## MSP Tracking
```cypher
// Neo4j query to track this decision
MATCH (d:Decision {id: '{decision-id}'})
MATCH (d)-[:IMPLEMENTED_BY]->(s:Session)
MATCH (d)-[:RESULTED_IN]->(o:Outcome)
RETURN d, s, o
MSP Session: {session-link}
Linear Issue: {issue-link}
Related Decisions: {decision-links}
Decision Types
Architecture Decisions
# template: architecture-decision
type: architecture
categories:
- database
- api-design
- infrastructure
- security
- performance
required_sections:
- current_architecture
- proposed_change
- migration_plan
- rollback_strategy
evaluation_criteria:
- scalability
- maintainability
- cost
- performance
- security
example_decisions:
- "Microservices vs Monolith"
- "SQL vs NoSQL"
- "REST vs GraphQL"
- "Containerization strategy"
Technology Decisions
# template: technology-decision
type: technology
categories:
- language
- framework
- library
- tool
- platform
required_sections:
- evaluation_criteria
- proof_of_concept
- team_expertise
- support_ecosystem
- licensing
comparison_matrix:
headers: [Feature, Option1, Option2, Option3]
scoring: [1-5 scale]
weights: [importance factors]
example_decisions:
- "React vs Vue vs Angular"
- "AWS vs GCP vs Azure"
- "Jest vs Mocha vs Vitest"
- "Docker vs Podman"
Process Decisions
# template: process-decision
type: process
categories:
- development
- deployment
- testing
- collaboration
required_sections:
- current_process
- pain_points
- proposed_process
- transition_plan
- success_metrics
stakeholders:
- who_affected
- who_decides
- who_implements
example_decisions:
- "Git flow vs GitHub flow"
- "CI/CD pipeline design"
- "Code review process"
- "Sprint length"
Decision Record Workflows
1. Lightweight Decision Tracking
During development:
# Quick decision
msp decide "Use Redis for session cache"
# With more context
msp decide "Implement rate limiting at API gateway" `
--category "security" `
--impact "high" `
--alternatives "Application-level,WAF,Service mesh" `
--rationale "Centralized control and monitoring"
2. Formal ADR Process
For significant decisions:
# Start ADR process
msp adr create "Migrate to Kubernetes"
# This launches interactive process:
# 1. Context gathering
# 2. Alternative research
# 3. Stakeholder input
# 4. Impact analysis
# 5. Document generation
# Collaborate on ADR
msp adr collaborate "ADR-042" --invite "@team-leads"
# Finalize ADR
msp adr finalize "ADR-042" --status "accepted"
3. Decision Review Cycle
# Schedule decision review
msp decision schedule-review "ADR-042" --after "3 months"
# Review outcomes
msp decision review "ADR-042" --add-outcome "Reduced deployment time by 70%"
# Update status if needed
msp decision update "ADR-042" --status "superseded" --by "ADR-058"
Integration with Development
Inline Decision Documentation
/**
* @msp:decision Authentication Strategy
* @decided: 2025-07-15
* @status: Implemented
*
* We chose JWT with refresh tokens over session-based auth because:
* 1. Stateless - better for horizontal scaling
* 2. Mobile-friendly - works across platforms
* 3. Standard - wide library support
*
* Trade-offs:
* - Cannot revoke individual tokens (mitigated by short expiry)
* - Larger request size (acceptable for our use case)
*
* @see ADR-015-authentication-strategy.md
*/
export class AuthService {
// Implementation follows decision
}
Git Integration
# Commit hooks add decision references
git commit -m "Implement JWT authentication
Implements: ADR-015
Session: msp-2025-07-15-093042
Decisions: Authentication strategy, Token expiry policy"
Code Review Integration
# .github/pull_request_template.md
## Decisions Made
<!-- List any architectural or technical decisions -->
- [ ] Decisions documented in code
- [ ] ADR created for significant decisions
- [ ] Alternatives were considered
- [ ] Team notified of decisions
## MSP Session
Session ID: <!-- msp session -->
Decision Records: <!-- ADR numbers -->
Decision Analytics
Query Decision History
# Find all decisions for a project
msp decisions list --project "e-commerce"
# Search decisions by topic
msp decisions search "caching"
# Show decision timeline
msp decisions timeline --visual
# Find decisions by outcome
msp decisions find --outcome "positive" --category "performance"
Decision Impact Analysis
// Neo4j query: Decisions that led to issues
MATCH (d:Decision)<-[:MADE_DECISION]-(s1:Session)
MATCH (b:Blocker)<-[:ENCOUNTERED_BLOCKER]-(s2:Session)
WHERE s2.timestamp > s1.timestamp
AND b.description CONTAINS d.keywords
RETURN d.title, count(b) as issues_caused
ORDER BY issues_caused DESC
// Successful decisions (no subsequent issues)
MATCH (d:Decision)<-[:MADE_DECISION]-(s:Session)
WHERE NOT EXISTS {
MATCH (b:Blocker)
WHERE b.timestamp > d.timestamp
AND b.relatedTo CONTAINS d.id
}
RETURN d.title, d.category, s.project
ORDER BY d.timestamp DESC
Team Decision Patterns
# Analyze team decision making
msp analyze decisions --team "backend" --period "last-quarter"
# Output:
# Decision Velocity: 3.2 decisions/week
# Categories: Architecture (45%), Technology (30%), Process (25%)
# Reversal Rate: 8%
# Average Time to Decision: 2.3 days
# Most Active Deciders: @john (12), @jane (10)
Decision Templates
Quick Decision Template
# Decision: {title}
**Date**: {date}
**Decider**: {user}
**Session**: {_session}
## TL;DR
{one-line-decision}
## Because
{rationale}
## Instead of
{alternatives}
## Watch out for
{risks}
Detailed Technical Decision
# Technical Decision: {title}
## Summary
**We will**: {decision}
**Because**: {primary-reason}
**Accepting**: {main-tradeoff}
## Context
### Problem
{what-problem-solving}
### Constraints
- {constraint-1}
- {constraint-2}
### Requirements
- Must: {requirement}
- Should: {requirement}
- Nice to have: {requirement}
## Options Analysis
| Criteria | Option A | Option B | Option C |
|----------|----------|----------|----------|
| Performance | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Cost | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
| Complexity | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| Team Experience | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |
**Winner**: {option} because {decisive-factor}
## Implementation Plan
1. {step-1} (Week 1)
2. {step-2} (Week 2)
3. {step-3} (Week 3-4)
## Success Metrics
- {metric-1}
- {metric-2}
## Review Date
{3-months-from-now}
Business Decision Template
# Business Decision: {title}
## Executive Summary
**Decision**: {what-deciding}
**Investment**: {cost/time}
**Expected Return**: {benefit}
**Risk Level**: {Low|Medium|High}
## Business Case
### Opportunity
{what-opportunity}
### Current State
{where-we-are}
### Desired State
{where-we-want-to-be}
## Financial Analysis
- Cost: {breakdown}
- ROI: {calculation}
- Payback Period: {timeline}
## Risks and Mitigation
| Risk | Probability | Impact | Mitigation |
|------|------------|---------|------------|
| {risk} | {L/M/H} | {L/M/H} | {strategy} |
## Stakeholder Analysis
- Sponsor: {who}
- Affected Teams: {who}
- External Impact: {who}
## Decision
**We will**: {decision}
**By**: {date}
**Success looks like**: {criteria}
## Next Steps
- [ ] {action-1} - {owner}
- [ ] {action-2} - {owner}
- [ ] {action-3} - {owner}
Decision Record Management
Organizing Decisions
project/
├── docs/
│ └── decisions/
│ ├── README.md
│ ├── ADR-001-use-postgresql.md
│ ├── ADR-002-rest-api-design.md
│ └── ADR-003-deployment-strategy.md
├── .msp/
│ └── decisions.json
Decision Index
# Decision Log
## Accepted
- [ADR-001](./ADR-001.md): Use PostgreSQL for persistent storage
- [ADR-002](./ADR-002.md): REST API with OpenAPI specification
- [ADR-004](./ADR-004.md): Kubernetes for container orchestration
## Superseded
- [ADR-003](./ADR-003.md): ~~Monolithic deployment~~ → See [ADR-004](./ADR-004.md)
## Proposed
- [ADR-005](./ADR-005.md): Adopt event-driven architecture
## By Category
### Database
- [ADR-001](./ADR-001.md): PostgreSQL selection
### API Design
- [ADR-002](./ADR-002.md): REST API design
### Infrastructure
- [ADR-004](./ADR-004.md): Kubernetes adoption
Automated Management
# Generate decision index
msp decisions index --output "docs/decisions/README.md"
# Check decision health
msp decisions health
# Output:
# ✅ 15 decisions documented
# ⚠️ 3 decisions need review (>6 months old)
# ❌ 2 decisions missing outcomes
# 📊 85% decisions have positive outcomes
# Archive old decisions
msp decisions archive --older-than "1 year" --status "superseded"
Best Practices
1. Decide at the Last Responsible Moment
- Don't decide too early (requirements change)
- Don't decide too late (block progress)
- Document when you're deciding and why now
2. Make Reversible Decisions Fast
- Identify one-way vs two-way doors
- Move quickly on reversible decisions
- Be careful with irreversible ones
3. Document the Context, Not Just the Decision
- Future you needs to understand why
- Context changes might invalidate decisions
- Learning comes from understanding context
4. Review and Update
- Schedule reviews for major decisions
- Update outcomes (positive and negative)
- Mark superseded decisions clearly
5. Link Everything
- Link to research and references
- Link to implementation sessions
- Link to outcomes and metrics
Examples
Real Decision Records
- Choosing Message Queue
msp decide "Use RabbitMQ for async processing" `
--type "architecture" `
--alternatives "SQS,Kafka,Redis Pub/Sub" `
--factors "Team expertise,Operational complexity,Cost" `
--outcome "RabbitMQ: Best balance of features and familiarity"
- API Versioning Strategy
msp adr create "API Versioning Strategy"
# Interactive session covers:
# - URL vs Header versioning
# - Breaking change policy
# - Deprecation timeline
# - Client migration plan
- Security Decision
msp decide "Implement OAuth2 with PKCE" `
--type "security" `
--risk "high" `
--compliance "OWASP,SOC2" `
--review-with "@security-team"
Complete Example from MSP Development:
ADR-003: Neo4j for Session Relationship Modeling
Status
Accepted
Context
Session management involves complex relationships between sessions, decisions, tasks, blockers, and progress over time. We need a data store that can efficiently model and query these relationships while providing insights into work patterns and team dynamics.
Decision
Use Neo4j as the primary data store for modeling session relationships and deriving insights.
Rationale
Why Graph Database?
- Natural relationship modeling: Sessions relate to decisions, tasks, people
- Pattern detection: Find recurring blockers, decision impacts
- Team insights: Visualize collaboration patterns
- Flexible schema: Evolve without migrations
- Graph algorithms: Built-in analytics capabilities
Why Neo4j Specifically?
- Market leader: Mature, well-supported
- Cypher query language: Intuitive and powerful
- ACID compliance: Data consistency
- Performance: Optimized for relationship traversal
- Ecosystem: Drivers for all major languages
Data Model
Core Nodes
// Time-based nodes
(s:Session {id, date, duration, progress})
(d:Day {date})
(w:Week {number, year})
// Work nodes
(dec:Decision {id, rationale, outcome})
(t:Task {id, title, status})
(b:Blocker {id, description, impact})
// People nodes
(dev:Developer {id, name, team})
(tm:Team {id, name})
Key Relationships
// Temporal
(s)-[:OCCURRED_ON]->(d)
(d)-[:PART_OF]->(w)
// Work relationships
(s)-[:INCLUDES]->(dec)
(s)-[:WORKED_ON]->(t)
(s)-[:ENCOUNTERED]->(b)
(dec)-[:RESOLVED]->(b)
// People relationships
(dev)-[:STARTED]->(s)
(dev)-[:MEMBER_OF]->(tm)
(tm)-[:OWNS]->(t)
Query Examples
Find Decision Impact
MATCH (d:Decision)<-[:INCLUDES]-(s1:Session),
(s2:Session)-[:INCLUDES]->(d2:Decision)
WHERE s2.date > s1.date
AND d2.rationale CONTAINS d.outcome
RETURN d, collect(d2) as influenced_decisions
Team Velocity Trends
MATCH (tm:Team)<-[:MEMBER_OF]-(dev:Developer)-[:STARTED]->(s:Session)
WHERE s.date > date() - duration('P30D')
WITH tm, toDays() as weekday, avg(s.progress) as avg_progress
RETURN tm.name, weekday, avg_progress
ORDER BY weekday
Integration Architecture
Write Path
CLI → Local State → Sync Queue → Neo4j Adapter → Neo4j
Read Path
Dashboard → API → Neo4j Driver → Neo4j → Cache → Response
Consequences
Positive
- Rich relationship queries
- Visual graph exploration
- Pattern detection capabilities
- No JOIN performance issues
- Schema flexibility
Negative
- Learning curve for Cypher
- Less common than SQL
- Backup complexity
- Hosting considerations
- Not ideal for tabular data
Alternatives Considered
PostgreSQL with JSONB
- Pros: Familiar, flexible schema
- Cons: Complex relationship queries
TimescaleDB
- Pros: Time-series optimization
- Cons: Poor relationship modeling
MongoDB
- Pros: Document flexibility
- Cons: No ACID, poor relationships
DynamoDB
- Pros: Serverless, scalable
- Cons: Limited query capability
Migration Strategy
- Start with Neo4j Community Edition
- Use Aura (cloud) for production
- PostgreSQL for auxiliary data
- Sync critical data to both stores
Performance Considerations
- Index on frequently queried properties
- Limit traversal depth
- Use parameter queries
- Cache common patterns
- Monitor query performance
Next Steps
- Review the templates and choose one that fits
- Document your next decision using MSP
- Set up decision reviews for existing choices
- Analyze your decision patterns for insights
Good decisions age well. Great decision records help you understand why.
PRD Template
Battle-tested Product Requirements Document template optimized for MSP workflows. Keep your PRDs living alongside code with integrated progress tracking and decision documentation.
Session Templates
Pre-built session templates for common development scenarios. Start faster, track consistently, and maintain context with templates for bug fixes, features, planning, reviews, and more.