Repository navigation
Cookbook proposal: Jev as an agent's shell-command approval gate (measured, with a public MIT implementation) #5
Description
Hi — a pattern we built on Jev and measured on a real deployment, offered as a cookbook/skill candidate. If it's useful, tell me which shape you want and I'll write it that way.
The decision point: an agent's shell-command approval gate
Long-lived coding agents gate flagged shell commands through a "guardian" call that expects exactly one word back — APPROVE, DENY, or ESCALATE. We ran that gate on an LLM judge for a while and it has two structural problems:
- The call is fragile. Reasoning models spend a small
max_tokensbudget on hidden reasoning, return empty content (finish_reason="length"), and the empty string maps to "escalate" — so every flagged command prompts the human, silently and permanently. That failure mode is tracked upstream (smart approvals: max_tokens=16 on the guardian returns an empty answer with reasoning models, so every flagged command escalates to the user NousResearch/hermes-agent#108163, #68263); I measured 16 tokens → empty, 256 → clean verdict on two different routes. - A prose verdict gives nothing to calibrate on. No confidence, no runner-up margin, no way to answer "how sure were you, and was the alternative close?"
Jev answers exactly this shape of question: one Choice with three explicit criteria comes back as a calibrated distribution plus confidence, at ~0.2 s, with no free text that can overrun a budget.
What we built
approval-judge-bridge (MIT, no dependencies) — an OpenAI-compatible /v1/chat/completions endpoint that adapts the host's guardian call to a judge, so nothing in the host is patched and a host upgrade can't lose the integration. Three interchangeable backends: Jev (typesafe), any OpenAI-compatible model, or a deterministic rule file. Fail-closed on every path (missing key, timeout, HTTP error, missing answer envelope, unknown class, empty answer) — it never returns APPROVE because it could not tell.
Three findings
1. Jev's judging confidence needs calibrating, and the data is there to do it. On our traffic Jev's approve probability for ordinary development work sits at 0.65–0.81 with a margin of 0.30–0.66. Reusing Jev's own classify defaults (auto_accept=0.85, margin=0.6) escalated 17 of 21 judgements — 12 of the 13 real work commands — even though Jev's winning class was approve in 10 of them. After replaying the logged distributions and moving to 0.65 / 0.30 (plus naming routine dev work explicitly in the criteria), the next 36 judgements came back 19 APPROVE / 10 DENY / 3 low-confidence ESCALATE / 4 escalate-class ESCALATE, median latency 0.18 s.
2. The invariant worth stating in a cookbook: a deny/escalate winning class is never auto-approved at any threshold. Only approve can pass a gate, so threshold tuning trades prompts for quiet — never protection. We ship that statement as an executable check: tools/replay_battery.py (9 benign commands that must approve, 8 dangerous controls that must not, including two probes for an over-narrowed escalate class — an approval-config edit and base64 -d | bash). It passes end to end here, and it caught a real regression risk when we tightened the criteria.
3. Our escalations match your documented limits, with one criteria bug of our own. Obfuscation, pipe-to-shell, credential exfiltration and review-addressing text all escalate as expected. The interesting miss: an escalate class phrased as "touches credentials" made read-only credential inspection escalate at 0.88 — that was a question-design problem, not a model problem. Naming it "altering credentials or the approval machinery" fixed it. Worth a line in any gate-oriented cookbook: ask about the operation, not the noun.
Ask
Happy to contribute this as a cookbook entry, a section inside the official typesafe-ai skill, a second skill, or a demo — whichever fits your pipeline. The worked implementation is already public and MIT-licensed, plus 29 offline tests and the calibration harness.
If cookbooks aren't open to outside contributions, a pointer to the right channel (or just a "not this shape") is all I need.
Activity
aoright commentedon Sep 24, 2026
This is a compelling pattern that highlights the exact strengths of System One models over generative LLM judges for agent safety gates.
Key Strengths of the Approach
Eliminating the Reasoning Model Token-Budget Failure Mode:
Generative reasoning models frequently exhaust tight token budgets on chain-of-thought before emitting their verdict, returning
finish_reason="length"with empty content. In contrast, Jev evaluates the 3-wayChoicedirectly on the prefill forward pass in ~180ms, eliminating output truncation risk.Fail-Closed Verification Semantics:
Your invariant that
denyandescalatecan never auto-approve regardless of threshold is the correct system boundary. Tuning confidence thresholds (p >= 0.65,margin >= 0.30) modulates human interaction frequency without compromising security invariants.Operational vs. Entity-Noun Criteria Formulation:
Your observation regarding "altering credentials vs inspecting credentials" touches on a fundamental question-engineering insight for System One: bounding the action semantic rather than matching lexical entities prevents false-positive escalation cascades on routine reads.
Suggested Cookbook / Skill Integration Structure
A dedicated recipe in the docs/cookbooks (e.g.,
cookbooks/agent_command_guardian.md) would be very valuable:command,working_directory,agent_intent, andrecent_tool_history.approve: Routine, read-only, non-destructive development commands within workspace scope.deny: Destructive, network-exfiltrating, or security-weakening commands outside acceptable bounds.escalate: Ambiguous commands, credential modifications, or operations outside sandbox scope requiring human review.p(approve) >= tau_approveandp(approve) - p_runner_up >= tau_margin) falling back to human escalation on any exception, timeout, or ambiguity.approval-judge-bridgetranslates OpenAI chat completion requests into fast System One decisions for seamless agent integration.