一键导入
engineering-rfc-decision-documentation
Architecture Decision Records (ADRs), decision rationale, status tracking, and post-implementation review
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Architecture Decision Records (ADRs), decision rationale, status tracking, and post-implementation review
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Index of Build Systems Skills
Coordination patterns for distributed dataflow systems including barriers, epochs, and distributed snapshots
Windowing, sessionization, time-series aggregation, and late data handling for streaming systems
Comprehensive guide to GNU Debugger (GDB) for debugging C/C++/Rust programs. Covers breakpoints, stack traces, variable inspection, TUI mode, .gdbinit customization, Python scripting, remote debugging, and core file analysis.
Paxos consensus algorithm including Basic Paxos, Multi-Paxos, roles, phases, and practical implementations
Gossip protocols for disseminating information, failure detection, and eventual consistency in large-scale distributed systems
| name | engineering-rfc-decision-documentation |
| description | Architecture Decision Records (ADRs), decision rationale, status tracking, and post-implementation review |
Scope: Documenting architectural decisions, tracking status, maintaining decision history, and post-implementation review Lines: ~320 Last Updated: 2025-10-25 Format Version: 1.0 (Atomic)
Activate this skill when:
Purpose: Lightweight documentation of significant architectural decisions
Format: Markdown file in docs/adr/ or adr/ directory
Naming: ADR-NNN-title-in-kebab-case.md (e.g., ADR-005-use-postgres-over-mongodb.md)
When to Write an ADR:
When NOT to Write an ADR:
Status Flow:
Proposed → Accepted → Implemented → [Deprecated | Superseded]
↓
Rejected
Proposed: Decision is being considered, not yet approved Accepted: Decision approved, ready for implementation Implemented: Decision has been built and deployed Deprecated: Decision no longer valid (context changed) Superseded: Replaced by newer decision (link to new ADR) Rejected: Decision not accepted (document why)
Context: What circumstances led to this decision? Options Considered: What alternatives were evaluated? Decision: What did we choose? Rationale: Why did we choose this? (trade-offs, constraints) Consequences: What are the positive, negative, neutral outcomes? Related Decisions: What other decisions does this affect?
When to use:
# ADR-012: Use JWT for API Authentication
**Date**: 2025-10-25
**Status**: Accepted
**Deciders**: @alice (backend lead), @bob (security)
## Context
We need to authenticate API requests from web and mobile clients.
Current system uses session cookies (server-side state, doesn't scale).
Requirements:
- Stateless authentication (no server-side sessions)
- Works for web and mobile
- Support for token expiration and refresh
## Decision
We will use **JWT (JSON Web Tokens)** for API authentication.
## Rationale
- **Stateless**: No server-side session storage (scales horizontally)
- **Cross-platform**: Works for web, mobile, and third-party API clients
- **Standard**: Well-documented, many libraries available
- **Expiration**: Built-in expiry (`exp` claim), supports refresh tokens
## Consequences
### Positive
- Horizontal scaling: No session replication needed
- Faster authentication: No database lookup per request
- Mobile-friendly: Tokens stored in app, not cookies
### Negative
- Token size: ~200 bytes vs 32-byte session ID (acceptable overhead)
- Revocation: Cannot invalidate token before expiry (mitigated with short TTL + refresh tokens)
- Secret management: Must protect JWT signing secret (use env vars, rotate regularly)
### Neutral
- Need to implement token refresh logic (standard pattern)
- Must validate tokens on every request (minimal CPU overhead)
## Alternatives Considered
### Session-based Auth (Current System)
**Pros**: Simple, easy to revoke
**Cons**: Server-side state, doesn't scale horizontally, not mobile-friendly
**Rejected**: Scalability requirement
### OAuth 2.0
**Pros**: Industry standard, supports third-party login
**Cons**: Complex for our use case (overkill for internal API)
**Deferred**: Consider for future third-party integrations
### API Keys
**Pros**: Simple, long-lived
**Cons**: No expiration, hard to rotate, security risk
**Rejected**: No built-in expiration mechanism
Use case: Complex decision requiring clear accountability
# ADR-018: Migrate from Monolith to Microservices
**Date**: 2025-10-25
**Status**: Accepted
**Last Updated**: 2025-10-26
## DACI
**Driver**: @alex (backend architect)
- Responsible for RFC and implementation plan
**Approver**: @cto
- Final decision authority
- Accountable for outcome
**Contributors**:
- @jordan (backend lead): Technical feasibility
- @taylor (DevOps): Infrastructure and deployment
- @sam (product): Product impact and timeline
**Informed**:
- engineering@company.com
- leadership@company.com
## Context
Current monolithic Rails app is becoming difficult to scale and maintain:
- Deployment takes 30+ minutes (affects release velocity)
- Tight coupling makes bug fixes risky (change one feature, break another)
- Team growth is bottlenecked (merge conflicts, slow tests)
- Database queries are slow (N+1 problems, no caching)
Goals:
- Improve deployment speed (target: <5 min per service)
- Enable independent team scaling (3 teams, 15 engineers)
- Reduce blast radius of bugs (isolate failures)
## Decision
We will **gradually migrate** from monolith to microservices using the Strangler Fig pattern.
**Phase 1**: Extract Auth Service (Q1 2025)
**Phase 2**: Extract User Service (Q2 2025)
**Phase 3**: Extract Project Service (Q3 2025)
## Rationale
- **Gradual migration**: Reduces risk vs big-bang rewrite
- **Strangler Fig**: Proven pattern (Netflix, Airbnb successfully used)
- **Start small**: Auth Service is well-isolated, low risk
- **Team autonomy**: Each service can be owned by a team (clear boundaries)
## Consequences
### Positive
- Faster deployments: 5 min per service vs 30 min monolith
- Independent scaling: Scale auth separately from other services
- Team autonomy: Teams can deploy independently (no coordination)
- Technology flexibility: Can use different languages/frameworks per service
### Negative
- Complexity: Distributed systems (service discovery, tracing)
- Cost: More infrastructure (3 services vs 1 monolith)
- Estimated: $500/mo → $1,200/mo (2.4x increase)
- Debugging: Cross-service issues harder to debug (need distributed tracing)
- Data consistency: Eventual consistency (no ACID across services)
### Neutral
- Learning curve: Team needs to learn Kubernetes, service mesh
- Operational overhead: More services to monitor and maintain
- Network latency: Service-to-service calls add ~10ms overhead
## Risks & Mitigations
| Risk | Impact | Mitigation |
|------|--------|------------|
| Migration takes too long | High | Timebox to 9 months, cancel if not on track |
| Data consistency issues | High | Use event sourcing for critical workflows |
| Cost overruns | Medium | Monitor monthly, optimize resource usage |
| Team expertise gap | Medium | Hire DevOps engineer, training budget |
## Alternatives Considered
### Continue with Monolith
**Pros**: No migration cost, simpler operations
**Cons**: Doesn't solve scaling, deployment, team autonomy problems
**Rejected**: Problems will worsen as team grows
### Modular Monolith
**Pros**: Logical separation, single deployment
**Cons**: Still have deployment bottleneck, doesn't solve scaling
**Considered**: Good middle ground, but doesn't meet goals
### Full Microservices Rewrite
**Pros**: Clean slate, modern architecture
**Cons**: High risk, 12+ months, business disruption
**Rejected**: Too risky, Strangler Fig is safer
## Implementation Plan
[Link to RFC-042: Microservices Migration Plan]
## Post-Implementation Review
**Scheduled**: 2026-01-15 (3 months after Phase 3 completion)
**Participants**: @alex, @jordan, @taylor, @sam, @cto
**Review Questions**:
- Did we achieve deployment speed goal? (<5 min per service)
- Did team autonomy improve? (measure: deploy frequency per team)
- What unexpected issues arose?
- Would we make the same decision again?
Use case: Maintaining history of decision lifecycle
# ADR-005: Use PostgreSQL Over MongoDB
**Status**: Implemented
**Created**: 2025-01-15
**Accepted**: 2025-01-20
**Implemented**: 2025-02-10
**Last Reviewed**: 2025-10-25
## Status History
| Date | Status | Notes |
|------|--------|-------|
| 2025-01-15 | Proposed | Initial draft by @alice |
| 2025-01-17 | In Review | Feedback from @bob, @charlie |
| 2025-01-20 | Accepted | Approved by @cto after design review |
| 2025-02-10 | Implemented | Deployed to production |
| 2025-10-25 | Reviewed | Still valid, no changes needed |
## Review Notes (2025-10-25)
- **Still valid?**: Yes, Postgres continues to meet needs
- **Performance**: Query latency <50ms (p95), meets SLA
- **Scalability**: 1.5M users, no scaling issues yet
- **Would we choose differently?**: No, Postgres was correct choice
- **Next review**: 2026-04-25 (6 months)
Use case: When a decision is replaced by a newer one
# ADR-003: Use Redis for Session Storage
**Status**: Superseded by ADR-012 (JWT Authentication)
**Created**: 2024-06-01
**Accepted**: 2024-06-10
**Implemented**: 2024-07-01
**Superseded**: 2025-10-25
## Superseded Notice
⚠️ **This decision is no longer active.**
**Superseded by**: [ADR-012: Use JWT for API Authentication](./ADR-012-use-jwt-for-api-authentication.md)
**Reason**: Migrated from session-based auth to stateless JWT auth for better scalability.
**Migration**: Completed 2025-10-25. Redis session store decommissioned.
---
## Original Decision (For Historical Reference)
### Context
We needed server-side session storage for user authentication...
[Keep original ADR content for historical reference]
Use case: When context changes and decision is no longer valid
# ADR-008: Deploy on Heroku
**Status**: Deprecated (No Longer Valid)
**Created**: 2023-03-15
**Accepted**: 2023-03-20
**Implemented**: 2023-04-01
**Deprecated**: 2025-06-15
## Deprecation Notice
⚠️ **This decision is no longer valid.**
**Deprecated Date**: 2025-06-15
**Reason**: Company standardized on AWS for all infrastructure.
**Current State**: All services migrated to AWS ECS (completed 2025-06-15).
**Replacement Decision**: [ADR-025: Standardize on AWS](./ADR-025-standardize-on-aws.md)
---
## Original Decision (For Historical Context)
### Context
We chose Heroku for fast iteration and minimal DevOps overhead...
[Keep original content for reference]
Use case: Documenting decisions that were NOT accepted
# ADR-014: Use GraphQL for Public API (REJECTED)
**Status**: Rejected
**Created**: 2025-05-10
**Rejected**: 2025-05-20
**Deciders**: @alice (backend lead), @bob (CTO)
## Context
We evaluated GraphQL as an alternative to our REST API for the public API.
## Proposal (Rejected)
Replace REST API with GraphQL to reduce over-fetching and under-fetching.
## Rationale for Rejection
### Reasons NOT Accepted
1. **Team expertise**: No GraphQL experience on team (6+ month learning curve)
2. **Third-party integrations**: Most partners expect REST APIs (not GraphQL)
3. **Tooling**: Our monitoring/caching infrastructure is REST-optimized
4. **Client complexity**: Mobile apps would need GraphQL client library (adds weight)
### What We Learned
- Over-fetching is not a significant problem (bandwidth is cheap)
- Under-fetching can be solved with REST API design (compound endpoints)
- GraphQL benefits don't justify migration cost for our use case
## Alternative Chosen
Continue with REST API, improve with:
- Compound endpoints to reduce round-trips (e.g., `/users/:id?include=projects`)
- Field filtering via query params (e.g., `?fields=name,email`)
- Better API documentation (OpenAPI/Swagger)
## Related Decisions
- [ADR-006: REST API Design Principles](./ADR-006-rest-api-design-principles.md)
## Future Consideration
If we build a complex web app with diverse data needs, revisit GraphQL.
**Trigger**: If >10 clients request custom data views.
Use case: Tracking changes to RFC during review process
# RFC-042: Real-Time Collaboration
[... RFC content ...]
---
## Changelog
### Version 1.3 (2025-10-26) - Final
- **Added**: Security section (rate limiting, auth)
- **Changed**: WebSocket server from Node.js to Go (better concurrency)
- **Reason**: Security review feedback from @charlie
- **Status**: Approved by @cto
### Version 1.2 (2025-10-25)
- **Added**: Failure mode analysis (Redis downtime)
- **Changed**: Rate limit from 100 to 200 ops/sec
- **Removed**: Audio/video chat (out of scope)
- **Reason**: Design review feedback from @jordan, @taylor
### Version 1.1 (2025-10-24)
- **Added**: Cost analysis ($500/mo at 10k users)
- **Changed**: Alternative approach section (expanded CRDTs analysis)
- **Reason**: @bob requested cost breakdown
### Version 1.0 (2025-10-23) - Initial Draft
- **Created**: Initial draft by @alex
- **Sections**: Problem, solution, architecture, alternatives
---
## Version History Table
| Version | Date | Author | Status | Key Changes |
|---------|------|--------|--------|-------------|
| 1.3 | 2025-10-26 | @alex | Approved | Security section added |
| 1.2 | 2025-10-25 | @alex | In Review | Failure modes, rate limit |
| 1.1 | 2025-10-24 | @alex | In Review | Cost analysis |
| 1.0 | 2025-10-23 | @alex | Draft | Initial draft |
Use case: Retrospective after decision is implemented
# Post-Implementation Review: ADR-012 JWT Authentication
**Review Date**: 2025-10-25 (6 months post-implementation)
**Participants**: @alice (backend lead), @bob (security), @charlie (DevOps), @dana (product)
## Original Decision (Summary)
- **Date**: 2025-04-25
- **Decision**: Migrate from session-based auth to JWT
- **Rationale**: Stateless, scalable, mobile-friendly
## Implementation Timeline
- **Start**: 2025-05-01
- **Alpha**: 2025-05-15 (internal testing)
- **Beta**: 2025-06-01 (10% rollout)
- **GA**: 2025-06-15 (100% rollout)
## Success Metrics (Actual vs Target)
| Metric | Target | Actual | Status |
|--------|--------|--------|--------|
| API latency reduction | -20ms (p95) | -35ms | ✅ Exceeded |
| Horizontal scaling | 3x capacity | 5x capacity | ✅ Exceeded |
| Failed logins (migration) | <1% | 0.3% | ✅ Met |
| Support tickets (auth issues) | <50 | 12 | ✅ Exceeded |
## What Went Well
1. **Smooth migration**: Dual-write period prevented data loss
2. **Performance**: Better than expected (-35ms vs -20ms target)
3. **Scalability**: 5x capacity increase (vs 3x target)
4. **Minimal user impact**: Only 12 support tickets (vs 50 expected)
## What Went Poorly
1. **Token refresh complexity**: Took 2 weeks longer than estimated
- Root cause: Edge cases in refresh token rotation
- Mitigation: Added integration tests for refresh flows
2. **Secret rotation**: Manual process (should be automated)
- Action item: Automate JWT secret rotation (ADR-030)
3. **Mobile token storage**: Security concern (tokens in local storage)
- Action item: Migrate to secure keychain (iOS) and keystore (Android)
## Unexpected Challenges
- **Third-party integrations**: 3 partners needed JWT support (undiscovered dependency)
- Resolution: Provided migration guide and support
- **Token size**: 200-byte tokens caused issues with legacy proxies
- Resolution: Whitelisted JWT header in proxy config
## Lessons Learned
1. **Dual-write is critical**: Prevented data loss during migration
2. **Test refresh flows**: Edge cases are tricky, need comprehensive tests
3. **Automate ops**: Secret rotation should be automated from day 1
4. **Mobile security**: Token storage needs platform-specific solutions
## Would We Make Same Decision?
**Yes**, JWT was the correct choice.
**Rationale**:
- Performance and scalability benefits exceeded expectations
- Migration was smooth despite token refresh complexity
- Would address mobile token storage earlier next time
## Follow-Up Actions
- [ ] **ADR-030**: Automate JWT secret rotation (assigned: @charlie)
- [ ] **ADR-031**: Migrate mobile to secure token storage (assigned: @alice)
- [ ] **Documentation**: Update API docs with JWT best practices
## Next Review
**Scheduled**: 2026-04-25 (6 months)
**Trigger**: If token-related security incidents occur, review immediately
Required Sections | Optional Sections
------------------|------------------
Date | DACI roles
Status | Status history
Context | Related decisions
Decision | Risks & mitigations
Rationale | Implementation plan
Consequences | Post-implementation review
Alternatives |
Status | Meaning | Next Action
-------|---------|------------
Proposed | Being considered | Seek feedback, approve/reject
Accepted | Approved | Implement
Implemented | Deployed | Monitor, review
Deprecated | No longer valid | Link to replacement
Superseded | Replaced | Link to new decision
Rejected | Not accepted | Document why
Write ADR | Don't Write ADR
----------|----------------
Technology choice (DB, cloud) | Routine code changes
Architectural pattern | Variable naming
Security approach | UI colors/layout
Data strategy | Bug fixes
Hard-to-reverse decisions | Easily reversible decisions
Question | Purpose
---------|--------
Did we achieve goals? | Measure success
What went well? | Identify strengths
What went poorly? | Learn from mistakes
Would we decide the same way? | Validate decision
What's next? | Plan follow-up actions
✅ DO: Document why, not just what (rationale is critical)
✅ DO: Include alternatives considered (why not X?)
✅ DO: Track status changes over time
✅ DO: Conduct post-implementation reviews (learn from outcomes)
✅ DO: Link related decisions (create decision graph)
❌ DON'T: Skip consequences (positive, negative, neutral)
❌ DON'T: Forget to update status (proposed → accepted → implemented)
❌ DON'T: Delete superseded ADRs (keep for historical context)
❌ DON'T: Write ADRs for trivial decisions
❌ DON'T: Ignore post-implementation learnings
❌ Decision Without Rationale: "We chose X" without explaining why
# ❌ NEVER:
## Decision
We will use PostgreSQL.
# ✅ CORRECT:
## Decision
We will use PostgreSQL.
## Rationale
- ACID transactions required for billing (compliance)
- Rich query capabilities (JOINs, window functions)
- Team expertise (all backend engineers know SQL)
- Proven scalability (read replicas, partitioning)
## Alternatives Considered
- MongoDB: Flexible schema, but no ACID (rejected)
- DynamoDB: Managed, but vendor lock-in (rejected)
❌ No Consequences Section: Ignoring negative outcomes ✅ Correct approach: Document positive, negative, and neutral consequences
❌ Deleting Superseded Decisions: Removing historical context
# ❌ Don't:
[Delete ADR-003 after it's superseded]
# ✅ Correct:
Keep ADR-003 with "Superseded" status and link to ADR-012
❌ No Status Updates: Decision stays "Proposed" even after implementation ✅ Better: Update status to Accepted → Implemented with dates
❌ Skipping Post-Implementation Review: No retrospective on decision
# ❌ Don't:
Implement decision → Move on to next task
# ✅ Correct:
Implement decision → Wait 3-6 months → Conduct review → Document learnings
❌ ADR for Trivial Decisions: "ADR-099: Use camelCase for variable names" ✅ Better: ADRs for significant, hard-to-reverse decisions only
rfc-structure-format.md - RFC document templates and formattingrfc-technical-design.md - Architecture proposals and technical designrfc-consensus-building.md - Driving approval and building consensusproduct/prd-structure-templates.md - Product decision documentation (PRDs)Last Updated: 2025-10-25 Format Version: 1.0 (Atomic)