shotgate 0.1.0__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.
Files changed (83) hide show
  1. shotgate-0.1.0/.containerignore +23 -0
  2. shotgate-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +44 -0
  3. shotgate-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +34 -0
  4. shotgate-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +24 -0
  5. shotgate-0.1.0/.github/dependabot.yml +19 -0
  6. shotgate-0.1.0/.github/workflows/ci.yml +134 -0
  7. shotgate-0.1.0/.github/workflows/release.yml +129 -0
  8. shotgate-0.1.0/.gitignore +48 -0
  9. shotgate-0.1.0/.gitlab-ci.yml +57 -0
  10. shotgate-0.1.0/CHANGELOG.md +103 -0
  11. shotgate-0.1.0/CODEOWNERS +9 -0
  12. shotgate-0.1.0/CODE_OF_CONDUCT.md +37 -0
  13. shotgate-0.1.0/CONTRIBUTING.md +82 -0
  14. shotgate-0.1.0/Containerfile +73 -0
  15. shotgate-0.1.0/GOVERNANCE.md +48 -0
  16. shotgate-0.1.0/Jenkinsfile +60 -0
  17. shotgate-0.1.0/LICENSE +202 -0
  18. shotgate-0.1.0/MAINTAINERS.md +42 -0
  19. shotgate-0.1.0/Makefile +105 -0
  20. shotgate-0.1.0/NOTICE +7 -0
  21. shotgate-0.1.0/PKG-INFO +326 -0
  22. shotgate-0.1.0/README.md +279 -0
  23. shotgate-0.1.0/SECURITY.md +33 -0
  24. shotgate-0.1.0/docs/README.md +18 -0
  25. shotgate-0.1.0/docs/adr/0001-record-architecture-decisions.md +24 -0
  26. shotgate-0.1.0/docs/adr/0002-statistical-validation-core.md +38 -0
  27. shotgate-0.1.0/docs/adr/0003-container-and-vm-isolation.md +44 -0
  28. shotgate-0.1.0/docs/architecture.md +150 -0
  29. shotgate-0.1.0/docs/assertions.md +137 -0
  30. shotgate-0.1.0/docs/assets/bell-state-demo.svg +63 -0
  31. shotgate-0.1.0/docs/diagrams/architecture.mmd +26 -0
  32. shotgate-0.1.0/docs/diagrams/pipeline.mmd +12 -0
  33. shotgate-0.1.0/docs/getting-started.md +126 -0
  34. shotgate-0.1.0/docs/hardware-validation.md +133 -0
  35. shotgate-0.1.0/docs/motivation.md +76 -0
  36. shotgate-0.1.0/docs/pipeline.md +145 -0
  37. shotgate-0.1.0/docs/workflow-spec.md +87 -0
  38. shotgate-0.1.0/examples/bell-state/bell.qasm +8 -0
  39. shotgate-0.1.0/examples/bell-state/workflow.yaml +43 -0
  40. shotgate-0.1.0/examples/bell-state-hardware/bell.qasm +8 -0
  41. shotgate-0.1.0/examples/bell-state-hardware/workflow.yaml +40 -0
  42. shotgate-0.1.0/examples/ghz-state/ghz.qasm +9 -0
  43. shotgate-0.1.0/examples/ghz-state/workflow.yaml +31 -0
  44. shotgate-0.1.0/examples/grover-2q/grover.qasm +22 -0
  45. shotgate-0.1.0/examples/grover-2q/workflow.yaml +30 -0
  46. shotgate-0.1.0/infra/qemu/README.md +49 -0
  47. shotgate-0.1.0/infra/qemu/cloud-init/meta-data +2 -0
  48. shotgate-0.1.0/infra/qemu/cloud-init/user-data +43 -0
  49. shotgate-0.1.0/infra/qemu/create-runner-vm.sh +133 -0
  50. shotgate-0.1.0/infra/terraform/README.md +64 -0
  51. shotgate-0.1.0/infra/terraform/examples/basic/main.tf +22 -0
  52. shotgate-0.1.0/infra/terraform/main.tf +61 -0
  53. shotgate-0.1.0/infra/terraform/outputs.tf +19 -0
  54. shotgate-0.1.0/infra/terraform/variables.tf +58 -0
  55. shotgate-0.1.0/infra/terraform/versions.tf +4 -0
  56. shotgate-0.1.0/pyproject.toml +101 -0
  57. shotgate-0.1.0/scripts/demo.sh +41 -0
  58. shotgate-0.1.0/src/shotgate/__init__.py +24 -0
  59. shotgate-0.1.0/src/shotgate/__main__.py +8 -0
  60. shotgate-0.1.0/src/shotgate/backends/__init__.py +19 -0
  61. shotgate-0.1.0/src/shotgate/backends/base.py +53 -0
  62. shotgate-0.1.0/src/shotgate/backends/ibm_runtime.py +153 -0
  63. shotgate-0.1.0/src/shotgate/backends/local_aer.py +46 -0
  64. shotgate-0.1.0/src/shotgate/backends/registry.py +89 -0
  65. shotgate-0.1.0/src/shotgate/circuits/__init__.py +7 -0
  66. shotgate-0.1.0/src/shotgate/circuits/loader.py +57 -0
  67. shotgate-0.1.0/src/shotgate/cli.py +130 -0
  68. shotgate-0.1.0/src/shotgate/config.py +178 -0
  69. shotgate-0.1.0/src/shotgate/pytest_plugin.py +195 -0
  70. shotgate-0.1.0/src/shotgate/report.py +183 -0
  71. shotgate-0.1.0/src/shotgate/runner.py +153 -0
  72. shotgate-0.1.0/src/shotgate/telemetry.py +40 -0
  73. shotgate-0.1.0/src/shotgate/validation/__init__.py +11 -0
  74. shotgate-0.1.0/src/shotgate/validation/assertions.py +240 -0
  75. shotgate-0.1.0/src/shotgate/validation/metrics.py +247 -0
  76. shotgate-0.1.0/tests/conftest.py +7 -0
  77. shotgate-0.1.0/tests/test_assertions.py +108 -0
  78. shotgate-0.1.0/tests/test_config.py +116 -0
  79. shotgate-0.1.0/tests/test_ibm_backend.py +144 -0
  80. shotgate-0.1.0/tests/test_metrics.py +101 -0
  81. shotgate-0.1.0/tests/test_pytest_plugin.py +177 -0
  82. shotgate-0.1.0/tests/test_report.py +71 -0
  83. shotgate-0.1.0/tests/test_runner_integration.py +72 -0
@@ -0,0 +1,23 @@
1
+ # Keep the build context small and reproducible.
2
+ .git
3
+ .github
4
+ .venv
5
+ venv
6
+ **/__pycache__
7
+ **/*.pyc
8
+ .pytest_cache
9
+ .ruff_cache
10
+ .mypy_cache
11
+ htmlcov
12
+ *.egg-info
13
+ dist
14
+ build
15
+ docs
16
+ infra
17
+ report-quantum-devops.md
18
+ *.xml
19
+ *.json
20
+ !examples/**/*.json
21
+ .gitignore
22
+ .containerignore
23
+ .dockerignore
@@ -0,0 +1,44 @@
1
+ name: Bug report
2
+ description: Report incorrect behavior in shotgate
3
+ labels: ["bug"]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: Thanks for filing a bug! Please include enough detail to reproduce it.
8
+ - type: textarea
9
+ id: what-happened
10
+ attributes:
11
+ label: What happened?
12
+ description: A clear description of the bug and what you expected instead.
13
+ validations:
14
+ required: true
15
+ - type: textarea
16
+ id: workflow
17
+ attributes:
18
+ label: Workflow YAML
19
+ description: The (minimal) workflow that reproduces the issue.
20
+ render: yaml
21
+ - type: textarea
22
+ id: command
23
+ attributes:
24
+ label: Command and output
25
+ description: How you ran shotgate (e.g. `make run WORKFLOW=...`) and the output.
26
+ render: shell
27
+ - type: input
28
+ id: version
29
+ attributes:
30
+ label: shotgate version / image tag
31
+ validations:
32
+ required: true
33
+ - type: dropdown
34
+ id: backend
35
+ attributes:
36
+ label: Backend
37
+ options: [local-aer, ibm, braket, other]
38
+ validations:
39
+ required: true
40
+ - type: input
41
+ id: environment
42
+ attributes:
43
+ label: Environment
44
+ description: Podman/QEMU versions, host OS.
@@ -0,0 +1,34 @@
1
+ name: Feature request
2
+ description: Suggest a new assertion oracle, backend, reporter, or capability
3
+ labels: ["enhancement"]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem
9
+ description: What can't you do today? What quantum-DevOps gap does this close?
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ description: Sketch the YAML/CLI/API you'd want. Statistical rationale welcome.
17
+ validations:
18
+ required: true
19
+ - type: dropdown
20
+ id: area
21
+ attributes:
22
+ label: Area
23
+ options:
24
+ - Assertion oracle
25
+ - Backend (provider)
26
+ - Reporter / integration
27
+ - Infrastructure (Terraform / QEMU / Helm)
28
+ - Other
29
+ validations:
30
+ required: true
31
+ - type: textarea
32
+ id: alternatives
33
+ attributes:
34
+ label: Alternatives considered
@@ -0,0 +1,24 @@
1
+ # Summary
2
+
3
+ <!-- What does this PR change and why? Link any related issues. -->
4
+
5
+ ## Type of change
6
+
7
+ - [ ] Bug fix
8
+ - [ ] New feature (new assertion oracle / backend / reporter)
9
+ - [ ] Documentation
10
+ - [ ] Infrastructure (Containerfile, CI, Terraform, QEMU)
11
+
12
+ ## Checklist
13
+
14
+ - [ ] `make check` passes (ruff + full test suite in containers)
15
+ - [ ] New/changed behavior is covered by tests
16
+ - [ ] Docs updated (`docs/`, `README.md`) where relevant
17
+ - [ ] For a new assertion type: added to `ASSERTION_TYPES`, documented in
18
+ `docs/assertions.md`, and covered by a unit test
19
+ - [ ] For a new backend: registered in `backends/registry.py` and import-guarded
20
+ so the validation core stays SDK-free
21
+
22
+ ## Notes for reviewers
23
+
24
+ <!-- Anything that needs special attention, trade-offs, or follow-ups. -->
@@ -0,0 +1,19 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ groups:
8
+ python-deps:
9
+ patterns: ["*"]
10
+
11
+ - package-ecosystem: github-actions
12
+ directory: "/"
13
+ schedule:
14
+ interval: weekly
15
+
16
+ - package-ecosystem: docker
17
+ directory: "/"
18
+ schedule:
19
+ interval: weekly
@@ -0,0 +1,134 @@
1
+ name: ci
2
+
3
+ # Container-native CI: every job runs tools inside Podman containers, mirroring
4
+ # exactly what a developer gets locally with `make`. No language toolchains are
5
+ # installed onto the runner directly.
6
+ #
7
+ # NOTE: This is shotgate's OWN repository CI, so it builds the image from source to
8
+ # test the code under change. CONSUMERS should instead *pull* the published image
9
+ # (`podman run ghcr.io/coldqubit/shotgate:latest run workflow.yaml`), as shown in
10
+ # README.md and the GitLab/Jenkins references in docs/pipeline.md.
11
+
12
+ on:
13
+ push:
14
+ branches: [main]
15
+ pull_request:
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ concurrency:
21
+ group: ci-${{ github.ref }}
22
+ cancel-in-progress: true
23
+
24
+ jobs:
25
+ lint-and-core-tests:
26
+ name: lint + core tests
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+
31
+ - name: ruff + mypy + core unit tests (containerized)
32
+ run: |
33
+ podman run --rm -v "$PWD:/work:Z" -w /work \
34
+ docker.io/library/python:3.12-slim bash -euc "
35
+ pip install -q -e '.[dev]'
36
+ ruff check src tests
37
+ mypy
38
+ pytest -q -m 'not integration' --junitxml=core-junit.xml
39
+ "
40
+
41
+ - name: Upload core test report
42
+ if: always()
43
+ uses: actions/upload-artifact@v4
44
+ with:
45
+ name: core-junit
46
+ path: core-junit.xml
47
+
48
+ image-and-integration:
49
+ name: build image + integration + example gates
50
+ runs-on: ubuntu-latest
51
+ steps:
52
+ - uses: actions/checkout@v4
53
+
54
+ - name: Build shotgate runtime image
55
+ run: podman build -t shotgate:ci .
56
+
57
+ - name: Build test image and run full suite (unit + integration)
58
+ run: |
59
+ podman build --target test -t shotgate:ci-test .
60
+ podman run --rm -v "$PWD:/work:Z" shotgate:ci-test \
61
+ pytest -q --junitxml=/work/integration-junit.xml
62
+
63
+ - name: Run example workflows as quality gates
64
+ run: |
65
+ set -euo pipefail
66
+ # Map the runner user through the container userns so reports are writable.
67
+ USERMAP="--userns=keep-id --user $(id -u):$(id -g)"
68
+ for wf in bell-state ghz-state grover-2q; do
69
+ echo "::group::shotgate run examples/${wf}"
70
+ podman run --rm $USERMAP -v "$PWD:/work:Z" -w /work shotgate:ci \
71
+ run "examples/${wf}/workflow.yaml" \
72
+ --junit "report-${wf}.xml" --markdown "summary-${wf}.md"
73
+ cat "summary-${wf}.md" >> "$GITHUB_STEP_SUMMARY"
74
+ echo "::endgroup::"
75
+ done
76
+
77
+ - name: Upload reports
78
+ if: always()
79
+ uses: actions/upload-artifact@v4
80
+ with:
81
+ name: shotgate-reports
82
+ path: |
83
+ report-*.xml
84
+ integration-junit.xml
85
+
86
+ pip-consumer-path:
87
+ name: pip path (CLI + pytest plugin)
88
+ runs-on: ubuntu-latest
89
+ steps:
90
+ - uses: actions/checkout@v4
91
+
92
+ - name: pip install and exercise the CLI and pytest plugin (containerized)
93
+ run: |
94
+ podman run --rm -v "$PWD:/work:Z" -w /work \
95
+ docker.io/library/python:3.12-slim bash -euc "
96
+ pip install -q '.[aer,dev]'
97
+ # The pytest11 entry point must expose --shotgate after a pip install.
98
+ pytest --help 2>/dev/null | grep -q -- '--shotgate'
99
+ # CLI consumer path: gate a Bell workflow and emit a JUnit report.
100
+ shotgate run examples/bell-state/workflow.yaml --junit cli-junit.xml
101
+ # Plugin consumer path: in an isolated directory (free of this repo's
102
+ # pytest testpaths), each assertion of the workflow becomes one pytest
103
+ # item. pytest exits non-zero if nothing is collected or a gate fails.
104
+ cp -r examples/bell-state /tmp/gate
105
+ cd /tmp/gate
106
+ pytest -q --shotgate workflow.yaml --junitxml=/work/plugin-junit.xml
107
+ "
108
+
109
+ - name: Upload pip-path reports
110
+ if: always()
111
+ uses: actions/upload-artifact@v4
112
+ with:
113
+ name: pip-path-junit
114
+ path: |
115
+ cli-junit.xml
116
+ plugin-junit.xml
117
+
118
+ terraform:
119
+ name: terraform fmt + validate
120
+ runs-on: ubuntu-latest
121
+ steps:
122
+ - uses: actions/checkout@v4
123
+
124
+ - name: Format check
125
+ run: |
126
+ podman run --rm -v "$PWD:/work:Z" -w /work \
127
+ docker.io/hashicorp/terraform:latest -chdir=infra/terraform fmt -check -recursive
128
+
129
+ - name: Init + validate example
130
+ run: |
131
+ podman run --rm -v "$PWD:/work:Z" -w /work \
132
+ docker.io/hashicorp/terraform:latest -chdir=infra/terraform/examples/basic init -backend=false -input=false
133
+ podman run --rm -v "$PWD:/work:Z" -w /work \
134
+ docker.io/hashicorp/terraform:latest -chdir=infra/terraform/examples/basic validate
@@ -0,0 +1,129 @@
1
+ name: release
2
+
3
+ # Triggered by a semver tag (e.g. v0.1.0). Builds the Python distribution and the
4
+ # container image, publishes the image to GHCR, and attaches the dist to the
5
+ # GitHub Release. Everything is built inside containers.
6
+
7
+ on:
8
+ push:
9
+ tags:
10
+ - "v*.*.*"
11
+
12
+ permissions:
13
+ contents: write
14
+ packages: write
15
+
16
+ jobs:
17
+ build-dist:
18
+ name: build python distribution
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - name: Build sdist + wheel (containerized)
24
+ run: |
25
+ podman run --rm -v "$PWD:/work:Z" -w /work \
26
+ docker.io/library/python:3.12-slim bash -euc "
27
+ pip install -q build
28
+ python -m build
29
+ "
30
+
31
+ - name: Upload distribution artifacts
32
+ uses: actions/upload-artifact@v4
33
+ with:
34
+ name: dist
35
+ path: dist/*
36
+
37
+ publish-image:
38
+ name: publish container image to GHCR
39
+ runs-on: ubuntu-latest
40
+ needs: build-dist
41
+ steps:
42
+ - uses: actions/checkout@v4
43
+
44
+ - name: Compute image refs
45
+ id: meta
46
+ run: |
47
+ # ghcr.io/coldqubit/shotgate when hosted at github.com/coldqubit/shotgate
48
+ IMG="ghcr.io/${GITHUB_REPOSITORY,,}"
49
+ VERSION="${GITHUB_REF_NAME#v}" # strip leading 'v' from the tag
50
+ SHA="${GITHUB_SHA::12}" # short git sha
51
+ {
52
+ echo "image=${IMG}"
53
+ echo "version=${VERSION}"
54
+ echo "sha=${SHA}"
55
+ } >> "$GITHUB_OUTPUT"
56
+
57
+ - name: Log in to GHCR
58
+ run: |
59
+ echo "${{ secrets.GITHUB_TOKEN }}" | \
60
+ podman login ghcr.io -u "${{ github.actor }}" --password-stdin
61
+
62
+ - name: Build and push runtime image (aer)
63
+ env:
64
+ IMG: ${{ steps.meta.outputs.image }}
65
+ VERSION: ${{ steps.meta.outputs.version }}
66
+ SHA: ${{ steps.meta.outputs.sha }}
67
+ run: |
68
+ # Tags: semver version, git sha, and latest.
69
+ podman build \
70
+ -t "${IMG}:${VERSION}" \
71
+ -t "${IMG}:${SHA}" \
72
+ -t "${IMG}:latest" .
73
+ podman push "${IMG}:${VERSION}"
74
+ podman push "${IMG}:${SHA}"
75
+ podman push "${IMG}:latest"
76
+
77
+ - name: Build and push IBM variant (aer + qiskit-ibm-runtime)
78
+ env:
79
+ IMG: ${{ steps.meta.outputs.image }}
80
+ VERSION: ${{ steps.meta.outputs.version }}
81
+ run: |
82
+ # Cloud/QPU-capable image so the ibm backend is runnable from a pull.
83
+ podman build --build-arg SHOTGATE_EXTRAS="aer,ibm" \
84
+ -t "${IMG}:${VERSION}-ibm" \
85
+ -t "${IMG}:latest-ibm" .
86
+ podman push "${IMG}:${VERSION}-ibm"
87
+ podman push "${IMG}:latest-ibm"
88
+
89
+ publish-pypi:
90
+ name: publish to PyPI (trusted publishing)
91
+ runs-on: ubuntu-latest
92
+ needs: build-dist
93
+ # OIDC, no API token. GitHub mints a signed identity token that PyPI verifies
94
+ # against a configured trusted publisher. One-time setup on PyPI before the
95
+ # first tag: pypi.org -> the `shotgate` project (or a "pending publisher" if it
96
+ # does not exist yet) -> add a GitHub publisher with
97
+ # owner: coldqubit repo: shotgate workflow: release.yml environment: pypi
98
+ environment:
99
+ name: pypi
100
+ url: https://pypi.org/p/shotgate
101
+ permissions:
102
+ id-token: write
103
+ steps:
104
+ - name: Download distribution artifacts
105
+ uses: actions/download-artifact@v4
106
+ with:
107
+ name: dist
108
+ path: dist
109
+
110
+ - name: Publish to PyPI
111
+ uses: pypa/gh-action-pypi-publish@release/v1
112
+ with:
113
+ packages-dir: dist
114
+
115
+ github-release:
116
+ name: create github release
117
+ runs-on: ubuntu-latest
118
+ needs: [build-dist, publish-image, publish-pypi]
119
+ steps:
120
+ - uses: actions/checkout@v4
121
+ - uses: actions/download-artifact@v4
122
+ with:
123
+ name: dist
124
+ path: dist
125
+ - name: Create release
126
+ uses: softprops/action-gh-release@v2
127
+ with:
128
+ files: dist/*
129
+ generate_release_notes: true
@@ -0,0 +1,48 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ dist/
7
+ build/
8
+ .venv/
9
+ venv/
10
+
11
+ # Test / coverage / type / lint caches
12
+ .pytest_cache/
13
+ .coverage
14
+ coverage.xml
15
+ htmlcov/
16
+ .mypy_cache/
17
+ .ruff_cache/
18
+
19
+ # shotgate reports
20
+ report.xml
21
+ report.json
22
+ summary.md
23
+ *.shotgate.json
24
+
25
+ # Terraform
26
+ infra/terraform/**/.terraform/
27
+ infra/terraform/**/*.tfstate
28
+ infra/terraform/**/*.tfstate.*
29
+ infra/terraform/**/.terraform.lock.hcl
30
+ crash.log
31
+
32
+ # QEMU/KVM artifacts (downloaded images, overlays, seeds)
33
+ infra/qemu/.cache/
34
+ *.qcow2
35
+ seed.iso
36
+
37
+ # Editor / OS
38
+ .idea/
39
+ .vscode/
40
+ .DS_Store
41
+
42
+ # Stray caches (e.g. XDG cache when running python in a container with cwd HOME)
43
+ .cache/
44
+
45
+ # Local AI-assistant context (not part of the project)
46
+ CLAUDE.md
47
+ CLAUDE.local.md
48
+ .claude/
@@ -0,0 +1,57 @@
1
+ # Reference GitLab CI for gating a pipeline on a shotgate quantum workflow.
2
+ #
3
+ # Copy this into your own repo. It PULLS the published image (no build step) and runs
4
+ # the gate as a container job, emitting a JUnit report so the stage turns red when a
5
+ # statistical assertion fails. Exit-code contract: 0 = pass, 1 = a gate failed,
6
+ # 2 = bad config. The contract matches the GitHub Actions and Jenkins references.
7
+
8
+ stages:
9
+ - quantum
10
+
11
+ variables:
12
+ SHOTGATE_IMAGE: "ghcr.io/coldqubit/shotgate:latest"
13
+ WORKFLOW: "examples/bell-state/workflow.yaml"
14
+
15
+ quantum-gate:
16
+ stage: quantum
17
+ image: "$SHOTGATE_IMAGE"
18
+ script:
19
+ # The image entrypoint is `shotgate`; GitLab overrides it, so call it explicitly.
20
+ - shotgate run "$WORKFLOW" --junit report.xml --json report.json
21
+ artifacts:
22
+ when: always
23
+ paths:
24
+ - report.json
25
+ reports:
26
+ junit: report.xml
27
+
28
+ # Cloud/QPU variant: switch to the :latest-ibm image and provide a token via a
29
+ # masked CI/CD variable (Settings -> CI/CD -> Variables: SHOTGATE_IBM_TOKEN).
30
+ #
31
+ # quantum-gate-qpu:
32
+ # stage: quantum
33
+ # image: "ghcr.io/coldqubit/shotgate:latest-ibm"
34
+ # script:
35
+ # - shotgate run examples/bell-state-hardware/workflow.yaml --backend ibm --junit report.xml
36
+ # artifacts:
37
+ # when: always
38
+ # reports:
39
+ # junit: report.xml
40
+ # rules:
41
+ # - if: '$SHOTGATE_IBM_TOKEN'
42
+
43
+ # Pip alternative (no image pull): install the package and gate with the CLI or the
44
+ # pytest plugin instead of pulling the container image.
45
+ #
46
+ # quantum-gate-pip:
47
+ # stage: quantum
48
+ # image: "python:3.12-slim"
49
+ # script:
50
+ # - pip install "shotgate[aer]"
51
+ # - shotgate run "$WORKFLOW" --junit report.xml # CLI path
52
+ # # or one pytest item per assertion (the pytest plugin):
53
+ # - pytest --shotgate "$WORKFLOW" --junitxml=report.xml
54
+ # artifacts:
55
+ # when: always
56
+ # reports:
57
+ # junit: report.xml
@@ -0,0 +1,103 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ *Nothing yet.*
10
+
11
+ ## [0.1.0] - 2026-06-10
12
+
13
+ > First public, tagged release. The codebase began on 2026-06-01 under the name `qforge`
14
+ > and was renamed to `shotgate`; it had no prior git tag, PyPI release, or published
15
+ > container image, so this is the project's first release of record. The capability
16
+ > baseline (workflows, oracles, backends, CLI, reporters, IaC, isolation) is listed under
17
+ > **Core capabilities** below; the entries above it are what changed on the way to release.
18
+
19
+ ### Changed
20
+
21
+ - **Relicensed from AGPL-3.0-or-later to Apache-2.0.** The `LICENSE` file now carries the
22
+ verbatim Apache License 2.0 text, every `src/shotgate/**/*.py` SPDX header reads
23
+ `Apache-2.0`, and `pyproject.toml` declares `license = "Apache-2.0"` with the
24
+ `License :: OSI Approved :: Apache Software License` classifier. Apache-2.0 is permissive:
25
+ use, modification, and redistribution are allowed for any purpose, including commercial and
26
+ closed-source, provided the license and attribution notices are retained. The previous
27
+ network-copyleft (source-disclosure for hosted modified versions) no longer applies.
28
+ - **Renamed the project from `qforge` to `shotgate`.** The name `qforge` was already
29
+ taken (PyPI/crates) and raised a VS Code marketplace trademark concern. The package
30
+ (`src/shotgate`), CLI program, container image, environment variables
31
+ (`SHOTGATE_IBM_TOKEN`), and the workflow API version (`shotgate.dev/v1alpha1`) all
32
+ moved to the new name. The canonical home is `github.com/coldqubit/shotgate` and the
33
+ published image is `ghcr.io/coldqubit/shotgate`.
34
+ - **Pull-first usage.** Documentation now leads with `podman run
35
+ ghcr.io/coldqubit/shotgate …`; building from source is the contributor fallback.
36
+ - **Honest extras.** `braket` and `mitigation` are marked *planned* and removed from the
37
+ installable `all` extra, since no Braket backend or Mitiq integration ships yet.
38
+ `--backend braket` now fails fast at schema validation with a clear message.
39
+ - **Project identity and governance made consistent.** Committed files refer to the
40
+ project home as `coldqubit` and to the maintainer *role* rather than to a personal
41
+ account: the README maintainer note was rewritten, [`CODEOWNERS`](CODEOWNERS) now
42
+ points at the `@coldqubit/maintainers` team, and the contribution terms were aligned.
43
+ The `CONTRIBUTING.md` inbound-license statement, which incorrectly named the MIT
44
+ License, now correctly states Apache-2.0 and is expressed as a Developer Certificate of
45
+ Origin (DCO) sign-off.
46
+
47
+ ### Added
48
+
49
+ - **Published container image** to GHCR on tag, tagged with the semver version, the
50
+ git SHA, and `latest` (release pipeline).
51
+ - **Reference CI for GitLab and Jenkins** (`.gitlab-ci.yml`, `Jenkinsfile`) that pull the
52
+ published image and emit JUnit, alongside the existing GitHub Actions example.
53
+ - **Hardened IBM/QPU backend**: robust counts extraction from named classical registers
54
+ (with a clear error on unexpected result shapes), corrected Runtime channel default,
55
+ a token-gated smoke test, and an `[ibm]`-baked image variant (build arg
56
+ `SHOTGATE_EXTRAS="aer,ibm"`, published as the `:…-ibm` image tag).
57
+ - **Noise-tolerant example** (`examples/bell-state-hardware/`) with relaxed thresholds
58
+ for real-device runs, plus a documented simulator-vs-QPU threshold split.
59
+ - **`docs/hardware-validation.md`**: a step-by-step plan and acceptance matrix for
60
+ validating the statistical gates on real IBM quantum hardware (v0.2 milestone).
61
+ - **`GOVERNANCE.md` and `MAINTAINERS.md`**: how decisions are made (lazy consensus,
62
+ Architecture Decision Records for substantial changes, single maintainer today and
63
+ structured to grow) and who maintains the project, including the concrete path for a
64
+ co-maintainer to join.
65
+ - **Automated PyPI publishing** via trusted publishing (OIDC, no stored token): the tagged
66
+ release pipeline builds the sdist + wheel and publishes them to PyPI alongside the GHCR
67
+ image and the GitHub Release, so `pip install shotgate[aer]` resolves from a tag.
68
+ - **README terminal visual** (`docs/assets/bell-state-demo.svg`): a branded render of the
69
+ `examples/bell-state` gate output (five passing oracles), plus a live CI status badge.
70
+
71
+ > The `ibm` backend remains **implemented but not yet validated on real hardware**.
72
+
73
+ ### Core capabilities
74
+
75
+ > The feature baseline, first built under the name `qforge` (workflow API `qforge.dev/v1alpha1`,
76
+ > since renamed to `shotgate.dev/v1alpha1`).
77
+
78
+ - **Declarative workflows** (`qforge.dev/v1alpha1`): strict, Kubernetes-style YAML
79
+ schema for "quantum workflow as code" with workflow-level backend defaults.
80
+ - **Statistical assertion oracles**: `distribution_tvd`, `hellinger_fidelity`,
81
+ `chi_square` (Pearson goodness-of-fit), `state_probability`, `allowed_states`.
82
+ - **Pure-Python statistics core**: total variation distance, Hellinger fidelity, and a
83
+ from-scratch chi-square survival function via the regularised incomplete gamma
84
+ function (no SciPy/numpy dependency).
85
+ - **Pluggable backends**: `Backend` ABC + lazy registry; `local-aer` (Qiskit Aer) and
86
+ an `ibm` (Qiskit Runtime) backend. SDKs imported lazily so the core stays light.
87
+ - **CLI**: `shotgate run` (CI quality gate, exit 0/1/2), `validate`, `backends`.
88
+ - **Reporters**: JUnit XML, JSON, Markdown summary, and Rich console output.
89
+ - **Telemetry**: per-job circuit width/depth/size/op-counts and wall-clock runtime.
90
+ - **Container-native tooling**: multi-stage `Containerfile` (non-root runtime + test
91
+ stage) and a Podman/QEMU `Makefile`.
92
+ - **KVM/QEMU isolation tier**: `infra/qemu` boots an ephemeral Fedora micro-VM
93
+ (cloud-init, copy-on-write overlay) that runs shotgate in Podman inside the VM.
94
+ - **Terraform IaC module**: express a quantum quality gate as a `terraform_data`
95
+ resource driven by the shotgate container.
96
+ - **CI/CD**: Podman-based GitHub Actions for lint, core + integration tests, example
97
+ gates, Terraform validation, and a tagged release pipeline (dist + GHCR image).
98
+ - **Docs**: solution architecture, pipeline schema, workflow spec, assertion catalog
99
+ (with the math), getting-started guide, and ADRs.
100
+ - **Examples**: Bell state, 3-qubit GHZ, and 2-qubit Grover workflows.
101
+
102
+ [Unreleased]: https://github.com/coldqubit/shotgate/compare/v0.1.0...HEAD
103
+ [0.1.0]: https://github.com/coldqubit/shotgate/releases/tag/v0.1.0
@@ -0,0 +1,9 @@
1
+ # Code owners for shotgate. The project is developed under the coldqubit project home
2
+ # and is maintained today by one person; MAINTAINERS.md is the source of truth for the
3
+ # current roster, and GOVERNANCE.md for how that roster changes.
4
+ #
5
+ # Ownership points at the @coldqubit/maintainers team rather than any personal account,
6
+ # so review requests track the maintainer role, not an individual. Create that team in
7
+ # the coldqubit organization on GitHub (members = the people in MAINTAINERS.md) for
8
+ # these entries to resolve.
9
+ * @coldqubit/maintainers
@@ -0,0 +1,37 @@
1
+ # Code of Conduct
2
+
3
+ ## Our pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in the shotgate
6
+ community a harassment-free experience for everyone, regardless of age, body size,
7
+ visible or invisible disability, ethnicity, sex characteristics, gender identity and
8
+ expression, level of experience, education, socio-economic status, nationality,
9
+ personal appearance, race, religion, or sexual identity and orientation.
10
+
11
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse,
12
+ inclusive, and healthy community.
13
+
14
+ ## Our standards
15
+
16
+ Examples of behavior that contributes to a positive environment:
17
+
18
+ - Demonstrating empathy and kindness toward other people
19
+ - Being respectful of differing opinions, viewpoints, and experiences
20
+ - Giving and gracefully accepting constructive feedback
21
+ - Focusing on what is best for the overall community
22
+
23
+ Unacceptable behavior includes harassment, trolling, insulting or derogatory comments,
24
+ public or private harassment, publishing others' private information without consent,
25
+ and other conduct which could reasonably be considered inappropriate.
26
+
27
+ ## Enforcement
28
+
29
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to
30
+ the maintainers listed in `CODEOWNERS`. All complaints will be reviewed and
31
+ investigated promptly and fairly. Maintainers will respect the privacy and security of
32
+ the reporter.
33
+
34
+ ## Attribution
35
+
36
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
37
+ version 2.1.