The permission question in a coding agent is rarely "may this user run this?" Native permission systems already answer that. The harder question is whether the specific command in front of the agent is something the user actually asked for, in this repository, at this moment. Claude Code, Codex, and OpenCode each expose a different seam for that judgment, and the integrations built on those seams behave differently when the judgment fails.
Three different seams
| Agent | Where the judgment attaches | Catalog integration | Verdicts | Failure posture |
|---|---|---|---|---|
| Claude Code | Event hooks around tool use | Jev Plugin for Claude Code | Allow, deny, or no change | Fails safe: changes nothing when Jev is unsure or offline |
| OpenCode | Permission prompt via a plugin | jev-guard (OpenCode) | Run or ask | Fails to ask when Jev is unreachable or unkeyed |
| Codex | Model and reasoning selection | jev-codex-bridge | Pick a model-and-effort pair | Keeps the current eligible pair when Jev is unreachable |
The Codex row surprises people: its dedicated integration routes model and effort, and does not decide whether a shell command may run. Permission gating for Codex CLI comes from a separate tool, jev-guard, which also supports Claude Code and Antigravity.
Claude Code: thresholds inside a hook
Jev Plugin for Claude Code asks Jev at six points: four event hooks and two routing decisions. Each call takes about a second and costs a fraction of a cent, by the README's numbers. The permission hook allows a Bash call when the safe score is at least 0.9 and the destructive score at most 0.1, or when the on-task score is at least 0.9. It denies when the destructive score is at least 0.9, and it never auto-approves a static dangerous list that includes deletions, pushes, sudo, deploys, and secrets. A PostToolUse hook watches WebFetch, WebSearch, MCP, and downloading Bash commands, and at 0.8 or above warns that fetched content addresses the agent. WebFetch and MCP calls can be allowed when clearly read-only but are never denied, because an MCP request carries no statement of what the user asked for.
That is a defensible default for a hook that adds convenience rather than replacing a boundary. It is also young: the catalog notes an MIT license, zero stars, a README that stops mid-row in the permission table, and no captured install or key-setup instructions. The thresholds are documented behavior, not an independent evaluation.
OpenCode: six questions and a stricter default
jev-guard (OpenCode) sends every shell command to Jev first, including FarHand's remote shell commands. It asks six typed questions per command: verdict, host_litter, global_install, global_config, harmful, and privacy. A command is safe only if the verdict is run with confidence at or above minConfidence and every risk is below its own threshold. Anything else asks in OpenCode.
The failure posture is the opposite of the Claude plugin's no-op. If Jev cannot be reached, times out, or no API key is set, the command asks. The guard only ever adds prompts; it never turns a prompt that the user's OpenCode or FarHand settings would ask for into an allow. Categories live in jev-guard.jsonc, edits apply on the next command without a restart, and project-local config may only make the guard stricter.
The cost is friction: an API outage becomes a permission prompt, not a silent allow. OpenCode 2.0.14 does not show the reason, so a flagged command puts a one-line note in the transcript.
Codex: routing is not permission
The Codex bridge picks the model and reasoning effort for Codex Desktop and CLI sessions from task history and tool results, reassessing when new instructions or evidence arrive. It reuses the existing Codex login. When Jev is unreachable mid-session, it keeps the current eligible pair or the initial fallback and continues working; $jev-explain shows the decision details stored locally.
Routing text and model metadata go to TypeSafe, while the Codex conversation goes to OpenAI. The bridge needs Node.js 24+, Git, Codex, and a TypeSafe key; it is a routing integration, not a permission system.
For Codex permission checks, jev-guard is the closer fit. It returns ALLOW, ASK, or DENY; local fast-path rules decide credential files, workspace escapes, and trusted read-only commands in under a millisecond, while ambiguous or destructive calls go to the model. It fails safe by asking when the API is unreachable, and audit mode logs what would have been blocked. The README publishes no independent benchmarks, so treat the fast-path figure as the project's own framing.
The question permissions cannot answer
Identity permissions and intent checks are different layers. jev-agent-authorization makes that concrete: it verifies Kinde tokens, permissions, and flags before any Jev call or workspace write, then sends the call, the request, and the read documents to Jev for signals covering match, destructiveness, planted-text following, exfiltration, and risk. Policy code (not model prose) decides allow, step-up approval, or deny, and every decision is written to a ledger first.
Its reported benchmark is striking but author-labeled: over 300 labeled calls run three times each, Jev signals plus policy code produced a 0.0% false-allow rate at 83.7% accuracy, against 12.4% for a single Jev verdict and 7.9% for an LLM judge. The same run reports 205 ms and $0.029 per 1,000 calls for the Jev path, versus 2,073 ms and $0.931 for the judge. The labels are author-written; remeasure before quoting. A destructive call that needs a human is held for 10 minutes and runs once after approval on a page requiring fresh sign-in. The model supplies signals, and code supplies the irreversible part.
Rules first, model second
The strongest permission designs put deterministic rules ahead of the model. pi-automode-classifier parses shell commands, including $(...), bash -c strings, and sudo or timeout wrappers, and returns run, confirm, or block. Hosted Jev is opt-in; Kev and Laya run locally on CPU with no GPU. It is not a sandbox: it guards the agent's tool calls, not commands you type, and extensions run with your permissions.
jev-tool-permissions applies the same shape to the Vercel AI SDK. Both the pre-flight approval gate and tool-list pruning sit on a deterministic allow/deny floor that never calls the model; deny rules are checked before anything reaches Jev. If the Jev call errors or times out, the gate defaults to ask-human and pruning keeps every tool definition. The README prices Jev at roughly $0.04 per 1M input tokens and argues an LLM judge would cost more than the call it gates; that is the README's own claim, and the repository lists no license.
Finally, context for the agent is not a runtime control. Agent Skill teaches Claude Code, Codex, and other agents how to structure states and questions, but it is guidance, and a stale copy can make the agent invent fields. Jev with Coding Agents says the same from the vendor side: there is no model: jev-latest setting for these agents, so the integration has to be a hook, a plugin, or a policy layer.
What to compare
- Read the seam, not the logo: a hook, a permission prompt, and a router enforce different things.
- Read the failure posture: no-op, ask, and keep-the-fallback differ under an outage.
- Keep a deterministic floor for denials and a human path for irreversible actions.
The pattern is consistent: the model judges, code decides, and the permission system remains the boundary. For policy, see approval policies for coding agents; for gate design, Jev in Coding Agents; for the attack surface, guardrails and prompt injection. The coding agent entry covers where a guardrail belongs, and fail-closed is safer until your own numbers say otherwise.