|
| 1 | +--- |
| 2 | +document_type: decisions |
| 3 | +project_id: SPEC-2025-12-19-002 |
| 4 | +--- |
| 5 | + |
| 6 | +# Hook Enhancement v2 - Architecture Decision Records |
| 7 | + |
| 8 | +## ADR-001: PreCompact Uses stderr for User Feedback |
| 9 | + |
| 10 | +**Date**: 2025-12-19 |
| 11 | +**Status**: Accepted |
| 12 | +**Deciders**: Development team |
| 13 | + |
| 14 | +### Context |
| 15 | + |
| 16 | +The PreCompact hook needs to inform users when memories are auto-captured before context compaction. The original plan assumed PreCompact could use `additionalContext` in hookSpecificOutput for this purpose. |
| 17 | + |
| 18 | +However, research into the Claude Code hooks API revealed that PreCompact is **side-effects only** - it does not process JSON output. Only stderr is shown to users. |
| 19 | + |
| 20 | +### Decision |
| 21 | + |
| 22 | +PreCompact will: |
| 23 | +1. Capture memories as side effects (writing to git notes) |
| 24 | +2. Output a summary message to stderr for user visibility |
| 25 | +3. Return an empty JSON object `{}` to stdout |
| 26 | + |
| 27 | +### Consequences |
| 28 | + |
| 29 | +**Positive:** |
| 30 | +- Works within API constraints |
| 31 | +- Users still see notification of auto-captured memories |
| 32 | +- No need for workaround or API extension request |
| 33 | + |
| 34 | +**Negative:** |
| 35 | +- Less structured feedback than additionalContext would provide |
| 36 | +- stderr messages are less prominent in Claude Code UI |
| 37 | +- Cannot inject captured memory summaries into Claude's context |
| 38 | + |
| 39 | +**Neutral:** |
| 40 | +- Aligns with PreCompact's intended use case (backup/logging) |
| 41 | + |
| 42 | +### Alternatives Considered |
| 43 | + |
| 44 | +1. **Request Claude Code API change**: Too slow; creates external dependency |
| 45 | +2. **Skip user notification**: Poor UX; users wouldn't know what was captured |
| 46 | +3. **Use Stop hook instead**: Wrong lifecycle point; compaction already occurred |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +## ADR-002: Namespace Marker Syntax Design |
| 51 | + |
| 52 | +**Date**: 2025-12-19 |
| 53 | +**Status**: Accepted |
| 54 | +**Deciders**: Development team |
| 55 | + |
| 56 | +### Context |
| 57 | + |
| 58 | +Users need to specify which namespace their inline captures should target. The existing syntax (`[remember]`, `@memory`) always routes to `learnings` namespace. |
| 59 | + |
| 60 | +### Decision |
| 61 | + |
| 62 | +Support two syntaxes for namespace specification: |
| 63 | + |
| 64 | +1. **Bracket syntax**: `[remember:namespace]` and `[capture:namespace]` |
| 65 | +2. **At-sign syntax**: `@memory:namespace` |
| 66 | + |
| 67 | +Examples: |
| 68 | +- `[remember:decisions] Use PostgreSQL for database` |
| 69 | +- `[capture:patterns] API error handling approach` |
| 70 | +- `@memory:blockers CORS issue with frontend` |
| 71 | + |
| 72 | +Existing syntax without namespace remains valid and auto-detects or defaults to `learnings`. |
| 73 | + |
| 74 | +### Consequences |
| 75 | + |
| 76 | +**Positive:** |
| 77 | +- Intuitive extension of existing syntax |
| 78 | +- Backward compatible (existing markers unchanged) |
| 79 | +- Namespace clearly visible in the marker |
| 80 | +- Consistent with common annotation patterns |
| 81 | + |
| 82 | +**Negative:** |
| 83 | +- More regex patterns to maintain |
| 84 | +- Users need to learn new syntax |
| 85 | + |
| 86 | +**Neutral:** |
| 87 | +- Namespace validation needed (invalid namespace falls back to auto-detect) |
| 88 | + |
| 89 | +### Alternatives Considered |
| 90 | + |
| 91 | +1. **Separate markers per namespace**: `[decision]`, `[learning]`, etc. - Too many new markers |
| 92 | +2. **Namespace as parameter**: `[remember namespace=decisions]` - Verbose, less readable |
| 93 | +3. **Hashtag syntax**: `[remember #decisions]` - Conflicts with potential tag syntax |
| 94 | + |
| 95 | +--- |
| 96 | + |
| 97 | +## ADR-003: Auto-Capture Enabled by Default |
| 98 | + |
| 99 | +**Date**: 2025-12-19 |
| 100 | +**Status**: Accepted |
| 101 | +**Deciders**: Development team, User validation |
| 102 | + |
| 103 | +### Context |
| 104 | + |
| 105 | +PreCompact hook can auto-capture high-confidence uncaptured content before context compaction. This is a new behavior that writes to git notes without explicit user action. |
| 106 | + |
| 107 | +Options considered: |
| 108 | +1. Enabled by default, users can opt-out |
| 109 | +2. Disabled by default, users must opt-in |
| 110 | +3. Prompt user before each capture |
| 111 | + |
| 112 | +### Decision |
| 113 | + |
| 114 | +Auto-capture enabled by default (`HOOK_PRE_COMPACT_AUTO_CAPTURE=true`) with high confidence threshold (0.85). |
| 115 | + |
| 116 | +Rationale: Most users will benefit from automatic preservation of valuable content. Power users who want control can disable via environment variable. |
| 117 | + |
| 118 | +### Consequences |
| 119 | + |
| 120 | +**Positive:** |
| 121 | +- Maximum value for majority of users |
| 122 | +- Prevents loss of valuable context during compaction |
| 123 | +- Fail-safe: captured memories are tagged `["auto-captured", "pre-compact"]` for filtering |
| 124 | + |
| 125 | +**Negative:** |
| 126 | +- Some users may be surprised by automatic captures |
| 127 | +- Could create memories users didn't intend to save |
| 128 | +- May need tuning of confidence threshold over time |
| 129 | + |
| 130 | +**Neutral:** |
| 131 | +- High confidence threshold (0.85) limits false positives |
| 132 | +- Maximum 3 captures per compaction event |
| 133 | + |
| 134 | +### Alternatives Considered |
| 135 | + |
| 136 | +1. **Opt-in only**: Lower adoption, users who need it most won't enable it |
| 137 | +2. **Prompt first**: Interrupts compaction flow, poor UX |
| 138 | + |
| 139 | +--- |
| 140 | + |
| 141 | +## ADR-004: Response Guidance as XML in additionalContext |
| 142 | + |
| 143 | +**Date**: 2025-12-19 |
| 144 | +**Status**: Accepted |
| 145 | +**Deciders**: Development team |
| 146 | + |
| 147 | +### Context |
| 148 | + |
| 149 | +To improve signal detection accuracy, we need to teach Claude how to structure responses. The guidance must be injected into Claude's context at session start. |
| 150 | + |
| 151 | +Options: |
| 152 | +1. XML in additionalContext (existing pattern) |
| 153 | +2. Markdown in additionalContext |
| 154 | +3. System prompt modification |
| 155 | +4. Separate skill file |
| 156 | + |
| 157 | +### Decision |
| 158 | + |
| 159 | +Use XML format in SessionStart additionalContext, consistent with existing memory context injection. |
| 160 | + |
| 161 | +Structure: |
| 162 | +```xml |
| 163 | +<response_guidance> |
| 164 | + <capture_patterns> |
| 165 | + <pattern type="decision">...</pattern> |
| 166 | + <pattern type="learning">...</pattern> |
| 167 | + </capture_patterns> |
| 168 | + <inline_markers>...</inline_markers> |
| 169 | + <best_practices>...</best_practices> |
| 170 | +</response_guidance> |
| 171 | +``` |
| 172 | + |
| 173 | +### Consequences |
| 174 | + |
| 175 | +**Positive:** |
| 176 | +- Consistent with existing ContextBuilder patterns |
| 177 | +- Claude parses XML well |
| 178 | +- Structured data is easy to maintain and test |
| 179 | +- Can control verbosity via detail_level config |
| 180 | + |
| 181 | +**Negative:** |
| 182 | +- Adds tokens to context budget |
| 183 | +- XML is more verbose than markdown |
| 184 | + |
| 185 | +**Neutral:** |
| 186 | +- Configurable: users can disable if context budget is critical |
| 187 | + |
| 188 | +### Alternatives Considered |
| 189 | + |
| 190 | +1. **Markdown**: Less structured, harder to parse programmatically |
| 191 | +2. **System prompt**: Requires user to modify their config |
| 192 | +3. **Skill file**: Only works when skill is invoked, not always-on |
| 193 | + |
| 194 | +--- |
| 195 | + |
| 196 | +## ADR-005: PostToolUse Matcher Pattern |
| 197 | + |
| 198 | +**Date**: 2025-12-19 |
| 199 | +**Status**: Accepted |
| 200 | +**Deciders**: Development team |
| 201 | + |
| 202 | +### Context |
| 203 | + |
| 204 | +PostToolUse hook requires a matcher to filter which tools trigger the hook. Options: |
| 205 | +1. Match all tools (`.*`) |
| 206 | +2. Match specific write tools (`Write|Edit|MultiEdit`) |
| 207 | +3. Match all file operations (including Read) |
| 208 | + |
| 209 | +### Decision |
| 210 | + |
| 211 | +Match only write operations: `Write|Edit|MultiEdit` |
| 212 | + |
| 213 | +Rationale: |
| 214 | +- Read operations don't modify files, no memory context needed |
| 215 | +- Bash operations are too varied (could be reads or writes) |
| 216 | +- Write/Edit/MultiEdit indicate active development on a file domain |
| 217 | + |
| 218 | +### Consequences |
| 219 | + |
| 220 | +**Positive:** |
| 221 | +- Focused triggering reduces hook invocations |
| 222 | +- Lower latency impact (fewer hook calls) |
| 223 | +- Relevant memories surfaced at editing time |
| 224 | + |
| 225 | +**Negative:** |
| 226 | +- Won't inject memories when user reads a file |
| 227 | +- Bash file modifications not captured |
| 228 | + |
| 229 | +**Neutral:** |
| 230 | +- Can expand matcher later if needed (backward compatible) |
| 231 | + |
| 232 | +### Alternatives Considered |
| 233 | + |
| 234 | +1. **Match all (`.*`)**: Too noisy, hooks fire constantly |
| 235 | +2. **Include Read**: Context useful but may be overwhelming |
| 236 | +3. **Include Bash**: Hard to determine if Bash is file-related |
0 commit comments