open-standards/wai/wai-quantum/README.md
Transaction Science a1bf417590 wai-quantum: a program's history, attributed, and the Studio's Versions
Feature 6 of the co-design report: every version of a program, who made
each change and how, and whose hand each line and gate is in, sealed
into the run's receipt.

- engine::versions:
  - versions in a chain, each naming its parents (none, one, or two for
    a merge), who made it (the person, the assistant, an outside agent,
    the engine, or where the program came from) and how (an edit, a
    proposal reviewed change by change, a merge);
  - a version's digest covers its parents' digests, and the recording
    host's key seals it; verify checks every digest, seal and review;
  - changes and apply: a line diff (Myers), so a proposal is taken
    change by change, and the version keeps the whole proposal;
  - blame, authorship and gate_hands: a line keeps its author until
    changed; a model's or an agent's line the person edits is in both
    hands; an undo keeps the earlier authors; a merge keeps each side's;
    gates follow their lines, at a generator's inputs;
  - attest and check_job: a job's request carries the account, the
    receipt binds it, and it is recomputed from the history;
  - call: the history by name with JSON arguments, for the page and the
    desktop app.
- The command line: history start | commit | changes | propose | merge |
  log | blame | verify; run and submit --history; verify --history.
- MCP: history_commit, history_changes, history_blame and history_log.
  An agent's edit is recorded as an outside agent's, under the name its
  client gave in initialize, whatever it says of itself.
- The Studio's Versions pane:
  - what the reader types is theirs, recorded when they pause;
  - every proposal (the assistant's program, an alternative, a generator
    from the Workbench) is offered change by change while the editor
    waits; a fix is the engine's;
  - lines of work in lanes: an older version opened and edited starts
    its own, and "Bring in" merges one change by change;
  - "Who wrote it" marks lines in the gutter and gates on the diagram;
  - the run's receipt binds the account, which the result recomputes;
  - kept in the browser, downloaded for the command line;
  - window.quantumStudio.propose for an embedding page.
- Fixes found by the Studio's test: a run shows it is running before
  the account is made, and the draft is kept as the page goes.
- CI: wai-web's native engine tests count 8, the history's included.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 02:02:58 -04:00

574 lines
51 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# wai-quantum
A **deterministic quantum stack in pure Rust**. Byte-exact circuit simulation,
the operational layer around it, and signed energy-accounted receipts binding
every stage.
No QPU, no cloud service, no vendor SDK, and **no system libraries** — so the
same source runs natively, in the browser via wasm, and as a WASI component at
the edge, producing **byte-identical results and receipts on all three**. Nine
opt-in features reach outside the crate: `quantum_fabric_webgpu` (the
platform's GPU interface), `quantum_fabric_cuda` (the CUDA driver and runtime
compiler) and `quantum_fabric_opencl` (the OpenCL ICD loader), the last two
loaded when first used, `quantum_fabric_fpga` (Verilator, run as a program
when first used), `quantum_fabric_npu` (the platform's model runtime, on
macOS), `quantum_fabric_sme` (the processor's streaming vector mode, by
inline assembly), `quantum_fabric_vector` (the processor's vector extension),
`quantum_fabric_dsp` (the signal processor's vector
unit, in a build for that processor) and `quantum_fabric_dataflow` (a dataflow
device's library, loaded when first used); no default feature reaches a system
library.
```toml
[dependencies]
wai-quantum = "0.4"
```
```rust
use wai_quantum::quantum::Circuit;
use wai_quantum::quantum_toolchain as qt;
let mut c = Circuit::new(3);
c.h(0).cx(0, 1).cx(1, 2); // GHZ
let sv = c.simulate().unwrap();
println!("{:?}", qt::top_outcomes(&sv, 2)); // |000> 0.5, |111> 0.5
// a portable identity for the reconstruction — same on every machine
let h: [u8; 32] = sv.statevector_hash();
```
## What's in it
| Feature | What it gives you |
|---|---|
**Cross-architecture reproducibility is tested, not asserted.** The full test
suite passes under `wasm32-wasip2` on wasmtime as well as natively, and the
floating-point results — entropy, the Holevo bound — are pinned to their exact
IEEE-754 bits, so a platform that computes something different fails the suite
instead of quietly returning a different number:
```text
CARGO_TARGET_WASM32_WASIP2_RUNNER=wasmtime cargo test --release --target wasm32-wasip2 --features full
```
The same binary answers what a state *carries*, not only what a circuit does:
```text
wai-quantum entropy bell --keep 0 # half a Bell pair: 1 bit, invisible to a state vector
wai-quantum channel depolarizing --prob 0.5
wai-quantum bb84 --eavesdrop # interception shows up in the error rate
wai-quantum chsh # 2 sqrt(2), exactly, not sampled
wai-quantum qutrit # d = 3, not just qubits
```
`channel` prints the Holevo bound before and after, and it can only fall: noise
never creates information.
| `quantum` | byte-exact statevector simulation (dyadic Clifford+T+P(k)), as `wai.quantum.circuit2` by default or as the frozen `wai.quantum.circuit` |
| `quantum_toolchain` | algorithm library, backend recommendation, **OpenQASM 2/3 ingest of what the mainstream toolchains actually export** — both register and both measurement spellings, `rx`/`ry`/`rz`/`sx`/`u`/`u2`/`u3`/`crz`, and exact rational-multiple-of-pi angles (non-dyadic angles are refused, never rounded); **device-ready OpenQASM 2/3** (`device::device_qasm`): every gate lowered exactly to its dialect's standard library, multi-controlled gates included, every qubit measured into `c[i]`, and the service's counts read back onto the crate's basis; **native programs** (`native::compile`): a processor's own basis (`rz`/`sx`/`x`/`cz`; `prx`/`cz`; or `gpi`/`gpi2`/`zz` with angles in turns, written exactly; the Z rotations carried in the phases of the last two) on its own qubits, routed over its coupling map, and checked against the circuit by simulation before it is sent — Bloch / entanglement / purity analysis |
| `quantum_qasm` | **the OpenQASM reader the job service runs**, for every surface that takes a program: OpenQASM 3 and the OpenQASM 2 forms in common use, every register, a gate on a whole register, gate definitions with parameters, `ctrl`/`negctrl` modifiers, angle expressions, comments, and measurement in every spelling. A program that measures and then acts, resets after a gate or uses `if` is kept as dynamic steps. Generators: integer `input`s, `const`s and `for` loops (ranges, steps, sets, nested), with integer arithmetic in indices and sizes and `if` on integers decided on reading, so one program describes a family of circuits; `qasm::parse_with` reads it at given inputs and `qasm::instantiate` writes that circuit out as plain OpenQASM. `while`, `inv`, `pow` and anything else not listed are refused with their line. Lowered to each method's input exactly up to a global phase. `qasm::dyadic_circuit` gives the exact state vector's circuit (dyadic angles) for a program whose measurements all come at the end, and refuses any other with the reason |
| `quantum_engine` | **the quantum job service's engine, for every host**: a job (an OpenQASM program and what is asked of it: shots, Pauli expectation values, amplitudes, noise) planned onto the strongest method it admits, with the reason and the memory and work it will take; run; answered in the service's JSON with its accuracy class; and sealed over the request and the result in their canonical JSON (`engine::job`, `engine::receipt`), so a result from the service, the command line or a browser tab checks the same way. Also a program's circuit drawn as text (`engine::draw`); the specification-and-evaluator workbench (`engine::discover`: a specification, the engine's verdict on a generator at every size, and an archive of the cheapest verified generator in every cell of two measures, sealed); a program's history, attributed (`engine::versions`: versions in a sealed chain, each with who made it and how, proposals reviewed change by change, and each line and gate in the hand that wrote it, which a job's receipt can bind); and the CPU energy the kernel counts for one process (`engine::energy`). It builds for `wasm32-unknown-unknown`, where it runs on one thread and claims no time |
| `quantum_stabilizer` | stabilizer (CHP) tableau — `O(n²)`, scales far past statevector |
| `quantum_mps` | tensor-network (matrix-product-state) backend |
| `quantum_pauli` | sparse-Pauli / Heisenberg observable propagation over the dyadic gate set (up to 64 qubits) |
| `quantum_spd` | **sparse Pauli dynamics at utility scale**: arbitrary-angle Pauli rotations on up to 1024 qubits, exact Clifford and quarter-turn rotations, a rigorous bound on what truncation can move a result, and the 127-qubit heavy-hex kicked-Ising circuits — whose exactly computed 5-step magnetization it reproduces on all 127 qubits |
| `quantum_spd_receipt` | a signed, energy-accounted receipt over a sparse-Pauli-dynamics run, re-checkable bit for bit on any machine |
| `quantum_bptn` | **tensor-network states on the hardware graph**: simple-update evolution with belief-propagation environments and re-gauging, the device's couplings applied a layer at a time in parallel (bit-identical to one at a time). Exact on trees; on the 127-qubit lattice it gives the exactly computed 5-step magnetization to 4e-7 at bond dimension 32 — an independent check on sparse Pauli dynamics, whose errors it does not share |
| `quantum_resource` | **fault-tolerant resource estimation**: from a program's logical counts (qubits, T, Toffoli and rotation gates, measurements) to code distance, T-state factories found by exhaustive search, physical qubits and runtime, on six reference qubits and three codes, with the qubits-versus-time frontier. Reproduces the published worked examples to their printed precision |
| `quantum_resource_receipt` | a signed, energy-accounted receipt over an estimate, re-checkable bit for bit on any machine |
| `quantum_qio` | **quantum-inspired optimisation**: Ising and Max-Cut problems (G-set reader, spin-glass generator), simulated bifurcation in its ballistic, discrete and heated forms (batched eight trials per pass, bit-identical to one at a time), simulated annealing, single-flip descent, an exact Gray-code referee up to 34 spins, and step-to-solution. Reaches the best-known cut on seven G-set instances |
| `quantum_uf` | **union-find decoding in near-linear time** over the same matching graph: event-driven cluster growth on integer weights (a radix heap orders the fill events), merges, and peeling. Measured against exact matching on the same shots: within 0.92–1.18× the failures, up to 77× faster at `d = 11` |
| `quantum_dmrg` | **ground states of spin chains by DMRG**: matrix-product operators for nearest-neighbour chains (XXZ Heisenberg in a field, transverse-field Ising), two-site sweeps with Lanczos and density-matrix truncation, entanglement entropies, a symmetric eigensolver, and two exact referees: full diagonalisation up to 22 sites, and the free-fermion solution of the Ising chain at any length. The critical Ising chain is reproduced to about `10⁻¹¹` per site at 200 sites |
| `quantum_tdvp` | **time evolution of spin chains by TDVP**: two-site sweeps forward and back, Lanczos exponentials that halve a step they cannot converge, bonds split by singular value decomposition, and every basis completed with null vectors so a product state's small bonds do not hold the evolution back. Measures site and bond observables, entanglement at every bond, energy and the Loschmidt echo. Held to two exact referees: Krylov evolution of all amplitudes up to 20 sites, and the free-fermion solution of an Ising quench at any length. On a 100-site critical quench at bond 64 it stays within `10⁻⁹` of the exact answer until the entanglement fills the bond, and past that its error follows the discarded weight it reports |
| `quantum_chem` | **molecules by DMRG**: FCIDUMP integrals, the second-quantised Hamiltonian on spin orbitals compiled into an exact MPO (minimum vertex covers, no numerical compression), DMRG from Hartree–Fock with complete bases, and full configuration interaction as the referee. LiH and H₂O reach full CI to `10⁻¹³` |
| `quantum_nqs` | **neural quantum states**: spin models on any graph (Heisenberg, frustrated J₁–J₂, transverse-field Ising), a restricted Boltzmann machine with real parameters (and Marshall's sign on bipartite lattices) or complex ones that learn a sign structure nobody supplied, projected onto a momentum and spin-flip sector, variational Monte Carlo by Metropolis chains or exact enumeration, and stochastic reconfiguration solved in whichever of parameter or sample space is smaller. Held to exact diagonalisation and to DMRG on the same operator sum |
| `quantum_noisy` | **noisy circuits**: quantum trajectories on the state vector (depolarizing, dephasing, amplitude damping, readout), an exact density-matrix referee up to 12 qubits that reuses the same kernels, linear cross-entropy fidelity (sampled, exact and the circuit's own), and the digital error model. Measures where that model is off: below the true fidelity by a margin that grows with the error rate, not with depth |
| `quantum_ldpc` | **qLDPC memory at circuit level**: bivariate-bicycle codes from their two polynomials (`k` by rank, logical bases), the depth-8 syndrome cycle with circuit-level noise, its detector error model, and BP-OSD decoding (min-sum with adaptive scaling, ordered statistics with a combination sweep). The error model has the same columns as the source's own decoding matrices, and on identical syndromes the decoder makes the source's decisions shot for shot |
| `quantum_arch` | **architecture-level estimation**: yoked surface-code storage (row and grid parity checks over patches, hot and cold), magic-state cultivation read off the published simulation curves, CCZ factories, and a clock set by whichever is slowest of lattice surgery, the magic-state supply and the control loop. Assembles whole-machine estimates; its storage search matches the source's footprint tool layout for layout |
| `quantum_receipt` | signed, energy-accounted receipt over a reconstruction |
| `quantum_ops` | the operations/attestation layer |
| `quantum_cal`, `quantum_control`, `quantum_noise` | calibration, filter-function robust control, DD noise spectroscopy, Cycle-Benchmarking noise learning |
| `quantum_mitigate` | zero-noise extrapolation, readout M3, classical shadows |
| `quantum_qec` | CSS codes (distance verified by exhaustive search, not asserted) — **rotated surface** `[[d²,1,d]]`, toric, bivariate-bicycle, and the **`[[7,1,3]]` colour code**, whose self-duality buys a *transversal* logical Hadamard — one round, no ancillas, no surgery — verified on the simulator, with the surface code shown failing the same move — with **two decoders**: union-find (weighted matching, single-shot, space-time with faulty measurement, **and circuit-level with hook errors**; **imports and exports** Stim-syntax detector error models, so other tools' noise models decode here and ours decode there) and Relay-BP (for qLDPC) |
| `quantum_frame` | **noisy Clifford circuits at QEC scale**: reads the ecosystem's circuit text; samples detection events by bit-packed Pauli-frame simulation (64 shots per word); derives the detector error model by backward sensitivity, refusing non-deterministic detectors; generates the rotated surface-code memory experiment byte for byte as the reference layout; and decodes by **exact minimum-weight perfect matching** (Edmonds' blossom on integer weights). Measures logical error rates and fits the code model resource estimates assume |
| `quantum_tn` | **tensor-network contraction**: circuits (any unitary on any qubits) become networks; a seeded hyper-optimiser finds contraction trees from randomised-greedy and multilevel-partition families, reconfigures them optimally in subtrees, and slices them to a memory cap with a second search around the slices; slices contract in a fixed order, threaded, to the same bits everywhere. Single amplitudes or open-output batches |
| `quantum_cutrank` | **Clifford circuits measured in a product basis, exactly**: the stabilizer state's graph form (`Tableau::graph_form`) and one closing layer of single-qubit gates at any angles, summed one qubit at a time along an order in a table of `2^{cut-rank}` entries. Exact amplitudes, probabilities and samples (by Parseval), at a cost set by the entanglement across the order's cuts, not by the number of qubits; orders annealed for less work; tables in double or single precision; the same bits at any thread count |
| `quantum_gbs` | **Gaussian boson sampling, exactly**: hafnians (power traces, Hessenberg + characteristic polynomial, `O(n³ 2^{n/2})`), torontonians, lossy Gaussian states from squeezers and an interferometer, exact click and photon-number probabilities, exact samples drawn mode by mode, and a check of observed samples against the exact one- and two-mode click statistics |
| `quantum_sv` | **the dense state vector at any angle**: one-, two- and `k`-qubit kernels with a diagonal fast path, gate fusion around multi-qubit gates, threads over independent blocks; every kernel path computes each amplitude in the same order, so threading never changes a bit. Agrees with an independent simulator to 2·10⁻¹⁶ |
| `quantum_compile` | Clifford routing + stabilizer-tableau equivalence proof |
| `quantum_atom` | neutral-atom register preparation (Hungarian / LSAP) |
| `quantum_qir` | **QIR export + ingest** — emit and parse QIR (the QIR Alliance's LLVM-based IR); emitted modules validated with `llvm-as`, and 9 of 10 catalog algorithms re-ingest to a bit-identical statevector |
| `quantum_comm` | **key distribution and security**: BB84 with an intercept-resend eavesdropper (a quiet channel gives a perfect key; interception costs a quarter of it), and the no-cloning theorem priced |
| `quantum_qudit` | **qubits and qutrits**: the Weyl–Heisenberg group, the Fourier gate over `Z_d`, the controlled sum — exact for `d = 2` and `3` |
| `quantum_info` | **mixed states**: density matrices, the partial trace, purity, exact Pauli expectations, and CHSH against the classical and Tsirelson bounds |
| `quantum_source` | **the limits on encoding and transport**: von Neumann entropy, the Schumacher limit, and the Holevo bound — which says `n` qubits carry at most `n` classical bits, so quantum does not compress classical media |
| `quantum_channel` | **transport itself**: Kraus channels (bit flip, dephasing, depolarizing, amplitude damping), and linear-inversion tomography to see what actually arrived — with the law that a channel can only *lose* information, never create it |
| `quantum_qbom` | Quantum Bill of Materials — stage receipts into one manifest |
| `quantum_vml`, `quantum_phasor`, `quantum_qfhrr`, `quantum_kernel`, `quantum_qdata`, `quantum_phasor_meter` | the interference / phasor ML layer |
| `quantum_fabric` | **the compute fabric**: members (the CPU and accelerators, quantum processors among them), each kernel implementation certified against the CPU reference in the process that uses it (bit-exact, within a stated tolerance, or statistical by classical fidelity over stated shots), with the certificate saying where it was earned (silicon, an emulator, or a simulator); placement by parity, provenance and metered energy; a signed receipt naming the member and implementation behind a result. Two kernels: apply (a circuit's state) and sample (its measurement counts), the latter with the CPU reference sampler, a corpus shaped for quantum processors, and a virtual quantum processor whose stated noise model lets every step of a processor's path run and be tested without one; its certificates say they were earned in a simulator. `quantum_fabric::stablehlo` writes the gate as a portable tensor program (StableHLO), every value a 64-bit integer that never overflows, for any tensor compiler to build for its own devices; the `stablehlo_gate` example writes it with a batch of inputs and the exact outputs a build must give, and `ci/tensor-program/check.sh` runs a build and holds it to them |
| `quantum_fabric_webgpu` | **the fabric's WebGPU member**, opt-in and not in `full`: the 32-bit-lane gate kernel in WGSL, one dispatch per gate, through Metal, Vulkan or DX12 natively and through a browser's WebGPU on `wasm32-unknown-unknown`; a second implementation applies runs of gates tile by tile, one dispatch per run, and is certified on its own. Each adapter is probed against the CPU's arithmetic in the process that uses it and certified bit-exact by reproducing the CPU reference's pinned corpus digests; a result that would leave 32 bits is refused, never returned. One of the features that reach outside the crate |
| `quantum_fabric_cuda` | **the fabric's CUDA member**, opt-in and not in `full`, native targets only: the gate kernel in CUDA C with exact 64-bit integers, compiled at run time for each device's own architecture, one launch per gate. The CUDA driver and runtime compiler are loaded when first used, so a build with the feature runs on a host without CUDA and finds no member there, saying why. Each device is probed against the CPU's arithmetic in the process that uses it and certified bit-exact by reproducing the CPU reference's pinned corpus digests; a result that would leave 32 bits is refused, never returned. On a device of compute capability 8.0 or later, a **second kernel runs every product on the tensor cores** (`CudaMember::tensor`): each value as four 8-bit limbs in bf16, accumulated in f32, which holds every partial sum exactly; probed and certified under its own implementation id, with its own mutants. With `quantum_sv` too, the **dense f64 state vector** runs on the device bit for bit as on the CPU: the CPU's own launches (diagonal, one-qubit and grouped formulas), each an IEEE binary64 operation with no fused multiply-add, certified against a pinned corpus digest |
| `quantum_fabric_metal` | **the fabric's Metal member**, opt-in and not in `full`, macOS: the gate kernel in the Metal shading language with exact 64-bit integers, compiled at run time by the operating system's own compiler, one serial dispatch per gate in one command buffer, the state in memory the GPU and the host share. Elsewhere the build finds no member and says why. Each device is probed against the CPU's arithmetic in the process that uses it and certified bit-exact by reproducing the CPU reference's pinned corpus digests, keyed by its GPU family number (`gpu-msl-<family>`). On a GPU with SIMD-group matrices, a **second kernel forms every product with the matrix multiply** (`MetalMember::matrix`): each value as four 8-bit limbs in bf16, accumulated in f32, which holds every partial sum exactly; probed and certified under its own implementation id, with its own mutants. Under operating system 26 or later, a **third kernel forms every product with the shading language's tensor operation** (`MetalMember::tensor_ops`), which the platform maps to the GPU's matrix hardware where it has it: offset-binary 8-bit limbs in bf16, accumulated in f32, through per-threadgroup scratch |
| `quantum_fabric_hip` | **the fabric's HIP member**, opt-in and not in `full`, Linux: the CUDA member's kernel text, unchanged, compiled at run time by HIP's runtime compiler for each device's own architecture, one launch per gate. The runtime and its compiler are loaded when first used, so a build with the feature runs on a host without them and finds no member there, saying why; the device's properties are read in the runtime's frozen layout or the device is refused. Probed and certified as the CUDA member is, under its own implementation id, and with `quantum_sv` the dense f64 state vector runs bit for bit as on the CPU. On a gfx11 GPU, a **second kernel forms every product with the bf16 matrix instruction** (`HipMember::wmma`): each value offset-binary, as four unsigned 8-bit limbs, because the instruction's accumulation is not exact once a negative term enters a sum; the offset is removed in 64-bit integers. Probed and certified under its own implementation id, with its own mutants |
| `quantum_fabric_opencl` | **the fabric's OpenCL member**, opt-in and not in `full`, native targets only: the same exact 64-bit kernel in OpenCL C, built at run time by each device's own compiler, one launch per gate, on any OpenCL GPU or CPU (an OpenCL accelerator is refused: no fabric class names it). The ICD loader is opened when first used, so a build with the feature runs on a host without OpenCL and finds no member there, saying why. Each device is probed and certified as the CUDA member's are, and keyed by its vendor id (`opencl-<kind>-<vendor id>`). With `quantum_sv` too, the dense f64 state vector runs bit for bit as on the CPU on every device with binary64 (contraction off); a device without it refuses, saying so |
| `quantum_fabric_fpga` | **the fabric's FPGA member, simulated**, opt-in and not in `full`, native targets only: the gate datapath in Verilog (each 32×32 product from four 16-bit partial products, the size of an FPGA's multiplier blocks; a state RAM; one pair per two cycles), compiled at run time by Verilator into a cycle-accurate simulation driven over a pipe. Probed and certified as the other members are, and every certificate says it was earned in a simulator, so placement ranks it after silicon. A host without Verilator finds no member and says why |
| `quantum_fabric_npu` | **the fabric's neural-processor member**, opt-in and not in `full`, macOS only: each 32-bit operand split into eight 4-bit limbs, every limb product and limb sum formed in fp16 on the platform's neural processor (each value an integer fp16 holds exactly, whatever order it is added in), the host assembling each product and applying the fixed-point arithmetic. The member exists only where the platform model runtime's compute plan places every operation of the model on the neural processor; a model it would run elsewhere is refused with the placement it reported. Probed and certified as every member is |
| `quantum_fabric_npu_cores` | **the fabric's npu-cores member**, opt-in and not in `full`, Linux: the gate's fixed-point arithmetic on one compute core of a neural processor's tile array, programmed directly rather than through a model runtime: exact 64-bit products on the core, the host gathering each gate's pairs and checking each row's range. At run time the member finds the device by its driver, builds the core's program with the tile array's open toolchain (`WAI_QUANTUM_NPU_CORES_PYTHON` names its Python; the program is cached per variant, generation and toolchain) and compiles its host side against the device runtime. Each of the three kernel mutants is its own program and must be caught. Probed and certified as the other members are; its certificates' provenance is silicon |
| `quantum_fabric_tensor_engine` | **the fabric's tensor-engine member**, opt-in and not in `full`: the gate's products as exact limb convolutions on a tensor processor's matrix engine, one bf16 matrix multiply per tile of pairs accumulated in fp32 (four 8-bit limbs per value, which bf16 holds exactly; every partial sum an integer below `2^24`, which fp32 holds exactly in any order), the host assembling the products and applying the fixed-point arithmetic. The kernel runs as a helper under the engine's kernel toolchain (`WAI_QUANTUM_TENSOR_ENGINE_PYTHON`); where its target is that toolchain's simulator, every certificate says so. Four mutants must be caught, nine-bit limbs the engine cannot hold among them |
| `quantum_fabric_sme` | **the fabric's matrix-extension member**, opt-in and not in `full`, aarch64 only: the gate's fixed-point arithmetic in the processor's streaming vector mode (SME), 64-bit lanes, the host gathering each gate's pairs and checking each row's range. Every instruction it uses exists only in that mode, so a kernel that ran, ran there. Detected by the processor's feature flags (on Linux, the kernel's `AT_HWCAP2`, which a user-mode emulator supplies); under an emulator the runner says so (`WAI_QUANTUM_SME_EMULATOR`) and every certificate carries it. Three kernel mutants are compiled in and must be caught |
| `quantum_fabric_dsp` | **the fabric's DSP vector-unit member**, opt-in and not in `full`, in a build for the signal processor with its vector unit in 128-byte mode: the gate's fixed-point arithmetic in 32-bit lanes, each 64-bit value a pair of words, every product the vector unit's exact 32×32 multiply and every carry and borrow kept; the host gathers each gate's pairs and checks each row's range. Its instructions exist only on that unit, so a kernel that ran, ran there. Under an emulator the runner says so (`WAI_QUANTUM_DSP_EMULATOR`) and every certificate carries it. Three kernel mutants are compiled in and must be caught. Its class is `dsp` |
| `quantum_fabric_vector` | **the fabric's CPU vector-unit members**, opt-in and not in `full`: the gate's fixed-point arithmetic in the processor's own vector extension, one kernel per instruction set, and one member per set the processor has — `avx2` (x86-64, 256-bit), `avx512` (x86-64, 512-bit, with the unit's own 64-bit arithmetic shift), `sve` (aarch64, the scalable vector extension, any length) and `rvv` (riscv64, the vector extension 1.0, any length) — each operand sign-extended to 64-bit lanes, the host gathering each gate's pairs and checking each row's range. The scalable kernels set their length per pass; the member reads the length from the unit and names it in its id and detail. Detected by the processor's feature flags (on Linux, `AT_HWCAP` for the vector extension, which a user-mode emulator supplies); under an emulator the runner says so (`WAI_QUANTUM_VECTOR_EMULATOR`). Its id extends the CPU reference's, so placement with no energy figures keeps the reference. Three kernel mutants per instruction set are compiled in and must be caught |
| `quantum_fabric_dataflow` | **the fabric's dataflow member**, opt-in and not in `full`, Linux: the gate's fixed-point arithmetic on the first RISC-V core of each of 32 compute tiles of a dataflow accelerator, each over a contiguous slice of a gate's pairs. The program is built in this crate (`quantum_fabric::rv32`, an RV32IM encoder whose listings an independent assembler reproduces word for word): every 64-bit value a pair of words, `mul`/`mulh` for products, `sltu` for carries and borrows. The device's library (`WAI_QUANTUM_DATAFLOW_LIB`, loaded at run time) presents the device as a PCI endpoint; the host opens two memory windows on each tile, holds its cores in reset, writes the program at the reset address and that tile's parameters and slice beside it, releases the first cores and clocks the device until every tile reports done. The device is named by its PCI ids (`dataflow-1e52-<device>`); the library is a simulator, and every certificate says so (`WAI_QUANTUM_DATAFLOW_SIMULATOR`). Three kernel mutants are compiled in. On the device generation whose vector engine multiplies 23-bit numbers, a second member (`-vector`) runs the gate on that engine, 32 lanes at a time: the first core configures the tile's unpacker and packer and hands the tile its instructions inline (`quantum_fabric::tensix`, transcribed from the simulator's own table and checked against it; `quantum_fabric::vector_engine`), each 32×32 product from four 23-bit partial products |
| `full` | everything |
Default features are `quantum`, `quantum_toolchain`, `quantum_receipt`.
## Speed
Byte-exactness is the contract, so the simulator is optimised only in ways that
cannot move a single amplitude: identity does nothing, a diagonal gate phases half
the state with one multiply rather than four, and `X` — so `CX` — is a swap with no
arithmetic at all. `fxmul(ONE, x) == x` exactly in this fixed point, which is what
makes those paths provably identical rather than merely close, and they are checked
against the previous implementation amplitude by amplitude.
An all-real matrix — `H`, and any real rotation — halves its multiplies too, since
the imaginary cross terms are multiplications by exactly zero.
At 20 qubits that is 8.9x on `Z`, 7.1x on `X`, 4.6x on `CZ`, 4.3x on `CX`, 3.4x on
`T`, 1.9x on `Y` and 1.8x on `H`.
## Utility scale
`quantum_spd` evolves an observable instead of a state, so a circuit costs what
its non-Clifford rotations make it cost rather than `2ⁿ`:
```sh
cargo run --release --example utility --features quantum_spd -- 0.2 20 1e-4
```
computes ⟨Z₆₂⟩ after 20 Trotter steps of the 127-qubit heavy-hex kicked-Ising
circuit in a fraction of a second, with the bound on how far truncation can have moved
it. `--example utility_mz` checks the 5-step magnetization against the exactly
computed values for every angle, and `tests/utility_reference.rs` holds the
published references. `quantum_bptn` computes the same circuits as tensor
networks (`--example utility_bptn`), so a result can be checked by a second
method that does not share the first one's approximation.
## Fault-tolerant resources
What a program would need on a machine that does not exist yet is a resource
estimate, and claims about that machine stand on one. `quantum_resource` makes
the estimate a deterministic function of its inputs:
```sh
wai-quantum estimate factoring # 2048-bit factoring, six reference qubits
wai-quantum estimate chemistry --qubit ns-e4 --frontier
wai-quantum estimate factoring --qubit ns-e4 --receipt | wai-quantum verify
```
The model is the planar-ISA one of arXiv:2211.07629: surface and Floquet-code
patches, lattice surgery, and 15-to-1 distillation factories chosen by
exhaustive search over unit types, distances and copy counts. The tests
reproduce that source's own tables:
- every code distance and factory of its per-qubit factoring table, down to the
copy counts;
- the distance, factory count, physical qubits and runtime of all twelve
factoring and chemistry rows of its summary table;
- all twelve factory counts of its dynamics rows. Factoring on the `(ns, 10⁻⁴)`
qubit comes out at `d = 13`, 18 factories, 8,716,258 physical qubits and
17 h 43 min.
Holding the model to those tables exposed places where the source's prose and
its numbers disagree, and one factory that is not the minimum of its own model.
Each is documented in the module and settled by the tables.
A sealed estimate names its whole job (counts, qubit, code, budget, slowdown and
search limits, to the bit). Re-running it anywhere must reproduce every figure,
down to each factory round, and the bytes are the same natively and as a WASI
component.
## Optimisation
```sh
wai-quantum qio --gset G22 --method dsb --dt 0.5 --steps 20000 --trials 64 --target 13359
wai-quantum qio --gset G14 --method sa --steps 300000 --beta0 0.2 --beta1 4 --target 3064
wai-quantum qio --sk 24 --method exact --spins # the true ground state, for small problems
```
Optimisation is the claim made most often for quantum hardware, and every
such claim is a comparison against a classical solver. `quantum_qio` is a
re-runnable one. It offers:
- simulated bifurcation (ballistic, discrete, and both with heating);
- simulated annealing;
- single-flip descent;
- an exact referee that settles small instances.
A result is a spin configuration, so anyone can re-check its cut or energy
in one pass. On the G-set Max-Cut benchmark the best-known cut is reached on
G1, G2, G3, G11, G14, G22 and G43. On G55 the best found is 10,292 against
10,299. The module documents each setting and success rate, and the bound
that sparse graphs put on the time step.
## Spin chains
```sh
wai-quantum dmrg -n 200 --bond 64 --sweeps 4 # critical Ising chain, against its exact energy
wai-quantum dmrg --chain heisenberg -n 100 --bond 128 # entanglement profile and discarded weight included
```
Claims that classical computers cannot simulate a material are claims about
entanglement. For one-dimensional systems the density-matrix renormalization
group usually can simulate it, with an error it reports itself.
`quantum_dmrg` is that method, held to exact answers:
- full diagonalisation for short chains;
- the free-fermion solution of the transverse-field Ising chain at any length.
At 200 sites the critical Ising chain comes out within about `10⁻¹¹` per site
of its exact energy. Runs repeat bit for bit at any thread count, natively and
as WebAssembly.
## Time evolution
```sh
wai-quantum tdvp -n 100 --bond 64 --dt 0.1 --t 4 # critical Ising quench, against free fermions
wai-quantum tdvp --chain heisenberg -n 100 --bond 64 --t 3 # the Néel state melting, entanglement included
```
A quantum simulation of dynamics is checkable when a classical method can
follow it. `quantum_tdvp` evolves a matrix-product state by the
time-dependent variational principle and reports what it gave up: the
discarded weight, the energy drift and the entanglement at every bond. It is
held to exact evolution of every amplitude on short chains, and to the
free-fermion solution of the Ising quench at any length, including the
Loschmidt echo.
On the 100-site critical Ising quench at bond 64, every site's `σˣ` stays
within `10⁻⁹` of the exact answer through `t = 3`, with the Loschmidt rate
agreeing to seven digits. When the entanglement outgrows the bond, the error
rises with the discarded weight, and the run says so. A chain small enough to
fit the bond evolves exactly, to rounding, at any time step. Runs repeat bit
for bit at any thread count, natively and as WebAssembly.
## Molecules
```sh
wai-quantum chem --fcidump h2o.fcidump --bond 64 --sweeps 2 # against Hartree–Fock and full CI
```
Quantum chemistry is where quantum computers are most often said to pay off,
and an energy claim for a molecule is checkable when a classical method
reaches the same number. `quantum_chem` reads a molecule's integrals, writes
its Hamiltonian as an exact matrix-product operator, and finds the ground
state by DMRG, held to full configuration interaction computed in the same
crate. LiH and water reach full CI to `10⁻¹³` in one sweep. N₂, on 20 spin
orbitals at bond 64, comes within `4·10⁻⁴` of it, and reports the discarded
weight that accounts for the difference.
## Neural quantum states
```sh
wai-quantum nqs --lx 8 --exact --steps 200 --lr 0.1 # every configuration enumerated: no sampling noise
wai-quantum nqs --model ising --lx 4 --ly 4 --h 3.044 --alpha 1 --steps 400
wai-quantum nqs --model j1j2 --lx 8 --periodic --complex --exact --steps 250 --lr 0.1 # frustrated: the sign is learned
wai-quantum nqs --lx 10 --periodic --complex --project --kpi --odd --exact --steps 200 --lr 0.1 # held in its sector
```
Neural-network wavefunctions are offered as evidence about systems that no
exact method reaches. `quantum_nqs` trains one the standard way and holds it
to exact answers. On a 4 × 4 lattice at the Ising model's critical field, it
lands within its own error bar of exact diagonalisation. Past exact reach,
the same Hamiltonian goes to DMRG through its exact MPO, so two independent
methods meet on one number. For frustrated models, whose signs no rule gives,
a complex network learns them. On the Majumdar–Ghosh ring it reaches the
exact energy to rounding. Projected onto a lattice's translations and the
global spin flip, a network is held in the sector the ground state lives in.
Rings reach their exact energies to rounding, and the frustrated 4 × 4 torus
at `J₂ = 0.5` comes within a percent.
## Noisy circuits
```sh
wai-quantum noisy --file circuit.jsonl --depol2 0.01 --depol1 0.001 --readout 0.01 --trajectories 4000 --xeb
wai-quantum noisy --file circuit.jsonl --damping 0.02 --expect "Z0; X3 X4" --exact
```
Every quantum-advantage experiment so far runs on noisy hardware and reports
a fidelity. For random-circuit sampling that fidelity is a cross-entropy
estimate, compared against a digital error model that multiplies the success
probabilities of every gate and readout. `quantum_noisy` checks that
arithmetic three ways:
- quantum trajectories on the state vector;
- the exact density matrix, for registers up to 12 qubits;
- the model itself.
On random brickwork circuits under depolarizing noise, the exact fidelity sits
above the model's prediction by a few percent. The margin grows with the error
rate, not with depth, and it is wider for circuits that do not scramble. The
module tabulates the margin.
## Fast decoding
```sh
wai-quantum qec -d 9 --p 0.005 --shots 20000 --decoder uf # union-find
wai-quantum qec -d 9 --p 0.005 --shots 20000 --decoder exact # exact matching, same shots
```
A fault-tolerant machine must decode each round of syndromes before the next
arrives. `quantum_uf` is the union-find decoder over the matching graph that
exact matching uses. Clusters grow from the fired detectors and merge as edges
fill, then each cluster's spanning tree is peeled to a correction. Its time per
shot grows linearly with the number of fired detectors. On the same shots it
fails between 0.92 and 1.18 times as often as exact matching. The module
tabulates both decoders by distance and noise, with the time each takes.
## qLDPC memory
```sh
wai-quantum ldpc --code 144 --p 0.004 --cycles 12 --shots 1000 # failures per cycle, both halves
wai-quantum ldpc --circuit --code 72 --cycles 6 --p 0.003 # the circuit itself
```
High-rate codes are where most of the projected qubit savings in fault
tolerance come from, and their headline numbers are logical failure rates per
syndrome cycle under circuit noise. `quantum_ldpc` re-derives them for the
bivariate-bicycle family (arXiv:2308.07915):
- the codes are built from their polynomials;
- the depth-8 syndrome cycle is written out gate by gate;
- the circuit is sampled with the Pauli-frame simulator;
- its error model is decoded with belief propagation plus ordered statistics.
The source published its simulation software, and running it gives the
oracle. On the 72-qubit code the derived error model has the source's columns,
detector for detector, and on identical syndromes the decoder makes the
source's decision shot for shot. Logical failure rates track the source's;
the one open residual, 2.3σ on one half at the highest noise, is documented
in the module. On the 144-qubit code the rates land on the source's published
curve.
## Architecture
```sh
wai-quantum arch factoring --bits 2048 # the whole machine, region by region
wai-quantum arch storage --target 1e-15 # cheapest plain, row- and grid-yoked layouts
wai-quantum arch cultivate --p 1e-3 --target 1e-7
```
Most of the recent fall in projected fault-tolerant cost comes from the
architecture around the code, not from better qubits. Idle qubits sit in yoked
storage (arXiv:2312.04522). T states are cultivated inside one patch rather
than distilled (arXiv:2409.17595). The clock runs at the pace of the slowest of
lattice surgery, the magic-state supply and the control loop. `quantum_arch`
prices each of these.
It re-runs the 2025 estimate that 2048-bit factoring takes under a week on
under a million noisy qubits (arXiv:2505.15917).
- **Reproduced.** Its 897,864 physical qubits, its storage density of
429.03 qubits per logical qubit, and its Toffoli counts for every tabulated
key size, each to the reference implementation's own rounding.
- **Corrected.** Re-running it surfaced six places where the source disagrees
with itself, each documented in the module. Its hot-storage count is below
its own peak formula. Its cold storage assumes fractional blocks. Its
printed runtime is 14% above its own tallies. With every correction applied,
the machine needs 958,480 qubits and 4.3 days. The conclusion holds.
## Error correction at circuit level
An error-correction experiment is a noisy Clifford circuit, its detectors and
its logical observable. `quantum_frame` samples it, derives its detector error
model, and decodes it exactly:
```sh
wai-quantum qec -d 5 --p 0.003 --shots 100000 # surface-code memory, per-round logical error
wai-quantum qec --file circuit.txt --shots 100000 # any circuit in the ecosystem's text
wai-quantum qec --dem -d 3 # its detector error model
wai-quantum qec --fit # measure a and p* of P(d) = a·(p/p*)^((d+1)/2)
```
The model is checked against an independent implementation:
- the generated circuits are identical, byte for byte, across distances 2–15
and 1–8 rounds;
- the derived error models match mechanism for mechanism, to 10⁻¹² in
probability, across surface codes in both bases (rotated and unrotated) and
repetition codes;
- decoded logical error rates agree point by point within sampling error.
`tests/frame_reference.rs` keeps two of those fixtures in the repository. The
fitted code model comes out at `a ≈ 0.023`, `p* ≈ 0.0100`. That is a measured
value for the constants a resource estimate (`quantum_resource`) otherwise takes
on trust, and it can be fed straight into one.
## State vector
```sh
wai-quantum sv --file circuit.jsonl --top 8 # likeliest outcomes
wai-quantum sv --file circuit.jsonl --expect "Z0 Z1; X3"
wai-quantum sv --file circuit.jsonl --sample 1000 --seed 7
```
`quantum_sv` runs any gate at any angle on up to 32 qubits, in double
precision. `gates` provides the standard gates by name (H, S, T, √X, √Y, √W,
rotations, CX, CZ, iSWAP, fSim, …) for it and for the tensor networks. A
26-qubit, depth-20 random circuit runs in about nine seconds on one machine,
and the bits do not depend on how many threads ran it.
## Tensor networks
An amplitude of a circuit is a tensor network, and the order it is contracted
in decides whether it costs `2³⁰` operations or `2⁶⁰`. `quantum_tn` searches for
that order, slices it to fit memory, and contracts it:
```sh
wai-quantum tn --file circuit.jsonl --bits 0110… # one amplitude
wai-quantum tn --file circuit.jsonl --open 0,5,9 # a batch over three open outputs
wai-quantum tn --file circuit.jsonl --plan-only --cap-log2 30
```
Circuits are JSON lines, one gate per line: `{"q":[a,b],"m":[re,im, …]}`.
Each gate is split at the qubits it is block-diagonal on: a control, or a
qubit it is diagonal on. That qubit's part is an exact three-index delta,
joined to the rest of the gate by a bond of dimension 2, so a cut through a
controlled-Z costs 2 instead of the 4 of its two wires. Then every index
that some tensor allows only one value of is fixed there, so the input and
output projections run through diagonal gates: a controlled-Z beside a
projected output becomes scalars. On 61-qubit controlled-Z circuits of depth
8 to 20, the trees found on split, reduced networks cost 2.7 to 5.4 decades
less than on whole-gate ones. `--whole-gates` keeps every gate one tensor and
the network as built.
On single amplitudes of random circuits on the 54-qubit advantage-experiment
grid, the search finds trees of `10¹⁰·⁵` operations at 10 cycles and `10¹⁸·⁸` at
20, in seconds. An independently developed hyper-optimiser, given the same
networks, lands within a factor of 2.5 of these at every depth, in either
direction. The 54-qubit, 10-cycle amplitude, contracted here in 16 slices,
agrees with an independent contraction to 12 significant figures. The module
documentation states what slicing costs on deep circuits and what the scalar
executor can and cannot contract.
## Clifford circuits in a product basis
A Clifford circuit followed by one layer of single-qubit gates, any gates at any
angles, is out of the stabilizer tableau's reach. Its amplitudes are still a
sum over a graph state, and `quantum_cutrank` takes that sum one qubit at a
time. The table it carries has `2^r` entries, where `r` is the state's cut-rank
(its entanglement, in bits) across the cut the sum has reached. So the cost is
set by the widest cut along the order, not by the number of qubits.
`anneal_order` searches for an order with narrower cuts, and `work` reports the
entries the passes touch.
```sh
cargo run --release --example cutrank_qasm --features quantum_cutrank -- circuit.qasm cuts
cargo run --release --example cutrank_qasm --features quantum_cutrank -- circuit.qasm order 300000 1 > order.txt
CUTRANK_ORDER=order.txt CUTRANK_PRECISION=single \
cargo run --release --example cutrank_qasm --features quantum_cutrank -- circuit.qasm sample 1000 7
```
`order` anneals for the least work and prints the order it found. A move of
the search takes one qubit to another place, and only the cuts between the two
places are recounted, so 300 000 moves on the 70-qubit circuit below take a few
seconds. `sample` prints each exact sample with `2^n · p`.
A stabilizer tableau fixes a state only up to a global phase, and the graph
form inherits that. `PhasedTableau` carries the phase: alongside the tableau it
tracks one basis state of the support and its exact amplitude, a power of
`2^{-1/2}` times an eighth root of unity, gate by gate. A Hadamard reads the
stabilizer whose X part is that one qubit, which is a reduction of the
stabilizers. `ProductMeasured::scale` then brings every amplitude to the
circuit's own phase: by the ratio of the tracked amplitude to the graph form's
at the same basis state (`with_last` with identities), times whatever phase
the caller's lowering to Clifford gates dropped.
A 70-qubit graph-state sampling circuit has a nearest-neighbour Clifford bulk,
then a non-Clifford basis on every qubit. With an annealed order, every cut is
29 bits or fewer. On one workstation, one amplitude takes about half a second
and one exact sample 1.1 to 1.5 s, with a largest table of 4 GiB in single
precision. Amplitudes agree between orders and between precisions to about
10⁻⁷ relative.
## Gaussian boson sampling
```sh
wai-quantum gbs --squeezing 0.9,0.7,0.8,0.6 --eta 0.5 --seed 3 # exact click statistics
wai-quantum gbs --squeezing 0.9,0.7,0.8,0.6 --eta 0.5 --seed 3 --sample 20000 > s.txt
wai-quantum gbs --squeezing 0.9,0.7,0.8,0.6 --eta 0.5 --seed 3 --check s.txt
```
A photonic sampler's outcome probabilities are hafnians (photon-number
detection) or torontonians (threshold detection) of its Gaussian state.
`quantum_gbs` computes both exactly. They agree with an independent
implementation:
- 10⁻¹² for probabilities and for hafnians up to `20 × 20`;
- 10⁻⁷ at `36 × 36`.
`--check` holds a file of observed click patterns to the state's exact one-
and two-mode statistics. Those are computable for any number of modes, and
every sampler of the state must reproduce them.
## Determinism
Simulation is **byte-exact**: amplitudes are dyadic fixed-point, so a circuit
reconstructs to the same `statevector_hash` on every machine and every target.
The approximate methods (MPS truncation, sparse Pauli dynamics, the phasor/ML
layer) are *reproducible f64*: IEEE-754-strict, and identical given the same
inputs and seed on every platform. They are documented as such rather than
claimed byte-exact. Their `sin`, `cos`, `ln` and `atan2` are computed in-crate
from `+ − × ÷`, because platform math libraries differ in the last place — enough
that four of these layers once gave different bits natively and as a WASI
component. `tests/bit_identity.rs` pins one result from each, so any platform
whose arithmetic differs fails there.
A circuit carries the `Gateset` its phases come from, and its `circuit_hash`
names it, so the same gates in the two gatesets are different circuits.
`Circuit::new` and `Circuit::qft` build `wai.quantum.circuit2` (`Gateset::V2`,
container magic `WQC2`), whose table holds the integers nearest to each
`e^{2πi/2^k}`. `wai.quantum.circuit` (`Gateset::V1`, `WQC1`) is kept bit for bit
so that every file, hash and receipt made with it reproduces; its table deviates
from the ideal phase for `P(k ≥ 8)` and applies none for `k ≥ 19`. A circuit
read from a container takes the container's gateset, and one derived from
another keeps it.
A receipt separates the two halves of a cost honestly: **work** is
portable-exact (`n_ops · 2^n` amplitude updates, recomputed by the verifier, so a
sink cannot inflate it) and **energy** is measured-attested (only the signer can
vouch for its own silicon). Signatures travel between substrates because the
computation is reproducible — not because two runtimes agreed to trust each other.
An energy figure is only comparable with another when it says how it was
acquired — read from the silicon's own counter, from a calibrated instrument,
from a model, or a constant. `quantum_energy::Labelled` seals that acquisition
class, with its declared uncertainty, inside the receipt's signature, and
`LabelledQbom` does the same per entry of a bill of materials. A receipt sealed
without a label keeps exactly the bytes it always had. `MaybeLabelled` parses
and verifies a receipt in whichever form it arrives, and checks a job's link to
its calibration in either form. A label's declared uncertainty must be at
least the `0.5/√3` µJ (≈ 0.289 µJ) that rounding the figure to whole
microjoules adds: `joules_micro × relative_ppm` of at least 288 676.
## Upgrading from 0.3
- `Circuit::new` builds `Gateset::V2`. To reproduce or verify an artefact made
with 0.3, read its `WQC1` file, or set `c.gateset = Gateset::V1` on a circuit
built in code.
- `quantum::phase`, `quantum::inv_sqrt2` and `quantum::CAPABILITY` are removed;
`Gateset::phase`, `Gateset::inv_sqrt2` and `Gateset::capability` replace them.
- `to_wqc`, `circuit_hash` and `quantum_toolchain::circuit_id` return a `Result`.
They fail only on a circuit its gateset does not allow, so never on one that
has simulated.
- `Circuit` and `QuantumError` are `#[non_exhaustive]`, and `QuantumError` has a
`Contract` variant and a `kind()`.
- `quantum_fabric::certify_lanes` and `lanes::random_circuit` take a gateset.
- `from_wqc` refuses the circuit/1 payloads extensions/quantum-sim §8 lists;
`validate` refuses a gate with more than 255 controls, and a receipt's
`from_json` a qubit or op count its fields cannot hold.
## Also available
- A CLI (`wai-quantum` in the [`wai`](https://crates.io/crates/wai) crate) — run
circuits, emit OpenQASM, seal and verify receipts, native or under `wasmtime`.
- A WASI-HTTP component serving the stack as an ordinary HTTP handler.
- Browser demos and a course: <https://wai.transaction.science/quantum-ide>
## License
Apache-2.0