{"version":"2.1.289","anchor":"toolcheck-hook-decision-accepts-an-optional-hook-string","canonical_anchor":"toolcheck-hook-decision-accepts-an-optional-hook-string","heading":"Permission decisions can now name the hook that made them","tier":"use","area":"Plugin Hooks","scope":"individual","heads_up":false,"url":"https:\/\/changelogs.core-directive.com\/v\/2.1.289\/e\/toolcheck-hook-decision-accepts-an-optional-hook-string","release_url":"https:\/\/changelogs.core-directive.com\/v\/2.1.289","markdown":"### Permission decisions can now name the hook that made them\n\nPermission decisions gain an optional `hook` field, which plugin `tool.check` hooks can set, and rules inside nested commands are now found\n\n**Unclear.** How the hook name is used after it is accepted, and whether plugin hooks of this kind are on by default, is not clear.\n\n**What**\n\nBefore Claude Code runs a tool (such as a shell command), it decides whether to allow it, ask you, or refuse. The record of that decision held `decision`, `reason` and `rule`. It now also has an optional `hook` field saying which hook made the decision. A hook is a piece of plugin or user code that runs at a set moment.\n\n- Plugin hooks: a `tool.check` hook can now return a `hook` string with its decision. A non-string value is rejected with the message \"a reason, rule or hook that is not a string\".\n\n- Filling the field: `hook` comes from the hook's own answer or is looked up from the decision's `decisionReason.hookName`, ignoring `tool.check`.\n\n- Nested commands: the rule lookup now searches inside nested `subcommandResults`. Before, it checked only one level deep, so a compound command could miss the rule that decided it.\n\n**Why**\n\nTools and SDK users reading these decisions can tell when a hook, and which one, allowed or blocked a tool. Compound commands now report their deciding rule more reliably.\n\n- Area: Plugin Hooks\n- Tier: Use it now\n- Useful: 3\/5\n- Signal: 2\/5\n- Scope: individual\n- Heads-up: no"}