Last reviewed
Correct answer: C. The conversation opens regardless, because sessionStart is fire-and-forget; a gate has to sit on a hook that can genuinely block, such as one guarding shell, tool or MCP calls.
Explanation
The principle — Hooks fall into two useful groups. Some sit in front of an action and can stop it: hooks guarding shell execution, MCP calls, file reads, tool use and prompt submission all return a decision the agent loop waits for. Others observe. sessionStart is called when a new composer conversation is created, and it runs as fire-and-forget: the agent loop does not wait for it or enforce a blocking response. Its purpose is to set session-scoped environment variables and inject additional context.
Why the key is correct — Session creation goes ahead. The schema will accept a continue field, but current callers do not enforce it, so a refusal is written, returned and ignored. The team's check is real work producing no protection, which is worse than having no check, because the review that approved it now believes a control exists. Move the gate to a hook the loop actually waits on: refuse shell execution, MCP calls or prompt submission while the policy is unaccepted, and the same script becomes enforceable. Keep sessionStart for what it is good at, namely setting up the session and telling the agent what the policy state is.
Why the others are wrong — Enforcement is a property of the individual hook rather than of hooks in general, so a denial that binds a tool hook does nothing here. Marking the hook fail-closed changes only what happens when it crashes, times out or returns unparseable output; it cannot create an enforcement point where the loop never pauses. And the first turn is not held either, which is the second half of fire-and-forget: any environment or context the hook prepares may arrive after the turn that needed it, so treat that setup as best-effort rather than guaranteed.
Remember this — sessionStart informs a session; it cannot refuse one. A gate belongs on a hook whose answer the loop waits for.
Sources — Cursor's Hooks documentation.
Sources
“Called when a new composer conversation is created. This hook runs as fire-and-forget; the agent loop does not wait for or enforce a blocking response.”
Practise 10 questions on this topic
Take Cursor Basics — Timed Test 1 (10 questions) — scored instantly, explanation for every question, no login.