open-standards/wai/wai-quantum/docs/qec.md
Transaction Science b9af554c7c wai-quantum contract over error correction and mitigation: their answers' schemas, distinct refusal codes, the basis in the new passes, and the smoke within one window
Error correction and mitigation join the version contract. An error-correction
answer (wai.quantum.qec/1: a code, a decode or a threshold), a code's distance
certificate (wai.quantum.distance/1) and a job's mitigation
(wai.quantum.mitigation/1) are engine schemas; every answer engine::qec::call
gives names the engine and its schema, inside what a host seals. The job
request names mitigate, and a compile's options and certificate twirl and dd.
qec_code, qec_decode and qec_threshold answer to output schemas on both
servers; the strict tests call each, a mitigated run and a compile with both
passes, the engine's test holds every decoder's answer and each mitigation
method to its schema, the contract workflow requires it by name, and
check_schemas.py holds the command line's answers too.

Refusal codes: the set branch and this one had each taken J007. A set that
does not read keeps J007; mitigation's refusals are J008 and error
correction's J009, in the table, its page, the tests, the docs and the
changelog.

The basis rename reaches the new passes: compile::Options carries twirl and
dd beside basis, and the command line's compile, both servers' compile
options and their tests name the gate set basis.

The service smoke test made 32 submissions with both branches' checks, past
the 30 a client may make in a window (it is also run against production after
a deploy). It now makes 28 (29 on a host with a GPU, whose single-precision
run is held to the exact values instead of a second run): the code-capacity
decode against its error, the changed estimate, the counts document and the
classical shortcuts are left to the MCP servers' tests, which hold each.

The agent docs are regenerated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 08:42:54 -04:00

11 KiB
Raw Permalink Blame History

Error correction and mitigation

engine::qec answers three calls, the same on every surface: the command line (wai-quantum qec code|decode|threshold), both MCP servers (qec_code, qec_decode, qec_threshold), the job service (POST /v1/qec/code, /v1/qec/decode, /v1/qec/threshold), the Studio's error-correction pane, the desktop app and Python (wai_quantum.qec_code, qec_decode, qec_threshold). Each answer is {"request", "result"}, the result sealed in a job's receipt, so wai-quantum verify and wai_quantum.verify check it. A request the engine cannot answer is refused with J009; the job service's bounds on shots, points and distances refuse with J031.

Mitigation is part of a job: "mitigate" beside "noise" and "observables" (wai-quantum run --mitigate zne, wai_quantum.run(..., mitigate="zne"), the Studio's Noise section). Its refusals are J008.

Codes

Name Code Notes
surface:D the rotated surface code, [[D², 1, D]], odd D from 3 to 15
toric:L the toric code, [[2L², 2, L]], L from 2 to 12
steane [[7, 1, 3]] the d = 3 colour code
color:D the triangular 6.6.6 colour code, [[(3D² + 1)/4, 1, D]], odd D from 3 to 15 quantum_color
bb:72, bb:90, bb:108, bb:144 (gross), bb:288 the bivariate-bicycle codes quantum_ldpc

A code's answer gives its checks (Z-type: they see X errors) and stabilizers (X-type), k counted by rank, a layout to draw it, and the decoders it takes.

The distance certificate

quantum_distance::certify finds, in each sector, the least weight of a logical operator: a support that commutes with every check and is not in the span of the stabilizers. The search grows connected supports (a lightest logical of these codes can always be taken connected in the graph where two qubits meet when they share a check), branching on the first violated check, barring siblings already tried, and pruning by the least number of qubits that could still satisfy the violated checks. A code's symmetries (a bivariate-bicycle code's translations) shrink the search to one support per orbit; each symmetry is checked to map the checks onto themselves before it is used.

The certificate (wai.quantum.distance/1) gives, per sector, the distance, a witness of that weight, no_logical_below and the search's node count, and a digest of the code's checks. Checking one ("certificate" in the request, --check FILE, certificate= in Python) verifies each witness is a logical of its stated weight and runs the search again, node for node. A search stopped by bound says no logical is lighter than the bound and settles nothing past it. The colour codes are certified to d = 9 in the test suite (d = 7 in a debug build), the bivariate-bicycle codes from 72 to 144 qubits in a release build; bb:288 ([[288, 12, 18]], 575 million search nodes, about 18 s in a release build) is certified on the command line, and the job service refuses its certification as more work than one request takes.

Decoders

Every decoder here is held to one test before any rate is measured: every error below half the distance is corrected to a trivial residual (at circuit level: every set of edges below half the matching graph's distance, with every edge at one probability). That test has found bugs that aggregate rates did not show.

At code capacity ("code" with "syndrome" or "error")

Decoder For Guarantee
matching codes whose qubits sit in at most two checks of a kind (surface, toric) exact minimum-weight perfect matching: every error below half the distance corrected
union_find the same codes linear time in the fired checks; the same ground truth checked
color colour codes restriction to matching on the three restricted lattices, lifted at each colour, completed below half the distance by an exact search: every error below half the distance corrected (checked to d = 9)
relay_bp any code belief propagation with relayed memory; it can stall on a degenerate error of a topological code and then says it did not converge
search any code the lightest error with the syndrome, up to max_weight (at most 8)

Given an error, the answer decodes its syndrome and judges the residual: a product of stabilizers (the logical state is unharmed), a logical operator, or a correction that does not explain the syndrome.

At circuit level ("memory", "circuit" or "model")

memory is the rotated surface-code memory experiment (distance, rounds, p); circuit is a noisy Clifford circuit in the ecosystem's circuit text; model is a detector error model in its text. With detectors the answer predicts which observables flipped; with shots (a circuit is needed) it samples and decodes, and gives the failures, the rate and its standard error, (rate·(1 − rate)/shots)^½.

Decoder What it does Guarantee
matching exact minimum-weight perfect matching (blossom, integer weights) every edge set below half the graph's distance corrected
correlated matches once, lowers the weight of the other parts of each decomposed fault the first matching used, matches again, and keeps the second answer only when the model's mechanisms explain it more cheaply the same edge-set guarantee; on the d = 5, two-round experiment's 95,703 sets of one or two faults it misses 73 pairs where matching misses 103, and neither misses a single fault
union_find union-find over the same graph the edge-set ground truth checked
bp_osd belief propagation with ordered-statistics post-processing for models that are not graphlike
window a sliding window as the syndrome arrives: window: {commit, buffer} rounds a window that covers everything is the batch decoder on every shot; every edge set below half the distance is corrected once buffer ≥ (d + 1)/2

The sliding window commits the matched edges that start in its first commit rounds and decides the buffer's again in the next window. A buffer shorter than the longest mechanism is refused; one round of buffer at d = 5 mispredicts 286 of the 166,176 sets of at most two edges, and a buffer of (d + 1)/2 rounds none. A stream states its latency budget per round (budget_ns, the hardware's cycle time): a window must decode within commit × budget_ns or work piles up behind it. quantum_window::measure times every window on the machine it runs on and says which fit; the prediction is the same bits everywhere, the timing is a measurement of that machine and is labelled so.

Thresholds

threshold measures logical failure rates over distances and physical rates p: family: "surface" at circuit level (decoders matching, correlated, union_find; the code model P(d) = a·(p/p*)^((d+1)/2) per round fitted to the points), or color, toric, surface_capacity at code capacity. Each point gives its shots, failures, rate and standard error; below_threshold says, at each p, whether every larger distance failed less. A crossing measured on few shots is not a threshold: quote rates with their errors.

The circuit and model texts

quantum_qec_text reads and writes the ecosystem's circuit text and detector error model text, the subset the crate's circuits use and more: tags on instructions (DEPOLARIZE1[leak](0.01) 0), Pauli-target observables (OBSERVABLE_INCLUDE(0) X0 Z3), detector coordinates, REPEAT blocks, SHIFT_COORDS, and in models ^-separated decompositions, detector and logical_observable declarations, repeat and shift_detectors. A circuit's model written back keeps its tags and coordinates. What the reader does not take it refuses with the line, never skipping it. The conformance vectors hold each form, the model each circuit gives, and each refusal.

Mitigation

Method What it does Bias Variance
zne zero-noise extrapolation: the program folded (U U† U) to odd noise scales (factors, default 1, 3, 5) and extrapolated to zero (extrapolation: richardson, linear, exponential) assumes the value varies smoothly with the noise scale and that folding multiplies the noise by the factor; a curve of another shape leaves a bias the error bar does not include each factor's shot noise carried through the extrapolation's coefficients, (Σ c_i² σ_i²)^½; a value outside [−1, 1] is reported as computed, not clipped
pea error amplification: a sparse Pauli–Lindblad model learned from the device (here, from simulated benchmarking of the job's noise), its rates multiplied by each factor, and extrapolated assumes the noise is the learned model under twirling; an error in the learned rates remains as bias (learned against true rates is in the details) as zne; the learning's shot noise enters as model error, not in the error bar
pec probabilistic error cancellation: each gate's learned channel inverted as a quasi-probability and sampled (samples) unbiased when the learned model is the noise; converges_to says where the estimate goes for this learned model grows as γ²; the error bar is the sampled circuits' signed, γ-scaled spread over √samples
cdr Clifford data regression: near-Clifford circuits made from the program (training, keeping keep non-Clifford rotations) fit a line from noisy to ideal values assumes one line relates noisy to ideal values for the program and its training circuits the program's shot noise through the slope and the fit's residual spread
vd virtual distillation: Tr(ρ² O)/Tr(ρ²) on two copies the dominant eigenvector's distance from the ideal state remains the ratio's, to first order, from shots on each
readout the job's counts with each qubit's readout error inverted assumes independent, symmetric misreads amplified by (1 − 2p)^−k; negative quasi-probabilities kept

Every mitigated value is reported beside the raw one, each with its error bar, and labelled with the method, its options and its stated assumptions. In simulation the ideal value is known and given too, so the bias can be read; on a device it would not be. A job's own expectation values stay the unmitigated ones; the mitigation sits beside them in the result and is sealed with it. Mitigation needs a noise model and observables (counts, for readout), refuses a program that measures in the middle, and is bounded at 8 qubits and a stated amount of work.

Pauli twirling and dynamical decoupling are compile passes, checked by the equivalence ladder: see the compiler page.

What is not here

  • A magic-state cultivation circuit generator. The architecture model (wai-quantum lab arch cultivate) prices cultivation from published rates; generating the circuits needs non-Clifford stages checked on state vectors against a reproduced reference, which is not done.
  • Decoders for hypergraph faults other than through decomposition (bp_osd takes them undecomposed).