wai: wasmQ, an OpenQASM 3 program and the WebAssembly its externs call, run the same everywhere, metered and receipted #659

Closed
dcharlot wants to merge 25 commits from wai/quantum-wasmq into main
270 changed files with 26928 additions and 349 deletions

View file

@ -1,6 +1,6 @@
# step: quantum job receipts · receipt_verify.py
# order: 701
# paths: wai/extensions/quantum-providers.md
# paths: wai/extensions/quantum-providers.md wai/extensions/quantum-wasmq.md
# working-directory: .
# independent: quantum-receipts media python3 -I quantum-conformance/tools/receipt_differential.py --second-only --corpus quantum-conformance/receipts
#
@ -16,6 +16,6 @@
python3 -I wai/quantum-conformance/receipts/generate.py --check
python3 -I wai/quantum-conformance/receipts/generate.py --self-test
python3 -I wai/quantum-conformance/tools/receipt_verify.py --self-test wai/wai-quantum/src/engine/testdata/es-number-tostring.txt
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only; do
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only wasmq-unchecked; do
python3 -I wai/quantum-conformance/tools/receipt_differential.py --second-only --plant "$plant" | tail -1
done

View file

@ -29,33 +29,44 @@ on:
- 'wai/wai-quantum/**'
- 'wai/wai-quantum-cli/**'
- 'wai/wai-quantum-qpu/**'
- 'wai/wai-wasmq/**'
- 'wai/quantum-conformance/eval/**'
- 'wai/quantum-conformance/wasmq/**'
- 'wai/wai-quantum-writer/**'
# The writer's model runs on this crate, which it path-depends on.
- 'jouleclaw/jouleclaw-rs/crates/jouleclaw-loader-gguf/**'
- 'wai/quantum-conformance/eval/**'
- 'wai/quantum-cross-simulator/**'
- 'wai/quantum-conformance/receipts/**'
- 'wai/quantum-conformance/tools/receipt_verify.py'
- 'wai/quantum-conformance/tools/receipt_differential.py'
- 'wai/quantum-conformance/tools/wasmq_mutants.py'
- 'wai/quantum-conformance/tools/referee.py'
- 'wai/extensions/quantum-providers.md'
- 'wai/extensions/quantum-wasmq.md'
- 'rust-toolchain.toml'
- '.github/workflows/wai-quantum-cli.yml'
# Nightly, beside the pushes: each rule's weakenings (below), which take a second build.
schedule:
- cron: '41 3 * * *'
pull_request:
paths:
- 'wai/wai-quantum/**'
- 'wai/wai-quantum-cli/**'
- 'wai/wai-quantum-qpu/**'
- 'wai/wai-wasmq/**'
- 'wai/quantum-conformance/eval/**'
- 'wai/quantum-conformance/wasmq/**'
- 'wai/wai-quantum-writer/**'
# The writer's model runs on this crate, which it path-depends on.
- 'jouleclaw/jouleclaw-rs/crates/jouleclaw-loader-gguf/**'
- 'wai/quantum-conformance/eval/**'
- 'wai/quantum-cross-simulator/**'
- 'wai/quantum-conformance/receipts/**'
- 'wai/quantum-conformance/tools/receipt_verify.py'
- 'wai/quantum-conformance/tools/receipt_differential.py'
- 'wai/quantum-conformance/tools/wasmq_mutants.py'
- 'wai/quantum-conformance/tools/referee.py'
- 'wai/extensions/quantum-providers.md'
- 'wai/extensions/quantum-wasmq.md'
- 'rust-toolchain.toml'
- '.github/workflows/wai-quantum-cli.yml'
@ -194,9 +205,27 @@ jobs:
python3 -I wai/quantum-conformance/receipts/generate.py --self-test
python3 -I wai/quantum-conformance/tools/receipt_verify.py --self-test wai/wai-quantum/src/engine/testdata/es-number-tostring.txt
python3 -I wai/quantum-conformance/tools/receipt_differential.py --reference wai/wai-quantum-cli/target/release/wai-quantum
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only; do
for plant in lenient-key no-alg last-duplicate no-inexact measured-simulator whole-cap lax-small-order-r no-canonical-spelling set-seal-only names-layout-only wasmq-unchecked; do
python3 -I wai/quantum-conformance/tools/receipt_differential.py --reference wai/wai-quantum-cli/target/release/wai-quantum --plant "$plant" | tail -1
done
# Each rule of a wasmQ job's form weakened in each verifier, from its code (the check
# dropped, a comparison moved by one, a count or a digest read loosely, a null member read
# as absent and an absent one as null), and every weakening caught by the differential:
# the second verifier's as files, the engine's as one build that holds every weakening,
# each switched on alone (wasmq_mutants.py). Counted per rule. Nightly.
- name: Each rule's weakenings caught, in both verifiers
if: github.event_name == 'schedule'
shell: bash
run: |
set -euo pipefail
python3 -I wai/quantum-conformance/tools/wasmq_mutants.py python --reference wai/wai-quantum-cli/target/release/wai-quantum --jobs 4
m="$RUNNER_TEMP/wasmq-mutants"
rm -rf "$m" && mkdir -p "$m"
git worktree add --detach "$m/wt" HEAD
python3 -I wai/quantum-conformance/tools/wasmq_mutants.py rust-schemata "$m/wt/wai/wai-quantum/src/engine/wasmq.rs" "$m/mutants.json"
(cd "$m/wt/wai/wai-quantum-cli" && CARGO_TARGET_DIR="$m/target" cargo build --locked --release)
python3 -I wai/quantum-conformance/tools/wasmq_mutants.py rust --reference "$m/target/release/wai-quantum" --mutants "$m/mutants.json" --jobs 4
git worktree remove --force "$m/wt"
# The release binary, pinned by version and SHA-256, rather than a build from source.
# Every WAI workflow that runs wasmtime pins this one version, and every run passes
# -W nan-canonicalization=y -W relaxed-simd-deterministic=y: every NaN a float
@ -264,6 +293,24 @@ jobs:
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y "$w" estimate --demo-key --json --qubit us-e3 < "$RUNNER_TEMP/est.qasm" > "$RUNNER_TEMP/wasi-estimate.json" 2> /dev/null
cmp "$RUNNER_TEMP/native-estimate.json" "$RUNNER_TEMP/wasi-estimate.json" || { echo "::error::an estimate differs under wasmtime"; exit 1; }
echo "the WASI component's output equals the native build's"
# verify gives its verdict at its own bound under wasm32 as natively: a job of 384 MiB,
# one of 2^22 values, and one more of each (too_large).
- name: The WASI component judges a job at verify's bound
shell: bash
working-directory: wai/wai-quantum-cli
run: |
set -euo pipefail
w=target/wasm32-wasip2/release/wai-quantum.wasm
n=target/release/wai-quantum
d=$(mktemp -d "$RUNNER_TEMP/bound.XXXX")
python3 -I tests/verify_at_bound.py "$d"
for f in long longer many more; do
$n verify --json "$d/$f.json" > "$d/native-$f.txt" || true
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir "$d" "$w" verify --json "$d/$f.json" > "$d/wasi-$f.txt" || true
test -s "$d/native-$f.txt" || { echo "::error::no verdict at verify's bound ($f)"; exit 1; }
cmp "$d/native-$f.txt" "$d/wasi-$f.txt" || { echo "::error::verify at its bound differs under wasmtime ($f)"; exit 1; }
done
rm -rf "$d"
cli-macos:
name: command line · macos

197
.github/workflows/wai-quantum-wasmq.yml vendored Normal file
View file

@ -0,0 +1,197 @@
name: wai-quantum wasmQ
# wasmQ (wai/extensions/quantum-wasmq.md): an OpenQASM 3 program and the WebAssembly its
# `extern`s call, run with the same result bytes and fuel on every host and sealed in a
# receipt (wai/wai-wasmq). Each leg runs the crate's tests on its host and checks the
# conformance vectors, which pin each run's whole job digest, so every leg passing is the
# claim that the bytes are the same on linux x86_64, macOS arm64 and wasm32. The linux leg
# also rebuilds the reference modules and requires the modules of record byte for byte.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches: [main]
paths:
- 'wai/wai-wasmq/**'
- 'wai/quantum-conformance/wasmq/**'
- 'wai/extensions/quantum-wasmq.*'
- 'wai/wai-quantum/**'
- 'rust-toolchain.toml'
- '.github/workflows/wai-quantum-wasmq.yml'
pull_request:
paths:
- 'wai/wai-wasmq/**'
- 'wai/quantum-conformance/wasmq/**'
- 'wai/extensions/quantum-wasmq.*'
- 'wai/wai-quantum/**'
- 'rust-toolchain.toml'
- '.github/workflows/wai-quantum-wasmq.yml'
jobs:
relevant:
name: does this change touch it
runs-on: linux
outputs:
run: ${{ steps.gate.outputs.run }}
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- id: gate
run: |
set -euo pipefail
r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-quantum-wasmq.yml \
"${{ github.event.pull_request.base.sha }}" \
"${{ github.event.pull_request.head.sha }}")
echo "this change touches wasmQ: $r"
echo "run=$r" >> "$GITHUB_OUTPUT"
native:
name: profile, engines, reference modules, adversarial, vectors · ${{ matrix.os }}
needs: relevant
if: needs.relevant.outputs.run == 'true'
strategy:
fail-fast: false
matrix:
os: [linux, macos]
runs-on: ${{ matrix.os }}
timeout-minutes: 60
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.99.1
shell: bash
run: |
export PATH="$HOME/.cargo/bin:$PATH"
command -v rustup >/dev/null 2>&1 || \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.99.1
rustup toolchain install 1.99.1 --profile minimal --component clippy
rustup default 1.99.1
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: The crate's tests, every engine of this host
shell: bash
working-directory: wai/wai-wasmq
run: |
set -euo pipefail
cargo test --locked --release --no-fail-fast 2>&1 | tee "$RUNNER_TEMP/wasmq.log"
if grep -q 'FAILED' "$RUNNER_TEMP/wasmq.log"; then echo "::error::a test failed"; exit 1; fi
# Every test file of the crate ran, and none ran empty: a file nobody runs, or
# one whose tests are all compiled out, would otherwise pass unseen.
for f in tests/*.rs; do
t=$(basename "$f" .rs)
awk -v t="tests/$t.rs" '$1 == "Running" && $2 == t { seen = 1; next } seen && /^test result: ok\. [1-9][0-9]* passed; 0 failed/ { ok = 1; exit } seen && /^test result:/ { exit } END { exit ok ? 0 : 1 }' "$RUNNER_TEMP/wasmq.log" \
|| { echo "::error::tests/$t.rs did not run and pass with at least one test"; exit 1; }
done
grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/wasmq.log" || { echo "::error::no test ran"; exit 1; }
- name: The vectors, each engine, and their digest
shell: bash
working-directory: wai/wai-wasmq
run: |
set -euo pipefail
for e in native interpreter interpreter-prepared; do
cargo run --locked --release -q --bin wasmq_vectors -- verify ../quantum-conformance/wasmq "$e" | tail -1
done
- name: Clippy, warnings denied
shell: bash
working-directory: wai/wai-wasmq
run: cargo clippy --locked --release --all-targets -- -D warnings
# wai-quantum holds a wasmQ job's form beside its receipts (engine::wasmq), and its
# engine builds without them; each feature set builds, without warnings.
- name: wai-quantum's engine with the receipts and without them
if: matrix.os == 'linux'
shell: bash
working-directory: wai/wai-quantum
env:
RUSTFLAGS: -D warnings
run: |
set -euo pipefail
cargo check --locked --no-default-features --features quantum_engine --lib
cargo check --locked --no-default-features --features quantum_engine,quantum_receipt --lib
modules:
name: the reference modules rebuild to their modules of record · linux
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: linux
timeout-minutes: 30
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.99.1 with the wasm32-unknown-unknown target
shell: bash
run: |
export PATH="$HOME/.cargo/bin:$PATH"
command -v rustup >/dev/null 2>&1 || \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.99.1
rustup toolchain install 1.99.1 --profile minimal
rustup default 1.99.1
rustup target add --toolchain 1.99.1 wasm32-unknown-unknown
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Build and compare
shell: bash
run: bash wai/wai-wasmq/modules/build.sh --check
- name: The sources the modules of record were built from
shell: bash
run: bash wai/wai-wasmq/modules/build.sh --sources
wasip2:
name: interpreter and vectors under wasm32-wasip2 (wasmtime)
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: linux
timeout-minutes: 60
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.99.1 with the wasm32-wasip2 target
shell: bash
run: |
export PATH="$HOME/.cargo/bin:$PATH"
command -v rustup >/dev/null 2>&1 || \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.99.1
rustup toolchain install 1.99.1 --profile minimal
rustup default 1.99.1
rustup target add --toolchain 1.99.1 wasm32-wasip2
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
# The release binary, pinned by version and SHA-256, with both determinism settings on
# every run (scripts/check-wasmtime-pin.py). Here wasmtime is the host the interpreter
# runs in; the modules the interpreter runs are interpreted, not compiled by it.
- name: Install wasmtime 50.0.1
shell: bash
run: |
set -euo pipefail
[ "$(uname -m)" = x86_64 ] || { echo "::error::the pinned wasmtime archive is x86_64; this host is $(uname -m)"; exit 1; }
if ! command -v xz >/dev/null 2>&1; then
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
$SUDO apt-get update -qq
$SUDO apt-get install -y -qq xz-utils
fi
v=50.0.1
f="wasmtime-v$v-x86_64-linux.tar.xz"
curl --proto '=https' --tlsv1.2 -sSfL -o "$RUNNER_TEMP/$f" \
"https://github.com/bytecodealliance/wasmtime/releases/download/v$v/$f"
echo "685466455dd42a14774a86c36c8f2e45cbb9bd6d92a850139315df60a75498a5 $RUNNER_TEMP/$f" | sha256sum -c -
tar -xJf "$RUNNER_TEMP/$f" -C "$RUNNER_TEMP"
echo "$RUNNER_TEMP/wasmtime-v$v-x86_64-linux" >> "$GITHUB_PATH"
- name: The tests under wasm32, the interpreter the only engine
shell: bash
working-directory: wai/wai-wasmq
run: |
set -euo pipefail
W=$(cd .. && pwd)
CARGO_TARGET_WASM32_WASIP2_RUNNER="wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir $W::$W" \
cargo test --locked --release --target wasm32-wasip2 --no-default-features --no-fail-fast \
--lib --tests 2>&1 | tee "$RUNNER_TEMP/wasip2.log"
if grep -q 'FAILED' "$RUNNER_TEMP/wasip2.log"; then echo "::error::a test failed under wasip2"; exit 1; fi
for f in tests/*.rs; do
t=$(basename "$f" .rs)
awk -v t="tests/$t.rs" '$1 == "Running" && $2 == t { seen = 1; next } seen && /^test result: ok\. [1-9][0-9]* passed; 0 failed/ { ok = 1; exit } seen && /^test result:/ { exit } END { exit ok ? 0 : 1 }' "$RUNNER_TEMP/wasip2.log" \
|| { echo "::error::tests/$t.rs did not run and pass under wasip2 with at least one test"; exit 1; }
done
- name: The vectors under wasm32
shell: bash
run: |
set -euo pipefail
cargo build --locked --release --target wasm32-wasip2 --manifest-path wai/wai-wasmq/Cargo.toml --no-default-features --bin wasmq_vectors
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir wai/quantum-conformance/wasmq::/v \
wai/wai-wasmq/target/wasm32-wasip2/release/wasmq_vectors.wasm verify /v interpreter,interpreter-prepared | tail -1

View file

@ -34,6 +34,7 @@ PHRASES=(
'[Nn]obody signs'
'[Nn]ot one signs'
'[Nn]one signs'
'\b[Nn]either\b[^.]* signs?\b'
'[Bb]est[- ]in[- ]class'
'\b[Bb]eats\b [A-Z]'
'\b[Ss]uperior(ity)?\b'

View file

@ -62,6 +62,13 @@ expect() { # expect <pass|fail> <what> [text the output must hold]
}
mk; expect pass "the pinned release, run every way with both settings, passes"
mk; mkdir -p "$tmp/wai/c"; printf '[features]\nwasmtime = ["dep:wasmtime"]\n[target.x.dependencies]\nwasmtime = { version = "=50.0.1", default-features = false }\n' > "$tmp/wai/c/Cargo.toml"
expect pass "a crate that pins the release exactly passes"
mk; printf '[dependencies]\nwasmtime = { version = "50", default-features = false }\n' > "$tmp/wai/c/Cargo.toml"
expect fail "a crate on a caret range of the release fails" 'a crate pins the release the workflows run'
mk; printf '[dependencies]\nwasmtime = "=49.0.2"\n' > "$tmp/wai/c/Cargo.toml"
expect fail "a crate on another release fails" 'depends on wasmtime =49.0.2'
rm -rf "$tmp/wai"
mk; rep "v=50.0.1" "v=49.0.2"
expect fail "another version" "downloads wasmtime 49.0.2"

View file

@ -21,7 +21,10 @@ requires that
a module path, and every `CARGO_TARGET_<triple>_RUNNER` that is wasmtime, passes
`-W nan-canonicalization=y` and `-W relaxed-simd-deterministic=y`;
4. at least one download and one run were found, so a check that looked in the wrong
place fails rather than passing on nothing.
place fails rather than passing on nothing;
5. every crate under wai/ that depends on wasmtime as a library pins it to that release
exactly (`version = "=PIN"`), so the engine a crate embeds is the one the workflows
run (wai-wasmq's native engine, extensions/quantum-wasmq.md §4.6).
check-wasmtime-pin.py [--root DIR]
@ -51,6 +54,9 @@ INVOKE = re.compile(
r"(?:^|[\s;&|(`/\"'=])wasmtime\s+(?:(?:run|serve|compile)\b|[^\s-]\S*\.(?:c?wasm|wat)\b)"
)
RUNNER = re.compile(r"CARGO_TARGET_\w+_RUNNER\s*[:=]\s*[\"']?wasmtime\b")
# A Cargo dependency on the wasmtime library, and the version it asks for.
CRATE_DEP = re.compile(r"^\s*wasmtime\s*=")
CRATE_VERSION = re.compile(r"version\s*=\s*\"([^\"]+)\"|^\s*wasmtime\s*=\s*\"([^\"]+)\"")
def logical_lines(text):
@ -130,13 +136,34 @@ def main(argv):
d, r = check_file(os.path.join(wf, name), f".github/workflows/{name}", findings)
downloads += d
runs += r
crates = 0
wai = os.path.join(root, "wai")
for dirpath, dirnames, filenames in os.walk(wai):
dirnames[:] = [d for d in dirnames if d not in ("target", "node_modules", ".git")]
if "Cargo.toml" not in filenames:
continue
path = os.path.join(dirpath, "Cargo.toml")
rel = os.path.relpath(path, root)
section = ""
for n, line in enumerate(open(path, encoding="utf-8").read().splitlines(), 1):
if line.strip().startswith("["):
section = line.strip()
continue
# Only a dependency table names a crate; `wasmtime = [...]` in [features] does not.
if "dependencies" not in section or not CRATE_DEP.match(line):
continue
crates += 1
v = CRATE_VERSION.search(line)
ver = (v.group(1) or v.group(2)) if v else None
if ver != "=" + PIN:
findings.append(f"{rel}:{n}: depends on wasmtime {ver or '(no version)'}; a crate pins the release the workflows run, \"={PIN}\"")
if downloads == 0 or runs == 0:
findings.append(f"found {downloads} wasmtime download(s) and {runs} run(s) under {wf}: this check looked in the wrong place")
for f in findings:
print(f"::error::{f}")
if findings:
return 1
print(f"check-wasmtime-pin: {downloads} downloads of wasmtime {PIN}, each checked against its digest; {runs} runs, each with both settings")
print(f"check-wasmtime-pin: {downloads} downloads of wasmtime {PIN}, each checked against its digest; {runs} runs, each with both settings; {crates} crate dependencies, each on ={PIN}")
return 0

View file

@ -108,6 +108,8 @@ printf 'Carriage is not a differentiator any more.\n' > "$tmp/differentiator.md"
printf 'It is not a rate-competitive codec.\n' > "$tmp/rate-competitive.md"
printf 'This is the moat <!-- allow-phrase: -->\n' > "$tmp/prose-empty.md"
printf 'WAI_MOAT_DIR <!-- allow-phrase: an environment variable name, not prose -->\n' > "$tmp/prose-reasoned.md"
printf 'Neither, in what they publish, meters the callout or signs what ran.\n' > "$tmp/neither-signs.md"
printf 'Neither engine appears in a receipt.\n' > "$tmp/neither-clean.md"
printf 'The decoder is integer all the way down.\n' > "$tmp/prose-clean.md"
expect 1 "prose: superiority" bash "$prose" "$tmp/superiority.md"
@ -119,6 +121,8 @@ expect 1 "prose: unclaimed" bash "$prose" "$tmp/unclaimed.md"
expect 1 "prose: fast win" bash "$prose" "$tmp/fast-win.md"
expect 1 "prose: differentiator" bash "$prose" "$tmp/differentiator.md"
expect 1 "prose: rate-competitive" bash "$prose" "$tmp/rate-competitive.md"
expect 1 "prose: neither ... signs" bash "$prose" "$tmp/neither-signs.md"
expect 0 "prose: neither, of our own two things" bash "$prose" "$tmp/neither-clean.md"
expect 1 "prose: an opt-out with an empty reason is not honoured" bash "$prose" "$tmp/prose-empty.md"
expect 0 "prose: an opt-out with a reason is honoured" bash "$prose" "$tmp/prose-reasoned.md"
expect 0 "prose: a clean file is clean" bash "$prose" "$tmp/prose-clean.md"

View file

@ -322,6 +322,7 @@ and a role are fixed once registered.
| `wai.quantum.circuit` | payload | registered | binary | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.quantum.circuit2` | payload | registered | binary | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.quantum.job` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.quantum.wasmq` | payload | registered | binary | standalone | royalty-free | standard-defined | — | §5 Interactive, temporal & computed content |
| `wai.route.record` | record | registered | — | — | — | — | — | §5 Interactive, temporal & computed content |
| `wai.semantic.clip` | payload | registered | image | standalone | royalty-free | behavioral | — | §5 Neural capabilities |
| `wai.semantic.perco2` | payload | registered | image | standalone | non-commercial | behavioral | — | §5 Neural capabilities |
@ -446,6 +447,7 @@ and a role are fixed once registered.
| `wai.quantum.landscape/sample` | a fabric kernel: the sampling of an energy-landscape job |
| `wai.quantum.circuit/1` | a contract revision: the `ext` of a wai.quantum.circuit payload's contract (quantum-sim §2.1), a part of the capability's definition |
| `wai.quantum.circuit2/1` | a contract revision: the `ext` of a wai.quantum.circuit2 payload's contract (quantum-sim §2.1), a part of the capability's definition |
| `wai.quantum.wasmq/1` | a contract revision: the `profile` of a wai.quantum.wasmq payload's contract and of its run's result (quantum-wasmq §2.2, §6.4, §10), a part of the capability's definition |
| `wai.quantum.job-record/1` | a document with no schema file: the record a job service's store keeps a job in (wai-quantum-service) |
| `wai.quantum.provider-job/1` | a document with no schema file: the record wai-quantum-qpu keeps of a job on a person's provider, written before the job is sent |
| `wai.quantum.optimize-checkpoint/1` | a document with no schema file: an optimisation's checkpoint (wai-quantum's `engine::variational`) |
@ -453,6 +455,7 @@ and a role are fixed once registered.
| `wai.quantum.docs-manifest/1` | a document with no schema file: the list of documents tools/quantum-docs checks |
| `wai.quantum.write/1` | a document with no schema file: the transcript wai-quantum-writer keeps of writing a program for a task |
| `wai.quantum.model/1` | a document with no schema file: the manifest of a writer's model, the file wai-model.json (wai-quantum-writer's `coder`) |
| `wai.quantum.wasmq.result/1` | a document with no schema file: the result of a wasmQ run, held to its form by wai-quantum's `engine::wasmq` (quantum-wasmq §6.4, §6.5) |
| `wai.quantum.job-key/1` | a digest domain: the digest a job service keeps a client's idempotency key under, the client's name beside the key (wai-quantum-service) |
| `wai.quantum.trace/1` | a digest domain: an optimisation trace's first link is BLAKE3 of it and the request's canonical text (wai-quantum's `engine::variational`) |
| `wai.quantum.circuit3` | refused on purpose: not a capability; the circuit core's test gives it to see no gateset read from it |
@ -463,6 +466,9 @@ and a role are fixed once registered.
| `wai.quantum.provider/2` | refused on purpose: a version of the provider protocol that no text defines; the reference provider's test sends it to see it answered unsupported_version (quantum-providers §10) |
| `wai.quantum.provider/9` | refused on purpose: a version of the provider protocol that no text defines; the protocol schema's test sends it to see it answered unsupported_version (quantum-providers §10) |
| `wai.quantum.provider/999` | refused on purpose: a version of the provider protocol that no text defines; the provider conformance corpus sends it to see it answered unsupported_version (quantum-providers §10) |
| `wai.quantum.wasmq/2` | refused on purpose: a wasmQ profile that no text defines; wasmQ's tests, the receipts corpus and its verifiers put it in a contract or a result to see the job refused (quantum-wasmq §6.5, rules 4 and 11) |
| `wai.quantum.wasmq/1x` | refused on purpose: the wasmQ profile one letter longer; the receipts' differential check puts it in a contract to see both verifiers refuse the job (quantum-wasmq §6.5, rule 4) |
| `wai.quantum.wasmx` | refused on purpose: not a capability; wasmQ's adversarial test and its vectors put it in a payload's manifest to see the envelope refused with W013 (quantum-wasmq §2.3) |
| wire identifier (not a capability) | kind | status | defined in |
|---|---|---|---|

View file

@ -1008,6 +1008,7 @@ standard. See the linked extension for each.
| `wai.ternary.tt` | WQTT container (balanced-ternary MPS cores — packed trits + integer per-column scales) | a **quantum-inspired** (tensor-network) transform ported from the ternary/MPS fabric with ONE change: the per-column scale is an **integer**, so the whole decode is `i64`/`i128` and the reconstruction is byte-identical on every machine — **reconstruction-equivalence** (a portable recon hash), receiptable. Scope: a **provenance** transform, measured at 13.3 dB SNR for 3.8× with six residual layers (`Lossy` tier; the extension's §5). Encoder-side float SVD only · [ternary-tt](extensions/ternary-tt.md) |
| `wai.quantum.circuit` | WQC container (gate op-log — Clifford+T + dyadic phase) | the wire carries a **circuit** (kilobytes, linear in gate count), the sink CLASSICALLY simulates it in a fixed-point **complex** floor (`Amp` = i64 re/im), and the reconstructed `2^n`-amplitude statevector is byte-identical on every machine — **statevector-equivalence** (a portable statevector hash); measurement is sampled by the pinned `splitmix64` so a shot histogram at a pinned `(seed, shots)` converges too (**shot-histogram-equivalence**). The dyadic phase ladder transports the **QFT** ("quantum FFT") as a circuit, reconstructed byte-exact; the phase table is frozen as existing content was made with it, so `P(k)` deviates from the ideal phase for k ≥ 8 and applies none for k ≥ 19, and new content uses `wai.quantum.circuit2`. No quantum hardware — NISQ noise breaks the determinism the standard rests on; this makes a quantum *computation* transportable + receiptable, with **no** speedup claimed · [quantum-sim](extensions/quantum-sim.md) |
| `wai.quantum.circuit2` | WQC container under magic `WQC2` (the same gate op-log) | the successor of `wai.quantum.circuit`, with the same statevector- and shot-histogram-equivalence: a correctly rounded phase table (each component of every `P(k)` within half a unit of 2^30·e^{2πi/2^k}), so the dyadic phase ladder gives the **QFT**; a byte-canonical contract; an op-log that ends exactly after its last op. A new capability, not a change to the old one, because a registered capability's payload format is fixed (§8): a reader that predates it rejects a `WQC2` payload at the magic · [quantum-sim](extensions/quantum-sim.md) |
| `wai.quantum.wasmq` | WAI1 envelope whose payload is a `WQM1` bundle: an OpenQASM 3 program of Clifford gates, the WebAssembly modules its `extern`s call and their priors, each pinned by BLAKE3 in a canonical contract | **result-equivalence** · [quantum-wasmq](extensions/quantum-wasmq.md) §6.4: every conforming runner gives an envelope the same result bytes, the same fuel for every callout and the same fault, on every host and engine. A run is whole-number arithmetic throughout: a stabilizer tableau, outcomes from an integer stream, and modules held to a deterministic profile (Lime1, nothing imported, memory and stack bounded, NaNs canonical, fuel counted on the module as written), sealed in the job receipt |
*Scene carriage* ([scene-carriage](extensions/scene-carriage.md)) maps a world (`WWLD`),
an audio scene (`WSCN`), the assets a world names and timed media items onto ISO/IEC

View file

@ -0,0 +1,162 @@
### wasmQ: an OpenQASM 3 program and the WebAssembly its `extern`s call, run the same everywhere, metered and receipted
- **The extension** [`extensions/quantum-wasmq.md`](extensions/quantum-wasmq.md) registers
`wai.quantum.wasmq` (SPEC §5): a WAI1 envelope whose payload carries an OpenQASM 3 program,
the WebAssembly modules that define its `extern` functions and their priors, each pinned by
BLAKE3 in a canonical contract, so the envelope's digest names all of it. Its interface is
[`extensions/quantum-wasmq.wit`](extensions/quantum-wasmq.wit).
- **Whole numbers from end to end.** This version runs Clifford programs (the gates that take
no angle) on a stabilizer tableau, with each random outcome one bit of an integer stream the
text defines, so a result's bytes are the same on every conforming runner.
- **The profile.** A module is a core module in the Lime1 feature set that imports nothing,
bounds its memory and its size, and has no start function, threads, vectors, references or
growing table; each rule has a refusal code (`W001`–`W017`), and a reader refuses on reading
everything a run could not finish for a reason of the bundle's own. WebAssembly 3.0's
deterministic profile leaves `memory.grow`, `table.grow` and the call depth to the host; the
profile fixes all three.
- **What a run asks of its host.** A reader bounds from the bundle alone, and a program as it
reads it, what a run asks of a host outside its modules' fuel: the program's text, nesting,
qubits, bits, steps and the bits its calls pass, the memory and code among a bundle's modules,
an envelope's size, its results, and the work of its steps, its calls, its instances, its
compiling and the most fuel it may be given. So an envelope that opens on one host opens and
finishes on every host, a 32-bit one among them. The reader's nesting bound (`Q130`, as every
reading of a program counts it) and its bounds for programs from others (`Q323`) hold for a
bundle's program; `Q209` keeps its meaning, definitions and calls past 32.
- **A determined measurement, word by word.** The stabilizer tableau finds a determined
outcome as the sign of the stabilizers' product, a machine word of rows at a time, without
copying the tableau: at the most qubits, milliseconds where it took seconds, with the same
outcome, which a test holds to the full product on random states.
- **Fuel and stack, defined on the module.** Fuel is charged at the start of each run of
instructions, with the weights of the pinned wasmtime's own default count, and a page a
module grows at what zeroing it costs. The stack is
bounded by weight: each function's frame weighs a base and its parameters, results, locals,
the most operands its body holds and its bytes, and the frames suspended at calls may weigh 2^23 together, so the bound holds for
a frame of any size. A test holds the native engine to eight bytes of stack for each unit.
- **Two engines, one result.** The pinned wasmtime runs the module prepared to meter itself;
an interpreter of the crate's own, which also runs on wasm32, meters it itself. Every
instruction, charge, trap and fault agrees between them, and a host reaches a module's
memory the same way on both, as its export `memory`.
- **Callouts in the program.** The reader takes `extern` calls as steps when asked
(`qasm::read_callouts`, which returns the program with its steps, `qasm::Step`, and its
`extern`s): a call runs in program order between gates, its arguments bits or integers
known on reading, its result written to bits a later `if` reads. Every other reading still
refuses them (`Q125`), and nothing in the reader's existing types changes. An `extern` lowers
to an integer function when its widths fit 64 bits, and to lists otherwise: the Component
Model's canonical ABI.
- **The receipt.** A run goes shot by shot and seals its result in the job receipt the
engine already signs: counts, the fuel of every callout, the modules' digests, a digest of
every call's inputs and outputs, and the fault that stopped it (fuel, stack, a trap or a
result past its width), as a signed fault receipt. Every member of the result is defined by
the text.
- **The command line**: `wai-quantum pack-wasmq`, `check-wasmq`, `run ENVELOPE.wai`
(`--engine`, `--transcript`, `--replay`, each record written and read a call at a time), and
`verify JOB --bundle ENVELOPE.wai`, which also runs the envelope again and compares byte for
byte. A flag of a program's run given with an envelope, or an envelope's given with a
program, is refused rather than ignored. A bundle goes to no provider: the provider protocol
carries no call between gates, and the bring-your-own-quantum boundary is as it was.
- **One verdict on every surface.** A wasmQ job is checked on the one path every job is
(`engine::job::check`), so `wai-quantum verify` (with `--json` and `--lines`), the job
service's `POST /v1/verify`, both MCP servers, the Python package, the desktop app, a view
and a page give it the same verdict. Its text is read as the provider protocol's §8.2 reads
every job's, and §8.4 gains one reason, `wasmq_form`: the job breaks a rule of
quantum-wasmq §6.5, whose thirty-five numbered rules hold the contract, the result, the fuel,
the fault and the counts to the profile, by what is sealed alone, under whichever key. Beside
the verdict, `wasmq` states how the run ended, each rule it breaks, and where the host's
unsealed words differ from what is sealed, which change no verdict. The form lives in the
engine (`engine::wasmq`), and the runner takes its constants from there.
- **Receipts of record.** The receipts corpus holds six wasmQ jobs the command line sealed
(a run, one of a single instance, and faults in a call, of the run's budget, in an init and
in a prior) and forty-four crafted from them: forty each breaking the one rule of §6.5 it
names and no other (every rule but the first, which no receipt can break alone, as every
place a number may be has a rule of its own, and rule 27, which rule 32 holds too), two
breaking two, and two the same sealed content written otherwise or under another envelope. The second verifier, written in
Python from §6.5 without the reference, gives `wasmq_form` on its own, and the differential
holds the two to each other on every one-member change of each of the six; a planted
verifier that skips the rules (`wasmq-unchecked`) is caught.
- **Every surface, every body.** Text that does not read as a job's, a body that is no job,
and a result with no receipt are each a verdict with that reason alone on every surface:
the command line, both MCP tools, the job service over HTTP (a 200 verdict, no longer a
400), the Python package, the desktop app, a page and a view. The service's tool given a
job's members checks the body it is given, its unsealed status among them. The Python
package judges a dict as the text it writes for it, and reads text that begins with a byte
order mark as text. A job routes to an estimate's or an algorithm's verifier only when it
is not a wasmQ job (`job::has_own_verifier`).
- **The command line's `--lines`** reads each line on its own: a line that is not UTF-8,
or blank, is that line's `unreadable`, and a file of no line is refused. `verify` says a
job found unreadable or with no receipt was not judged, and runs no envelope for it.
- **The form, tightened.** A call that stopped the run is one of the calls made: its
callout's fuel counts it, and its largest call is at least what it used. A whole number
past 2^53 − 1 is no count however a reader holds it. Rule 1's walk is linear in the text,
however long a member's name. A member is present whatever its value, `null` among them.
- **Writer and verifier agree.** Each budget is at most 2^39 when packed (`W017`), as every
verifier holds a contract to it. The program's qubits are defined for a program that names
physical qubits, and the bits' order for several registers; a vector pins both. A hybrid
reading's refusal for controls offers no method its run cannot use.
- **Every tie the writer keeps is a rule.** Rules 20 to 35 hold what the runner guarantees
between members:
- a returned call used 1 to the most one call used, and the stopped one the fault's fuel;
when the most is a returned call's, the others used 1 each at least;
- each set of instances passed every prior, a prior costing its bytes and 3 at least, and
called the `wasmq-seed` or `init` a lifecycle fault shows its module exports; the set a
lifecycle fault stopped passed the priors of the modules before its own; the stopped
call's fuel is on top of all of it; and each prior passed whole fits one lifecycle call's
limit;
- a call's fault is in its callout's module, a prior's in a module with one, a
`bad_result` in a call or a prior;
- a lifecycle fault is in shot 0 for one instance a run, and before any call in shot 0;
- a fuel fault used its whole limit, and any other fault at least what its reason shows
was charged (1; 2 for `bad_result`; 788 for `stack_exhausted`, the frames §3.2 allows
to pass 2^23);
- with no call returned, the transcript is the run's end alone, which the receipt holds;
- §4.8's products and sums over what a receipt shows: a shot's bits (a name's length in
characters), the shots' bits, the work (4097 for each call made among it), the calls a
shot's 2^21 steps hold, and the envelope's bytes, its manifest and its contract with its
frames.
§6.5 says what it leaves free, and why, among it a program's and a module's least length
and an `extern`'s spelling; a result's `qubits` is at least 1. Rule 6 no longer repeats the bounds rules 6 and 31 imply, and rules 8,
14 and 18 no longer repeat what rules 20, 25 and 30 hold.
- **The outcome, exactly.** §6.1 gives a shot's outcome as every bit the program declares at
its top level, written or not; a block's own bits are in no outcome; a measurement in a
program that calls externs names its bit (`Q324` refuses one that does not). Vectors pin
bits nothing writes and a block's own bit, and refuse a measurement with no bit.
- **The differential's rules stage**: each rule of the form at its bound, on both sides,
sealed again, each verdict written by hand, the review's labelled cases among them; the
second verifier's own hand-labelled cases run through the reference as well; and weakenings
of each rule, generated in both verifiers, each caught.
- **One answer, every kind of job.** An estimate or an algorithm's answer with no receipt, or
that is no job, is that reason alone on the command line, its MCP tool, `POST /v1/verify`
and the service's tool, as every other job is; one is run again only once its receipt and
§8.4's rules hold (`job::answer_of`, `job::answer_of_text`), and the service runs an
algorithm's answer again as the command line does, its tool alike given the job's text,
the job, or its members. A job past what a surface reads, in its bytes or in its values, is
`too_large`, a new reason of §8.4 reported alone, stating both (`read_at_most`):
`wai-quantum verify` reads 384 MiB and 2^22 values on every host, in about 1 GiB of memory;
`POST /v1/verify` and `/mcp` read 4 MiB and 2^19 values, and check off the service's async
workers, two at a time. `/mcp` answers a verify call past that with its verdict by its id,
reading a message past six times that only as far as its id, method and tool. A check
holds one reading of a job at a time. A job of any depth reaches its verdict through a
view's request and an MCP call, `unreadable` past 127, judged before the message is read
whole. An estimate whose request runs again nowhere is not valid and says why
(`rerun_error`), as an algorithm's answer does, on every surface. `verify` prints the verdict
of text that does not read and of no job. The Python package reads a str as a path only
when it names a file, and gives a verdict for every str and dict, a lone surrogate's
among them.
- **Breaking:** `POST /v1/verify` answers 200 with a verdict for a body that is not JSON, no
job, has no receipt (`unreadable`, `not_a_job`, `no_receipt`) or is past 4 MiB or 2^19
values (`too_large`), where it answered 400 for the first three and 413 past 1 MiB; a
client reads `valid` and `reasons`. Its OpenAPI document says
so. `wai-quantum verify` reads at most 384 MiB and 2^22 values of a job, where it read any
file whole.
- **Breaking:** the command line's MCP server answers a line that is not UTF-8 with JSON-RPC
-32700 and reads on, where it ended its session.
- **Breaking:** the Python package's `verify` given a str that names no file reads it as the
job's text and gives its verdict (`unreadable` for a path that is not there), where it
raised `FileNotFoundError`.
- **Reference modules** from the engine's own code: the qLDPC decoder (matching for codes
with a matching graph, Relay-BP otherwise) and the atom rearrangement planner, modules of
record built on x86_64 Linux and committed with their sources' digests. Their results equal
the same functions compiled natively, called directly and in the middle of circuits.
- **Vectors** in `quantum-conformance/wasmq/`: envelopes with the result each must give on
every engine and host, and modules and envelopes a runner refuses, at least one for every
code, each one defect away from one that is accepted.

View file

@ -844,7 +844,7 @@ package of several components: the
media classes `graphics` (7) and `text` (8) beside packaging's others, the rungs each medium
takes, how each component is cut at the lead's piece starts, each piece's object and `target`,
and the decoded-output digest each entry states. The reference package is written by
`wai-pack` under `compose/policy.toml`: the lead `v`, a 320 × 180 test pattern (the fixture
`wai-pack` under `compose/policy.toml`: the lead `v`, a test pattern of 320 × 180 (the fixture
`compose-01`) with an integer base and a supplied AV1 floor for every piece; `g`,
`vector-conformance`'s title card and credit roll; `t`, three captions; `s`, a score with a
FLAC floor of each piece's mixdown, which this page does not decode (no route: it holds no

View file

@ -542,6 +542,7 @@ as a set: none for a valid receipt. It is valid exactly when there is none.
| `unreadable` | the text breaks a rule of reading (§8.2). Reported alone |
| `not_a_job` | the value is not an object whose `request` and `result` are both objects. Reported alone |
| `no_receipt` | the result has no `receipt`. Reported alone |
| `too_large` | the job is longer than the surface reads, in its bytes or in its values (one, and one more for each `,`, `:`, `[` and `{` outside its strings: what a check holds follows them), which it states with the verdict (`read_at_most`: `{"bytes", "values"}`); it judged none of it. Reported alone. `wai-quantum verify`, on every host, reads 384 MiB and 2^22 values, more than any job holds; the job service's `POST /v1/verify` and `/mcp` read 4 MiB and 2^19 values. A job given as a string is its text's bytes and values; one given parsed in a message, as it is written there |
| `receipt_form` | the receipt is not an object; its `alg` is not `ed25519`; it has a `canon` other than `rfc8785`; or its `key`, `digest` or `signature` is not lower-case hex of its length. When it is reported, the next three are not checked |
| `digest_mismatch` | the digest the receipt states is not the digest (§8.2) of this request and result |
| `bad_key` | `key` is refused by the strict rules (§8.2). When it is reported, the signature is not checked |
@ -556,6 +557,7 @@ as a set: none for a valid receipt. It is valid exactly when there is none.
| `execution` | a stated provider's result whose `execution` breaks a rule of §8.3; or, for a kind with rows, is neither one of the rows that hold for its provenance nor stated by `nobody`; or, for `http` and `process`, is not stated by `provider` or `nobody` |
| `compiled_program` | a stated provider's result whose `compiled.program` is not the BLAKE3 of `compiled.qasm3`'s UTF-8 bytes, when `qasm3` is a string and `program` is 64 lower-case hex digits |
| `cost_confirmation` | a stated provider's result whose `cost.confirmed` is `true` on a free run or `false` on one that is not free (§7), when both are `true` or `false` |
| `wasmq_form` | a wasmQ job's result (its `format` is `wai.quantum.wasmq.result/1`, [quantum-wasmq](quantum-wasmq.md)) whose request or result breaks a rule of [quantum-wasmq §6.5](quantum-wasmq.md#65-verifying): the job is not one that profile writes |
A provider's result is one whose `method` is `provider`. It is *stated* when it
carries a member `counts_source` or a member `execution` (whatever their
@ -598,6 +600,12 @@ A verifier also states, for a provider's result (one with no receipt
included), its class as its provenance reads it, and, in the stated form, its
counts' source and its `execution`, each as the result gives it.
A wasmQ job's result is held to `wasmq_form` whatever its `method`, and to the provider
rules too when its `method` is `provider`. A verifier also states, for a wasmQ job, what
quantum-wasmq §6.5 says it states beside the verdict: how the run ended, each rule it
breaks and where the body's unsealed members differ from what is sealed. None of that
changes the verdict.
These are all the rules: what §8.1 names and this table does not check
(`compiled.hash` and `placement`, the notes, the `ideal` figures, the
estimate's contents) is the host's word, unchecked. The schemas
@ -686,6 +694,10 @@ whether each `qasm` is that program (`derived`, beside the reasons); that is the
engine's check of the set, not a rule of its receipt, and a verifier that does
not write programs out does not make it.
A program that calls WebAssembly between its gates ([quantum-wasmq](quantum-wasmq.md))
is not a program of §4: it has steps between gates that this protocol does not carry. A
client MUST NOT send one to a provider; it runs where its runner is (quantum-wasmq §7).
## 9. Conformance
`wai-quantum-qpu/conformance/provider-v1.json` holds the vectors:
@ -731,9 +743,17 @@ surface that verifies is held to the manifest by its own tests, given each
receipt's text: the job service over HTTP and as a tool, the command line's tool
(each takes the job's text), the Python package (text, bytes or a path), the
desktop app and a browser tab. A surface given a job already parsed into objects
(a tool's `request` and `result`, a Python dict) cannot see what parsing loses:
(a tool's `request` and `result`, a view's object) cannot see what parsing loses:
a member named twice (`unreadable`), and a whole number past what its reader
keeps (`inexact_number`). It reports every other reason, and is held to the
keeps (`inexact_number`). A job parsed deeper than a text is read (127) is
`unreadable` there too, however deep it is: a message that carries a job (a tool's
call, a view's request) is read so that the job reaches its verdict (a job nested past
127, or past what the surface reads, is judged before the message is read whole, and the
message around it may nest at most 8 more), and a message that does not read is the
protocol's error, as a line that is not UTF-8 is to the command line's MCP server, which
answers it and reads on. The Python package judges a dict as the text it writes
for it, so a dict's nesting and its whole numbers are judged as text's are; only a
member named twice is past what a dict can hold. It reports every other reason, and is held to the
manifest on every receipt but those. A tool's text is a JSON string, which holds
UTF-8 only, so text that is not UTF-8 reaches a verifier only as a file's bytes.

View file

@ -0,0 +1,988 @@
# WAI Extension: Hybrid Quantum-Classical Execution (`wai.quantum.wasmq`)
Status: **Draft.** Reference implementation: `wai-wasmq` (the profile, `src/profile.rs`;
the prepared module, `src/meter.rs`; the interpreter, `src/interp.rs`; the engines,
`src/engine.rs`; the lowering, `src/abi.rs`; the envelope, `src/envelope.rs`; the run and
its receipt, `src/run.rs`), the OpenQASM reader's callouts (`wai-quantum`,
`qasm::read_callouts`), and the command line's `pack-wasmq`, `check-wasmq`, `run` and
`verify` (`wai-quantum-cli`, `src/wasmq.rs`). A job's form (§6.5) is the engine's, where
every verifier of its receipts reaches it (`wai-quantum`, `engine::wasmq`). Interface: [`quantum-wasmq.wit`](quantum-wasmq.wit).
Vectors: [`../quantum-conformance/wasmq/`](../quantum-conformance/wasmq/).
Keywords **MUST**, **MUST NOT**, **SHOULD** and **MAY** are RFC 2119/8174.
## 0. What this extension adds
A hybrid quantum program runs classical code between its gates: it decodes a syndrome
and corrects the error before the next round, or plans the moves that fill an atom
array. OpenQASM 3 declares such a function with `extern` and leaves its body, its binary
form and how it is linked outside the language. This extension fills that gap for WAI
Quantum, and nothing else:
- **One envelope.** A WAI1 envelope of capability `wai.quantum.wasmq` carries the
OpenQASM 3 program, the WebAssembly modules that define its `extern`s, and the modules'
parameter files (priors), each pinned by BLAKE3 in a canonical contract (§2).
- **One profile.** A module is a core WebAssembly module in the Lime1 feature set, which
imports nothing, whose memory, size and stack are bounded, and which uses nothing whose
result a host may choose (§3).
- **The same bytes and the same fuel everywhere.** Fuel, the stack's weight and the NaN a
float instruction makes are defined on the module as written (§4), so every runner
gives a callout the same results, the same fuel and the same fault. The reference runs
each module on two engines, a native one and an interpreter that also runs on wasm32,
and every vector holds on both, on every host.
- **A receipt.** A run seals its result in the job receipt the engine already signs
(`engine::receipt`): the counts, the fuel each callout used, the modules' digests, a
digest of every call's inputs and outputs, and the fault that stopped the run, if one
did (§6).
This version of the profile runs Clifford programs, in whole numbers from end to end
(§5.1, §6.1). A run simulates the quantum program and runs the classical code for real.
§7 says what holds when the quantum part runs on hardware, and §10 what this version
leaves out.
## 1. Principles
1. **Nothing outside reaches the result.** A module imports nothing: no clock, no
random source, no file, no network, no host function. Its only inputs are its bytes,
its priors, the seed the run gives it and the bits the program passes (§3.2, §5.3).
2. **The host chooses nothing.** Every place where WebAssembly lets an engine choose (a
NaN's bits, a relaxed vector instruction, how deep calls may go, when memory runs out,
when to stop a long computation) is fixed by the profile or refused (§3, §4).
3. **Fuel is the measure, not time.** A callout's budget is a number of weighted
instructions (§4.2). It is the same on every host; wall-clock time is not, and the
profile does not claim one.
4. **The direction is the hardware's.** The quantum program calls the module, as a
real-time controller calls classical code between gates. A module drives no gates.
5. **One form for one bundle.** A bundle has exactly one envelope, so its BLAKE3 names
it, and a receipt that names the digest names the program, the modules, the priors and
the run (§2.4).
6. **What is read is what runs.** A reader refuses on reading every bundle a run could
not finish for a reason of the bundle's own (§2.3). A run that starts ends in a
receipt, unless the host itself fails (§6.3).
## 2. The envelope
### 2.1 Container and manifest
The envelope is a WAI1 container (SPEC §2). Its manifest is, in this order and with no
other member:
```json
{"wai":"1.0","media":"binary","intent":"replicate",
"model_requirement":{"capability":"wai.quantum.wasmq","fallback":null},
"conditioning":{"kind":"wasmq"},
"target":{"qubits":17,"shots":32,"seed":1234}}
```
`fallback` is `null`: a sink without this capability holds no way to run the program's
callouts, so the envelope is inert there (SPEC §4). `target` is informational (SPEC §3)
and is the contract's: the program's qubits (§2.2), the shots and the seed.
`conditioning` carries no `prior`: SPEC §3.1's pin names a parameter set the sink
supplies, and a wasmQ envelope carries its modules' priors itself, each pinned in the
contract (§2.2).
### 2.2 Payload and contract
```text
payload = "WQM1" | u32 contract_len | contract | frames
frames = program | for each module, in order: the module, then each of its priors in order
```
`contract_len` is little-endian. The contract is JSON in the canonical form of RFC 8785
(JCS), with exactly these members:
| member | |
|---|---|
| `profile` | `"wai.quantum.wasmq/1"` |
| `program` | `{ "blake3", "bytes", "inputs" }`: the OpenQASM 3 source's digest and length, and the values of its integer `input`s (an object, empty when there are none) |
| `modules` | for each module: `{ "name", "blake3", "bytes", "priors": [{ "name", "blake3", "bytes" }] }` |
| `callouts` | one for each `extern` the program declares, in the order it declares them: `{ "extern", "module", "export" }`, the module by its index |
| `run` | `{ "shots", "seed", "method", "state", "fuel": { "per_call", "per_job", "per_instance" } }` (§6.1, §4.2) |
`blake3` is the BLAKE3 digest of the frame as 64 lowercase hexadecimal digits; `bytes`
its length. A `name` is for people. `method` is `stabilizer`, the one method of this
version (§5.1). `state` is `shot` (a fresh instance of each module every shot) or `job`
(one instance for the run, its shots in order). `shots` is 1 to 2^20. `seed` and the
size of each input are at most 2^53 − 1, so that every JSON reader holds them exactly, and
each budget at most 2^39 (§4.8). `per_job` is held to less with any module: its eight
operations for each unit of fuel take all of a run's work at 2^39, and a run's other work
is never nothing (§4.8). Every module is named by
at least one callout. The program's text is at most 1 MiB, and the modules'
bytes at most 512 KiB among them.
**The program's qubits** are the qubits it declares, all its registers together; a program
that declares none and names physical qubits (`$0`, `$5`) has one more than the highest
index it names, the qubits below it among them.
### 2.3 Reading an envelope
A reader MUST refuse an envelope, with the code of §3.3, when:
- it is longer than 128 MiB, its first four bytes are not `WAI1`, its capability is not
`wai.quantum.wasmq`, its manifest is not the one §2.1 gives for its contract byte for
byte, or any byte follows the payload (`W013`);
- the payload's magic is not `WQM1`, the contract is not in its RFC 8785 form, holds a
member §2.2 does not list or lacks one, or the frames do not end exactly where the
payload ends (`W013`);
- a frame's BLAKE3 is not the one the contract pins: the program, a module, a prior
(`W014`);
- a module breaks the profile (§3: its code), the modules hold more than 4096 pages among
them (`W003`, §4.7), or more than 512 KiB of bytes (`W010`);
- the program is longer than 1 MiB, is refused by the reader, calls nothing, has a gate
outside §5.1's, or is past a bound §4.8 reads it within (`W016`);
- the callouts are not one for each `extern` in the order declared, a module is named
by none, a callout's export is not the type its `extern` lowers to, or a module the
host must write to or read a list from does not export what §5.2 asks (`W015`);
- the run is outside §2.2's ranges, or past what §4.8 lets a run ask of its host (`W017`).
A writer checks the same rules and writes nothing that breaks one. An envelope that
passes them runs: nothing about a bundle is left for a run to find (§6.3).
### 2.4 One envelope for one bundle
A writer MUST write the frames in §2.2's order, the contract in its canonical form with
its callouts in the order the program declares its `extern`s, and the manifest exactly
as §2.1 gives it. A reader that holds these rules reads every bundle from exactly one
sequence of bytes, so the envelope's BLAKE3 (`envelope_blake3`) names the bundle, and a
receipt that binds it binds every frame.
## 3. The module profile
### 3.1 A core module
A module is a core WebAssembly module (WebAssembly 3.0, §5 Binary Format), not a
component. It MAY be the core module of a component: its exports are the canonical
lowering of the functions [`quantum-wasmq.wit`](quantum-wasmq.wit) declares, so a
component host can wrap it, and a host of this profile calls it directly.
### 3.2 The rules
A module MUST validate under the **Lime1** feature set of the WebAssembly tool
conventions: WebAssembly 1.0 with mutable globals, multi-value, sign extension,
non-trapping float-to-int conversion, `memory.copy` and `memory.fill`, extended constant
expressions and the overlong `call_indirect` encoding. Every instruction is in the
encoding that feature set gives it, and every function body ends with the `end` of its
own block. And:
| rule | why |
|---|---|
| It imports nothing. | Nothing outside the module reaches its result. A clock, a random source or any host function would. |
| It has at most one memory, 32-bit, unshared, of 64 KiB pages, with a maximum of at most 4096 pages (256 MiB). | A memory without a maximum grows as far as a host lets it, which differs by host. |
| It has no start function. | Nothing runs when an instance is made: every instruction runs in a metered call (§5.3). |
| Nothing shared, no atomic instruction. | Lime1 has no threads. |
| No vector instruction or type, relaxed or not. | A relaxed vector instruction's result is the engine's choice; the profile takes none. |
| No instruction or type of another feature outside Lime1: references, exceptions, tail calls, garbage collection, passive segments. | Lime1's values are numbers. |
| At most one table, of `funcref`, at most 2^16 entries, filled once from active segments of function indices; no instruction reads or changes it but `call_indirect`. | `table.grow` stays non-deterministic in the deterministic profile (below). |
| In every function, at most 4096 parameters, locals and operands at once. | It bounds what one frame holds in an interpreter. |
| At most 512 KiB of bytes, which is also what the modules of a bundle hold among them; at most 2^16 types, functions, globals, data segments and element segments each; at most 2^10 exports, each name at most 256 bytes; a function type of at most 2^8 parameters and 2^8 results; a function's entry in the code section of at most 2^14 bytes. | They bound what a reader, an engine and a frame need (§4.3), with room for what preparing a module adds (§4.4): a body of calls grows some 53 times prepared, and an engine compiles a function whole. |
| Every active data and element segment fits where it is placed. | Instantiation then cannot fail. |
| No export begins `__wasmq`, and an export a host calls has exactly its type (§5.2, §5.3). | The first are the prepared module's names (§4.4); a host passes the second arguments of those types. |
WebAssembly 3.0 defines a deterministic profile: every NaN an instruction makes is
canonical and positive, and every relaxed vector instruction has a fixed behaviour. Even
under it, `memory.grow` and `table.grow` remain non-deterministic, to indicate resource
exhaustion, and the depth of calls an engine allows is an implementation limit. This
profile takes the deterministic profile's rule for NaNs (§4.5) and closes the others: no
vector instruction is taken, the table never grows, the memory grows only within the
maximum the module declares (§4.7), and the stack is weighed (§4.3).
The limits of the last rows are each below the limits of the validator and the native
engine the reference uses, and stay below them once a module is prepared: a test makes a
module of the most bytes, its largest body all calls, with the most exports, names, table
entries and memory and as many of each other item as fit beside them, and prepares,
compiles and runs it on every engine (`wai-wasmq/tests/engines.rs`).
### 3.3 Refusal codes
| code | the module or envelope |
|---|---|
| `W001` | is not a valid core module in Lime1, for a reason no other code names (a component, a malformed module, a body that does not end, an encoding of another feature) |
| `W002` | imports something |
| `W003` | has more than one memory, a 64-bit one, one with a page size of its own, one without a maximum or past 4096 pages; or (envelope) has modules with more than 4096 pages among them |
| `W004` | has a start function |
| `W005` | has a shared memory, global, table or type, or an atomic instruction |
| `W006` | has a vector instruction or type, relaxed or not |
| `W007` | has an instruction or a type of a feature outside Lime1 that no other code names |
| `W008` | has more than one table, one not of `funcref`, past 2^16 entries, or an instruction that reads or changes it other than `call_indirect` |
| `W009` | has a function whose parameters, locals and operands can pass 4096 |
| `W010` | is past a size the last rows of §3.2 give; or (envelope) has modules of more than 512 KiB among them |
| `W011` | has a data or element segment that does not fit where it is placed |
| `W012` | exports a name the profile reserves, or an export a host calls with another type than its own |
| `W013` | (envelope) is not one this profile writes, or is past its size (§2.3) |
| `W014` | (envelope) has a frame whose digest is not the one its contract pins |
| `W015` | (envelope) has callouts that are not one for each `extern` in order, a module no callout names, an export of another type than its `extern` lowers to, or a module the host cannot reach as §5.2 asks |
| `W016` | (envelope) has a program longer than 1 MiB, that the reader refuses, that calls nothing, with a gate outside §5.1's, or past a bound it is read within (§4.8) |
| `W017` | (envelope) has a run outside the profile's ranges, or past what §4.8 lets a run ask of its host |
A module or an envelope that breaks more than one rule is refused with the code of one
of them. Each refusal vector (§9) breaks exactly one.
`wai-quantum check-wasmq MODULE.wasm` holds a module to the profile and names the code.
## 4. Running a module the same everywhere
### 4.1 Instances
An instance is made from the module with no imports. Its memory starts at its initial
size, zeroed, with the active data segments copied in; its table holds the active element
segments; its globals hold their initial values. A host MUST be able to hold the memory's
maximum before it calls the instance (§4.7).
### 4.2 Fuel
Every call a host makes into an instance has a limit of fuel. Fuel is defined on the
module as written, not on any engine:
- A function's body is a sequence of **runs**. A run starts at the function's first
instruction and right after each `block`, `loop`, `if`, `else`, `end`, `br`, `br_if`,
`br_table`, `return`, `call`, `call_indirect` and `unreachable`; it ends with the first
of them that follows, or with the body.
- The **weight** of an instruction is 0 for `nop`, `drop`, `block`, `loop`,
`unreachable`, `return`, `else` and `end`, and 1 for every other. Entering a function
weighs 1.
- When execution reaches the start of a run, the run's weight (with 1 more for the first
run of a body) is charged. Before `memory.copy` and `memory.fill` execute, the byte
count they take is charged; before `memory.grow` executes, 1024 for each page it asks
for is charged, whether or not the growth succeeds: zeroing a page costs a host what
1024 instructions do.
- When a charge takes the fuel below zero, the call stops with `fuel_exhausted`.
So a charge happens at the start of a run, before any of the run's instructions, and a
call that traps in the middle of a run has been charged the whole run. On every path that
does not stop early, the fuel a call uses is the number of instructions it executed under
these weights, and one for each function it entered.
**Limits.** The contract gives three budgets. A callout's limit is `per_call`, and it
covers every call the host makes for it (§5.2). The limit of an instance's lifecycle
calls is `per_instance`, for each of them (§5.3). `per_job` is the run's: when less than
a call's limit is left of it, what is left is the call's limit. The fuel a call used is
its limit less what it left, and is taken from what is left of the run's; a call that
stops with `fuel_exhausted` used its whole limit.
The weights are the default operator costs of the native engine the reference uses, with
one for a byte of `memory.copy` or `memory.fill` and 1024 for a page of `memory.grow`. A
test holds the profile's fuel equal to that engine's own count, on the module as written,
over control flow, calls and memory instructions, with one difference it states: for
`memory.grow` the profile charges 1024 for each page asked for, and that engine's own
meter one for each page it gets (`wai-wasmq/tests/engines.rs`).
Fuel is a count of work, the same on every host. It is not a time: a host that must
answer within a deadline measures its own instructions per second and sets the budget.
### 4.3 The stack
Calls are bounded by weight, not by count, so that the bound holds for a frame of any
size on any engine. The **weight of a function's frame** is
```text
576 + its parameters + its results + its locals + its operands + the bytes of its entry in the code section
```
its parameters and results those of its type, its locals the ones it declares, its
operands the most values its body holds on the operand stack at once (as a validator
counts them after each instruction: a call's results among them), and its entry's bytes
the value of the entry's own size field. The **stack's weight** is zero
when a host calls an export. Before a `call` or `call_indirect` executes, the weight of
the function that holds the instruction is added to it; when the callee returns, the
same weight is taken off. A call that would take the stack's weight past **8 388 608**
(2^23) stops with `stack_exhausted`, before the instruction does anything else: a
`call_indirect` that is both past the stack and through an entry it cannot call stops
for the stack.
So the frames suspended at calls never weigh more than 2^23 together, and one more
frame runs on top of them. An interpreter that keeps a frame's parameters, locals and
operands in slots needs at most one slot for each unit. The reference's native engine
needs at most eight bytes for each unit: a test runs modules made to keep as much in a
frame as the largest body allows (locals held across a call, a new value held at every
step, the results of calls held on the operand stack across a call, the largest function
types), each recursing to the limit, on a stack of exactly that size, and shows a smaller
one fails (`wai-wasmq/tests/engines.rs`). It gives each call nearly twice that.
A function of a few instructions recurses some 14 000 deep; a function at the largest
body the profile takes, some 490.
### 4.4 The prepared module
A host MAY run a module with an engine that implements §4.2, §4.3 and §4.5 itself (the
reference interpreter does). The reference's native engine does not, so it runs the
**prepared module**: the module with every instruction kept byte for byte, and added
1. two mutable globals, after the module's own, exported as `__wasmq_fuel` (i64) and
`__wasmq_stack` (i32);
2. at the start of each run whose weight is not zero, the charge
`global.get F; i64.const w; i64.sub; global.set F; global.get F; i64.const 0; i64.lt_s; if; unreachable; end`;
3. before `memory.copy` and `memory.fill`, the same charge of the byte count, and before
`memory.grow`, of 1024 times the page count, each taken from the operand with
`local.tee` of one added `i32` local;
4. around each `call` and `call_indirect`, with `w` the weight of the function they are
in, `global.get S; i32.const w; i32.add; global.set S; global.get S; i32.const 8388608; i32.gt_u; if; unreachable; end`
before it and `global.get S; i32.const w; i32.sub; global.set S` after it;
5. after each instruction of §4.5, a call of an added function that returns its argument,
or the canonical NaN if the argument is a NaN;
with every custom section dropped. The host sets `__wasmq_fuel` to the call's limit and
`__wasmq_stack` to 0 before each call. When the prepared module traps at `unreachable`
with `__wasmq_fuel` below zero, the fault is `fuel_exhausted`; with `__wasmq_stack` past
2^23, `stack_exhausted`; otherwise the module's own `unreachable`.
The prepared module is one way to hold §4.2, §4.3 and §4.5, and its bytes are the
reference's own: this text does not fix them, and no receipt names them. What a
conforming runner must reproduce is what those sections define.
### 4.5 NaNs
The result of `f32` and `f64` `add`, `sub`, `mul`, `div`, `min`, `max`, `sqrt`, `ceil`,
`floor`, `trunc` and `nearest`, of `f32.demote_f64` and of `f64.promote_f32` is, when it
is a NaN, the canonical positive NaN (`0x7fc00000`, `0x7ff8000000000000`): WebAssembly
3.0's deterministic profile. Every other instruction already has one result everywhere.
A test shows that a module whose result depends on a NaN's bits reads what the host chose
when neither the preparation nor the engine canonicalises, and the canonical NaN when
either does (`wai-wasmq/tests/adversarial.rs`).
### 4.6 Engines
The reference runs every module on two engines and holds them to the same bytes:
- **native**: the repository's one pinned release of wasmtime, compiling the prepared
module with Cranelift, with NaN canonicalisation on, relaxed vector instructions fixed
and refused, vector instructions, tail calls and every proposal past Lime1 off, its
own fuel on as a backstop under the profile's, and a run's calls made on one thread with
a stack of the size §4.3 bounds;
- **interpreter**: `wai-wasmq`'s own, which runs the module as written and implements
§4.2, §4.3 and §4.5 itself, and which also runs on wasm32 (where the native engine
does not run). It also runs the prepared module, with its own metering off, as a check
of the preparation on the vectors; that use is held to none of §4.8's bounds.
`wai-quantum run ENVELOPE.wai --engine native|interpreter` chooses; the receipt is the
same.
### 4.7 Memory
`memory.grow` past the module's declared maximum returns −1, on every engine. Within the
maximum, it succeeds: a host that cannot grow the memory within the maximum (it has run
out of memory) MUST stop the run and seal nothing (§6.3), because what it would seal
would be its own condition, not the module's.
The modules of a bundle hold at most 4096 pages among them, by the maxima they declare
(`W003`), so that a 32-bit host holds any bundle's memory: a limit for each module alone
would leave the number of modules to decide which hosts can run an envelope.
### 4.8 What a run asks of its host
Fuel is the work of the modules. A run also asks work and memory of its host that no
fuel counts: reading the program, its steps on the tableau, a fresh instance's memory,
compiling its modules, the result. So that an envelope that opens on one host opens and
finishes on every host, a 32-bit one among them, a reader bounds all of it from the
bundle alone, before anything runs, and refuses past the bounds; nothing here differs by
engine. A receipt shows part of what these bounds count, and §6.5 holds a job to that part
(rules 29 to 32).
**Reading.** The program is read within these bounds, each checked as it is read, so that
a short program cannot make a reader hold or do more than a host has before it is refused
(`W016`):
| bound | |
|---|---|
| its text | 1 MiB (a reader holds some eighty bytes of tokens for each) |
| nesting | 128 (`Q130`): a reader's stack. A statement at the top level is at depth 1; each statement in a block or a body, each expression a statement holds, each operand of an operator, what a bracket holds and each index's indexed value is one deeper than what holds it; operators group as they bind, so a chain of 127 is at the bound; an `else if` is at its `if`'s depth, at most 1024 to one `if`; and a call's body is read in its place, one deeper than the call |
| qubits | 32 768 |
| bits: the program's and its blocks' own together, any one value's, and those of any one array, its elements times each element's | 2^20 |
| steps, its loops unrolled | 2^21 |
| the bits its calls take and give, summed over its steps | 2^23 |
| the work of reading: one for each statement and loop iteration, for each value worked out one and one more for each bit or element it makes, and one for each bit declared | 2^26 |
Past one, the reader's code is `Q323`, or `Q111` for the qubits. **A run ends**: the
reader unrolls every loop, a `while` included, to the bounds it reads or is told
(`@wai.max_iterations`), so every jump in a program's steps goes forward.
**Memory.** A run's shots times the bits a shot holds (all the program's bits, its blocks'
own among them, though an outcome shows only the program's, §6.1) are at most 2^28
(`W017`). With the most memory (§4.7), the largest
envelope (§2.3), the most code (§3.2), the most qubits, bits and steps and the bits of
calls, these leave a run within a 32-bit host's address space at every limit at once,
which a test holds the reference to under wasm32 (`wai-wasmq/tests/sweep.rs`).
**Work.** A run's work is at most 2^42 operations on a word (`W017`), where, with `n` the
program's qubits and `r` = ⌈`n`/32⌉ (at least 1) the words of a tableau's run for one
qubit:
| for each shot | operations |
|---|---|
| its fresh tableau | 2·`n`·`r` |
| each gate | `r` |
| each measurement or reset | 2·`n`·`r` |
| each callout | 4096 for each call of the module's (its export, `cabi_realloc` for each list argument, and `cabi_post_<export>` after a list result), 4 for each bit it takes and gives, and 1 |
| each other step | 1 |
| for each instance, one for each shot, or one for the run when `state` is `job` | operations |
|---|---|
| each module, and each call of `wasmq-seed`, `init`, and two for each prior | 4096 |
| each byte of each module | 1 |
| each page of the memory a module starts with | 8192 |
| for the run | operations |
|---|---|
| each byte of each module, compiled | 131 072 |
| each unit of the most fuel it may be given, `per_job` | 8 |
A random measurement rewrites the tableau's rows that hold an X at its qubit; a determined
one's outcome is the sign of the product of up to `n` stabilizers, which the reference
finds a machine word of rows at a time without copying the tableau. Either reads the
tableau about once, which is the `n`·`r` of its weight. A page a module grows is paid for in fuel (§4.2), as
a page it starts with is counted here. This is a bound on a host's effort from the bundle
alone, not a measure of it: fuel is the profile's measure of the modules' work (§4.2).
The reference was measured at a 64th of the limit, each kind of work alone, on x86_64
Linux natively and under wasm32: at the limit it would take at most about three hours.
## 5. Callouts
### 5.1 In the program
A program declares each function it calls with `extern`, its arguments and its result
written as types:
```qasm
extern decode64(bit[4]) -> bit[9];
bit[4] s;
bit[9] corr;
s = measure a;
corr = decode64(s);
if (corr[0]) x d[0];
```
An argument is `bit[n]`, `uint[k]` or `int[k]` (k from 1 to 64); the result is `bit[n]`
or nothing. An argument is a bit register or an integer known on reading (a constant, a
loop's variable, an `input`); the result goes into a bit register, in a declaration or
an assignment, and a later condition reads it. Calls inside `for` loops unroll; calls
under `if` run only on the shots that take the branch.
**The gates.** This version runs the Clifford gates that take no angle: `id`, `x`, `y`,
`z`, `h`, `s`, `sdg`, `sx`, `sxdg`, `cx`, `cy`, `cz` and `swap`, and gates a program
defines from them, with measurement, reset and conditions on bits, on at most 32 768
qubits. A program with any other gate is refused (`W016`), whatever its angle: `rz(pi/2)`
acts as `s`, and is refused all the same, so that no reader decides in floating point
which gate a program holds. With these gates a state is a stabilizer tableau and every
step of a run is whole-number arithmetic (§6.1).
OpenQASM 3 schedules an `extern` call and lets it run concurrently with other
operations. This profile fixes one schedule: a call runs when the program reaches it, in
program order, and completes before the next statement; it is atomic. A program read
with any other reader of this repository keeps refusing an `extern` call (`Q125`).
### 5.2 Lowering
A callout has one of two forms, by its widths, as [`quantum-wasmq.wit`](quantum-wasmq.wit)
declares them:
- **scalar**, when every argument and the result have at most 64 bits: each lowers to one
`i64` (WIT `u64`), bit `i` of the register bit `i` of the integer, an `int[k]`
sign-extended. The export's type is `(i64, …) -> (i64)`, or `-> ()` with no result.
- **list**, otherwise: each `bit[n]` argument lowers to a `list<u8>` (an `i32` pointer and
an `i32` length) and the result to one `i32` that points to a pointer and a length;
`uint[k]` and `int[k]` arguments stay `i64`. The list's bytes are `ceil(n/8)` long, bit
`i` in byte `i/8` at bit `i % 8`, the rest of the last byte zero: the Component Model's
canonical ABI.
A host reaches a module's memory only as its export named `memory`. A module with a
list-form callout exports it, and `cabi_realloc` when the callout has a list argument
(`W015`). The exports a host calls have exactly these types (`W012`):
| export | type |
|---|---|
| `cabi_realloc` | `(i32, i32, i32, i32) -> (i32)` |
| `cabi_post_<export>` | `(i32) -> ()` |
| `wasmq-seed` | `(i64) -> ()` |
| `wasmq-prior` | `(i32, i32, i32) -> ()` |
| `init` | `() -> ()` |
A host makes a callout in these steps, each guest call under the callout's one limit,
its stack's weight starting at zero:
1. For each list argument, in order: it calls `cabi_realloc(0, 0, 1, len)`, charges
`len` fuel, and writes the bytes at the address returned.
2. It calls the export.
3. For a scalar result: a bit set at or above the result's width ends the run.
4. For a list result at address `r`: `r` is a multiple of 4; it reads a pointer and a
length at `r`; the length is `ceil(n/8)`; it charges that many fuel and reads the
bytes; no bit past the width is set in the last byte; then it calls
`cabi_post_<export>(r)` if the module exports it.
A step that cannot be done as written (bytes that do not fit in the memory at an
address, an address not a multiple of 4, another length, a bit past the width) ends the
run with `bad_result`, with the fuel used up to that step.
### 5.3 Lifecycle
Instances are made at the start of a shot, before its first step, one for each module in
the contract's order (each shot when `state` is `shot`, once at the first shot when it is
`job`); a fault in making one ends the run there, and no later module's is made. When an
instance is made, the host calls, in this order and each if the module exports it, each
under the limit `per_instance`:
1. `wasmq-seed(seed: u64)`, with the run's seed, or, when `state` is `shot`, the shot's
seed (§6.1);
2. `wasmq-prior(index: u32, bytes: list<u8>)` for each of the module's priors, in the
contract's order, the bytes passed as a list argument is (§5.2, step 1);
3. `init()`.
A module with priors exports `wasmq-prior`, `cabi_realloc` and its memory (`W015`).
### 5.4 Priors
A prior is a parameter file a module reads: a code's parity checks, a target register, a
noise model, a calibration. It travels in the envelope and is pinned in the contract, so
a module is never run against another prior than the one it was packed with (`W014`).
## 6. A run and its receipt
### 6.1 Shots and outcomes
A run goes shot by shot, in order. Each shot starts from `|0…0⟩` with every bit 0, and
has a **stream**: the outputs of SplitMix64 from the state `s XOR 0x51574d31`, where `s`,
the shot's seed, is SplitMix64's output for the state
`seed + (shot + 1) · 0x9e3779b97f4a7c15` (all sums modulo 2^64).
A measurement of a qubit in the computational basis has an outcome that is determined by
the state, or is 0 or 1 with equal chance; with §5.1's gates there is no other case. A
determined outcome is the outcome, and takes nothing from the stream. A random outcome
takes the stream's next value `x`, and is 1 when `x < 2^63`. A `reset` measures its qubit
the same way, without writing a bit, and applies `x` to it when the outcome is 1; a
reset of a qubit whose outcome is determined takes nothing from the stream.
A shot's outcome is its program's bits, `n` of them: every bit it declares at its top
level, whether or not anything writes it, numbered in the order the program declares them
(its first declared bit is bit 0, a register's bits in their order) and written bit
`n − 1` first; the counts sum the shots that read each outcome. A bit that a block or a
subroutine declares is its own (`Q322`): the steps read and write it, and no outcome holds
it. Each measurement names the bit it writes: a `measure` with no target bit is refused
in a program that calls externs (`Q324`), since its outcome is the bits it declares. A
program that measures nothing has its bits as its outcome all the same, those its calls
write and 0 for each bit nothing writes: no qubit is read for it.
### 6.2 Faults
A run stops at the first fault, seals what it ran, and reports:
| reason | |
|---|---|
| `fuel_exhausted` | a charge took the fuel below zero (§4.2); `budget` says whose limit it was: `call`, `instance`, or `run` when the limit was what was left of the run's |
| `stack_exhausted` | §4.3 |
| `unreachable`, `memory_out_of_bounds`, `table_out_of_bounds`, `indirect_call_null`, `indirect_call_type`, `integer_divide_by_zero`, `integer_overflow`, `invalid_conversion_to_integer` | the module trapped (WebAssembly 3.0, §4 Execution) |
| `bad_result` | §5.2 |
A fault has the members `reason`, `shot`, `phase` (`seed`, `prior`, `init` or `call`),
`module` (its name), `fuel` (what the stopped call used), `callout` (the `extern`'s
name) when the phase is `call`, and `budget` when the reason is `fuel_exhausted`, and no
other. The counts are of the shots that finished. A fault receipt is a receipt like any
other: it verifies, and running the envelope again reproduces it.
### 6.3 What is never sealed
A host that could not run the bundle seals nothing: a refused envelope (§2.3, §3.3), a
host that cannot hold the memory's maximum or grow within it (§4.7), an engine that
fails for its own reasons. These are the host's condition, not the bundle's, and a
receipt that recorded them would differ by host. Nothing a bundle holds can lead here:
what a bundle could cause is refused on reading (§2.3, §4.7, §4.8) or sealed as a fault.
### 6.4 The result
The job body is the engine's (`engine::job`), with exactly four members:
`{ "status", "method", "request", "result" }`. The request is
`{ "wasmq": <the contract>, "envelope_blake3" }`. `status` is `done` when the result's
`status` is `ok` and `fault` otherwise; `method` is the result's. The receipt signs the
request and the result, as [the provider protocol's §8.2](quantum-providers.md#82-how-it-is-sealed-and-how-a-job-is-read)
seals every job; `status` and `method` only repeat what is signed. They are the host's
word, unsealed: a verdict takes nothing from them, and a check notes where they, or any
other member of the body, differ from what is sealed (§6.5).
The result has exactly these members:
| member | |
|---|---|
| `format` | `"wai.quantum.wasmq.result/1"` |
| `profile` | `"wai.quantum.wasmq/1"` |
| `status` | `ok`, or `fault` when the run stopped |
| `method`, `qubits`, `shots`, `seed` | the contract's method, the program's qubits (§2.2), the contract's shots and seed |
| `shots_run` | the shots that finished |
| `counts` | outcome to shots (§6.1) |
| `callouts` | the callouts made, one that stopped the run among them |
| `fuel` | `{ "used", "instances", "budget": { "per_call", "per_job", "per_instance" }, "callouts": { name: { "calls", "fuel", "max" } } }`: all the fuel used, the part of it lifecycle calls used, the contract's budgets, and for each `extern` the run called, its calls, their fuel and the most one of them used (an `extern` it did not call has no entry) |
| `modules` | for each, in the contract's order: `{ "name", "blake3" }` |
| `transcript_blake3` | BLAKE3 over `wai:wasmq-transcript\x01` and, for each callout that returned, in order: its shot (u64), the index of its `extern` (u32), its input's length (u32) and bytes, its output's length (u32) and bytes, and its fuel (u64), little-endian, the input the arguments' bits in order and the output the result's, packed as a list's bytes are (§5.2); after a fault, the bytes `fault`, the shot (u64), the reason's bytes and the fault's fuel (u64) |
| `fault` | §6.2, when the run stopped |
| `accuracy` | `{ "class": "exact" }` |
| `energy` | `{ "unmetered": "the runner reads no energy meter; fuel is the profile's measure of work" }` |
| `receipt` | the engine's job receipt (`engine::receipt`): Ed25519 over BLAKE3 of the request and the result in RFC 8785 form |
**Result-equivalence.** Every conforming runner, on every host and every engine, gives
an envelope the same result: the same bytes in its RFC 8785 form, the receipt aside. So
the receipt's digest is the same everywhere, and under one key the whole job is.
### 6.5 Verifying
A wasmQ job is a job like any other: every verifier of the engine's job receipts reads it
and judges it by [the provider protocol's §8.4](quantum-providers.md#84-what-a-verifier-checks),
and so gives it one verdict, wherever it is checked. `wai-quantum verify` (and its
`--json` and `--lines`), the job service's `POST /v1/verify`, both MCP servers given the
job's text, the Python package, the desktop app and a page read the job from its text as
§8.2 reads every job's, so its seal and its numbers are held as every receipt's are. A
surface given the job already parsed (a view, an MCP server given its members) cannot see
what parsing loses, as the provider protocol's §9 says, and gives every other reason; the
Python package judges a dict as the text it writes for it. A result
whose `format` is `wai.quantum.wasmq.result/1` is a wasmQ job's, and §8.4 adds one reason
for it, `wasmq_form`: the job breaks a rule below. Only what is sealed (the request, and
the result less its receipt) and the form of its seal decide it. A signature shows that a key sealed a job and says
nothing of what the job holds, so without the envelope to run again these rules are what
hold a result to its contract and to itself: a key can seal any result of this form, and
only running the envelope again shows that a result is the one it gives.
In these rules a number's value is the double it reads as (§8.2). A *count* is a number
whose value is a whole number from 0 to 2^53 − 1, however it is written (`1`, `1.0` and
`1e0` are one count, sealed as one); "at most" and "equals" compare counts, and a rule on
a count fails when the number is not one. A *digest* is a string of 64 lowercase
hexadecimal digits. Two values are *equal* as JSON values are, numbers by their value and
an object's members in any order. "Exactly the members" means every one named and no
other; a value that is not an object has none. A member is *present* when its object names
it, whatever its value, `null` among them: "has no `fault`" and "has a `callout`" read
so. A list or a map named below that is not an
array or an object is read as an empty one, after its own rule has failed. `C` is the
request's `wasmq` (the contract), `run` is `C`'s `run`, `r` is the result and `F` is
`r`'s `fuel`. *The budget* `per_call`, `per_job` or `per_instance` is that member of `run`'s
`fuel`. The job breaks the form when any of these fails:
1. No number in the request, or in the result less its receipt, has a magnitude past
2^53 − 1.
2. The request has exactly the members `wasmq` and `envelope_blake3`, and
`envelope_blake3` is a digest.
3. `C` has exactly the members §2.2 gives: `profile`, `program`, `modules`, `callouts`
and `run`; its `program` exactly `blake3`, `bytes` and `inputs`; `run` exactly
`shots`, `seed`, `method`, `state` and `fuel`; and `run`'s `fuel` exactly `per_call`,
`per_job` and `per_instance`.
4. `C`'s `profile` is `wai.quantum.wasmq/1`.
5. The program's `blake3` is a digest; its `bytes` a count from 1 to 2^20; its `inputs` an
object each of whose values is a number whose value is whole and at most 2^53 − 1 in
size.
6. `C`'s `modules` is an array that is not empty. Each module has exactly the members
`name`, `blake3`, `bytes` and `priors`: `name` a string, `blake3` a digest, `bytes` a
count of at least 1, and `priors` an array each of whose priors has exactly the members
`name` (a string), `blake3` (a digest) and `bytes` (a count). The modules' `bytes` that
are counts add up to at most 2^19, so each is at most that; rule 31 bounds a prior's.
7. `C`'s `callouts` is an array that is not empty. Each callout has exactly the members
`extern`, `module` and `export`: `extern` and `export` strings, and `module` a count
less than the number of modules. No two callouts have the same `extern`, and each
module's index is the `module` of a callout.
8. `run`'s `shots` is a count from 1 to 2^20, its `seed` a count, its `method`
`stabilizer`, its `state` `shot` or `job`, and each of its fuel's three budgets a count,
`per_call` and `per_instance` each of at most 2^39 (§4.8; rule 30 holds `per_job` to
less).
9. `r` has exactly the members of §6.4 (`format`, `profile`, `status`, `method`,
`qubits`, `shots`, `shots_run`, `seed`, `counts`, `callouts`, `fuel`, `modules`,
`transcript_blake3`, `accuracy`, `energy` and `receipt`), and may have `fault`.
10. The receipt is an object whose `canon` is `rfc8785`: the first form (§8.2) is older than
this profile, and no host sealed a wasmQ job in it.
11. `r`'s `format` is `wai.quantum.wasmq.result/1`, its `profile` `wai.quantum.wasmq/1`,
its `accuracy` `{ "class": "exact" }` and its `energy` the one §6.4 gives; and its
`method`, `shots` and `seed` equal `run`'s.
12. `r`'s `qubits` is a count from 1 to 2^15 (a program declares a qubit at least, `Q100`),
and its `transcript_blake3` a digest.
13. `F` has exactly the members `used`, `instances`, `budget` and `callouts`; its `budget`
equals `run`'s `fuel`; and `used` is a count of at most the budget `per_job` (0 when
that is not a count).
14. `F`'s `callouts` is an object. Each of its members is named by the `extern` of one of
`C`'s callouts, and has exactly the members `calls`, `fuel` and `max`: `calls` a count
of at least 1; `max` a count of at most the budget `per_call` (0 when that is not a
count) and at most its own `fuel`; and `fuel` a count (rule 20 bounds it by its calls
and their `max`).
15. `F`'s `instances` and the `fuel` of each member of `F`'s `callouts`, added, are `F`'s
`used`; and the `calls` of each member, added, are `r`'s `callouts`. Each of them is a
count.
16. `r`'s `modules` has as many entries as `C`'s, each with exactly the members `name`
and `blake3`, its `blake3` a digest, and its `name` and `blake3` equal to those of
`C`'s module at its index.
17. `F`'s `instances` is a count of at most M × S × the budget `per_instance` (0 when that
is not a count): S is the sum, over `C`'s modules, of 2 and the number of its priors
(each instance's seed, its init and each prior, §4.2, §5.3); M, the instances made, is 1
when `run`'s `state` is `job`, whatever the status; for any other `state` it is `r`'s
`shots_run` (0 when it is not a count), plus 1 when `r`'s `status` is `fault`.
18. When `r`'s `status` is `ok`: `r` has no `fault`, and its `shots_run` equals its
`shots`. When it is `fault`: the fault has exactly the members `reason`, `shot`,
`phase`, `module` and `fuel`, and may have `callout` and `budget`; `reason` is one §6.2
names; `shots_run` is less than `shots`; `shot` equals `shots_run`; `phase` is `seed`,
`prior`, `init` or `call`; `module` equals the `name` of one of `C`'s modules; `fuel`
is a count, and in a phase other than `call` at most the budget `per_instance` (0 when
that is not a count: a call's is held by its callout's `max`, below, and rule 14; rules
20 and 25, with rule 15, hold either within `F`'s `used`); it has a
`callout` exactly when its phase is `call`, and that is the `extern` of one of `C`'s
callouts that names a member of `F`'s `callouts` whose `max` is at least the fault's
`fuel` (the call that stopped is one of the calls made, §6.4); and it has
a `budget` exactly when its reason is `fuel_exhausted`, and that is `run`, or `call` in
a call and `instance` otherwise. Any other `status` breaks the form.
19. `r`'s `counts` is an object; each of its names holds only `0` and `1` (the empty name
among them), all of one length; each of its values is a count of at least 1; and its values, added, are `r`'s
`shots_run`.
Rules 20 to 35 tie members to each other, as the writer does. In them *the fault* is `r`'s
`fault` when `r`'s `status` is `fault` and that is an object, and there is none
otherwise; a rule about the fault holds when there is none. A *call's fault* is a fault
whose `phase` is `call`, and a *lifecycle fault* one that has a `phase` other than `call`.
20. For each member of `F`'s `callouts`, let `s` be 1 when the fault is a call's fault
whose `callout` is that member's name, and 0 otherwise, and `e` the fault's `fuel` when
`s` is 1 (0 when that is not a count) and 0 otherwise. `T`, its `fuel` less `e`, the fuel
of its calls that returned, is not less than 0, and is from `k` to `k` × `max`, where `k`
is its `calls` less `s` (0 when that is less than 0): the call that stopped used the
fault's fuel, and each call that returned used at least 1 (§4.2: entering a function
weighs 1) and at most the most one call used. When `max` is more than `e`, the most was a
call's that returned, and each of the others used at least 1, so `T` is also at least
`max` + `k` − 1. `calls`, `fuel` and `max` are counts.
21. `F`'s `instances` is a count of at least `W` × `P` + `E`, the least that making the
instances took outside a stopped call (§5.3: a shot's instances are made module by
module in `C`'s order, each one's `wasmq-seed`, then its priors, then its `init`; passing
a prior calls `cabi_realloc`, at least 2 since it returns a value, then charges the
prior's bytes, then calls `wasmq-prior`, at least 1, §4.2, §5.2):
- `P`, what each set of instances took at least: the sum, over every prior of every one
of `C`'s modules, of 3 and the prior's `bytes` (0 when that is not a count), and 1
more when the fault is a lifecycle fault in phase `seed` or `init`: its module exports
that function, and each set called it;
- `W`, the sets made whole: `r`'s `shots_run` (0 when that is not a count), plus 1 when
there is a call's fault; when `run`'s `state` is `job` it is that or 1, whichever is
less;
- `E`, when the fault is a lifecycle fault, what the set it stopped took at least: the
same sum, of 3 and its `bytes`, over the priors of each module before the one the fault
names (the first of `C`'s modules with that `name`), and, when its phase is `init`, over
that module's own; 0 otherwise, and when no module has that `name`.
22. A call's fault's `module` equals the `name` of `C`'s module whose index is the
`module` of each of `C`'s callouts whose `extern` is the fault's `callout` (rule 7
allows one): a call runs in its callout's module (§2.2, §6.2). It fails when there is
no such callout, or no such module.
23. A fault whose `phase` is `prior` has as its `module` the `name` of one of `C`'s
modules whose `priors` is not empty: a prior is passed only to a module that has one
(§5.3).
24. A fault whose `reason` is `bad_result` has the `phase` `call` or `prior`: only these
pass bytes or take a result (§5.2).
25. A lifecycle fault's `fuel` is a count, and `F`'s `instances` (a count) is at least it
added to rule 21's `W` × `P` + `E`: what the stopped lifecycle call used is part of the
instances' fuel, beside what the calls before it took.
26. When `run`'s `state` is `job`, a lifecycle fault's `shot` is the count 0: the run's
one instance of each module is made at the first shot (§5.3).
27. A lifecycle fault whose `shot` is the count 0 comes with `r`'s `callouts` the count 0:
the first shot's instances are made before its first step (§5.3). (Rule 32 holds this
too, so rule 27 is never broken alone.)
28. A fault whose `reason` is `fuel_exhausted` used its whole limit (§4.2). When its
`budget` is `call`, its `fuel` is a count equal to the budget `per_call`; when it is
`instance`, to the budget `per_instance` (each 0 when it is not a count). When it is
`run`, `F`'s `used` is a count equal to the budget `per_job` (a count), and the fault's
`fuel` is a count, less than its own limit: the budget `per_call` in a call's fault, and
the budget `per_instance` in a lifecycle fault, each read as 0 when it is not a count (a
fault with no `phase` has no limit here, and breaks rule 18): the run's budget was the
limit only because less of it was left than the call's own.
29. When `r`'s `counts` has a name, the length of the longest, in characters (Unicode code
points), is at most 2^20, and `run`'s `shots` (0 when that is not a count) times that
length at most 2^28: a program holds at most 2^20 bits, and a run's shots times them are
at most 2^28 (§4.8). (Rule 19 holds each name to `0` and `1`, one byte each; a verifier
counts a name that breaks it in characters too.)
30. The part of a run's work that a receipt shows is at most 2^42 (§4.8):
`S` × 2·`n`·`w` + `I` × Σ (4096 × (1 + 2 × `p`) + `b`) + 131072 × Σ `b` + 4097 × `K` + 8 ×
the budget `per_job`. `S` is `run`'s `shots`; `n` is `r`'s `qubits`; `w` is ⌈`n`/32⌉, or
1 when that is 0; `I` is 1 when `run`'s `state` is `job` and `S` otherwise; each sum is
over `C`'s modules, `p` a module's number of priors and `b` its `bytes`; and `K` is `r`'s
`callouts`. Every number here that is not a count is read as 0. The host's work is at
least this: each shot's fresh tableau, each instance's module and its calls of
`wasmq-prior` and of `cabi_realloc` for it, the run's compiling, each call made (its
module's part, 4096, and its step, 1: a callout's step is counted in each shot whether or
not it runs) and the run's fuel.
31. The envelope the contract names is at most 2^27 bytes (§2.3): 20 bytes of magic and
lengths, its manifest (§2.1's members, in that order and with no space: 192 bytes and the
decimal digits of its `qubits`, `r`'s, and its `shots` and `seed`, `run`'s, each read as 0
when it is not a count), `C` in RFC 8785 form (§2.2; no bytes when the request has no
`wasmq`), and its frames (the program's `bytes`, each module's `bytes` and each prior's
`bytes`, each 0 when it is not a count), added, are at most 2^27.
32. `r`'s `callouts` is at most 2^21 × `H` (each 0 when it is not a count), where `H`, the
shots that ran steps, is `r`'s `shots_run` and 1 more when there is a call's fault: a
shot runs each of its steps at most once, every jump going forward, and a program has
at most 2^21 steps (§4.8), each call one of them.
33. Each prior passed whole fits within one lifecycle call's limit: 3 and its `bytes` (0 when
that is not a count) are at most the budget `per_instance` (0 when that is not a count),
for every prior of every one of `C`'s modules when `W` (rule 21) is at least 1, and for
each prior `E` counts otherwise. Passing a prior is one stretch under one limit:
`cabi_realloc`, its bytes and `wasmq-prior` (§5.2, §5.3).
34. A fault's `fuel`, when it is a count, is at least what its `reason` shows was charged
(§4.2), when it has one: 1 for every reason but `fuel_exhausted`, one §6.2 does not name
or `null` among them (a call stops any other way only after its entry was charged); 2
for `bad_result` (a value came back: the entry, and an instruction that made it); and 788
for `stack_exhausted`. A frame weighs at most
576 + 4096 + 2^8 + 2^14 = 21 312 (§3.2, §4.3), so the stack's weight passes 2^23 only at
a call in the 394th frame entered or deeper, and each frame entered was charged at least
2: its entry, and the run that holds its call.
35. When no call returned, the transcript is what §6.4 gives such a run: when `r`'s
`callouts` is 0, or 1 and the fault is a call's fault (each a count), `r`'s
`transcript_blake3` is BLAKE3 over the bytes `wai:wasmq-transcript` and the byte 0x01
and, when there
is a fault, the bytes `fault`, the fault's `shot` (u64), its `reason`'s UTF-8 bytes and
its `fuel` (u64), little-endian (`shot` and `fuel` each 0 when it is not a count, and
`reason` no bytes when it is not a string).
**What the rules leave free, and why.** What else the writer fixes, the rules leave free,
each for the reason given, and only running the envelope again (`--bundle`) holds a job to
it:
- the `transcript_blake3`'s value once a call returned: it digests each call's input and
output, which no receipt holds (rule 35 holds it when none returned); and each `blake3`
against the bytes it pins, which no receipt holds;
- `r`'s `qubits` within rule 12, the outcomes' length within rule 29, and the number of
callouts within rules 30 and 32, against the program: its text is not sealed, only its
digest and length, so how many qubits and bits it declares, and how many calls each shot
makes, are its own;
- which shot read which outcome, and the counts' spread: only the run shows them;
- whether a module exports `wasmq-seed` or `init`, but for the one a fault in that phase
names (rule 21): only its code shows it. So a fault in phase `seed` or `init` may name any
module;
- the instances' fuel within rules 17, 21 and 25: what each lifecycle call used past its
least, and how far the module a fault names got, are its code's;
- the fuel of each call within rules 14, 18, 20, 28 and 34, and a fault's fuel within rules
18, 20, 21, 25, 28 and 34: where in its work a call traps, and how many bytes its arguments
pass, are its module's and its program's;
- a trap's `reason` against its phase: any guest call can trap any way, and only
`bad_result` is the host's (rule 24);
- the rest of §4.8's bounds (the steps of a shot past rule 32's count, the gates and
measurements, the bits of calls, the pages a module starts with, the program's reading):
each counts what only the program or the modules hold, so rules 29 to 32 take what a
receipt shows, and a job a writer can write never breaks them;
- the least length of a program and of a module, and the spelling of an `extern`: a program
that packs declares an `extern`, a qubit and a call, a module that packs has a type, a
function, an export and its code, and an `extern` is a name the reader reads, its letters
any of Unicode's. So each has a least length, and an `extern` a form, that a rule could
state; but they follow from the grammar, WebAssembly's binary format and Unicode's tables
rather than from anything a run does, bound nothing a host does, and a rule at them would
hold every verifier to those tables. Rules 5, 6 and 7 hold the program's and a module's
`bytes` to at least 1 and an `extern` to a string, and leave the rest free.
Beside §8.4's reasons a verifier of the engine states, for a wasmQ job, `wasmq`:
`outcome`, the sealed result's `status`; `problems`, what breaks each rule the job breaks,
in words, each naming its rule first (`rule 19: ...`), the first 64 of them and then how
many more; and `notes`, where the host's unsealed words
differ from what is sealed or are missing ("the host's unsealed status says `done`; the
sealed result says `fault`"). A note is no part of the verdict: the verdict is the sealed
content's alone, so that every surface that checks a job gives the same one.
`wai-quantum verify JOB.json` prints the receipt's check, the outcome and each problem and
note; `--json` gives the verdict as JSON. `--lines` reads a file of one job a line, each
line on its own as a job's text (a line that is not UTF-8, or blank, is that line's
`unreadable`; the newline that ends the file ends its last line), and gives one verdict a
line, each a job's whatever its kind; a file with no line is refused. A job found
unreadable, no job, with no receipt, or longer than the surface reads (`too_large`) is
reported alone (§8.4), whatever kind of job it says it is: `verify` says that its form was
not judged, and runs no envelope for it. `verify` reads at most 384 MiB and 2^22 values
(§8.4), more than any job holds, in about 1 GiB of memory at most on every host: a file past the
bytes is `too_large` by its size, before it is read, and one past the values once read,
before it is parsed; a file of lines past the bytes is refused, and a line past the values
is that line's `too_large`. With `--bundle ENVELOPE.wai` it also checks
that the envelope is the one the receipt binds (its BLAKE3 is the request's
`envelope_blake3`, and its contract is `C`), and runs it again here: the result must be
the same, byte for byte, the receipt aside; with `--json` the verdict then also says
`bundle` and `reproduced`, and is valid only when both hold. A wasmQ job carries no
history, so `--history` is refused for one.
## 7. On hardware
**The bring-your-own-quantum boundary is unchanged.** WAI Quantum never pays for or
resells hardware time; a person's providers speak `wai.quantum.provider/1`
([quantum-providers](quantum-providers.md)), whose program is a fixed sequence of native
gates measured at the end. A wasmQ bundle calls its modules between gates, which that
protocol does not carry, so `run ENVELOPE.wai --provider NAME` is refused, and the hosted
job service takes no bundle. A wasmQ run simulates the quantum part on this machine.
**Nothing here has run a module beside a quantum processor.** This repository has run
wasmQ modules only on the hosts its tests name. What holds for a module on a machine
that runs classical code between gates, and what does not:
- A scalar-form module (§5.2) is a function of integers that imports nothing. Whether a
given machine takes it is that machine's to say.
- The quantum part's measurements on hardware are not reproducible, so a hardware run
has no single result to reproduce. Its classical part does: given the inputs each call
received, a module gives the same outputs and the same fuel on every host, so a
record of the calls (`run --transcript`) replays through the modules alone and is
checked call by call (`run ENVELOPE.wai --replay TRANSCRIPT`), each of a shot the run
has, in the order of its shots. Each call shows only itself; that a record is the whole
of a run's shows in its digest, which a replay states and the receipt of a run that ended
`ok` seals as `transcript_blake3`. A machine that ran the module would have to report
those inputs and outputs for anyone to check them.
- Fuel is not time (§4.2). A real-time deadline is the machine's; the profile states
the work.
## 8. Reference modules
Two modules of record are built from code the engine already has, for
`wasm32-unknown-unknown` with Lime1 (`wai-wasmq/modules/`, `build.sh`), and committed in
[`../quantum-conformance/wasmq/modules/`](../quantum-conformance/wasmq/modules/) with
the digests of the sources that made them. rustc's wasm32 output depends on the host it
runs on, so they are built on x86_64 Linux, where CI rebuilds them and compares.
### 8.1 The qLDPC decoder
`quantum_qec`'s decoders: union-find matching for a code whose qubits each lie in at most
two checks (the surface code), Relay-BP in fixed-point arithmetic otherwise (the
bivariate-bicycle codes), as the engine itself chooses. Prior 0 is a code's parity
checks in `CssCode::check_matrix_bytes`'s form. Exports: `decode` (list) and `decode64`
(scalar). Tests hold every result to the same functions compiled natively, on every
weight-two error of the distance-3 surface code and on random errors of the [[72,12]]
bivariate-bicycle code (`CssCode::gross()`), and run memory rounds of the distance-3 and
distance-5 surface codes and of that code (a 129-qubit circuit) with the decoder called
between the syndrome and the correction, each shot ending in the code, on every engine
with the same bytes.
### 8.2 The atom rearrangement planner
`quantum_atom::solve`, an exact Hungarian assignment of loaded atoms to target sites.
Prior 0 is the target register in `target_bytes`'s form. Exports: `plan` (list) and
`plan64` (scalar). A circuit loads each trap with probability ½, measures the occupancy,
calls the planner, applies its moves and reads the array: every shot whose plan is
feasible fills the target, and atoms are moved, never made or lost.
## 9. Conformance
[`../quantum-conformance/wasmq/`](../quantum-conformance/wasmq/) holds:
- `envelopes/`: envelopes, each with the result it MUST give on every engine and every
host (`vectors.json`, `runs`): the status, the fault, the fuel, the transcript's
digest, the result's digest, the receipt's digest and, under the vectors' key, the
whole job's digest. Among them are runs that end in every fault reason §6.2 names, in
every phase and of every budget; callouts of the list form, with a `cabi_post` call and
with each way a list result is not one; a signed argument; two modules made in order; a
program that declares no qubit and names physical ones, its bits in two registers; a
program that measures nothing; one with bits nothing writes, and one whose block holds a
bit of its own, which pin §6.1's outcome; and a program whose resets and measurements pin
§6.1's stream;
- `refuse/`: modules and envelopes a runner MUST refuse, each with its code
(`vectors.json`, `refuse`), at least one for every code of §3.3, each one defect away
from a module or an envelope that is accepted; the modules also as WebAssembly text
where they have one. An envelope past §2.3's size has no vector, for its size: a test
in `wai-wasmq/tests/sweep.rs` makes one;
- `modules/`: the modules of record (§8).
Six wasmQ jobs the command line sealed are among the job receipts of
[`../quantum-conformance/receipts/`](../quantum-conformance/receipts/) (`jobs/cli-wasmq-*`):
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. Beside them are jobs
crafted from them, sealed again, each of rules 2 to 31 broken alone by one at least, so the
two verifiers of that corpus, which share no code, are held to each other on `wasmq_form`
and on the rules each states broken, and on every change of one member of each of the six.
`wasmq_vectors verify wai/quantum-conformance/wasmq` checks them on every engine of the
build and prints a digest of what it computed (each run's job and each refusal's code),
the same on every host that conforms.
## 10. Versioning
`wai.quantum.wasmq/1` is this text. A change to anything that moves a result's bytes or
a module's fuel (the weights, the runs, the stack's weights, the lowering, the stream,
the transcript, the result's members) is a new profile version, and a receipt names the
version it was made under.
This version leaves out, and a later one may add under a name of its own:
- gates that take an angle and gates outside the Clifford group, which need a method
whose arithmetic this text would have to fix bit for bit. The state-vector method,
which the engine runs in floating point, is not part of this version for that reason:
`stabilizer` is its one method (§2.2);
- floating-point arguments and results of a callout;
- noise, and observables other than the counts.

View file

@ -0,0 +1,61 @@
// The WebAssembly interface of a wasmQ module (quantum-wasmq.md).
// SPDX-License-Identifier: Apache-2.0
//
// A wasmQ module is a core WebAssembly module (quantum-wasmq.md §3). Its exports are the
// Component Model's canonical lowering of the functions below, so a component host can
// wrap it, and a host of this profile calls it directly. An OpenQASM 3 `extern` lowers to
// one of two forms (§5.2): scalar, every argument and the result at most 64 bits, each a
// u64 or s64; or list, each `bit[n]` a list<u8>, the lowest bit first. A module with a
// list-form export or a prior exports its memory as `memory`, where a host reaches it.
//
// The direction is the hardware's: the quantum program calls the module. A module
// imports nothing (§3.2), so this package has no interface a module imports.
package wai:[email protected];
/// What a receipt names when a run stops (§6.2).
interface receipt {
enum fault-reason {
unreachable,
memory-out-of-bounds,
table-out-of-bounds,
indirect-call-null,
indirect-call-type,
integer-divide-by-zero,
integer-overflow,
invalid-conversion-to-integer,
fuel-exhausted,
stack-exhausted,
bad-result,
}
}
/// A module's lifecycle (§5.3), every export optional: the seed, then each prior in the
/// order the contract lists them, then `init`, each metered.
world module {
/// The seed for this instance: the run's, or the shot's when an instance lives for a shot.
export wasmq-seed: func(seed: u64);
/// Prior `index` of the module's priors, its bytes as the contract pins them.
export wasmq-prior: func(index: u32, bytes: list<u8>);
export init: func();
}
/// The reference decoder (§8.1): the engine's qLDPC decoder. Prior 0 is a code's parity
/// checks; a syndrome goes in, a correction comes out.
world qldpc-decoder {
include module;
/// The list form: `extern decode(bit[m]) -> bit[n];` for any code.
export decode: func(syndrome: list<u8>) -> list<u8>;
/// The scalar form: `extern decode64(bit[m]) -> bit[n];`, m and n at most 64.
export decode64: func(syndrome: u64) -> u64;
}
/// The reference planner (§8.2): the engine's neutral-atom rearrangement. Prior 0 is the
/// target register; an occupancy goes in, the moves come out as masks.
world atom-planner {
export wasmq-prior: func(index: u32, bytes: list<u8>);
/// The list form: `extern plan(bit[n]) -> bit[2n+1];`.
export plan: func(occupancy: list<u8>) -> list<u8>;
/// The scalar form, for at most 31 sites.
export plan64: func(occupancy: u64) -> u64;
}

View file

@ -20,7 +20,9 @@ The OpenQASM 3 reader's corpus, programs with what the reader must do with
each, is `qasm3/`, with a README of its own. The error-correction text formats
(noisy Clifford circuits and detector error models, read and written back byte
for byte, with what each must count and what must be refused) are `qec-text/`,
with a README of its own. Programs in other formats (QIR under its profiles,
with a README of its own. Programs that call WebAssembly between their gates (`wai.quantum.wasmq`), the
reference modules of record and what a runner refuses are `wasmq/`, with a README of its
own. Programs in other formats (QIR under its profiles,
and jeff), each with the program it must read to, its round trip and its
refusals, and OpenQASM written to each, are `formats/`, with a README of its
own.

View file

@ -8,11 +8,12 @@ exactly the reasons the manifest names (§8.4): none for a valid one.
|---|---|
| `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, and runs on the reference provider over a local process, free and priced |
| `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/service-*.json` | made by the free job service, sealed with its key (`make.sh`) |
| `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) |
| `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, each sealed again with the demo key where the change is inside the seal so that one rule alone breaks |
| `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 and of a wasmQ job's form, each sealed again with the demo key where the change is inside the seal so that one rule alone breaks |
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
@ -24,7 +25,9 @@ to pass a test. A row of §8.3 that a client stops writing is held by the receip
- `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. Standard library only: its BLAKE3,
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. Standard library only: its BLAKE3,
Ed25519, RFC 8785 text and strict reader are its own, each held to published answers by
`--self-test`.
@ -47,6 +50,35 @@ replaced) and requires the same reasons from both for every change, and two orac
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 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

View file

@ -302,11 +302,50 @@ def seal_set(body, seed=DEMO):
return out
def _count(v):
"""A count's value (quantum-wasmq section 6.5): a whole number from 0 to 2^53 - 1."""
if isinstance(v, Raw):
v = v.value
if isinstance(v, bool) or not isinstance(v, (int, float)) or v != v or v in (float("inf"), float("-inf")):
return None
return int(v) if v == int(v) and 0 <= v <= 2 ** 53 - 1 else None
def bare_transcript(r):
"""The transcript_blake3 of a wasmQ result in which no call returned (quantum-wasmq
section 6.5, rule 35): the prefix and, after a fault, its shot, reason and fuel. None
when a call returned, or its callouts are no count."""
if not isinstance(r, dict) or r.get("format") != "wai.quantum.wasmq.result/1":
return None
fault = r.get("fault") if r.get("status") == "fault" and isinstance(r.get("fault"), dict) else None
in_call = 1 if fault is not None and fault.get("phase") == "call" else 0
k = _count(r.get("callouts"))
if k is None or k > in_call:
return None
data = b"wai:wasmq-transcript\x01"
if fault is not None:
reason = fault.get("reason")
data += b"fault" + struct.pack("<Q", _count(fault.get("shot")) or 0) + (reason.encode("utf-8") if isinstance(reason, str) else b"") + struct.pack("<Q", _count(fault.get("fuel")) or 0)
return blake3(data).hex()
def retranscribed(before, b):
"""b, a wasmQ job changed from before, its transcript made again as the writer makes it
when no call returned, unless the change was to the transcript itself."""
r = b.get("result")
if isinstance(r, dict) and r.get("transcript_blake3") == before.get("result", {}).get("transcript_blake3"):
t = bare_transcript(r)
if t is not None:
r["transcript_blake3"] = t
return b
def edited(body, edit, form="canonical"):
"""body changed by edit (which may change request, result or both), sealed again."""
"""body changed by edit (which may change request, result or both), sealed again; a
wasmQ job in which no call returned keeps the transcript its writer would give it."""
b = copy.deepcopy(body)
edit(b)
return seal(b, form=form)
return seal(retranscribed(body, b), form=form)
def rx(body, edit):
@ -700,6 +739,138 @@ def cases():
add("method-measured", edited(run, at(R + ("accuracy", "class"), "measured")), ["provider_class"], "the engine's own result labelled measured")
add("method-simulated", edited(run, at(R + ("accuracy", "class"), "simulated")), ["provider_class"], "the engine's own result labelled simulated")
add("method-class-unknown", edited(run, at(R + ("accuracy", "class"), "quasi-exact")), [], "a class a verifier does not know: not a reason, since a later version may add one")
# --- a wasmQ job (quantum-wasmq section 6.5): each sealed again, one rule broken
wrun = load("cli-wasmq-run.json")
wfault = load("cli-wasmq-fault.json")
wjob = load("cli-wasmq-state-job.json")
C = ("request", "wasmq")
def fewer(k, by=1):
def f(b):
counts = b["result"]["counts"]
most = max(counts, key=lambda o: counts[o])
counts[most] -= by
if k:
b["result"]["shots_run"] -= by
return f
def both(name, value):
def f(b):
b["request"]["wasmq"]["run"][name] = value
b["result"][name] = value
return f
def budget(name, value):
def f(b):
b["request"]["wasmq"]["run"]["fuel"][name] = value
b["result"]["fuel"]["budget"][name] = value
return f
add("wasmq-counts-short", edited(wrun, fewer(False)), ["wasmq_form"], "a wasmQ run whose counts add up to one shot fewer than it ran (rule 19)")
add("wasmq-ok-before-all-shots", edited(wrun, fewer(True)), ["wasmq_form"], "a wasmQ run that is ok after 31 of its 32 shots (rule 18)")
add("wasmq-fuel-unaccounted", edited(wrun, lambda b: b["result"]["fuel"].update(instances=b["result"]["fuel"]["instances"] + 1)), ["wasmq_form"], "a wasmQ run whose instances and calls do not add up to the fuel it used (rule 15)")
add("wasmq-fuel-past-job-budget", edited(wfault, budget("per_job", 100)), ["wasmq_form"], "a wasmQ fault that used 400 fuel under a run's budget of 100 (rule 13)")
add("wasmq-instances-past-budget", edited(wjob, budget("per_instance", 8000)), ["wasmq_form"], "one instance for the whole run, given more fuel for its seed, init and prior than three stretches of 8000 (rule 17)")
add("wasmq-fault-unnamed", edited(wfault, lambda b: (b["result"]["fault"].update(reason="out_of_fuel"), b["result"]["fault"].pop("budget"))), ["wasmq_form"], "a wasmQ fault of a reason the profile does not name (rule 18)")
add("wasmq-result-member-added", edited(wrun, at(R + ("note",), "a member the profile does not write")), ["wasmq_form"], "a wasmQ result with a member the profile does not write (rule 9)")
add("wasmq-contract-method", edited(wrun, both("method", "statevector")), ["wasmq_form"], "a wasmQ contract and result of a method the profile does not have (rule 8)")
add("wasmq-seed-past-exact", edited(wrun, both("seed", 2 ** 53)), ["wasmq_form"], "a wasmQ seed of 2^53: a double holds it, so it is no inexact number, and the profile allows at most 2^53 - 1 (rules 1, 8)")
add("wasmq-modules-other", edited(wrun, lambda b: b["result"]["modules"][0].update(blake3="ab" * 32)), ["wasmq_form"], "a wasmQ result naming a module the contract does not pin (rule 16)")
add("wasmq-transcript-upper", edited(wrun, lambda b: b["result"].update(transcript_blake3=b["result"]["transcript_blake3"].upper())), ["wasmq_form"], "a wasmQ transcript digest in upper case (rule 12)")
add("wasmq-first-form", seal(wrun, form="first"), ["wasmq_form"], "a wasmQ job sealed in the first form, older than the profile: the seal holds, and no host wrote it (rule 10)")
def uncounted(b):
b["result"].update(callouts=0)
b["result"]["fuel"].update(callouts={}, instances=400)
add("wasmq-call-fault-uncounted", edited(wfault, uncounted), ["wasmq_form"], "a call that stopped the run, which the fuel counts no call of: the stopped call is one of the calls made (rule 18)")
def past_largest(b):
b["result"].update(callouts=2)
b["result"]["fuel"]["callouts"]["f"].update(calls=2, fuel=401, max=399)
b["result"]["fuel"]["used"] = 401
add("wasmq-call-fault-past-largest", edited(wfault, past_largest), ["wasmq_form"], "a call that stopped after 400 fuel, where the most one call of it used is 399 (rule 18)")
# Each rule the corpus held no receipt for, broken alone (rule 1 cannot be: every place a
# number may be has a rule of its own that holds it within 2^53 - 1).
wrunf = load("cli-wasmq-fault-run.json")
winit = load("cli-wasmq-fault-init.json")
wprior = load("cli-wasmq-fault-prior.json")
def each(*edits):
def f(b):
for e in edits:
e(b)
return f
def later_shot(shot, state=None, instances=1, fuel=1, callouts=None):
# The init fault moved to `shot`, after that many shots of one call each.
def f(b):
n = shot if callouts is None else callouts
if state:
b["request"]["wasmq"]["run"]["state"] = state
b["result"].update(shots_run=shot, counts={"0": shot} if shot else {}, callouts=n)
b["result"]["fuel"].update(instances=instances, callouts={"f": {"calls": n, "fuel": n, "max": 1}} if n else {}, used=instances + n)
b["result"]["fault"].update(shot=shot, fuel=fuel)
return f
def second_module(fault_module):
def f(b):
c = b["request"]["wasmq"]
c["modules"].append({"name": "m2", "blake3": "cd" * 32, "bytes": 57, "priors": []})
c["callouts"].append({"extern": "g", "module": 1, "export": "g"})
b["result"]["modules"].append({"name": "m2", "blake3": "cd" * 32})
b["result"]["fault"]["module"] = fault_module
return f
def shots(n):
def f(b):
b["request"]["wasmq"]["run"]["shots"] = b["result"]["shots"] = n
return f
add("wasmq-request-member-added", edited(wrun, at(("request", "x"), 1)), ["wasmq_form"], "a wasmQ request with a member the profile does not write (rule 2)")
add("wasmq-contract-member-added", edited(wrun, at(C + ("x",), 1)), ["wasmq_form"], "a wasmQ contract with a member section 2.2 does not list (rule 3)")
add("wasmq-contract-profile", edited(wrun, at(C + ("profile",), "wai.quantum.wasmq/2")), ["wasmq_form"], "a wasmQ contract of another profile (rule 4)")
add("wasmq-program-empty", edited(wrun, at(C + ("program", "bytes"), 0)), ["wasmq_form"], "a wasmQ contract whose program is 0 bytes long (rule 5)")
add("wasmq-module-empty", edited(wrun, lambda b: b["request"]["wasmq"]["modules"][0].update(bytes=0)), ["wasmq_form"], "a wasmQ contract whose module is 0 bytes long (rule 6)")
add("wasmq-callouts-twice", edited(wrun, lambda b: b["request"]["wasmq"]["callouts"].append({"extern": "decode64", "module": 0, "export": "x"})), ["wasmq_form"], "a wasmQ contract with two callouts of one extern (rule 7)")
add("wasmq-result-seed", edited(wrun, lambda b: b["result"].update(seed=b["result"]["seed"] + 1)), ["wasmq_form"], "a wasmQ result whose seed is not its contract's (rule 11)")
add("wasmq-call-past-per-call", edited(wrun, budget("per_call", 21750)), ["wasmq_form"], "a wasmQ run whose largest call used 21751 fuel under a budget of 21750 a call (rule 14)")
add("wasmq-calls-of-no-fuel", edited(wrun, lambda b: (b["result"]["fuel"]["callouts"]["decode64"].update(fuel=0, max=0), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"]))), ["wasmq_form"], "32 calls that returned having used no fuel, where entering a function weighs 1 (rule 20)")
add("wasmq-priors-unpassed", edited(wrun, lambda b: b["result"]["fuel"].update(instances=32 * 90 - 1, used=32 * 90 - 1 + 588348)), ["wasmq_form"], "32 shots of instances passed a prior of 87 bytes in less fuel than its bytes and its two calls take, cabi_realloc 2 at least and wasmq-prior 1 (rule 21)")
add("wasmq-call-fault-other-module", edited(wfault, second_module("m2")), ["wasmq_form"], "a call of a callout in the first module, whose fault names the second (rule 22)")
add("wasmq-prior-fault-no-prior", edited(winit, at(R + ("fault", "phase"), "prior")), ["wasmq_form"], "a fault while a prior is passed, in a module with no prior (rule 23)")
add("wasmq-bad-result-in-init", edited(winit, each(at(R + ("fault", "reason"), "bad_result"), at(R + ("fault", "fuel"), 2), at(R + ("fuel", "instances"), 2), at(R + ("fuel", "used"), 2))), ["wasmq_form"], "a bad_result from an init, which takes no result (rule 24)")
add("wasmq-lifecycle-fuel-past-instances", edited(winit, later_shot(1, instances=1, fuel=2)), ["wasmq_form"], "an init fault in shot 1 that used 2 fuel, where the instances used 1, shot 0's init 1 of it at least (rule 25)")
add("wasmq-job-state-later-instance", edited(winit, later_shot(2, state="job", instances=2)), ["wasmq_form"], "a run of one instance for the run whose instance fails in shot 2 (rule 26)")
add("wasmq-first-instance-after-call", edited(winit, later_shot(0, callouts=1)), ["wasmq_form"], "the first shot's instance failing after a call was made, where no shot ran its steps (rules 27 and 32)")
add("wasmq-fuel-fault-under-limit", edited(wfault, lambda b: (b["result"]["fuel"]["callouts"]["f"].update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=10))), ["wasmq_form"], "a call's fuel fault after 10 fuel, under its limit of 400 (rule 28)")
add("wasmq-run-budget-not-spent", edited(wrunf, budget("per_job", 60)), ["wasmq_form"], "a fault of the run's budget with 50 of its 60 used (rule 28)")
add("wasmq-results-past-bits", edited(wrunf, each(shots(2 ** 20), lambda b: b["result"].update(counts={"0" * 257: 2}))), ["wasmq_form"], "2^20 shots of 257 bits, past the 2^28 bits a run's results hold (rule 29)")
add("wasmq-work-past-bound", edited(wrun, budget("per_job", 2 ** 39)), ["wasmq_form"], "a run given 2^39 fuel beside a module's code, past the 2^42 operations a run asks (rule 30)")
add("wasmq-frames-past-envelope", edited(wprior, lambda b: b["request"]["wasmq"]["modules"][0]["priors"][0].update(bytes=2 ** 27)), ["wasmq_form"], "a prior of 2^27 bytes beside a program and a module, more than an envelope holds (rule 31)")
add("wasmq-fault-null", edited(wrun, at(R + ("fault",), None)), ["wasmq_form"], "an ok result with a fault member whose value is null: a member is present whatever its value (rule 18)")
# Round 5's rules, each broken alone.
add("wasmq-no-qubit", edited(wrun, at(R + ("qubits",), 0)), ["wasmq_form"], "a wasmQ result of a program of no qubit, which no program a reader reads is (rule 12)")
def calls_at_their_largest(b):
b["result"]["fuel"]["callouts"]["decode64"].update(fuel=21751)
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + 21751
add("wasmq-calls-under-largest", edited(wrun, calls_at_their_largest), ["wasmq_form"], "32 calls in 21751 fuel, where the most one of them used is 21751 and each other used 1 at least (rule 20)")
def calls_past_steps(b):
n = 32 * 2 ** 21 + 1
b["result"]["callouts"] = n
b["result"]["fuel"]["callouts"]["decode64"].update(calls=n, fuel=n, max=1)
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + n
add("wasmq-calls-past-steps", edited(wrun, calls_past_steps), ["wasmq_form"], "32 shots that made 2^21 calls each and one more, where a shot runs at most 2^21 steps (rule 32)")
add("wasmq-prior-past-instance-budget", edited(wrun, each(budget("per_instance", 89), lambda b: b["result"]["fuel"].update(instances=32 * 90, used=32 * 90 + 588348))), ["wasmq_form"], "a prior of 87 bytes passed whole in one stretch, which takes 90 at least, under a lifecycle call's budget of 89 (rule 33)")
add("wasmq-trap-of-no-fuel", edited(winit, at(R + ("fault", "fuel"), 0)), ["wasmq_form"], "an init that trapped after no fuel, where its entry is charged before it runs (rule 34)")
add("wasmq-transcript-of-no-call", edited(winit, at(R + ("transcript_blake3",), "ab" * 32)), ["wasmq_form"], "a fault before any call whose transcript is not the run's end alone (rule 35)")
respelt = copy.deepcopy(wrun)
respelt["request"]["wasmq"]["run"]["shots"] = Raw("32.0", 32)
respelt["result"]["shots"] = Raw("3.2e1", 32)
add("wasmq-respelt", (dump(respelt) + "\n").replace('"state": ', '"\\u0073tate": ', 1), [], "a wasmQ job with its shots written 32.0 and 3.2e1 and a member of its contract named with an escape: the same sealed content")
moved = copy.deepcopy(wfault)
moved.update(status="done", method="statevector", id="j-another")
add("wasmq-envelope-changed", moved, [], "a wasmQ fault whose unsealed body says done, another method and an id: a note beside the verdict, not a reason")
return out
@ -729,6 +900,12 @@ MADE = {
"cli-set-sweep.json": ("the command line: a sweep of an input at three points, sealed as a set", []),
"first-form-service-run.json": ("the job service as it was on 18 October 2026, commit 72d18742d, sealing with the first form's own writer: counts", []),
"first-form-service-observables.json": ("the same service, the same writer: expectation values, doubles in its own text", []),
"cli-wasmq-run.json": ("the command line: a wasmQ run, a surface-code round decoded by WebAssembly between its gates, 32 shots", []),
"cli-wasmq-state-job.json": ("the command line: a wasmQ run of one instance for the whole run, its decoder reading a prior", []),
"cli-wasmq-fault.json": ("the command line: a wasmQ run that stopped in a call past the call's fuel budget", []),
"cli-wasmq-fault-run.json": ("the command line: a wasmQ run that stopped in its third shot when the run's fuel ran out", []),
"cli-wasmq-fault-init.json": ("the command line: a wasmQ run that stopped in an instance's init", []),
"cli-wasmq-fault-prior.json": ("the command line: a wasmQ run that stopped while a module read its prior", []),
}

View file

@ -0,0 +1 @@
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3","bytes":50,"name":"m","priors":[]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":1,"shots":4,"state":"shot"}},"envelope_blake3":"d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":4,"shots_run":0,"seed":1,"counts":{},"callouts":0,"fuel":{"used":1,"instances":1,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{}},"modules":[{"name":"m","blake3":"f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"}],"transcript_blake3":"1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881","accuracy":{"class":"exact"},"fault":{"reason":"unreachable","shot":0,"phase":"init","module":"m","fuel":1},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"ac633eb1fb15f62ad6df9b6b7891dc7ada2dac6c1503e5f4d073dc866b40cd6d","signature":"0c6cdfa74c73a0922c550acef28da9cca21f87eae4310ed81e7365dc85a6076361b11316c21bc0a2db66f103d0f7c2e7c46bd4da68620c1112d3ac80a728c109"}}}

View file

@ -0,0 +1 @@
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0","bytes":105,"name":"m","priors":[{"blake3":"024f67c0425a3dc02fbaf58cb93de5132e3d75c519faa0bada21491d88c97057","bytes":5,"name":"weights"}]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":1,"shots":4,"state":"shot"}},"envelope_blake3":"6da2c86da1b3d288df324fa7902e4cb10c9c5b21160921907299402466c5d50c"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":4,"shots_run":0,"seed":1,"counts":{},"callouts":0,"fuel":{"used":8,"instances":8,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{}},"modules":[{"name":"m","blake3":"2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0"}],"transcript_blake3":"3db8f511346d060c257940c086300666c8eb1b27c6083d36066b8d8f38e6408c","accuracy":{"class":"exact"},"fault":{"reason":"unreachable","shot":0,"phase":"prior","module":"m","fuel":8},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"48f6ca3e7cc12a0ac8f277c342bf8098c9ca9d2938f855eb75336a33e0ce29b3","signature":"78b5984d9ce1a89580c32cdd987840b89d357745d23e70ae259bdd66ae0cc128ca10cc0e754e67bf71e1c768c531e340f7b5ea9d654a2508d9fb6f60709ba80a"}}}

View file

@ -0,0 +1 @@
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43","bytes":68,"name":"m","priors":[]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":50},"method":"stabilizer","seed":1,"shots":8,"state":"shot"}},"envelope_blake3":"0a19542a6a9178984a93d9863a1d5e9371e00b86c6e9143e04b5f0fb5b0be177"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":8,"shots_run":2,"seed":1,"counts":{"0101101101011011":1,"1011111010111110":1},"callouts":3,"fuel":{"used":50,"instances":0,"budget":{"per_call":10000000,"per_job":50,"per_instance":100000000},"callouts":{"f":{"calls":3,"fuel":50,"max":23}}},"modules":[{"name":"m","blake3":"9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43"}],"transcript_blake3":"3772395e9bb2f9fba3b1a7ef4f5def3e5f10f76a9ba517d16056e5fd7cb7d413","accuracy":{"class":"exact"},"fault":{"reason":"fuel_exhausted","shot":2,"phase":"call","module":"m","fuel":4,"callout":"f","budget":"run"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"39102ed51a3b76f36d8fafb5a7f4d9af7c1d2363e74b5c1d6dfe593770b364ad","signature":"7705ba3a31066100c6b9e228716e2359a834eb10b6bffda1bcca5da1483227ae0a4553e113b351e4ae4861060eb73b01343c0e26ec58f7c5bba7d730fc1dc70e"}}}

View file

@ -0,0 +1 @@
{"status":"fault","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"f","extern":"f","module":0}],"modules":[{"blake3":"a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1","bytes":57,"name":"m","priors":[]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319","bytes":128,"inputs":{}},"run":{"fuel":{"per_call":400,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":9,"shots":32,"state":"shot"}},"envelope_blake3":"22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"fault","method":"stabilizer","qubits":8,"shots":32,"shots_run":0,"seed":9,"counts":{},"callouts":1,"fuel":{"used":400,"instances":0,"budget":{"per_call":400,"per_job":17179869184,"per_instance":100000000},"callouts":{"f":{"calls":1,"fuel":400,"max":400}}},"modules":[{"name":"m","blake3":"a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"}],"transcript_blake3":"47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7","accuracy":{"class":"exact"},"fault":{"reason":"fuel_exhausted","shot":0,"phase":"call","module":"m","fuel":400,"callout":"f","budget":"call"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"9cab411ba32a647e5c4b0ce53609a4308c1a07bd26c817fca582e3e04258bff4","signature":"c939aab422b5bf97f2abb4264df90c7aa2c69287570ed177edaa1a2fad8c4ddc9ea3758ee11cea21341c84a9d4eb47da4549431f32c9d8adbfe2721ade007a07"}}}

View file

@ -0,0 +1 @@
{"status":"done","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"decode64","extern":"decode64","module":0}],"modules":[{"blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962","bytes":39442,"name":"qldpc-decoder","priors":[{"blake3":"1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db","bytes":87,"name":"checks"}]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85","bytes":1104,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":1234,"shots":32,"state":"shot"}},"envelope_blake3":"3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"ok","method":"stabilizer","qubits":17,"shots":32,"shots_run":32,"seed":1234,"counts":{"000000000000000000000000001001":3,"000000000000000000000000001010":2,"000000000000000000000000001011":4,"000000000000000000000000001101":2,"000000000000000000000000001110":2,"000000000000000000000000001111":1,"000000000000000000000100010000":4,"000000000000000000010010000010":2,"000000000000000000100001010011":2,"000000000000000001000000110100":2,"000000000000000010000010100101":2,"000000000000000100000001000110":3,"000000011000000000000100010001":2,"110000000000001000000000101000":1},"callouts":32,"fuel":{"used":836380,"instances":248032,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{"decode64":{"calls":32,"fuel":588348,"max":21751}}},"modules":[{"name":"qldpc-decoder","blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"}],"transcript_blake3":"037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82","accuracy":{"class":"exact"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"df6d2e83f44afa7db6d7c6a3d4791443525b1778b794023326296050cb47dcb1","signature":"1ea3250661d07afe9e5f0bac876186cb6fb93ff2c9595e1f4d41c1bb7f9b0674d0146f9329a24d3b22c74d666f3f63329b19970c9ee90eb199f448e7a0e13a01"}}}

View file

@ -0,0 +1 @@
{"status":"done","method":"stabilizer","request":{"wasmq":{"callouts":[{"export":"decode64","extern":"decode64","module":0}],"modules":[{"blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962","bytes":39442,"name":"qldpc-decoder","priors":[{"blake3":"a0a28225df247910039d0693ff2dfb69d3b012487e81fc449486dd5b9afc3fd7","bytes":231,"name":"checks"}]}],"profile":"wai.quantum.wasmq/1","program":{"blake3":"1c79196a4e25b4f73f53a8327d9ab5d4d1644040f6b5036bb34aa1d456f2ee28","bytes":3346,"inputs":{}},"run":{"fuel":{"per_call":10000000,"per_instance":100000000,"per_job":17179869184},"method":"stabilizer","seed":77,"shots":16,"state":"job"}},"envelope_blake3":"3691fd8cac6fffe58d46a496aeff248a40d654129fe8cd23bae3dd6d3cebf8f4"},"result":{"format":"wai.quantum.wasmq.result/1","profile":"wai.quantum.wasmq/1","status":"ok","method":"stabilizer","qubits":47,"shots":16,"shots_run":16,"seed":77,"counts":{"000000000000000000000000000000000000000000000000000000000000000000000000001001110011":1,"000000000000000000000000000000000000000000000000000000000000010000000000011110000000":1,"000000000000000000000000000000000000000000000000000001000000010000000010110100000000":1,"000000000000000000000000000000000000000000000000000010001000000101000010010010101001":1,"000000000000000000000000000000000000000000000000010000000100000100001001000110000100":1,"000000000000000000000000000000000000000000000000100000000100000100001010000110100100":1,"000000000000000000000000000000000000000000000001000000000000011000000010010000001110":1,"000000000000000000000000000000000000000000000010100000000000000010001110000110101111":1,"000000000000000000000000000000000000001000000000000000000000000000100000001111010111":1,"000000000000000000000001100000000000000000000010000000000000010010000100010111100001":1,"000000000000011000110000000000000000000000000000000000011000000001000001000101001011":1,"000000000000011000110000000000000000000000000000000100011000010000000101010101100000":1,"000000011000110000000000000000000000000000000100001000000000000000010001000110010001":1,"001010001100000000000000000000000000000001000010000000000000000000000100001000010110":1,"001100000000000000000000000000000000000010100000000000000000001000110000001001110110":1,"110000000000000000000000000000000000001000000000000001000000000000100010100100011000":1},"callouts":16,"fuel":{"used":765610,"instances":24078,"budget":{"per_call":10000000,"per_job":17179869184,"per_instance":100000000},"callouts":{"decode64":{"calls":16,"fuel":741532,"max":57659}}},"modules":[{"name":"qldpc-decoder","blake3":"005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"}],"transcript_blake3":"eb5252076ea8bb4c45ccec714a3cc64b89e833fe0a49c36a28881b63b1c3799e","accuracy":{"class":"exact"},"energy":{"unmetered":"the runner reads no energy meter; fuel is the profile's measure of work"},"receipt":{"alg":"ed25519","canon":"rfc8785","key":"197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61","digest":"5109fd0c11be13f637530e8861ec2d625a2985a9a3ad9340e0d00d36aea2346d","signature":"62f2f505f3a36cf6e94e4113639db0eb64c4efe8ee8a902c4895e11f4de322ffdb6f610e68dbcbf6bdd2698ba7a0e46925a65134b95547d434070e6316cd1e09"}}}

View file

@ -0,0 +1,90 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
"bytes": 50,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "shot"
}
},
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 0,
"seed": 1,
"counts": {},
"callouts": 0,
"fuel": {
"used": 2,
"instances": 2,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {}
},
"modules": [
{
"name": "m",
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
}
],
"transcript_blake3": "c48396a6714b39ae0ea80250bf9f0311f615658bffd12ba92f0bb2f59872d7e4",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "bad_result",
"shot": 0,
"phase": "init",
"module": "m",
"fuel": 2
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "72f072588513ed965a36a7cd402e9980479d14208d7c51fe865791327e054b91",
"signature": "110cc7f0544a210de71a2ea0a54240dfa572ba7719ebf3a258c1fd2121272810a77c88da29e58dfc1b103d7f8f9b957b98aacaed29ac59ca9e63d1358a428c02"
}
}
}

View file

@ -0,0 +1,113 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
},
{
"extern": "g",
"module": 1,
"export": "g"
}
],
"modules": [
{
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
"bytes": 57,
"name": "m",
"priors": []
},
{
"name": "m2",
"blake3": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
"bytes": 57,
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 400,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 9,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 32,
"shots_run": 0,
"seed": 9,
"counts": {},
"callouts": 1,
"fuel": {
"used": 400,
"instances": 0,
"budget": {
"per_call": 400,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 1,
"fuel": 400,
"max": 400
}
}
},
"modules": [
{
"name": "m",
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
},
{
"name": "m2",
"blake3": "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
}
],
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 0,
"phase": "call",
"module": "m2",
"fuel": 400,
"callout": "f",
"budget": "call"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "e4af5b30d391f6049cba79d7d84b0069f659afa8e6215f790314014a4cf53c25",
"signature": "ec802b9ff66aa15c36c3cf2d2ae0924d6e2928b7697fa65c612b90e90f72bc2b07102c267304ac89311e1ad8adc78dca0836bb2116fafdd223dab24315d3cb0c"
}
}
}

View file

@ -0,0 +1,98 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
"bytes": 57,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 400,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 9,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 32,
"shots_run": 0,
"seed": 9,
"counts": {},
"callouts": 2,
"fuel": {
"used": 401,
"instances": 0,
"budget": {
"per_call": 400,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 2,
"fuel": 401,
"max": 399
}
}
},
"modules": [
{
"name": "m",
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
}
],
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 0,
"phase": "call",
"module": "m",
"fuel": 400,
"callout": "f",
"budget": "call"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "583cc658764532b53630e620ed79cc95ed0cf8d5ef4a54ceafea43b7e9304381",
"signature": "9341a9016bf590b7ce944cadbb070a4894b2bbb7083e3f8167109556d989979ee4087aae8de3e70649b5e8908cf9392c9b6d7fc969d1f06dc717fa24a10e730a"
}
}
}

View file

@ -0,0 +1,92 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
"bytes": 57,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 400,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 9,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 32,
"shots_run": 0,
"seed": 9,
"counts": {},
"callouts": 0,
"fuel": {
"used": 400,
"instances": 400,
"budget": {
"per_call": 400,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {}
},
"modules": [
{
"name": "m",
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
}
],
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 0,
"phase": "call",
"module": "m",
"fuel": 400,
"callout": "f",
"budget": "call"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "64aa39cd10a072bd758f09c0c6b4850d266f6025d2baf16d3e5c2366c74db475",
"signature": "ed7b6d1c9603d5a9371c4d59e3355acd3d24247ff1fab0b3fc45f9c7a61d3247286833f642ede8f3cc70fd2e74438eac8ab6664e393cdd909de5233f3fb73909"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 21750,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 21750,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "2b2cf2d827fe92e3a3b2d637fba76aa3b0019b34f9c355639e54a5ccd6b2f45e",
"signature": "225ea523d6694ac1679a54299bfaff95df59e844ae46318c3277675aa95ac4c958695315b9a080cf81b7d92c7f08ef22c5e5c6bef59063bc959360d2663a8d09"
}
}
}

View file

@ -0,0 +1,115 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
},
{
"extern": "decode64",
"module": 0,
"export": "x"
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "bdc1785c22876018049224778e3858b046cfbaad1169317de89bc5e22d1d46cb",
"signature": "f88677c1b1e369f68e930b99cf403e6e7d88456dd11ce9d83bde8f88f60b5613eaf057e5530b2356b8ccedf462b2b4e330907ddbdf131f0f1cc5577c75d3b702"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 248032,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 0,
"max": 0
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "db162e5b9b78f0eb0ff9988798d5224d2fce210dcd1c64d7f9a297280039beae",
"signature": "c4260104d12ba3c0baad5ee973db5c8d4e9f4f2df149fbeaccf4e456e48ed75023611cffc94328e9ea5bbf469c388dd8adecca4206cc186815cb95fc5b25770e"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 67108865,
"fuel": {
"used": 67356897,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 67108865,
"fuel": 67108865,
"max": 1
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "4ec0a4e4db7be0d45ce463a896aa9fb3b44c3b465452956adf68e96876e018c0",
"signature": "617f9909f5dbd9d25edd7b57bf5262ba0ead27eaf8b2ff06e680527229c8f37edf526a2435d5b9f631eea7b32cc87d886fc51e4f5dc8c251941c87e873801806"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 269783,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 21751,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "a8cccf2ac55c7b38c9d79c39632973d16edf0c30a9562e6e2320925695707c3b",
"signature": "e4dc7b3e7b5c5ed75c8656363466e6a39cbe33651c6f06135400f87421f4796c03aec50b280717340d8bb0cab10192a6ad63aa0cf739861233c0f1afdc789505"
}
}
}

View file

@ -0,0 +1,111 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
},
"x": 1
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "14d0220bed707653f2072608c81f8ff6681cb3ffcf0005b440818fcaa08ba680",
"signature": "805417bb8001494fbd5588ae1f4e7012e36fd1a1be0d791c1c02538050d2961de7a8def653a12fd13f737d836d1c279b9090a26ade13dd8fe65c1428de70d60c"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "statevector",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "statevector",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "441385ba757f9a5db8c0299871049c51c39a6650212b33c47ea4622720bc9de2",
"signature": "afd53deb5667de62981865b46e768c59629055926c5c0351e5c02ad3062a3d2c560235bd83c0ef289d449c278c05de94f57c47d38b618744f9b214b9f5fb910c"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/2",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "2daf5e56c89d2e829182a0f11eace97ae0e8870f810a1ffe952817d664307a1e",
"signature": "3d99bec66c031477ba6427f6191b482a220f058ec1cd3529ea7355f1c2929735a2061e437b6fc8de86442eb77729aaf16e15a2086e0167979a197d0b359aa70d"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 3,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "992a20a6788ae3dade8cdfa90e798fed53867f2d05189cde9cf2a9d4b14706fa",
"signature": "65d3cab9ccdbd288f3819c9c5b46bc9e3259148a349a8d0780622b161564f28fac036d94a63d68ebdd72ee6c3f0f151dfa91fbe94f20f644cd2cfd4d5d7ebb0d"
}
}
}

View file

@ -0,0 +1,99 @@
{
"status": "done",
"method": "statevector",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
"bytes": 57,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 400,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 9,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 32,
"shots_run": 0,
"seed": 9,
"counts": {},
"callouts": 1,
"fuel": {
"used": 400,
"instances": 0,
"budget": {
"per_call": 400,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 1,
"fuel": 400,
"max": 400
}
}
},
"modules": [
{
"name": "m",
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
}
],
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 0,
"phase": "call",
"module": "m",
"fuel": 400,
"callout": "f",
"budget": "call"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "9cab411ba32a647e5c4b0ce53609a4308c1a07bd26c817fca582e3e04258bff4",
"signature": "c939aab422b5bf97f2abb4264df90c7aa2c69287570ed177edaa1a2fad8c4ddc9ea3758ee11cea21341c84a9d4eb47da4549431f32c9d8adbfe2721ade007a07"
}
},
"id": "j-another"
}

View file

@ -0,0 +1,111 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"fault": null,
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "354d530ddc5ecbec7050d0d7c398342b5bf4ca203756a6110762059337d9236b",
"signature": "464dfe6c951e6260f6dca0c835a798e303b1f2b8d9bda4cf6ef40b59acfc532925f8cd55c22b246b652f2e98f2aaf2096bdbed8c4b14b6dd8638046afab46603"
}
}
}

View file

@ -0,0 +1,97 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
"bytes": 57,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 400,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 9,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 32,
"shots_run": 0,
"seed": 9,
"counts": {},
"callouts": 1,
"fuel": {
"used": 400,
"instances": 0,
"budget": {
"per_call": 400,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 1,
"fuel": 400,
"max": 400
}
}
},
"modules": [
{
"name": "m",
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
}
],
"transcript_blake3": "0101d6548d258cfee420ce019df99a45ba980ec6bb92fded0b69b8a1d514de7f",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "out_of_fuel",
"shot": 0,
"phase": "call",
"module": "m",
"fuel": 400,
"callout": "f"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "c38a68561b19ab771e54e6c34db5fbe78de3d4b4794cf7eb5a2affd74bd14d6b",
"signature": "3b4c8eacc2bd7df3a4d9ecf284d7f333013e0d296cdbc496d09501888c45e9706a77809426b6b88b712e48bbe9fd625ac91b547b800755f2449b1d7ee5b8f405"
}
}
}

View file

@ -0,0 +1,109 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "3b1d20813e1400bcb189647a563054d2b7af6c392b4dfc0a94e377d20600137d",
"signature": "327b8d73f295ed0a61f5c9352bc194c3a69746dd20f1af4d3aae650bac97076b8d188e9588f6a1dc844a26558e46c7ba18366e097b53ff9d985f2453f826610e"
}
}
}

View file

@ -0,0 +1,96 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
"bytes": 50,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "shot"
}
},
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 0,
"seed": 1,
"counts": {},
"callouts": 1,
"fuel": {
"used": 2,
"instances": 1,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 1,
"fuel": 1,
"max": 1
}
}
},
"modules": [
{
"name": "m",
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
}
],
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "unreachable",
"shot": 0,
"phase": "init",
"module": "m",
"fuel": 1
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "ae7a6dc8dcb90b1060a50adb3bcf335906d9984e08ca0cd36d69bbab150213bd",
"signature": "1ae288c8b53b9552f903443c9a2f650cba16dd2ab191b0c024e10276d6bd49e963a40d7b640179c2a0c3fc850df773fac2f52852d0174beca69f8d1d1b02bd0b"
}
}
}

View file

@ -0,0 +1,96 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0",
"bytes": 105,
"name": "m",
"priors": [
{
"blake3": "024f67c0425a3dc02fbaf58cb93de5132e3d75c519faa0bada21491d88c97057",
"bytes": 134217728,
"name": "weights"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "shot"
}
},
"envelope_blake3": "6da2c86da1b3d288df324fa7902e4cb10c9c5b21160921907299402466c5d50c"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 0,
"seed": 1,
"counts": {},
"callouts": 0,
"fuel": {
"used": 8,
"instances": 8,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {}
},
"modules": [
{
"name": "m",
"blake3": "2bd6df6f77cff04a53312cc69ee9024ae6e445af9dd3a7d410cc5c8a18c0c4d0"
}
],
"transcript_blake3": "3db8f511346d060c257940c086300666c8eb1b27c6083d36066b8d8f38e6408c",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "unreachable",
"shot": 0,
"phase": "prior",
"module": "m",
"fuel": 8
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "5dd5e46465d0286cb9acc026e233131fb1d04963f5d9e4169c31f2d8a1e41f44",
"signature": "00636291efa15d23752e5057f5bb8e083867cdc4ae1c229f092eb3ee5636ba9c71d12c582f195f7723dbf3d00f8e1993a8bedb5c4d3964c64c0b27a1c8c74907"
}
}
}

View file

@ -0,0 +1,98 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
"bytes": 57,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 400,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 9,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 32,
"shots_run": 0,
"seed": 9,
"counts": {},
"callouts": 1,
"fuel": {
"used": 10,
"instances": 0,
"budget": {
"per_call": 400,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 1,
"fuel": 10,
"max": 10
}
}
},
"modules": [
{
"name": "m",
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
}
],
"transcript_blake3": "f4cc7113b6c3237834200520bf45efee02d8308e3f23df558d51744f4c3cd176",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 0,
"phase": "call",
"module": "m",
"fuel": 10,
"callout": "f",
"budget": "call"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "73f5e4f2f5432960fd96597f4ebdaab949a42e000e928f46f212a72e1f228cd9",
"signature": "26b4495af949987c4e2d94a4dca1d38111414c7bbfe4f04c269abf3f7f71fe1a944aca17345c85fd46f6b05281cab2343df7e44aab53afa59d0ca77c7b6e6801"
}
}
}

View file

@ -0,0 +1,98 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1",
"bytes": 57,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 400,
"per_instance": 100000000,
"per_job": 100
},
"method": "stabilizer",
"seed": 9,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "22d84ca179e6f5c69a4a2eb93e9bdc545b021add204c96cb1466c306119b0b35"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 32,
"shots_run": 0,
"seed": 9,
"counts": {},
"callouts": 1,
"fuel": {
"used": 400,
"instances": 0,
"budget": {
"per_call": 400,
"per_job": 100,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 1,
"fuel": 400,
"max": 400
}
}
},
"modules": [
{
"name": "m",
"blake3": "a1341d4aec22430d9f26a6a9044e98a92a1e67d97743fa64eee9720c835eb9b1"
}
],
"transcript_blake3": "47e0790eb680fb9b05637b791d60d2614cf74adea1114bbceb36ee237f9839f7",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 0,
"phase": "call",
"module": "m",
"fuel": 400,
"callout": "f",
"budget": "call"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "a52c41a705873742fc38fcbbd2e9c63d7e8afd3afd4a693001dceac368dfc330",
"signature": "90784ba730c4a7bf618b2193ec8f215330f65c45b047e5d2da16337a0f5e5c4cb3d3ee82963c429e61bfefb5b218c7d3ba76f322a6b5f169be6226b12906930a"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248033,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "f3ca37425506d722cbad2ee337cdfc0e8c894bc4b75091e680130de1a94a2223",
"signature": "3454dfda2f0409e93d6f07404750f54e2809648cc065ce54d676dac5de6a9583099cff05f0c9780b0f83361b61213a1f5187eec93725b3088df35088dcfc8803"
}
}
}

View file

@ -0,0 +1,112 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "a0a28225df247910039d0693ff2dfb69d3b012487e81fc449486dd5b9afc3fd7",
"bytes": 231,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "1c79196a4e25b4f73f53a8327d9ab5d4d1644040f6b5036bb34aa1d456f2ee28",
"bytes": 3346,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 8000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 77,
"shots": 16,
"state": "job"
}
},
"envelope_blake3": "3691fd8cac6fffe58d46a496aeff248a40d654129fe8cd23bae3dd6d3cebf8f4"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 47,
"shots": 16,
"shots_run": 16,
"seed": 77,
"counts": {
"000000000000000000000000000000000000000000000000000000000000000000000000001001110011": 1,
"000000000000000000000000000000000000000000000000000000000000010000000000011110000000": 1,
"000000000000000000000000000000000000000000000000000001000000010000000010110100000000": 1,
"000000000000000000000000000000000000000000000000000010001000000101000010010010101001": 1,
"000000000000000000000000000000000000000000000000010000000100000100001001000110000100": 1,
"000000000000000000000000000000000000000000000000100000000100000100001010000110100100": 1,
"000000000000000000000000000000000000000000000001000000000000011000000010010000001110": 1,
"000000000000000000000000000000000000000000000010100000000000000010001110000110101111": 1,
"000000000000000000000000000000000000001000000000000000000000000000100000001111010111": 1,
"000000000000000000000001100000000000000000000010000000000000010010000100010111100001": 1,
"000000000000011000110000000000000000000000000000000000011000000001000001000101001011": 1,
"000000000000011000110000000000000000000000000000000100011000010000000101010101100000": 1,
"000000011000110000000000000000000000000000000100001000000000000000010001000110010001": 1,
"001010001100000000000000000000000000000001000010000000000000000000000100001000010110": 1,
"001100000000000000000000000000000000000010100000000000000000001000110000001001110110": 1,
"110000000000000000000000000000000000001000000000000001000000000000100010100100011000": 1
},
"callouts": 16,
"fuel": {
"used": 765610,
"instances": 24078,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 8000
},
"callouts": {
"decode64": {
"calls": 16,
"fuel": 741532,
"max": 57659
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "eb5252076ea8bb4c45ccec714a3cc64b89e833fe0a49c36a28881b63b1c3799e",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "1c206e03bf6f101beb5edb5980d56dc39ef1fccc6eceef5f7bcd13b75b497c3b",
"signature": "e75ea79d367fddcca67ab5453a84b17dad3806846f038c14c58345cee4dfe73a461302a3c5e89c3216495e9d0f3ca6087c32b20b833e9917249c94c3af77050d"
}
}
}

View file

@ -0,0 +1,98 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
"bytes": 50,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "job"
}
},
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 2,
"seed": 1,
"counts": {
"0": 2
},
"callouts": 2,
"fuel": {
"used": 4,
"instances": 2,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 2,
"fuel": 2,
"max": 1
}
}
},
"modules": [
{
"name": "m",
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
}
],
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "unreachable",
"shot": 2,
"phase": "init",
"module": "m",
"fuel": 1
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "cd3556fb381a67b108d6755354fe8d87ad1c42728a0068dd3a6a4bfed05ebf43",
"signature": "7e7bb2e459d68477764542d4955ddab660bbf64ea95d2a24bd4ab0bc9b4c64404adf7960192027380711559b42b0e38ac2de6974f02bd030eaa5c80e5d950a0f"
}
}
}

View file

@ -0,0 +1,98 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
"bytes": 50,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "shot"
}
},
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 1,
"seed": 1,
"counts": {
"0": 1
},
"callouts": 1,
"fuel": {
"used": 2,
"instances": 1,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 1,
"fuel": 1,
"max": 1
}
}
},
"modules": [
{
"name": "m",
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
}
],
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "unreachable",
"shot": 1,
"phase": "init",
"module": "m",
"fuel": 2
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "cfc4ab8a2ac1e68009697a596ef65943ab215d888a1ced72b16bce0770b4d88d",
"signature": "94de72874b843958e61c1f79d4274feca3536b6d8cb504be1c22993312d1df540e7bec8a0c919e3c67e34da03c51ffd5c858600a180e68f9d3f0cd6c96248b04"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 0,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "cd573b96d3b69c2044b06d60be8913abb651fdd09a6c71af5c364a0f511a17f7",
"signature": "3c91f0be4f76a74b87ae1e4140822462c263e63b9a9b84096731f3260057fe22c76afcba184c53420c3ba00ffa30370ff2b00fdf5949e378adb303110331060a"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "abababababababababababababababababababababababababababababababab"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "d7b11e29fe5bea4e68237efac286ff6c45b52f74118fb179895f91c0528e0f94",
"signature": "62cdcd744588c9a569420ad8d075cb579f89e50fd4ab41ea6889a90b4a5d01dec7205245684aafd409823ade469fede4f858436988c813526e80a56e8459d60d"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 0,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "44773b725087f65952c9e578798e1827a0fed4f5169e8e7e5508b6163771797b",
"signature": "a4fcebc636f016322d061a0908dfc7c0f79fdfd2aeda2a877a12929616298927c92bd7d0e5548e1b25c6769c40c70cc238d34ee4a2d5f337cad3711678d69602"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 31,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 3,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "9a071896c902c5b761037264068dd5091628d88f908a91009ced24bce3cc6902",
"signature": "2be8d8084fa580eae554d50066c7a342ca51685c8836b511140a347484b796742c9ee52fdec69a295f4d089ada18af2d5210f02fd40b7a4c766183d83312410c"
}
}
}

View file

@ -0,0 +1,90 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
"bytes": 50,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "shot"
}
},
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 0,
"seed": 1,
"counts": {},
"callouts": 0,
"fuel": {
"used": 1,
"instances": 1,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {}
},
"modules": [
{
"name": "m",
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
}
],
"transcript_blake3": "1f9cfb398c872903d55e1962f50421060c42968e524e914e04bb0b971e4d0881",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "unreachable",
"shot": 0,
"phase": "prior",
"module": "m",
"fuel": 1
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "f7ccd98fc1b31bc3ba2a488bb2b96a4ac8387ad99d9f51408d78c5dffe8754ed",
"signature": "ea2cddbe43f18b519487586c21bae5ff3ecd5449d2dd699946f95b0c0ee7845662b799cfc52c78be35e625d502afca357a904ae5b2ee1888af28e832764ae70b"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 89,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 591228,
"instances": 2880,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 89
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "8992cecec525170cd95d696169802c2c793f40ffe87a9a9cc9dd9e8945a6b36d",
"signature": "28d3e413d5b8c57c4ad1767c4eb577794c86441700e3cf1a38a61b03830dae036ec718a6dfbd88749e5b2ff535afa561fc288e473b67aa45b8009153f8f5ea0c"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 591227,
"instances": 2879,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "8e6877a12e97c1b014543253c8f4efda9575b8a83677e1ce0eb667aad7d8232e",
"signature": "c06e25a6bd6839ce02f19378097867e5c0e44d2cf9b20de2673e4e797d06cd979aed1b8c15c7d43ece78dde6ec55408fa7f95717033bef4f8171db88d853d100"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 0,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "1d897b197a92ccb06456d13ec048db95cb4ef3ff7baf7d8b6af3b9a081998673",
"signature": "5978b536b336e3537a11f17ef7e969a50be122e74d7e5d4478840fd4742f821bbc64b491cfb3acb67b262f92629b4d6d7668ed5edcfe9d4d3f982825455bd804"
}
}
}

View file

@ -0,0 +1,111 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236",
"x": 1
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "d70fdae9305fcc22843ecb996e95e0f2f55d2012575a5f3018885a5db1d0bdf0",
"signature": "ff922f40dc484319c3c7565f737bcd821486db77fcecceeb8a6062f18b0eeff76b5f935cc27b65c354c3a07e9ee63bb86d4e764c17de7447e5079bd5df882706"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32.0,
"\u0073tate": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 3.2e1,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "df6d2e83f44afa7db6d7c6a3d4791443525b1778b794023326296050cb47dcb1",
"signature": "1ea3250661d07afe9e5f0bac876186cb6fb93ff2c9595e1f4d41c1bb7f9b0674d0146f9329a24d3b22c74d666f3f63329b19970c9ee90eb199f448e7a0e13a01"
}
}
}

View file

@ -0,0 +1,111 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"note": "a member the profile does not write",
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "593a9e2ccb96f59a8b95be3f8193085275245e40c3625923047dcbde34334531",
"signature": "71a8617693a99ad90f38e61edcd1dc1f04bfe8090adc19e07f5aa0436f83c63597e7702c2b158140963183b0715b46b0843343825ed93952ac1830ea986dfd0a"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1235,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "f7d44a5e34e72ecfff5410ca0aadc927fbc4fca15eca88db2c4b4d8c845419b3",
"signature": "4309cc7a5ef605a8363d663e5bcf669ee7735f29f7f81f3affa6a19a99732cf85bdb9b0b43b1f07cac0110174b47598dd482c1e0048465dd3b16be57fd8dd906"
}
}
}

View file

@ -0,0 +1,100 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43",
"bytes": 68,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 50
},
"method": "stabilizer",
"seed": 1,
"shots": 1048576,
"state": "shot"
}
},
"envelope_blake3": "0a19542a6a9178984a93d9863a1d5e9371e00b86c6e9143e04b5f0fb5b0be177"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 1048576,
"shots_run": 2,
"seed": 1,
"counts": {
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000": 2
},
"callouts": 3,
"fuel": {
"used": 50,
"instances": 0,
"budget": {
"per_call": 10000000,
"per_job": 50,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 3,
"fuel": 50,
"max": 23
}
}
},
"modules": [
{
"name": "m",
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43"
}
],
"transcript_blake3": "3772395e9bb2f9fba3b1a7ef4f5def3e5f10f76a9ba517d16056e5fd7cb7d413",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 2,
"phase": "call",
"module": "m",
"fuel": 4,
"callout": "f",
"budget": "run"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "5c0940231cdea3e717c8f4a21dc9b8cb6c5e7a2a05a95daf14ead02e4dba8e21",
"signature": "1ecb47df023cab2f4085bb6c6d3a81b8c62f89a94e33496f82fca9065a3cf3e8fd43610750fd3a799c9492ffe30a8c5c72e63f6b7f18d82c064520a8b2ae7307"
}
}
}

View file

@ -0,0 +1,101 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43",
"bytes": 68,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 60
},
"method": "stabilizer",
"seed": 1,
"shots": 8,
"state": "shot"
}
},
"envelope_blake3": "0a19542a6a9178984a93d9863a1d5e9371e00b86c6e9143e04b5f0fb5b0be177"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 8,
"shots_run": 2,
"seed": 1,
"counts": {
"0101101101011011": 1,
"1011111010111110": 1
},
"callouts": 3,
"fuel": {
"used": 50,
"instances": 0,
"budget": {
"per_call": 10000000,
"per_job": 60,
"per_instance": 100000000
},
"callouts": {
"f": {
"calls": 3,
"fuel": 50,
"max": 23
}
}
},
"modules": [
{
"name": "m",
"blake3": "9de978f8d33833a7abb3ab51af439869309b3d7a6d11d0066650c22c26542d43"
}
],
"transcript_blake3": "3772395e9bb2f9fba3b1a7ef4f5def3e5f10f76a9ba517d16056e5fd7cb7d413",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "fuel_exhausted",
"shot": 2,
"phase": "call",
"module": "m",
"fuel": 4,
"callout": "f",
"budget": "run"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "39a21b49ebb0c7a9e22e2594c4b4afdb06edde9f68de01c275b65075984db36a",
"signature": "8b70291f63f1fcd478991416cf2707046db92bac88b3658c1fc240eef45a1001d9549f23bd58211017455e83eb6835605a3148c16bd29997a509637265453a01"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 9007199254740992,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 9007199254740992,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "4db53dce118ecb83ec243bbce84c1ad5fc878cfb0e9ccc751b7bf0a1bdc79bc1",
"signature": "d4fc00c7c1f5eaf7139f1e17f1d317406b56aabb3869716ab466078a7104463a68ba46b8f14c12498e57aebc2e9fff7b2e24e45450752ebce499e3ab1968920b"
}
}
}

View file

@ -0,0 +1,90 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
"bytes": 50,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "shot"
}
},
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 0,
"seed": 1,
"counts": {},
"callouts": 0,
"fuel": {
"used": 1,
"instances": 1,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {}
},
"modules": [
{
"name": "m",
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
}
],
"transcript_blake3": "abababababababababababababababababababababababababababababababab",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "unreachable",
"shot": 0,
"phase": "init",
"module": "m",
"fuel": 1
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "061b0aec47ca7e32a6d1c05b4e965e8ca686230ec5ccd4334b369b5a20391584",
"signature": "20846be21c6b161ebfda94b759e9cfaf45b2e2c5b80a55ec86a1e6d89815dd0139852aa20538d22e71322ec93453bbd51213cdc79ddd69d9ba514a3471b7ad0f"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069C26AC0BEBA900FEFB241E021DEC52C77356506CAD8FF39D3240C090D82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "630fd56edc1fbecb0936c3cfd47a2624b8fcc96a5dbae4c9226129f83a23e144",
"signature": "a2311d8ae5cc18d25a0012a737b783e0dabf1cd3a1c3bcd5552dfb28ea8450ee9d56fbdea688c274b186732457c521b1f103ecc9b80814803ccf301fbcfb1300"
}
}
}

View file

@ -0,0 +1,90 @@
{
"status": "fault",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "f",
"extern": "f",
"module": 0
}
],
"modules": [
{
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3",
"bytes": 50,
"name": "m",
"priors": []
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "3e7ed8c589abdebfae8431e20bb8b2f7f1392cfb3ad101fb50002b4a11a18319",
"bytes": 128,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 17179869184
},
"method": "stabilizer",
"seed": 1,
"shots": 4,
"state": "shot"
}
},
"envelope_blake3": "d3cc9387b18e2f2cd1e49379249884bf0cdc58399e3fe031933e4e17a7a538f9"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "fault",
"method": "stabilizer",
"qubits": 8,
"shots": 4,
"shots_run": 0,
"seed": 1,
"counts": {},
"callouts": 0,
"fuel": {
"used": 1,
"instances": 1,
"budget": {
"per_call": 10000000,
"per_job": 17179869184,
"per_instance": 100000000
},
"callouts": {}
},
"modules": [
{
"name": "m",
"blake3": "f3f2aabf3edb17dd4e18532dcf6291bb6b806371b85e6c1e27af3da77dab93b3"
}
],
"transcript_blake3": "f4af8469005fcf8eeefc686a9394562530230ccb29bbfaae324cb7cb9343a4e4",
"accuracy": {
"class": "exact"
},
"fault": {
"reason": "unreachable",
"shot": 0,
"phase": "init",
"module": "m",
"fuel": 0
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "56763e6f0af29fe7abaa4776dc1c76b0e6f33dbf911bbeefce8d7d92b888fd34",
"signature": "9a83c80f27c98966065f554c176977cc11b1372773bc6560ec4b8b0a7a9ef377e14b2828d7691fa0819f8c3f0307a3926fb989f4e325705c5bf5d7f6d04b020a"
}
}
}

View file

@ -0,0 +1,110 @@
{
"status": "done",
"method": "stabilizer",
"request": {
"wasmq": {
"callouts": [
{
"export": "decode64",
"extern": "decode64",
"module": 0
}
],
"modules": [
{
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962",
"bytes": 39442,
"name": "qldpc-decoder",
"priors": [
{
"blake3": "1f593bab90aa9ff3995361a32a9860760f020bec8759e6f94175c8b4b211f4db",
"bytes": 87,
"name": "checks"
}
]
}
],
"profile": "wai.quantum.wasmq/1",
"program": {
"blake3": "72471b167c0b1b590f0d817a75d484451408a0448b9d9a8924b670cdef131d85",
"bytes": 1104,
"inputs": {}
},
"run": {
"fuel": {
"per_call": 10000000,
"per_instance": 100000000,
"per_job": 549755813888
},
"method": "stabilizer",
"seed": 1234,
"shots": 32,
"state": "shot"
}
},
"envelope_blake3": "3a11569a35aa1baad3963b0090c56755638390a8f843bbdf5e34f1d212352236"
},
"result": {
"format": "wai.quantum.wasmq.result/1",
"profile": "wai.quantum.wasmq/1",
"status": "ok",
"method": "stabilizer",
"qubits": 17,
"shots": 32,
"shots_run": 32,
"seed": 1234,
"counts": {
"000000000000000000000000001001": 3,
"000000000000000000000000001010": 2,
"000000000000000000000000001011": 4,
"000000000000000000000000001101": 2,
"000000000000000000000000001110": 2,
"000000000000000000000000001111": 1,
"000000000000000000000100010000": 4,
"000000000000000000010010000010": 2,
"000000000000000000100001010011": 2,
"000000000000000001000000110100": 2,
"000000000000000010000010100101": 2,
"000000000000000100000001000110": 3,
"000000011000000000000100010001": 2,
"110000000000001000000000101000": 1
},
"callouts": 32,
"fuel": {
"used": 836380,
"instances": 248032,
"budget": {
"per_call": 10000000,
"per_job": 549755813888,
"per_instance": 100000000
},
"callouts": {
"decode64": {
"calls": 32,
"fuel": 588348,
"max": 21751
}
}
},
"modules": [
{
"name": "qldpc-decoder",
"blake3": "005631822744a3b2271dfc6c4a7dd9412bb4eca91740cc06f1cda2d5cec11962"
}
],
"transcript_blake3": "037069c26ac0beba900fefb241e021dec52c77356506cad8ff39d3240c090d82",
"accuracy": {
"class": "exact"
},
"energy": {
"unmetered": "the runner reads no energy meter; fuel is the profile's measure of work"
},
"receipt": {
"alg": "ed25519",
"canon": "rfc8785",
"key": "197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
"digest": "eed9dde93614e853b2944351ff11bb3f0e5707493f82fcc901f8db7ced11ae5f",
"signature": "25dbf3e5c4672c479054261b06bb76028fa023712eef2618e859e518e8026da763e9c349049a4b4945ffa92fcbc616dec0b97d2c8effd0f29c1553e6c7617105"
}
}
}

View file

@ -8,6 +8,12 @@
"cli-run-trajectories.json": "c41c35bb5384d3582d83450f7b3d38225be2d353e4e3ad71e49a82c306656ede",
"cli-set-programs.json": "81059f216b449468ac4ab6803de72a0a5f894458cb178eae15f2abf42bfd2437",
"cli-set-sweep.json": "2b9af76474074a522ac5404c2de07a2b307620ce56e413b2319523b26fd168e1",
"cli-wasmq-fault-init.json": "be0c62291b21d35cdf10955dc3611913b6fdc824561d14ce509fecceeee98465",
"cli-wasmq-fault-prior.json": "47e497cf002051e090161a4eaa70933d46f2ecb56dbacdf05f83ecf74f67a065",
"cli-wasmq-fault-run.json": "00367bd6ff66f4d8f354dbb1f5c8e3519687924ab0e871800815a9d7e4943b8d",
"cli-wasmq-fault.json": "f86dc76d54591e765f4609adfe2e817e775421094c0b4d23284c54d9fc9a0122",
"cli-wasmq-run.json": "09c757a4739e448945cad383391d4c8cae140c678293a95af72d1d334cef214f",
"cli-wasmq-state-job.json": "cc2820d766d8b90f4e7fa3dc7b5d8528e500fc58555834ac870f83844f06b280",
"first-form-service-observables.json": "098a720239f1757bb7ae7ceb8e35f7e0c30c91bb5fa7c977aef9aec02b855fa9",
"first-form-service-run.json": "f21a23fd33df0ec4c540bbc341c4296aeb4612bc4b9e58044604cbd19521a535",
"fixture-compile-legacy.json": "04c53ef2b350a4cdbd5f42deb8c44a91a1616a05c498a30f2f9cecd9c7402bca",

View file

@ -11,6 +11,7 @@
# the ones it was given, and never makes them again to pass a test.
set -euo pipefail
B=$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")
ENVELOPES=$(cd "$(dirname "$0")/../wasmq/envelopes" && pwd -P)
OUT=$(mkdir -p "$2" && cd "$2" && pwd -P)
W=$(mktemp -d)
trap 'rm -rf "$W"' EXIT
@ -33,6 +34,9 @@ printf 'OPENQASM 3.0;\ninclude "stdgates.inc";\nqubit[1] q;\nrx(0.4) q[0];\n' >
printf 'OPENQASM 3.0;\ninclude "stdgates.inc";\ninput float theta;\nqubit[1] q;\nbit[1] c;\nrx(theta) q[0];\nc = measure q;\n' > theta.qasm
"$B" run bell.qasm --program three.qasm --shots 64 --seed 3 --demo-key --json > "$OUT/cli-set-programs.json"
"$B" run theta.qasm --sweep theta=0.25,0.5,1.5 --shots 64 --seed 9 --demo-key --json > "$OUT/cli-set-sweep.json"
for pair in run:surface3-decode64 state-job:surface5-decode64-job fault:fault-fuel fault-run:fault-fuel-run fault-init:fault-in-init fault-prior:fault-in-prior; do
"$B" run "$ENVELOPES/${pair#*:}.wai" --demo-key --json > "$OUT/cli-wasmq-${pair%%:*}.json"
done
"$B" submit bell.qasm --shots 200 --seed 11 --json > "$OUT/service-run.json"
"$B" submit bell.qasm --shots 200 -o "Z0 Z1" --json > "$OUT/service-run-stabilizer.json"
for f in "$OUT"/cli-*.json "$OUT"/service-*.json; do "$B" verify "$f" > /dev/null || { echo "make.sh: $f does not verify" >&2; exit 1; }; done

View file

@ -55,6 +55,42 @@
"made_by": "made",
"what": "the command line: a sweep of an input at three points, sealed as a set"
},
{
"file": "jobs/cli-wasmq-fault-init.json",
"reasons": [],
"made_by": "made",
"what": "the command line: a wasmQ run that stopped in an instance's init"
},
{
"file": "jobs/cli-wasmq-fault-prior.json",
"reasons": [],
"made_by": "made",
"what": "the command line: a wasmQ run that stopped while a module read its prior"
},
{
"file": "jobs/cli-wasmq-fault-run.json",
"reasons": [],
"made_by": "made",
"what": "the command line: a wasmQ run that stopped in its third shot when the run's fuel ran out"
},
{
"file": "jobs/cli-wasmq-fault.json",
"reasons": [],
"made_by": "made",
"what": "the command line: a wasmQ run that stopped in a call past the call's fuel budget"
},
{
"file": "jobs/cli-wasmq-run.json",
"reasons": [],
"made_by": "made",
"what": "the command line: a wasmQ run, a surface-code round decoded by WebAssembly between its gates, 32 shots"
},
{
"file": "jobs/cli-wasmq-state-job.json",
"reasons": [],
"made_by": "made",
"what": "the command line: a wasmQ run of one instance for the whole run, its decoder reading a prior"
},
{
"file": "jobs/first-form-service-observables.json",
"reasons": [],
@ -1162,6 +1198,354 @@
"reasons": [],
"made_by": "crafted",
"what": "a class a verifier does not know: not a reason, since a later version may add one"
},
{
"file": "jobs/crafted-wasmq-counts-short.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ run whose counts add up to one shot fewer than it ran (rule 19)"
},
{
"file": "jobs/crafted-wasmq-ok-before-all-shots.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ run that is ok after 31 of its 32 shots (rule 18)"
},
{
"file": "jobs/crafted-wasmq-fuel-unaccounted.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ run whose instances and calls do not add up to the fuel it used (rule 15)"
},
{
"file": "jobs/crafted-wasmq-fuel-past-job-budget.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ fault that used 400 fuel under a run's budget of 100 (rule 13)"
},
{
"file": "jobs/crafted-wasmq-instances-past-budget.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "one instance for the whole run, given more fuel for its seed, init and prior than three stretches of 8000 (rule 17)"
},
{
"file": "jobs/crafted-wasmq-fault-unnamed.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ fault of a reason the profile does not name (rule 18)"
},
{
"file": "jobs/crafted-wasmq-result-member-added.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ result with a member the profile does not write (rule 9)"
},
{
"file": "jobs/crafted-wasmq-contract-method.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ contract and result of a method the profile does not have (rule 8)"
},
{
"file": "jobs/crafted-wasmq-seed-past-exact.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ seed of 2^53: a double holds it, so it is no inexact number, and the profile allows at most 2^53 - 1 (rules 1, 8)"
},
{
"file": "jobs/crafted-wasmq-modules-other.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ result naming a module the contract does not pin (rule 16)"
},
{
"file": "jobs/crafted-wasmq-transcript-upper.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ transcript digest in upper case (rule 12)"
},
{
"file": "jobs/crafted-wasmq-first-form.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ job sealed in the first form, older than the profile: the seal holds, and no host wrote it (rule 10)"
},
{
"file": "jobs/crafted-wasmq-call-fault-uncounted.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a call that stopped the run, which the fuel counts no call of: the stopped call is one of the calls made (rule 18)"
},
{
"file": "jobs/crafted-wasmq-call-fault-past-largest.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a call that stopped after 400 fuel, where the most one call of it used is 399 (rule 18)"
},
{
"file": "jobs/crafted-wasmq-request-member-added.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ request with a member the profile does not write (rule 2)"
},
{
"file": "jobs/crafted-wasmq-contract-member-added.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ contract with a member section 2.2 does not list (rule 3)"
},
{
"file": "jobs/crafted-wasmq-contract-profile.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ contract of another profile (rule 4)"
},
{
"file": "jobs/crafted-wasmq-program-empty.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ contract whose program is 0 bytes long (rule 5)"
},
{
"file": "jobs/crafted-wasmq-module-empty.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ contract whose module is 0 bytes long (rule 6)"
},
{
"file": "jobs/crafted-wasmq-callouts-twice.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ contract with two callouts of one extern (rule 7)"
},
{
"file": "jobs/crafted-wasmq-result-seed.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ result whose seed is not its contract's (rule 11)"
},
{
"file": "jobs/crafted-wasmq-call-past-per-call.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ run whose largest call used 21751 fuel under a budget of 21750 a call (rule 14)"
},
{
"file": "jobs/crafted-wasmq-calls-of-no-fuel.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "32 calls that returned having used no fuel, where entering a function weighs 1 (rule 20)"
},
{
"file": "jobs/crafted-wasmq-priors-unpassed.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "32 shots of instances passed a prior of 87 bytes in less fuel than its bytes and its two calls take, cabi_realloc 2 at least and wasmq-prior 1 (rule 21)"
},
{
"file": "jobs/crafted-wasmq-call-fault-other-module.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a call of a callout in the first module, whose fault names the second (rule 22)"
},
{
"file": "jobs/crafted-wasmq-prior-fault-no-prior.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a fault while a prior is passed, in a module with no prior (rule 23)"
},
{
"file": "jobs/crafted-wasmq-bad-result-in-init.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a bad_result from an init, which takes no result (rule 24)"
},
{
"file": "jobs/crafted-wasmq-lifecycle-fuel-past-instances.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "an init fault in shot 1 that used 2 fuel, where the instances used 1, shot 0's init 1 of it at least (rule 25)"
},
{
"file": "jobs/crafted-wasmq-job-state-later-instance.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a run of one instance for the run whose instance fails in shot 2 (rule 26)"
},
{
"file": "jobs/crafted-wasmq-first-instance-after-call.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "the first shot's instance failing after a call was made, where no shot ran its steps (rules 27 and 32)"
},
{
"file": "jobs/crafted-wasmq-fuel-fault-under-limit.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a call's fuel fault after 10 fuel, under its limit of 400 (rule 28)"
},
{
"file": "jobs/crafted-wasmq-run-budget-not-spent.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a fault of the run's budget with 50 of its 60 used (rule 28)"
},
{
"file": "jobs/crafted-wasmq-results-past-bits.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "2^20 shots of 257 bits, past the 2^28 bits a run's results hold (rule 29)"
},
{
"file": "jobs/crafted-wasmq-work-past-bound.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a run given 2^39 fuel beside a module's code, past the 2^42 operations a run asks (rule 30)"
},
{
"file": "jobs/crafted-wasmq-frames-past-envelope.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a prior of 2^27 bytes beside a program and a module, more than an envelope holds (rule 31)"
},
{
"file": "jobs/crafted-wasmq-fault-null.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "an ok result with a fault member whose value is null: a member is present whatever its value (rule 18)"
},
{
"file": "jobs/crafted-wasmq-no-qubit.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a wasmQ result of a program of no qubit, which no program a reader reads is (rule 12)"
},
{
"file": "jobs/crafted-wasmq-calls-under-largest.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "32 calls in 21751 fuel, where the most one of them used is 21751 and each other used 1 at least (rule 20)"
},
{
"file": "jobs/crafted-wasmq-calls-past-steps.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "32 shots that made 2^21 calls each and one more, where a shot runs at most 2^21 steps (rule 32)"
},
{
"file": "jobs/crafted-wasmq-prior-past-instance-budget.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a prior of 87 bytes passed whole in one stretch, which takes 90 at least, under a lifecycle call's budget of 89 (rule 33)"
},
{
"file": "jobs/crafted-wasmq-trap-of-no-fuel.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "an init that trapped after no fuel, where its entry is charged before it runs (rule 34)"
},
{
"file": "jobs/crafted-wasmq-transcript-of-no-call.json",
"reasons": [
"wasmq_form"
],
"made_by": "crafted",
"what": "a fault before any call whose transcript is not the run's end alone (rule 35)"
},
{
"file": "jobs/crafted-wasmq-respelt.json",
"reasons": [],
"made_by": "crafted",
"what": "a wasmQ job with its shots written 32.0 and 3.2e1 and a member of its contract named with an escape: the same sealed content"
},
{
"file": "jobs/crafted-wasmq-envelope-changed.json",
"reasons": [],
"made_by": "crafted",
"what": "a wasmQ fault whose unsealed body says done, another method and an id: a note beside the verdict, not a reason"
}
]
}

View file

@ -27,14 +27,23 @@ of the reference, and changes nothing.
(`receipt_verify.py --plant`), and succeeds only when the differential catches
it: the proof that the check can fail.
`--second FILE` holds another second verifier (a mutant of receipt_verify.py) to the
same stages; `--wasmq-only` keeps to what holds a wasmQ job (its receipts, their
one-member changes, the rules stage and the labelled cases); `--first` stops at the
first stage that disagrees; and `RD_CACHE=DIR` keeps each verifier's answers, so that a
run over many mutants of one verifier asks the other once (`wasmq_mutants.py`).
Exit status 0 only when everything agrees (or, with --plant, when the plant is
caught). Standard library only, Python 3.9+.
"""
import argparse
import base64
import copy
import hashlib
import importlib.util
import json
import os
import re
import subprocess
import sys
import tempfile
@ -43,12 +52,24 @@ from collections import Counter
HERE = os.path.dirname(os.path.abspath(__file__))
CORPUS = os.path.join(HERE, "..", "receipts")
SECOND = os.path.join(HERE, "receipt_verify.py")
ORIGINAL_SECOND = SECOND
def compact(v):
return json.dumps(v, ensure_ascii=False, separators=(",", ":"))
def spelt(v, raw):
"""A line of v's text, each `raw` literal as it is written."""
if isinstance(v, raw):
return v.literal
if isinstance(v, dict):
return "{" + ",".join(json.dumps(k, ensure_ascii=False) + ":" + spelt(x, raw) for k, x in v.items()) + "}"
if isinstance(v, list):
return "[" + ",".join(spelt(x, raw) for x in v) + "]"
return compact(v)
def verdicts(lines_text, json_lines):
out = []
for line in lines_text.splitlines():
@ -60,29 +81,110 @@ def verdicts(lines_text, json_lines):
return out
def run_reference_files(ref, files):
out = []
for f in files:
p = subprocess.run([ref, "verify", "--json", f], capture_output=True, text=True)
if p.returncode not in (0, 1) or not p.stdout.strip():
raise SystemExit("the reference failed on %s (status %d): %s" % (f, p.returncode, p.stderr.strip()[:400]))
out.append(json.loads(p.stdout.strip().splitlines()[-1]))
def _who(cmd):
"""What decides a verifier's answers, for the cache: the reference binary (its path, size
and time) and the mutant it is asked to be, or the second verifier's text and its plant."""
h = hashlib.sha256()
script = any(part.endswith(".py") for part in cmd)
for part in cmd:
h.update(part.encode() + b"\0")
if part.endswith(".py") and os.path.isfile(part):
with open(part, "rb") as f:
h.update(f.read())
elif os.path.isfile(part) and os.access(part, os.X_OK):
st = os.stat(part)
h.update(("%d %d" % (st.st_size, st.st_mtime_ns)).encode())
if not script:
h.update(os.environ.get("WQ_MUTANT", "").encode())
return h.hexdigest()
def cached(cmd, inputs, compute):
"""compute(), or what it gave before for the same verifier and the same inputs when
RD_CACHE names a directory: a run of many mutants of one verifier asks the other the
same questions each time."""
d = os.environ.get("RD_CACHE")
if not d:
return compute()
h = hashlib.sha256(_who(cmd).encode())
for b in inputs:
h.update(hashlib.sha256(b).digest())
path = os.path.join(d, h.hexdigest() + ".json")
try:
with open(path, encoding="utf-8") as f:
return json.load(f)
except (OSError, ValueError):
pass
out = compute()
os.makedirs(d, exist_ok=True)
with open(path + ".tmp%d" % os.getpid(), "w", encoding="utf-8") as f:
json.dump(out, f)
os.replace(path + ".tmp%d" % os.getpid(), path)
return out
def _contents(files):
out = []
for f in files:
with open(f, "rb") as h:
out.append(h.read())
return out
def run_reference_files(ref, files):
def compute():
out = []
for f in files:
p = subprocess.run([ref, "verify", "--json", f], capture_output=True, text=True)
if p.returncode not in (0, 1) or not p.stdout.strip():
raise SystemExit("the reference failed on %s (status %d): %s" % (f, p.returncode, p.stderr.strip()[:400]))
out.append(json.loads(p.stdout.strip().splitlines()[-1]))
return out
return cached([ref, "verify", "--json"], _contents(files), compute)
def run_second_files(files, plant):
cmd = [sys.executable, "-I", SECOND] + (["--plant", plant] if plant else []) + files
p = subprocess.run(cmd, capture_output=True, text=True)
if p.returncode not in (0, 1):
raise SystemExit("the second verifier failed (status %d): %s" % (p.returncode, p.stderr.strip()[:400]))
return verdicts(p.stdout, len(files))
cmd = [sys.executable, "-I", SECOND] + (["--plant", plant] if plant else [])
def compute():
p = subprocess.run(cmd + files, capture_output=True, text=True)
if p.returncode not in (0, 1):
raise SystemExit("the second verifier failed (status %d): %s" % (p.returncode, p.stderr.strip()[:400]))
return verdicts(p.stdout, len(files))
return cached(cmd, _contents(files), compute)
def run_lines(cmd, path, n):
p = subprocess.run(cmd + [path], capture_output=True, text=True)
if p.returncode not in (0, 1):
raise SystemExit("%s failed (status %d): %s" % (cmd[0], p.returncode, p.stderr.strip()[:400]))
return verdicts(p.stdout, n)
def compute():
p = subprocess.run(cmd + [path], capture_output=True, text=True)
if p.returncode not in (0, 1):
raise SystemExit("%s failed (status %d): %s" % (cmd[0], p.returncode, p.stderr.strip()[:400]))
return verdicts(p.stdout, n)
return cached(cmd, _contents([path]), compute)
def rules_of(v):
"""The numbers of the rules of a wasmQ job's form a verdict states as broken (each
problem names its rule first), or None when it states none or only the first of many."""
w = v.get("wasmq")
if not isinstance(w, dict) or not isinstance(w.get("problems"), list):
return None
out = set()
for p in w["problems"]:
if not isinstance(p, str) or p.startswith("and "):
return None
m = re.match(r"rule (\d+): ", p)
if not m:
return None
out.add(int(m.group(1)))
return out
def same_rules(what, x, y, problems):
"""Both verifiers state the same rules broken, where both state them in full."""
rx, ry = rules_of(x), rules_of(y)
if rx is not None and ry is not None and rx != ry:
problems.append("%s: the reference states rules %s broken; the second verifier %s" % (what, sorted(rx), sorted(ry)))
def said(v):
@ -217,6 +319,461 @@ def edges(body, seal):
return out
# ------------------------------------------------- the rules of a wasmQ job's form
def rule_cases(corpus, seal):
"""(what, body, expected reasons): for each rule of quantum-wasmq section 6.5, the
genuine wasmQ jobs of the corpus changed at the rule's bound, on both sides of it where
it has two, and sealed again with the demo key, so that the rule alone decides. Each
expected verdict is written here by hand from the text, as the manifest's are: none is
copied from a verifier. A verifier with a rule dropped, or a bound moved, gives some
case here another verdict."""
def load(name):
with open(os.path.join(corpus, "jobs", name), encoding="utf-8") as f:
return json.load(f)
run, fault, init, job, frun, prior = (load("cli-wasmq-%s.json" % n) for n in ("run", "fault", "fault-init", "state-job", "fault-run", "fault-prior"))
out = []
g = generator()
def case(rule, what, base, edit, valid, respell=None):
b = copy.deepcopy(base)
edit(b)
# With no call returned, the transcript the writer gives the result as changed
# (rule 35), unless the change was to the transcript.
sealed = seal(g.retranscribed(base, b))
if respell:
# After the seal: another spelling of a number, not another value, so it holds.
respell(sealed)
sealed = spelt(sealed, g.Raw)
out.append(("rule %s, %s" % (rule, what), sealed, [] if valid else ["wasmq_form"]))
def contract(b):
return b["request"]["wasmq"]
def budget(name, value):
def f(b):
contract(b)["run"]["fuel"][name] = value
b["result"]["fuel"]["budget"][name] = value
return f
def stretches(b):
return sum(2 + len(m["priors"]) for m in contract(b)["modules"])
def second_module(bytes0, bytes1, named=True):
def f(b):
c = contract(b)
c["modules"][0]["bytes"] = bytes0
c["modules"].append({"name": "second", "blake3": "cd" * 32, "bytes": bytes1, "priors": []})
b["result"]["modules"].append({"name": "second", "blake3": "cd" * 32})
if named:
c["callouts"].append({"extern": "g", "module": 1, "export": "g"})
return f
def each(*edits):
def f(b):
for e in edits:
e(b)
return f
def at(path, value):
def f(b):
o = b
for k in path[:-1]:
o = o[k]
o[path[-1]] = value
return f
def calls(b):
(name, e), = b["result"]["fuel"]["callouts"].items()
return e
def passed(b):
# What passing every prior to one shot's instances takes at the least (rule 21):
# cabi_realloc, 2 at least, its bytes, and wasmq-prior, 1 at least.
return sum(p["bytes"] + 3 for m in contract(b)["modules"] for p in m["priors"])
def shots(n):
def f(b):
width = len(next(iter(b["result"]["counts"])))
contract(b)["run"]["shots"] = b["result"]["shots"] = b["result"]["shots_run"] = n
b["result"]["counts"] = {"1" * width: n}
fuel = b["result"]["fuel"]
more = max(0, n * passed(b) - fuel["instances"])
fuel.update(instances=fuel["instances"] + more, used=fuel["used"] + more)
return f
def later_shot(shot, state=None, instances=1, fuel=1, calls=None):
# The init fault moved to `shot`, after that many shots of one call each.
def f(b):
n = shot if calls is None else calls
if state:
contract(b)["run"]["state"] = state
b["result"].update(shots_run=shot, counts={"0": shot} if shot else {}, callouts=n)
b["result"]["fuel"].update(instances=instances, callouts={"f": {"calls": n, "fuel": n, "max": 1}} if n else {}, used=instances + n)
b["result"]["fault"].update(shot=shot, fuel=fuel)
return f
def fault_module(name):
def f(b):
second_module(57, 57)(b)
b["result"]["fault"]["module"] = name
return f
def counts(width, n):
return lambda b: b["result"].update(counts={"0" * width: n})
def work_left(b):
# The most per_job the rest of rule 30's work leaves room for.
c, r = contract(b), b["result"]
n, s = r["qubits"], c["run"]["shots"]
inst = 1 if c["run"]["state"] == "job" else s
rest = s * 2 * n * max(1, -(-n // 32)) + inst * sum(4096 * (1 + 2 * len(m["priors"])) + m["bytes"] for m in c["modules"]) + 131072 * sum(m["bytes"] for m in c["modules"]) + 4097 * r["callouts"]
return (2 ** 42 - rest) // 8
def frames(b):
c = contract(b)
return c["program"]["bytes"] + sum(m["bytes"] + sum(p["bytes"] for p in m["priors"]) for m in c["modules"])
def most_prior(b):
# The most bytes the first prior may have: 2^27 less the envelope's other bytes, its
# magic and lengths, its manifest, its contract and its other frames (rule 31).
c, r = contract(b), b["result"]
c["modules"][0]["priors"][0]["bytes"] = 10 ** 8
manifest = 192 + sum(len(str(x)) for x in (r["qubits"], c["run"]["shots"], c["run"]["seed"]))
rest = 20 + manifest + len(g.text(c).encode("utf-8")) + frames(b) - 10 ** 8
return 2 ** 27 - rest
def calls_of(n, max_fuel=1):
# n calls of the run's one callout, each of 1 but the most.
def f(b):
b["result"]["callouts"] = n
calls(b).update(calls=n, fuel=n - 1 + max_fuel, max=max_fuel)
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + calls(b)["fuel"]
return f
def own_prior(nbytes):
# The first module given a prior of nbytes.
return lambda b: contract(b)["modules"][0].update(priors=[{"name": "p", "blake3": "ef" * 32, "bytes": nbytes}])
def fault_of(reason, fuel):
# The call's fault of `fault`, stopped for reason after fuel.
def f(b):
b["result"]["fault"].update(reason=reason, fuel=fuel)
b["result"]["fault"].pop("budget", None)
calls(b).update(calls=1, fuel=fuel, max=fuel)
b["result"]["fuel"]["used"] = fuel
return f
def own_fuel(delta):
def f(b):
e = calls(b)
e["fuel"] = e["max"] + delta
b["result"]["fuel"]["used"] = b["result"]["fuel"]["instances"] + e["fuel"]
return f
R, F = ("result",), ("result", "fuel")
# 1: no number past 2^53 - 1 (it breaks another rule too: each place a number may be holds it)
case(1, "an input of 2^53", run, lambda b: contract(b)["program"].update(inputs={"n": 2 ** 53}), False)
# 2: the request
case(2, "a member the request does not define", run, at(("request", "x"), 1), False)
case(2, "envelope_blake3 not a digest", run, lambda b: b["request"].update(envelope_blake3=b["request"]["envelope_blake3"].upper()), False)
# 3, 4: the contract's members and profile
case(3, "a member the contract does not define", run, lambda b: contract(b).update(x=1), False)
case(3, "a member the run does not define", run, lambda b: contract(b)["run"].update(x=1), False)
case(4, "another profile", run, lambda b: contract(b).update(profile="wai.quantum.wasmq/2"), False)
# 5: the program
case(5, "a program of 2^20 bytes", run, lambda b: contract(b)["program"].update(bytes=2 ** 20), True)
case(5, "a program of 2^20 + 1 bytes", run, lambda b: contract(b)["program"].update(bytes=2 ** 20 + 1), False)
case(5, "a program of 0 bytes", run, lambda b: contract(b)["program"].update(bytes=0), False)
case(5, "a program of 1 byte", run, lambda b: contract(b)["program"].update(bytes=1), True)
case(5, "an input of 2^53 - 1", run, lambda b: contract(b)["program"].update(inputs={"n": 2 ** 53 - 1}), True)
case(5, "an input of -(2^53 - 1)", run, lambda b: contract(b)["program"].update(inputs={"n": -(2 ** 53 - 1)}), True)
case(5, "an input of 0.5", run, lambda b: contract(b)["program"].update(inputs={"n": 0.5}), False)
# 6: the modules and their priors
case(6, "a module of 1 byte", run, lambda b: contract(b)["modules"][0].update(bytes=1), True)
case(6, "a module of 0 bytes", run, lambda b: contract(b)["modules"][0].update(bytes=0), False)
case(6, "a prior of 0 bytes", run, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=0), True)
case(6, "a prior of 0.5 bytes", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=0.5), False)
case(6, "a module of 2^19 bytes", run, lambda b: contract(b)["modules"][0].update(bytes=2 ** 19), True)
case(6, "a module of 2^19 + 1 bytes", run, lambda b: contract(b)["modules"][0].update(bytes=2 ** 19 + 1), False)
case(6, "a module's priors null", run, lambda b: contract(b)["modules"][0].update(priors=None), False)
case(6, "a prior's name null", run, lambda b: contract(b)["modules"][0]["priors"][0].update(name=None), False)
case(6, "a module's name null, alike in the result", run, lambda b: (contract(b)["modules"][0].update(name=None), b["result"]["modules"][0].update(name=None)), False)
case(6, "modules of 2^19 bytes together", run, second_module(2 ** 18, 2 ** 18), True)
case(6, "modules of 2^19 + 1 bytes together", run, second_module(2 ** 18, 2 ** 18 + 1), False)
# 7: the callouts
case(7, "a module no callout names", run, second_module(39442, 1, named=False), False)
case(7, "two callouts of one extern", run, lambda b: contract(b)["callouts"].append({"extern": "decode64", "module": 0, "export": "x"}), False)
case(7, "a callout of a module the contract does not hold", run, lambda b: contract(b)["callouts"][0].update(module=1), False)
case(7, "a callout of the module past the last, beside one of each module", run, lambda b: contract(b)["callouts"].append({"extern": "g", "module": 1, "export": "g"}), False)
case(7, "a callout of the last module, beside one of each module", run, second_module(39442, 57), True)
# No module and no callout: rule 7's first clause alone holds it, its others vacuous.
def nothing(b):
contract(b).update(modules=[], callouts=[])
b["result"].update(modules=[], callouts=0)
b["result"]["fuel"].update(callouts={}, instances=0, used=0)
case(7, "no module and no callout", run, nothing, False)
case(7, "no module, null for the modules, and no callout", run, each(nothing, lambda b: contract(b).update(modules=None)), False)
# 8: the run
case(8, "2^20 shots", run, shots(2 ** 20), True)
case(8, "2^20 + 1 shots", run, shots(2 ** 20 + 1), False)
for name in ("per_call", "per_instance", "per_job"):
# per_job at 2^39 is past rule 30's work beside any module: it is held there.
case(30 if name == "per_job" else 8, "the budget %s at 2^39" % name, run, budget(name, 2 ** 39), name != "per_job")
case(30 if name == "per_job" else 8, "the budget %s at 2^39 + 1" % name, run, budget(name, 2 ** 39 + 1), False)
case(8, "a seed of 0, alike in the result", run, lambda b: (contract(b)["run"].update(seed=0), b["result"].update(seed=0)), True)
case(8, "a seed below 0, alike in the result", run, lambda b: (contract(b)["run"].update(seed=-1), b["result"].update(seed=-1)), False)
case(8, "a seed of 2^53 - 1, alike in the result", run, lambda b: (contract(b)["run"].update(seed=2 ** 53 - 1), b["result"].update(seed=2 ** 53 - 1)), True)
case(8, "1 shot", run, shots(1), True)
case(8, "0 shots", job, lambda b: (contract(b)["run"].update(shots=0), b["result"].update(shots=0, shots_run=0, counts={}, callouts=0), b["result"]["fuel"].update(callouts={}, used=b["result"]["fuel"]["instances"])), False)
case(8, "a budget of 0", fault, budget("per_instance", 0), True)
case(8, "a call's budget of 0, its one call stopped at once", fault, each(budget("per_call", 0), lambda b: (calls(b).update(fuel=0, max=0), b["result"]["fuel"].update(used=0), b["result"]["fault"].update(fuel=0))), True)
case(8, "another state", run, at(("request", "wasmq", "run", "state"), "call"), False)
# 9, 10: the result's members, and the form of its seal
case(9, "a member the result does not define", run, at(R + ("x",), 1), False)
first = copy.deepcopy(run)
out.append(("rule 10, sealed in the first form", seal(first, form="first"), ["wasmq_form"]))
# 11: what the result repeats
case(11, "another seed in the result", run, lambda b: b["result"].update(seed=b["result"]["seed"] + 1), False)
case(11, "another shots in the result", run, lambda b: b["result"].update(shots=b["result"]["shots"] + 1), False)
case(11, "another accuracy", run, at(R + ("accuracy",), {"class": "exact", "x": 1}), False)
case(11, "another energy", run, at(R + ("energy",), {"unmetered": "a meter"}), False)
# 12: qubits
case(12, "2^15 qubits", run, at(R + ("qubits",), 2 ** 15), True)
case(12, "1 qubit", run, at(R + ("qubits",), 1), True)
case(12, "0 qubits", run, at(R + ("qubits",), 0), False)
case(12, "qubits null", run, at(R + ("qubits",), None), False)
case(12, "2^15 + 1 qubits", run, at(R + ("qubits",), 2 ** 15 + 1), False)
# 13: the fuel's budget and what it used
case(13, "used equal to per_job", run, lambda b: budget("per_job", b["result"]["fuel"]["used"])(b), True)
case(13, "used past per_job", run, lambda b: budget("per_job", b["result"]["fuel"]["used"] - 1)(b), False)
case(13, "a budget the contract does not give", run, lambda b: b["result"]["fuel"]["budget"].update(per_call=b["result"]["fuel"]["budget"]["per_call"] + 1), False)
# 14: each callout's fuel
case(14, "a call's largest equal to per_call", run, lambda b: budget("per_call", calls(b)["max"])(b), True)
case(14, "a call's largest past per_call", run, lambda b: budget("per_call", calls(b)["max"] - 1)(b), False)
case(14, "a call's largest equal to its fuel", fault, own_fuel(0), True)
case(14, "a call's largest past its fuel", run, own_fuel(-1), False)
case(14, "a callout with no call", run, lambda b: (calls(b).update(calls=0, fuel=0, max=0), b["result"].update(callouts=0), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"])), False)
case(20, "fuel past its calls of their largest", run, lambda b: (calls(b).update(fuel=calls(b)["calls"] * calls(b)["max"] + 1), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"] + calls(b)["fuel"])), False)
# 15: what adds up
case(15, "a call more than the fuel counts", run, lambda b: b["result"].update(callouts=b["result"]["callouts"] + 1), False)
# 16: the result's modules
case(16, "a module of the result named otherwise", run, lambda b: b["result"]["modules"][0].update(name="other"), False)
# 17: what the instances could be given
case(17, "a fault's instance counted: one, given 1 each stretch", init, budget("per_instance", 1), True)
case(17, "one instance for the run, at its bound", job, lambda b: budget("per_instance", -(-b["result"]["fuel"]["instances"] // stretches(b)))(b), True)
case(17, "one instance for the run, past its bound", job, lambda b: budget("per_instance", (b["result"]["fuel"]["instances"] - 1) // stretches(b))(b), False)
# 18: how it ended
case(18, "a fault in init within its phase's budget", init, each(budget("per_instance", 2), at(F + ("instances",), 2), at(F + ("used",), 2), at(R + ("fault", "fuel"), 2)), True)
case(18, "a fault in init past its phase's budget", init, each(budget("per_instance", 1), at(F + ("instances",), 2), at(F + ("used",), 2), at(R + ("fault", "fuel"), 2)), False)
case(18, "a fault after every shot", fault, lambda b: (b["result"].update(shots_run=32, counts={"0": 32}), b["result"]["fault"].update(shot=32)), False)
case(18, "a fault in another shot than the next", fault, at(R + ("fault", "shot"), 1), False)
case(28, "a call's fuel fault of the run's budget, with the run's budget not spent", fault, at(R + ("fault", "budget"), "run"), False)
case(18, "a call's fuel fault of the instance's budget", fault, at(R + ("fault", "budget"), "instance"), False)
case(18, "a fault in init that names a callout", init, at(R + ("fault", "callout"), "f"), False)
case(18, "a call's fault the fuel counts no call of", fault, lambda b: (b["result"].update(callouts=0), b["result"]["fuel"].update(callouts={}, instances=400)), False)
case(18, "a call that stopped at its callout's largest", fault, lambda b: (b["result"].update(callouts=2), b["result"]["fuel"]["callouts"]["f"].update(calls=2, fuel=401, max=400), b["result"]["fuel"].update(used=401)), True)
case(18, "a call that stopped past its callout's largest", fault, lambda b: (b["result"].update(callouts=2), b["result"]["fuel"]["callouts"]["f"].update(calls=2, fuel=401, max=399), b["result"]["fuel"].update(used=401)), False)
case(18, "a lifecycle fault whose callout is null", init, at(R + ("fault", "callout"), None), False)
case(18, "a trap whose budget is null", init, at(R + ("fault", "budget"), None), False)
case(18, "a trap in seed", init, at(R + ("fault", "phase"), "seed"), True)
case(18, "a fault in another phase", init, at(R + ("fault", "phase"), "start"), False)
case(18, "a trap of another reason the profile names", init, at(R + ("fault", "reason"), "invalid_conversion_to_integer"), True)
case(18, "a fault in a shot after shots_run", frun, at(R + ("fault", "shot"), 1), False)
case(18, "a fault in a module named null", init, at(R + ("fault", "module"), None), False)
case(18, "a trap that names a budget", init, at(R + ("fault", "budget"), "instance"), False)
case(18, "an ok result whose fault is null", run, at(R + ("fault",), None), False)
case(18, "a call's fault whose callout is null", fault, at(R + ("fault", "callout"), None), False)
case(18, "a fuel fault whose budget is null", fault, at(R + ("fault", "budget"), None), False)
# 19: the counts
case(19, "outcomes of two widths", run, lambda b: (b["result"]["counts"].update({next(iter(b["result"]["counts"])): b["result"]["counts"][next(iter(b["result"]["counts"]))] - 1}), b["result"]["counts"].update({"0": 1})), False)
case(19, "a count of 0", run, lambda b: b["result"]["counts"].update({"0" * len(next(iter(b["result"]["counts"]))): 0}), False)
case(19, "an outcome of no bits", run, counts(0, 32), True)
case(19, "an outcome holding a 2", run, lambda b: b["result"].update(counts={"012": 32}), False)
case(19, "counts null", fault, at(R + ("counts",), None), False)
# Round 4's labelled cases, each where a weakening of one rule moves a verdict.
case(2, "envelope_blake3 of 65 digits", run, lambda b: b["request"].update(envelope_blake3=b["request"]["envelope_blake3"] + "0"), False)
case(12, "transcript_blake3 of 63 digits", run, lambda b: b["result"].update(transcript_blake3=b["result"]["transcript_blake3"][:63]), False)
case(3, "run's fuel a member more, the budget alike", run, budget("z", 1), False)
case(3, "the program a member more", run, lambda b: contract(b)["program"].update(z=1), False)
case(4, "a profile one letter longer", run, lambda b: contract(b).update(profile="wai.quantum.wasmq/1x"), False)
case(5, "inputs null", run, lambda b: contract(b)["program"].update(inputs=None), False)
case(5, "the program's bytes 1104.5", run, lambda b: contract(b)["program"].update(bytes=1104.5), False)
case(5, "an input that is true", run, lambda b: contract(b)["program"].update(inputs={"n": True}), False)
case(6, "a module's bytes 39442.5", run, lambda b: contract(b)["modules"][0].update(bytes=39442.5), False)
case(7, "an export null", run, lambda b: contract(b)["callouts"][0].update(export=None), False)
case(7, "an extern null, with no call made", init, lambda b: contract(b)["callouts"][0].update(extern=None), False)
case(7, "a callout of module 0.5", run, lambda b: contract(b)["callouts"].append({"extern": "g", "module": 0.5, "export": "g"}), False)
def respell(path, text, value):
def f(s):
o = s
for k in path[:-1]:
o = o[k]
o[path[-1]] = g.Raw(text, value)
return f
case(11, "the result's seed written 1234.0", run, lambda b: None, True, respell(R + ("seed",), "1234.0", run["result"]["seed"]))
case(12, "qubits written 17.0", run, lambda b: None, True, respell(R + ("qubits",), "17.0", 17))
case(13, "a budget written 1e7", run, lambda b: None, True, respell(F + ("budget", "per_call"), "1e7", 10000000))
case(14, "the callouts' fuel null", init, at(F + ("callouts",), None), False)
case(14, "the callouts' fuel an array", init, at(F + ("callouts",), []), False)
case(15, "a call fewer than the fuel counts", run, lambda b: b["result"].update(callouts=b["result"]["callouts"] - 1), False)
case(16, "the result's modules in another order", run, lambda b: (second_module(39442, 1)(b), b["result"].update(modules=b["result"]["modules"][::-1])), False)
case(17, "the instances' fuel past 32 x S x per_instance", run, budget("per_instance", 2583), False)
case(17, "one instance for the run, a fault, past 1 x S x per_instance", init, each(at(("request", "wasmq", "run", "state"), "job"), budget("per_instance", 1), at(F + ("instances",), 3), at(F + ("used",), 3)), False)
case(25, "an init fault's fuel past what was used", init, at(R + ("fault", "fuel"), 2), False)
case(18, "a call's fault past its callout's max", frun, at(R + ("fault", "fuel"), 24), False)
case(18, "an ok result one shot past its shots", run, lambda b: (b["result"]["counts"].update({next(iter(b["result"]["counts"])): b["result"]["counts"][next(iter(b["result"]["counts"]))] + 1}), b["result"].update(shots_run=33)), False)
# 20: the fuel of the calls that returned, each 1 to the most one used
case(20, "calls that returned using 1 each", run, lambda b: (calls(b).update(fuel=32, max=1), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"] + 32)), True)
case(20, "calls that returned using nothing", run, lambda b: (calls(b).update(fuel=0, max=0), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"])), False)
case(20, "two calls that returned and one that stopped, in 6", frun, each(budget("per_job", 6), lambda b: (calls(b).update(fuel=6, max=4), b["result"]["fuel"].update(used=6))), True)
case(20, "two calls that returned and one that stopped, in 5", frun, each(budget("per_job", 5), lambda b: (calls(b).update(fuel=5, max=4), b["result"]["fuel"].update(used=5))), False)
case(20, "calls that returned at the most one used", frun, lambda b: calls(b).update(max=23), True)
case(20, "calls that returned past the most one used", frun, lambda b: calls(b).update(max=21), False)
case(20, "the one call, the one that stopped, its fuel more than the fault's", fault, lambda b: (b["result"]["fault"].update(reason="unreachable", fuel=10), b["result"]["fault"].pop("budget")), False)
case(20, "the one call, the one that stopped, its fuel the fault's", fault, lambda b: (b["result"]["fault"].update(reason="unreachable", fuel=10), b["result"]["fault"].pop("budget"), calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10)), True)
# 21: the priors passed to each shot's instances
case(21, "instances that passed each prior at the least", run, lambda b: b["result"]["fuel"].update(instances=32 * passed(b), used=32 * passed(b) + calls(b)["fuel"]), True)
case(21, "instances that passed the priors in less", run, lambda b: b["result"]["fuel"].update(instances=32 * passed(b) - 1, used=32 * passed(b) - 1 + calls(b)["fuel"]), False)
case(21, "one instance for the run, its prior in less", job, lambda b: b["result"]["fuel"].update(instances=passed(b) - 1, used=passed(b) - 1 + calls(b)["fuel"]), False)
case(21, "a prior's fault: no prior passed whole", prior, lambda b: None, True)
# 22: a call's fault in its callout's module
case(22, "a call's fault in its callout's module, beside another", fault, fault_module("m"), True)
case(22, "a call's fault in the other module", fault, fault_module("second"), False)
# 23, 24: a phase against the module's priors, a reason against its phase
case(23, "a prior's fault in a module with none", init, at(R + ("fault", "phase"), "prior"), False)
case(24, "a bad_result while a prior is passed", prior, at(R + ("fault", "reason"), "bad_result"), True)
case(24, "a bad_result in a call", fault, each(at(R + ("fault", "reason"), "bad_result"), lambda b: b["result"]["fault"].pop("budget")), True)
case(24, "a bad_result in init", init, at(R + ("fault", "reason"), "bad_result"), False)
case(24, "a bad_result in seed", init, each(at(R + ("fault", "reason"), "bad_result"), at(R + ("fault", "phase"), "seed")), False)
# 25, 26, 27: a lifecycle fault against the instances, the state and the calls
case(25, "an init fault in shot 1 within the instances' fuel", init, later_shot(1, instances=3, fuel=2), True)
case(25, "an init fault in shot 1, shot 0's init uncounted", init, later_shot(1, instances=2, fuel=2), False)
case(25, "an init fault in shot 1 past the instances' fuel", init, later_shot(1, instances=1, fuel=2), False)
case(26, "one instance for the run, failing in shot 0", init, at(("request", "wasmq", "run", "state"), "job"), True)
case(26, "one instance for the run, failing in shot 2", init, later_shot(2, state="job"), False)
case(26, "a fresh instance each shot, failing in shot 2", init, later_shot(2, instances=3), True)
case(27, "the first shot's instances failing after a call", init, later_shot(0, calls=1), False)
# 28: a fuel fault used its whole limit
case(28, "a call's fuel fault at its limit", fault, each(budget("per_call", 10), lambda b: (calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=10))), True)
case(28, "a call's fuel fault under its limit", fault, lambda b: (calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=10)), False)
case(28, "an instance's fuel fault at its limit", init, each(budget("per_instance", 1), at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "instance")), True)
case(28, "an instance's fuel fault under its limit", init, each(at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "instance")), False)
case(28, "the run's budget run out, not all used", frun, budget("per_job", 51), False)
case(28, "the run's budget the limit, under the call's own", frun, each(budget("per_call", 24), at(R + ("fault", "fuel"), 23), lambda b: calls(b).update(max=23)), True)
case(28, "the run's budget the limit, at the call's own", frun, each(budget("per_call", 23), at(R + ("fault", "fuel"), 23)), False)
case(28, "an instance's run budget, at the instance's own", init, each(budget("per_job", 1), budget("per_instance", 1), at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "run")), False)
case(28, "an instance's run budget, under the instance's own", init, each(budget("per_job", 1), budget("per_instance", 2), at(R + ("fault", "reason"), "fuel_exhausted"), at(R + ("fault", "budget"), "run")), True)
# 29: the bits of a shot, and of the shots
case(29, "outcomes of 2^20 bits", run, counts(2 ** 20, 32), True)
case(29, "outcomes of 2^20 + 1 bits", run, counts(2 ** 20 + 1, 32), False)
case(29, "2^20 shots of 256 bits", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), counts(256, 2)), True)
case(29, "2^20 shots of 257 bits", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), counts(257, 2)), False)
# 30: the work a receipt shows
case(30, "per_job at the most the rest leaves", run, lambda b: budget("per_job", work_left(b))(b), True)
case(30, "per_job one past it", run, lambda b: budget("per_job", work_left(b) + 1)(b), False)
case(30, "2^15 qubits over 2^20 shots", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20, qubits=2 ** 15))), False)
case(30, "one instance for the run: its instance counted once", job, lambda b: budget("per_job", work_left(b))(b), True)
# 31: the envelope
case(31, "an envelope of 2^27 bytes", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=most_prior(b)), True)
case(31, "an envelope of 2^27 + 1 bytes", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=most_prior(b) + 1), False)
case(31, "frames one short of 2^27, the envelope past it", prior, lambda b: contract(b)["modules"][0]["priors"][0].update(bytes=2 ** 27 - 1 - (frames(b) - contract(b)["modules"][0]["priors"][0]["bytes"])), False)
# 20: the most one call used, a returned call's, and each other 1 at least
case(20, "32 calls, the most 21751, in 21751 + 31", run, calls_of(32, 21751), True)
case(20, "32 calls, the most 21751, in 21751 + 30", run, each(calls_of(32, 21751), lambda b: (calls(b).update(fuel=21751 + 30), b["result"]["fuel"].update(used=b["result"]["fuel"]["instances"] + 21751 + 30))), False)
case(20, "two returned, the most 23, beside a stopped call of 4, in 28", frun, each(budget("per_job", 28), lambda b: (calls(b).update(fuel=28, max=23), b["result"]["fuel"].update(used=28))), True)
case(20, "two returned, the most 23, beside a stopped call of 4, in 27", frun, each(budget("per_job", 27), lambda b: (calls(b).update(fuel=27, max=23), b["result"]["fuel"].update(used=27))), False)
case(20, "one returned in 5, then one stopped at 0, the run's budget spent", frun, each(budget("per_job", 5), lambda b: (b["result"].update(callouts=2), calls(b).update(calls=2, fuel=5, max=5), b["result"]["fuel"].update(used=5), b["result"]["fault"].update(fuel=0))), True)
case(20, "two returned in 11, the most 10, then one stopped at 0", frun, each(budget("per_job", 11), lambda b: (calls(b).update(fuel=11, max=10), b["result"]["fuel"].update(used=11), b["result"]["fault"].update(fuel=0))), True)
case(20, "two returned in 10, the most 10, then one stopped at 0", frun, each(budget("per_job", 10), lambda b: (calls(b).update(fuel=10, max=10), b["result"]["fuel"].update(used=10), b["result"]["fault"].update(fuel=0))), False)
# 21, 25: what a lifecycle fault shows of the set it stopped
case(25, "an init stopped after its 100-byte prior, in 104", init, each(own_prior(100), at(F + ("instances",), 104), at(F + ("used",), 104)), True)
case(25, "an init stopped after its 100-byte prior, in 103", init, each(own_prior(100), at(F + ("instances",), 103), at(F + ("used",), 103)), False)
case(21, "an init stopped after its 100-byte prior, in 102", init, each(own_prior(100), at(F + ("instances",), 102), at(F + ("used",), 102)), False)
case(25, "a seed stopped after its 100-byte prior's module, passed none", init, each(own_prior(100), at(R + ("fault", "phase"), "seed")), True)
case(25, "the second module's init stopped after the first's prior, in 104", init, each(second_module(50, 57), own_prior(100), at(R + ("fault", "module"), "second"), at(F + ("instances",), 104), at(F + ("used",), 104)), True)
case(25, "the second module's init stopped after the first's prior, in 103", init, each(second_module(50, 57), own_prior(100), at(R + ("fault", "module"), "second"), at(F + ("instances",), 103), at(F + ("used",), 103)), False)
case(25, "a seed stopped in shot 1, shot 0's seed shown", init, each(later_shot(1, instances=2, fuel=1), at(R + ("fault", "phase"), "seed")), True)
case(25, "a seed stopped in shot 1, shot 0's seed uncounted", init, each(later_shot(1, instances=1, fuel=1), at(R + ("fault", "phase"), "seed")), False)
# 29: the longest name, in characters
case(29, "two widths, the longer past 2^20", run, lambda b: b["result"].update(counts={next(iter(b["result"]["counts"])): 31, "0" * (2 ** 20 + 1): 1}), False)
case(19, "2^20 shots of a name of 256 characters in 257 bytes", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), lambda b: b["result"].update(counts={"\u00e9" + "0" * 255: 2})), False)
case(29, "2^20 shots of a name of 257 characters", frun, each(lambda b: (contract(b)["run"].update(shots=2 ** 20), b["result"].update(shots=2 ** 20)), lambda b: b["result"].update(counts={"\u00e9" + "0" * 256: 2})), False)
# 32: the calls a shot can make
case(32, "32 shots of 2^21 calls", run, calls_of(32 * 2 ** 21), True)
case(32, "32 shots of 2^21 calls and one more", run, calls_of(32 * 2 ** 21 + 1), False)
case(32, "a call's fault in the first shot, after 2^21 - 1 calls", fault, lambda b: (b["result"].update(callouts=2 ** 21), calls(b).update(calls=2 ** 21, fuel=2 ** 21 - 1 + 400), b["result"]["fuel"].update(used=2 ** 21 - 1 + 400)), True)
case(32, "a call's fault in the first shot, after 2^21 calls", fault, lambda b: (b["result"].update(callouts=2 ** 21 + 1), calls(b).update(calls=2 ** 21 + 1, fuel=2 ** 21 + 400), b["result"]["fuel"].update(used=2 ** 21 + 400)), False)
# 33: a prior passed whole within one lifecycle call's limit
case(33, "a prior of 87 bytes under 90 a lifecycle call", run, each(budget("per_instance", 90), at(F + ("instances",), 32 * 90), at(F + ("used",), 32 * 90 + 588348)), True)
case(33, "a prior of 87 bytes under 89 a lifecycle call", run, each(budget("per_instance", 89), at(F + ("instances",), 32 * 90), at(F + ("used",), 32 * 90 + 588348)), False)
case(33, "an init stopped after its 100-byte prior, under 103", init, each(own_prior(100), budget("per_instance", 103), at(F + ("instances",), 104), at(F + ("used",), 104)), True)
case(33, "an init stopped after its 100-byte prior, under 102", init, each(own_prior(100), budget("per_instance", 102), at(F + ("instances",), 104), at(F + ("used",), 104)), False)
# 34: what a fault's reason shows was charged
case(34, "a trap after nothing charged", init, each(at(R + ("fault", "fuel"), 0)), False)
case(34, "a result that is not one, after 2", fault, fault_of("bad_result", 2), True)
case(34, "a result that is not one, after 1", fault, fault_of("bad_result", 1), False)
case(34, "the stack past 2^23 after 788", fault, each(budget("per_call", 1000), fault_of("stack_exhausted", 788)), True)
case(34, "the stack past 2^23 after 787", fault, each(budget("per_call", 1000), fault_of("stack_exhausted", 787)), False)
# 35: the transcript of no returned call
case(35, "an ok run of no call, its transcript the prefix's", run, lambda b: (b["result"].update(callouts=0), b["result"]["fuel"].update(callouts={}, used=b["result"]["fuel"]["instances"])), True)
case(35, "an ok run of no call, its transcript the calls'", run, lambda b: (b["result"].update(callouts=0, transcript_blake3=b["result"]["transcript_blake3"][::-1]), b["result"]["fuel"].update(callouts={}, used=b["result"]["fuel"]["instances"])), False)
case(35, "a call's fault of no returned call, another transcript", fault, at(R + ("transcript_blake3",), "ab" * 32), False)
case(35, "a lifecycle fault, another transcript", init, at(R + ("transcript_blake3",), "ab" * 32), False)
# Places where a member's own rule and another's both read it: each verifier must state
# every rule it breaks, so that one reading it otherwise in one rule shows.
case(13, "per_job 2^53, alike in the result", run, budget("per_job", 2 ** 53), False)
case(6, "a module's blake3 in upper case, alike in the result", run, lambda b: (contract(b)["modules"][0].update(blake3=contract(b)["modules"][0]["blake3"].upper()), b["result"]["modules"][0].update(blake3=b["result"]["modules"][0]["blake3"].upper())), False)
def named_one(b):
contract(b)["modules"][0]["name"] = 1
b["result"]["modules"][0]["name"] = 1
if "fault" in b["result"]:
b["result"]["fault"]["module"] = 1
case(6, "a module named 1, the result's module 1.0", run, named_one, False, respell(R + ("modules", 0, "name"), "1.0", 1))
case(6, "a module named 1, an init's fault in 1.0", init, named_one, False, respell(R + ("fault", "module"), "1.0", 1))
case(6, "a module named 1, a prior's fault in 1.0", prior, named_one, False, respell(R + ("fault", "module"), "1.0", 1))
case(26, "one instance for the run, a fault in shot 0.5", init, each(at(("request", "wasmq", "run", "state"), "job"), at(R + ("fault", "shot"), 0.5)), False)
case(18, "a fault in shot 0.5, after a call", init, each(at(R + ("fault", "shot"), 0.5), at(R + ("callouts",), 1)), False)
# A lifecycle fault is one that has a phase: null among them, absent not.
case(26, "a fault whose phase is null, in shot 2 of one instance for the run", init, each(later_shot(2, state="job"), at(R + ("fault", "phase"), None)), False)
case(18, "a fault with no phase, in shot 2 of one instance for the run", init, each(later_shot(2, state="job"), lambda b: b["result"]["fault"].pop("phase")), False)
# Every member of each genuine job given a value of another kind (half a unit off, below
# 0, past 2^53 - 1, null, a digest in upper case), sealed again. No member of a wasmQ job
# holds such a value: each verifier must refuse each, and both must state the same rules
# broken (the differential holds them to that), so that a rule's check read loosely in
# one, or a null read as absent, shows wherever another rule's check also refuses it.
def leaves(v, path):
if isinstance(v, dict):
for k, x in v.items():
yield path + (k,), x
for y in leaves(x, path + (k,)):
yield y
elif isinstance(v, list):
for i, x in enumerate(v[:1]):
yield path + (i,), x
for y in leaves(x, path + (i,)):
yield y
for name, base in (("run", run), ("fault", fault), ("init", init), ("fault-run", frun), ("prior", prior), ("state-job", job)):
for part in ("request", "result"):
for path, v in leaves(base[part], (part,)):
# The receipt is the seal's; the format says what kind of job it is.
if "receipt" in path or path == ("result", "format"):
continue
where = "%s %s" % (name, "/".join(map(str, path)))
if isinstance(v, (int, float)) and not isinstance(v, bool):
case("kinds", "%s + 0.5" % where, base, at(path, v + 0.5), False)
case("kinds", "%s at -1" % where, base, at(path, -1), False)
case("kinds", "%s at 2^53" % where, base, at(path, 2 ** 53), False)
if isinstance(v, str) and re.fullmatch("[0-9a-f]{64}", v):
case("kinds", "%s in upper case" % where, base, at(path, v.upper()), False)
case("kinds", "%s null" % where, base, at(path, None), False)
return out
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--reference", help="the wai-quantum binary")
@ -224,7 +781,13 @@ def main():
ap.add_argument("--corpus", default=CORPUS)
ap.add_argument("--extra", action="append", default=[], help="a directory of receipts both must find valid")
ap.add_argument("--plant", help="run the second verifier with this planted defect; succeed only if it is caught")
ap.add_argument("--second", help="another second verifier's file in place of receipt_verify.py (a mutant of it)")
ap.add_argument("--wasmq-only", action="store_true", help="only what holds a wasmQ job: its receipts, their changes, the rules and the labelled cases")
ap.add_argument("--first", action="store_true", help="stop at the first stage that finds a disagreement")
a = ap.parse_args()
global SECOND
if a.second:
SECOND = os.path.abspath(a.second)
if not a.second_only and not a.reference:
ap.error("--reference is required, unless --second-only")
ref = os.path.abspath(a.reference) if a.reference else None
@ -239,20 +802,48 @@ def main():
problems.append("%s is in the manifest and not in the corpus" % f)
# The corpus: both verifiers and the manifest, receipt by receipt.
files = [os.path.join(a.corpus, e["file"]) for e in manifest if e["file"] in present]
entries = [e for e in manifest if e["file"] in present]
entries = [e for e in manifest if e["file"] in present and (not a.wasmq_only or "wasmq" in e["file"])]
files = [os.path.join(a.corpus, e["file"]) for e in entries]
r2 = run_second_files(files, a.plant)
r1 = r2 if a.second_only else run_reference_files(ref, files)
agree = 0
for e, x, y in zip(entries, r1, r2):
if not a.second_only:
same_rules(e["file"], x, y, problems)
want = tuple(sorted(e["reasons"]))
if said(x) != said(y) or said(x)[0] != want:
problems.append("%s: the manifest says %s; the reference %s; the second verifier %s" % (e["file"], list(want), list(said(x)), list(said(y))))
else:
agree += 1
# A crafted wasmQ receipt that names one rule breaks that rule alone: one problem from the
# reference, and that rule alone from the second verifier, which numbers its rules.
alone = 0
for e, x, y in zip(entries, r1, r2):
m = re.search(r"\(rule (\d+)\)$", e.get("what", ""))
if not m or not e["file"].startswith("jobs/crafted-wasmq-"):
continue
alone += 1
for who, v in ((None if a.second_only else "the reference", x), ("the second verifier", y)):
if who and rules_of(v) != {int(m.group(1))}:
problems.append("%s breaks rule %s alone, but %s states %s" % (e["file"], m.group(1), who, (v.get("wasmq") or {}).get("problems")))
print("corpus: %d crafted wasmQ receipts each break the one rule they name, and no other" % alone)
valid = sum(1 for e in entries if not e["reasons"])
print("corpus: %d receipts (%d valid, %d not), %d agree %s" % (len(entries), valid, len(entries) - valid, agree, "with the manifest (second verifier only)" if a.second_only else "three ways (manifest, reference, second)"))
if a.second_only:
g = generator()
problems += rules_stage(None, a.plant, (g.seal, g.public_key(g.DEMO).hex()))
problems += labelled_stage(None, a.plant)
return finish(a, problems)
if a.first and problems:
return finish(a, problems)
# The rules and the labelled cases first: each is short, and each has its verdict written.
g = generator()
seal = (g.seal, g.public_key(g.DEMO).hex())
problems += rules_stage(ref, a.plant, seal)
if a.first and problems:
return finish(a, problems)
problems += labelled_stage(ref, a.plant)
if a.first and problems:
return finish(a, problems)
# Receipts a person holds: both must find them valid.
@ -268,8 +859,6 @@ def main():
# Every valid receipt, one member changed at a time.
lines, meta = [], []
g = generator()
seal = (g.seal, g.public_key(g.DEMO).hex())
for e in entries:
if e["reasons"]:
continue
@ -293,6 +882,7 @@ def main():
reasons = Counter()
for (fname, what, expected), x, y in zip(meta, m1, m2):
sx, sy = said(x), said(y)
same_rules("%s, %s" % (fname, what), x, y, problems)
if sx != sy:
problems.append("%s, %s: the reference %s; the second verifier %s" % (fname, what, list(sx), list(sy)))
continue
@ -310,10 +900,67 @@ def main():
held += 1
print("changed: %d receipts from %d valid ones; %d agree (%d refused, as every change inside the seal must be; %d valid, as every change outside it must be; %d at the edges of a number, judged only by the other verifier)" % (len(lines), valid, agree, caught, held, compared))
print("reasons given to the changed receipts: " + ", ".join("%s %d" % kv for kv in sorted(reasons.items())))
return finish(a, problems)
def rules_stage(ref, plant, seal):
"""Each verifier given every case of rule_cases: each must give the reasons written for
it (the second alone with --second-only)."""
cases = rule_cases(CORPUS, seal[0])
with tempfile.TemporaryDirectory() as tmp:
path = os.path.join(tmp, "rules.jsonl")
with open(path, "w", encoding="utf-8") as f:
f.write("\n".join(b if isinstance(b, str) else compact(b) for _, b, _ in cases) + "\n")
second = run_lines([sys.executable, "-I", SECOND] + (["--plant", plant] if plant else []) + ["--lines"], path, len(cases))
first = run_lines([ref, "verify", "--lines"], path, len(cases)) if ref else second
problems = []
for (what, _, want), x, y in zip(cases, first, second):
if ref:
same_rules(what, x, y, problems)
rule = re.match(r"rule (\d+), ", what)
for who, v in (("the reference", x), ("the second verifier", y)):
if tuple(sorted(v.get("reasons", []))) != tuple(want):
problems.append("%s: written %s; %s %s" % (what, want, who, sorted(v.get("reasons", []))))
elif want and rule and rules_of(v) is not None and int(rule.group(1)) not in rules_of(v):
problems.append("%s: %s finds it breaks rules %s, not the rule it is written for" % (what, who, sorted(rules_of(v))))
rules = len({w.split(",")[0] for w, _, _ in cases if re.match(r"rule \d+,", w)})
kinds = sum(1 for w, _, _ in cases if w.startswith("rule kinds,"))
print("rules: %d cases, %d at the bounds of %d rules of a wasmQ job's form and %d of members of another kind, sealed again; %d as written, the same rules broken by both" % (len(cases), len(cases) - kinds, rules, kinds, len(cases) - len({p.split(":")[0] for p in problems})))
return problems
def labelled_stage(ref, plant):
"""The second verifier's own hand-labelled wasmQ cases (`receipt_verify.py --wasmq-cases`),
each as its exact text, given to both verifiers: each must give the reasons its author
wrote, so that one labelled corpus binds both. The labels come from receipt_verify.py as
written, whichever second verifier is under test."""
with tempfile.TemporaryDirectory() as tmp:
out = os.path.join(tmp, "cases.jsonl")
p = subprocess.run([sys.executable, "-I", ORIGINAL_SECOND, "--wasmq-cases", out], capture_output=True, text=True)
if p.returncode != 0:
raise SystemExit("receipt_verify.py --wasmq-cases failed: %s" % p.stderr.strip()[:400])
with open(out, encoding="utf-8") as f:
cases = [json.loads(line) for line in f if line.strip()]
files = []
for i, c in enumerate(cases):
path = os.path.join(tmp, "case-%04d.json" % i)
with open(path, "wb") as f:
f.write(base64.b64decode(c["raw"]))
files.append(path)
second = run_second_files(files, plant)
first = run_reference_files(ref, files) if ref else second
problems = []
for c, x, y in zip(cases, first, second):
if ref:
same_rules("labelled %s" % c["name"], x, y, problems)
want = sorted(c["reasons"])
for who, v in (("the reference", x), ("the second verifier", y)):
if sorted(v.get("reasons", [])) != want:
problems.append("labelled %s: written %s; %s %s" % (c["name"], want, who, sorted(v.get("reasons", []))))
print("labelled: %d of the second verifier's hand-labelled wasmQ cases, given to both; %d as written" % (len(cases), len(cases) - len({p.split(":")[0] for p in problems})))
return problems
def finish(a, problems):
if a.plant:
if problems:

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,561 @@
#!/usr/bin/env python3
"""wasmq_mutants.py: each rule of a wasmQ job's form (quantum-wasmq section 6.5), weakened in
each verifier, and held to the receipts differential: every weakening must be caught.
python3 -I wasmq_mutants.py python --reference PATH/wai-quantum [--jobs N] [--rule N]
python3 -I wasmq_mutants.py rust-schemata ENGINE_RS OUT.json
python3 -I wasmq_mutants.py rust --reference PATH/wai-quantum --mutants OUT.json [--jobs N]
The weakenings are made from the code, not written by hand: at each place a rule is checked,
drop the check never fails;
bound a comparison moved by one (`<` for `<=`, `>` for `>=`, and back), or a whole
number in it one more;
type a count read as any number (0.5, -1, a number past 2^53), a digest as any string of
its length, two values compared as written rather than as JSON values;
null a member that is `null` read as absent;
absent a member that is absent read as `null`;
extreme the most of many read as the least, and back (a `max` over a list for a `min`).
Each is assigned the rule whose check it is (the second verifier numbers its checks; the
engine marks each rule's code `// Rule N.` or `// N:`). The second verifier's mutants are
whole files; the engine's are one build (`rust-schemata` writes every mutant into the engine
behind the environment variable WQ_MUTANT, each off unless it is named), run once a mutant.
A mutant is caught when `receipt_differential.py --wasmq-only --first` fails with it: the
corpus, the rules stage, the labelled cases and the one-member changes. A mutant no input
can tell from the text (one that only changes how a verdict already refused is worded, say)
is listed in EQUIVALENT with the reason; any other survivor fails the run. Counts are
reported per rule. Standard library only, Python 3.9+.
"""
import argparse
import ast
import copy
import json
import os
import re
import subprocess
import sys
import tempfile
from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor
HERE = os.path.dirname(os.path.abspath(__file__))
SECOND = os.path.join(HERE, "receipt_verify.py")
DIFFERENTIAL = os.path.join(HERE, "receipt_differential.py")
# Mutants that no input can tell from the text, each by its rule, kind and what it does
# ("RULES|KIND|WHAT"), with the reason no input tells it from the text.
EQUIVALENT = {
# The engine's.
'6|bound|whole\'s upper bound one more in `!m["name"].is_string() || !is_digest(&m["blake3"]) || !whole(&m["bytes"], 1, MAX_EXACT)`': "a count is at most 2^53 - 1 by its own reading (count), so a bound one past that bounds nothing more",
'6|bound|whole\'s upper bound one more in `!pr["name"].is_string() || !is_digest(&pr["blake3"]) || !whole(&pr["bytes"], 0, MAX_EXACT)`': "the same, for a prior's bytes",
'8|bound|whole\'s upper bound one more in `!whole(&run["seed"], 0, MAX_EXACT)`': "the same, for the seed",
"14|drop|the check never fails: `all.is_none()`": "rule 14's check of a call's largest against its fuel refuses a fuel that is no count already",
'16|type|same read loosely in `mods.len() != got.len() || mods.iter().zip(got).any(|(a, b)| !same(&a["blake3"], &b["blake3"]) || !same(&a["name"], &b["name"]))`#blake3': "a blake3 that is no string breaks rule 16's own check that the result's is a digest, so comparing it as written changes no rule",
'18|null|a null member read as absent: fuel["callouts"].get(name) in `fuel["callouts"].get(name)`': "both ways the stopped call is found missing are rule 18's",
'18|absent|an absent member read as null: fuel["callouts"].get(name) in `fuel["callouts"].get(name)`': "the same",
"19|type|count read loosely in `count(n).is_none_or(|n| n == 0)`": "rule 19's sum of the counts refuses a count that is no count already",
'20-35|null|a null member read as absent: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the fault is read only as an object: null and absent are both none",
'20-35|absent|an absent member read as null: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the same",
'35|null|a null member read as absent: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the same, where rule 35 reads the fault",
'35|absent|an absent member read as null: r.get("fault") in `if r["status"] == "fault" { r.get("fault").filter(|f| f.is_object()) } else { None }`': "the same",
}
def _equivalent(rules, kind, what):
return "%s|%s|%s" % (",".join(map(str, rules)), kind, what) in EQUIVALENT
# ------------------------------------------------------------------ the second verifier
# The type-check helpers: a value read through one of them is read the same whether it is
# absent or null (each refuses both), so a null-or-absent weakening under one changes nothing.
_CHECKERS = {"_count", "_count_in", "_text_is", "_lower_hex", "_obj", "_arr", "_or_zero", "_exactly", "isinstance", "_n"}
_LOOSE = {"_count": "_mut_count", "_count_in": "_mut_count_in", "_lower_hex": "_mut_lower_hex"}
_HELPERS_SOURCE = '''
def _mut_count(v):
"""A weakening: any number is a count."""
return isinstance(v, Num) and v.value >= -1e300
def _mut_count_in(v, low, high):
return _mut_count(v) and low <= int(v.value) <= high
def _mut_lower_hex(v, n):
return isinstance(v, str) and len(v) == n
def _mut_get_null(v, name):
"""A weakening: a member that is null is read as absent."""
x = _get(v, name)
return _ABSENT if x is None else x
def _mut_get_absent(v, name):
"""A weakening: a member that is absent is read as null."""
x = _get(v, name)
return None if x is _ABSENT else x
def _mut_in_null(name, v):
return isinstance(v, dict) and v.get(name) is not None
def _mut_in_absent(name, v):
return isinstance(v, dict)
'''
def _wasmq_functions(tree):
"""The second verifier's functions that check a wasmQ job's form: wasmq_broken and each
module-level function it calls that is no shared helper."""
funcs = {n.name: n for n in tree.body if isinstance(n, ast.FunctionDef)}
root = funcs["wasmq_broken"]
called = {n.func.id for n in ast.walk(root) if isinstance(n, ast.Call) and isinstance(n.func, ast.Name)}
shared = _CHECKERS | {"_get", "rule", "all", "any", "len", "set", "sorted", "sum", "min", "max", "abs", "int", "str", "list", "range", "isinstance", "_numbers", "_text_is"}
out = [root]
for name in sorted(called - shared):
f = funcs.get(name)
if f is not None and f.lineno > funcs.get("is_wasmq", root).lineno:
out.append(f)
return out
def _rule_calls(fn):
"""(line, number, the call) for each rule(N, ...) in fn, in order."""
out = []
for n in ast.walk(fn):
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == "rule" and n.args and isinstance(n.args[0], ast.Constant):
out.append((n.lineno, n.args[0].value, n))
return sorted(out, key=lambda x: x[0])
def _rule_of(node, root_calls, helper_rules, fn):
"""The rule a node's check belongs to: the rule(N, ...) call around it; else, in
wasmq_broken, for a value assigned, every rule whose own code (from the rule before it to
its call) reads that name, or else the first rule called at or after its line; in a
helper, the rules whose checks call it."""
for line, number, call in root_calls:
if any(x is node for x in ast.walk(call)):
return [number]
if fn.name != "wasmq_broken":
return helper_rules.get(fn.name, ["?"])
top = next((st for st in fn.body if any(x is node for x in ast.walk(st))), None)
if isinstance(top, ast.Assign):
names = {t.id for target in top.targets for t in ast.walk(target) if isinstance(t, ast.Name)}
readers = []
bounds = [0] + [line for line, _, _ in root_calls]
for (line, number, _), start in zip(root_calls, bounds):
block = [st for st in fn.body if start < st.lineno <= line and st is not top]
if any(isinstance(x, ast.Name) and x.id in names for st in block for x in ast.walk(st)):
readers.append(number)
if readers:
return sorted(set(readers))
after = [number for line, number, _ in root_calls if line >= node.lineno]
return after[:1] or ["?"]
def python_mutants(path=SECOND):
"""Every weakening of the second verifier's form check: (id, rules, what, the file's text)."""
with open(path, encoding="utf-8") as f:
source = f.read()
tree = ast.parse(source)
fns = _wasmq_functions(tree)
root = fns[0]
root_calls = _rule_calls(root)
helper_rules = defaultdict(list)
for line, number, call in root_calls:
for n in ast.walk(call):
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and any(n.func.id == f.name for f in fns[1:]):
helper_rules[n.func.id].append(number)
# A helper called from code before a rule(N, ...) is that rule's.
for f in fns[1:]:
if f.name not in helper_rules:
for n in ast.walk(root):
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == f.name:
helper_rules[f.name] = _rule_of(n, root_calls, {}, root)
parents = {}
for fn in fns:
for p in ast.walk(fn):
for c in ast.iter_child_nodes(p):
parents[c] = p
sites = [] # (node, kind, what, transform)
flip = {ast.Lt: ast.LtE, ast.LtE: ast.Lt, ast.Gt: ast.GtE, ast.GtE: ast.Gt}
for fn in fns:
for n in ast.walk(fn):
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id == "rule" and n.args and isinstance(n.args[0], ast.Constant):
sites.append((n, "drop", "rule %s never fails" % n.args[0].value, lambda m: ast.Call(func=m.func, args=[m.args[0], ast.Constant(True)], keywords=[])))
if isinstance(n, ast.Compare):
for i, op in enumerate(n.ops):
if type(op) in flip:
def t(m, i=i):
m.ops[i] = flip[type(m.ops[i])]()
return m
sites.append((n, "bound", "%s for %s in %s" % (flip[type(op)].__name__, type(op).__name__, ast.unparse(n)), t))
for c in ast.walk(n):
if isinstance(c, ast.Constant) and type(c.value) is int:
sites.append((c, "bound", "%d for %d in %s" % (c.value + 1, c.value, ast.unparse(n)), lambda m: ast.Constant(m.value + 1)))
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name) and n.func.id in ("max", "min") and len(n.args) == 1:
other = "min" if n.func.id == "max" else "max"
sites.append((n, "extreme", "%s for %s in %s" % (other, n.func.id, ast.unparse(n)), lambda m, other=other: ast.Call(func=ast.Name(other, ast.Load()), args=m.args, keywords=m.keywords)))
if isinstance(n, ast.Call) and isinstance(n.func, ast.Name):
if n.func.id == "_count_in":
for c in n.args[1:]:
if isinstance(c, ast.Constant) and type(c.value) is int:
sites.append((c, "bound", "%d for %d in %s" % (c.value + 1, c.value, ast.unparse(n)), lambda m: ast.Constant(m.value + 1)))
if n.func.id in _LOOSE:
sites.append((n, "type", "%s read loosely" % ast.unparse(n), lambda m: ast.Call(func=ast.Name(_LOOSE[m.func.id], ast.Load()), args=m.args, keywords=m.keywords)))
if n.func.id == "_get":
p = parents.get(n)
checked = isinstance(p, ast.Call) and isinstance(p.func, ast.Name) and p.func.id in _CHECKERS
if not checked:
sites.append((n, "null", "a null member read as absent: %s" % ast.unparse(n), lambda m: ast.Call(func=ast.Name("_mut_get_null", ast.Load()), args=m.args, keywords=[])))
sites.append((n, "absent", "an absent member read as null: %s" % ast.unparse(n), lambda m: ast.Call(func=ast.Name("_mut_get_absent", ast.Load()), args=m.args, keywords=[])))
if isinstance(n, ast.Compare) and len(n.ops) == 1 and isinstance(n.ops[0], (ast.In, ast.NotIn)) and isinstance(n.left, ast.Constant) and isinstance(n.left.value, str):
for kind, helper in (("null", "_mut_in_null"), ("absent", "_mut_in_absent")):
def t(m, helper=helper):
call = ast.Call(func=ast.Name(helper, ast.Load()), args=[m.left, m.comparators[0]], keywords=[])
return ast.UnaryOp(ast.Not(), call) if isinstance(m.ops[0], ast.NotIn) else call
sites.append((n, kind, "`%s` in: %s" % (n.left.value, "null read as absent" if kind == "null" else "absent read as null"), t))
out = []
for k, (node, kind, what, transform) in enumerate(sites):
fn = next(f for f in fns if any(x is node for x in ast.walk(f)))
rules = _rule_of(node, root_calls, helper_rules, fn)
mutant_tree = copy.deepcopy(tree)
# The same node in the copy: by its place in a walk of the same function.
index = [i for i, x in enumerate(ast.walk(fn)) if x is node][0]
mfn = next(f for f in mutant_tree.body if isinstance(f, ast.FunctionDef) and f.name == fn.name)
target = list(ast.walk(mfn))[index]
replaced = transform(copy.deepcopy(target))
_replace(mfn, target, replaced)
ast.fix_missing_locations(mutant_tree)
text = ast.unparse(mutant_tree) + _HELPERS_SOURCE
ident = "P%04d %s:%d %s" % (k, fn.name, node.lineno, kind)
out.append((ident, rules, what, text))
return out
def _replace(tree, old, new):
for p in ast.walk(tree):
for field, value in ast.iter_fields(p):
if value is old:
setattr(p, field, new)
return
if isinstance(value, list):
for i, x in enumerate(value):
if x is old:
value[i] = new
return
raise ValueError("no place to replace")
# ------------------------------------------------------------------ the engine
_FUNCS = ("fn contract_form(", "pub fn problems(", "fn across(", "fn members(", "pub fn envelope_bytes(", "pub fn bare_transcript(")
_MARK = re.compile(r"^\s*// (?:Rule )?(\d+)[.:]")
_CMP = re.compile(r"(?<=[\w\)\]]) (>=|<=|>|<) (?=[\w\(&!*-])")
_FLIP = {">=": ">", ">": ">=", "<=": "<", "<": "<="}
_HELPERS_RS = '''
/// The weakening this build is, when wasmq_mutants.py made it: none otherwise.
fn mutant(k: u32) -> bool {
static WHICH: std::sync::OnceLock<u32> = std::sync::OnceLock::new();
*WHICH.get_or_init(|| std::env::var("WQ_MUTANT").ok().and_then(|v| v.parse().ok()).unwrap_or(u32::MAX)) == k
}
/// A weakening: any number is a count.
fn loose_count(v: &Value) -> Option<u64> {
v.as_f64().map(|x| x.abs() as u64)
}
fn loose_whole(v: &Value, lo: u64, hi: u64) -> bool {
loose_count(v).is_some_and(|n| lo <= n && n <= hi)
}
fn loose_digest(v: &Value) -> bool {
v.as_str().is_some_and(|s| s.len() == 64)
}
fn raw_same(a: &Value, b: &Value) -> bool {
a == b
}
'''
def _calls(expr, name):
"""Each place `name(` is called in expr: (start, end) of the call, its parentheses matched."""
out = []
for m in re.finditer(r"(?<![\w.])" + re.escape(name) + r"\(", expr):
depth, i = 0, m.end() - 1
while i < len(expr):
if expr[i] == "(":
depth += 1
elif expr[i] == ")":
depth -= 1
if depth == 0:
out.append((m.start(), i + 1))
break
i += 1
return out
def _args(call):
"""A call's arguments, split at its top-level commas."""
inner = call[call.index("(") + 1:-1]
out, depth, start = [], 0, 0
for i, ch in enumerate(inner):
if ch in "([{":
depth += 1
elif ch in ")]}":
depth -= 1
elif ch == "," and depth == 0:
out.append(inner[start:i].strip())
start = i + 1
out.append(inner[start:].strip())
return out
def _expr_mutants(expr):
"""(kind, what, the expression weakened) for each weakening of one expression, `what`
naming the expression it weakens."""
return [(kind, "%s in `%s`" % (what, expr), mut) for kind, what, mut in _expr_mutants_bare(expr)]
def _expr_mutants_bare(expr):
out = []
for m in _CMP.finditer(expr):
out.append(("bound", "%s for %s" % (_FLIP[m.group(1)], m.group(1)), expr[:m.start(1)] + _FLIP[m.group(1)] + expr[m.end(1):]))
for m in re.finditer(r"(?<![\w.<])Some\((\d+)\)", expr):
out.append(("bound", "Some(%d) for Some(%s)" % (int(m.group(1)) + 1, m.group(1)), expr[:m.start(1)] + str(int(m.group(1)) + 1) + expr[m.end(1):]))
for a, b in _calls(expr, "whole"):
args = _args(expr[a:b])
if len(args) == 3:
out.append(("bound", "whole's upper bound one more", expr[:a] + "whole(%s, %s, (%s).saturating_add(1))" % (args[0], args[1], args[2]) + expr[b:]))
if args[1].isdigit() and int(args[1]) > 0:
out.append(("bound", "whole's lower bound one less", expr[:a] + "whole(%s, %d, %s)" % (args[0], int(args[1]) - 1, args[2]) + expr[b:]))
out.append(("type", "whole read loosely", expr[:a] + "loose_whole(" + expr[a + len("whole("):]))
for name, loose in (("count", "loose_count"), ("is_digest", "loose_digest"), ("same", "raw_same")):
for a, b in _calls(expr, name):
out.append(("type", "%s read loosely" % name, expr[:a] + loose + expr[a + len(name):]))
for m in re.finditer(r"(?<![\w.])(\w+(?:\[[^\[\]]*\])*)\.get\(([^()]*)\)", expr):
whole_get = m.group(0)
recv, key = whole_get[: whole_get.rindex(".get(")], m.group(2)
out.append(("null", "a null member read as absent: %s" % whole_get, expr[:m.start()] + "%s.get(%s).filter(|v| !v.is_null())" % (recv, key) + expr[m.end():]))
out.append(("absent", "an absent member read as null: %s" % whole_get, expr[:m.start()] + "Some(%s.get(%s).unwrap_or(&Value::Null))" % (recv, key) + expr[m.end():]))
for m in re.finditer(r"\.(max|min)\(\)", expr):
other = "min" if m.group(1) == "max" else "max"
out.append(("extreme", "%s() for %s()" % (other, m.group(1)), expr[:m.start(1)] + other + expr[m.end(1):]))
for m in re.finditer(r"(\w+)\.contains_key\(([^()]*)\)", expr):
out.append(("null", "a null member read as absent: contains_key", expr[:m.start()] + "%s.get(%s).is_some_and(|v| !v.is_null())" % (m.group(1), m.group(2)) + expr[m.end():]))
return out
def rust_schemata(engine_rs, out_json):
"""Writes every weakening of the engine's form check into engine_rs, each behind
mutant(K), and the list of them to out_json."""
with open(engine_rs, encoding="utf-8") as f:
lines = f.read().split("\n")
mutants, rule, inside, depth = [], "?", False, 0
new = []
for no, line in enumerate(lines, 1):
if not inside and any(line.startswith(f) or line.startswith(" " + f) or line.startswith("pub(crate) " + f) for f in _FUNCS):
# What across reads before rule 20's mark is the fault, which rules 20 to 35 share.
inside, depth, rule = True, 0, ("members" if "fn members(" in line else "20-35" if "fn across(" in line else "?")
new.append(line)
depth += line.count("{") - line.count("}")
continue
if inside:
m = _MARK.match(line)
if m:
rule = m.group(1)
if line.strip().startswith("fn ") and "fn priors(" in line:
new.append(line)
depth += line.count("{") - line.count("}")
continue
done = _mutate_line(line, lines[no] if no < len(lines) else "", rule, no, mutants)
new.append(done)
depth += line.count("{") - line.count("}")
if depth <= 0:
inside = False
continue
new.append(line)
text = "\n".join(new)
test_at = text.find("\n#[cfg(test)]")
text = text[:test_at] + _HELPERS_RS + text[test_at:] if test_at >= 0 else text + _HELPERS_RS
with open(engine_rs, "w", encoding="utf-8") as f:
f.write(text)
with open(out_json, "w", encoding="utf-8") as f:
json.dump(mutants, f, indent=1)
print("rust-schemata: %d weakenings written into %s" % (len(mutants), engine_rs))
def _mutate_line(line, following, rule, no, mutants):
"""The line with each weakening of its check behind mutant(K)."""
def chain(expr, extra=()):
variants = list(extra) + _expr_mutants(expr)
if not variants:
return None
arms = []
seen = defaultdict(int)
for kind, what, mut in variants:
k = len(mutants)
seen[what] += 1
if seen[what] > 1 or sum(1 for _, w, _ in variants if w == what) > 1:
# The same weakening at two places of one expression: named by what it weakens.
at = re.search(r'&\w\["(\w+)"\], &\w\["\1"\]', mut[mut.find("raw_same(") if "raw_same(" in mut else 0:])
what = "%s#%s" % (what, at.group(1) if at else seen[what])
mutants.append({"id": k, "rule": rule, "kind": kind, "what": what, "line": no})
arms.append("if mutant(%d) { %s }" % (k, mut))
if kind == "drop":
mutants[-1]["what"] = "the check never fails: `%s`" % expr
return "(" + " else ".join(arms) + " else { %s })" % expr
pushes = following.strip().startswith(("out.push(", "problem("))
m = re.match(r"^(\s*)if let (.+) = (.+) \{$", line)
if m and not pushes and re.search(r"\.(max|min)\(\)", m.group(3)):
# What a check after it reads, found as the most or the least of many.
c = chain(m.group(3))
return "%sif let %s = %s {" % (m.group(1), m.group(2), c) if c else line
if m and pushes:
# A check of what is found, as rule 1's: never found.
k = len(mutants)
mutants.append({"id": k, "rule": rule, "kind": "drop", "what": "the check never fails: `%s`" % m.group(3), "line": no})
return "%sif let %s = (%s).filter(|_| !mutant(%d)) {" % (m.group(1), m.group(2), m.group(3), k)
m = re.match(r"^(\s*)&& (.+)$", line)
if m and following.strip() == "{":
c = chain(m.group(2), [("drop", "the check never fails", "false")])
return "%s&& %s" % (m.group(1), c) if c else line
m = re.match(r"^(\s*)if (?!let )(.+) \{$", line)
if m and pushes and " let " not in m.group(2):
c = chain(m.group(2), [("drop", "the check never fails", "false")])
return "%sif %s {" % (m.group(1), c) if c else line
m = re.match(r"^(\s*)((?:Some\(.*?\)|None)) if (.+?) => (.*)$", line)
if m:
c = chain(m.group(3), [("drop", "the check never fails", "false")])
return "%s%s if %s => %s" % (m.group(1), m.group(2), c, m.group(4)) if c else line
m = re.match(r"^(\s*)match (.+) \{$", line)
if m and ".get(" in m.group(2):
c = chain(m.group(2))
return "%smatch %s {" % (m.group(1), c) if c else line
m = re.match(r"^(\s*)let (mut )?([\w(), ]+?)(: [^=]+)? = (.+);$", line)
if m and not m.group(5).lstrip().startswith(("|", "move |")) and any(x in m.group(5) for x in ("count(", "whole(", ".get(", " > ", " < ", " >= ", " <= ", "Some(")):
c = chain(m.group(5))
return "%slet %s%s%s = %s;" % (m.group(1), m.group(2) or "", m.group(3), m.group(4) or "", c) if c else line
return line
# ------------------------------------------------------------------ running them
def caught(env_extra, reference, second=None):
cmd = [sys.executable, "-I", DIFFERENTIAL, "--reference", reference, "--wasmq-only", "--first"]
if second:
cmd += ["--second", second]
env = dict(os.environ)
env.update(env_extra)
p = subprocess.run(cmd, capture_output=True, text=True, env=env)
first = next((l for l in p.stdout.splitlines() if l.startswith("DISAGREE")), "")
if p.returncode not in (0, 1):
return None, (p.stderr.strip().splitlines() or ["status %d" % p.returncode])[-1]
return p.returncode == 1, first
def report(results):
"""results: (id, rules, kind, what, caught, why). Prints counts per rule; returns the
survivors not listed as equivalent."""
per = defaultdict(lambda: defaultdict(int))
survivors = []
for ident, rules, kind, what, got, why in results:
for r in rules:
per[str(r)]["generated"] += 1
per[str(r)]["caught" if got else "equivalent" if _equivalent(rules, kind, what) else "survived"] += 1
if not got and not _equivalent(rules, kind, what):
survivors.append((ident, rules, kind, what, why))
def key(r):
return (0, int(r)) if r.isdigit() else (1, r)
print("%-10s %9s %7s %10s %8s" % ("rule", "generated", "caught", "equivalent", "survived"))
for r in sorted(per, key=key):
c = per[r]
print("%-10s %9d %7d %10d %8d" % (r, c["generated"], c["caught"], c["equivalent"], c["survived"]))
for s in survivors:
print("SURVIVED %s (rules %s) %s: %s %s" % (s[0], ",".join(map(str, s[1])), s[2], s[3], s[4]))
return survivors
def main():
ap = argparse.ArgumentParser()
ap.add_argument("what", choices=["python", "rust", "rust-schemata"])
ap.add_argument("paths", nargs="*")
ap.add_argument("--reference")
ap.add_argument("--mutants")
ap.add_argument("--jobs", type=int, default=4)
ap.add_argument("--rule", help="only the weakenings of this rule")
ap.add_argument("--list", action="store_true", help="list the weakenings, run none")
a = ap.parse_args()
if a.what == "rust-schemata":
engine_rs, out_json = a.paths
return rust_schemata(engine_rs, out_json)
if a.what == "python" and a.list:
ms = [m for m in python_mutants() if not a.rule or a.rule in map(str, m[1])]
counts = defaultdict(lambda: defaultdict(int))
for ident, rules, what, _ in ms:
print(ident, rules, what)
for r in rules:
counts[str(r)][ident.split()[-1]] += 1
for r in sorted(counts, key=lambda r: (0, int(r)) if r.isdigit() else (1, r)):
print("rule %s: %s" % (r, dict(counts[r])))
print("%d weakenings" % len(ms))
return 0
if not a.reference:
ap.error("--reference is required")
cache = tempfile.mkdtemp(prefix="wasmq-mutants-cache-")
base = {"RD_CACHE": cache}
# The unweakened pair agrees: else nothing below means anything.
ok, why = caught(base, a.reference)
if ok is not False:
print("the unweakened verifiers do not agree, or the differential failed: %s" % why)
return 2
results = []
if a.what == "python":
ms = [m for m in python_mutants() if not a.rule or a.rule in map(str, m[1])]
if a.list:
for ident, rules, what, _ in ms:
print(ident, rules, what)
return 0
tmp = tempfile.mkdtemp(prefix="wasmq-mutants-py-")
def one(m):
ident, rules, what, text = m
path = os.path.join(tmp, "m%s.py" % ident.split()[0])
with open(path, "w", encoding="utf-8") as f:
f.write(text)
got, why = caught(base, a.reference, second=path)
os.remove(path)
return (ident, rules, ident.split()[-1], what, bool(got), why)
with ThreadPoolExecutor(a.jobs) as pool:
for r in pool.map(one, ms):
results.append(r)
print("%s %-8s %s %s" % ("caught " if r[4] else "SURVIVED", r[2], r[0], r[3]), flush=True)
else:
with open(a.mutants, encoding="utf-8") as f:
ms = [m for m in json.load(f) if not a.rule or m["rule"] == a.rule]
def one(m):
env = dict(base, WQ_MUTANT=str(m["id"]))
got, why = caught(env, a.reference)
ident = "R%04d line %d %s" % (m["id"], m["line"], m["kind"])
return (ident, [m["rule"]], m["kind"], m["what"], bool(got), why)
with ThreadPoolExecutor(a.jobs) as pool:
for r in pool.map(one, ms):
results.append(r)
print("%s %-8s %s %s" % ("caught " if r[4] else "SURVIVED", r[2], r[0], r[3]), flush=True)
survivors = report(results)
print("%s: %d weakenings, %d caught, %d survived" % (a.what, len(results), sum(1 for r in results if r[4]), len(survivors)))
return 1 if survivors else 0
if __name__ == "__main__":
sys.exit(main())

View file

@ -0,0 +1,2 @@
# The modules of record, the envelopes and the WebAssembly vectors are compared byte for byte: never converted.
* -text

View file

@ -0,0 +1,27 @@
# wasmQ conformance
Vectors for [`../../extensions/quantum-wasmq.md`](../../extensions/quantum-wasmq.md) §9.
**Provenance.** Generated here by `wai-wasmq`'s `tests/vectors.rs` (`WASMQ_BLESS=1`) from the
reference programs (`wai-wasmq/src/reference.rs`) and modules written as WebAssembly text or
bytes in that file, which also holds every committed file to the bytes it makes. No media.
| path | what |
|---|---|
| `modules/` | the reference modules of record, built on x86_64 Linux by `wai-wasmq/modules/build.sh`, with `modules.json`: their digests and the SHA-256 of every source that made them |
| `envelopes/` | envelopes; `vectors.json` `runs` pins what each gives on every engine and host: status, fault, fuel, the transcript's digest, the result's digest, the receipt's digest and, under the vectors' key (32 bytes of 7), the whole job's digest |
| `envelopes/surface3-decode64.*` | one run in the open: its program, the prior its decoder reads (the code's parity checks) and its sealed job |
| `refuse/` | modules (also as WebAssembly text, where they have one) and envelopes a runner refuses; `vectors.json` `refuse` gives each one's code. There is at least one for every code, and each is one defect away from a module or an envelope that is accepted, which the test that makes them checks |
```sh
cargo run --release --manifest-path wai/wai-wasmq/Cargo.toml --bin wasmq_vectors -- verify wai/quantum-conformance/wasmq
```
prints a line for each vector and a digest of all of them: the same on every host and
every engine that conforms. Under wasm32 it runs with the interpreter alone:
```sh
cargo build --release --target wasm32-wasip2 --manifest-path wai/wai-wasmq/Cargo.toml --no-default-features --bin wasmq_vectors
wasmtime run -W nan-canonicalization=y -W relaxed-simd-deterministic=y --dir wai/quantum-conformance/wasmq::/v \
wai/wai-wasmq/target/wasm32-wasip2/release/wasmq_vectors.wasm verify /v
```

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more