shotgate 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- shotgate-0.2.2/.github/workflows/dockerhub-mirror.yml +91 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/workflows/hardware-validation.yml +26 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/workflows/pypi-smoke.yml +10 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/workflows/release.yml +41 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/CHANGELOG.md +56 -4
- {shotgate-0.2.0 → shotgate-0.2.2}/CONTRIBUTING.md +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/Containerfile +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/Makefile +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/PKG-INFO +6 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/README.md +5 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/SECURITY.md +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/README.md +3 -3
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/adr/0001-record-architecture-decisions.md +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/adr/0002-statistical-validation-core.md +3 -3
- shotgate-0.2.2/docs/adr/0004-rename-qforge-to-shotgate.md +35 -0
- shotgate-0.2.2/docs/adr/0005-license-apache-2-0.md +48 -0
- shotgate-0.2.2/docs/adr/0006-hardware-oracle-policy.md +48 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/architecture.md +14 -12
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/assertions.md +14 -11
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/diagrams/architecture.mmd +4 -4
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/diagrams/pipeline.mmd +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/hardware-validation.md +50 -18
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/motivation.md +12 -12
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/pipeline.md +4 -4
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/workflow-spec.md +8 -8
- shotgate-0.2.2/examples/bell-state/bell.qasm +8 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/bell-state/workflow.yaml +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/bell-state-hardware/workflow.yaml +2 -2
- shotgate-0.2.2/examples/bell-state-hardware-oracle-coverage/workflow.yaml +54 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/qemu/README.md +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/qemu/cloud-init/user-data +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/qemu/create-runner-vm.sh +3 -3
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/terraform/README.md +7 -5
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/terraform/examples/basic/main.tf +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/terraform/main.tf +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/pyproject.toml +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/scripts/demo.sh +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/__init__.py +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/backends/base.py +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/backends/ibm_runtime.py +16 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/config.py +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/report.py +3 -3
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/telemetry.py +2 -2
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/validation/metrics.py +1 -1
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/test_ibm_backend.py +3 -3
- {shotgate-0.2.0 → shotgate-0.2.2}/.containerignore +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/dependabot.yml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/scripts/pin-device.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/scripts/pull-base-image.sh +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.github/workflows/ci.yml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.gitignore +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/.gitlab-ci.yml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/CODEOWNERS +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/CODE_OF_CONDUCT.md +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/GOVERNANCE.md +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/Jenkinsfile +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/LICENSE +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/MAINTAINERS.md +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/NOTICE +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/adr/0003-container-and-vm-isolation.md +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/assets/bell-state-demo.svg +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/assets/shotgate-logomark.svg +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/docs/getting-started.md +0 -0
- {shotgate-0.2.0/examples/bell-state → shotgate-0.2.2/examples/bell-state-hardware}/bell.qasm +0 -0
- {shotgate-0.2.0/examples/bell-state-hardware → shotgate-0.2.2/examples/bell-state-hardware-oracle-coverage}/bell.qasm +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/ghz-state/ghz.qasm +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/ghz-state/workflow.yaml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/ghz-state-hardware/ghz.qasm +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/ghz-state-hardware/workflow.yaml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/grover-2q/grover.qasm +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/grover-2q/workflow.yaml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/grover-2q-hardware/grover.qasm +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/examples/grover-2q-hardware/workflow.yaml +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/qemu/cloud-init/meta-data +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/terraform/outputs.tf +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/terraform/variables.tf +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/infra/terraform/versions.tf +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/__main__.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/backends/__init__.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/backends/local_aer.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/backends/registry.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/circuits/__init__.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/circuits/loader.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/cli.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/pytest_plugin.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/runner.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/validation/__init__.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/src/shotgate/validation/assertions.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/conftest.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/test_assertions.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/test_config.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/test_metrics.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/test_pytest_plugin.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/test_report.py +0 -0
- {shotgate-0.2.0 → shotgate-0.2.2}/tests/test_runner_integration.py +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: dockerhub-mirror
|
|
2
|
+
|
|
3
|
+
# Mirror an already-published GHCR image set to Docker Hub, then sync this repo's
|
|
4
|
+
# README and tagline onto the Docker Hub repository page so the listing matches the
|
|
5
|
+
# source. GHCR stays the canonical registry; Docker Hub is a convenience mirror for
|
|
6
|
+
# discovery and the familiar `docker pull`. Runs on release (via workflow_call from
|
|
7
|
+
# release.yml) and on demand (workflow_dispatch) to re-mirror or back-fill any version.
|
|
8
|
+
#
|
|
9
|
+
# Credentials live in the `dockerhub` environment: DOCKERHUB_USERNAME and
|
|
10
|
+
# DOCKERHUB_TOKEN (a Docker Hub access token), and optionally DOCKERHUB_NAMESPACE
|
|
11
|
+
# to push under a Hub organization instead of the username. Absent credentials
|
|
12
|
+
# (a fork), the mirror step is skipped rather than failing.
|
|
13
|
+
#
|
|
14
|
+
# The README sync uses peter-evans/dockerhub-description, which drives the Docker
|
|
15
|
+
# Hub HTTP API. That API accepts a personal access token only if it is scoped
|
|
16
|
+
# read/write/delete; if DOCKERHUB_TOKEN is scoped narrower, set
|
|
17
|
+
# DOCKERHUB_DESCRIPTION_PASSWORD in the `dockerhub` environment (the account
|
|
18
|
+
# password or a read/write/delete token) and it is used in preference. The sync
|
|
19
|
+
# step is non-fatal (`continue-on-error`): a description failure never blocks the
|
|
20
|
+
# image mirror or the release.
|
|
21
|
+
|
|
22
|
+
on:
|
|
23
|
+
workflow_dispatch:
|
|
24
|
+
inputs:
|
|
25
|
+
version:
|
|
26
|
+
description: "Version to mirror from GHCR to Docker Hub (e.g. 0.2.1)"
|
|
27
|
+
required: true
|
|
28
|
+
workflow_call:
|
|
29
|
+
inputs:
|
|
30
|
+
version:
|
|
31
|
+
required: true
|
|
32
|
+
type: string
|
|
33
|
+
|
|
34
|
+
permissions:
|
|
35
|
+
contents: read
|
|
36
|
+
packages: read
|
|
37
|
+
|
|
38
|
+
jobs:
|
|
39
|
+
mirror:
|
|
40
|
+
name: mirror GHCR -> Docker Hub
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
environment: dockerhub
|
|
43
|
+
env:
|
|
44
|
+
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
45
|
+
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
46
|
+
DOCKERHUB_NAMESPACE: ${{ secrets.DOCKERHUB_NAMESPACE }}
|
|
47
|
+
steps:
|
|
48
|
+
- uses: actions/checkout@v6
|
|
49
|
+
|
|
50
|
+
- name: Compute Docker Hub repository
|
|
51
|
+
id: hub
|
|
52
|
+
if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }}
|
|
53
|
+
run: |
|
|
54
|
+
# Namespace defaults to the Hub username; DOCKERHUB_NAMESPACE overrides
|
|
55
|
+
# it to push under a Hub organization. Same rule as the mirror step.
|
|
56
|
+
NS="${DOCKERHUB_NAMESPACE:-$DOCKERHUB_USERNAME}"
|
|
57
|
+
echo "repository=${NS,,}/shotgate" >> "$GITHUB_OUTPUT"
|
|
58
|
+
|
|
59
|
+
- name: Mirror the version, latest, and -ibm tags
|
|
60
|
+
if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }}
|
|
61
|
+
env:
|
|
62
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
63
|
+
ACTOR: ${{ github.actor }}
|
|
64
|
+
REPO: ${{ github.repository }}
|
|
65
|
+
VERSION: ${{ inputs.version }}
|
|
66
|
+
HUB_REPO: ${{ steps.hub.outputs.repository }}
|
|
67
|
+
run: |
|
|
68
|
+
V="${VERSION#v}" # tolerate a leading 'v'
|
|
69
|
+
GHCR="ghcr.io/${REPO,,}"
|
|
70
|
+
DH="docker.io/${HUB_REPO}"
|
|
71
|
+
echo "$GH_TOKEN" | podman login ghcr.io -u "$ACTOR" --password-stdin
|
|
72
|
+
echo "$DOCKERHUB_TOKEN" | podman login docker.io -u "$DOCKERHUB_USERNAME" --password-stdin
|
|
73
|
+
for tag in "$V" latest "${V}-ibm" latest-ibm; do
|
|
74
|
+
podman pull "${GHCR}:${tag}"
|
|
75
|
+
podman tag "${GHCR}:${tag}" "${DH}:${tag}"
|
|
76
|
+
podman push "${DH}:${tag}"
|
|
77
|
+
done
|
|
78
|
+
echo "Mirrored ${GHCR}:{${V},latest,${V}-ibm,latest-ibm} -> ${DH}"
|
|
79
|
+
|
|
80
|
+
# Keep the Docker Hub repository page in sync with the source: the repo
|
|
81
|
+
# README becomes the full description, the project tagline the short one.
|
|
82
|
+
- name: Sync Docker Hub README and short description
|
|
83
|
+
if: ${{ env.DOCKERHUB_USERNAME != '' && env.DOCKERHUB_TOKEN != '' }}
|
|
84
|
+
continue-on-error: true
|
|
85
|
+
uses: peter-evans/dockerhub-description@v5
|
|
86
|
+
with:
|
|
87
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
88
|
+
password: ${{ secrets.DOCKERHUB_DESCRIPTION_PASSWORD || secrets.DOCKERHUB_TOKEN }}
|
|
89
|
+
repository: ${{ steps.hub.outputs.repository }}
|
|
90
|
+
short-description: "Container-native CI/CD quality gates for quantum circuits"
|
|
91
|
+
readme-filepath: ./README.md
|
|
@@ -11,9 +11,9 @@ on:
|
|
|
11
11
|
workflow_dispatch:
|
|
12
12
|
inputs:
|
|
13
13
|
device:
|
|
14
|
-
description: "IBM device to pin (empty = least_busy)"
|
|
14
|
+
description: "IBM device to pin (empty = least_busy, the portable default)"
|
|
15
15
|
required: false
|
|
16
|
-
default: "
|
|
16
|
+
default: ""
|
|
17
17
|
shots:
|
|
18
18
|
description: "Shots per job"
|
|
19
19
|
required: false
|
|
@@ -73,6 +73,30 @@ jobs:
|
|
|
73
73
|
exit "$fail"
|
|
74
74
|
'
|
|
75
75
|
|
|
76
|
+
- name: Oracle-coverage diagnostic (non-gating, measures chi_square on QPU)
|
|
77
|
+
env:
|
|
78
|
+
SHOTGATE_IBM_TOKEN: ${{ secrets.SHOTGATE_IBM_TOKEN }}
|
|
79
|
+
DEVICE: ${{ inputs.device }}
|
|
80
|
+
SHOTS: ${{ inputs.shots }}
|
|
81
|
+
REQUESTED_VERSION: ${{ inputs.version }}
|
|
82
|
+
run: |
|
|
83
|
+
# Runs all five oracles on one Bell circuit so chi_square has a hardware
|
|
84
|
+
# data point. chi_square is EXPECTED to fail under device noise, so this
|
|
85
|
+
# step never fails the job (|| true); the JSON report carries the number.
|
|
86
|
+
podman run --rm \
|
|
87
|
+
-v "$PWD:/work:ro" -v "$PWD/reports:/reports" \
|
|
88
|
+
-e SHOTGATE_IBM_TOKEN -e DEVICE -e SHOTS -e REQUESTED_VERSION \
|
|
89
|
+
docker.io/library/python:3.12-slim bash -euc '
|
|
90
|
+
SPEC="shotgate[ibm]"
|
|
91
|
+
[ -n "$REQUESTED_VERSION" ] && SPEC="shotgate[ibm]==$REQUESTED_VERSION"
|
|
92
|
+
pip install -q --no-cache-dir "$SPEC"
|
|
93
|
+
wf=bell-state-hardware-oracle-coverage
|
|
94
|
+
cp -r "/work/examples/${wf}" "/tmp/${wf}" && cd "/tmp/${wf}"
|
|
95
|
+
python /work/.github/scripts/pin-device.py workflow.yaml "$DEVICE"
|
|
96
|
+
shotgate run workflow.yaml --shots "$SHOTS" \
|
|
97
|
+
--json "/reports/${wf}.json" --markdown "/reports/${wf}.md" || true
|
|
98
|
+
' || true
|
|
99
|
+
|
|
76
100
|
- name: Publish step summary
|
|
77
101
|
if: always()
|
|
78
102
|
run: |
|
|
@@ -40,7 +40,16 @@ jobs:
|
|
|
40
40
|
docker.io/library/python:3.12-slim bash -euc '
|
|
41
41
|
SPEC="shotgate[aer]"
|
|
42
42
|
[ -n "$REQUESTED_VERSION" ] && SPEC="shotgate[aer]==$REQUESTED_VERSION"
|
|
43
|
-
|
|
43
|
+
# A freshly released version can lag for several minutes in the PyPI
|
|
44
|
+
# /simple/ index that pip reads, even after the files are live and the
|
|
45
|
+
# per-release JSON shows them (observed ~10 min on 2026-06-11). Retry
|
|
46
|
+
# generously so dispatching right after a release tolerates the lag.
|
|
47
|
+
for attempt in $(seq 1 20); do
|
|
48
|
+
pip install -q --no-cache-dir "$SPEC" pytest && break
|
|
49
|
+
echo "install attempt ${attempt}/20 failed (index may be propagating); retrying in 45s" >&2
|
|
50
|
+
sleep 45
|
|
51
|
+
done
|
|
52
|
+
pip show shotgate >/dev/null # fail the step if all attempts failed
|
|
44
53
|
echo "--- installed:"
|
|
45
54
|
pip show shotgate | sed -n "1,2p"
|
|
46
55
|
echo "--- CLI gate (exit 0 expected):"
|
|
@@ -98,6 +98,17 @@ jobs:
|
|
|
98
98
|
podman push "${IMG}:${VERSION}-ibm"
|
|
99
99
|
podman push "${IMG}:latest-ibm"
|
|
100
100
|
|
|
101
|
+
# Mirror the just-published GHCR images to Docker Hub (optional convenience
|
|
102
|
+
# registry). Delegated to the reusable dockerhub-mirror workflow, which is also
|
|
103
|
+
# dispatchable on its own to re-mirror any version. Skipped automatically when
|
|
104
|
+
# the dockerhub environment has no credentials.
|
|
105
|
+
mirror-dockerhub:
|
|
106
|
+
needs: publish-image
|
|
107
|
+
uses: ./.github/workflows/dockerhub-mirror.yml
|
|
108
|
+
with:
|
|
109
|
+
version: ${{ github.ref_name }}
|
|
110
|
+
secrets: inherit
|
|
111
|
+
|
|
101
112
|
publish-pypi:
|
|
102
113
|
name: publish to PyPI (trusted publishing)
|
|
103
114
|
runs-on: ubuntu-latest
|
|
@@ -134,8 +145,38 @@ jobs:
|
|
|
134
145
|
with:
|
|
135
146
|
name: dist
|
|
136
147
|
path: dist
|
|
148
|
+
- name: Compose install instructions
|
|
149
|
+
id: notes
|
|
150
|
+
run: |
|
|
151
|
+
V="${GITHUB_REF_NAME#v}"
|
|
152
|
+
{
|
|
153
|
+
echo "## Install ${GITHUB_REF_NAME}"
|
|
154
|
+
echo
|
|
155
|
+
echo "The package is on **PyPI** and the image on the **GitHub Container Registry (GHCR)** for convenience (the usual one-liners below). If you would rather not use a package index at all, the wheel attached to this release and the GHCR image are both pullable straight from GitHub, no extra account needed."
|
|
156
|
+
echo
|
|
157
|
+
echo "**Python package** (PyPI, or the attached wheel):"
|
|
158
|
+
echo '```bash'
|
|
159
|
+
echo "pip install 'shotgate[aer]==${V}'"
|
|
160
|
+
echo "# or straight from this release, no index:"
|
|
161
|
+
echo "pip install https://github.com/${GITHUB_REPOSITORY}/releases/download/${GITHUB_REF_NAME}/shotgate-${V}-py3-none-any.whl"
|
|
162
|
+
echo '```'
|
|
163
|
+
echo
|
|
164
|
+
echo "**Container** (GHCR, canonical; add the \`-ibm\` tag suffix for the QPU-capable variant):"
|
|
165
|
+
echo '```bash'
|
|
166
|
+
echo "podman pull ghcr.io/${GITHUB_REPOSITORY}:${V}"
|
|
167
|
+
echo "podman run --rm -v \"\$PWD:/work:Z\" -w /work ghcr.io/${GITHUB_REPOSITORY}:${V} run examples/bell-state/workflow.yaml"
|
|
168
|
+
echo "# also mirrored to Docker Hub: docker.io/${GITHUB_REPOSITORY}:${V}"
|
|
169
|
+
echo '```'
|
|
170
|
+
echo
|
|
171
|
+
echo "---"
|
|
172
|
+
} > release-notes.md
|
|
173
|
+
env:
|
|
174
|
+
GITHUB_REPOSITORY: ${{ github.repository }}
|
|
175
|
+
|
|
137
176
|
- name: Create release
|
|
138
177
|
uses: softprops/action-gh-release@v3
|
|
139
178
|
with:
|
|
140
179
|
files: dist/*
|
|
180
|
+
body_path: release-notes.md
|
|
181
|
+
append_body: true
|
|
141
182
|
generate_release_notes: true
|
|
@@ -6,7 +6,57 @@ All notable changes to this project are documented here. The format is based on
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## [0.2.2] - 2026-06-11
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **Three Architecture Decision Records.** ADR-0004 (rename `qforge` to `shotgate`,
|
|
14
|
+
including the breaking `apiVersion` change), ADR-0005 (license MIT to
|
|
15
|
+
AGPL-3.0-or-later to Apache-2.0, and the DCO inbound policy), and ADR-0006
|
|
16
|
+
(`chi_square` simulator-only, noise-aware hardware thresholds), completing the
|
|
17
|
+
ADR series against the GOVERNANCE.md criteria.
|
|
18
|
+
- **Docker Hub repository page sync.** After mirroring images, the `dockerhub-mirror`
|
|
19
|
+
workflow now pushes the repository README and the project tagline to the Docker Hub
|
|
20
|
+
repository description, so the Hub listing tracks the source. The step is non-fatal:
|
|
21
|
+
a description-API failure never blocks the image mirror or the release.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **Docker Hub mirroring is a reusable, dispatchable workflow.** The mirror moved from an
|
|
26
|
+
inline release job to `dockerhub-mirror.yml` (`workflow_call` from the release plus
|
|
27
|
+
`workflow_dispatch` to back-fill any version), with credentials read from the
|
|
28
|
+
`dockerhub` environment (`DOCKERHUB_USERNAME`, `DOCKERHUB_TOKEN`, optional
|
|
29
|
+
`DOCKERHUB_NAMESPACE`) instead of repository secrets.
|
|
30
|
+
- **Reporter copy uses ASCII separators.** The Markdown summary title format is now
|
|
31
|
+
``## shotgate: `name` (status)``, the no-assertion row prints `n/a`, and the plain
|
|
32
|
+
console fallback separates label and message with a colon; previously all three used
|
|
33
|
+
an em-dash. JUnit and JSON payloads are unchanged.
|
|
34
|
+
|
|
35
|
+
## [0.2.1] - 2026-06-11
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- **Full oracle coverage on hardware.** A non-gating diagnostic example,
|
|
40
|
+
`bell-state-hardware-oracle-coverage`, runs all five oracles on one Bell circuit so
|
|
41
|
+
`chi_square` also has a real-QPU data point. Measured on `ibm_fez`: the four
|
|
42
|
+
distance/structural oracles passed while `chi_square` returned p-value 0.0000
|
|
43
|
+
(statistic 1.5e17, dof 3), confirming why it is simulator-only. Mechanism and numbers
|
|
44
|
+
in `docs/hardware-validation.md` section 9.
|
|
45
|
+
- **GitHub-only install path in release notes.** Each release now documents installing the
|
|
46
|
+
attached wheel and pulling the GHCR image directly, so neither PyPI nor Docker Hub is
|
|
47
|
+
required to consume a release.
|
|
48
|
+
- **Optional Docker Hub mirror** in the release pipeline. When the `DOCKERHUB_USERNAME` and
|
|
49
|
+
`DOCKERHUB_TOKEN` repository secrets are present, released images are mirrored to Docker
|
|
50
|
+
Hub alongside the canonical GHCR images; absent the secrets the step is skipped and the
|
|
51
|
+
release is unaffected.
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
|
|
55
|
+
- **Portable device selection.** A pinned `ibm` device that the account or instance cannot
|
|
56
|
+
reach now raises a clear error listing the reachable real devices and pointing at the
|
|
57
|
+
`least_busy` default, instead of an opaque Qiskit lookup failure. The
|
|
58
|
+
`hardware-validation` workflow's device input now defaults to empty (`least_busy`) rather
|
|
59
|
+
than a pinned `ibm_fez`.
|
|
10
60
|
|
|
11
61
|
## [0.2.0] - 2026-06-11
|
|
12
62
|
|
|
@@ -76,7 +126,7 @@ All notable changes to this project are documented here. The format is based on
|
|
|
76
126
|
moved to the new name. The canonical home is `github.com/coldqubit/shotgate` and the
|
|
77
127
|
published image is `ghcr.io/coldqubit/shotgate`.
|
|
78
128
|
- **Pull-first usage.** Documentation now leads with `podman run
|
|
79
|
-
ghcr.io/coldqubit/shotgate
|
|
129
|
+
ghcr.io/coldqubit/shotgate ...`; building from source is the contributor fallback.
|
|
80
130
|
- **Honest extras.** `braket` and `mitigation` are marked *planned* and removed from the
|
|
81
131
|
installable `all` extra, since no Braket backend or Mitiq integration ships yet.
|
|
82
132
|
`--backend braket` now fails fast at schema validation with a clear message.
|
|
@@ -97,7 +147,7 @@ All notable changes to this project are documented here. The format is based on
|
|
|
97
147
|
- **Hardened IBM/QPU backend**: robust counts extraction from named classical registers
|
|
98
148
|
(with a clear error on unexpected result shapes), corrected Runtime channel default,
|
|
99
149
|
a token-gated smoke test, and an `[ibm]`-baked image variant (build arg
|
|
100
|
-
`SHOTGATE_EXTRAS="aer,ibm"`, published as the
|
|
150
|
+
`SHOTGATE_EXTRAS="aer,ibm"`, published as the `:...-ibm` image tag).
|
|
101
151
|
- **Noise-tolerant example** (`examples/bell-state-hardware/`) with relaxed thresholds
|
|
102
152
|
for real-device runs, plus a documented simulator-vs-QPU threshold split.
|
|
103
153
|
- **`docs/hardware-validation.md`**: a step-by-step plan and acceptance matrix for
|
|
@@ -143,7 +193,9 @@ All notable changes to this project are documented here. The format is based on
|
|
|
143
193
|
(with the math), getting-started guide, and ADRs.
|
|
144
194
|
- **Examples**: Bell state, 3-qubit GHZ, and 2-qubit Grover workflows.
|
|
145
195
|
|
|
146
|
-
[Unreleased]: https://github.com/coldqubit/shotgate/compare/v0.2.
|
|
196
|
+
[Unreleased]: https://github.com/coldqubit/shotgate/compare/v0.2.2...HEAD
|
|
197
|
+
[0.2.2]: https://github.com/coldqubit/shotgate/compare/v0.2.1...v0.2.2
|
|
198
|
+
[0.2.1]: https://github.com/coldqubit/shotgate/compare/v0.2.0...v0.2.1
|
|
147
199
|
[0.2.0]: https://github.com/coldqubit/shotgate/compare/v0.1.1...v0.2.0
|
|
148
200
|
[0.1.1]: https://github.com/coldqubit/shotgate/compare/v0.1.0...v0.1.1
|
|
149
201
|
[0.1.0]: https://github.com/coldqubit/shotgate/releases/tag/v0.1.0
|
|
@@ -7,11 +7,11 @@ favors small, well-tested, well-reasoned changes.
|
|
|
7
7
|
|
|
8
8
|
- Be kind; follow the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
9
9
|
- Discuss non-trivial changes in an issue first (especially new assertion oracles or
|
|
10
|
-
backends
|
|
10
|
+
backends, which have design implications).
|
|
11
11
|
- Keep the **validation core dependency-free** (standard library + pydantic). Quantum
|
|
12
12
|
SDKs are optional extras, imported lazily inside backends only.
|
|
13
13
|
|
|
14
|
-
## Development workflow (containers only
|
|
14
|
+
## Development workflow (containers only, no host installs)
|
|
15
15
|
|
|
16
16
|
Everything runs through Podman via the `Makefile`:
|
|
17
17
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# shotgate
|
|
1
|
+
# shotgate: Podman/QEMU task runner.
|
|
2
2
|
#
|
|
3
3
|
# Everything runs in containers or VMs; nothing is installed on the host.
|
|
4
4
|
# Override any variable on the command line, e.g. make run WORKFLOW=examples/ghz-state/workflow.yaml
|
|
@@ -14,7 +14,7 @@ MOUNT := -v "$(CURDIR):/work:Z" -w /work
|
|
|
14
14
|
RUN := $(PODMAN) run --rm $(MOUNT)
|
|
15
15
|
|
|
16
16
|
# Map the invoking host user through the container's user namespace so that
|
|
17
|
-
# report files written to the bind mount are owned by you
|
|
17
|
+
# report files written to the bind mount are owned by you, while the image
|
|
18
18
|
# keeps its non-root default user. The standard Podman idiom for this case.
|
|
19
19
|
USERMAP := --userns=keep-id --user $(shell id -u):$(shell id -g)
|
|
20
20
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shotgate
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Container-native CI/CD quality gates for quantum circuits: statistically validate probabilistic output across simulators and QPUs.
|
|
5
5
|
Project-URL: Homepage, https://github.com/coldqubit/shotgate
|
|
6
6
|
Project-URL: Documentation, https://github.com/coldqubit/shotgate/tree/main/docs
|
|
@@ -138,7 +138,7 @@ $ shotgate run examples/bell-state/workflow.yaml
|
|
|
138
138
|
The same run drops into a pipeline through the Markdown reporter (`--markdown`), rendered
|
|
139
139
|
as a step summary or a PR comment:
|
|
140
140
|
|
|
141
|
-
> ## shotgate: `bell-state`
|
|
141
|
+
> ## shotgate: `bell-state` (✅ passed)
|
|
142
142
|
>
|
|
143
143
|
> - Jobs: **1**, failed: **0**
|
|
144
144
|
> - Assertions: **5**, failed: **0**
|
|
@@ -180,6 +180,10 @@ podman run --rm -e SHOTGATE_IBM_TOKEN \
|
|
|
180
180
|
run examples/bell-state-hardware/workflow.yaml --backend ibm
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
+
The same images are mirrored to Docker Hub if you prefer it: swap the registry prefix for
|
|
184
|
+
`docker.io/coldqubit/shotgate` (tags `latest`, `latest-ibm`, and each version). GHCR is the
|
|
185
|
+
canonical registry; the Docker Hub copy is a convenience mirror.
|
|
186
|
+
|
|
183
187
|
### Path B: pip (CLI and pytest plugin)
|
|
184
188
|
|
|
185
189
|
Install the package with the backend extra you need (`aer` for the local simulator, `ibm` for
|
|
@@ -91,7 +91,7 @@ $ shotgate run examples/bell-state/workflow.yaml
|
|
|
91
91
|
The same run drops into a pipeline through the Markdown reporter (`--markdown`), rendered
|
|
92
92
|
as a step summary or a PR comment:
|
|
93
93
|
|
|
94
|
-
> ## shotgate: `bell-state`
|
|
94
|
+
> ## shotgate: `bell-state` (✅ passed)
|
|
95
95
|
>
|
|
96
96
|
> - Jobs: **1**, failed: **0**
|
|
97
97
|
> - Assertions: **5**, failed: **0**
|
|
@@ -133,6 +133,10 @@ podman run --rm -e SHOTGATE_IBM_TOKEN \
|
|
|
133
133
|
run examples/bell-state-hardware/workflow.yaml --backend ibm
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
+
The same images are mirrored to Docker Hub if you prefer it: swap the registry prefix for
|
|
137
|
+
`docker.io/coldqubit/shotgate` (tags `latest`, `latest-ibm`, and each version). GHCR is the
|
|
138
|
+
canonical registry; the Docker Hub copy is a convenience mirror.
|
|
139
|
+
|
|
136
140
|
### Path B: pip (CLI and pytest plugin)
|
|
137
141
|
|
|
138
142
|
Install the package with the backend extra you need (`aer` for the local simulator, `ibm` for
|
|
@@ -15,7 +15,7 @@ acknowledge within 72 hours and to provide a remediation timeline after triage.
|
|
|
15
15
|
|
|
16
16
|
## Security model (what to attack / what we defend)
|
|
17
17
|
|
|
18
|
-
- **Untrusted circuits.** Circuits are OpenQASM parsed by qiskit's QASM reader
|
|
18
|
+
- **Untrusted circuits.** Circuits are OpenQASM parsed by qiskit's QASM reader, not
|
|
19
19
|
`eval`'d Python. For circuits from untrusted sources, use the **VM isolation tier**
|
|
20
20
|
(`infra/qemu`), which runs the workflow in an ephemeral KVM micro-VM.
|
|
21
21
|
- **Secrets.** Provider tokens are read from environment variables / container `-e`
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
| [Pipeline Schema](pipeline.md) | How shotgate gates a CI/CD pipeline; stage contract; exit codes. |
|
|
8
8
|
| [Workflow Specification](workflow-spec.md) | The `shotgate.dev/v1alpha1` YAML schema, field by field. |
|
|
9
9
|
| [Assertion Catalog](assertions.md) | The statistical oracles, with the math and threshold guidance. |
|
|
10
|
-
| [Hardware Validation Plan](hardware-validation.md) | v0.2 runbook
|
|
10
|
+
| [Hardware Validation Plan](hardware-validation.md) | v0.2 milestone: runbook and measured `ibm_fez` baseline (2026-06-11). |
|
|
11
11
|
| [Motivation](motivation.md) | The market/community gap shotgate fills, with sources. |
|
|
12
12
|
| [ADRs](adr/) | Architecture Decision Records and their rationale. |
|
|
13
13
|
| [Diagrams](diagrams/) | Mermaid sources for the architecture and pipeline diagrams. |
|
|
14
14
|
|
|
15
15
|
Infrastructure docs live next to the code they describe:
|
|
16
16
|
|
|
17
|
-
- [Terraform module](../infra/terraform/README.md)
|
|
18
|
-
- [KVM/QEMU runner](../infra/qemu/README.md)
|
|
17
|
+
- [Terraform module](../infra/terraform/README.md): quantum workflow as code.
|
|
18
|
+
- [KVM/QEMU runner](../infra/qemu/README.md): ephemeral VM isolation tier.
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
## Context
|
|
7
7
|
|
|
8
8
|
shotgate sits at an immature intersection (quantum × DevOps) where the "right" design
|
|
9
|
-
is not yet settled by convention. Decisions
|
|
10
|
-
why a Terraform module instead of a provider
|
|
9
|
+
is not yet settled by convention. Decisions (why statistical oracles, why containers,
|
|
10
|
+
why a Terraform module instead of a provider) need to be legible to contributors and
|
|
11
11
|
to our future selves.
|
|
12
12
|
|
|
13
13
|
## Decision
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
Quantum programs are probabilistic; exact-equality assertions are either flaky or
|
|
9
9
|
vacuous. The academic literature (χ²-as-oracle, QUTest, QuCheck, QUT) establishes the
|
|
10
|
-
correct techniques
|
|
11
|
-
goodness-of-fit
|
|
10
|
+
correct techniques (total variation distance, Hellinger fidelity, chi-square
|
|
11
|
+
goodness-of-fit), but they live in research prototypes, not in production CI tooling.
|
|
12
12
|
Meanwhile DevOps writers repeatedly note that quantum CI "lacks robust test
|
|
13
|
-
frameworks" and needs "specialized validation
|
|
13
|
+
frameworks" and needs "specialized validation... in CI/CD pipelines".
|
|
14
14
|
|
|
15
15
|
We must also decide the dependency footprint. Pulling SciPy (for `chi2.sf`) and numpy
|
|
16
16
|
into the core would make the metrics layer heavy and couple it to a scientific stack.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ADR-0004: Rename qforge to shotgate (and the workflow apiVersion with it)
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-06-01
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
The project started on 2026-06-01 under the name `qforge`. Before any release was
|
|
9
|
+
tagged, two problems surfaced: the name was already taken on the package indexes
|
|
10
|
+
(PyPI and crates.io), and it raised a trademark concern on the VS Code marketplace.
|
|
11
|
+
The name is load-bearing in more places than the repository title: the Python
|
|
12
|
+
package, the command-line interface (CLI) program, the container image path, the
|
|
13
|
+
environment variables, and the workflow schema's `apiVersion` literal
|
|
14
|
+
(`qforge.dev/v1alpha1`) all embed it.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
Rename the project to **shotgate** everywhere the old name appeared: package
|
|
19
|
+
`src/shotgate`, CLI program `shotgate`, image `ghcr.io/coldqubit/shotgate`,
|
|
20
|
+
environment variable prefix `SHOTGATE_*`, and the workflow schema pin
|
|
21
|
+
`apiVersion: shotgate.dev/v1alpha1`. The schema pin is a pydantic `Literal`, so a
|
|
22
|
+
workflow declaring the old `qforge.dev/v1alpha1` fails schema validation rather
|
|
23
|
+
than being silently accepted.
|
|
24
|
+
|
|
25
|
+
## Consequences
|
|
26
|
+
|
|
27
|
+
- **+** The name is unique on PyPI and the container registries, so the package and
|
|
28
|
+
image are installable under their own name with no squatting or trademark risk.
|
|
29
|
+
- **+** It describes the product (gating on measurement shots) instead of a generic
|
|
30
|
+
"forge" metaphor.
|
|
31
|
+
- **−** The `apiVersion` change is breaking for any pre-rename workflow file. The
|
|
32
|
+
impact was zero in practice: the rename landed on 2026-06-01 and the first tagged
|
|
33
|
+
release (`v0.1.0`) followed on 2026-06-10, so no published package, image, or tag
|
|
34
|
+
ever carried the old name and no external consumer existed to break.
|
|
35
|
+
- The old name survives only in git history and in the `CHANGELOG.md` v0.1.0 notes.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# ADR-0005: License is Apache-2.0 (after MIT and an AGPL interlude)
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-06-08
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
The project's license changed twice before the first release settled it:
|
|
9
|
+
|
|
10
|
+
1. **MIT** at inception (2026-06-01).
|
|
11
|
+
2. **AGPL-3.0-or-later** later the same day, chosen for the network copyleft:
|
|
12
|
+
distributing the tool, or running a modified version as a hosted service, would
|
|
13
|
+
have required releasing source.
|
|
14
|
+
3. **Apache-2.0** on 2026-06-08, two days before the first tagged release.
|
|
15
|
+
|
|
16
|
+
The week under AGPL exposed a conflict with the adoption model. shotgate's target
|
|
17
|
+
user is a corporate continuous integration (CI) pipeline, and the quantum ecosystem
|
|
18
|
+
it builds on (Qiskit, Qiskit Aer, Cirq, Mitiq) is Apache-2.0 licensed; a
|
|
19
|
+
network-copyleft gate inside that stack invites legal review friction that a CI
|
|
20
|
+
utility cannot justify, and the "hosted modified service" trigger is ambiguous for a
|
|
21
|
+
tool whose whole purpose is to run inside other people's pipelines.
|
|
22
|
+
|
|
23
|
+
Relicensing was legally clean at that date: every line of source had a single
|
|
24
|
+
copyright holder (the maintainer), since the only third-party commits were
|
|
25
|
+
Dependabot version-range bumps and none had landed before the relicense commit.
|
|
26
|
+
|
|
27
|
+
## Decision
|
|
28
|
+
|
|
29
|
+
License the project **Apache-2.0**: verbatim license text in `LICENSE`, the
|
|
30
|
+
two-line SPDX header (`Apache-2.0`, `Copyright (C) 2026 coldqubit`) in all `src/`
|
|
31
|
+
files (17 files at the time), the `Apache-2.0` expression and classifier in
|
|
32
|
+
`pyproject.toml`, and the OCI license label in the `Containerfile`. Inbound
|
|
33
|
+
contributions are accepted under a Developer Certificate of Origin (DCO) sign-off
|
|
34
|
+
carrying the same Apache-2.0 terms (Apache-2.0 section 5), with no separate
|
|
35
|
+
contributor license agreement.
|
|
36
|
+
|
|
37
|
+
## Consequences
|
|
38
|
+
|
|
39
|
+
- **+** Permissive adoption: use, modification, and redistribution for any purpose,
|
|
40
|
+
including commercial and closed-source, retaining the license and attribution
|
|
41
|
+
notices (Apache-2.0 sections 4(a) through 4(d)).
|
|
42
|
+
- **+** An explicit patent grant (section 3), which MIT lacked.
|
|
43
|
+
- **+** License-compatible with the Apache-2.0 quantum SDK stack it imports.
|
|
44
|
+
- **−** The AGPL network-copyleft promise is removed, not replaced: a vendor can
|
|
45
|
+
ship a modified closed-source shotgate as a service.
|
|
46
|
+
- **−** Practically irreversible: once external DCO-signed contributions land,
|
|
47
|
+
relicensing again would require every contributor's consent. This ADR therefore
|
|
48
|
+
also fixes the inbound policy (DCO, same license in and out).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# ADR-0006: chi_square is simulator-only; hardware gates use distance, fidelity, and structural oracles
|
|
2
|
+
|
|
3
|
+
- **Status:** Accepted
|
|
4
|
+
- **Date:** 2026-06-11
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
The v0.2 milestone ran the example gates on a real quantum processing unit (QPU)
|
|
9
|
+
for the first time (`ibm_fez`, 156-qubit Heron r2, 4096 shots per job). Two facts
|
|
10
|
+
came out of those runs:
|
|
11
|
+
|
|
12
|
+
1. Simulator-tight thresholds (total variation distance (TVD) ≤ 0.03, Hellinger
|
|
13
|
+
fidelity ≥ 0.99, leakage ≤ 0.005) fail on a healthy device: the measured Bell
|
|
14
|
+
TVD was 0.1284 and the GHZ-3 TVD 0.1536.
|
|
15
|
+
2. `chi_square` fails on hardware for a mechanical reason, not a tuning one. The
|
|
16
|
+
non-gating diagnostic Bell job (`d8l592rqv2lc738621eg`) returned statistic
|
|
17
|
+
1.5e17, dof 3, p-value 0.0000, while the four distance/structural oracles passed
|
|
18
|
+
on the same counts (TVD 0.1350, fidelity 0.8650, leakage 0.1350, P(`00`) 0.4343).
|
|
19
|
+
The ideal expected distribution `{00: 0.5, 11: 0.5}` assigns probability 0 to
|
|
20
|
+
the error states `01`/`10`; the implementation floors expected counts at
|
|
21
|
+
`_MIN_EXPECTED = 1e-12` to keep the statistic finite, so each of the 553 leaked
|
|
22
|
+
shots contributes on the order of `observed^2 / 1e-12`. Against an ideal support,
|
|
23
|
+
any device leakage forces rejection regardless of thresholds.
|
|
24
|
+
|
|
25
|
+
## Decision
|
|
26
|
+
|
|
27
|
+
1. **Hardware gates use the distance, fidelity, marginal, and structural oracles**
|
|
28
|
+
(`distribution_tvd`, `hellinger_fidelity`, `state_probability`,
|
|
29
|
+
`allowed_states`) with noise-aware thresholds (Bell: TVD ≤ 0.15, fidelity
|
|
30
|
+
≥ 0.85, leakage ≤ 0.15; full table in `docs/hardware-validation.md` section 4),
|
|
31
|
+
encoded in the `examples/*-hardware` workflows.
|
|
32
|
+
2. **`chi_square` stays simulator-only** until a gate can declare a noise-aware
|
|
33
|
+
expected distribution (a device error model with nonzero mass on the error
|
|
34
|
+
states), which is out of scope for v0.2.
|
|
35
|
+
3. A **non-gating oracle-coverage diagnostic**
|
|
36
|
+
(`examples/bell-state-hardware-oracle-coverage`) keeps measuring all five
|
|
37
|
+
oracles on hardware so the exclusion stays evidence-based run over run.
|
|
38
|
+
|
|
39
|
+
## Consequences
|
|
40
|
+
|
|
41
|
+
- **+** The hardware gates pass a healthy device with measured margins of 0.0216
|
|
42
|
+
(Bell TVD, the tightest) to 0.1357 (Grover P(`11`)) while still bounding leakage
|
|
43
|
+
and fidelity, so they catch a broken circuit or mis-mapped qubits.
|
|
44
|
+
- **−** The formal hypothesis test is unavailable on hardware, so hardware gating
|
|
45
|
+
loses the goodness-of-fit (GoF) guarantee and relies on distance bounds instead.
|
|
46
|
+
- Revisit when an error-model expected distribution exists (candidate for the v0.3
|
|
47
|
+
error-mitigation work); the diagnostic's measurements will show when `chi_square`
|
|
48
|
+
becomes viable on devices.
|