A Claude Code command hook may answer permissionDecision: "ask", which in Claude
Code raises a prompt. Albedo's hook seam has no prompt and no verdict for it, so the
answer is dropped and the call runs. A policy that says "review this" is silently
widened to "allow", which is the wrong direction for the one case a policy writer
thought was risky.
Evidence #
priv/python/albedo_hook_command.py (answer/1) maps only two refusals:
if output.get("decision") == "block": # -> block
if specific.get("permissionDecision") == "deny": # -> block
An ask therefore merges as {}. Run through the real helper
(python3 priv/python/albedo_hook_command.py with the daemon's request shape and
$ALBEDO_HOME/hooks.json running chook, which is a Claude Code hook that answers ask):
$ ... command: "rm -rf /tmp/chook-probe-does-not-exist"
{"block": null, "halt": null, "arguments": null, "context": [], "notes": []}
$ ... command: "sudo -n true" # chook denies this one
{"block": "sudo is not allowed. Find an alternative that doesn't require elevated privileges.", ...}
and in a real turn, on the deny:
PermissionError: blocked by a hook: sudo is not allowed. Find an alternative that
doesn't require elevated privileges.
while the ask-ed command ran untouched (run("rm", "-rf", ...) returned exit 0).
robot-docs/hooks.md documents exit 2, decision: "block" and
permissionDecision: "deny" only, so this may be a deliberate omission -- but then the
payload should not invite it either: albedo sends "permission_mode": "default", which
reads as "an interactive mode exists".
Why it matters #
The natural pattern for a policy hook is deny / ask / allow, and ask is exactly where a
rule author puts the judgement calls. Under albedo those become allows with no trace --
not a note, not an event, nothing in the transcript.
Options #
- Treat
askas a block whose reason ispermissionDecisionReason, since there is nobody to ask. That is whatCHOOK_UNATTENDED=1already makes chook do for its own asks, so the two agree. - Or carry it as a distinct verdict, so a client with a prompt (the TUI) could ask and a client without one turns it into a refusal.
- Or, at minimum, turn it into a note and document that
askis ignored, so a hook author is not quietly loosening their policy.
im really going to ask to please put these in your own words. i realize i myself am not consistent with this but these drive-bys are hard to read and im not a huge fan of being a meat proxy. im not even sure if youre running into these on your own or automating them (which is fine!) but id like to know that too