Skip to content

Quantum AI Lab messages

  • Authenticate first (protocol v2). Every Lab connection begins with {"type": "authenticate", "token": "<token>"} and waits for {"type": "authenticated"}; see Authentication. The examples below show the messages that follow the handshake, and the replay tests send the handshake through the real authentication gate before every fixture.
  • Replies are flat {"type": ...} objects. Failures are {"type": "error", "phase": "trainability" | "discovery", "code", "message"} plus job_id, run_id, candidate_id, path or column where they apply.
  • Sync requests (trainability_inspect, trainability_lint, the *_cancel messages, discovery_evaluators, discovery_mutate, discovery_conjecture_schema) answer with one message.
  • Job requests (trainability_start, discovery_evaluate, discovery_audit, discovery_conjecture_test) run in subprocesses and stream. The client chooses the id for trainability and conjecture jobs (job_id); discovery jobs are keyed by run_id and candidate_id. A job always ends with its terminal message, even when cancelled.
  • Closing the WebSocket cancels every job the connection owns.
  • A web build has no kernel; the Lab needs the desktop app (or a kernel you run yourself).

Executes the code once (same trust as execute), finds the parameterized circuit and reports what the Lab can analyze. Optional fields: language, params.

lab_trainability_inspect.request.json
{
"type": "trainability_inspect",
"code": "from qiskit import QuantumCircuit\nfrom qiskit.circuit import ParameterVector\n\nn = params.get(\"n_qubits\", 4)\ntheta = ParameterVector(\"t\", 2 * n)\nqc = QuantumCircuit(n)\nfor q in range(n):\n qc.ry(theta[q], q)\nfor q in range(n - 1):\n qc.cz(q, q + 1)\nfor q in range(n):\n qc.ry(theta[n + q], q)\n",
"language": "python",
"params": {
"n_qubits": 4
}
}
lab_trainability_inspect.responses.json
[
{
"type": "trainability_inspected",
"framework": "qiskit",
"n_qubits": 4,
"parameters": [
"t[0]",
"t[1]",
"t[2]",
"t[3]",
"t[4]",
"t[5]",
"t[6]",
"t[7]"
],
"gate_count": 11,
"param_gates": [
{
"source_index": 0,
"parameter": "t[0]",
"gate": "RY",
"qubits": [
0
]
},
{
"source_index": 1,
"parameter": "t[1]",
"gate": "RY",
"qubits": [
1
]
},
{
"source_index": 2,
"parameter": "t[2]",
"gate": "RY",
"qubits": [
2
]
},
{
"source_index": 3,
"parameter": "t[3]",
"gate": "RY",
"qubits": [
3
]
},
{
"source_index": 7,
"parameter": "t[4]",
"gate": "RY",
"qubits": [
0
]
},
{
"source_index": 8,
"parameter": "t[5]",
"gate": "RY",
"qubits": [
1
]
},
{
"source_index": 9,
"parameter": "t[6]",
"gate": "RY",
"qubits": [
2
]
},
{
"source_index": 10,
"parameter": "t[7]",
"gate": "RY",
"qubits": [
3
]
}
],
"sweepable_params": [
"n_qubits"
],
"observable_declared": null,
"notes": []
}
]

sweepable_params lists the names the code reads through params.get("name") or params["name"], which the scaling study can sweep. param_gates[].source_index is the gate’s position in the framework’s own circuit order.

The editor-time lint: rules TRN001 to TRN007 under a 0.35 s compute budget. observable is optional (the code’s nuclei_observable, else preset:local_z). Rules that need a complete Lie algebra closure are skipped, and named in summary.skipped_rules, if it does not finish in time.

lab_trainability_lint.request.json
{
"type": "trainability_lint",
"code": "from qiskit import QuantumCircuit\nfrom qiskit.circuit import ParameterVector\n\nn = params.get(\"n_qubits\", 4)\ntheta = ParameterVector(\"t\", 2 * n)\nqc = QuantumCircuit(n)\nfor q in range(n):\n qc.ry(theta[q], q)\nfor q in range(n - 1):\n qc.cz(q, q + 1)\nfor q in range(n):\n qc.ry(theta[n + q], q)\n",
"language": "python",
"params": {
"n_qubits": 6
},
"observable": "preset:global_z"
}
lab_trainability_lint.responses.json
[
{
"type": "trainability_lint_result",
"diagnostics": [
{
"code": "TRN001",
"severity": "warning",
"title": "Global cost function",
"message": "<any>",
"citation": {
"label": "Cerezo et al., Nat. Commun. 12, 1791 (2021)",
"url": "https://doi.org/10.1038/s41467-021-21728-w"
},
"line": null,
"source_indices": []
},
{
"code": "TRN003",
"severity": "info",
"title": "Polynomial dynamical Lie algebra",
"message": "<any>",
"citation": {
"label": "Goh et al., arXiv:2308.01432 (2023)",
"url": "https://arxiv.org/abs/2308.01432"
},
"line": null,
"source_indices": []
}
],
"summary": {
"n_qubits": 6,
"n_parameters": 12,
"dla": {
"status": "complete",
"dimension": 42
},
"observable": "Z0*Z1*Z2*Z3*Z4*Z5",
"elapsed_ms": "<any>",
"skipped_rules": [],
"skipped_reason": null,
"trn004": "complete"
}
}
]

A malformed observable answers with an error whose column is the 0-based offset of the problem in the observable text:

lab_trainability_lint_invalid_observable.request.json
{
"type": "trainability_lint",
"code": "from qiskit import QuantumCircuit\nfrom qiskit.circuit import ParameterVector\n\nn = params.get(\"n_qubits\", 4)\ntheta = ParameterVector(\"t\", 2 * n)\nqc = QuantumCircuit(n)\nfor q in range(n):\n qc.ry(theta[q], q)\nfor q in range(n - 1):\n qc.cz(q, q + 1)\nfor q in range(n):\n qc.ry(theta[n + q], q)\n",
"language": "python",
"params": {
"n_qubits": 4
},
"observable": "Z0 Q1"
}
lab_trainability_lint_invalid_observable.responses.json
[
{
"type": "error",
"phase": "trainability",
"code": "invalid_observable",
"message": "<any>",
"column": 3
}
]

See the lint rule table for what each code means.

Starts an analysis job. Required: job_id (client-chosen, at most 128 characters), code, observable (may be empty). Optional: language, params, analyses (a subset of gradients, scaling, lie, expressibility, entanglement, landscape) and settings (clamped; the clamped values come back in provenance.settings).

Stream: trainability_started, trainability_progress (at most about 10 per second, omitted from the fixture), one trainability_partial per finished analysis, then trainability_result with status complete, cancelled or failed, per-analysis results and errors, and the provenance block that powers the Trainability Certificate.

lab/trainability_start.stream.json
{
"request": {
"type": "trainability_start",
"job_id": "docs-job-1",
"code": "from qiskit import QuantumCircuit\nfrom qiskit.circuit import ParameterVector\n\nn = params.get(\"n_qubits\", 4)\ntheta = ParameterVector(\"t\", 2 * n)\nqc = QuantumCircuit(n)\nfor q in range(n):\n qc.ry(theta[q], q)\nfor q in range(n - 1):\n qc.cz(q, q + 1)\nfor q in range(n):\n qc.ry(theta[n + q], q)\n",
"language": "python",
"params": {
"n_qubits": 3
},
"observable": "preset:local_z",
"analyses": [
"gradients",
"lie"
],
"settings": {
"samples": 64,
"seed": 7,
"init": "uniform",
"method": "auto"
}
},
"until": "trainability_result",
"ignore_types": [
"trainability_progress"
],
"responses": [
{
"type": "trainability_started",
"job_id": "docs-job-1"
},
{
"type": "trainability_partial",
"job_id": "docs-job-1",
"analysis": "gradients",
"result": {
"samples": null,
"init": "uniform",
"method": "ppe",
"backend": "<any>",
"interval_kind": "truncation",
"interval": {
"kind": "truncation",
"variance_mean": [
"<approx:0.046296296296296:0.00000462962963>",
"<approx:0.046296296296296:0.00000462962963>"
],
"ppe_method": "pauli_propagation_exact",
"status": "complete",
"frontier_peak": "<any>",
"discarded_mass": "<approx:0:0.000000001>"
},
"per_parameter": [
{
"name": "t[0]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.048611111111111:0.000004861111111>",
"<approx:0.048611111111111:0.000004861111111>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[1]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.0625:0.00000625>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.0625:0.00000625>",
"<approx:0.0625:0.00000625>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[2]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.048611111111111:0.000004861111111>",
"<approx:0.048611111111111:0.000004861111111>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[3]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.041666666666667:0.000004166666667>",
"<approx:0.041666666666667:0.000004166666667>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[4]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.034722222222222:0.000003472222222>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.034722222222222:0.000003472222222>",
"<approx:0.034722222222222:0.000003472222222>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[5]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.041666666666667:0.000004166666667>",
"<approx:0.041666666666667:0.000004166666667>"
],
"dead": false,
"dead_reason": null
}
],
"variance_mean": "<approx:0.046296296296296:0.00000462962963>",
"variance_mean_ci95": [
"<approx:0.046296296296296:0.00000462962963>",
"<approx:0.046296296296296:0.00000462962963>"
],
"gradient_norm_mean": null,
"cost_mean": "<any>",
"cost_variance": "<any>",
"cost_variance_ci95": "<any>",
"gradient_norm_rms": "<approx:0.52704627669473:0.000052704627669>",
"gate_values": [
{
"source_index": 0,
"gate_index": 0,
"parameter": "t[0]",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null
},
{
"source_index": 1,
"gate_index": 1,
"parameter": "t[1]",
"variance": "<approx:0.0625:0.00000625>",
"abs_mean": null
},
{
"source_index": 2,
"gate_index": 2,
"parameter": "t[2]",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null
},
{
"source_index": 5,
"gate_index": 5,
"parameter": "t[3]",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null
},
{
"source_index": 6,
"gate_index": 6,
"parameter": "t[4]",
"variance": "<approx:0.034722222222222:0.000003472222222>",
"abs_mean": null
},
{
"source_index": 7,
"gate_index": 7,
"parameter": "t[5]",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null
}
],
"seed": 7,
"notes": [],
"fallback_reason": null,
"elapsed_ms": "<any>"
}
},
{
"type": "trainability_partial",
"job_id": "docs-job-1",
"analysis": "lie",
"result": {
"status": "complete",
"reason": null,
"n_qubits": 3,
"dimension": 12,
"dimension_lower_bound": 12,
"max_dimension": 4096,
"ideals": "<any>",
"prediction_note": "<any>",
"classification": {
"label": "other",
"family": "other",
"confidence": "none",
"note": "Classification is by exact dimension match, not an isomorphism proof; other algebras can share a dimension."
},
"path": "pauli_strings",
"generators": {
"count": 6,
"unique": 6,
"examples": [
"Y0",
"Y1",
"Y2",
"Y0Z1"
]
},
"fixed_gates": {
"clifford": true,
"handled_by": "clifford_conjugation"
},
"purity": {
"initial_state": "<approx:0:0.000000001>",
"observable": "<approx:0:0.000000001>",
"observable_in_algebra": false,
"state_in_algebra": false
},
"predicted_variance": null,
"prediction_applicable": false,
"prediction_quantity": "cost_variance",
"abelian": false,
"assumptions": [
"Deep-circuit regime: the circuit is an approximate 2-design over e^𝔤 (not guaranteed for shallow circuits).",
"𝔤 = centre (dim 0) ⊕ 2 simple ideal(s) (connected components of the anticommutation graph); the centre is excluded and the ideals' variances add, each ideal assumed Haar-random.",
"The predicted quantity is the variance of the cost C over the group, not of a single gradient component.",
"Initial state |0…0⟩; fixed gates are pushed to the end of the circuit."
],
"simulability": {
"kind": "g_sim_feasible",
"summary": "dim 𝔤 = 12 (≤ 4n² = 36). Expectations are classically simulable in poly(dim 𝔤) time when the observable or the initial state lies in 𝔤 (𝔤-sim, Goh et al. 2023 (arXiv:2308.01432)); a polynomial dimension does not by itself bound the purities or guarantee trainability. Observable in 𝔤: no; initial state in 𝔤: no."
},
"elapsed_ms": "<any>"
}
},
{
"type": "trainability_result",
"job_id": "docs-job-1",
"status": "complete",
"results": {
"gradients": {
"samples": null,
"init": "uniform",
"method": "ppe",
"backend": "<any>",
"interval_kind": "truncation",
"interval": {
"kind": "truncation",
"variance_mean": [
"<approx:0.046296296296296:0.00000462962963>",
"<approx:0.046296296296296:0.00000462962963>"
],
"ppe_method": "pauli_propagation_exact",
"status": "complete",
"frontier_peak": "<any>",
"discarded_mass": "<approx:0:0.000000001>"
},
"per_parameter": [
{
"name": "t[0]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.048611111111111:0.000004861111111>",
"<approx:0.048611111111111:0.000004861111111>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[1]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.0625:0.00000625>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.0625:0.00000625>",
"<approx:0.0625:0.00000625>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[2]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.048611111111111:0.000004861111111>",
"<approx:0.048611111111111:0.000004861111111>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[3]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.041666666666667:0.000004166666667>",
"<approx:0.041666666666667:0.000004166666667>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[4]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.034722222222222:0.000003472222222>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.034722222222222:0.000003472222222>",
"<approx:0.034722222222222:0.000003472222222>"
],
"dead": false,
"dead_reason": null
},
{
"name": "t[5]",
"mean": "<approx:0:0.000000001>",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null,
"variance_ci95": [
"<approx:0.041666666666667:0.000004166666667>",
"<approx:0.041666666666667:0.000004166666667>"
],
"dead": false,
"dead_reason": null
}
],
"variance_mean": "<approx:0.046296296296296:0.00000462962963>",
"variance_mean_ci95": [
"<approx:0.046296296296296:0.00000462962963>",
"<approx:0.046296296296296:0.00000462962963>"
],
"gradient_norm_mean": null,
"cost_mean": "<any>",
"cost_variance": "<any>",
"cost_variance_ci95": "<any>",
"gradient_norm_rms": "<approx:0.52704627669473:0.000052704627669>",
"gate_values": [
{
"source_index": 0,
"gate_index": 0,
"parameter": "t[0]",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null
},
{
"source_index": 1,
"gate_index": 1,
"parameter": "t[1]",
"variance": "<approx:0.0625:0.00000625>",
"abs_mean": null
},
{
"source_index": 2,
"gate_index": 2,
"parameter": "t[2]",
"variance": "<approx:0.048611111111111:0.000004861111111>",
"abs_mean": null
},
{
"source_index": 5,
"gate_index": 5,
"parameter": "t[3]",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null
},
{
"source_index": 6,
"gate_index": 6,
"parameter": "t[4]",
"variance": "<approx:0.034722222222222:0.000003472222222>",
"abs_mean": null
},
{
"source_index": 7,
"gate_index": 7,
"parameter": "t[5]",
"variance": "<approx:0.041666666666667:0.000004166666667>",
"abs_mean": null
}
],
"seed": 7,
"notes": [],
"fallback_reason": null,
"elapsed_ms": "<any>"
},
"lie": {
"status": "complete",
"reason": null,
"n_qubits": 3,
"dimension": 12,
"dimension_lower_bound": 12,
"ideals": "<any>",
"prediction_note": "<any>",
"max_dimension": 4096,
"classification": {
"label": "other",
"family": "other",
"confidence": "none",
"note": "Classification is by exact dimension match, not an isomorphism proof; other algebras can share a dimension."
},
"path": "pauli_strings",
"generators": {
"count": 6,
"unique": 6,
"examples": [
"Y0",
"Y1",
"Y2",
"Y0Z1"
]
},
"fixed_gates": {
"clifford": true,
"handled_by": "clifford_conjugation"
},
"purity": {
"initial_state": "<approx:0:0.000000001>",
"observable": "<approx:0:0.000000001>",
"observable_in_algebra": false,
"state_in_algebra": false
},
"predicted_variance": null,
"prediction_applicable": false,
"prediction_quantity": "cost_variance",
"abelian": false,
"assumptions": [
"Deep-circuit regime: the circuit is an approximate 2-design over e^𝔤 (not guaranteed for shallow circuits).",
"𝔤 = centre (dim 0) ⊕ 2 simple ideal(s) (connected components of the anticommutation graph); the centre is excluded and the ideals' variances add, each ideal assumed Haar-random.",
"The predicted quantity is the variance of the cost C over the group, not of a single gradient component.",
"Initial state |0…0⟩; fixed gates are pushed to the end of the circuit."
],
"simulability": {
"kind": "g_sim_feasible",
"summary": "dim 𝔤 = 12 (≤ 4n² = 36). Expectations are classically simulable in poly(dim 𝔤) time when the observable or the initial state lies in 𝔤 (𝔤-sim, Goh et al. 2023 (arXiv:2308.01432)); a polynomial dimension does not by itself bound the purities or guarantee trainability. Observable in 𝔤: no; initial state in 𝔤: no."
},
"elapsed_ms": "<any>"
}
},
"errors": {},
"elapsed_ms": "<any>",
"provenance": {
"code_sha256": "e0fe018aba5c0bffca76d586a1e5a98df1798ebd451d6817e3cecc73672eafd9",
"observable": "0.3333333333333333*Z0 + 0.3333333333333333*Z1 + 0.3333333333333333*Z2",
"params": {
"n_qubits": 3
},
"settings": {
"samples": 64,
"seed": 7,
"init": "uniform",
"method": "auto",
"backend": "<any>",
"scaling": {
"qubits": [
2,
3,
4,
5,
6
],
"layers": [
4
],
"qubit_param": "n_qubits",
"layer_param": "n_layers"
},
"expressibility": {
"pairs": 2000,
"bins": 75
},
"entanglement": {
"samples": 1000
},
"landscape": {
"resolution": 41,
"span": "<approx:3.141592653589793:0.000314159265359>"
},
"lie": {
"max_dimension": 4096,
"time_budget_s": "<approx:10:0.001>"
}
},
"kernel": "<any>",
"analyses_fingerprint": "<any>",
"backend": "<any>",
"created_at": "<any>"
}
}
]
}

At most 2 jobs run per connection and 4 globally; more answer trainability_busy. Jobs are killed after 20 minutes. A request with no job_id is refused:

lab_trainability_start_invalid.request.json
{
"type": "trainability_start",
"code": "from qiskit import QuantumCircuit\nfrom qiskit.circuit import ParameterVector\n\nn = params.get(\"n_qubits\", 4)\ntheta = ParameterVector(\"t\", 2 * n)\nqc = QuantumCircuit(n)\nfor q in range(n):\n qc.ry(theta[q], q)\nfor q in range(n - 1):\n qc.cz(q, q + 1)\nfor q in range(n):\n qc.ry(theta[n + q], q)\n",
"observable": "preset:local_z",
"analyses": [
"gradients"
]
}
lab_trainability_start_invalid.responses.json
[
{
"type": "error",
"phase": "trainability",
"code": "invalid_request",
"message": "<any>"
}
]

Replies trainability_cancelled with accepted: true when the job was running.

lab_trainability_cancel_unknown.request.json
{
"type": "trainability_cancel",
"job_id": "docs-job-1"
}
lab_trainability_cancel_unknown.responses.json
[
{
"type": "trainability_cancelled",
"job_id": "docs-job-1",
"accepted": false
}
]
CodeMeaning
invalid_requestA field is missing or the wrong type
invalid_observableThe observable does not parse; carries column
compile_errorThe code has a syntax error
unbound_parametersThe circuit still has free symbols the code never binds
ppe_not_applicable, ppe_requiredThe exact Pauli-propagation engine was requested (or needed beyond 20 qubits) but the circuit is outside its class
analysis_unavailable, analysis_failedThe analysis could not run, or raised
out_of_memoryThe analysis exhausted memory
trainability_busyToo many jobs for this connection or kernel

Error codes raised by the circuit converters (for example an unsupported gate) are passed through with their own code.

Lists the registered evaluators. Each entry carries kind, version, title, description, task, entry_signature, objectives, descriptors, a JSON Schema 2020-12 config_schema and a default_config. The fixture below pins the order and the kinds; the other fields are summarized as "<any>".

lab_discovery_evaluators.request.json
{
"type": "discovery_evaluators"
}
lab_discovery_evaluators.responses.json
[
{
"type": "discovery_evaluators_result",
"evaluators": [
{
"kind": "qec_memory",
"version": "<any>",
"title": "QEC memory experiment",
"description": "<any>",
"task": "stim_circuit",
"entry_signature": "<any>",
"objectives": "<any>",
"descriptors": "<any>",
"config_schema": "<any>",
"default_config": "<any>",
"stages": {
"screen": {
"shots": {
"min": 1000,
"max": 5000,
"max_errors": 50
}
},
"full": {},
"confirm": {}
},
"available": true
},
{
"kind": "state_synthesis",
"version": "<any>",
"title": "State preparation",
"description": "<any>",
"task": "quantum_circuit",
"entry_signature": "<any>",
"objectives": "<any>",
"descriptors": "<any>",
"config_schema": "<any>",
"default_config": "<any>",
"stages": {
"screen": {
"optimize_parameters": {
"restarts": 1,
"steps": 60
}
},
"full": {},
"confirm": {}
},
"available": true
},
{
"kind": "trainability_frontier",
"version": "<any>",
"title": "Trainability frontier",
"description": "<any>",
"task": "quantum_circuit",
"entry_signature": "<any>",
"objectives": "<any>",
"descriptors": "<any>",
"config_schema": "<any>",
"default_config": "<any>",
"stages": {
"screen": {
"max_sizes": 2
},
"full": {},
"confirm": {}
},
"available": true
},
{
"kind": "vqe_ground_state",
"version": "<any>",
"title": "Variational ground state",
"description": "<any>",
"task": "quantum_circuit",
"entry_signature": "<any>",
"objectives": "<any>",
"descriptors": "<any>",
"config_schema": "<any>",
"default_config": "<any>",
"stages": {
"screen": {
"training": {
"restarts": 1,
"steps": 50
},
"trainability_prefilter": {
"samples": 32
}
},
"full": {},
"confirm": {}
},
"available": true
}
]
}
]

Kinds: qec_memory, state_synthesis, vqe_ground_state, trainability_frontier.

Every entry also carries available (boolean). The installed app does not ship Stim or PyMatching (they come from the in-app Research catalog), so qec_memory is still listed but reports available: false together with missing (import names, for example ["stim", "pymatching"]) and install ({catalog_ids, hint}, the Research catalog entry ids). discovery_evaluate and discovery_audit for such an evaluator fail fast with {type: "error", phase: "discovery", code: "missing_dependency", message, missing, install}. The other evaluators, conjectures and the whole Trainability Lab need only numpy and the quantum frameworks. Clients on older kernels see no available field and should treat that as available. The fixture above was recorded with the research packages installed, so every entry is available.

Scores one candidate program. Required: run_id, candidate_id, evaluator ({kind, config}), program, seed. Optional: entry (default per evaluator), stage (screen, full, confirm; default full). The reply is discovery_evaluate_accepted with a queue_position, then later one discovery_evaluation carrying the evaluation record.

lab/discovery_evaluate.stream.json
{
"request": {
"type": "discovery_evaluate",
"run_id": "docs-run",
"candidate_id": "c-0001",
"evaluator": {
"kind": "state_synthesis",
"config": {
"target": {
"kind": "ghz",
"n_qubits": 3
}
}
},
"program": "from qiskit import QuantumCircuit\n\n\ndef build(n_qubits):\n qc = QuantumCircuit(n_qubits)\n qc.h(0)\n for q in range(1, n_qubits):\n qc.cx(q - 1, q)\n return qc\n",
"entry": "build",
"seed": 1,
"stage": "full"
},
"until": "discovery_evaluation",
"ignore_types": [],
"responses": [
{
"type": "discovery_evaluate_accepted",
"run_id": "docs-run",
"candidate_id": "c-0001",
"queue_position": 0
},
{
"type": "discovery_evaluation",
"run_id": "docs-run",
"candidate_id": "c-0001",
"evaluation": {
"candidate_id": "c-0001",
"run_id": "docs-run",
"status": "scored",
"fitness": "<approx:9.800000000000001:0.00098>",
"objectives": {
"infidelity": {
"value": "<approx:0:0.000000001>",
"direction": "minimize",
"label": "Infidelity"
},
"cost": {
"value": 2,
"direction": "minimize",
"label": "Cost (two_qubit_gates)"
}
},
"descriptors": {
"two_qubit_gates": 2,
"depth": 3
},
"metrics": {
"fidelity": "<approx:1:0.0001>",
"fidelity_threshold": "<approx:0.999:0.0000999>",
"meets_threshold": true,
"restart_fidelities": [
"<approx:1:0.0001>"
],
"optimized": false,
"n_parameters": 0,
"parameter_names": [],
"best_theta": [],
"n_fixed_nonclifford_angles": 0,
"cost_kind": "two_qubit_gates",
"costs": {
"two_qubit_gates": 2,
"depth": 3,
"t_count": 0
},
"continuous_rotations": 0
},
"guardrails": [
{
"id": "ir_conversion",
"label": "Circuit converts to elementary gates",
"status": "pass",
"detail": null
},
{
"id": "gate_set",
"label": "Only allowed gates",
"status": "pass",
"detail": null
},
{
"id": "qubit_count",
"label": "Exactly 3 qubits",
"status": "pass",
"detail": null
},
{
"id": "no_measurement",
"label": "No measurements",
"status": "pass",
"detail": null
},
{
"id": "parameter_budget",
"label": "At most 128 free parameters",
"status": "pass",
"detail": null
}
],
"rejection": null,
"failure": null,
"stdout": "<any>",
"stderr": "<any>",
"timings_ms": "<any>",
"evaluator": {
"kind": "state_synthesis",
"version": "<any>",
"fingerprint": "<any>"
},
"seed": 1,
"stage": "full",
"program_key": "<any>",
"cache_hit": false,
"isolation": "<any>",
"isolation_detail": "<any>",
"compute": "<any>"
}
}
]
}

The record is always returned, whatever happened: status is scored, rejected (a guardrail failed; see rejection and the guardrails list, in which later guardrails are skipped) or failed (the sandbox or scorer broke; see failure). isolation says how the candidate was contained: sandbox-exec (macOS), bwrap (Linux) or process. cache_hit: true means an in-kernel LRU (512 entries, keyed by program, fingerprint, seed and stage) answered.

Errors: an unknown kind and a config that fails the schema.

lab_discovery_evaluate_unknown_evaluator.request.json
{
"type": "discovery_evaluate",
"run_id": "docs-run",
"candidate_id": "c-0001",
"evaluator": {
"kind": "nope"
},
"program": "from qiskit import QuantumCircuit\n\n\ndef build(n_qubits):\n qc = QuantumCircuit(n_qubits)\n qc.h(0)\n for q in range(1, n_qubits):\n qc.cx(q - 1, q)\n return qc\n",
"seed": 1
}
lab_discovery_evaluate_unknown_evaluator.responses.json
[
{
"type": "error",
"phase": "discovery",
"code": "unknown_evaluator",
"message": "<any>",
"run_id": "docs-run",
"candidate_id": "c-0001"
}
]
lab_discovery_evaluate_invalid_config.request.json
{
"type": "discovery_evaluate",
"run_id": "docs-run",
"candidate_id": "c-0001",
"evaluator": {
"kind": "state_synthesis",
"config": {
"target": {
"kind": "ghz",
"n_qubits": 99
}
}
},
"program": "from qiskit import QuantumCircuit\n\n\ndef build(n_qubits):\n qc = QuantumCircuit(n_qubits)\n qc.h(0)\n for q in range(1, n_qubits):\n qc.cx(q - 1, q)\n return qc\n",
"seed": 1
}
lab_discovery_evaluate_invalid_config.responses.json
[
{
"type": "error",
"phase": "discovery",
"code": "invalid_config",
"message": "<any>",
"run_id": "docs-run",
"candidate_id": "c-0001"
}
]

candidate_id is optional; omit it to cancel everything in a run. cancelled counts jobs. A cancelled job still emits a discovery_evaluation with status failed and code cancelled.

lab_discovery_cancel.request.json
{
"type": "discovery_cancel",
"run_id": "docs-run",
"candidate_id": "c-0001"
}
lab_discovery_cancel.responses.json
[
{
"type": "discovery_cancelled",
"run_id": "docs-run",
"candidate_id": "c-0001",
"cancelled": 0
}
]

The AST baseline mutator. start_marker and end_marker default to # EVOLVE-BLOCK-START and # EVOLVE-BLOCK-END; count is 1 to 64. The same program and seed give the same mutations.

lab_discovery_mutate.request.json
{
"type": "discovery_mutate",
"program": "from qiskit import QuantumCircuit\n\n\ndef build(n_qubits):\n qc = QuantumCircuit(n_qubits)\n qc.h(0)\n for q in range(1, n_qubits):\n qc.cx(q - 1, q)\n return qc\n",
"seed": 7,
"count": 2
}
lab_discovery_mutate.responses.json
[
{
"type": "discovery_mutations",
"mutations": [
{
"program": "<any>",
"operators": [
"duplicate_statement",
"change_index"
],
"description": "<any>"
},
{
"program": "<any>",
"operators": [
"swap_gate_method",
"swap_statements"
],
"description": "<any>"
}
]
}
]
CodeMeaning
invalid_requestA field is missing or malformed
invalid_configThe evaluator config failed validation
unknown_evaluatorNo evaluator of that kind
discovery_busyMore than 64 jobs queued for this connection
mutation_failedThe program could not be mutated (for example it does not parse)
discovery_internalA handler bug; the connection survives

An audit re-scores a candidate’s artifact independently of the evaluator and compares the two (see Red Queen mode).

Required: run_id, candidate_id, evaluator, program, seed and evaluation (the record the evaluator produced, with a valid status). Evaluators without an audit answer audit_unavailable. The reply is discovery_audit_accepted, then discovery_audit_result. audit.verdict is consistent, exploit or inconclusive; gap is evaluator fitness minus audit fitness; every checks[] entry is shown, passed or not.

lab/discovery_audit.stream.json
{
"request": {
"type": "discovery_audit",
"run_id": "docs-run",
"candidate_id": "c-0001",
"evaluator": {
"kind": "state_synthesis",
"config": {
"target": {
"kind": "ghz",
"n_qubits": 3
}
}
},
"program": "from qiskit import QuantumCircuit\n\n\ndef build(n_qubits):\n qc = QuantumCircuit(n_qubits)\n qc.h(0)\n for q in range(1, n_qubits):\n qc.cx(q - 1, q)\n return qc\n",
"entry": "build",
"seed": 1,
"evaluation": {
"candidate_id": "c-0001",
"run_id": "docs-run",
"status": "scored",
"fitness": 9.8,
"objectives": {
"infidelity": {
"value": 4.440892098500626e-16,
"direction": "minimize",
"label": "Infidelity"
},
"cost": {
"value": 2,
"direction": "minimize",
"label": "Cost (two_qubit_gates)"
}
},
"descriptors": {
"two_qubit_gates": 2,
"depth": 3
},
"metrics": {
"fidelity": 0.9999999999999996,
"fidelity_threshold": 0.999,
"meets_threshold": true,
"restart_fidelities": [
0.9999999999999996
],
"optimized": false,
"n_parameters": 0,
"cost_kind": "two_qubit_gates",
"costs": {
"two_qubit_gates": 2,
"depth": 3,
"t_count": 0
},
"continuous_rotations": 0
},
"guardrails": [
{
"id": "ir_conversion",
"label": "Circuit converts to elementary gates",
"status": "pass",
"detail": null
},
{
"id": "gate_set",
"label": "Only allowed gates",
"status": "pass",
"detail": null
},
{
"id": "qubit_count",
"label": "Exactly 3 qubits",
"status": "pass",
"detail": null
},
{
"id": "no_measurement",
"label": "No measurements",
"status": "pass",
"detail": null
},
{
"id": "parameter_budget",
"label": "At most 128 free parameters",
"status": "pass",
"detail": null
}
],
"rejection": null,
"failure": null,
"stdout": "",
"stderr": "",
"timings_ms": {
"sandbox": 22465,
"score": 130,
"total": 22625
},
"evaluator": {
"kind": "state_synthesis",
"version": "1.0.0",
"fingerprint": "a9af94776972173151eb7f461b3ddefe7559ed8ed71513b870ee93921db0ead7"
},
"seed": 1,
"stage": "full",
"program_key": "5a7ae9880af4e0f3a5c2e801795cc45fcf1f321c15cafcbfa2f8ec9bcaca1653",
"cache_hit": false,
"isolation": "sandbox-exec",
"compute": {
"backend": "numpy",
"method": "statevector_sampling"
}
}
},
"until": "discovery_audit_result",
"ignore_types": [],
"responses": [
{
"type": "discovery_audit_accepted",
"run_id": "docs-run",
"candidate_id": "c-0001",
"queue_position": 0
},
{
"type": "discovery_audit_result",
"run_id": "docs-run",
"candidate_id": "c-0001",
"audit": {
"verdict": "consistent",
"evaluator_fitness": "<approx:9.800000000000001:0.00098>",
"audit_fitness": "<approx:9.800000000000001:0.00098>",
"gap": "<approx:0:0.000000001>",
"checks": [
{
"id": "candidate_deterministic",
"label": "Candidate output is identical across fresh sandbox runs",
"status": "pass",
"detail": null
},
{
"id": "ir_valid",
"label": "Fresh IR re-validated",
"status": "pass",
"detail": null
},
{
"id": "no_measurement",
"label": "No measurements",
"status": "pass",
"detail": null
},
{
"id": "qubit_count",
"label": "Exactly 3 qubits",
"status": "pass",
"detail": null
},
{
"id": "oracle_vs_compiler",
"label": "Compiler agrees with the naive oracle",
"status": "pass",
"detail": null
},
{
"id": "fidelity_reproduced",
"label": "Fidelity reproduced by the oracle",
"status": "pass",
"detail": "oracle F=1.000000 via no free parameters; evaluator F=1.000000"
},
{
"id": "cost_decomposition",
"label": "Cost is not below the real compiled CX count",
"status": "pass",
"detail": "canonical 2 >= transpiled CX 2"
},
{
"id": "fitness_reproduced",
"label": "Fitness reproduced",
"status": "pass",
"detail": "gap +0.000000"
}
],
"reasons": [],
"evaluator": {
"kind": "state_synthesis",
"version": "<any>",
"fingerprint": "<any>"
},
"audit_fingerprint": "<any>",
"seed": 1,
"audit_seed": "<any>",
"isolation": "<any>",
"timings_ms": "<any>",
"notes": [
"oracle fidelity 1.000000 (no free parameters)"
]
}
}
]
}
lab_discovery_audit_cancel.request.json
{
"type": "discovery_audit_cancel",
"run_id": "docs-run"
}
lab_discovery_audit_cancel.responses.json
[
{
"type": "discovery_audit_cancelled",
"run_id": "docs-run",
"candidate_id": null,
"cancelled": 0
}
]

Returns what a conjecture may say: the structural features a predicate can filter on, the quantities a prediction can bound, the test-family JSON Schema (families), the predicate grammar and the limits (circuits 5 to 32, points 4 to 8, n up to 128, 60 s per circuit, 600 s total). The app validates every model-proposed conjecture against this reply, so the model cannot propose what the kernel will not run.

lab_discovery_conjecture_schema.request.json
{
"type": "discovery_conjecture_schema"
}
lab_discovery_conjecture_schema.responses.json
[
{
"type": "discovery_conjecture_schema_result",
"features": [
{
"key": "n_qubits",
"type": "integer",
"description": "<any>"
},
{
"key": "n_params",
"type": "integer",
"description": "<any>"
},
{
"key": "parametric_gates",
"type": "integer",
"description": "<any>"
},
{
"key": "params_per_qubit",
"type": "number",
"description": "<any>"
},
{
"key": "two_qubit_gates",
"type": "integer",
"description": "<any>"
},
{
"key": "two_qubit_depth",
"type": "integer",
"description": "<any>"
},
{
"key": "rotation_axes",
"type": "string",
"description": "<any>"
},
{
"key": "entangler",
"type": "string",
"description": "<any>",
"values": [
"cx",
"cy",
"cz",
"iswap",
"swap",
"other",
"mixed",
"none"
]
},
{
"key": "entangler_pattern",
"type": "string",
"description": "<any>",
"values": [
"ladder",
"brick",
"ring",
"all_to_all",
"nearest_neighbor",
"long_range",
"none"
]
},
{
"key": "distinct_bonds",
"type": "integer",
"description": "<any>"
},
{
"key": "connectivity_fraction",
"type": "number",
"description": "<any>"
},
{
"key": "n_layers",
"type": "integer",
"description": "<any>"
},
{
"key": "two_qubit_gates_per_layer",
"type": "number",
"description": "<any>"
},
{
"key": "params_per_layer",
"type": "number",
"description": "<any>"
},
{
"key": "rotation_axis_counts.X",
"type": "integer",
"description": "<any>"
},
{
"key": "rotation_axis_counts.Y",
"type": "integer",
"description": "<any>"
},
{
"key": "rotation_axis_counts.Z",
"type": "integer",
"description": "<any>"
}
],
"quantities": [
{
"name": "beta_upper95",
"ops": [
"<",
"<=",
">",
">="
],
"value_type": "number",
"description": "<any>"
},
{
"name": "verdict",
"ops": [
"==",
"!=",
"in"
],
"value_type": "string",
"description": "<any>"
},
{
"name": "variance_at_max_n",
"ops": [
"<",
"<=",
">",
">="
],
"value_type": "number",
"description": "<any>"
},
{
"name": "log2_dla_dimension",
"ops": [
"<",
"<=",
">",
">="
],
"value_type": "number",
"description": "<any>"
}
],
"families": "<any>",
"predicate": "<any>",
"limits": {
"circuits": [
5,
32
],
"points": [
4,
8
],
"n_max": 128,
"per_circuit_s": "<approx:60:0.006>",
"total_s": "<approx:600:0.06>"
}
}
]

Required: job_id, conjecture, optional seed (0 to 2^31 - 1, default 0). Stream: discovery_conjecture_started, discovery_conjecture_progress (throttled; omitted from the fixture), one discovery_conjecture_evidence per held-out circuit, then discovery_conjecture_result with status complete, cancelled or failed. A complete result carries a verdict (supported, refuted or inconclusive), a tally, the evidence, any counterexamples (each with the IR needed to rebuild the circuit) and a fingerprint of the tester.

The example below is a real run, and it is a refutation: the conjecture claimed that brick-pattern CZ circuits with Y and Z rotations keep beta_upper95 below 0.1 under a local observable; every one of the five held-out circuits violated it. Evidence and counterexample bodies are summarized as "<any>" in the fixture.

lab/discovery_conjecture_test.stream.json
{
"request": {
"type": "discovery_conjecture_test",
"job_id": "docs-cj-1",
"conjecture": {
"id": "cj-docs-1",
"statement": "Brick-pattern CZ circuits with YZ rotations keep the upper 95% bound on beta below 0.1 up to 32 qubits at four layers.",
"feature_predicate": {
"all": [
{
"feature": "entangler_pattern",
"op": "==",
"value": "brick"
},
{
"feature": "n_layers",
"op": "<=",
"value": 4
}
]
},
"prediction": {
"quantity": "beta_upper95",
"op": "<",
"value": 0.1
},
"test_family": {
"family": "layered",
"rotation_axes": [
"Y",
"Z"
],
"entangler": "cz",
"pattern": "brick",
"layers": 4,
"rotations_per_qubit_per_layer": 2,
"observable": "preset:local_z",
"variants": 4
},
"n_range": [
4,
32
],
"circuits": 5,
"points": 4
},
"seed": 11
},
"until": "discovery_conjecture_result",
"ignore_types": [
"discovery_conjecture_progress"
],
"responses": [
{
"type": "discovery_conjecture_started",
"job_id": "docs-cj-1"
},
{
"type": "discovery_conjecture_evidence",
"job_id": "docs-cj-1",
"item": "<any>"
},
{
"type": "discovery_conjecture_evidence",
"job_id": "docs-cj-1",
"item": "<any>"
},
{
"type": "discovery_conjecture_evidence",
"job_id": "docs-cj-1",
"item": "<any>"
},
{
"type": "discovery_conjecture_evidence",
"job_id": "docs-cj-1",
"item": "<any>"
},
{
"type": "discovery_conjecture_evidence",
"job_id": "docs-cj-1",
"item": "<any>"
},
{
"type": "discovery_conjecture_result",
"job_id": "docs-cj-1",
"status": "complete",
"result": {
"conjecture_id": "cj-docs-1",
"verdict": "refuted",
"summary": "Refuted: 5 of 5 held-out circuits tested violate 'beta_upper95 < 0.1'. First counterexample: v4 (see counterexamples).",
"reasons": [],
"partial": false,
"tally": {
"meets": 0,
"violates": 5,
"indeterminate": 0
},
"n_circuits_requested": 5,
"n_circuits_tested": 5,
"n_range": [
4,
32
],
"n_values": [
4,
8,
16,
32
],
"n_max_tested": 32,
"n_max_planned": 32,
"counterexamples": "<any>",
"evidence": "<any>",
"resampling": {
"attempts": 13,
"accepted": 5,
"rejected": 6,
"distinct": "<any>",
"duplicates": "<any>",
"cap": 125
},
"seed": 11,
"timings": "<any>",
"conjecture": {
"id": "cj-docs-1",
"statement": "Brick-pattern CZ circuits with YZ rotations keep the upper 95% bound on beta below 0.1 up to 32 qubits at four layers.",
"feature_predicate": {
"all": [
{
"feature": "entangler_pattern",
"op": "==",
"value": "brick"
},
{
"feature": "n_layers",
"op": "<=",
"value": 4
}
]
},
"prediction": {
"quantity": "beta_upper95",
"op": "<",
"value": "<approx:0.1:0.00001>"
},
"test_family": {
"family": "layered",
"rotation_axes": [
"Y",
"Z"
],
"entangler": "cz",
"pattern": "brick",
"layers": [
4,
4
],
"rotations_per_qubit_per_layer": 2,
"observable": "preset:local_z",
"variants": 4,
"clifford_dressing": "<approx:0:0.000000001>",
"brick_start": "random"
},
"n_range": [
4,
32
],
"circuits": 5,
"points": 4,
"dla_probe_qubits": 4,
"budget": {
"per_circuit_s": "<approx:60:0.006>",
"total_s": "<approx:600:0.06>"
}
},
"fingerprint": "<any>"
}
}
]
}

A malformed conjecture is refused before anything runs, with the path of the first problem:

lab_discovery_conjecture_invalid.request.json
{
"type": "discovery_conjecture_test",
"job_id": "docs-cj-1",
"conjecture": {
"id": "x"
},
"seed": 1
}
lab_discovery_conjecture_invalid.responses.json
[
{
"type": "error",
"phase": "discovery",
"code": "invalid_conjecture",
"message": "<any>",
"job_id": "docs-cj-1",
"path": "statement"
}
]
lab_discovery_conjecture_cancel.request.json
{
"type": "discovery_conjecture_cancel",
"job_id": "docs-cj-1"
}
lab_discovery_conjecture_cancel.responses.json
[
{
"type": "discovery_conjecture_cancelled",
"job_id": "docs-cj-1",
"accepted": false
}
]
CodeMeaning
invalid_conjectureThe conjecture failed validation; path names the field
invalid_requestBad job_id, seed or duplicate job
conjecture_busyToo many tests running
conjecture_internalA handler bug or the worker failed to start