open-standards/wai/wai-quantum/schemas/job-request.v1.json
Transaction Science d3cef1a13e wai-quantum: a receipt seals what the answer must do, the layer that checked it, and what that layer does not show
A job's receipt showed that a result is the one its signer sealed. A verdict
(wai.quantum.verdict/1) already said how far the engine checked a circuit
job's intent, as a level. It now names what did the checking, a job on a
provider's device and a qudit job carry one, and a verifier works a sealed
verdict out again. The contract is quantum-providers §8.9.

The layer. Every check, and the verdict, names its layer and that layer's
limits: exact_simulation, stabilizer, pass_equivalence, reading, certificate,
random_states, agreement, samples, physical_consistency or unchecked
(verdict::LAYERS). The verdict's is the weakest of its checks', and unchecked
where an intent was not decided or none was given. The result's accuracy
class is beside it under executed.accuracy.

More intents. expectation (an observable's exact value on the program's
state), and four of the answer the job returned: outcomes, conserves (weight
or parity), counts (the job's own counts held to a stated distribution, by a
test at a level or within a distance) and agrees (those counts held to the
exact distribution the engine computes of the program). outcomes and
conserves are decided by the program's exact distribution where the run is
the program's own, and on the counts otherwise.

More jobs. provider::read reads an intent before the job is sent and refuses
a sampled one there (J020); provider::seal seals the verdict with the
device's answer. A qudit job takes an intent of its counts. An
energy-landscape job's own sealed word reads as a verdict (verdict::of_job,
which panicked on one: its `verdict` is a word, not an object). A job whose
form holds no intent, or one another host sealed, is signed off
(engine::signoff, wai.quantum.signoff/1, schemas/signoff.v1.json): a job
about that job, sealing its digest, the intent and the verdict together.

Verifying. job::answer_of routes a job that seals a verdict to job::rerun,
and job::verdict and verdict_of_text work it out again too
(verdict::recheck, within the state vector of 22 qubits): `answer` gives the
level, holds, the layer and its limits, the accuracy class, and `again`:
reproduced, partly, host_statement or differs. A verdict that is not of its
own form, names another method or class than the result, another job than a
sign-off holds, or a check decided here otherwise, differs, and the job is
not valid though its seal holds. A sampled check's samples and a proof
another engine version reached are the host's statement, not a difference.
A verdict sealed before layers were named is held to its level and its
checks. A job that asks for no verdict gives the bytes it gave.

Conformance. quantum-conformance/verdicts/: 21 sealed jobs and what a
verifier must say of each, written by hand from §8.9: verdicts that hold, one
that fails, ones no layer decided, ones past what a verifier works out
again, five a host sealed that its job does not bear out, one changed after
its seal, a provider's, a qudit job's, and sign-offs of a wasmQ job and an
energy-landscape job. tests/verdict_conformance.rs holds the kept jobs to the
manifest (natively and under wasm32-wasip2) and makes each again with this
engine. quantum-conformance/intents/ gains twelve cases, and its harness
holds each verdict to its layer, every kind of intent and every layer a
circuit job's verdict can stand on. wai-quantum-verdict.yml runs the new set
and requires the new tests by name.

What moves with it: the answer set's stored seal is over a verdict, so it is
written again (WAI_ANSWER_BUNDLE_WRITE=1); wai-web's pinned course check
holds each case's verdict, so its digest moves, and the page gains
QuantumEngine.signoff and a wasm test (wai-web-wasm.yml counts 24);
schema::FILES gains signoff.v1.json (acknowledged in the changes entry);
the qudit referee reads `intent` as a member of a request.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
2026-11-11 11:01:31 -05:00

604 lines
21 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://git.transaction.science/Transaction-Science/open-standards/raw/branch/main/wai/wai-quantum/schemas/job-request.v1.json",
"title": "wai.quantum.job-request/1",
"description": "A job as a client submits it: a program and what is asked of it, or a set: many programs (programs), or one over a grid of its inputs (sweep), run as one job. The command line, both MCP servers, the job service, the desktop app and the Studio read it alike, and a receipt seals it as it was given. A member the engine does not read is ignored, and sealed with the rest.",
"type": "object",
"anyOf": [
{
"required": [
"qasm"
]
},
{
"required": [
"programs"
]
},
{
"required": [
"source"
]
}
],
"properties": {
"qasm": {
"type": "string",
"description": "The program, in OpenQASM 3 or the OpenQASM 2 forms in common use."
},
"source": {
"type": "object",
"required": [
"format"
],
"description": "The program in another format, in place of qasm (engine::formats::expand): read to the job's qasm before the job is read, the request keeping its source.",
"properties": {
"format": {
"enum": [
"qasm",
"qir",
"jeff"
]
},
"program": {
"type": "string",
"description": "The program's text (OpenQASM, QIR)."
},
"program_base64": {
"type": "string",
"description": "The program's bytes as base64 (jeff)."
}
}
},
"shots": {
"type": "integer",
"minimum": 0,
"maximum": 1000000,
"description": "Measurement shots; 1024 when no observables or amplitudes are asked for, otherwise 0."
},
"seed": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "The sampling seed (1 when not given): the same job and seed give the same counts."
},
"method": {
"type": "string",
"description": "auto (the default: the strongest method the program admits), or a method by its name as the methods list names it; pulse runs a pulse program (OpenPulse calibrations) under the pulse options."
},
"observables": {
"type": "array",
"maxItems": 256,
"description": "Pauli observables to take the expectation values of.",
"items": {
"anyOf": [
{
"type": "string",
"description": "A Pauli string, as \"Z0 Z1\"; qubits count from 0."
},
{
"type": "object",
"required": [
"pauli"
],
"properties": {
"pauli": {
"type": "string",
"description": "A Pauli string, as \"X3\"."
},
"coeff": {
"type": "number",
"description": "Its coefficient (1 when not given)."
}
}
}
]
}
},
"amplitudes": {
"type": "array",
"maxItems": 64,
"description": "Basis states whose amplitudes to return: one 0 or 1 per qubit, qubit n-1 first.",
"items": {
"type": "string"
}
},
"noise": {
"type": "object",
"description": "A noise model, each channel a probability. A channel not listed here is refused.",
"additionalProperties": false,
"properties": {
"depolarizing_1q": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"depolarizing_2q": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"amplitude_damping": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"dephasing": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"readout": {
"type": "number",
"minimum": 0,
"maximum": 1
}
}
},
"options": {
"type": "object",
"description": "Options of the method that runs the job, as the methods list names them (max_bond, cutoff, fusion, trajectories, threshold, max_weight, ladder, max_terms, path_restarts, controls), and memory_gb.",
"additionalProperties": true,
"properties": {
"controls": {
"enum": ["whole", "standard"],
"description": "A gate whose standard gates would double (x, y, z or h under three or more controls; s, sdg, t, tdg, p, rx, ry, rz, u, sx or sxdg under two or more) runs as one on statevector and in standard gates on exact. \"standard\" runs standard gates on statevector too, which reproduces a result made that way bit for bit. \"whole\" holds the gate whole on exact too, which gives other bits than its default, and is refused (J003) on a job that runs standard gates: another method named, a compile, noise, mitigation, a device target or a named place on the fabric. Any other value is refused."
}
}
},
"compile": {
"$ref": "compile-result.v1.json#/$defs/options"
},
"intent": {
"description": "What the program must do, checked with the run: one intent or a list. The result's verdict says how far it was checked.",
"anyOf": [
{
"$ref": "#/$defs/intent"
},
{
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/$defs/intent"
}
}
]
},
"verdict": {
"type": "boolean",
"description": "true: the result carries a verdict even with no intent."
},
"target": {
"description": "A device target: a built-in target's name, or a target document. The program is compiled to it, placed and simulated under its noise; noise may not be given beside it.",
"anyOf": [
{
"type": "string"
},
{
"$ref": "target.v1.json"
}
]
},
"fabric": {
"description": "Where the statevector method's state runs: auto (the default: on a member only where the committed measurements show it faster than this host's CPU for the job's size and fusion width, otherwise on the CPU), cpu, accelerator (the first accelerator member certified bit-exact here that holds the state, falling back to the next if it fails during the run), a member's id or key (wai-quantum fabric lists them), or a list of members, a power of two of them, the state split by its top qubits into one partition on each (cpu is a member, and a member may be named more than once). A member certified bit-exact gives the CPU's bits. A placement this host cannot honour is refused (J013), never made elsewhere.",
"anyOf": [
{
"type": "string",
"minLength": 1
},
{
"type": "array",
"minItems": 2,
"maxItems": 64,
"items": {
"type": "string",
"minLength": 1
}
}
]
},
"repair": {
"description": "Repair the program first on its flagged lines: true, or the choices.",
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"properties": {
"max_iterations": {
"type": "integer",
"minimum": 1
},
"dyadic_bits": {
"type": "integer",
"minimum": 1,
"maximum": 32
},
"sizes": {
"type": "object",
"additionalProperties": {
"type": "integer",
"minimum": 1
}
}
}
}
]
},
"history": {
"type": "object",
"description": "The program's history's account of the version the job runs: its digest, and the gates and lines in each hand. The receipt binds it; a history recomputes and checks it."
},
"provider": {
"type": "string",
"description": "The person's own provider to run on, by the name their registry gives it. Only a host that holds their credentials runs such a job; every other host refuses it."
},
"programs": {
"type": "array",
"minItems": 1,
"items": {
"anyOf": [
{
"type": "string",
"description": "A program's text."
},
{
"type": "object",
"required": [
"qasm"
],
"description": "A job of its own, read as a job request is (no programs or sweep in it); each item of the set's result holds its request in full."
}
]
},
"description": "A set (engine::sets): the programs to run as one job, each a program's text or a job of its own; the request's other fields apply to every item that does not set them itself."
},
"sweep": {
"type": "object",
"additionalProperties": {
"type": "array",
"minItems": 1,
"items": {
"type": "number"
}
},
"description": "A set over the request's own qasm: values for each of the program's inputs (integer, float or angle), every combination run, the names in sorted order and the first varying slowest."
},
"params": {
"type": "object",
"additionalProperties": {
"type": "number"
},
"description": "A value for each of the program's parameters (`input float theta;`, `input angle phi;`), bound exactly before the program is read: it runs as if each were written as a `const` at that double. A parameter left without a value is refused (Q114, J050). In a sweep, the parameters it fixes, each bound at every point."
},
"dry_run": {
"type": "boolean",
"description": "With true: what the host would do with the job or set, running nothing."
},
"mitigate": {
"description": "Mitigate the job's expectation values (or, for readout, its counts) under its noise (engine::mitigate): zne, pea, pec, cdr, vd or readout, or {\"method\", …} with its options. The result's mitigation gives each value raw and mitigated.",
"anyOf": [
{
"enum": [
"zne",
"pea",
"pec",
"cdr",
"vd",
"readout"
]
},
{
"type": "object",
"required": [
"method"
]
}
]
},
"pulse": {
"type": "object",
"description": "A pulse run's options (method \"pulse\"): the sample period, the levels kept, the tolerance on the stated error, the steps a sample is divided into, each qubit's parameters, static couplings, and ports beyond the names d0, m0, a0.",
"additionalProperties": false,
"properties": {
"dt_ns": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000,
"description": "The sample period, ns (default 0.5)."
},
"levels": {
"type": "integer",
"enum": [
2,
3
],
"description": "Levels kept per qubit (default 2; 3 shows leakage)."
},
"tolerance": {
"type": "number",
"exclusiveMinimum": 0,
"exclusiveMaximum": 1,
"description": "The most the stated error may be (default 1e-6): a run whose bound and rounding estimate pass it is refused, naming the steps that would meet it."
},
"substeps": {
"type": "integer",
"minimum": 1,
"maximum": 4096,
"description": "Steps per sample (default: chosen so each step times the generator's norm is at most 0.5)."
},
"qubits": {
"type": "object",
"description": "Each qubit's parameters by its index, over the target's and the defaults.",
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"properties": {
"frequency_ghz": {
"type": "number",
"description": "Its frequency, GHz."
},
"rabi_mhz": {
"type": "number",
"description": "Its Rabi frequency at full amplitude, MHz."
},
"anharmonicity_mhz": {
"type": "number",
"description": "Its anharmonicity, MHz."
},
"t1_us": {
"type": "number",
"description": "Its relaxation time, µs."
},
"t2_us": {
"type": "number",
"description": "Its coherence time, µs (at most 2·T1)."
}
}
}
},
"couplings": {
"type": "array",
"description": "Static ZZ couplings.",
"items": {
"type": "object",
"required": [
"qubits",
"zz_khz"
],
"additionalProperties": false,
"properties": {
"qubits": {
"type": "array",
"items": {
"type": "integer",
"minimum": 0
},
"minItems": 2,
"maxItems": 2
},
"zz_khz": {
"type": "number",
"description": "The coupling's rate, kHz."
}
}
}
},
"ports": {
"type": "object",
"description": "Ports by name: what each is for and the qubit it reaches.",
"additionalProperties": {
"type": "object",
"required": [
"kind",
"qubit"
],
"additionalProperties": false,
"properties": {
"kind": {
"enum": [
"drive",
"measure",
"acquire"
]
},
"qubit": {
"type": "integer",
"minimum": 0
}
}
}
}
}
},
"contract": {
"description": "What the job wants of an answer (wai/extensions/quantum-providers.md section 8.7). Every route the host can see is priced with what is really known, those that cannot meet this are rejected, the cheapest of the rest runs, and the reasoning is sealed in the result as `planner`. Nothing falls back in silence, and a job no route can meet is refused (J071). A job without it plans as it always has, byte for byte. Refused on a set (J073).",
"type": [
"object",
"null"
],
"additionalProperties": false,
"properties": {
"exactness": {
"description": "The class wanted. Without it, the job keeps the class auto would give: auto's pick stands while it meets the rest of the contract, and only a route at least as exact may take its place. A device's counts are in no classical class: measured wants a processor's, simulated a provider's simulator's that its provider does not state is approximate, and any takes every route.",
"enum": [
"bit-exact",
"exact",
"single",
"bounded",
"estimate",
"heuristic",
"measured",
"simulated",
"any",
null
]
},
"max_cost": {
"description": "The most a provider's estimate of the run may come to, before it runs: it bounds the estimate, not the charge, which is stated after the run beside it (kept.cost). A route with an unknown cost, an estimate that is only the least it can come to, or a price in another currency does not meet it: nothing is converted.",
"type": [
"object",
"null"
],
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "An amount in decimals: digits, and optionally a point and digits, at most 64 characters.",
"maxLength": 64
},
"currency": {
"type": "string",
"minLength": 1
}
}
},
"deadline_seconds": {
"description": "When it must be done by, in seconds from when it starts. A route whose time is not known does not meet it. A host that can stop a run stops it there (J074); otherwise the result says whether it was kept.",
"type": [
"number",
"null"
],
"exclusiveMinimum": 0
},
"max_joules": {
"description": "The most energy it may take, held by a live reading while it runs: at the ceiling the run is stopped, gives no answer, and its receipt says so. A route nothing here can read and stop does not meet it, so on a host that reads none every route is rejected. An estimate can refuse a job clearly past it, and promises nothing.",
"type": [
"number",
"null"
],
"exclusiveMinimum": 0
},
"providers": {
"description": "Whether a route may be one of the person's providers. never is the default, given or not: a job that names a provider under a contract that does not allow one is refused (J070), and a host asks no provider anything under it. A host that reaches none (the job service) lists none. A provider that costs money is chosen only under max_cost, or when the job names it, and still runs only on the person's word for that route and its estimate.",
"enum": [
"never",
"allowed",
null
]
}
}
}
},
"$defs": {
"intent": {
"type": "object",
"description": "One of distribution, equivalent, prepares, sampled, expectation, outcomes, conserves, counts or agrees, with its options.",
"properties": {
"expectation": {
"type": "object",
"description": "An observable's exact value on the program's state, held to the value within the tolerance.",
"required": [
"observable",
"value"
],
"properties": {
"observable": {
"description": "A Pauli string, as \"Z0 Z1\" or {\"pauli\", \"coeff\"}."
},
"value": {
"type": "number"
}
}
},
"outcomes": {
"type": "array",
"description": "The outcomes the answer may be: by the program's exact distribution where the run is the program's own, otherwise on the counts the job returned.",
"minItems": 1,
"maxItems": 4096,
"items": {
"type": "string"
}
},
"conserves": {
"type": "object",
"description": "A quantity every outcome keeps: weight, the sum of its digits, or parity, that sum modulo 2 (a qudit job's: modulo its dimension).",
"minProperties": 1,
"maxProperties": 1,
"properties": {
"weight": {
"type": "integer",
"minimum": 0
},
"parity": {
"type": "integer",
"minimum": 0
}
}
},
"counts": {
"type": "object",
"description": "The job's own counts held to this distribution: by test and alpha, or within tolerance in total variation distance.",
"additionalProperties": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"agrees": {
"const": "simulation",
"description": "The job's own counts held to the exact distribution the engine computes of the program: by test and alpha, or within tolerance in total variation distance."
},
"distribution": {
"type": "object",
"additionalProperties": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"tolerance": {
"type": "number",
"minimum": 0
},
"equivalent": {
"type": "string"
},
"prepares": {
"type": "string"
},
"sampled": {
"type": "object",
"additionalProperties": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"test": {
"enum": [
"chi_squared",
"g_test"
]
},
"alpha": {
"type": "number",
"exclusiveMinimum": 0,
"exclusiveMaximum": 1
},
"shots": {
"type": "integer",
"minimum": 1
},
"seed": {
"type": "integer",
"minimum": 0
},
"require": {
"const": "proof"
},
"note": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}