Commit 719ea07
fix(claude-code,m4): rebuild ADR-027 W6 hooks with type=command shim (v1.0.659-alpha)
ADR-027 W11 fix-up wedge #3 — claude-code M4 boot regression caught on
on-host smoke of v1.0.658: settings.local.json hooks fail validation
with "Expected string, but received undefined" and claude refuses to
launch.
Root cause: ADR-027 W6 emitted hook entries of shape
{"type": "mcp_tool", "tool": "mcp__termipod-host__hook_*", ...}
which was a speculative design — claude-code's actual hook schema
only supports {"type": "command", "command": <string>}. The `tool`
field is unknown; `command` is missing; validator throws on first
load. Hooks have been silently broken since v1.0.592; nobody noticed
because most claude-code spawns run M2 stream-json, not M4 LocalLogTail.
Fix (rebuild W6 properly):
New host-runner subcommand `hook-fire` (internal/hookfire/) — a
one-shot stdio bridge that wraps claude-code's hook contract over the
existing UDS MCP gateway:
- claude spawns `host-runner hook-fire --socket <uds> --event <Event>`
- writes hook payload (single JSON object) to stdin, closes stdin
- shim wraps as JSON-RPC `tools/call` with name=`hook_<event_snake>`,
arguments=<payload>
- dials per-spawn UDS, half-closes write side, reads one response line
- extracts `result.content[0].text`, writes to stdout, exits 0
Failure semantics tuned for blocking hooks: transport blip → stdout
"{}" + non-zero exit + stderr warning, same outcome as an uninstalled
hook (claude defaults to "allow").
hooks_install.go rewrites appendTermipodMatcher to emit:
{"matcher": "",
"_termipod_managed": true,
"hooks": [{"type": "command",
"command": "host-runner hook-fire --socket '<sock>' --event <Event>",
"timeout": <n>}]}
`_termipod_managed` retained as the strip-then-append key — this lets
v1.0.659 spawns self-heal stale workdirs that still hold the pre-v1.0.659
invalid mcp_tool entries. New test
TestInstallClaudeHooks_SelfHealsStaleMcpToolEntries locks this.
Side effect: the v1.0.657 turn.result emission in hookStop now actually
fires (Stop hook reaches the adapter again). v1.0.657 symptom #4 fix
becomes load-bearing for real.
Tests:
- internal/hookfire/run_test.go × 6 (round-trip, gateway error, dial
failure, event coverage, CLI usage errors)
- internal/hostrunner/hooks_install_test.go rewritten — schema
validation, self-heal of stale workdirs, plus the 5 prior behaviour
tests adapted to the new command-typed shape
- launch_m4_locallogtail_test.go updated — substring assertions now
check for "host-runner hook-fire" + "--event PreCompact" instead of
the (now-absent) mcp__termipod-host__hook_pre_compact string
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>1 parent 8ff54b2 commit 719ea07
10 files changed
Lines changed: 767 additions & 41 deletions
File tree
- docs
- hub
- cmd/host-runner
- internal
- buildinfo
- hookfire
- hostrunner
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
26 | 141 | | |
27 | 142 | | |
28 | 143 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| 51 | + | |
51 | 52 | | |
52 | 53 | | |
53 | 54 | | |
| |||
83 | 84 | | |
84 | 85 | | |
85 | 86 | | |
| 87 | + | |
| 88 | + | |
86 | 89 | | |
87 | 90 | | |
88 | 91 | | |
| |||
125 | 128 | | |
126 | 129 | | |
127 | 130 | | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
128 | 137 | | |
129 | 138 | | |
130 | 139 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
0 commit comments