From 891f1b65055ca1d1fef67cc9f5cc95a965118b02 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 21:30:13 +0530 Subject: [PATCH 01/37] fix: validate QEC resource estimator inputs --- backend/qec/resource.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/backend/qec/resource.py b/backend/qec/resource.py index a63f1d9..e499b06 100644 --- a/backend/qec/resource.py +++ b/backend/qec/resource.py @@ -28,13 +28,27 @@ _A = 0.1 # pre-factor — empirically calibrated for surface codes +def _validate_probability(value: float, name: str, *, allow_zero: bool = True) -> None: + lower_ok = value >= 0 if allow_zero else value > 0 + if not isinstance(value, (int, float)) or not math.isfinite(value) or not lower_ok or value > 1: + lower = "0" if allow_zero else "greater than 0" + raise ValueError(f"{name} must be {lower} and at most 1") + + def logical_error_rate(p: float, d: int) -> float: - """p_L ≈ A * (p / p_th)^((d+1)/2)""" + """Approximate p_L; validates probabilities and odd code distance.""" + _validate_probability(p, "p") + if not isinstance(d, int) or d < 3 or d % 2 == 0: + raise ValueError("d must be an odd integer >= 3") + if p == 0: + return 0.0 return _A * (p / _P_TH) ** ((d + 1) / 2) def min_distance(p: float, p_L_per_gate: float) -> int: - """Smallest odd d >= 3 such that p_L(p, d) < p_L_per_gate.""" + """Smallest odd d >= 3 meeting the target, or 61 if the cap is exceeded.""" + _validate_probability(p, "p") + _validate_probability(p_L_per_gate, "p_L_per_gate", allow_zero=False) for d in range(3, 61, 2): if logical_error_rate(p, d) < p_L_per_gate: return d @@ -68,6 +82,13 @@ def estimate( feasible : bool — True if total < 10 million references : {label: qubit_count} dict of published estimates """ + _validate_probability(p_physical, "p_physical") + if not isinstance(n_logical, int) or n_logical < 1: + raise ValueError("n_logical must be a positive integer") + if not isinstance(t_gates, int) or t_gates < 1: + raise ValueError("t_gates must be a positive integer") + _validate_probability(p_total_failure, "p_total_failure", allow_zero=False) + # Target per-gate failure budget p_L_per_gate = p_total_failure / t_gates From a0a25361c362b0f980c719a41eae918f77286ae0 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 21:30:15 +0530 Subject: [PATCH 02/37] security: restrict QEC API CORS origins --- backend/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/server.py b/backend/server.py index c2583ef..54231b7 100644 --- a/backend/server.py +++ b/backend/server.py @@ -1,4 +1,4 @@ -from fastapi import FastAPI, Query +import os\n\nfrom fastapi import FastAPI, Query from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel, Field From cb482983f78d5ecf47cbe11704bd7c9acd6a405a Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 21:30:19 +0530 Subject: [PATCH 03/37] docs: document local API origin policy and estimate limits --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9976314..60e26e5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ![Stim](https://img.shields.io/badge/Stim-1.16-purple) ![PyMatching v2](https://img.shields.io/badge/PyMatching-v2-green) -This is the second half of a two-project arc. The first half - [Quantum Collapse](https://github.com/Pyhroff/quantum-collapse) - simulates what happens when a cryptographically relevant quantum computer breaks RSA: cascading infrastructure failure across banks, CAs, cloud providers, and government systems. It's the "what breaks" story. +This is an educational simulator, not a validated forecast of quantum hardware capabilities or a cryptographic break-time prediction. Resource estimates are assumption-sensitive; cite the source papers and report model assumptions when interpreting them.\n\nThis is the second half of a two-project arc. The first half - [Quantum Collapse](https://github.com/Pyhroff/quantum-collapse) - simulates what happens when a cryptographically relevant quantum computer breaks RSA: cascading infrastructure failure across banks, CAs, cloud providers, and government systems. It's the "what breaks" story. Quantum OS is the "how and when" story. It simulates the fault-tolerant quantum computer that would actually do that: a surface code engine running real MWPM decoding, lattice surgery primitives, and a physical resource estimator grounded in current literature. The gap between "cryptographically relevant QC" and today's hardware is mostly an error correction problem, and this is what that problem looks like under the hood. @@ -40,7 +40,7 @@ pip install -r requirements.txt uvicorn server:app --port 8001 --reload ``` -Then open `frontend/index.html` directly in a browser. No build step, no bundler, just a file open. The page connects to `http://localhost:8001`. +In a second terminal from the repository root, run `python -m http.server 8080`, then open `http://localhost:8080/frontend/`. The UI connects to `http://localhost:8001`. The API allows these local origins by default; set `QEC_LAB_ALLOWED_ORIGINS` to a comma-separated origin allowlist for a different local setup. Do not expose the development server to untrusted networks. If you just want to see some numbers without the UI: From b8ffa982077d3d57288e2ee7aedd07c76cfc04c9 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 21:30:25 +0530 Subject: [PATCH 04/37] test: cover QEC lattice and resource invariants --- backend/tests/test_core.py | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 backend/tests/test_core.py diff --git a/backend/tests/test_core.py b/backend/tests/test_core.py new file mode 100644 index 0000000..5ab5046 --- /dev/null +++ b/backend/tests/test_core.py @@ -0,0 +1,61 @@ +"""Fast, deterministic regression tests for QEC Lab's core model.""" + +import pytest + +from qec import estimate, make_lattice, run_shot +from qec.resource import logical_error_rate, min_distance + + +@pytest.mark.parametrize("distance", [3, 5, 7, 9]) +def test_rotated_surface_code_stabilizer_count(distance): + lattice = make_lattice(distance) + assert lattice["n_data"] == distance**2 + assert lattice["n_stabs"] == distance**2 - 1 + assert len(lattice["logical_x"]) == distance + assert len(lattice["logical_z"]) == distance + + +def test_seeded_zero_noise_shot_is_reproducible_and_clean(): + first = run_shot(d=3, p=0.0, seed=1234) + second = run_shot(d=3, p=0.0, seed=1234) + assert first == second + assert first["errors_x"] == [] + assert first["errors_z"] == [] + assert first["logical_error"] is False + + +def test_logical_error_rate_handles_zero_noise(): + assert logical_error_rate(0.0, 3) == 0.0 + + +@pytest.mark.parametrize( + "p,d", + [(-0.1, 3), (1.1, 3), (0.01, 2), (0.01, 4)], +) +def test_logical_error_rate_rejects_invalid_inputs(p, d): + with pytest.raises(ValueError): + logical_error_rate(p, d) + + +def test_min_distance_rejects_invalid_target(): + with pytest.raises(ValueError): + min_distance(0.001, 0.0) + + +def test_resource_estimator_rejects_invalid_inputs(): + for kwargs in ( + {"p_physical": -0.1}, + {"p_physical": 0.001, "n_logical": 0}, + {"p_physical": 0.001, "t_gates": 0}, + {"p_physical": 0.001, "p_total_failure": 0.0}, + ): + with pytest.raises(ValueError): + estimate(**kwargs) + + +def test_resource_estimate_is_explicit_and_nonnegative(): + result = estimate(p_physical=0.001, n_logical=100, t_gates=1_000_000) + assert result["d"] >= 3 + assert result["d"] % 2 == 1 + assert result["total_physical"] == result["n_logical"] * result["phys_per_logical"] + assert result["total_physical"] > 0 From 8506ce4af866e2b2d9b97949faf1bb0516ead586 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 21:30:30 +0530 Subject: [PATCH 05/37] ci: add deterministic QEC regression tests --- .github/workflows/ci.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..53aef56 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + +permissions: + contents: read + +jobs: + tests: + name: QEC model tests (Python 3.11) + runs-on: ubuntu-latest + defaults: + run: + working-directory: backend + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: "3.11" + - name: Install backend and test dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -r requirements.txt pytest + - name: Run regression tests + run: python -m pytest -q tests + - name: Compile Python sources + run: python -m compileall -q . + From c555a7526f99bb535cd1fb8f6bdc4cf18120f001 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 21:30:35 +0530 Subject: [PATCH 06/37] fix: validate estimator numeric inputs safely --- backend/qec/resource.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/qec/resource.py b/backend/qec/resource.py index e499b06..6ad2268 100644 --- a/backend/qec/resource.py +++ b/backend/qec/resource.py @@ -29,8 +29,10 @@ def _validate_probability(value: float, name: str, *, allow_zero: bool = True) -> None: + if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value): + raise ValueError(f"{name} must be a finite number") lower_ok = value >= 0 if allow_zero else value > 0 - if not isinstance(value, (int, float)) or not math.isfinite(value) or not lower_ok or value > 1: + if not lower_ok or value > 1: lower = "0" if allow_zero else "greater than 0" raise ValueError(f"{name} must be {lower} and at most 1") From a7d5d9b52a866cf02f063d7e8475f6af4f84562b Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 21:48:16 +0530 Subject: [PATCH 07/37] fix: correct server imports and restrict CORS origins --- backend/server.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/backend/server.py b/backend/server.py index 54231b7..83bc166 100644 --- a/backend/server.py +++ b/backend/server.py @@ -1,4 +1,6 @@ -import os\n\nfrom fastapi import FastAPI, Query +import os + +from fastapi import FastAPI, Query from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel, Field @@ -13,11 +15,20 @@ app = FastAPI(title="QEC Lab API") +_allowed_origins = [ + origin.strip() + for origin in os.getenv( + "QEC_LAB_ALLOWED_ORIGINS", + "http://localhost:8080,http://127.0.0.1:8080", + ).split(",") + if origin.strip() +] + app.add_middleware( CORSMiddleware, - allow_origins=["*"], - allow_methods=["*"], - allow_headers=["*"], + allow_origins=_allowed_origins, + allow_methods=["GET", "POST"], + allow_headers=["Content-Type"], ) From 176e8653519e00f92f406029a30a326290bdd87c Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 22:36:15 +0530 Subject: [PATCH 08/37] fix: reject boolean resource estimator counts --- backend/qec/resource.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/qec/resource.py b/backend/qec/resource.py index 6ad2268..3bb39bf 100644 --- a/backend/qec/resource.py +++ b/backend/qec/resource.py @@ -85,9 +85,9 @@ def estimate( references : {label: qubit_count} dict of published estimates """ _validate_probability(p_physical, "p_physical") - if not isinstance(n_logical, int) or n_logical < 1: + if isinstance(n_logical, bool) or not isinstance(n_logical, int) or n_logical < 1: raise ValueError("n_logical must be a positive integer") - if not isinstance(t_gates, int) or t_gates < 1: + if isinstance(t_gates, bool) or not isinstance(t_gates, int) or t_gates < 1: raise ValueError("t_gates must be a positive integer") _validate_probability(p_total_failure, "p_total_failure", allow_zero=False) From deea5b028bd33f3e6dc887bd93467d0fcfe174fe Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 22:36:18 +0530 Subject: [PATCH 09/37] test: expand QEC reproducibility and model invariants --- backend/tests/test_core.py | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/backend/tests/test_core.py b/backend/tests/test_core.py index 5ab5046..e8914ee 100644 --- a/backend/tests/test_core.py +++ b/backend/tests/test_core.py @@ -59,3 +59,45 @@ def test_resource_estimate_is_explicit_and_nonnegative(): assert result["d"] % 2 == 1 assert result["total_physical"] == result["n_logical"] * result["phys_per_logical"] assert result["total_physical"] > 0 + + + +def test_seeded_noisy_shot_is_reproducible(): + first = run_shot(d=3, p=0.03, seed=9876) + second = run_shot(d=3, p=0.03, seed=9876) + assert first == second + + +def test_surface_code_error_model_is_monotonic_below_threshold(): + low_noise = logical_error_rate(0.001, 3) + higher_noise = logical_error_rate(0.002, 3) + larger_distance = logical_error_rate(0.001, 5) + assert 0 <= larger_distance < low_noise < higher_noise + + +def test_required_distance_does_not_increase_when_noise_decreases(): + noisier = min_distance(0.001, 1e-6) + cleaner = min_distance(0.0005, 1e-6) + assert cleaner <= noisier + assert cleaner >= 3 and cleaner % 2 == 1 + assert noisier >= 3 and noisier % 2 == 1 + + +def test_resource_estimator_rejects_boolean_counts(): + with pytest.raises(ValueError): + estimate(p_physical=0.001, n_logical=True) + with pytest.raises(ValueError): + estimate(p_physical=0.001, t_gates=True) + + +def test_api_cors_has_explicit_local_allowlist(): + from server import app + + cors = next(m for m in app.user_middleware if m.cls.__name__ == "CORSMiddleware") + assert cors.kwargs["allow_origins"] == [ + "http://localhost:8080", + "http://127.0.0.1:8080", + ] + assert cors.kwargs["allow_methods"] == ["GET", "POST"] + assert cors.kwargs["allow_headers"] == ["Content-Type"] + assert "*" not in cors.kwargs["allow_origins"] From f5afe52d608e408ce036ad93cad89bdeb41b4d79 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 22:36:20 +0530 Subject: [PATCH 10/37] docs: clarify QEC model validation and reproducibility limits --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 60e26e5..0895c7b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ ![Stim](https://img.shields.io/badge/Stim-1.16-purple) ![PyMatching v2](https://img.shields.io/badge/PyMatching-v2-green) -This is an educational simulator, not a validated forecast of quantum hardware capabilities or a cryptographic break-time prediction. Resource estimates are assumption-sensitive; cite the source papers and report model assumptions when interpreting them.\n\nThis is the second half of a two-project arc. The first half - [Quantum Collapse](https://github.com/Pyhroff/quantum-collapse) - simulates what happens when a cryptographically relevant quantum computer breaks RSA: cascading infrastructure failure across banks, CAs, cloud providers, and government systems. It's the "what breaks" story. +This is an educational simulator, not a validated forecast of quantum hardware capabilities or a cryptographic break-time prediction. Resource estimates are assumption-sensitive; cite the source papers and report model assumptions when interpreting them. + +This is the second half of a two-project arc. The first half - [Quantum Collapse](https://github.com/Pyhroff/quantum-collapse) - simulates what happens when a cryptographically relevant quantum computer breaks RSA: cascading infrastructure failure across banks, CAs, cloud providers, and government systems. It's the "what breaks" story. Quantum OS is the "how and when" story. It simulates the fault-tolerant quantum computer that would actually do that: a surface code engine running real MWPM decoding, lattice surgery primitives, and a physical resource estimator grounded in current literature. The gap between "cryptographically relevant QC" and today's hardware is mostly an error correction problem, and this is what that problem looks like under the hood. @@ -112,3 +114,10 @@ Phenomenological noise is the middle ground: data errors plus measurement flip p --- MIT license. + + +## Validation and scientific limitations + +CI checks deterministic invariants for surface-code geometry, seeded noisy-shot reproducibility, probability and resource-input validation, monotonic behavior of the simplified logical-error approximation below its configured threshold, and explicit local CORS policy. These tests establish implementation consistency, not empirical calibration against a hardware backend. + +The resource estimator is a simplified analytical model. Its outputs depend on assumptions such as the logical-error approximation, threshold, prefactor, code distance cap, algorithmic gate counts, and accepted total failure budget. Treat the result as a reproducible scenario estimate—not a benchmark of a specific quantum processor or a guarantee that RSA-2048 factoring is feasible. When comparing runs, record all inputs and the code revision; published resource estimates can differ substantially because their architectures and arithmetic assumptions differ. From 006714d2dfe36b2e56ac28eae47658557df7cbf7 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:14:44 +0530 Subject: [PATCH 11/37] feat: add reproducible QEC resource parameter sweep --- backend/qec/resource_sweep.py | 134 ++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 backend/qec/resource_sweep.py diff --git a/backend/qec/resource_sweep.py b/backend/qec/resource_sweep.py new file mode 100644 index 0000000..ef2c6a2 --- /dev/null +++ b/backend/qec/resource_sweep.py @@ -0,0 +1,134 @@ +"""Reproducible parameter sweep for the simplified RSA-2048 resource model. + +This is a deterministic analytical scenario sweep, not a hardware benchmark. +A reported distance of 61 is the model's cap sentinel (search tested d=3..59); +rows at that sentinel must not be read as a validated minimum-distance solution. +""" +from __future__ import annotations + +import argparse +import json +import os +import platform +import sys +import time +from datetime import datetime, timezone +from pathlib import Path +from typing import Iterable + +from .resource import estimate + +DEFAULT_P_VALUES = (0.0005, 0.001, 0.002, 0.005, 0.007, 0.009) +DEFAULT_T_GATES = (100_000_000, 1_000_000_000, 3_000_000_000) +THRESHOLD = 0.01 + + +def build_sweep_report( + *, + p_values: Iterable[float] = DEFAULT_P_VALUES, + t_gate_counts: Iterable[int] = DEFAULT_T_GATES, + n_logical: int = 3000, + p_total_failure: float = 0.5, + code_revision: str | None = None, +) -> dict: + physical_rates = list(p_values) + gate_counts = list(t_gate_counts) + if not physical_rates or not gate_counts: + raise ValueError("p_values and t_gate_counts must not be empty") + for p in physical_rates: + if isinstance(p, bool) or not isinstance(p, (int, float)) or not 0 <= p < THRESHOLD: + raise ValueError(f"each physical error rate must be in [0, {THRESHOLD})") + for gates in gate_counts: + if isinstance(gates, bool) or not isinstance(gates, int) or gates < 1: + raise ValueError("each T-gate count must be a positive integer") + + started = time.perf_counter() + rows = [] + for p in physical_rates: + for gates in gate_counts: + result = estimate( + p_physical=p, + n_logical=n_logical, + t_gates=gates, + p_total_failure=p_total_failure, + ) + cap_exceeded = result["d"] == 61 + rows.append({ + "p_physical": p, + "n_logical": n_logical, + "t_gates": gates, + "p_total_failure": p_total_failure, + "reported_distance": result["d"], + "distance_cap_exceeded": cap_exceeded, + "target_met_within_search_cap": not cap_exceeded, + "p_L_per_gate_target": result["p_L_per_gate"], + "p_L_at_reported_distance": result["p_L_achieved"], + "physical_qubits_at_reported_distance": result["total_physical"], + "below_10m_qubit_threshold_at_reported_distance": result["feasible"], + }) + + return { + "schema_version": "1.0", + "experiment": "qec-lab-rsa2048-resource-parameter-sweep", + "measurement_type": "analytical_model_sweep_not_hardware_measurement", + "created_at_utc": datetime.now(timezone.utc).isoformat(), + "code_revision": code_revision or os.getenv("GITHUB_SHA", "unknown"), + "environment": { + "python": sys.version.split()[0], + "platform": platform.platform(), + }, + "model": { + "name": "simplified_surface_code_logical_error_approximation", + "logical_error_rate": "A * (p_physical / p_threshold) ** ((distance + 1) / 2)", + "p_threshold": THRESHOLD, + "prefactor_A": 0.1, + "searched_odd_distances": list(range(3, 60, 2)), + "distance_cap_sentinel": 61, + "total_failure_budget_interpretation": "per-T-gate target = p_total_failure / t_gates", + "limitations": [ + "not calibrated against a hardware backend", + "omits architecture-specific routing, magic-state factory, and layout overhead", + "distance 61 means no solution was found within tested distances 3..59", + "qubit counts at the cap sentinel are reference values, not validated minimum requirements", + ], + }, + "parameters": { + "physical_error_rates": physical_rates, + "t_gate_counts": gate_counts, + "n_logical": n_logical, + "p_total_failure": p_total_failure, + }, + "result_count": len(rows), + "runtime_seconds": round(time.perf_counter() - started, 6), + "results": rows, + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--p-values", default=",".join(map(str, DEFAULT_P_VALUES))) + parser.add_argument("--t-gates", default=",".join(map(str, DEFAULT_T_GATES))) + parser.add_argument("--n-logical", type=int, default=3000) + parser.add_argument("--p-total-failure", type=float, default=0.5) + parser.add_argument("--revision", default=None) + parser.add_argument("--output", type=Path) + args = parser.parse_args() + try: + report = build_sweep_report( + p_values=[float(value) for value in args.p_values.split(",") if value.strip()], + t_gate_counts=[int(value) for value in args.t_gates.split(",") if value.strip()], + n_logical=args.n_logical, + p_total_failure=args.p_total_failure, + code_revision=args.revision, + ) + except ValueError as exc: + parser.error(str(exc)) + rendered = json.dumps(report, indent=2, sort_keys=True) + "\n" + if args.output: + args.output.write_text(rendered, encoding="utf-8") + print(rendered, end="") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From d0fc69ceea522f9ed1503cc9ec5aa9d3099a252b Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:14:49 +0530 Subject: [PATCH 12/37] test: verify QEC sweep reproducibility manifest --- backend/tests/test_core.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/backend/tests/test_core.py b/backend/tests/test_core.py index e8914ee..9589508 100644 --- a/backend/tests/test_core.py +++ b/backend/tests/test_core.py @@ -101,3 +101,32 @@ def test_api_cors_has_explicit_local_allowlist(): assert cors.kwargs["allow_methods"] == ["GET", "POST"] assert cors.kwargs["allow_headers"] == ["Content-Type"] assert "*" not in cors.kwargs["allow_origins"] + + + +def test_resource_sweep_records_reproducible_parameters_and_model_limits(): + from qec.resource_sweep import build_sweep_report + + report = build_sweep_report( + p_values=[0.001, 0.005], + t_gate_counts=[1000, 100000], + n_logical=100, + p_total_failure=0.5, + code_revision="test-revision", + ) + assert report["schema_version"] == "1.0" + assert report["code_revision"] == "test-revision" + assert report["measurement_type"] == "analytical_model_sweep_not_hardware_measurement" + assert report["result_count"] == 4 + assert len(report["results"]) == 4 + assert report["model"]["distance_cap_sentinel"] == 61 + assert all("distance_cap_exceeded" in row for row in report["results"]) + + +def test_resource_sweep_rejects_threshold_and_empty_grids(): + from qec.resource_sweep import build_sweep_report + + with pytest.raises(ValueError): + build_sweep_report(p_values=[0.01], t_gate_counts=[1000]) + with pytest.raises(ValueError): + build_sweep_report(p_values=[], t_gate_counts=[1000]) From 3cd699a531f36f45741a766d4e91030d8e467bc0 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:14:53 +0530 Subject: [PATCH 13/37] ci: smoke-test reproducible QEC resource sweep --- .github/workflows/ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53aef56..eaff66c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,18 @@ jobs: python -m pip install -r requirements.txt pytest - name: Run regression tests run: python -m pytest -q tests + - name: Run reproducible resource-sweep smoke test + run: | + python -m qec.resource_sweep --p-values 0.001,0.005 --t-gates 1000000,3000000000 --output /tmp/qec-resource-sweep.json + python - <<'PY' + import json + with open("/tmp/qec-resource-sweep.json", encoding="utf-8") as handle: + report = json.load(handle) + assert report["result_count"] == 4 + assert report["measurement_type"] == "analytical_model_sweep_not_hardware_measurement" + assert report["code_revision"] + print(f"Resource sweep passed: {report['result_count']} cases, {report['runtime_seconds']} seconds") + PY - name: Compile Python sources run: python -m compileall -q . From dc0e61872af59c7b67b9cafeb9fe9129a2059649 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:16:48 +0530 Subject: [PATCH 14/37] fix: bound logical-error probabilities outside model domain --- backend/qec/resource.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/backend/qec/resource.py b/backend/qec/resource.py index 3bb39bf..18eba78 100644 --- a/backend/qec/resource.py +++ b/backend/qec/resource.py @@ -38,13 +38,22 @@ def _validate_probability(value: float, name: str, *, allow_zero: bool = True) - def logical_error_rate(p: float, d: int) -> float: - """Approximate p_L; validates probabilities and odd code distance.""" + """Approximate p_L below threshold; saturate to 1 outside model domain. + + The formula is only predictive for physical error rates below _P_TH. + At or above threshold, 1.0 is a conservative sentinel, not a hardware estimate. + """ _validate_probability(p, "p") if not isinstance(d, int) or d < 3 or d % 2 == 0: raise ValueError("d must be an odd integer >= 3") if p == 0: return 0.0 - return _A * (p / _P_TH) ** ((d + 1) / 2) + # The below-threshold approximation must not be extrapolated above p_th. + # Return a saturated sentinel so callers never receive an impossible + # probability > 1; estimate() separately marks the result out of domain. + if p >= _P_TH: + return 1.0 + return min(1.0, _A * (p / _P_TH) ** ((d + 1) / 2)) def min_distance(p: float, p_L_per_gate: float) -> int: @@ -109,6 +118,10 @@ def estimate( "phys_per_logical": phys_per_logical, "total_physical": total, "feasible": total < 10_000_000, + "model_domain_valid": p_physical < _P_TH, + "distance_cap_exceeded": d == 61, + "target_met_within_search_cap": d != 61, + "total_physical_is_cap_reference": d == 61, "references": { "Gidney & Ekera 2019 (arXiv:1905.09749)": 20_000_000, "Gidney 2025 (arXiv:2505.15917)": 1_000_000, From fded94436d3519376b48f8456003129ad3d49463 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:16:53 +0530 Subject: [PATCH 15/37] feat: expose resource model validity and cap status --- backend/qec/runtime.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/qec/runtime.py b/backend/qec/runtime.py index 89b0fe8..c86551e 100644 --- a/backend/qec/runtime.py +++ b/backend/qec/runtime.py @@ -50,6 +50,10 @@ class RunReport: phys_per_logical: int total_physical: int feasible: bool + model_domain_valid: bool + distance_cap_exceeded: bool + target_met_within_search_cap: bool + total_physical_is_cap_reference: bool # runtime estimate physical_cycles: int # circuit_depth × d (QEC rounds per logical cycle) @@ -122,6 +126,9 @@ def run( "d": sr["d"], "total_physical": sr["total_physical"], "feasible": sr["feasible"], + "model_domain_valid": sr["model_domain_valid"], + "distance_cap_exceeded": sr["distance_cap_exceeded"], + "target_met_within_search_cap": sr["target_met_within_search_cap"], }) # Validation factor vs nearest published benchmark @@ -149,6 +156,10 @@ def run( phys_per_logical = res["phys_per_logical"], total_physical = res["total_physical"], feasible = res["feasible"], + model_domain_valid = res["model_domain_valid"], + distance_cap_exceeded = res["distance_cap_exceeded"], + target_met_within_search_cap = res["target_met_within_search_cap"], + total_physical_is_cap_reference = res["total_physical_is_cap_reference"], physical_cycles = physical_cycles, runtime_us = runtime_us, From 98b022c4c6074001f84b5b369c2792c496e9a05f Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:16:59 +0530 Subject: [PATCH 16/37] fix: do not mark capped or above-threshold estimates feasible --- backend/qec/resource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/qec/resource.py b/backend/qec/resource.py index 18eba78..e0230c6 100644 --- a/backend/qec/resource.py +++ b/backend/qec/resource.py @@ -117,7 +117,7 @@ def estimate( "p_L_achieved": p_L, "phys_per_logical": phys_per_logical, "total_physical": total, - "feasible": total < 10_000_000, + "feasible": total < 10_000_000 and p_physical < _P_TH and d != 61, "model_domain_valid": p_physical < _P_TH, "distance_cap_exceeded": d == 61, "target_met_within_search_cap": d != 61, From efea1515425923520ffff716ad0aff47fc2d7104 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:17:04 +0530 Subject: [PATCH 17/37] test: flag invalid QEC resource-model extrapolations --- backend/tests/test_core.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/backend/tests/test_core.py b/backend/tests/test_core.py index 9589508..ff7d223 100644 --- a/backend/tests/test_core.py +++ b/backend/tests/test_core.py @@ -130,3 +130,24 @@ def test_resource_sweep_rejects_threshold_and_empty_grids(): build_sweep_report(p_values=[0.01], t_gate_counts=[1000]) with pytest.raises(ValueError): build_sweep_report(p_values=[], t_gate_counts=[1000]) + + + +def test_above_threshold_resource_estimate_is_flagged_not_reported_feasible(): + assert logical_error_rate(0.05, 3) == 1.0 + result = estimate(p_physical=0.05, n_logical=100, t_gates=1_000_000) + assert result["model_domain_valid"] is False + assert result["distance_cap_exceeded"] is True + assert result["target_met_within_search_cap"] is False + assert result["total_physical_is_cap_reference"] is True + assert result["feasible"] is False + + +def test_runtime_propagates_resource_model_domain_flags(): + from qec.runtime import run + + report = run("shor-rsa2048", p_physical=0.05).to_dict() + assert report["model_domain_valid"] is False + assert report["distance_cap_exceeded"] is True + assert report["feasible"] is False + assert all("model_domain_valid" in row for row in report["sensitivity"]) From 5ddafe480deff501043e30bc8456af5c1bc5be25 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:17:21 +0530 Subject: [PATCH 18/37] fix: keep resource slider within model threshold domain --- frontend/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 95e965d..2087d2c 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -421,8 +421,8 @@ PHYSICAL ERROR RATE 0.1% - -
0.1%4.0%
+ +
0.1%0.9% · below threshold
LOGICAL QUBITS 3 000 @@ -1047,7 +1047,7 @@ // RESOURCE ESTIMATOR // ================================================================ async function updateResource() { - const pPct = +document.getElementById('rp-slider').value / 10; // 0.1..4.0% + const pPct = +document.getElementById('rp-slider').value / 10; // 0.1..0.9% const p = pPct / 100; const nL = +document.getElementById('rl-slider').value; document.getElementById('rp-val').textContent = pPct.toFixed(1); From 145abdb2377c870cb17851893c904888328814d6 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:17:27 +0530 Subject: [PATCH 19/37] fix: restrict resource API to below-threshold model inputs --- backend/server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/server.py b/backend/server.py index 83bc166..d769eb3 100644 --- a/backend/server.py +++ b/backend/server.py @@ -63,10 +63,11 @@ def threshold_endpoint(shots: int = Query(600, ge=100, le=2000)): @app.get("/api/resource") def resource_endpoint( - p: float = Query(0.001, ge=1e-4, le=0.05), + p: float = Query(0.001, ge=1e-4, le=0.009), n_logical: int = Query(3000, ge=100, le=20000), t_gates: int = Query(3_000_000_000, ge=1_000_000), ): + """Return below-threshold estimates only; use /api/run for explicit domain flags.""" return estimate(p_physical=p, n_logical=n_logical, t_gates=t_gates) From c7d078229915cf70f770ca282f6fa23f0d812f7a Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:17:39 +0530 Subject: [PATCH 20/37] fix: distinguish invalid-domain and capped resource estimates --- frontend/index.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/index.html b/frontend/index.html index 2087d2c..5351443 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1916,7 +1916,13 @@ // note const note = document.getElementById('os-note'); - if (d.feasible) { + if (!d.model_domain_valid) { + note.className = 'os-runtime-note warn'; + note.textContent = '⚠ OUTSIDE MODEL DOMAIN — below-threshold surface-code approximation is not predictive at p ≥ 1%.'; + } else if (d.distance_cap_exceeded) { + note.className = 'os-runtime-note warn'; + note.textContent = `⚠ REQUIRED DISTANCE EXCEEDS SEARCH CAP (d ≤ 59). ${fmtBig(d.total_physical)} qubits is a cap reference, not a validated minimum.`; + } else if (d.feasible) { note.className = 'os-runtime-note ok'; note.textContent = `✓ FEASIBLE — ${fmtBig(d.total_physical)} qubits at p=${(p*100).toFixed(3)}%`; } else { From f48960f7c6cff74fcac2d7d25a147a7312e0810a Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:17:44 +0530 Subject: [PATCH 21/37] docs: document resource sweep and model-domain limits --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 0895c7b..0e89526 100644 --- a/README.md +++ b/README.md @@ -121,3 +121,14 @@ MIT license. CI checks deterministic invariants for surface-code geometry, seeded noisy-shot reproducibility, probability and resource-input validation, monotonic behavior of the simplified logical-error approximation below its configured threshold, and explicit local CORS policy. These tests establish implementation consistency, not empirical calibration against a hardware backend. The resource estimator is a simplified analytical model. Its outputs depend on assumptions such as the logical-error approximation, threshold, prefactor, code distance cap, algorithmic gate counts, and accepted total failure budget. Treat the result as a reproducible scenario estimate—not a benchmark of a specific quantum processor or a guarantee that RSA-2048 factoring is feasible. When comparing runs, record all inputs and the code revision; published resource estimates can differ substantially because their architectures and arithmetic assumptions differ. + + +## Reproducible resource sweep + +From `backend/`, run: + +```bash +python -m qec.resource_sweep --output resource-sweep.json +``` + +The JSON manifest records the code revision, Python/platform, parameter grid, threshold/prefactor assumptions, run duration, and one result per physical-error-rate × T-gate-count pair. A reported distance of `61` is a sentinel meaning the search found no solution for odd distances `3..59`; the associated qubit count is a cap reference, not a validated minimum. The analytical model is only predictive below its configured 1% threshold. Resource API controls are restricted to 0.1–0.9%; the separate runtime endpoint marks out-of-domain inputs explicitly. From b6402d8674967c131d7c5e93c7c3ec6503b99a02 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:18:06 +0530 Subject: [PATCH 22/37] fix: omit benchmark ratio for capped or out-of-domain estimates --- backend/qec/runtime.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/qec/runtime.py b/backend/qec/runtime.py index c86551e..2156666 100644 --- a/backend/qec/runtime.py +++ b/backend/qec/runtime.py @@ -136,7 +136,9 @@ def run( nonzero = [v for v in references.values() if v > 0] nearest = min(nonzero, key=lambda v: abs(v - res["total_physical"])) if nonzero else None within_factor = ( - round(res["total_physical"] / nearest, 2) if nearest and nearest > 0 else None + round(res["total_physical"] / nearest, 2) + if nearest and nearest > 0 and res["model_domain_valid"] and not res["distance_cap_exceeded"] + else None ) return RunReport( From e07d9ec66b65ca4b81fc470fd9fa66b533880e31 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:18:10 +0530 Subject: [PATCH 23/37] test: suppress benchmark ratios for invalid resource estimates --- backend/tests/test_core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/tests/test_core.py b/backend/tests/test_core.py index ff7d223..cdc62d0 100644 --- a/backend/tests/test_core.py +++ b/backend/tests/test_core.py @@ -150,4 +150,5 @@ def test_runtime_propagates_resource_model_domain_flags(): assert report["model_domain_valid"] is False assert report["distance_cap_exceeded"] is True assert report["feasible"] is False + assert report["within_factor"] is None assert all("model_domain_valid" in row for row in report["sensitivity"]) From 7f6ec380cbca3ea16521ebdae5e33366fd90b75b Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:20:46 +0530 Subject: [PATCH 24/37] ci: run the full resource parameter grid --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaff66c..843de92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,12 +31,12 @@ jobs: run: python -m pytest -q tests - name: Run reproducible resource-sweep smoke test run: | - python -m qec.resource_sweep --p-values 0.001,0.005 --t-gates 1000000,3000000000 --output /tmp/qec-resource-sweep.json + python -m qec.resource_sweep --output /tmp/qec-resource-sweep.json python - <<'PY' import json with open("/tmp/qec-resource-sweep.json", encoding="utf-8") as handle: report = json.load(handle) - assert report["result_count"] == 4 + assert report["result_count"] == 18 assert report["measurement_type"] == "analytical_model_sweep_not_hardware_measurement" assert report["code_revision"] print(f"Resource sweep passed: {report['result_count']} cases, {report['runtime_seconds']} seconds") From b4dcb9bf5321acf7a678d8208755010ac59c622c Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:22:13 +0530 Subject: [PATCH 25/37] docs: publish measured analytical resource-sweep table --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 0e89526..d9e9a98 100644 --- a/README.md +++ b/README.md @@ -132,3 +132,19 @@ python -m qec.resource_sweep --output resource-sweep.json ``` The JSON manifest records the code revision, Python/platform, parameter grid, threshold/prefactor assumptions, run duration, and one result per physical-error-rate × T-gate-count pair. A reported distance of `61` is a sentinel meaning the search found no solution for odd distances `3..59`; the associated qubit count is a cap reference, not a validated minimum. The analytical model is only predictive below its configured 1% threshold. Resource API controls are restricted to 0.1–0.9%; the separate runtime endpoint marks out-of-domain inputs explicitly. + + +### CI resource-sweep snapshot + +The full 18-case analytical grid was executed in CI with `n_logical=3000` and a total failure budget of 0.5. The rows below show the 3-billion-T-gate scenario; values are outputs of this simplified model, not hardware measurements. + +| Physical error rate | Reported distance | Physical qubits at reported distance | Search cap exceeded? | +|---:|---:|---:|---| +| 0.05% | 13 | 1,014,000 | No | +| 0.1% | 17 | 1,734,000 | No | +| 0.2% | 25 | 3,750,000 | No | +| 0.5% | 59 | 20,886,000 | No | +| 0.7% | 61 (sentinel) | 22,326,000 (cap reference) | Yes | +| 0.9% | 61 (sentinel) | 22,326,000 (cap reference) | Yes | + +The cap rows mean the target was not met for any tested odd distance from 3 through 59. They must not be interpreted as a proven minimum-qubit design. From 19e941174b0b0729869965277ea226d9d0436e6d Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:26:54 +0530 Subject: [PATCH 26/37] docs: align API and UI resource-rate ranges --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d9e9a98..0db5620 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ From `backend/`, run: python -m qec.resource_sweep --output resource-sweep.json ``` -The JSON manifest records the code revision, Python/platform, parameter grid, threshold/prefactor assumptions, run duration, and one result per physical-error-rate × T-gate-count pair. A reported distance of `61` is a sentinel meaning the search found no solution for odd distances `3..59`; the associated qubit count is a cap reference, not a validated minimum. The analytical model is only predictive below its configured 1% threshold. Resource API controls are restricted to 0.1–0.9%; the separate runtime endpoint marks out-of-domain inputs explicitly. +The JSON manifest records the code revision, Python/platform, parameter grid, threshold/prefactor assumptions, run duration, and one result per physical-error-rate × T-gate-count pair. A reported distance of `61` is a sentinel meaning the search found no solution for odd distances `3..59`; the associated qubit count is a cap reference, not a validated minimum. The analytical model is only predictive below its configured 1% threshold. The resource UI slider is restricted to 0.1–0.9%; the API accepts 0.01–0.9%. The separate runtime endpoint marks out-of-domain inputs explicitly. ### CI resource-sweep snapshot From 662353bc9b581035235ca5dea74250dd9beafad6 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Fri, 9 Oct 2026 23:27:01 +0530 Subject: [PATCH 27/37] docs: clarify resource sweep feasibility threshold --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0db5620..f94340f 100644 --- a/README.md +++ b/README.md @@ -138,13 +138,13 @@ The JSON manifest records the code revision, Python/platform, parameter grid, th The full 18-case analytical grid was executed in CI with `n_logical=3000` and a total failure budget of 0.5. The rows below show the 3-billion-T-gate scenario; values are outputs of this simplified model, not hardware measurements. -| Physical error rate | Reported distance | Physical qubits at reported distance | Search cap exceeded? | -|---:|---:|---:|---| -| 0.05% | 13 | 1,014,000 | No | -| 0.1% | 17 | 1,734,000 | No | -| 0.2% | 25 | 3,750,000 | No | -| 0.5% | 59 | 20,886,000 | No | -| 0.7% | 61 (sentinel) | 22,326,000 (cap reference) | Yes | -| 0.9% | 61 (sentinel) | 22,326,000 (cap reference) | Yes | +| Physical error rate | Reported distance | Physical qubits at reported distance | Under 10M cutoff? | Search cap exceeded? | +|---:|---:|---:|---|---| +| 0.05% | 13 | 1,014,000 | Yes | No | +| 0.1% | 17 | 1,734,000 | Yes | No | +| 0.2% | 25 | 3,750,000 | Yes | No | +| 0.5% | 59 | 20,886,000 | No | No | +| 0.7% | 61 (sentinel) | 22,326,000 (cap reference) | No | Yes | +| 0.9% | 61 (sentinel) | 22,326,000 (cap reference) | No | Yes | The cap rows mean the target was not met for any tested odd distance from 3 through 59. They must not be interpreted as a proven minimum-qubit design. From bd7aaefe10e487f91b5033c85b452563b517edb1 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 01:10:22 +0530 Subject: [PATCH 28/37] feat: add seeded Monte Carlo resource scenarios --- backend/qec/uncertainty.py | 131 +++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 backend/qec/uncertainty.py diff --git a/backend/qec/uncertainty.py b/backend/qec/uncertainty.py new file mode 100644 index 0000000..1d5bf15 --- /dev/null +++ b/backend/qec/uncertainty.py @@ -0,0 +1,131 @@ +"""Seeded Monte Carlo scenario sweep for the simplified resource estimator. + +The output distribution reflects user-chosen input ranges and sampling policy. +It is not an empirical confidence interval or a forecast of quantum hardware. +""" +from __future__ import annotations + +import math +import random +import statistics +from typing import Any + +from .resource import estimate + + +def _nearest_rank(values: list[float], quantile: float) -> float: + ordered = sorted(values) + index = max(0, math.ceil(quantile * len(ordered)) - 1) + return ordered[min(index, len(ordered) - 1)] + + +def _distribution(values: list[int | float]) -> dict[str, int | float | None]: + numeric = [float(value) for value in values] + return { + "count": len(numeric), + "mean": statistics.fmean(numeric), + "sample_stddev": statistics.stdev(numeric) if len(numeric) > 1 else None, + "p05": _nearest_rank(numeric, 0.05), + "p50": _nearest_rank(numeric, 0.50), + "p95": _nearest_rank(numeric, 0.95), + "min": min(numeric), + "max": max(numeric), + } + + +def monte_carlo_resource_scenarios( + *, + samples: int = 1000, + seed: int = 20261010, + p_min: float = 0.0005, + p_max: float = 0.005, + n_logical_min: int = 1000, + n_logical_max: int = 5000, + t_gates_min: int = 1_000_000_000, + t_gates_max: int = 5_000_000_000, + p_total_failure_min: float = 0.1, + p_total_failure_max: float = 0.9, +) -> dict[str, Any]: + """Sample input assumptions uniformly and summarize modeled resource outputs.""" + if isinstance(samples, bool) or not isinstance(samples, int) or not 1 <= samples <= 20_000: + raise ValueError("samples must be an integer in [1, 20000]") + if isinstance(seed, bool) or not isinstance(seed, int): + raise ValueError("seed must be an integer") + + for name, value in (("p_min", p_min), ("p_max", p_max)): + if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value): + raise ValueError(f"{name} must be a finite number") + if not 0 <= value < 0.01: + raise ValueError(f"{name} must be in [0, 0.01), the estimator's below-threshold domain") + if p_min > p_max: + raise ValueError("p_min must be <= p_max") + + for name, value in (("n_logical_min", n_logical_min), ("n_logical_max", n_logical_max), + ("t_gates_min", t_gates_min), ("t_gates_max", t_gates_max)): + if isinstance(value, bool) or not isinstance(value, int) or value < 1: + raise ValueError(f"{name} must be a positive integer") + if n_logical_min > n_logical_max: + raise ValueError("n_logical_min must be <= n_logical_max") + if t_gates_min > t_gates_max: + raise ValueError("t_gates_min must be <= t_gates_max") + + for name, value in (("p_total_failure_min", p_total_failure_min), + ("p_total_failure_max", p_total_failure_max)): + if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value): + raise ValueError(f"{name} must be a finite number") + if not 0 < value <= 1: + raise ValueError(f"{name} must be in (0, 1]") + if p_total_failure_min > p_total_failure_max: + raise ValueError("p_total_failure_min must be <= p_total_failure_max") + + rng = random.Random(seed) + rows = [] + for _ in range(samples): + p_physical = rng.uniform(p_min, p_max) + n_logical = rng.randint(n_logical_min, n_logical_max) + t_gates = rng.randint(t_gates_min, t_gates_max) + p_total_failure = rng.uniform(p_total_failure_min, p_total_failure_max) + result = estimate( + p_physical=p_physical, + n_logical=n_logical, + t_gates=t_gates, + p_total_failure=p_total_failure, + ) + rows.append({ + "p_physical": p_physical, + "n_logical": n_logical, + "t_gates": t_gates, + "p_total_failure": p_total_failure, + "total_physical": result["total_physical"], + "reported_distance": result["d"], + "distance_cap_exceeded": result["distance_cap_exceeded"], + "model_domain_valid": result["model_domain_valid"], + "feasible": result["feasible"], + }) + + return { + "schema_version": "1.0", + "experiment": "qec-lab-resource-estimator-monte-carlo-scenarios", + "measurement_type": "monte_carlo_scenario_sweep_not_empirical_uncertainty", + "sample_count": samples, + "seed": seed, + "sampling_policy": { + "p_physical": {"distribution": "uniform", "min": p_min, "max": p_max}, + "n_logical": {"distribution": "discrete_uniform", "min": n_logical_min, "max": n_logical_max}, + "t_gates": {"distribution": "discrete_uniform", "min": t_gates_min, "max": t_gates_max}, + "p_total_failure": {"distribution": "uniform", "min": p_total_failure_min, "max": p_total_failure_max}, + }, + "interpretation": ( + "Quantiles summarize outputs under the specified input ranges and uniform sampling policy. " + "They are not calibrated hardware probabilities or empirical confidence intervals." + ), + "results": { + "total_physical": _distribution([r["total_physical"] for r in rows]), + "reported_distance": _distribution([r["reported_distance"] for r in rows]), + }, + "rates": { + "distance_cap_exceeded": sum(r["distance_cap_exceeded"] for r in rows) / samples, + "model_domain_valid": sum(r["model_domain_valid"] for r in rows) / samples, + "feasible": sum(r["feasible"] for r in rows) / samples, + }, + } From 50c42c5876e184e7aed9bb143d3f1c3490467a3e Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 01:10:24 +0530 Subject: [PATCH 29/37] feat: expose resource scenario uncertainty endpoint --- backend/server.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/backend/server.py b/backend/server.py index d769eb3..ae2c881 100644 --- a/backend/server.py +++ b/backend/server.py @@ -71,6 +71,41 @@ def resource_endpoint( return estimate(p_physical=p, n_logical=n_logical, t_gates=t_gates) +# ── resource-estimator scenario uncertainty ─────────────────────────────────── + +@app.get("/api/resource/uncertainty") +def resource_uncertainty_endpoint( + samples: int = Query(1000, ge=1, le=20000), + seed: int = Query(20261010), + p_min: float = Query(0.0005, ge=0.0, le=0.009999), + p_max: float = Query(0.005, ge=0.0, le=0.009999), + n_logical_min: int = Query(1000, ge=1, le=20000), + n_logical_max: int = Query(5000, ge=1, le=20000), + t_gates_min: int = Query(1_000_000_000, ge=1), + t_gates_max: int = Query(5_000_000_000, ge=1), + p_total_failure_min: float = Query(0.1, gt=0.0, le=1.0), + p_total_failure_max: float = Query(0.9, gt=0.0, le=1.0), +): + """Return scenario-spread summaries, not empirical confidence intervals.""" + from qec.uncertainty import monte_carlo_resource_scenarios + try: + return monte_carlo_resource_scenarios( + samples=samples, + seed=seed, + p_min=p_min, + p_max=p_max, + n_logical_min=n_logical_min, + n_logical_max=n_logical_max, + t_gates_min=t_gates_min, + t_gates_max=t_gates_max, + p_total_failure_min=p_total_failure_min, + p_total_failure_max=p_total_failure_max, + ) + except ValueError as e: + from fastapi import HTTPException + raise HTTPException(status_code=400, detail=str(e)) + + # ── lattice surgery ─────────────────────────────────────────────────────────── @app.get("/api/surgery/geometry") From f07949b3cc8b3af47c2384308be60938e456bd7f Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 01:10:26 +0530 Subject: [PATCH 30/37] test: cover seeded resource scenario uncertainty --- backend/tests/test_core.py | 51 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/backend/tests/test_core.py b/backend/tests/test_core.py index cdc62d0..219bec9 100644 --- a/backend/tests/test_core.py +++ b/backend/tests/test_core.py @@ -104,6 +104,57 @@ def test_api_cors_has_explicit_local_allowlist(): + +def test_monte_carlo_resource_scenarios_are_seeded_and_labeled_as_scenarios(): + from qec.uncertainty import monte_carlo_resource_scenarios + + kwargs = { + "samples": 100, + "seed": 123, + "p_min": 0.001, + "p_max": 0.002, + "n_logical_min": 100, + "n_logical_max": 200, + "t_gates_min": 1000, + "t_gates_max": 2000, + "p_total_failure_min": 0.2, + "p_total_failure_max": 0.8, + } + first = monte_carlo_resource_scenarios(**kwargs) + second = monte_carlo_resource_scenarios(**kwargs) + assert first == second + assert first["measurement_type"] == "monte_carlo_scenario_sweep_not_empirical_uncertainty" + assert first["sample_count"] == 100 + assert first["seed"] == 123 + assert first["results"]["total_physical"]["p05"] <= first["results"]["total_physical"]["p50"] + assert first["results"]["total_physical"]["p50"] <= first["results"]["total_physical"]["p95"] + assert 0.0 <= first["rates"]["distance_cap_exceeded"] <= 1.0 + assert "confidence interval" in first["interpretation"].lower() + + +@pytest.mark.parametrize( + "kwargs", + [ + {"samples": 0}, + {"samples": 10, "p_min": 0.005, "p_max": 0.001}, + {"samples": 10, "n_logical_min": 10, "n_logical_max": 1}, + {"samples": 10, "t_gates_min": 100, "t_gates_max": 10}, + {"samples": 10, "p_total_failure_min": 0.8, "p_total_failure_max": 0.2}, + ], +) +def test_monte_carlo_resource_scenarios_reject_invalid_ranges(kwargs): + from qec.uncertainty import monte_carlo_resource_scenarios + + with pytest.raises(ValueError): + monte_carlo_resource_scenarios(**kwargs) + + +def test_resource_uncertainty_api_is_registered(): + from server import app + + assert any(route.path == "/api/resource/uncertainty" for route in app.routes) + + def test_resource_sweep_records_reproducible_parameters_and_model_limits(): from qec.resource_sweep import build_sweep_report From ea7b2818c1aa567cfc0fcde2042d6d02990f7a8d Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 01:10:29 +0530 Subject: [PATCH 31/37] docs: explain resource scenario uncertainty --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index f94340f..1404827 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,18 @@ docs/ --- +## Scenario uncertainty analysis + +The API endpoint `GET /api/resource/uncertainty` runs a seeded Monte Carlo sweep over explicitly supplied ranges for physical error rate, logical-qubit count, T-gate count, and total failure budget. It reports p05/p50/p95, mean, sample standard deviation, and rates for cap-exceeded, model-domain-valid, and feasible scenarios. + +Example: + +```bash +curl 'http://localhost:8001/api/resource/uncertainty?samples=1000&seed=20261010&p_min=0.0005&p_max=0.005&n_logical_min=1000&n_logical_max=5000&t_gates_min=1000000000&t_gates_max=5000000000' +``` + +**Interpretation:** this is a distribution of outputs under user-chosen input ranges, not a calibrated probability distribution for future hardware and not an empirical confidence interval. The default uniform sampling policy is an exploratory sensitivity choice; the model still uses its fixed analytical surface-code approximation and omits architecture-specific overhead. Record the ranges and seed when comparing reports. + ## API ``` From 064f96ad9b3ef51b5fae35c14087a02aa5e3e3ce Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 03:25:48 +0530 Subject: [PATCH 32/37] feat: bridge observed PQC findings into scoped QEC estimates --- backend/qec/scenario_bridge.py | 140 +++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 backend/qec/scenario_bridge.py diff --git a/backend/qec/scenario_bridge.py b/backend/qec/scenario_bridge.py new file mode 100644 index 0000000..8b5249d --- /dev/null +++ b/backend/qec/scenario_bridge.py @@ -0,0 +1,140 @@ +"""Consume Quantum Collapse bridge output and add scoped QEC resource estimates. + +Only RSA findings are supported by the current RSA-2048 resource model. ECC/DH/DSA +findings are retained as observed evidence but never coerced into RSA estimates. +All generated values are analytical scenario outputs, not hardware measurements. +""" +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Any + +from .resource import estimate + + +def build_scenario_report( + bridge: dict[str, Any], + *, + p_physical: float = 0.001, + n_logical: int = 3000, + t_gates: int = 3_000_000_000, + p_total_failure: float = 0.5, +) -> dict[str, Any]: + """Add an RSA-2048 estimate for supported nodes in a bridge scenario.""" + if not isinstance(bridge, dict) or bridge.get("schema_version") != "1.0": + raise ValueError("input must be a Quantum Collapse bridge output with schema_version 1.0") + source = bridge.get("source") + scenario = bridge.get("modeled_scenario") + evidence = bridge.get("observed_evidence") + if not isinstance(source, dict) or not isinstance(scenario, dict) or not isinstance(evidence, dict): + raise ValueError("input must contain source, observed_evidence, and modeled_scenario objects") + nodes = scenario.get("nodes") + if not isinstance(nodes, list): + raise ValueError("modeled_scenario.nodes must be a list") + + rows = [] + for node in nodes: + if not isinstance(node, dict): + raise ValueError("each modeled scenario node must be an object") + crypto = node.get("crypto") + if not isinstance(crypto, str): + raise ValueError("each scenario node must include a crypto label") + evidence_ref = { + "node_id": node.get("id"), + "file": node.get("evidence_file", ""), + "line": node.get("evidence_line"), + "algorithm": node.get("evidence_algorithm", crypto), + } + if crypto == "RSA": + model_result = estimate( + p_physical=p_physical, + n_logical=n_logical, + t_gates=t_gates, + p_total_failure=p_total_failure, + ) + rows.append({ + **evidence_ref, + "crypto": crypto, + "status": "estimated", + "resource_estimate": model_result, + "limitation": "Estimate is scoped to RSA-2048 factoring; it does not establish runtime reachability or an attack timeline.", + }) + else: + rows.append({ + **evidence_ref, + "crypto": crypto, + "status": "unsupported_crypto_model", + "resource_estimate": None, + "limitation": "Current QEC resource model is scoped to RSA-2048 factoring; no RSA estimate is assigned to this finding.", + }) + + supported = sum(row["status"] == "estimated" for row in rows) + return { + "schema_version": "1.0", + "experiment": "qec-lab-quantum-collapse-scenario-bridge", + "measurement_type": "conditional_analytical_resource_estimate_not_hardware_measurement", + "input": { + "format": source.get("format"), + "format_version": source.get("version"), + "source_tool": source.get("tool"), + "bridge_schema_version": bridge.get("schema_version"), + "observed_finding_count": evidence.get("finding_count"), + }, + "resource_model": { + "name": "simplified_surface_code_rsa2048_estimator", + "scope": "RSA-2048 factoring only", + "parameters": { + "p_physical": p_physical, + "n_logical": n_logical, + "t_gates": t_gates, + "p_total_failure": p_total_failure, + }, + "limitations": [ + "analytical approximation, not a hardware measurement or calibrated forecast", + "omits architecture-specific routing, magic-state factory, and layout overhead", + "reported distance 61 is a search-cap sentinel, not a validated minimum-distance solution", + "source-code findings do not prove runtime reachability or deployed use", + "ECC, DH, and DSA findings are preserved but unsupported by this RSA-2048 model", + ], + }, + "summary": { + "scenario_node_count": len(nodes), + "supported_rsa_node_count": supported, + "unsupported_node_count": len(rows) - supported, + "edge_count": scenario.get("edge_count", 0), + }, + "findings": rows, + } + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("scenario", type=Path, help="Quantum Collapse SARIF bridge output JSON") + parser.add_argument("--p-physical", type=float, default=0.001) + parser.add_argument("--n-logical", type=int, default=3000) + parser.add_argument("--t-gates", type=int, default=3_000_000_000) + parser.add_argument("--p-total-failure", type=float, default=0.5) + parser.add_argument("--output", type=Path) + args = parser.parse_args() + try: + bridge = json.loads(args.scenario.read_text(encoding="utf-8")) + report = build_scenario_report( + bridge, + p_physical=args.p_physical, + n_logical=args.n_logical, + t_gates=args.t_gates, + p_total_failure=args.p_total_failure, + ) + except (OSError, json.JSONDecodeError, ValueError) as exc: + parser.error(str(exc)) + rendered = json.dumps(report, indent=2, sort_keys=True) + "\n" + if args.output: + args.output.write_text(rendered, encoding="utf-8") + print(rendered, end="") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From b8169e79afa6539e046ba8f0ca7daf3cc8776604 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 03:25:55 +0530 Subject: [PATCH 33/37] test: verify scenario bridge evidence and model boundaries --- backend/tests/test_core.py | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/backend/tests/test_core.py b/backend/tests/test_core.py index 219bec9..be32595 100644 --- a/backend/tests/test_core.py +++ b/backend/tests/test_core.py @@ -203,3 +203,70 @@ def test_runtime_propagates_resource_model_domain_flags(): assert report["feasible"] is False assert report["within_factor"] is None assert all("model_domain_valid" in row for row in report["sensitivity"]) + +def _sample_quantum_collapse_bridge(): + return { + "schema_version": "1.0", + "source": {"format": "SARIF", "version": "2.1.0", "tool": "pqc-scanner"}, + "observed_evidence": {"finding_count": 2}, + "modeled_scenario": { + "node_count": 2, + "edge_count": 0, + "nodes": [ + { + "id": "finding-0001", + "crypto": "RSA", + "evidence_file": "src/auth.py", + "evidence_line": 12, + "evidence_algorithm": "RSA", + }, + { + "id": "finding-0002", + "crypto": "ECC-P256", + "evidence_file": "src/exchange.py", + "evidence_line": 30, + "evidence_algorithm": "ECC/ECDSA/ECDH", + }, + ], + }, + } + + +def test_scenario_bridge_estimates_only_rsa_nodes(): + from qec.scenario_bridge import build_scenario_report + + report = build_scenario_report( + _sample_quantum_collapse_bridge(), + p_physical=0.001, + n_logical=100, + t_gates=1_000_000, + ) + assert report["measurement_type"] == "conditional_analytical_resource_estimate_not_hardware_measurement" + assert report["summary"]["supported_rsa_node_count"] == 1 + assert report["summary"]["unsupported_node_count"] == 1 + assert report["findings"][0]["status"] == "estimated" + assert report["findings"][0]["resource_estimate"]["n_logical"] == 100 + assert report["findings"][1]["status"] == "unsupported_crypto_model" + assert report["findings"][1]["resource_estimate"] is None + + +def test_scenario_bridge_rejects_unrecognized_contract(): + from qec.scenario_bridge import build_scenario_report + + with pytest.raises(ValueError, match="schema_version 1.0"): + build_scenario_report({"schema_version": "2.0"}) + + +def test_scenario_bridge_propagates_resource_model_domain_flags(): + from qec.scenario_bridge import build_scenario_report + + report = build_scenario_report( + _sample_quantum_collapse_bridge(), + p_physical=0.05, + n_logical=100, + t_gates=1_000_000, + ) + rsa = report["findings"][0]["resource_estimate"] + assert rsa["model_domain_valid"] is False + assert rsa["distance_cap_exceeded"] is True + assert rsa["feasible"] is False From 171f6df80e5c866953fdedf741f86edb022c6c90 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 03:26:01 +0530 Subject: [PATCH 34/37] test: add Quantum Collapse scenario bridge fixture --- .../fixtures/quantum_collapse_scenario.json | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 backend/tests/fixtures/quantum_collapse_scenario.json diff --git a/backend/tests/fixtures/quantum_collapse_scenario.json b/backend/tests/fixtures/quantum_collapse_scenario.json new file mode 100644 index 0000000..ad1bc70 --- /dev/null +++ b/backend/tests/fixtures/quantum_collapse_scenario.json @@ -0,0 +1,60 @@ +{ + "schema_version": "1.0", + "source": { + "format": "SARIF", + "version": "2.1.0", + "tool": "pqc-scanner" + }, + "observed_evidence": { + "finding_count": 2, + "by_bucket": { + "quantum_broken": 2, + "classically_broken": 0, + "quantum_weakened": 0, + "other": 0 + }, + "findings": [] + }, + "modeled_scenario": { + "node_count": 2, + "edge_count": 0, + "finding_weighted_risk_score": 0.5, + "nodes": [ + { + "id": "finding-0001", + "sector": "Scanned source finding", + "crypto": "RSA", + "criticality": 5, + "migration_pct": 0, + "evidence_file": "src/auth.py", + "evidence_line": 12, + "evidence_algorithm": "RSA", + "modeled_risk": 0.8 + }, + { + "id": "finding-0002", + "sector": "Scanned source finding", + "crypto": "ECC-P256", + "criticality": 5, + "migration_pct": 0, + "evidence_file": "src/exchange.py", + "evidence_line": 30, + "evidence_algorithm": "ECC/ECDSA/ECDH", + "modeled_risk": 0.8 + } + ], + "unmapped_quantum_findings": [], + "assumptions": { + "migration_pct": 0, + "criticality_by_sarif_level": { + "error": 5, + "warning": 3, + "note": 1 + }, + "dependency_edges": "none inferred; scanner output does not establish dependency topology", + "risk_score": "mean of modeled risk for mapped quantum-broken findings only", + "risk_coefficients": "illustrative values from quantum_collapse.risk", + "limitations": "static findings do not prove runtime reachability or deployed usage" + } + } +} From ad44f6783e8e348bbf8a0eb25409d567ace19553 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 03:26:07 +0530 Subject: [PATCH 35/37] ci: smoke-test PQC-to-QEC scenario bridge --- .github/workflows/ci.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 843de92..a0f372d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,23 @@ jobs: assert report["code_revision"] print(f"Resource sweep passed: {report['result_count']} cases, {report['runtime_seconds']} seconds") PY + - name: Run PQC evidence-to-QEC bridge smoke test + run: | + python -m qec.scenario_bridge tests/fixtures/quantum_collapse_scenario.json --n-logical 100 --t-gates 1000000 --output /tmp/qec-bridge.json + python - <<'PY' + import json + with open("/tmp/qec-bridge.json", encoding="utf-8") as handle: + report = json.load(handle) + assert report["measurement_type"] == "conditional_analytical_resource_estimate_not_hardware_measurement" + assert report["summary"]["supported_rsa_node_count"] == 1 + assert report["summary"]["unsupported_node_count"] == 1 + rows = {row["crypto"]: row for row in report["findings"]} + assert rows["RSA"]["status"] == "estimated" + assert rows["RSA"]["resource_estimate"]["n_logical"] == 100 + assert rows["ECC-P256"]["status"] == "unsupported_crypto_model" + assert rows["ECC-P256"]["resource_estimate"] is None + print("PQC-to-QEC bridge passed: RSA estimate scoped; ECC retained as unsupported evidence") + PY - name: Compile Python sources run: python -m compileall -q . From 334753efdca53bc333a9a7993fe096fc7879666d Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 03:26:13 +0530 Subject: [PATCH 36/37] docs: explain PQC evidence to QEC resource bridge --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 1404827..0b3a616 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,32 @@ docs/ --- +## PQC evidence → QEC resource scenario bridge + +QEC Lab can consume the versioned scenario JSON produced by Quantum Collapse's +PQC Scanner bridge. It retains the input finding references and runs the existing +resource estimator **only for RSA findings**, because the current estimator models +RSA-2048 factoring. ECC, DH, and DSA observations are preserved with an explicit +`unsupported_crypto_model` status rather than being treated as RSA equivalents. + +From `backend/`: + +```bash +python -m qec.scenario_bridge /path/to/scenario.json \ + --p-physical 0.001 --n-logical 3000 --t-gates 3000000000 \ + --p-total-failure 0.5 --output qec-resource-scenario.json +``` + +The output labels itself `conditional_analytical_resource_estimate_not_hardware_measurement`. +It carries the estimator's model-domain and distance-cap flags and documents that +the result is assumption-sensitive, omits architecture-specific overhead, and does +not prove source-code reachability, deployed use, or an attack timeline. Input +scenario risk scores and dependency assumptions are not recomputed or treated as +physical evidence. + +CI exercises this bridge using a small fixture containing one RSA and one ECC +node; the fixture is a contract/regression test, not a benchmark result. + ## Scenario uncertainty analysis The API endpoint `GET /api/resource/uncertainty` runs a seeded Monte Carlo sweep over explicitly supplied ranges for physical error rate, logical-qubit count, T-gate count, and total failure budget. It reports p05/p50/p95, mean, sample standard deviation, and rates for cap-exceeded, model-domain-valid, and feasible scenarios. From 4cbdcfce596384705e5addeab108b36fa10c03d0 Mon Sep 17 00:00:00 2001 From: Praising Harris Ratnam Date: Sat, 10 Oct 2026 03:26:51 +0530 Subject: [PATCH 37/37] docs: clarify bridge output metadata --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b3a616..569507a 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ python -m qec.scenario_bridge /path/to/scenario.json \ --p-total-failure 0.5 --output qec-resource-scenario.json ``` -The output labels itself `conditional_analytical_resource_estimate_not_hardware_measurement`. +Each output labels itself `conditional_analytical_resource_estimate_not_hardware_measurement`. It carries the estimator's model-domain and distance-cap flags and documents that the result is assumption-sensitive, omits architecture-specific overhead, and does not prove source-code reachability, deployed use, or an attack timeline. Input