@@ -980,6 +980,7 @@ Investigation triggered by system reminder messages showing "SessionStart:startu
980980** Claude Code Internal Bug** : The hook execution engine spawns ** two separate Python processes** for each hook invocation, regardless of configuration.
981981
982982** Current Configuration** (CORRECT per schema):
983+
983984``` json
984985"SessionStart" : [
985986 {
@@ -995,6 +996,7 @@ Investigation triggered by system reminder messages showing "SessionStart:startu
995996```
996997
997998** Schema Requirement** :
999+
9981000``` typescript
9991001{
10001002 " required" : [" hooks" ], // The "hooks" wrapper is MANDATORY
@@ -1007,6 +1009,7 @@ Investigation triggered by system reminder messages showing "SessionStart:startu
10071009** Initial theory** : Extra ` "hooks": [] ` wrapper was causing duplication.
10081010
10091011** Reality** : The wrapper is ** required by Claude Code schema** . Removing it causes validation errors:
1012+
10101013```
10111014Settings validation failed:
10121015- hooks.SessionStart.0.hooks: Expected array, but received undefined
@@ -1017,18 +1020,21 @@ Settings validation failed:
10171020### Evidence
10181021
10191022** Configuration Analysis** :
1023+
10201024- Only 1 SessionStart hook registered in settings.json
10211025- No duplicate configurations found
10221026- Schema validation confirms format is correct
10231027- ** Two separate Python processes** spawn anyway (different PIDs)
10241028
10251029** From ` .claude/runtime/logs/session_start.log ` ** :
1030+
10261031```
10271032[2025-11-21T13:01:07.113446] INFO: session_start hook starting (Python 3.13.9)
10281033[2025-11-21T13:01:07.113687] INFO: session_start hook starting (Python 3.13.9)
10291034```
10301035
10311036** From ` .claude/runtime/logs/stop.log ` ** :
1037+
10321038```
10331039[2025-11-20T21:37:05.173846] INFO: stop hook starting (Python 3.13.9)
10341040[2025-11-20T21:37:05.427256] INFO: stop hook starting (Python 3.13.9)
@@ -1038,19 +1044,20 @@ Settings validation failed:
10381044
10391045### Impact
10401046
1041- | Area | Effect |
1042- | ------| --------|
1043- | ** Performance** | 2-4 seconds wasted per session (double process spawning) |
1044- | ** Context Pollution** | USER_PREFERENCES.md injected twice (~ 19KB duplicate) |
1045- | ** Side Effects** | File writes, metrics, logs all duplicated |
1046- | ** Log Clarity** | Every entry appears twice, making debugging confusing |
1047- | ** Resource Usage** | Double memory allocation, double I/O operations |
1047+ | Area | Effect |
1048+ | --------------------- | -------------------------------------------------------- |
1049+ | ** Performance** | 2-4 seconds wasted per session (double process spawning) |
1050+ | ** Context Pollution** | USER_PREFERENCES.md injected twice (~ 19KB duplicate) |
1051+ | ** Side Effects** | File writes, metrics, logs all duplicated |
1052+ | ** Log Clarity** | Every entry appears twice, making debugging confusing |
1053+ | ** Resource Usage** | Double memory allocation, double I/O operations |
10481054
10491055### Solution
10501056
10511057** NO CODE FIX AVAILABLE** - This is a Claude Code internal bug.
10521058
10531059** Workarounds** :
1060+
105410611 . Accept the duplication (hooks are idempotent, safe but wasteful)
105510622 . Add process-level deduplication in hook_processor.py (complex)
105610633 . Wait for upstream Claude Code fix
@@ -1076,6 +1083,7 @@ Our configuration **matches the official schema exactly**:
10761083```
10771084
10781085** Schema requirement** :
1086+
10791087``` typescript
10801088" required" : [" hooks" ], // The "hooks" wrapper is MANDATORY
10811089" additionalProperties" : false
@@ -1085,13 +1093,13 @@ Attempting to remove the wrapper causes validation errors.
10851093
10861094### Affected Hooks
10871095
1088- | Hook | Status | Root Cause |
1089- | ------| --------| ------------|
1096+ | Hook | Status | Root Cause |
1097+ | ---------------- | ---------- | ---------------------- |
10901098| ** SessionStart** | ❌ Runs 2x | Claude Code bug #10871 |
1091- | ** Stop** | ❌ Runs 2x | Claude Code bug #10871 |
1092- | ** PostToolUse** | ❌ Runs 2x | Claude Code bug #10871 |
1093- | PreToolUse | ❓ Unknown | Likely affected |
1094- | PreCompact | ❓ Unknown | Likely affected |
1099+ | ** Stop** | ❌ Runs 2x | Claude Code bug #10871 |
1100+ | ** PostToolUse** | ❌ Runs 2x | Claude Code bug #10871 |
1101+ | PreToolUse | ❓ Unknown | Likely affected |
1102+ | PreCompact | ❓ Unknown | Likely affected |
10951103
10961104### Key Learnings
10971105
@@ -1107,6 +1115,7 @@ Attempting to remove the wrapper causes validation errors.
11071115** Decision** : Accept the duplication as a known limitation until Claude Code team fixes #10871 .
11081116
11091117** Rationale** :
1118+
11101119- Configuration is correct per official schema
11111120- No user-side fix available without breaking schema validation
11121121- Hooks are idempotent (safe to run twice)
@@ -1116,12 +1125,14 @@ Attempting to remove the wrapper causes validation errors.
11161125### Monitoring
11171126
11181127Track Claude Code GitHub for fix:
1128+
11191129- ** Issue #10871 ** : "Plugin-registered hooks are executed twice with different PIDs"
11201130- ** Related** : #3523 (hook duplication), #3465 (hooks fired twice from home dir)
11211131
11221132### Verification
11231133
11241134Configuration correctness verified:
1135+
112511361 . ✅ Only 1 hook registered per event type
112611372 . ✅ Schema validation passes
112711383 . ✅ Format matches official Claude Code documentation
@@ -1618,3 +1629,51 @@ Created Rust and Azure Kubernetes expert agents with 10-20x learning speedup.
16181629- Show code that fixed the problem
16191630- Update PATTERNS.md when a discovery becomes reusable
16201631- Archive entries older than 3 months to DISCOVERIES_ARCHIVE.md
1632+
1633+ ## 2025-12-01: STOP Gates Break Sonnet, Help Opus - Model-Specific Prompt Behavior (Issue #1755 )
1634+
1635+ ** Context** : Testing CLAUDE.md modifications across both Opus and Sonnet models revealed same text produces opposite outcomes.
1636+
1637+ ** Problem** : STOP validation gates have model-specific effects:
1638+
1639+ - ** Opus 4.5** : STOP gates help (20/22 → 22/22 steps) ✅
1640+ - ** Sonnet 4.5** : STOP gates break (22/22 → 8/22 steps) ❌
1641+ - ** Root cause** : Different models interpret validation language differently
1642+
1643+ ** Solution** : V2 (No STOP Gates) - Remove validation checkpoints while keeping workflow structure
1644+
1645+ ** Results** (6/8 benchmarks complete, 75%):
1646+
1647+ Sonnet V2:
1648+
1649+ - ✅ MEDIUM: 24.8m, $5.47, 22/22 steps (-16% cost improvement)
1650+ - ✅ HIGH: 21.7m, $4.92, 22 turns (-12% duration vs MEDIUM - negative scaling!)
1651+
1652+ Opus V2:
1653+
1654+ - ✅ MEDIUM: 61.5m, $56.86, ~ 20/22 steps (-12% duration, -21% cost improvement!)
1655+ - ⏳ HIGH: Testing (~ 4.5 hours remaining)
1656+
1657+ ** Key Insights** :
1658+
1659+ 1 . ** Multi-Model Testing Required** : Same prompt can help one model while breaking another
1660+ 2 . ** STOP Gate Paradox** : Removing validation gates IMPROVES performance (12-21% cost reduction)
1661+ 3 . ** Negative Complexity Scaling** : V2 HIGH faster than MEDIUM for well-defined tasks (task clarity > complexity)
1662+ 4 . ** Universal Optimization** : V2 improves BOTH models, not just fixes one
1663+ 5 . ** High-Salience Language Risky** : "STOP", "MUST", ALL CAPS trigger different model responses
1664+
1665+ ** Impact** :
1666+
1667+ - Fixes Sonnet degradation completely (8/22 → 22/22)
1668+ - Improves Sonnet performance (-12% to -16%)
1669+ - Improves Opus performance (-12% to -21%)
1670+ - $20K-$406K annual savings (moderate: $81K/year)
1671+ - Universal solution (single CLAUDE.md for both models)
1672+
1673+ ** Implementation** : V2 deployed when Opus HIGH validates (expected)
1674+
1675+ ** Related** : #1755 , #1703 , #1687
1676+
1677+ ** Pattern Identified** : Validation checkpoints can backfire - use flow language instead of interruption language
1678+
1679+ ** Lesson** : Always validate AI guidance changes empirically with ALL target models before deploying
0 commit comments