Security and compliance teams make a lot of small judgment calls: does this log line contain personal data, should this invoice be paid, is this scanner finding real. Rules catch the exact cases; the rest end up in a queue. This page covers PII detection, payment fraud gates and security triage, and how typed Jev decisions can sit next to exact checks to shrink those queues without hiding risk.
The problem
Three patterns recur:
- Sensitive data in the wrong place. Personal data in logs, prompts, analytics events or public repos. Formats like card numbers are easy; "my daughter's appointment at the oncology clinic on Elm Street" is not.
- Money leaving the company. Accounts payable fraud often looks routine: a vendor's bank details change, a duplicate invoice is resubmitted with a new number, an amount sits just under an approval limit.
- Findings that may not be real. Automated scanners produce many findings, a large share of which are false positives. Engineers lose trust and real issues get ignored.
In each case the cost of a miss is high and the volume is too large for humans to read everything.
Common approaches and trade-offs
Exact rules. Regexes with checksums for IDs, duplicate detection, three-way PO matching, allow-lists. Fast, explainable and required by many controls — but blind to context.
Specialised classifiers and NER models. Good at standard entity types, weaker on organisation-specific policy ("internal project names are confidential").
Prompted LLMs. Understand context, but produce free text, cost a full generative call, and can be talked into ignoring instructions by the very content they inspect.
Manual review. Accurate and auditable, but slow and expensive, and reviewers fatigue on long queues of benign items.
How Jev's typed decisions fit
Jev, from TypeSafe AI, answers typed questions about a state you provide:
- Noul returns a probability from 0 to 1 for a yes/no question —
contains_health_data,bank_details_changed_suspiciously,finding_is_true_positive. - Score places risk or severity on an ordered scale of 2 to 10 levels described in words.
- Choice picks the action —
pay,verify_vendor,human_review,reject— from up to 255 options.
The answer is always inside the schema, which matters for controls: there is no ambiguous text for a downstream system to interpret. TypeSafe reports 70–500 ms per request and Jev 1.13 is priced at $0.042 per million input tokens on Flatkey with free output, so screening every log batch, invoice or finding is affordable.
Design pattern: exact checks, then typed judgment, then enforcement
- Exact checks in code. Run regexes, duplicate and PO matching, vendor master lookups. Record each result as a fact.
- Build the state. Include the facts from step 1 plus the minimal text needed for judgment. Redact what does not need to be seen.
- Ask Jev. Action Choice, risk Score, needs_human Noul.
- Enforce with policy. Any failed exact check overrides the model. High risk or low confidence goes to a human. Only low-risk, high-confidence, rule-clean items pass automatically.
- Audit trail. Store facts, answers, thresholds and the final action. Auditors care about why a payment went through.
See AP invoice fraud gate, pentest finding validation and semantic PII lint for complete schemas.
Mapping controls to question types
| Check | Exact rule first | Jev question |
|---|---|---|
| Card or national ID in text | Regex + checksum | — (rule is enough) |
| Health, financial or location details in prose | — | Noul per data class |
| Exposure severity | — | Score, e.g. internal → customer_visible → public |
| Invoice action | Duplicate, PO match, bank change | Choice: pay / verify_vendor / human_review / reject |
| Fraud risk | Amount vs limits | Score on an ordered scale |
| Scanner finding real | Known false-positive signatures | Noul: true positive |
The table makes the division of labour explicit. Where a rule is exact, the rule decides and the model is not asked. Where the judgment depends on context, Jev answers a narrow, typed question and the policy layer combines that answer with the facts the rules established.
For a PII lint in CI, run it on diffs rather than whole repositories, and fail the build only above a high probability while posting lower-probability hits as review comments. That keeps developers from learning to ignore the check.
Pitfalls and evaluation tips
- Never let the model override a failed control. The model adds judgment on top of rules, not instead of them.
- Adversarial input. Invoices, emails and logs can contain text aimed at the model. Keep the question schema fixed and treat content strictly as state.
- Measure misses separately. For fraud and PII, a false negative is usually far worse than a false positive. Report recall on a labelled set, not just accuracy.
- Data minimisation. Sending less is cheaper and safer. Check your provider and gateway terms before sending regulated data.
- Thresholds per severity. A suspected card number in a public repo deserves a lower bar than a first name in an internal log.
When not to use Jev
Do not use a model where a deterministic control is required by policy or regulation. Do not use it to make final legal or employment decisions about people. And do not send data you are not permitted to share with a third-party API.
Glossary
- PII: personally identifiable information.
- Three-way match: checking an invoice against the purchase order and the goods receipt.
- False positive: a flagged item that is actually fine.
- Recall: the share of real problems that were caught.
- Control: a required check, often audited, that must run before an action.
Choose a use case below for the full schema, a live demo and copyable code.
Security & Compliance use cases
Finance / APDecide pay / verify vendor / human review / reject for each AP invoice before money moves
Gate every accounts payable invoice and payment with a typed Jev decision—pay / verify_vendor / human_review / reject—plus a fraud-risk Score and needs_human Noul, so duplicates, PO mismatches and vendor bank-detail changes never auto-pay.
See the workflow →
SecurityValidate pentest agent findings
Pass every finding from a pentest agent through four typed gates (adjudicate, re-grade, prune, confirm) before it reaches the report, so the finder never grades its own work.
See the workflow →
CI / Semantic lintDecide pass / warn / fail / needs review for each changed line against meaning-level lint rules like "never log PII"
ESLint catches syntax, not meaning. Write lint rules as English yes/no questions—"does this change log PII?"—and let Jev return calibrated probabilities per file, line and rule: pass / warn / fail / needs_review, plus a PII severity Score, so CI blocks real leaks and stays quiet on safe logging.
See the workflow →
Safety · also fitsGate every agent action with an independent allow / block / review call
Put an independent cheap Choice allow / block / review gate before every agent action—plus a Score for injection risk and a Noul for needs_human—so safety is not bound only inside the main model prompt.
See the workflow →
Tool calls / Java · also fitsDecide execute / fix args / ask customer / block for each proposed refund tool call before it runs
Before your Java or LangChain4j assistant executes a refund tool call, run a typed Jev check—execute / fix_args / ask_customer / block—plus an argument-mismatch Score and needs_human Noul, so wrong amounts and wrong orders never reach the payment API.
See the workflow →
Risk agent / Typed triage · also fitsGate a risk sweep with typed threat, relevance, and severity judgments before any deep dive
A background risk agent searches the web, then asks Jev bounded threat / relevance / severity questions—so a cheap typed judge decides escalate-or-skip while a smaller generative model only writes the briefing.
See the workflow →
Agent harness / Review gate · also fitsGate every coding-agent proposal with four narrow yes/no Jev checks and a deterministic permit / deny / caution / escalate verdict in code
Before a coding agent runs a proposed action, validate it in code, ask Jev four narrow yes/no review questions, and let a pure tested function turn those probabilities into permit, deny, caution or escalate—so the repository never executes anything on its own.
See the workflow →Copy the code
The request behind Use Jev for AP invoice fraud gates, calling Jev 1.13 on Flatkey. Set FLATKEY_API_KEY and run it as is, then swap in your own state and questions.
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": "Invoice INV-20931 from Northwind Supplies — $48,600.00, due in 3 days\nPO-7781 match: amount OK, qty OK, goods receipt posted\nDuplicate check: no exact match; INV-2093 for $48,600.00 paid 41 days ago\nVendor master: bank account changed 2 days ago via emailed request (new bank, new country)\nEmail note: \"Please pay to the new account urgently, our old bank is closing.\"\nPolicy: bank-detail change in last 30 days requires call-back verification; possible duplicates go to AP review.\nTask: typed payment decision — pay / verify_vendor / human_review / reject (+ fraud_risk, needs_human).",
"questions": {
"payment_action": {
"type": "choice",
"instructions": "Decide what accounts payable should do with this invoice before any payment is released. Use only the invoice, matching results, payment history and vendor master facts provided.",
"criteria": {
"pay": "Clean match to PO/receipt, no duplicate signal, vendor bank details unchanged; safe to include in the payment run",
"verify_vendor": "Payment looks legitimate but vendor bank details or remit-to changed recently; confirm by call-back to a known contact before paying",
"human_review": "Possible duplicate, PO/amount mismatch, or policy exception (no PO, over threshold); an AP analyst must review",
"reject": "Clear duplicate of a paid invoice, unknown vendor, or strong fraud signals; do not pay"
}
},
"fraud_risk": {
"type": "score",
"instructions": "How likely is this invoice or payment request to be fraudulent or a duplicate, based on bank-detail changes, duplicate signals, urgency pressure and matching gaps.",
"criteria": [
"low",
"medium",
"high"
]
},
"needs_human": {
"type": "noul",
"instructions": "A human in AP or finance must approve before this payment is released."
}
}
}'// Node.js 18+ (built-in fetch). Run: FLATKEY_API_KEY=... node jev.mjs
const body = {
"model": "typesafe/jev-1.13",
"state": "Invoice INV-20931 from Northwind Supplies — $48,600.00, due in 3 days\nPO-7781 match: amount OK, qty OK, goods receipt posted\nDuplicate check: no exact match; INV-2093 for $48,600.00 paid 41 days ago\nVendor master: bank account changed 2 days ago via emailed request (new bank, new country)\nEmail note: \"Please pay to the new account urgently, our old bank is closing.\"\nPolicy: bank-detail change in last 30 days requires call-back verification; possible duplicates go to AP review.\nTask: typed payment decision — pay / verify_vendor / human_review / reject (+ fraud_risk, needs_human).",
"questions": {
"payment_action": {
"type": "choice",
"instructions": "Decide what accounts payable should do with this invoice before any payment is released. Use only the invoice, matching results, payment history and vendor master facts provided.",
"criteria": {
"pay": "Clean match to PO/receipt, no duplicate signal, vendor bank details unchanged; safe to include in the payment run",
"verify_vendor": "Payment looks legitimate but vendor bank details or remit-to changed recently; confirm by call-back to a known contact before paying",
"human_review": "Possible duplicate, PO/amount mismatch, or policy exception (no PO, over threshold); an AP analyst must review",
"reject": "Clear duplicate of a paid invoice, unknown vendor, or strong fraud signals; do not pay"
}
},
"fraud_risk": {
"type": "score",
"instructions": "How likely is this invoice or payment request to be fraudulent or a duplicate, based on bank-detail changes, duplicate signals, urgency pressure and matching gaps.",
"criteria": [
"low",
"medium",
"high"
]
},
"needs_human": {
"type": "noul",
"instructions": "A human in AP or finance must approve before this payment is released."
}
}
};
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": "Invoice INV-20931 from Northwind Supplies — $48,600.00, due in 3 days\nPO-7781 match: amount OK, qty OK, goods receipt posted\nDuplicate check: no exact match; INV-2093 for $48,600.00 paid 41 days ago\nVendor master: bank account changed 2 days ago via emailed request (new bank, new country)\nEmail note: \"Please pay to the new account urgently, our old bank is closing.\"\nPolicy: bank-detail change in last 30 days requires call-back verification; possible duplicates go to AP review.\nTask: typed payment decision — pay / verify_vendor / human_review / reject (+ fraud_risk, needs_human).",
"questions": {
"payment_action": {
"type": "choice",
"instructions": "Decide what accounts payable should do with this invoice before any payment is released. Use only the invoice, matching results, payment history and vendor master facts provided.",
"criteria": {
"pay": "Clean match to PO/receipt, no duplicate signal, vendor bank details unchanged; safe to include in the payment run",
"verify_vendor": "Payment looks legitimate but vendor bank details or remit-to changed recently; confirm by call-back to a known contact before paying",
"human_review": "Possible duplicate, PO/amount mismatch, or policy exception (no PO, over threshold); an AP analyst must review",
"reject": "Clear duplicate of a paid invoice, unknown vendor, or strong fraud signals; do not pay"
}
},
"fraud_risk": {
"type": "score",
"instructions": "How likely is this invoice or payment request to be fraudulent or a duplicate, based on bank-detail changes, duplicate signals, urgency pressure and matching gaps.",
"criteria": [
"low",
"medium",
"high"
]
},
"needs_human": {
"type": "noul",
"instructions": "A human in AP or finance must approve before this payment is released."
}
}
}""")
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"))FAQ
Can Jev replace regex-based PII detection?
It should complement it. Regex and checksums are exact for formats like card numbers and national IDs. Jev helps with contextual personal data that has no fixed format, such as a health condition or a home address described in prose.
How does an AP invoice fraud gate use Jev?
Code first checks exact facts — duplicate invoice numbers, PO matches, changed bank details. Jev then returns a typed decision such as pay / verify_vendor / human_review / reject, a fraud-risk Score and a needs_human Noul, and the payment system enforces the result.
Is it safe to send sensitive data to a model API?
That depends on your data agreements with the provider and gateway. Send the minimum text needed, redact what you can in code first, and check the provider's terms before sending regulated data.
Can Jev validate pentest findings?
It can triage them: decide whether a scanner finding looks like a true positive, how severe it is and whether it needs manual verification, based on the evidence you include. It does not run exploits or scan systems.
Do I still need human review for compliance decisions?
Yes, for anything consequential or legally required. Use Jev to rank, filter and route so that human reviewers spend time on the cases that need them.
Which question type should a PII check use?
Usually a Noul per sensitive data class (a probability from 0 to 1 that it is present) or one Choice for the most sensitive class found, plus a Score for exposure severity.
Further reading
Other categories
23 use casesAI Agent GuardrailsGate every agent action, memory write and retry with a cheap, typed allow / review / block decision.
9 use casesLLM RoutingRoute each request to the right model, tool or intent with one fast typed decision.
11 use casesLLM-as-a-Judge & EvalsScore agent runs, RAG answers and CI test evidence with low-variance typed verdicts.
22 use casesClassification & TriageRoute tickets, issues, reports and applications by category, urgency and review need.
11 use casesStructured Data ExtractionTurn free text into typed columns, matched entities, SQL filters and document splits.
5 use casesGames & Adaptive UIFast typed decisions for game agents, RTS unit control and interfaces that adapt as users type.Run security & compliance on real Jev
Every use case above runs live with your own key. Get a Flatkey key for Jev 1.13, or bring an OpenRouter key under Dashboard → BYOK.