{"version":"2.1.247","anchor":"stricter-vetting-of-hooks-forwarded-to-a-cloud-session","canonical_anchor":"stricter-vetting-of-hooks-forwarded-to-a-cloud-session","heading":"Stricter vetting of hooks forwarded to a cloud session","tier":"notice","area":"Cloud Sessions","scope":null,"heads_up":null,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.247\/e\/stricter-vetting-of-hooks-forwarded-to-a-cloud-session","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.247","markdown":"### Stricter vetting of hooks forwarded to a cloud session\n\nHooks forwarded to a cloud session are vetted harder, and refused if their program lives somewhere the session can write.\n\n**What**\n\nForwarding this machine's hooks to a cloud session now goes through a fuller admission path that resolves each script's interpreter from its `#!` line, holds back scripts that read code or data out of the checkout, drops a shell prefix it cannot trust, and trims PATH entries it cannot resolve locally. Hooks whose program resolves somewhere the cloud session can write are refused at call time rather than served. The single generic notice about a hook not being pinnable is replaced by two that say which condition applied.\n\n**Details**\n\n- `#!` parsing understands `\/usr\/bin\/env`, including its `-S` option; an interpreter that is a relative path, contains `..`, is `env` carrying options, cannot be located, or resolves into somewhere the session can write holds the hook with reason `interpreter_unvouched`, described as an interpreter this machine cannot vouch for.\n- A script sitting outside the checkout that sources relative files, names the checkout, or reads the `$CLAUDE_PROJECT_DIR` environment variable is held with reason `loads_from_reach`; the usual `\/dev\/*` paths are exempt from this check.\n- Both holds can be overridden by marking the hook `cloud: \"device\"` in your hook settings.\n- If an interpreter name resolves to a file the cloud session can write, the served call is refused and recorded with the telemetry outcome `in_reach_refused`.\n- A `CLAUDE_CODE_SHELL_PREFIX` that is unreadable or writable by the session is discarded, the hook runs unwrapped, and a warning is emitted.\n- A hook that would run wrapped in `CLAUDE_CODE_SHELL_PREFIX` is not pinned, because the wrapper rather than the script decides what actually runs, and a script under a dot-directory is not pinned because only `~\/.claude` and `~\/.config` are read; both report `reason: \"unpinned_command\"` and suggest marking the hook `cloud: \"device\"`.\n- All of this applies only to cloud sessions that register device hooks, started with `claude --cloud`, which still require stored consent through the `\/hooks` command and a bound cloud session; there is no separate flag, and within that path these checks always run.\n\n**Evidence**\n\n`interpreter_unvouched: \"an interpreter this machine cannot vouch for\"`, `loads_from_reach`, `prefix-unwrapped`, `would run wrapped in your CLAUDE_CODE_SHELL_PREFIX`\n\n- Area: Cloud Sessions\n- Tier: You'll notice\n- Useful: 3\/5\n- Signal: 4\/5"}