wai-quantum: QIR and jeff read and written on every surface, each conversion checked, bounded against hostile input #554
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/quantum-interchange"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Programs now move between OpenQASM 3, QIR and jeff. The engine reads QIR (1.x and 2.x, under the profile its entry point names) and jeff 0.3, and writes both. Every conversion is checked by the equivalence ladder, and the result says how. Every surface takes the other formats: the command line, both MCP servers, the job service, the browser engine, the Studio and the desktop app. The readers are bounded against hostile input, and a seeded mutation test over the whole conformance set holds them to that natively and under wasm32-wasip2.
What it adds
QIR (
engine::formats, LLVM text)jeff (format 0.3, through a small Cap'n Proto reader and writer of the crate's own)
Refusals and checks
Q700–Q721) and its place.convert()checks each conversion with the equivalence ladder: written back to its format, read again and compared. The answer names the check and each of the reader's notes with its code.The conformance set (
wai/quantum-conformance/formats/)Surfaces
wai-quantum convert FILE --to qasm|qir|jeff [--profile base|adaptive] [-o FILE] [--json], the conversion checked and its notes on standard error. Every verb that reads a program reads.ll,.qirand.jeffby extension, or by the global--from.convert_program(one definition, from the engine), its answer the tools schema's newconvert. The command line's run tools (run_quantum_circuit,plan_quantum_circuit,run_on_target) take a program'ssource, as the service's do: one schema (engine::formats::source_schema) and one refusal, the reader's code before the job layer's.POST /v1/convertwithin its bounds. A job may carry its program as{"source": {"format", "program" | "program_base64"}}in place ofqasm, read before anything else reads it.engine_convert..ll,.qirand.jeffbeside.qasm. The engine reads the file to OpenQASM 3 in the worker, and the program goes into the editor as a version from the file. The line under it names the format, its version, the check and the reader's notes. A module the reader refuses leaves the editor as it was, with the refusal and its code in the status line.convertcommand.docs/formats.md(its commands run under the documentation check), the engine, CLI and service READMEs with their translations, and the changelog.Bounds against hostile input
Q111). Before, one of 2³² − 1 qubits asked for 34 GB, and under wasm32-wasip2 it trapped.u32::MAXoverflowed a 32-bitusize), and counts each list element against the words it may visit.Q210), and no longer truncates a 64-bit size, index, selector or shift.tests/formats_mutation.rsmutates every QIR and jeff file of the conformance set from a fixed seed: 45 153 inputs, with bits flipped, files cut short and spliced, and every length, count, offset and 32-bit field inflated. Each must convert or be refused with a code of the table, within 20 s and 1 GiB as measured by a counting allocator.wai-quantum-formats.ymlruns it natively and under wasm32-wasip2 (a release build with overflow checks), the count pinned.Two more fixes:
sourcetwice and then refused their own expanded run withJ003. Reading a source is now idempotent.GET /v1/healthbefore each POST and waits when none are left. CI starts each instance it smokes withWAI_QSVC_CLIENT_BURST=60, so it never waits there.Checked
formats_conformance: 2 passed. Mutation test: 45 153 inputs held (16 627 converted, 28 526 refused with a code; slowest 0.868 s; largest peak 245 MB). wasip2 under wasmtime: conformance 1 passed; mutation test (release, overflow checks on) 1 passed, slowest 0.689 s, peak 149 MB. CLI and service smoke: every check held. Breaking gate: no unacknowledged break. Repository checks: all 10 lines ok.check_docs.py --cli --service --rustagainst a local service:docs/formats.md, the CLI README and its zh-CN page (28 shell blocks, 28 receipts), the service README (5 blocks, 3 receipts),docs/READMEand its zh page, the Studio README and its zh page, the engine README and its zh page. All passed.mcp::: 14 passed. CLI: 71 passed (bin) and every integration target. Service: 37 + 1. wai-web native: 28 passed. Engine--features full --lib: 1111 passed.formats_conformance: 2 passed. Mutation test: 45 153 held (slowest 0.815 s). CLI smoke: every check held. Service smoke in three windows: CI's (burst 60) in 4 s, never paced; production's default (30 in 600 s) in 601 s, paced twice; a small one (3 in 20 s) in 205 s, paced 26 times. Breaking gate: no unacknowledged break.build-views --checkpassed after the views page was rebuilt (see below).studio.test.mjsrun twice: every check passed, including a QIR module opened and checked, a jeff module with itsQ715notes, and a base-profile module refused withQ704and the editor kept. Desktop: 19 passed, includinga_program_in_another_format_opens_in_the_app; clippy clean.55524840fwai-conformance.yml(two arm64 jobs built without debuginfo). Nothing was run again by hand for it; this PR's CI runs every leg.The views page. The Studio's Open names QIR and jeff in
locales/*/frame.json, which the views page is built from, so the page was rebuilt (fbe0cb0fb) withwai/wai-quantum-views/build.shincatthehacker/ubuntu:act-22.04with Rust 1.98.0, as the views workflow rebuilds it.Two tests that write QIR 1 need
quantum_qir, whichquantum_enginedoes not include, so they carry#[cfg(feature = "quantum_qir")]. Two pulse tests that seal their answers carry#[cfg(feature = "quantum_receipt")]. The contract workflow's test build compiles again, and the formats workflow still runs all four in the full build.Not done
Q720.Breaking
None. The breaking gate passes, and the changelog acknowledges no break.
🤖 Generated with Claude Code
The command line converts with `wai-quantum convert FILE --to qasm|qir|jeff [--profile base|adaptive] [-o FILE] [--json]`, the conversion checked and its notes on standard error, and every verb that reads a program reads QIR (.ll, .qir) and jeff (.jeff) by its extension, or by the global --from. Both MCP servers serve convert_program (the one definition, from the engine), its answer the tools schema's new convert; the job service answers POST /v1/convert within its bounds, and a job may carry its program as {"source": {"format", "program" | "program_base64"}} in place of qasm, read before anything else reads it. The Studio's engine has engine_convert. The agent docs are regenerated; both smoke scripts convert, run a QIR module and check a profile's refusal; the wasm32 and native pins in wai-web-wasm.yml move to 19 and 27. Co-Authored-By: Claude Opus 5.5 <[email protected]>run_quantum_circuit, plan_quantum_circuit and run_on_target on the command line's server take {"source": {"format", "program" | "program_base64"}} in place of qasm, read to the job's qasm first, as the job service's run tools now declare it too: one schema (engine::formats::source_schema) and one refusal, the reader's code before the job layer's. Reading a source is idempotent: a request whose qasm is what its source reads to (one read already, or sealed) reads as it is, and the service no longer refused its own expanded runs. The tools-list tests call each with a source and with a refusal; the agent docs are re-blessed. Co-Authored-By: Claude Opus 5.5 <[email protected]>