diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh index 6a0dcda16..bc284c360 100755 --- a/.claude/hooks/session-start.sh +++ b/.claude/hooks/session-start.sh @@ -242,10 +242,21 @@ fi # header owns the what and the why, this owns only the WHEN. # # WHY HERE and not on a later event: settings are a startup snapshot (CLOUD-187), -# so a write after the read binds nothing — measured, on this very session, by -# projecting mid-session and watching the identical call refuse exactly as -# before. This is the earliest writable moment, and the overlay it leaves is read -# by the next session start in this container. +# so a write after the read binds nothing, and this is the earliest writable +# moment there is. +# +# AND IT IS STILL NOT EARLY ENOUGH — say so here rather than let a reader infer a +# working mechanism from a running one. Three surfaces have now been tried and +# measured: the generated config edited mid-session, this overlay written +# mid-session, and this overlay present on disk BEFORE a session started (same +# container, same disk, verified by mtime). All three left the identical call +# refused. The refusal arrives from the CCR proxy, upstream of the local +# permission layer, where no file this hook can write will reach it — upstream +# anthropics/claude-code#61044 and #61015, and the capability gap CLOUD-312 +# tracks. What the projection is FOR, then, is the committed intent expressed +# against the identity that actually attached: that is what `mcp-allow-check`'s +# inert-rule predicate reads, and it is what makes that predicate closable rather +# than a verdict no edit could satisfy. # # NEVER SETS `fail`, and deliberately not routed through `step`, for the reason # `reclaim-census` below is not: a stale committed rule is a finding about the diff --git a/mise-tasks/mcp-grant-sync b/mise-tasks/mcp-grant-sync index 4f38aa22f..2602e99e5 100755 --- a/mise-tasks/mcp-grant-sync +++ b/mise-tasks/mcp-grant-sync @@ -25,8 +25,22 @@ # the Claude Code Remote server, against six committed `mcp__Claude_Code_Remote__*` # allow rules and 20 tools all sitting at `always_ask`. So the host performs this # projection and silently dropped one connector's entire grant. A process -# argument is fixed at startup and unreachable from a hook — but it is unioned -# with the settings files, and a settings file is rereadable. Hence the overlay. +# argument is fixed at startup and unreachable from a hook, which is what sends +# the projection to the overlay instead. +# +# WHAT THE OVERLAY DOES NOT DO, measured rather than hoped: it does not release +# the call. Three surfaces tried — the generated config edited mid-session, this +# overlay written mid-session, and this overlay already on disk before a session +# started (same container, verified by mtime) — and all three left the identical +# committed-but-inert call refused. The refusal is the CCR proxy's, upstream of +# the local permission layer (anthropics/claude-code#61044, #61015; CLOUD-312). +# +# So this is not a permission fix, and a reader should not spend a session +# expecting one. It is the committed intent expressed against the identity that +# actually attached, which is the thing `mcp-allow-check`'s inert-rule predicate +# reads: without it, "this rule names a server that never attached" would be a +# verdict no edit could satisfy, since a committed rule cannot name an identifier +# that rotates. # # WHY `.claude/settings.local.json` AND NOT THE COMMITTED FILE. The overlay is # gitignored (`.gitignore:22`), per-container, and derived: every rule it carries