Guardrails for Claude Code, decided by Jev.One mod that blocks destructive commands, catches prompt injection, pushes back on an unverified “done” and routes effort per turn.
Claude Code 2.1.287+Decided by JevMIT license
export TYPESAFE_API_KEY=ts_...shell profile/plugin install ohmyjev --marketplace Novacon/ohmyjevclaude code/jevclaude codeIf /jev ends with key: env TYPESAFE_API_KEY · typesafe · jev-1.13.0, you're set.
01 / What you get 10 features
what you get
Jev is TypeSafe's decision model. It answers typed questions with probabilities in about 300 ms for a fraction of a cent, cheap enough to ask about every command your agent runs. ohmyjev does, as in-process hooks with no server.
Bash gate
Denies a command Jev rates irreversible at 0.6+ or destructive at 0.7+.
bashGate
Write gate
Denies writes outside the repo and allowPaths, or with a real credential in them. The path check is plain code and follows symlinks like the OS.
writeGate
Exfil gate
Denies a WebFetch or MCP call Jev rates 0.7+ for sending your data, files or credentials out.
exfilGate
Policies
Every gate also checks the call against your own plain-English rules.
policies
Injection screen
Output from Bash, WebFetch, MCP or an outside Read that talks to the model gets a “treat as data” note.
injectionScreen
Done-check
Says it's done with no sign of a check? It blocks the stop once and tells the agent to verify.
doneCheck
Router
One Jev call per request for tier, effort and risk. Sets effort and picks the model for general-purpose subagents.
routeEffort, routeSubagents
Auto-compact
Task changed and context at least 40% full? It compacts, keeping the new request in full.
autoCompact
ask_jev
Lets the model ask Jev about repo files or text without loading them into its own context.
askJev
/jev
This session's calls, errors, cost, median latency, denies and key source. Never prints the key.
slash command
02 / How it decides One tool call
how it decides
Every tool call gets one quick question to Jev. Only a clear risk gets denied. Anything else goes on to Claude Code's normal permission flow, the same as without ohmyjev.
01 ohmyjev asks Jev ~300 ms
02 The output comes back
ohmyjev blocked this: irreversible (0.95): nothing would restore what this removes or overwrites.
This block is final. Do not try to work around it with another command, another tool, a different path, or an encoding that does the same thing. Stop and tell the user what was blocked and why.Fails open, never nags
Middling answers, a slow or down Jev, a missing key and any error inside ohmyjev all fall through to the normal flow. It never asks you to approve anything, so bypass-mode agents run fine.
Jev can be wrong, so keep your deny rules in settings.json.
03 / Install 4 steps
install it
You need a Jev key: a TypeSafe key, or an OpenRouter key if you'd rather go through OpenRouter. Everything else happens inside Claude Code.
STEP 1
Check your version
Mods are still early access, so you need Claude Code 2.1.287 or later.
claude --version
STEP 2
Install the plugin
Answer y to add the marketplace and pick a scope; user scope covers every session. The hooks run right away, no restart.
/plugin install ohmyjev --marketplace Novacon/ohmyjevSTEP 3
Add your key
- The settings screen during install (kept in secure storage)
TYPESAFE_API_KEYOPENROUTER_API_KEY, as~typesafe/jev-latest
export TYPESAFE_API_KEY=ts_...
STEP 4
Check it works
Run /jev. The last line says where the key came from. key: none means every gate stays open.
key: env TYPESAFE_API_KEY · typesafe · jev-1.13.0jev ⚠ no key
Set TYPESAFE_API_KEY in the shell that starts Claude Code, or run claude plugin configure ohmyjev@ohmyjev.
jev ⚠ down
A Jev call failed or took over 1.5 s in the last 5 minutes. Gates let calls through until Jev answers again.
Blocked by mistake
/jev shows the reason. Raise that gate's threshold in /config, or turn it off. Local MCP tools can trip exfilGate.
Nothing happens
Run claude --debug. A failing hook leaves a line naming it and the reason.
04 / In use /jev · ask_jev · statusline · policies
in use
Most of the time you won't notice it. /jev and the statusline show what it's doing, ask_jev spares the model a pile of reads, and policies adds your own plain-English rules to every gate.
/jev
this session, any timejev ✓23 ⛔1 ↑opus/high calls 23 · errors 0 · cost $0.000966 · p50 310ms denies: Bash 1 Bash: irreversible (0.95): nothing would restore what this removes or overwrites key: env TYPESAFE_API_KEY · typesafe · jev-1.13.0
ask_jev
repo files only · 8000 chars each · 80000 total{ "question": "Which of these files handles session login?",
"type": "choice",
"options": ["src/auth.ts", "src/session.ts", "src/routes.ts"],
"files": ["src/auth.ts", "src/session.ts", "src/routes.ts"] }Statusline
copy jev_segment() ↗jev ✓23 ⛔1 ↑opus/high 🗜2 calls, denies, route, compactions jev ⚠ down Jev failing, gates let calls through jev ⚠ no key no key configured
Your own rules
policies setting · separated by ;never touch the prod cluster; no deploys on Friday; don't edit migrations that already ran
05 / Settings /config
tune it
Every setting except the key is a row in /config. Gate thresholds are settings too, defaulting to the numbers in What you get.
| Setting | Default | What it changes |
|---|---|---|
bashGate, writeGate, exfilGate | on | Turns each gate on or off. |
injectionScreen, screenReads | on | Screens tool output, including Reads from outside the repo. |
doneCheck | on | Pushes back on an unverified “done”. |
routeEffort, routeSubagents | on | Lets the router change effort and the subagent model. |
routeMainModel | off | Also switches the main model. Off because that throws away the prompt cache. |
autoCompact | on | Compacts on a task change once the context is compactMinPercent (40) full. |
askJev | on | Gives the model the ask_jev tool. |
policies | empty | Your own rules, separated by ;. |
allowPaths | ~/.claude;$TMPDIR;/tmp | Writable places outside the repo. Entries with .. are ignored. |
fastModel, balancedModel, deepModel | claude-{haiku,sonnet,opus}-5-5 | The model id for each router tier. |
jevModel | jev-1.13.0 | The Jev model asked through TypeSafe. |
Logs
One line per decision in ~/.ohmyjev/log/<session>.jsonl, readable only by you. Verdicts, probabilities, latency and cost; never command output.
Update or remove
claude plugin update ohmyjev@ohmyjev claude plugin uninstall ohmyjev@ohmyjev
Restart Claude Code after an update.
Develop
The decision logic in hooks/policy.ts is pure and tested with plain tables. Rubrics from disler/ten-levels-of-jev.