open-standards/wai/quantum-conformance/receipts/README.md
Transaction Science 67b52900b4
Some checks failed
wai-quantum editors / does this change touch it (push) Successful in 38s
WAI operation catalogue / does this change touch it (push) Successful in 52s
wai-quantum clippy / does this change touch it (push) Successful in 46s
wai-quantum contract / does this change touch it (push) Successful in 46s
wai-quantum pulse and dynamics / does this change touch it (push) Successful in 47s
wai-quantum for JavaScript / does this change touch it (push) Successful in 49s
wai-quantum OpenQASM reader / does this change touch it (push) Successful in 48s
wai-quantum other formats / does this change touch it (push) Successful in 50s
wai-quantum extension points / does this change touch it (push) Successful in 38s
wai-quantum error correction and mitigation / does this change touch it (push) Successful in 40s
wai-quantum for Python / does this change touch it (push) Successful in 41s
wai-quantum service / does this change touch it (push) Successful in 39s
wai-quantum service / service energy · linux packages (push) Failing after 34s
wai-quantum studio and desktop / does this change touch it (push) Successful in 41s
wai-quantum views in agent hosts / does this change touch it (push) Successful in 41s
wai-quantum variational and algorithm library / does this change touch it (push) Successful in 42s
wai-quantum verdicts and repairs / does this change touch it (push) Successful in 42s
wai-sink-android native sink library / does this change touch it (push) Successful in 19s
wai-sink-swift native sink package / does this change touch it (push) Successful in 44s
WAI Studio / does this change touch it (push) Successful in 45s
wai-quantum command line / does this change touch it (push) Successful in 9m2s
wai-quantum docs, course and locales / does this change touch it (push) Successful in 8m59s
wai-quantum resource estimation / does this change touch it (push) Successful in 9m0s
wai-audit collector and player integration / does this change touch it (push) Successful in 9m18s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 25s
WAI examples / WAI examples · does this change touch them (push) Successful in 25s
wai-quantum wasmQ / does this change touch it (push) Successful in 13s
wai-quantum contract / the policy is linked, and the deprecations page reads (push) Successful in 11s
wai-quantum editors / editors · linux (push) Successful in 3m52s
wai-quantum OpenQASM reader / corpus under wasm32-wasip2 (wasmtime) (push) Successful in 1m46s
wai-quantum clippy / clippy, warnings denied, every feature set · linux (push) Successful in 6m35s
wai-quantum OpenQASM reader / reader and corpus · linux (push) Successful in 2m37s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs under wasm32-wasip2 (wasmtime) (push) Successful in 2m42s
wai-quantum pulse and dynamics / reader, simulator and pulse jobs · linux, release (push) Successful in 3m43s
wai-quantum other formats / the set under wasm32-wasip2 (wasmtime) (push) Successful in 4m7s
wai-quantum contract / API compatibility · linux (push) Successful in 11m14s
wai-quantum extension points / the registry under wasm32-wasip2 (wasmtime) (push) Successful in 2m57s
wai-quantum for JavaScript / javascript · linux (push) Successful in 10m33s
wai-quantum other formats / readers, writers and the set · linux (push) Successful in 8m43s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 17m31s
wai-quantum views in agent hosts / views · the page and its engine (push) Successful in 4m32s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 2m20s
wai-quantum verdicts and repairs / the intent set and the verdict under wasm32-wasip2 (wasmtime) (push) Successful in 2m51s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux, release (push) Successful in 5m19s
wai-quantum verdicts and repairs / verdicts, repairs and the intent set · linux (push) Successful in 4m4s
wai-quantum for Python / python · linux (push) Successful in 8m23s
wai-quantum contract / schemas and the committed tool lists · linux (push) Successful in 18m12s
wai-quantum error correction and mitigation / codes, decoders, texts and mitigation · linux, release (push) Successful in 8m35s
wai-quantum studio and desktop / studio · browser (push) Successful in 7m41s
wai-quantum extension points / the registry and the example · linux (push) Successful in 11m7s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 12m12s
wai-quantum views in agent hosts / views · a scripted host (push) Successful in 11m13s
wai-quantum service / service · linux (push) Successful in 14m53s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (push) Successful in 13s
wai-quantum docs, course and locales / the course and the command line's languages · linux (push) Successful in 5m53s
wai-quantum resource estimation / estimation and calibration · linux, release (push) Successful in 7m21s
WAI Studio / Studio in WebKit · linux (push) Successful in 22m10s
wai-audit collector and player integration / collector · linux (push) Successful in 4m55s
wai-quantum wasmQ / the reference modules rebuild to their modules of record · linux (push) Successful in 1m26s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 4m59s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · linux (push) Successful in 5m40s
wai-quantum wasmQ / interpreter and vectors under wasm32-wasip2 (wasmtime) (push) Successful in 6m31s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 15m4s
wai-quantum command line / command line · linux (push) Successful in 39m2s
WAI examples / WAI examples · portable · linux (push) Failing after 29m19s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (push) Successful in 46m17s
wai-quantum pulse and dynamics / the same bits · macos (push) Successful in 1m25s
wai-quantum editors / editors · macos (push) Successful in 2m59s
wai-quantum for Python / python · macos (push) Successful in 3m33s
wai-quantum pulse and dynamics / the same bits · linux-arm64 (push) Successful in 3m17s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 4m17s
wai-quantum service / service · macos (push) Successful in 8m29s
wai-quantum variational and algorithm library / parameters, gradients, optimisers, VQE, QAOA and builders · linux-arm64, release (push) Successful in 3m28s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Successful in 11m6s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 8m1s
wai-quantum extension points / the registry and the example · linux-arm64 (push) Successful in 8m26s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 7m43s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 14m42s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 15m21s
wai-quantum command line / command line · macos (push) Successful in 2m29s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m6s
WAI examples / WAI examples · android-app · linux-arm64 (push) Successful in 11m41s
wai-quantum wasmQ / profile, engines, reference modules, adversarial, vectors · macos (push) Successful in 2m5s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (push) Successful in 30m40s
wai-quantum studio and desktop / desktop app · windows (push) Has been cancelled
wai-quantum-qpu: native-turns on its service's published API, a fifth basis gpi gpi2 ms, noise seeds, shot records with their leakage, cancel and a bounded estimate
The native-turns client read only a backend's qubits, sent zz to noise models
whose devices run only an MS gate, sent no noise seed, rebuilt counts from
probabilities where the service gives shot records, and could neither cancel
nor estimate. Each is fixed and tested against a fake built from the
service's published OpenAPI document (version 0.4), corrected where a
read-only positive control of the service (2026-11-12) answered otherwise
(tests/fake_turns/): it refuses every member and value the API does not
allow, answers the paths as the service did, runs the gates by the service's
own printed matrices, and answers in each published result format and bit
order.

- The backend from GET /backends/{backend}, which the service answers for
  simulator and for qpu.-prefixed processors (bare names are not found, the
  published enum notwithstanding): status available or refused, degraded
  stated, the simulator's noise models bounding the one sent,
  characterization_id as the calibration, a processor's pairs from its
  characterization; the list only for a noise model's device.
- Placement: device_target from a processor's characterization through the
  engine's backend-characterization import; an ms backend now reads as gpims
  exactly there.
- Gates: zz only where the backend lists it, else ms; under a noise model the
  modelled device's gates and qubits (the list's entry, else the published
  models). A program in another gate set, or a noise model on a processor, is
  refused before anything is sent.
- Basis::GpiMs (gpims): gpi, gpi2 and ms(phi0, phi1, theta), the first phase
  the first qubit's, theta 0 to 1/4 turn; each cz ms(0, 0, 1/4) between gpi2(1/4)
  and gpi2(3/4), every program the prx rz xx program gate for gate. Proved by
  the engine's equivalence check (the cz, frames into ms's phases, the phase
  order, whole programs); seven native vectors pinned and proved, gpizz among
  them for the first time. In the open protocol within version 1: schema,
  reference --basis gpims, an ms-past-a-quarter-turn refusal vector.
- The published matrices pinned: gpi2(0) is Rx(pi/2) and gpi2(1/2) Rx(-pi/2),
  as the matrix says and the prose does not.
- noise.seed from the job's seed (1 when none), sealed as /noise/seed in the
  receipt's execution and held to the seed the service says it ran.
- Results from shot records, else the service's counts, else probabilities,
  qubit 0 first in v2 bitstrings and bit arrays; records and counts must agree.
  Leaked shots are counted as read and sealed in a new optional member,
  leakage (quantum-providers 8.1, 8.4, both verifiers).
- Cancel (PUT /jobs/{id}/status/cancel, canceled read as cancelled); GET
  /jobs/{id}/cost after a run.
- Estimate: a gate-priced job is the rate card's figure for exactly its gates
  and shots, its minimum included, rounded up to the cent, admitted by a cost
  ceiling only where the service's own estimate is no higher; compute-time
  prices (the service's own: credits by the compute-second), estimates above
  the card, amounts in no currency or another currency meet no ceiling. The
  simulator is free and not asked (the service estimates processors only).
- Spec 4, 5.1, 8.1, 8.3, 8.4, 10; receipt corpus: five new made receipts and
  twelve crafted ones; crafted-kind-turns-shots is now valid.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-11 21:09:57 -05:00

136 lines
14 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.

# Job receipts
A job's receipt, as [the provider protocol's §8](../../extensions/quantum-providers.md#8-the-receipt)
states it, judged by two verifiers that share no code. Each must give every receipt here
exactly the reasons the manifest names (§8.4): none for a valid one.
| file | what |
|---|---|
| `manifest.json` | every receipt in `jobs/`, the reasons a verifier must give it, how it was made, and what it is. Every expectation is written by hand from §8.4; none is copied from a verifier's output |
| `jobs/cli-*.json` | made by the command line on this machine, sealed with the published demo key (`make.sh`): runs by several methods, a compile, runs on the reference provider over a local process, free and priced, and jobs under a contract (§8.7), here, routed to the person's providers and on a provider named under a ceiling |
| `jobs/cli-wasmq-*.json` | wasmQ jobs ([quantum-wasmq](../../extensions/quantum-wasmq.md)) made by the command line from the profile's own envelopes (`../wasmq/envelopes/`) with the demo key (`make.sh`): a run of the surface-code round, one of a single instance for the whole run, and faults in a call, of the run's budget, in an instance's init and in a prior |
| `jobs/cli-wasmq2-*.json` | wasmQ/2 jobs (quantum-wasmq §11) made the same way from the second version's envelopes: the exact method (a Toffoli, a feedback rotation, angle arguments, rotations and a reset), and one Clifford program by each method; each with the energy the host it was made on read of its run (§11.5) |
| `jobs/cli-landscape-*.json`, `jobs/cli-landscape2-*.json` | energy-landscape jobs the command line sealed with the demo key (`make.sh`), of the first version ([quantum-landscape](../../extensions/quantum-landscape.md)) and of the second ([quantum-landscape-2](../../extensions/quantum-landscape-2.md)): of each, a sampling run, a settle, a quench, a replay, a sweep, a comparison, and runs on the reference provider over a local process, free and priced (quantum-providers §11). The second version's sampling runs state their joules unpriced, and its settle and quench are priced |
| `jobs/cli-qudit-*.json` | qudit jobs (`wai.quantum.qudit/1`, [quantum-sim §9.7](../../extensions/quantum-sim.md)) the command line sealed with the demo key (`make.sh`): a qutrit Bell pair with its amplitudes, ququarts under a phase, two qudits of six levels, and three qubits as a qudit job of dimension 2 |
| `jobs/service-*.json` | made by the free job service, sealed with its key (`make.sh`) |
| `jobs/service-wasmq*-*.json`, `jobs/service-qudit-*.json` | made by a job service built from this checkout (`make.sh` with `WAI_QSVC_BIN`), each run as a job and sealed with its key: the surface-code round, a wasmQ/2 run by the exact method with the energy the service read of its worker, a fault sealed, and a qutrit Bell pair; each the service's report, whose own members nothing seals |
| `jobs/scripted-sampler-v2-post-selected.json` | a `sampler-v2` device that answered 13 fewer shots than it was asked for, as a post-selected readout does: its counts sealed as the shots it kept, `accepted_shots` (§8.1) (`wai-quantum-qpu/tests/clients.rs`, `a_device_that_keeps_fewer_shots_than_asked_seals_how_many_it_kept`) |
| `jobs/scripted-*.json` | provider jobs of every built-in kind (`sampler-v2`, `prx-circuits`, `native-turns` with and without a noise model, `cloud-tasks` on a processor and on its simulator, with rows of shots and with probabilities), each through a service that follows that provider's published contract, sealed with the demo key (`wai-quantum-qpu/tests/clients.rs`, `every_built_in_kind_states_what_it_sent_and_its_receipt_keeps_every_rule`, with `WAI_QUANTUM_RECEIPT_CORPUS` set to this directory); `prx-circuits` under a contract, its device's counts with a classical method's beside them (`a_built_in_kind_runs_under_a_contract_and_a_classical_method_shadows_it`); and `prx-circuits` in both its rows: `scripted-prx-circuits.json`, the client that sent circuits and shots alone, and `scripted-prx-circuits-pinned.json`, the job pinned to its calibration set with decoupling sent off; and `scripted-prx-circuits-recalibrated.json`, through a fake built from that service's published models that recalibrated between the read and the submission, the job pinned, placed by the calibration's quality metrics, and its result naming the set the service compiled against (`wai-quantum-qpu/tests/prx_circuits.rs`, `prx_circuits_pins_the_calibration_it_read`) |
| `jobs/scripted-native-turns-*.json` (but `-noise`) | `native-turns` against a fake of its service's published API (`wai-quantum-qpu/tests/native_turns.rs`, with `WAI_QUANTUM_RECEIPT_CORPUS` set): a processor read from the service's list, its counts tallied from shot records; one whose records flag three shots as leaked (`leakage`, §8.1); the simulator under a noise model, sent the job's seed (§8.3's seeded row); a processor of `gpi`, `gpi2` and `ms` (basis `gpims`); and a gate-priced processor named under a ceiling |
| `jobs/first-form-*.json` | sealed by the job service as it was on 18 October 2026 (commit 72d18742d), so by the first form's own writer, not by a restatement of it |
| `jobs/fixture-*.json` | the engine's pinned fixtures, sealed by earlier engines: a run before results named their engine, a provider job of the earlier form, and a compile |
| `jobs/crafted-*.json` | made by `generate.py` from the receipts above, each changed one way: the seal's form, the strict signature (a weak-key forgery, `S + ℓ`, a mixed-order key, …), the first form, what any JSON reader and writer may do (and so must change nothing), the strict reader, and each rule of a provider's result, of a wasmQ job's form and of an energy-landscape job's form in each version, each sealed again with the demo key where the change is inside the seal so that one rule alone breaks |
| `jobs/crafted-time-*.json` | receipts that seal a time (§8.2), made by `generate.py`: issued, issued with an end, the same times written as other numbers, the largest a receipt states; a time changed, taken off, given an end, or put on a receipt that sealed none (`digest_mismatch`: the time is inside the digest); and each thing that is not a time of its form (`receipt_form`) |
| `held/*.json` | receipts judged held to a trust list or a time beside their seal ([§8.8](../../extensions/quantum-providers.md#88-whose-key-and-when)), made by `generate.py`. The manifest's `held` names, for each, what it is held to and the reasons a verifier must then give: a key's window at its first moment, its last and its end; a revocation a millisecond before and at its time; a receipt that seals no time against a window with no end, one that ends, and a revoked key; a key the list does not name; a rotation, each key on each side of it; and a time before a receipt's end, at it, at its issue, before it, and within and past an allowance. They are kept apart from `jobs/`, whose verdicts are a receipt's alone, held to nothing |
| `trust/*.json` | trust lists (§8.8), made by `generate.py`: six a verifier reads (a key open from the start, in a window, revoked, retired by a rotation with the transition both keys signed, another key alone, and a window whose times are written as other numbers), and `refused-*`, each not of its form one way, which a verifier refuses whole: it judges nothing by one, and exits 2. The manifest's `trust_lists` says which is which |
The made receipts are kept as they were made, each pinned by its digest in `made.lock.json`:
a receipt missing or changed fails `generate.py --check`. A receipt made again differs in its
times (and, from the service, perhaps its key) and verifies all the same, so none is made again
to pass a test. A row of §8.3 that a client stops writing is held by the receipt that has it.
## The two verifiers
- `wai-quantum verify --json FILE` (and `--lines FILE`, one job a line): the reference,
`wai_quantum::engine::job::check`.
- [`../tools/receipt_verify.py`](../tools/receipt_verify.py): written in Python from §8
alone, by a reader who had not seen the reference. Its `wasmq_form`, a wasmQ job's form,
was written the same way from [quantum-wasmq §6.5](../../extensions/quantum-wasmq.md#65-verifying),
whose rules are numbered so that each can be read alone, and the second version's from
[§11.6](../../extensions/quantum-wasmq.md#116-verifying) there (rules 4, 8, 11, 12 and 30 as
that version reads them, and 36, its energy). Its `landscape_form`, an energy-landscape
job's form, was written from the numbered rules of
[quantum-landscape §5.4](../../extensions/quantum-landscape.md#54-verifying-an-answer), and
the second version's from the list in
[quantum-landscape-2 §5.4](../../extensions/quantum-landscape-2.md#54-verifying-an-answer)
(rules 2, 3, 6, 8 and 10 as that version reads them). Standard library only: its BLAKE3,
Ed25519, RFC 8785 text and strict reader are its own, each held to published answers by
`--self-test`.
[`../tools/receipt_differential.py`](../tools/receipt_differential.py) holds them to each
other:
```sh
python3 -I receipts/generate.py --check # the crafted half is as written
python3 -I tools/receipt_verify.py --self-test ../wai-quantum/src/engine/testdata/es-number-tostring.txt
python3 -I tools/receipt_differential.py --reference PATH/wai-quantum
python3 -I tools/receipt_differential.py --reference PATH/wai-quantum --plant lenient-key
python3 -I tools/receipt_differential.py --second-only # no build: the second verifier and the manifest
```
The differential requires, for every receipt here, that both verifiers and the manifest name
the same reasons, and that both verifiers state the same key, form, class read by provenance,
counts' source and the time the receipt seals. It gives both each receipt of `held/` with the
trust list and the time the manifest holds it to (`--trust`, `--at`, `--skew-ms`, which the
two take alike), and requires the manifest's reasons from both and the same statement of what
it was held to; and each list of `trust/`, which both must read, or both refuse whole. Then it changes every valid receipt one member at a time (each member of
its request, its result, its receipt and its unsealed envelope, removed, and its value
replaced) and requires the same reasons from both for every change, and two oracles beside
them: a change inside the request, the result or the receipt is never valid, and a change to
the unsealed envelope, or a member added to the receipt, never changes the verdict.
A change of one member is caught by the seal before any rule of a job's form is read, so
it cannot hold the two verifiers to those rules. The rules stage does: for each rule of a
wasmQ job's form ([quantum-wasmq §6.5](../../extensions/quantum-wasmq.md#65-verifying)),
the genuine wasmQ jobs changed at the rule's bound, on both sides of it where it has two,
and sealed again with the demo key, each with the verdict written for it by hand from the
text (`rule_cases` in the differential). Both verifiers must give every case its written
verdict, so a rule dropped or a bound moved in either one fails: this stage, and the
manifest, are what back "the two verifiers agree" on the form's rules. `--second-only`
runs it for the second verifier. Each crafted wasmQ receipt that names one rule breaks that
rule alone: the reference states one problem for it, and the second verifier that rule.
The labelled stage gives both verifiers the second verifier's own hand-labelled wasmQ cases
(`receipt_verify.py --wasmq-cases`), each as its exact text: the labels its author wrote from
the text bind the reference as they bind the second verifier, so one labelled corpus holds
both.
[`../tools/wasmq_mutants.py`](../tools/wasmq_mutants.py) weakens each rule in each verifier,
from the code (each check dropped, each comparison moved by one, a count or a digest read
loosely, a null member read as absent and an absent one as null, the most of many read as the
least), and requires the
differential (`--wasmq-only --first`) to catch every weakening, counted per rule:
```sh
python3 -I tools/wasmq_mutants.py python --reference PATH/wai-quantum
python3 -I tools/wasmq_mutants.py rust-schemata ../wai-quantum/src/engine/wasmq.rs ../wai-quantum/src/engine/wasmq2.rs mutants.json # in a scratch checkout
# build the command line from that checkout, then
python3 -I tools/wasmq_mutants.py rust --reference PATH/wai-quantum --mutants mutants.json
```
It also changes each number of the provider receipts to values past a double's whole numbers,
and sets a job's shots in both its request and its result, to see a limit one verifier has and
the other does not; and it seals those of the demo key again, so that each is judged by what it
says and not only by its digest.
`--plant NAME` runs the second verifier with a defect planted in it: a lenient key check,
`alg` unchecked, the last of a member named twice kept, inexact numbers let through, a
simulator's counts let pass as measured, a ceiling on every whole number, `R` of small order
let through, under a contract (§8.7) each route's outcome, the planner's choice or a
shadow's distance taken as it stands, a receipt's time taken as it stands with its digest read
as one that seals none, a key's window taken to hold its end, and a receipt that seals no time
placed in any window. The differential succeeds only when it catches the plant. That is the proof that
it can fail.
`--extra DIR` adds receipts a person holds and does not publish: both verifiers must find each
valid. A receipt from a cloud account's task names that account's number in its job id, and
the receipt seals it, so the corpus holds none: the shape of such a receipt is here
(`scripted-cloud-tasks-*`), and real ones are checked with `--extra`.
CI runs the whole differential beside the build of the command line
(`.github/workflows/wai-quantum-cli.yml`, job `cli-linux`), and the second verifier against
the manifest, with its plants, among the independent verifiers
(`.github/wai-conformance/verifiers/quantum-receipts.sh`).
## Making it again
```sh
bash receipts/make.sh PATH/wai-quantum receipts/jobs # the command line's and the service's
(cd ../wai-quantum-qpu && WAI_QUANTUM_RECEIPT_CORPUS=$PWD/../quantum-conformance/receipts/jobs \
cargo test --test clients -- every_built_in_kind a_built_in_kind_runs_under_a_contract) # the built-in kinds'
python3 -I receipts/generate.py # the crafted half and the manifest
```
Making them again replaces receipts a release already judged, and `--check` then fails: add
receipts under new names, and keep the ones there. A new name is added to `MADE` in
`generate.py`; `generate.py --pin NAME` records its digest, and refuses a name it holds.