Agents
Cursor
Cursor and chock: install methods and steps, what it can enforce, and the evidence behind it.
Install methods: plugin, sync. Agentseam tier block+rewrite, grade enforceable before a tool runs.
Install methods
- Plugin:
chock install --client cursor(ask the user before running it) - Repo hooks:
chock sync --repo . --agents cursorwrites.cursor/hooks.json(ask the user before running it)
Install steps
Cursor (cursor)
Tested
The command (ask the user before running it: it builds a plugin of hooks that change how their agent behaves):
chock install --selection <code> --client cursor --apply
With --apply, chock runs these steps for Cursor:
Cursor loads ~/.cursor/plugins/local/chock-guardrails as a local plugin: run "Developer: Reload Window" (or restart Cursor), then check it under Customize. There is no command to run.
What it can enforce
- Tier
- block+rewrite
- Grade before a tool runs
- enforceable
- Fail mode before a tool runs
- configurable
- Basis
- live-run-partial
- Recorded
- 2026-09-23
Events
| Event | Can block | Can rewrite | Fail mode |
|---|---|---|---|
pre_tool | yes | yes | configurable |
post_tool | no | no | open |
tool_failure | no | no | open |
prompt_submit | yes | no | configurable |
session_start | no | no | open |
session_end | no | no | open |
subagent_start | no | no | open |
subagent_stop | no | no | open |
stop | yes | no | open |
pre_compact | no | no | open |
file_changed | no | no | open |
Ask support
Answers an ask with: ask. Honours ask: yes. Evidence: tested (tests/test_guard_fail_to_ask.py::test_a_crashed_guard_asks_rather_than_allowing).
Hook timeout
The engine records no timeout for this agent.
Test status
- Plugin (cursor): tested.
- Repo hooks: untested. A test of the plugin says nothing about repo hooks.
- Through the plugin install, at hook point plugin-hook: Cursor, 2026-08-24. live probe: a stdout deny blocked a matched command, a benign one still ran (chock 6b4d400)
Known limits
Fails OPEN by default; failClosed:true per hook definition makes it fail closed, and agentseam sets it on every gate it installs. ask is accepted by the preToolUse schema but not enforced today, so the adapter denies instead of returning a prompt that would behave as a pass; beforeShellExecution and beforeMCPExecution do honour ask. Separate Tab hooks (beforeTabFileRead, afterTabFileEdit) gate inline completions, and workspaceOpen fires outside any session with no canonical event here. Cursor also loads Claude Code-format hooks -- confirmed live (2026-08-27): with both .cursor/hooks.json and .claude/settings.json carrying the same probe, every event fired twice, once per config. SETTLED live (3.17.8, Windows, 2026-08-28) by a two-trial experiment differing in one key: a beforeShellExecution hook that exited 0 in SILENCE let echo hello run without failClosed, and BLOCKED it with failClosed:true. Silence here is a hook ERROR -- not a refusal, not an abstention. That retires the earlier note's flat 'an empty response is not an allow': the 2026-08-27 rejection it rested on was real, but the hook carried failClosed:true, which hook_config() set on every gate with no way to opt out. Its matcher also does not mean the same thing at every event: under beforeShellExecution it is a regex over the COMMAND TEXT, not a tool name, so the "Bash" a caller would reasonably pass matches almost nothing and quietly disables the guard -- the one hook field whose wrong value fails silently, since the install still reports success. What preToolUse's matcher matches was not established here, so hook_config writes NO matcher until one is: no matcher gates every call, which over-gates rather than under-gates, and is the conclusion a sibling guardrail reached independently after shipping this format. A hook agentseam wires here must still answer in-dialect, and now for a proven reason -- these gates install fail-closed by DEFAULT, so a silent adapter would refuse every allowed tool call. The same run recorded two facts nothing here had: the gate fires TWICE for one command (sandbox:true, then sandbox:false on Cursor's own retry), so a policy with side effects double-counts and a deny must hold on both passes; and beforeShellExecution DOES fire when it is wired. Across three capture sessions in which shell commands ran, beforeShellExecution never fired while tool_input.command arrived under preToolUse instead. RESOLVED 2026-08-28, and the cause was our own wiring: REVERSE_EVENT_MAP sends pre_tool to preToolUse, so beforeShellExecution was never installed in those captures. A consumer should still gate shell on pre_tool -- it covers every tool and is the only one that can rewrite -- but not because the dedicated event is absent. WITNESSED 2026-09-23 (3.21.18, Windows): the generic preToolUse gate DOES honour deny for a file write -- Write arrives with file_path and the full content, a {permission: deny} left the file unwritten -- so the write path is gateable here after all, and Write is recorded as the write vocabulary. The stop hook honours {followup_message}: the message is posted as the next turn and the agent acts on it, so a refusal at stop is delivered the way Claude Code's Stop block is; silence there ends the turn, so stop fails open. afterFileEdit still accepts nothing back, and the chat reply is not a tool call.
Built from engine 5a4b6287a46e and catalog 1e60d211c1bb.