|
| 1 | +# ADR-011: ADR Timeline Tracking and Context-Aware Analysis |
| 2 | + |
| 3 | +## Status |
| 4 | +Accepted |
| 5 | + |
| 6 | +## Date |
| 7 | +2025-11-19 |
| 8 | + |
| 9 | +## Context |
| 10 | + |
| 11 | +As our ADR analysis server matured, we identified several limitations in how we track and analyze architectural decisions: |
| 12 | + |
| 13 | +1. **No Temporal Awareness**: The system couldn't track when decisions were made or how long they've been in various states |
| 14 | +2. **Missing Staleness Detection**: No way to identify outdated or neglected ADRs that need attention |
| 15 | +3. **Context-Agnostic Thresholds**: Same staleness thresholds applied to all projects (startup vs. enterprise) |
| 16 | +4. **Manual Action Planning**: Users had to manually identify which ADRs need updates or implementation |
| 17 | +5. **Performance Concerns**: Extracting timeline data could be expensive without smart caching |
| 18 | + |
| 19 | +## Decision |
| 20 | + |
| 21 | +We implemented a comprehensive ADR Timeline Tracking system with the following components: |
| 22 | + |
| 23 | +### 1. Timeline Extraction (src/utils/adr-timeline-extractor.ts) |
| 24 | + |
| 25 | +**Multi-Source Timeline Extraction**: |
| 26 | +- **Git History** (preferred): Extract creation/update dates from git log |
| 27 | +- **Content Parsing** (fallback): Parse date fields from ADR content |
| 28 | +- **Filesystem** (last resort): Use file modification times |
| 29 | + |
| 30 | +**Smart Conditional Logic**: |
| 31 | +- Only extract when necessary (no timestamp in content, file modified, cache miss) |
| 32 | +- In-memory caching to avoid repeated expensive operations |
| 33 | +- Configurable force-extract option for manual overrides |
| 34 | + |
| 35 | +**Timeline Data Structure**: |
| 36 | +```typescript |
| 37 | +interface BasicTimeline { |
| 38 | + created_at: string; // ISO timestamp |
| 39 | + updated_at: string; // ISO timestamp |
| 40 | + age_days: number; // Days since creation |
| 41 | + days_since_update: number; // Days since last modification |
| 42 | + staleness_warnings: string[]; // Generated warnings |
| 43 | + extraction_method: 'git' | 'content' | 'filesystem'; |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +### 2. Project Context Detection (src/utils/adr-context-detector.ts) |
| 48 | + |
| 49 | +**Automatic Project Phase Detection**: |
| 50 | +- **Startup**: High commit rate (>50/week), frequent ADRs (>3/month) |
| 51 | +- **Growth**: Moderate commits (20-50/week), regular ADRs (>1/month) |
| 52 | +- **Mature**: Stable commits (5-20/week), occasional ADRs |
| 53 | +- **Maintenance**: Low commits (<5/week), rare ADRs (<0.5/month) |
| 54 | + |
| 55 | +**Adaptive Threshold Profiles**: |
| 56 | +```typescript |
| 57 | +THRESHOLD_PROFILES = { |
| 58 | + startup: { |
| 59 | + staleProposedDays: 14, // 2 weeks max |
| 60 | + acceptedUnimplementedDays: 21, |
| 61 | + outdatedAdrDays: 60, |
| 62 | + rapidChangeDays: 3 |
| 63 | + }, |
| 64 | + growth: { |
| 65 | + staleProposedDays: 30, // 1 sprint cycle |
| 66 | + acceptedUnimplementedDays: 45, |
| 67 | + outdatedAdrDays: 90, |
| 68 | + rapidChangeDays: 7 |
| 69 | + }, |
| 70 | + mature: { |
| 71 | + staleProposedDays: 90, // 1 quarter |
| 72 | + acceptedUnimplementedDays: 90, |
| 73 | + outdatedAdrDays: 180, |
| 74 | + rapidChangeDays: 14 |
| 75 | + }, |
| 76 | + maintenance: { |
| 77 | + staleProposedDays: 180, // 6 months |
| 78 | + acceptedUnimplementedDays: 180, |
| 79 | + outdatedAdrDays: 365, |
| 80 | + rapidChangeDays: 30 |
| 81 | + } |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +**ADR Type Modifiers**: |
| 86 | +- Infrastructure ADRs: 1.5x longer timelines (complex deployments) |
| 87 | +- Security ADRs: 0.8x shorter timelines (urgent) |
| 88 | +- Refactoring ADRs: 1.2x longer timelines (low priority) |
| 89 | +- Feature ADRs: 1.0x baseline |
| 90 | + |
| 91 | +### 3. Action Item Analyzer (src/utils/adr-action-analyzer.ts) |
| 92 | + |
| 93 | +**Automated Action Generation**: |
| 94 | +- Analyzes all ADRs with timeline data |
| 95 | +- Generates prioritized action items based on: |
| 96 | + - ADR status (proposed, accepted, deprecated) |
| 97 | + - Age and staleness |
| 98 | + - Implementation status |
| 99 | + - Project context and thresholds |
| 100 | + |
| 101 | +**Action Urgency Levels**: |
| 102 | +- **Critical** (P0): Blocking issues, security risks |
| 103 | +- **High** (P1): Stale proposed ADRs, long-unimplemented decisions |
| 104 | +- **Medium** (P2): Outdated ADRs needing review |
| 105 | +- **Low** (P3): Minor updates, documentation improvements |
| 106 | + |
| 107 | +**Work Queue Structure**: |
| 108 | +```typescript |
| 109 | +interface AdrWorkQueue { |
| 110 | + summary: { |
| 111 | + totalActions: number; |
| 112 | + criticalCount: number; |
| 113 | + highCount: number; |
| 114 | + mediumCount: number; |
| 115 | + lowCount: number; |
| 116 | + }; |
| 117 | + actions: ActionItem[]; // Sorted by urgency |
| 118 | + recommendations: string[]; |
| 119 | +} |
| 120 | +``` |
| 121 | + |
| 122 | +### 4. Integration |
| 123 | + |
| 124 | +**Enhanced ADR Discovery**: |
| 125 | +- `discoverAdrsInDirectory()` now accepts `includeTimeline` option |
| 126 | +- Timeline data automatically attached to each discovered ADR |
| 127 | +- Optional action generation with `generateActions` flag |
| 128 | + |
| 129 | +**New MCP Tool** (src/index.ts:6800-6950): |
| 130 | +- `analyze_adr_timeline`: Comprehensive timeline analysis with action items |
| 131 | +- Parameters: |
| 132 | + - `adrDirectory`: Directory to analyze |
| 133 | + - `generateActions`: Enable action item generation |
| 134 | + - `thresholdProfile`: Manual profile override |
| 135 | + - `autoDetectContext`: Auto-select profile (default: true) |
| 136 | + |
| 137 | +### 5. Cache Implementation Decision |
| 138 | + |
| 139 | +**Problem**: The existing `cache.ts` is designed for **prompt-driven AI operations** (returns prompts for AI to execute), but timeline extraction needs **synchronous in-memory caching** for performance. |
| 140 | + |
| 141 | +**Solution**: Implemented a simple in-memory cache directly in `adr-timeline-extractor.ts`: |
| 142 | +- `Map<string, CacheEntry>` for O(1) lookup |
| 143 | +- TTL-based expiration |
| 144 | +- Automatic cleanup on retrieval |
| 145 | +- No external dependencies |
| 146 | + |
| 147 | +**Why Not Use cache.ts**: |
| 148 | +- cache.ts returns `{ prompt, instructions, context }` for AI delegation |
| 149 | +- Timeline extractor needs immediate, synchronous cache access |
| 150 | +- In-memory cache is simpler and more appropriate for this use case |
| 151 | + |
| 152 | +## Consequences |
| 153 | + |
| 154 | +### Positive |
| 155 | + |
| 156 | +1. **Temporal Awareness**: System now understands ADR lifecycles and aging |
| 157 | +2. **Automated Action Planning**: Generates prioritized todo lists automatically |
| 158 | +3. **Context-Aware Analysis**: Thresholds adapt to project phase and velocity |
| 159 | +4. **Smart Performance**: Conditional extraction minimizes expensive operations |
| 160 | +5. **Type Safety**: ADR type modifiers provide realistic timelines |
| 161 | +6. **Better User Experience**: Users get actionable insights, not just data |
| 162 | + |
| 163 | +### Negative |
| 164 | + |
| 165 | +1. **Increased Complexity**: More code to maintain (4 new utility files) |
| 166 | +2. **Git Dependency**: Git extraction requires git to be available |
| 167 | +3. **Cache Divergence**: Two cache systems (prompt-driven and in-memory) |
| 168 | +4. **Context Detection Accuracy**: Auto-detection may misclassify edge-case projects |
| 169 | + |
| 170 | +### Neutral |
| 171 | + |
| 172 | +1. **Breaking Change**: `discoverAdrsInDirectory()` signature changed from 3 params to 2 params + options object |
| 173 | +2. **Memory Usage**: In-memory cache adds modest memory overhead |
| 174 | +3. **Learning Curve**: Users need to understand threshold profiles |
| 175 | + |
| 176 | +## Implementation Notes |
| 177 | + |
| 178 | +### Files Created |
| 179 | +- `src/utils/adr-timeline-extractor.ts` - Multi-source timeline extraction |
| 180 | +- `src/utils/adr-context-detector.ts` - Project context detection |
| 181 | +- `src/utils/adr-action-analyzer.ts` - Action item generation |
| 182 | +- `src/utils/adr-timeline-types.ts` - Shared type definitions |
| 183 | + |
| 184 | +### Files Modified |
| 185 | +- `src/utils/adr-discovery.ts` - Added timeline integration |
| 186 | +- `src/index.ts` - Added `analyze_adr_timeline` MCP tool |
| 187 | +- 20+ files - Updated `discoverAdrsInDirectory()` call sites |
| 188 | + |
| 189 | +### Testing |
| 190 | +- Manual verification: Timeline extraction working correctly |
| 191 | +- Git extraction: Successfully extracts from git history |
| 192 | +- Fallback chain: Content → filesystem fallback working |
| 193 | +- Cache: In-memory cache functioning as expected |
| 194 | + |
| 195 | +## Future Enhancements |
| 196 | + |
| 197 | +1. **Persistent Cache**: Move timeline cache to disk for cross-session persistence |
| 198 | +2. **ML-Based Context Detection**: Use machine learning to improve phase detection |
| 199 | +3. **Custom Thresholds**: Allow users to define custom threshold profiles |
| 200 | +4. **Timeline Visualization**: Generate charts showing ADR lifecycle trends |
| 201 | +5. **Notification Integration**: Alert users when ADRs become stale |
| 202 | +6. **ADR Dependencies**: Track dependencies between ADRs in timeline |
| 203 | + |
| 204 | +## Related ADRs |
| 205 | + |
| 206 | +- ADR-003: Memory-Centric Architecture (cache system design) |
| 207 | +- ADR-001: MCP Protocol Implementation (tool integration) |
| 208 | + |
| 209 | +## References |
| 210 | + |
| 211 | +- Git log extraction: `git log --follow --format="%ai" --diff-filter=A -- <file>` |
| 212 | +- Context detection metrics: Commit frequency, ADR creation rate, team velocity |
| 213 | +- Urgency scoring: Based on ADR status, age, and project context |
0 commit comments