Jev production reliability checklist
Ship Jev with versioned questions, schema validation, retries, confidence policy, audit logs, evaluation data, and human fallback.
1. Version the decision contract
Record the model, state schema, question IDs, criteria, and threshold policy together. Changing any one of them can change behavior and should trigger a new evaluation run.
const decisionContract = {
model: 'typesafe-ai/jev',
stateSchema: 'support-ticket@3',
questions: 'routing@5',
policy: 'confidence-bands@2',
}; 2. Separate failures from uncertainty
Timeouts, rate limits, overload, and invalid responses need retry or fallback handling. Low confidence is not a transport error; it is a valid signal that should follow an explicit review policy.
3. Log enough to reproduce decisions
Store request IDs, normalized state hashes, question versions, answers, distributions, confidence, latency, and the final application action without leaking sensitive content.
4. Evaluate and roll out gradually
Run labeled offline tests, shadow production traffic, compare human overrides, and use a kill switch. Expand automation only when the observed error cost matches the policy.
Work through a complete example and its failure paths
This lab writes demonstration tickets, decisions and delivery records to the local SQLite file you choose. Use a new exercise directory, never a business database. It makes no model, email or payment call.
This is a site-authored experiment with synthetic inputs and fixture responses. It uses only the Python 3.11+ standard library, no key or network. Passing tests establishes application behavior for these cases, not Jev accuracy, latency or real-provider retries.
Make the failure policy executable
Evaluation, persistence and effects are separate. The fixture provider only returns a Choice. evaluate allows 20ms per attempt, 70ms overall and two attempts. Transient failures may retry within that budget; authentication or invalid answers go to review. These tiny times make the exercise fast; they are neither production recommendations nor measured Jev latency.
- ingest binds ticket ID + version to an input hash. A saved request reuses its result; different input with the same key is rejected. Evaluation happens outside the transaction; the transaction rechecks and stores the decision and outbox together.
- deliver inserts the applied-event marker, updates the local assignment and marks delivery within one SQLite transaction. A pre-commit failure rolls all three back. Restarting can retry safely, and an old version cannot overwrite a new one.
- Concurrent workers can still evaluate twice; uniqueness and transactions prevent duplicate committed effects. Database lock waiting has a five-second limit; job-level backoff handles lock failure rather than retrying the model forever.
Expected fault-drill results
| Scenario | Expected outcome |
|---|---|
| transient | First attempt 503, second succeeds; attempts=2 and one outbox event. |
| auth / invalid / timeout | review; authentication and invalid answers get one attempt, timeout at most two; no assignment is queued. |
| crash-before-commit | After the intentional failure, assignments and applied_events are empty; a recovered delivery prints applied=1 and the next delivery prints 0. |
Boundary: the guarantee covers the local assignment inside one SQLite transaction. Email, payments and external APIs do not roll back with it. Sending first and marking later is not exactly-once. An external system needs stable idempotency support or reconciliation and compensation. Coroutines must cooperate with cancellation; a live HTTP adapter needs transport timeouts and must avoid multiplying SDK and outer retry loops.
Download offline regression tests · Download the type lab required by the tests · SQLite transaction semantics ↗
Expand the complete SQLite lab source · reliability_lab.py
"""Offline reliability lab: bounded evaluation + SQLite outbox + local effect.
Python 3.11+, standard library only. No provider, key, payment or email call.
The deterministic fixtures teach application behavior, not model accuracy.
"""
import argparse
import asyncio
from contextlib import contextmanager
import hashlib
import json
import os
import sqlite3
import time
import sys
from math import isfinite
if sys.version_info < (3, 11):
raise SystemExit('This lab requires Python 3.11 or newer; check python3 --version before running it.')
class ProviderError(Exception):
def __init__(self, status):
self.status = status
@contextmanager
def connect(path):
db = sqlite3.connect(path, timeout=5, isolation_level=None)
db.row_factory = sqlite3.Row
db.executescript("""
CREATE TABLE IF NOT EXISTS decisions (
request_id TEXT PRIMARY KEY, input_hash TEXT NOT NULL, result TEXT NOT NULL);
CREATE TABLE IF NOT EXISTS outbox (
event_id TEXT PRIMARY KEY, ticket_id TEXT NOT NULL, version INTEGER NOT NULL, team TEXT NOT NULL,
delivered INTEGER NOT NULL DEFAULT 0);
CREATE TABLE IF NOT EXISTS applied_events (event_id TEXT PRIMARY KEY);
CREATE TABLE IF NOT EXISTS assignments (ticket_id TEXT PRIMARY KEY, version INTEGER NOT NULL, team TEXT NOT NULL);
""")
try:
with db:
yield db
finally:
db.close()
def fingerprint(ticket_id, version, message):
body = json.dumps([ticket_id, version, message], ensure_ascii=False).encode()
return hashlib.sha256(body).hexdigest()
def cached(db, request_id, input_hash):
row = db.execute("SELECT * FROM decisions WHERE request_id=?", (request_id,)).fetchone()
if row and row["input_hash"] != input_hash:
raise ValueError("Idempotency key was reused for a different input")
return json.loads(row["result"]) if row else None
def valid_route(answer):
c = answer.get("confidence") if isinstance(answer, dict) else None
return (isinstance(answer, dict) and answer.get("type") == "choice"
and answer.get("choice") in {"technical", "billing", "human"}
and isinstance(c, (int, float)) and not isinstance(c, bool)
and isfinite(c) and 0 <= c <= 1)
async def evaluate(provider, *, attempt_timeout=0.02, total_timeout=0.07, max_attempts=2):
"""Provider must be an async callable with no application side effects."""
deadline = time.monotonic() + total_timeout
attempts = 0
reason = "budget_exhausted"
while attempts < max_attempts:
remaining = deadline - time.monotonic()
if remaining <= 0:
break
attempts += 1
try:
answer = await asyncio.wait_for(provider(attempts), min(attempt_timeout, remaining))
except TimeoutError:
reason = "timeout"
except ProviderError as error:
reason = "provider_failure"
if error.status not in {429, 500, 502, 503, 504}:
break
except Exception:
reason = "provider_failure"
break
else:
if not valid_route(answer):
reason = "invalid_response"
break
if answer["choice"] == "human" or answer["confidence"] < 0.75:
return {"action": "review", "reason": "policy", "attempts": attempts}
return {"action": "queue_assignment", "team": answer["choice"], "attempts": attempts}
if attempts < max_attempts:
# Bounded demonstration backoff; a live adapter must also bound Retry-After.
await asyncio.sleep(min(0.005, max(0, deadline - time.monotonic())))
return {"action": "review", "reason": reason, "attempts": attempts}
async def ingest(path, ticket_id, version, message, provider, **budget):
request_id = f"{ticket_id}:{version}"
digest = fingerprint(ticket_id, version, message)
with connect(path) as db:
existing = cached(db, request_id, digest)
if existing is not None:
return existing
result = await evaluate(provider, **budget)
with connect(path) as db:
db.execute("BEGIN IMMEDIATE")
# Another worker may have saved a decision while we awaited the provider.
existing = cached(db, request_id, digest)
if existing is not None:
return existing
db.execute("INSERT INTO decisions VALUES (?, ?, ?)", (request_id, digest, json.dumps(result)))
if result["action"] == "queue_assignment":
db.execute("INSERT INTO outbox(event_id,ticket_id,version,team) VALUES (?,?,?,?)",
(request_id, ticket_id, version, result["team"]))
return result
def deliver(path, *, crash_before_commit=False, hard_crash_before_commit=False):
"""The demonstrated side effect stays INSIDE this same SQLite transaction."""
applied = 0
with connect(path) as db:
db.execute("BEGIN IMMEDIATE")
for row in db.execute("SELECT * FROM outbox WHERE delivered=0 ORDER BY event_id").fetchall():
fresh = db.execute("INSERT OR IGNORE INTO applied_events VALUES (?)", (row["event_id"],)).rowcount
if fresh:
db.execute("INSERT INTO assignments VALUES (?, ?, ?) ON CONFLICT(ticket_id) DO UPDATE SET version=excluded.version, team=excluded.team WHERE excluded.version > assignments.version",
(row["ticket_id"], row["version"], row["team"]))
applied += 1
if hard_crash_before_commit:
# Fault drill in a disposable database: bypass Python rollback/cleanup.
os._exit(86)
if crash_before_commit:
raise RuntimeError("Injected crash: local update and marker must roll back together")
db.execute("UPDATE outbox SET delivered=1 WHERE event_id=?", (row["event_id"],))
return applied
def snapshot(path):
with connect(path) as db:
return {name: [dict(row) for row in db.execute(f"SELECT * FROM {name}")]
for name in ("decisions", "outbox", "applied_events", "assignments")}
def fixture(scenario):
async def provider(attempt):
if scenario == "timeout":
await asyncio.sleep(1)
if scenario == "auth":
raise ProviderError(401)
if scenario == "transient" and attempt == 1:
raise ProviderError(503)
if scenario == "invalid":
return {"type": "choice", "choice": "invented", "confidence": 0.99}
return {"type": "choice", "choice": "technical", "confidence": 0.8}
return provider
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("command", choices=["ingest", "deliver", "inspect"])
parser.add_argument("--db", required=True, help="Use a disposable local SQLite file")
parser.add_argument("--scenario", default="ok", choices=["ok", "transient", "timeout", "auth", "invalid"])
parser.add_argument("--ticket", default="ticket-7")
parser.add_argument("--version", type=int, default=1)
parser.add_argument("--crash-before-commit", action="store_true")
parser.add_argument("--hard-crash-before-commit", action="store_true",
help="Fault drill: terminate this process with exit 86 before SQLite commit")
args = parser.parse_args()
if args.command == "ingest":
result = asyncio.run(ingest(args.db, args.ticket, args.version, "Checkout is unavailable", fixture(args.scenario)))
elif args.command == "deliver":
result = {"applied": deliver(args.db, crash_before_commit=args.crash_before_commit,
hard_crash_before_commit=args.hard_crash_before_commit)}
else:
result = snapshot(args.db)
print(json.dumps({"offline_fixture": True, "result": result}, indent=2))
if __name__ == "__main__":
main()
Run
python3 --version # Requires Python 3.11+
python3 reliability_lab.py ingest --db ./jev-lab.sqlite --scenario transient
# Same key: reuses the cached decision; does NOT call the auth fixture.
python3 reliability_lab.py ingest --db ./jev-lab.sqlite --scenario auth
# Fresh key: actually exercises 401 and returns review.
python3 reliability_lab.py ingest --db ./jev-lab.sqlite --ticket auth-case --scenario auth
# Expected injected failure; inspect must show no applied assignment:
python3 reliability_lab.py deliver --db ./jev-lab.sqlite --crash-before-commit
python3 reliability_lab.py inspect --db ./jev-lab.sqlite
python3 reliability_lab.py deliver --db ./jev-lab.sqlite
python3 reliability_lab.py deliver --db ./jev-lab.sqlite
python3 reliability_lab.py ingest --db ./jev-lab.sqlite --ticket invalid-case --scenario invalid
python3 reliability_lab.py ingest --db ./jev-lab.sqlite --ticket timeout-case --scenario timeoutHow to verify the run
Run these commands in a fresh exercise directory; the fault-injection command intentionally exits nonzero. Repeated ingest reuses stored records and does not reset the database. Download both labs and the test file, then run python3 test_depth_labs.py to check restarts, rollback, concurrent deduplication, stale versions and malformed inputs.