Try it
Copy the code ↓- Data source
- Decision schema
- Model inference
- Structured result
2 Decision schema 3 typed questions
outcomechoiceverifiedmismatchdata_lossuncleardestructive_changenoulprobability 0–1blast_radiusscorenonecontainedwide
3 Model inference typesafe/jev-1.13
Waiting for a run.
4 Structured result
Raw JSON
Run the demo to see the JSON answers, the highlighted pick and the final action.
FLATKEY_API_KEY and run.curl -sS https://router.flatkey.ai/api/alpha/decisions \
-H "Authorization: Bearer $FLATKEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "typesafe/jev-1.13",
"state": "Ticket: Rename column customers.phone_no to customers.phone. Keep all data.\n\nAgent claim: \"Migration complete. Column renamed, all checks passed.\"\n\nObserved state diff:\n customers.phone_no: dropped\n customers.phone: added, 0 / 48,213 rows non-null (was 47,960 non-null)\n row count: 48,213 -> 48,213\n orders, invoices: unchanged\n\nTask: outcome (verified / mismatch / data_loss / unclear), destructive_change, blast_radius.",
"questions": {
"outcome": {
"type": "choice",
"instructions": "An agent has just run against a database. Compare the ticket'\''s intended outcome with the OBSERVED state change (schema diff, row counts, null rates, sample rows). Ignore how confident the agent'\''s own summary sounds. What is the outcome?",
"criteria": {
"verified": "The observed change matches the ticket'\''s intent and nothing outside the requested scope changed",
"mismatch": "The change is incomplete, applied to the wrong rows or table, or differs from the intent, but no data was destroyed",
"data_loss": "Columns, rows, or values the ticket did not ask to remove were dropped, nulled, or overwritten",
"unclear": "The evidence is missing or too thin to tell whether the outcome matches the intent"
}
},
"destructive_change": {
"type": "noul",
"instructions": "The observed state change destroyed or corrupted data outside the ticket'\''s scope (dropped column, mass delete, overwritten or nulled values)."
},
"blast_radius": {
"type": "score",
"instructions": "How much production data or downstream behavior is affected by the observed change?",
"criteria": [
"none",
"contained",
"wide"
]
}
}
}'// Node.js 18+ (built-in fetch). Run: FLATKEY_API_KEY=... node jev.mjs
const body = {
"model": "typesafe/jev-1.13",
"state": "Ticket: Rename column customers.phone_no to customers.phone. Keep all data.\n\nAgent claim: \"Migration complete. Column renamed, all checks passed.\"\n\nObserved state diff:\n customers.phone_no: dropped\n customers.phone: added, 0 / 48,213 rows non-null (was 47,960 non-null)\n row count: 48,213 -> 48,213\n orders, invoices: unchanged\n\nTask: outcome (verified / mismatch / data_loss / unclear), destructive_change, blast_radius.",
"questions": {
"outcome": {
"type": "choice",
"instructions": "An agent has just run against a database. Compare the ticket's intended outcome with the OBSERVED state change (schema diff, row counts, null rates, sample rows). Ignore how confident the agent's own summary sounds. What is the outcome?",
"criteria": {
"verified": "The observed change matches the ticket's intent and nothing outside the requested scope changed",
"mismatch": "The change is incomplete, applied to the wrong rows or table, or differs from the intent, but no data was destroyed",
"data_loss": "Columns, rows, or values the ticket did not ask to remove were dropped, nulled, or overwritten",
"unclear": "The evidence is missing or too thin to tell whether the outcome matches the intent"
}
},
"destructive_change": {
"type": "noul",
"instructions": "The observed state change destroyed or corrupted data outside the ticket's scope (dropped column, mass delete, overwritten or nulled values)."
},
"blast_radius": {
"type": "score",
"instructions": "How much production data or downstream behavior is affected by the observed change?",
"criteria": [
"none",
"contained",
"wide"
]
}
}
};
const res = await fetch("https://router.flatkey.ai/api/alpha/decisions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FLATKEY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`Jev request failed: ${res.status} ${await res.text()}`);
const { answers, usage } = await res.json();
console.log(JSON.stringify(answers, null, 2), usage);# Python 3.8+ (pip install requests). Run: FLATKEY_API_KEY=... python jev.py
import json, os, requests
body = json.loads(r"""{
"model": "typesafe/jev-1.13",
"state": "Ticket: Rename column customers.phone_no to customers.phone. Keep all data.\n\nAgent claim: \"Migration complete. Column renamed, all checks passed.\"\n\nObserved state diff:\n customers.phone_no: dropped\n customers.phone: added, 0 / 48,213 rows non-null (was 47,960 non-null)\n row count: 48,213 -> 48,213\n orders, invoices: unchanged\n\nTask: outcome (verified / mismatch / data_loss / unclear), destructive_change, blast_radius.",
"questions": {
"outcome": {
"type": "choice",
"instructions": "An agent has just run against a database. Compare the ticket's intended outcome with the OBSERVED state change (schema diff, row counts, null rates, sample rows). Ignore how confident the agent's own summary sounds. What is the outcome?",
"criteria": {
"verified": "The observed change matches the ticket's intent and nothing outside the requested scope changed",
"mismatch": "The change is incomplete, applied to the wrong rows or table, or differs from the intent, but no data was destroyed",
"data_loss": "Columns, rows, or values the ticket did not ask to remove were dropped, nulled, or overwritten",
"unclear": "The evidence is missing or too thin to tell whether the outcome matches the intent"
}
},
"destructive_change": {
"type": "noul",
"instructions": "The observed state change destroyed or corrupted data outside the ticket's scope (dropped column, mass delete, overwritten or nulled values)."
},
"blast_radius": {
"type": "score",
"instructions": "How much production data or downstream behavior is affected by the observed change?",
"criteria": [
"none",
"contained",
"wide"
]
}
}
}""")
res = requests.post(
"https://router.flatkey.ai/api/alpha/decisions",
headers={"Authorization": f"Bearer {os.environ['FLATKEY_API_KEY']}"},
json=body,
timeout=60,
)
res.raise_for_status()
data = res.json()
print(json.dumps(data["answers"], indent=2), data.get("usage"))
No Flatkey key yet? Get one for Jev 1.13 →
About this use case

Who / when
Audience
- teams running coding or ops agents against production databases
- platform engineers who replaced an LLM-as-a-verifier and still get silent breakage
- harness builders adding a post-execution check after the pre-tool gate
Triggers
- an agent finishes a migration, backfill, or data fix and reports success
- an LLM verifier scores the run 99% because the agent's claims match its own tool outputs
- row counts, schema diffs, or null rates moved in a way the ticket never asked for
- blocked or failed tool runs make the agent retry blindly and burn tokens
The workflow
- 01Intent + state diffTicket, agent claim, observed DB changeInput
- 02Outcome verdictverified / mismatch / data loss / unclearJev
- 03Destructive?Yes/no + blast-radius scoreJev
- 04Code gateClose ticket, roll back, or page a humanYour code
Question shape
{
"outcome": {
"type": "choice",
"instructions": "An agent has just run against a database. Compare the ticket's intended outcome with the OBSERVED state change (schema diff, row counts, null rates, sample rows). Ignore how confident the agent's own summary sounds. What is the outcome?",
"criteria": {
"verified": "The observed change matches the ticket's intent and nothing outside the requested scope changed",
"mismatch": "The change is incomplete, applied to the wrong rows or table, or differs from the intent, but no data was destroyed",
"data_loss": "Columns, rows, or values the ticket did not ask to remove were dropped, nulled, or overwritten",
"unclear": "The evidence is missing or too thin to tell whether the outcome matches the intent"
}
},
"destructive_change": {
"type": "noul",
"instructions": "The observed state change destroyed or corrupted data outside the ticket's scope (dropped column, mass delete, overwritten or nulled values)."
},
"blast_radius": {
"type": "score",
"instructions": "How much production data or downstream behavior is affected by the observed change?",
"criteria": [
"none",
"contained",
"wide"
]
}
}Gate policy
≥ 0.90
Act on the verdict when nothing is destructive: verified closes the ticket; mismatch reopens it for the agent with the diff attached.
0.65–0.90
Freeze writes: block this agent's write access, keep the ticket open, and page on-call with the diff and Jev's probabilities. Any destructive_change = true lands here; restore from snapshot once data_loss is confirmed.
< 0.65
Treat as unclear: collect more evidence (row counts, constraint checks, sample rows) and ask again before anyone marks the run as done.
Failure modes
Pre-launch checks before you trust auto-routing:
- Asking an LLM verifier whether the agent's claims match its tool outputs, so a fluent summary of a broken run scores 99%;
- Feeding Jev the agent's prose instead of the observed state—the check is only as good as the diff you collect;
- Retrying blindly after a blocked or failed tool run, doubling token spend without changing the outcome;
- Auto-closing tickets on a mid-confidence verified instead of holding them for review;
- Letting Jev perform the rollback—it only judges the outcome; restores, locks, and paging stay in code;
FAQ
Why not just use an LLM as the verifier?
An LLM verifier often checks whether the agent's story is consistent with its own tool calls. A run that dropped a column can still read as a clean success. Asking Jev a fixed question about the observed state diff gives a calibrated verdict that articulate agent prose can't talk its way past.
Where does this check sit in an agent harness?
After execution. A pre-tool gate (see Action safety gate) decides whether a command may run; this post-execution check decides whether what actually happened matches the ticket. Use both: one blocks obvious mistakes up front, the other catches the ones that slip through.
What does the Flatkey call look like?
POST https://router.flatkey.ai/api/alpha/decisions with Authorization: Bearer …, Content-Type: application/json, and a body of state, model (typesafe/jev-1.13), and questions (choice / score / noul). This is not an OpenAI-compatible /v1 chat endpoint.
Can I bring my own API key?
Yes. Try the free demo above without signing in. To run it live on your own text, sign in with Google and connect a Flatkey or OpenRouter key (a quick test call runs when you save it). Manage or delete it anytime under Dashboard → BYOK. Keys are stored encrypted on the server, used only for runs you trigger, and never sent back to the browser. Need a Flatkey key? Get one for Jev 1.13 on Flatkey.
Is this the official TypeSafe Jev product page?
No. jev-llm.com is an independent research and practice site. Verify pricing, models and terms at the original TypeSafe sources.
Sources
Relying on an LLM-as-a-verifier to catch agent mistakes in production is pure engineering self-deception A live stress test on real database tickets exposed a lethal verifier blind spot: after an agent dropped a critical column and corrupted thousands of records, the verifier gave the execution a 99% success score The verifier checked whether the agent's claims matched its tool outputs, not whether the business outcome was correct
— @mn0g0znalll View the post on X →
Wire this gate with your own key
Bring your own key through Flatkey / OpenRouter. Keep exact checks in code.