A prompt can agree and still emit the delete
I used to put the fence in the system text. "Do not delete the disk." "Do not touch .env." The model agreed. Then it emitted rm -rf /.
Prompt guardrails filter what the model says. A hook can deny the tool call before it runs. Those are different layers.
The prompt is a suggestion. A firing host hook can deny a tool call before it runs. That is hook grade. It does not replace the host wrapper or OS sandbox. Hermes pre_llm_call cannot veto.
The agree-and-delete case
A coding agent plans in text. Then it emits an action: a command, a file write, a network call, an MCP tool. I can read the plan and think I am safe. The plan is not the action.
Here is the boring case. The agent can write cleanup.sh containing a delete, then run bash cleanup.sh. On OpenCode, Write and Bash both hit tool.execute.before. Default Grok hooks are Bash + Read only, so Write/Edit never reach rv. rv evaluates the shell command string, not the script file. File-write policy uses the path, not the file body. bash cleanup.sh is allow. bash -c 'rm -rf /' is deny. Neither hook sees rm -rf / inside cleanup.sh.
Live rv test v0.2.21 (script not executed): bash cleanup.sh allow; rm -rf / and bash -c 'rm -rf /' deny core.filesystem:rm-rf-root-home.
I still write system text. I do not trust it as the fence. The prompt talks to a generator. The hook sees the tool, the args, and the surface the host chose to show.
I write policy in local packs. That file is not a prompt. It is the rule the hook evaluates when an action arrives. Policy only matters if the hook fired. A clean policy file with a silent host is a comfort object.
What I wait for
On OpenCode the visible deny is denied: a toast titled denied, a tool error like denied <context>: <detail>, or the fallback denied this command. Other hosts use other deny strings. It is not a [rv] DENIED line.
OpenCode leftover unused ask does not show an ask screen. I do not describe one.
I prove the OpenCode path in Trigger a known OpenCode deny before you leave. No block on that host means the hook never fired. I wrote that miss in If a hook never fires, the action already ran.
How the check works is in Runtime guardrails decide allow, ask, or deny before the tool runs.
Leftover ask is still not the gate
On an attended coding host, leftover unused policy ask is allow. Leftover unused policy ask is not a host-wire decision and does not open an ask UI. You get a block, or the command runs.
Unattended and CI harden leftover unused ask to deny. That is existing --ci or a truthy CI / RYK_CI / RYK_UNATTENDED / RYK_NONINTERACTIVE. There is no new flag. There is no rv unattended command.
I wrote that hole in An unattended agent has no one to click ask. A prompt that says "ask me first" is not those keys.
How I start the host
curl -fsSL https://rykanv.com/install | sh
rv setup
Then the host. rv setup is first-run. It creates workspace local packs if missing. Curl plus the host command alone skips that.
Install is on the docs. Other posts are on the blog. I start from rykanv.com.
The model can agree. A firing host hook can still deny. I want that hook.