### wai-quantum: one OpenQASM 3 front end, every refusal and warning under a stable code

One reader, with the source position of everything it handles, for every surface: the job service, the command line, both MCP servers, the Studio, the desktop app, the edge component and the in-browser IDE.

- **Diagnostic codes** (`qasm::diag`): every refusal and warning the reader gives, and every construct it lowers, carries or keeps verbatim, has a code with its outcome (refused, lowered, carried, preserved, warned) and a one-line meaning. A diagnostic's text keeps the message people read and ends with its code (`line 3: unknown gate foo [Q103]`); as data it has its line, column and length. The table is `wai-quantum/docs/qasm-diagnostics.md`, which a test holds to the code's table, and is served by `wai-quantum diagnostics [--json]`, the `qasm_diagnostics` tool of both MCP servers and `engine_diagnostic_codes()` in the browser engine. A code never changes meaning once released. `lint` gives the code, the column and the length, and the warnings.
- **The language** (`qasm::lex`, `qasm::parse`, `qasm::elab`): `def` subroutines, inlined (classical arguments by value, qubits by reference, values returned, a returned measurement written into the caller's bit, bits of their own fed forward); `inv @`, `pow(k) @` and exact fractional powers, and `ctrl`/`negctrl` on any gate, user gates included, each lowered exactly and held to the matrix it must equal; `float` (16, 32 and 64 bits), `angle[n]` (held to n bits of a turn, so dyadic, with the rounding reported), `complex`, `uint`, `bool`, bit registers set by constants, arrays, casts and the built-in functions, computed with the crate's own functions; `while` (unrolled when its condition is known, run at most `@wai.max_iterations N` times on measured bits), `switch`, `break`, `continue`, `end`; conditions on measured bits with comparisons, `&&`, `||` and `!`, compiled to forward jumps and checked against every value of their bits; `output`, carried into the result; `delay`, `box`, `stretch`, `barrier` and gate durations, carried as timing and labelled in a result whose method applies no durations; `defcal`, `cal` and `defcalgrammar`, kept verbatim and never run; aliases, slices, index sets, physical qubits, `gphase`.
- **One grammar**: `quantum_toolchain::from_qasm` (the edge component's and the processor clients' import) reads through the same reader and applies the bit-exact circuit's restriction, refusing with the reader's codes (Q500 a non-dyadic angle, Q501 width, Q502 a dynamic program). A controlled gate the modifiers write stays one gate under all its controls, so `to_qasm`'s output reads back gate for gate. A new feature, `quantum_lang`, holds the reader without the lowerings.
- **A job's result** carries `outputs`, a `timing` label (`applied: false`, Q400) and the reader's `diagnostics`, each only when there is one, so a program with none has the result it always had.
- **Conformance** (`wai/quantum-conformance/qasm3/`): the specification's 21 example programs, unchanged, and 38 programs for the constructs with references, each with what the reader must do (an exact distribution or outcome, equivalence to a reference, or a code). `stdgates.qasm` holds every standard gate to its definition in `U` and `CX`. Run natively and under wasm32-wasip2 (`wai-quantum-lang.yml`) and in the browser build (`wai-web-wasm.yml`: wasm32 count 8 to 9, native `quantum_engine::` count 14 to 15).
- **Feature matrix**: `wai-quantum/docs/qasm-feature-matrix.md`, every construct of OpenQASM 3.1 with what the reader does with it and its code.
- **Changed refusals**, each now read: `inv @`, `pow @`, a control on `rz`, `while`, two registers and gate definitions in `from_qasm`; a loop's integer sharing a gate parameter's name; `^` between integers under `OPENQASM 3` (exclusive or). A bare radian number in `from_qasm` is now held to the reader's dyadic tolerance, where a number within 1e-9 of a dyadic angle was rounded to it.

