UNDER THE HOOD
FOR THE LARP — Every prediction has a provenance.
Model outputs on this page are recorded evidence, each stamped with its date and build SHA. Every number in sections 3 to 6 is computed live in your browser by the same code production runs. This page makes no model calls and holds no keys.
1 The runtime pipeline
Two vision models read pixels; one router reads text; a human confirms; deterministic code does all the math. Select a stage.
MODEL CALL (server-only)
Jev router
jev-1.13-free (BeatAPI)
- Inputs
- Structured TEXT state only (component list, measure node, warnings, unresolved connections, validation errors). Never pixels.
- Outputs
- One choice: review_extraction / verify_topology / ask_user, with probabilities. verify_topology triggers one Groq verifier read (src/lib/ai/secondary.ts) that passes the same normalizer.
- Code
src/lib/ai/jev.tssrc/lib/ai/secondary.ts- Failure behavior
- No key, a paid model id, free-tier pacing (1 call/min, waits at most 8 s), 429 (Retry-After honoured) or a 15 s timeout all default to ask_user with an honest 'skipped'/'error' trace row. Paid jev-1.13 is refused in code.
2 Recorded traces
Real trace arrays returned by production, copied from the repo's evidence docs. Static data: replaying them here costs no quota.
RECORDED on 2026-10-11 12:51:28 PDT, build d1096b7
Input: public/samples/clear-divider.png
| step | provider / model | status | ms | tokens in / out | note |
|---|---|---|---|---|---|
extract | groq / qwen/qwen3.8-27b | ok | 839 | 1208 / 211 | |
route | beatapi / jev-1.13-free | ok | 711 | not recorded | review_extraction, p=1.00 |
Outcome: Exact graph (V1 5 V, R1 10k, R2 10k); user reviews and confirms.
Also observed ~12:30 PM PDT on build a9f6360: groq ok 795 ms, Jev review_extraction p=1.00 (docs/RELEASE_REPORT.md; tokens not recorded in that row).
Source: docs/demo/README.md (recorded backup run); README.md
3 Topology & validation
Models never hand the solver a picture. They hand it this typed graph, which validateGraph (zod schema + graph walk from GND) must accept before anything is solved. The checks below run in your browser.
// src/lib/circuit/types.ts (canonical contract, docs/API_CONTRACT.md v1)
export type CircuitComponent = {
id: string;
kind: 'resistor' | 'dc_voltage';
value: number; // SI units: ohm or volt
positiveNode: string;
negativeNode: string;
sourceBoundingBox?: [number, number, number, number];
};
export type CircuitGraph = {
schemaVersion: 1;
components: CircuitComponent[];
groundNode: 'GND';
measureNode: string;
};validateGraph: ok (3 components, measure VOUT)
Graph JSON
{
"schemaVersion": 1,
"components": [
{
"id": "V1",
"kind": "dc_voltage",
"value": 5,
"positiveNode": "VIN",
"negativeNode": "GND"
},
{
"id": "R1",
"kind": "resistor",
"value": 10000,
"positiveNode": "VIN",
"negativeNode": "VOUT"
},
{
"id": "R2",
"kind": "resistor",
"value": 10000,
"positiveNode": "VOUT",
"negativeNode": "GND"
}
],
"groundNode": "GND",
"measureNode": "VOUT"
}4 MNA solver: the only math authority
Modified Nodal Analysis stamps each resistor as a conductance into G and each ideal source as a row/column pair (B, C), then solves [G B; C D]·[v; j] = [i; e] by Gaussian elimination with partial pivoting. solveDC keeps its matrix private, so this page re-derives it with the same stamps (src/app/for-the-larp/math.ts) and checks the result against solveDC live; a unit test pins it. Fixture: Divider 5 V, 10k/10k.
| v(VIN) | v(VOUT) | i(V1) | b | x (solved) | |
|---|---|---|---|---|---|
| KCL @ VIN | 1 | 0 | 5 V | ||
| KCL @ VOUT | 0 | 0 | 2.5 V | ||
| V1 equation | 1 | 0 | 0 | 5 | -0.25 mA |
G[VIN, VIN] = 1/R1 S. Select a conductance cell to inspect its resistor contributions.
G conductances (S) B/C source incidence D zero for ideal sources. Source current follows MNA sign: current into the + terminal, so a source delivering power reads negative.
solveDC() in this browser returns VIN = 5 V, VOUT = 2.5 V: bit-for-bit identical to the displayed x.
5 Predictions & evidence
Drag the meter reading. diagnose() re-solves the circuit with each part open, shorted, off-value or each supply off-rail, and ranks single-fault hypotheses that reproduce your reading. No model, no network: everything below recomputes in your browser.
- R2 may be 1 kΩ instead of 10 kΩ
Expected 2.5 V at VOUT but measured 0.45 V. Hypothesis: a 1 kΩ R2 would give 0.455 V (exact fit 989 Ω), instead of the 10 kΩ in the diagram. A wrong resistor value or misread color band is one possible explanation. This is a hypothesis, not a confirmed fault.
Next: Disconnect power first, then measure R2's resistance with a multimeter and compare to 10 kΩ.
- R1 may be 100 kΩ instead of 10 kΩ
Expected 2.5 V at VOUT but measured 0.45 V. Hypothesis: a 100 kΩ R1 would give 0.455 V (exact fit 101 kΩ), instead of the 10 kΩ in the diagram. A wrong resistor value or misread color band is one possible explanation. This is a hypothesis, not a confirmed fault.
Next: Disconnect power first, then measure R1's resistance with a multimeter and compare to 10 kΩ.
- Supply V1 may be 0.9 V instead of 5 V
Expected 2.5 V at VOUT but measured 0.45 V. Hypothesis: if V1 were actually delivering about 0.9 V instead of 5 V, the reading would match (low battery, wrong supply or regulator setting). This is a hypothesis, not a confirmed fault.
Next: With the circuit powered, measure the voltage directly across V1's terminals (low-voltage DC only) and compare to 5 V.
6 Probe Guide: where to measure next
probeStep() builds 1 nominal + 13 single-fault hypotheses (each resistor open, shorted, ×10, ×0.1; supply dead), re-solves each with MNA, and weights them by a Gaussian meter model (σ = 2% + 10 mV). For each unmeasured node it groups hypotheses whose predicted readings a meter can't tell apart and computes expected information gain IG = H(posterior) − Σ P(outcome)·H(posterior | outcome) in bits. Highest gain wins. Computed live below.
Ladder: V1 = 5 V, R1, R2, R3 = 10 kΩ in series. Expected B = 1.667 V. Readings: B = 0 V.
| probe node | expected gain | |
|---|---|---|
| VIN | 0.81 bits | |
| A | 1.50 bits | ← probeStep picks |
Measure A next (~1.50 bits expected).
- ≈ 0 V → 50%: V1:dead, R1:open
- ≈ 2.5 V → 25%: R3:short
- ≈ 5 V → 25%: R2:open
Posterior (top 5)
- Supply V1 off / dead / disconnected25%
- R3 shorted (bridge or stray wire)25%
- R1 open / not connected25%
- R2 open / not connected25%
- No single modeled fault fits these readings1%
7 Usage, latency, limits & economics
Measured anecdotes, not distributions. Unknown is written as unknown, never as $0. Sources: docs/UNIT_ECONOMICS.md, docs/MODEL_ACCESS.md, docs/VISION_FALLBACK.md, docs/demo/README.md.
Measured (2026-10-11, production)
| stage | model | latency | tokens in / out | source |
|---|---|---|---|---|
| Extract (current primary) | qwen/qwen3.8-27b (Groq) | 839 ms | 1208 / 211 | clear divider, 12:51 PDT, d1096b7 (docs/demo/README.md) |
| Extract, 10 synthetic fixtures | qwen/qwen3.8-27b (Groq) | 735 ms median | 1208 / 233 | 10/10 exact, 0 API errors; not a benchmark (docs/VISION_FALLBACK.md) |
| Extract (fallback) | gemini-3.5-flash-lite | 1140 ms | 1310 / 229 | 12:52 PDT, d1096b7 (docs/demo/README.md) |
| Extract (Gemini-primary era) | gemini-3.5-flash | 3790 ms | 1310 / 106 | docs/UNIT_ECONOMICS.md |
| Route | jev-1.13-free (BeatAPI) | 440 ms | 475 / 49 | same Gemini-era run (docs/UNIT_ECONOMICS.md) |
| Solve | local MNA | ~1 ms | n/a | docs/UNIT_ECONOMICS.md |
Free-plan ceilings and listed prices (accessed 2026-10-11)
| provider | free-plan limit | paid price |
|---|---|---|
| Jev jev-1.13-free (BeatAPI) | 1 successful call/min before any top-up (binding: 1 analysis/min) | jev-1.13: $0.042 / 1M input, output free; refused in code |
| Groq qwen/qwen3.8-27b | 30 RPM, 1K RPD, 8K TPM, 200K TPD; ~2.5k tokens per image call ⇒ ~3 extractions/min | not listed (groq.com/pricing) |
| Gemini (fallback + tutor) | not listed (AI Studio only); free quota observed exhausted (429) on 2026-10-11 | gemini-3.5-flash: not listed |
| App guard (src/proxy.ts) | per IP: extract 6/min + 40/h, solve 60/min, explain 10/min | n/a |
Usage charges in this deployment: $0 by construction (free plans), which is not a production marginal-cost claim. Hypothetical paid cost per analysis (scripts/cost-model.mjs): Jev $0.0000200; Groq and Gemini unknown until their prices are listed, so the total is incomplete. No routing-savings claim: there is no same-case baseline yet.
8 Supported today vs planned
Works today
- DC resistive networks: resistors + ideal DC voltage sources
- Clean schematic images (synthetic renders; real-photo accuracy unmeasured)
- Single-fault hypotheses: open, short, off-value resistor, off-rail supply
- Probe Guide (information gain) and solver-grounded tutor
- Routes review_extraction and ask_user observed on the Groq-primary pipeline
Planned / research (not shipped)
- Topology confidence engine: research, PR #39 (open, not merged)
- verify_topology on the Groq-primary stack: implemented, not yet observed live
- Breadboard and netlist adapters: planned
- Capacitors, inductors, AC and transient analysis: research
- PCB/EDA imports: exploration
- Multiple simultaneous faults: not modeled (a fit warning says so)