Try it
Copy the code ↓- Data source
- Decision schema
- Model inference
- Structured result
2 Decision schema 4 typed questions
verdictchoiceconfirmedlikelyunverifiedfalse_positiveseverityscoreinfolowmediumhighcriticalprunenoulprobability 0–1needs_retestnoulprobability 0–1
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": "Finding: Reflected XSS in /search?q= on staging.example.com. Payload <script>alert(1)</script> is returned unescaped in the HTML response; no Content-Security-Policy header. Agent self-rating: Critical. Scope: *.example.com including staging. Evidence: request/response pair and screenshot of the alert.",
"questions": {
"verdict": {
"type": "choice",
"instructions": "Adjudicate: does the evidence show the vulnerability is real?",
"criteria": {
"confirmed": "The evidence directly demonstrates exploitation or the vulnerable behavior",
"likely": "Strong indicators, but no direct proof of impact",
"unverified": "A claim or scanner signature without supporting evidence",
"false_positive": "The evidence contradicts the claim or shows expected behavior"
}
},
"severity": {
"type": "score",
"instructions": "Re-grade: severity based on the evidence and scope, ignoring the finder'\''s own rating.",
"criteria": [
"info",
"low",
"medium",
"high",
"critical"
]
},
"prune": {
"type": "noul",
"instructions": "Prune: this finding duplicates another, is out of scope, or is a scanner artifact."
},
"needs_retest": {
"type": "noul",
"instructions": "Confirm: a human should re-run the proof of concept before this reaches the report."
}
}
}'// Node.js 18+ (built-in fetch). Run: FLATKEY_API_KEY=... node jev.mjs
const body = {
"model": "typesafe/jev-1.13",
"state": "Finding: Reflected XSS in /search?q= on staging.example.com. Payload <script>alert(1)</script> is returned unescaped in the HTML response; no Content-Security-Policy header. Agent self-rating: Critical. Scope: *.example.com including staging. Evidence: request/response pair and screenshot of the alert.",
"questions": {
"verdict": {
"type": "choice",
"instructions": "Adjudicate: does the evidence show the vulnerability is real?",
"criteria": {
"confirmed": "The evidence directly demonstrates exploitation or the vulnerable behavior",
"likely": "Strong indicators, but no direct proof of impact",
"unverified": "A claim or scanner signature without supporting evidence",
"false_positive": "The evidence contradicts the claim or shows expected behavior"
}
},
"severity": {
"type": "score",
"instructions": "Re-grade: severity based on the evidence and scope, ignoring the finder's own rating.",
"criteria": [
"info",
"low",
"medium",
"high",
"critical"
]
},
"prune": {
"type": "noul",
"instructions": "Prune: this finding duplicates another, is out of scope, or is a scanner artifact."
},
"needs_retest": {
"type": "noul",
"instructions": "Confirm: a human should re-run the proof of concept before this reaches the report."
}
}
};
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": "Finding: Reflected XSS in /search?q= on staging.example.com. Payload <script>alert(1)</script> is returned unescaped in the HTML response; no Content-Security-Policy header. Agent self-rating: Critical. Scope: *.example.com including staging. Evidence: request/response pair and screenshot of the alert.",
"questions": {
"verdict": {
"type": "choice",
"instructions": "Adjudicate: does the evidence show the vulnerability is real?",
"criteria": {
"confirmed": "The evidence directly demonstrates exploitation or the vulnerable behavior",
"likely": "Strong indicators, but no direct proof of impact",
"unverified": "A claim or scanner signature without supporting evidence",
"false_positive": "The evidence contradicts the claim or shows expected behavior"
}
},
"severity": {
"type": "score",
"instructions": "Re-grade: severity based on the evidence and scope, ignoring the finder's own rating.",
"criteria": [
"info",
"low",
"medium",
"high",
"critical"
]
},
"prune": {
"type": "noul",
"instructions": "Prune: this finding duplicates another, is out of scope, or is a scanner artifact."
},
"needs_retest": {
"type": "noul",
"instructions": "Confirm: a human should re-run the proof of concept before this reaches the report."
}
}
}""")
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
- security teams running autonomous or AI-assisted pentest agents
- consultancies that need clean, defensible client reports
- bug-bounty and vulnerability-management triage teams
Triggers
- a pentest agent emits a finding with its own self-rated severity
- scanner output floods the draft report with duplicates and artifacts
- a finding is about to be sent to a client or filed as a ticket
- you want a reviewer that is not the model that found the issue
The workflow
- 01Finding stateEvidence, scope and self-ratingInput
- 02Adjudicateconfirmed / likely / unverified / false positiveJev
- 03Re-grade + pruneSeverity score, duplicate or out-of-scope flagJev
- 04Confirm gateReport, retest or dropYour code
Question shape
{
"verdict": {
"type": "choice",
"instructions": "Adjudicate: does the evidence show the vulnerability is real?",
"criteria": {
"confirmed": "The evidence directly demonstrates exploitation or the vulnerable behavior",
"likely": "Strong indicators, but no direct proof of impact",
"unverified": "A claim or scanner signature without supporting evidence",
"false_positive": "The evidence contradicts the claim or shows expected behavior"
}
},
"severity": {
"type": "score",
"instructions": "Re-grade: severity based on the evidence and scope, ignoring the finder's own rating.",
"criteria": [
"info",
"low",
"medium",
"high",
"critical"
]
},
"prune": {
"type": "noul",
"instructions": "Prune: this finding duplicates another, is out of scope, or is a scanner artifact."
},
"needs_retest": {
"type": "noul",
"instructions": "Confirm: a human should re-run the proof of concept before this reaches the report."
}
}Gate policy
≥ 0.90
Add to the draft report at the re-graded severity.
0.65–0.90
Hold in review: a tester confirms the evidence and severity before release.
< 0.65
Drop from the report or send back to the agent for more evidence.
Failure modes
Pre-launch checks before you trust auto-routing:
- Self-rated severities that anchor the re-grade (keep them out of the question wording);
- Findings whose evidence is only a scanner signature or version banner;
- Scope edge cases: staging hosts, third-party assets, wildcard domains;
- Prompt injection in captured responses, headers or page content;
- Near-duplicates across hosts or parameters that should be merged, not pruned;
FAQ
Why not let the pentest agent rate its own findings?
Because the finder is biased toward its own result. Dark Factor's summary of four production papers (post below) puts it as "never let the finder grade its own finding": every result passes four typed gates, adjudicate, re-grade, prune and confirm, before it reaches the report. This page maps those four gates to one Choice, one Score and two Noul questions.
How is this different from general agent decision gates?
Agent decision gates control the loop: retry, escalate, call a tool, continue. These gates control output quality: they decide what a security report is allowed to claim. Many teams run both.
Can Jev replace a human reviewer?
No. It cuts the review queue by clearing obvious false positives and duplicates and flagging what needs a retest. Anything client-facing below your high band should still be confirmed by a tester.
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
4 papers just showed how to use Jev in 4 completely different production systems … this is a 7-step blueprint on how to move judgment off the LLM and make any AI system faster, cheaper and easier to audit … step 7 → never let the finder grade its own finding: in pentest agents every result passes four typed gates (adjudicate, re-grade, prune, confirm) before it reaches the report
— @DarkFactorr View the post on X →
Wire this gate with your own key
Bring your own key through Flatkey / OpenRouter. Keep exact checks in code.