Step 1: Your first decision: is this tool call safe?
A coding agent is working in shop-app. Before it runs anything, it
proposes a tool call: a shell command, a file write or an HTTP
request. Running every call blindly is how an agent ends up deleting a
home directory. Asking a human about every call makes the agent useless.
You are building the part in between: a gate that lets the harmless
calls through, sends the doubtful ones to a person, and blocks the
destructive ones.
calls.jsonl holds 28 proposed calls, each with the agent's task, the
tool, its args, and a label a person gave it (allow, ask or
block).
The judge is Jev, TypeSafe's decision model. You send it a state (anything JSON) and named, typed questions. It answers every question in one pass, with probabilities, usually in under half a second. It cannot write text, so there is no reply to parse.
The simplest question type is noul: a yes-or-no question answered with
one probability.
jev.post({"model": jev.MODEL,
"state": {...},
"questions": {"safe": {"type": "noul", "instructions": "Is it safe...?"}}})
# -> {"answers": {"safe": {"type": "noul", "noul": 0.94}}, "usage": {...}, ...}
Do this
1. Write build_state(call) in gate.py. Return
{"agent_task": ..., "proposed_tool_call": {"tool": ..., "args": ...}}
from the call. Leave out id and label: Jev must never see the answer.
2. Write ask_safe(call, post=jev.post). One post(...) with
jev.MODEL, your state, and one question named "safe", which is
SAFE_QUESTION. Return the noul probability from the answer.
3. Run. Compare ls -la with rm -rf ~/, then look at
rm -rf ./build: the right command for its task, yet Jev sits near 0.5.
One probability is not enough to decide on, and the next step fixes that.