jev-trust
Trust middleware for Jev decision APIs — spend confidence at its verified exchange rate.
Jev gives you calibrated-looking probabilities. But calibration is a property of (model, domain) pairs, not models. We measured hosted Jev 1.13 at ECE 0.041 on closed deterministic tasks — and accuracy 50% while stating 91% confidence on synthetic email triage (Assay research #1/#2). Same model. Same day. The number you actually care about is the one for your domain, and nobody has measured it yet — including the vendor.
jev-trust wraps the Jev API and measures it in your domain while you work:
- Every call logged — append-only JSONL: question, answer, stated confidence, effective confidence, usage, timestamp.
- Outcomes fed back — as ground truth arrives,
record_outcome()builds your domain's calibration record: accuracy, Brier, ECE, and calibration currency C = 1 − ECE. - Effective confidence on every answer —
r.effective_confidence= what the stated confidence is worth here so far (observed accuracy of the matching confidence bin, ≥5 samples; else C-adjusted; elseNone= insufficient evidence). - Overconfidence alerts — a callback fires when a decision is confident enough to act on but the domain hasn't earned that confidence yet.
- Signed evidence — one call signs the whole log (ed25519). Publish log + sig + pubkey; anyone — including Nautilus Assay — can independently recompute your numbers.
Zero dependencies. Pure stdlib. Python ≥ 3.8.
Install
pip install jev-trust
Quickstart
from jev_trust import TrustedJev
jev = TrustedJev(api_key=API_KEY, domain="email-triage")
# decide() never lets unexamined confidence through:
r = jev.decide(state, {"q": {"type": "choice", "instructions": "...",
"criteria": {...}}})["q"]
r.decision # 'alpha'
r.stated_confidence # 0.91 <- what Jev claims
r.effective_confidence # 0.50 <- what 0.91 is worth in YOUR domain so far
r.basis # 'bin_observed' | 'C_adjusted' | 'insufficient_n'
r.domain_verdict # FACE_VALUE | DISCOUNT | DOWNGRADE | UNVERIFIED
# feed ground truth back as it arrives:
jev.record_outcome("q", truth)
# your domain's running scorecard:
jev.stats()
# {'n_outcomes': 42, 'accuracy': 0.52, 'brier': 0.41, 'ece': 0.39,
# 'C': 0.61, 'verdict': 'DISCOUNT', ...}
The alert that pays for itself
def on_overconfidence(r):
# fired when stated >= 0.90 but the domain hasn't earned FACE_VALUE
log.warning(f"{r.qid}: Jev says {r.stated_confidence}, "
f"worth {r.effective_confidence} here — route to human?")
jev = TrustedJev(api_key=API_KEY, domain="fraud-flag",
alert_confidence=0.90, on_overconfidence=on_overconfidence)
Bipolarity self-check (v0.2) — ask both ways, or don't ask
We measured Jev answering yes/no questions whose required computation was too expensive for it: the answer collapsed onto the question's polarity rather than the data (both directions — reword the question the other way and the verdict flips with it; study artifacts). Stated confidence does not warn you — the two wrong halves each look confident.
decide_symmetric asks every question in both polarities inside ONE API call
(you write the flipped wording — the library never rewrites your semantics):
r = jev.decide_symmetric(state, {"q": {
"question": {"type": "noul", "instructions": "Is this transaction fraudulent?"},
"opposite": {"type": "noul", "instructions": "Is this transaction legitimate?"},
}})["q"]
r.decision # answer from the original polarity
r.polarity_consistent # False -> the two wordings disagree
r.trust_flag # "POLARITY_CONFLICT" — do not act without review
r.effective_confidence # None on conflict, regardless of stated confidence
r.stated_confidence # min of the two cross-polarity confidences (conservative)
Conflicting items fire on_polarity_conflict and are force-degraded: the
question the model can't actually compute is exactly the one this catches.
Verdicts (Assay calibration-currency reading levels)
| Verdict | Condition | Reading |
|---|---|---|
UNVERIFIED |
< 20 outcomes in domain | stated confidence is an unbacked claim |
FACE_VALUE |
C ≥ 0.80 | use stated confidence as-is |
DISCOUNT |
0.50 ≤ C < 0.80 | multiply trust by C |
DOWNGRADE |
C < 0.50 | route to human review |
The library ships with Assay's published reference rates (informational — your verdict is always computed from your outcomes):
jev_trust.ASSAY_REFERENCE_RATES
# {'closed-deterministic': {'C': 0.959, ...}, # n=240, ECE 0.041
# 'adversarial-stress': {'C': 0.988, ...}, # n=200, ECE 0.012
# 'synthetic-email-choice': {'C': 0.086, ...}} # acc 50% @ conf 91%
Signed evidence — make your numbers independently checkable
sig_path = jev.sign_log() # writes <log>.jsonl.sig
jev.keys.pub_hex # publish this next to the log
# anyone can verify:
from jev_trust import verify_log
verify_log("session.jsonl", "session.jsonl.sig", pub_hex) # -> VALID
Same canonical-JSON + ed25519 scheme as
assay-verify — a signed jev-trust
log is directly submittable to Nautilus Assay for independent recomputation
(the evidence format behind their Domain Calibration Reports).
Why this exists
Nautilus Assay independently verifies AI-agent performance claims. Their two
public Jev studies found: overall accuracy 92.2% / Brier 0.048 on closed tasks
(good), but domain calibration collapses on distribution shift — 50% accuracy
at 91% stated confidence in one synthetic triage domain. Vendor benchmarks
can't see your domain. jev-trust is the always-on instrument that can.
Methodology: ECE = equal-width 10-bin top-label; Brier = mean (1 − p_true)² (binary-identical to the standard (p − y)² form). Identical formulas to Assay's published verification code.
License
MIT. © 2026 Nautilus Assay.
Metadata
Release files for jev-trust 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| jev_trust-0.2.1.tar.gz | 21.8 kB | Without provenance | Details for jev_trust-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| jev_trust-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for jev_trust-0.2.1-py3-none-any.whl |
Total release size: 39.5 kB
Release files / jev_trust-0.2.1.tar.gz
| Download URL | jev_trust-0.2.1.tar.gz |
|---|---|
| Size | 21.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5b1abf7ed51c4dfbcfe6825b1b08b97003c506dd1813bce24a6ec2263035a4bb
|
|
BLAKE2b-256 checksum How to use checksums |
b7c63dce6e2f92e9a8e9c82a54bf30218748e9aa871a84ce772d537611bc4e63
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / jev_trust-0.2.1-py3-none-any.whl
| Download URL | jev_trust-0.2.1-py3-none-any.whl |
|---|---|
| Size | 17.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0c7846e6ee8d7a004f0797f7b7339aaa92f9cc55af48aaf2b5fb1ca7346ef3d7
|
|
BLAKE2b-256 checksum How to use checksums |
7b369e96a4d6ce9a6e0129ae4dd4d7aedae121a5cffc5001ac38509f2601d284
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for jev-trust 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.