evidence-gate 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 (47) hide show
  1. evidence_gate-0.1.0/.github/workflows/ci.yml +21 -0
  2. evidence_gate-0.1.0/.gitignore +11 -0
  3. evidence_gate-0.1.0/CHANGELOG.md +9 -0
  4. evidence_gate-0.1.0/LICENSE +21 -0
  5. evidence_gate-0.1.0/PKG-INFO +185 -0
  6. evidence_gate-0.1.0/README.md +159 -0
  7. evidence_gate-0.1.0/examples/integrate_with_existing_gate.py +31 -0
  8. evidence_gate-0.1.0/examples/minimal_usage.py +16 -0
  9. evidence_gate-0.1.0/pyproject.toml +65 -0
  10. evidence_gate-0.1.0/src/evidence_gate/__init__.py +15 -0
  11. evidence_gate-0.1.0/src/evidence_gate/completeness.py +477 -0
  12. evidence_gate-0.1.0/src/evidence_gate/projection.py +270 -0
  13. evidence_gate-0.1.0/src/evidence_gate/scope.py +118 -0
  14. evidence_gate-0.1.0/src/evidence_gate/timestamps.py +62 -0
  15. evidence_gate-0.1.0/src/evidence_gate/types.py +105 -0
  16. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/RUN_META.json +5 -0
  17. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/RUN_STATUS.json +5 -0
  18. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/current_claim.json +5 -0
  19. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/hash_manifest.sha256 +1 -0
  20. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/lineage_manifest.json +67 -0
  21. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/anchor_refs.json +7 -0
  22. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/attempt_index.json +7 -0
  23. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/boundary_limits.json +5 -0
  24. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/event_timestamps.json +5 -0
  25. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/honesty_credits.json +5 -0
  26. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/owned_scope.json +7 -0
  27. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/projected_facts.json +9 -0
  28. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/projection_hash_manifest.sha256 +1 -0
  29. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/projection_manifest.json +12 -0
  30. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/projected_evidence/supported_claims.json +5 -0
  31. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/quarantine/.gitkeep +0 -0
  32. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/raw_evidence/capture_manifest.json +8 -0
  33. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/raw_evidence/github/commit.json +3 -0
  34. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/raw_evidence/github/pull_request.json +6 -0
  35. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/raw_evidence/github/workflow_run.json +5 -0
  36. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/raw_evidence/raw_hash_manifest.sha256 +1 -0
  37. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/timestamp_provenance.json +14 -0
  38. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/verdict/gate_request.json +3 -0
  39. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/verdict/gate_response.json +3 -0
  40. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/verdict/scenario_result.json +3 -0
  41. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/verdict/verdict_hash_manifest.sha256 +1 -0
  42. evidence_gate-0.1.0/tests/fixtures/sample_pass_run/verdict/verdict_summary.json +3 -0
  43. evidence_gate-0.1.0/tests/test_completeness.py +562 -0
  44. evidence_gate-0.1.0/tests/test_integration.py +124 -0
  45. evidence_gate-0.1.0/tests/test_projection.py +266 -0
  46. evidence_gate-0.1.0/tests/test_scope.py +100 -0
  47. evidence_gate-0.1.0/tests/test_timestamps.py +70 -0
@@ -0,0 +1,21 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.10", "3.11", "3.12"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - run: pip install -e ".[dev]"
20
+ - run: pytest -q
21
+ - run: ruff check .
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ .pytest_cache/
3
+ .ruff_cache/
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+ venv/
9
+ .build-venv/
10
+ .*-venv/
11
+ .python-version
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Added completeness checks.
6
+ - Added timestamp ordering checks.
7
+ - Added raw-to-projected evidence helpers.
8
+ - Added scope bundle helpers.
9
+ - Added sample fixture, examples, and integration test.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nick Cunningham
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: evidence-gate
3
+ Version: 0.1.0
4
+ Summary: Catches green CI verdicts whose audit trail is missing, late, or unclear.
5
+ Project-URL: Homepage, https://github.com/blazingRadar/evidence-gate
6
+ Project-URL: Repository, https://github.com/blazingRadar/evidence-gate
7
+ Project-URL: Issues, https://github.com/blazingRadar/evidence-gate/issues
8
+ Project-URL: Changelog, https://github.com/blazingRadar/evidence-gate/blob/main/CHANGELOG.md
9
+ Author-email: Nick Cunningham <nick.lee.cunningham@gmail.com>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: audit,ci,evidence,github-actions,provenance
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Quality Assurance
21
+ Requires-Python: >=3.10
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest>=8; extra == 'dev'
24
+ Requires-Dist: ruff>=0.5; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # evidence-gate
28
+
29
+ `evidence-gate` catches green CI verdicts whose audit trail is missing, late,
30
+ or unclear.
31
+
32
+ It is a small Python library for GitHub Actions evidence bundles. It reads files
33
+ that your pipeline already captured, then reports whether the evidence trail is
34
+ complete, temporally bounded, and explicit about scope. It does not fetch from
35
+ GitHub, run jobs, validate claim semantics, or decide whether the underlying CI
36
+ result is correct.
37
+
38
+ The v0.1.0 bundle contract expects root metadata files (`current_claim.json`,
39
+ `RUN_META.json`, `RUN_STATUS.json`, `timestamp_provenance.json`, and
40
+ `lineage_manifest.json`), raw evidence under `raw_evidence/`, projected evidence
41
+ under `projected_evidence/`, and verdict artifacts under `verdict/`. Hash
42
+ manifests are supported through `ArtifactExpectation`, but they are optional in
43
+ the default v0.1.0 completeness contract.
44
+
45
+ ## The Four Patterns
46
+
47
+ ### Completeness Check
48
+
49
+ A CI verdict can be fact-correct while its audit trail is broken. The
50
+ completeness check runs after your existing verdict and verifies that the bundle
51
+ contains the expected raw evidence, projected evidence, lineage, timestamp,
52
+ verdict, and quarantine artifacts. It reports exact unsatisfied condition names
53
+ so a caller can fail closed without guessing what is missing.
54
+
55
+ ### Capture-Window Timestamp Ordering
56
+
57
+ Evidence captured after a claim should not silently support that claim. The
58
+ timestamp check recomputes whether raw authority was fetched inside the declared
59
+ capture window and by the claim time. The completeness check uses this
60
+ recomputation to catch timestamp provenance files whose stored booleans do not
61
+ match their recorded fetch times. The report names that failure as
62
+ `timestamp_provenance_self_consistent`.
63
+
64
+ A `record_fetch(label, timestamps)` helper is available for building the
65
+ `raw_github_fetch_times` mapping that `timestamp_provenance.json` consumes. It
66
+ writes a UTC timestamp into a caller-owned dict; the caller decides when to
67
+ serialize the dict to disk.
68
+
69
+ ### Raw vs Projected Evidence
70
+
71
+ Raw API responses and derived gate facts serve different purposes. This package
72
+ keeps them in separate trees and writes per-file projection lineage that names
73
+ which source files produced each projected artifact. That makes the derived
74
+ facts reviewable without mutating the raw capture.
75
+
76
+ ### Scope Bundle
77
+
78
+ An evidence bundle should state what it owns and what it does not claim. The
79
+ scope helpers validate and write `owned_scope`, `boundary_limits`, and
80
+ `honesty_credits` files. Empty honesty credits are allowed but reported as a
81
+ warning.
82
+
83
+ ## Minimal Usage
84
+
85
+ From a clone:
86
+
87
+ ```shell
88
+ python3 -m venv .venv
89
+ . .venv/bin/activate
90
+ python3 -m pip install -e .
91
+ ```
92
+
93
+ After publication:
94
+
95
+ ```shell
96
+ python3 -m venv .venv
97
+ . .venv/bin/activate
98
+ python3 -m pip install evidence-gate
99
+ ```
100
+
101
+ Save this script in the clone root to try the included fixture:
102
+
103
+ ```python
104
+ from pathlib import Path
105
+
106
+ from evidence_gate.completeness import check_completeness
107
+
108
+ run_dir = Path(__file__).resolve().parent / "tests" / "fixtures" / "sample_pass_run"
109
+ report = check_completeness(run_dir)
110
+
111
+ print(report.completeness_verdict)
112
+ print(report.unsatisfied_conditions)
113
+ ```
114
+
115
+ ## Integrating With An Existing Gate
116
+
117
+ ```python
118
+ from pathlib import Path
119
+
120
+ from evidence_gate.completeness import check_completeness
121
+
122
+ existing_ci_verdict = "PASS"
123
+ evidence_report = check_completeness(Path("/path/to/evidence-run"))
124
+ acceptable_evidence_verdicts = {"complete", "complete_with_quarantine"}
125
+
126
+ if (
127
+ existing_ci_verdict == "PASS"
128
+ and evidence_report.completeness_verdict not in acceptable_evidence_verdicts
129
+ ):
130
+ raise SystemExit("CI passed, but the audit trail is incomplete")
131
+ ```
132
+
133
+ ## Bundle Sequence
134
+
135
+ For the default v0.1.0 contract:
136
+
137
+ 1. Capture raw GitHub Actions files under `raw_evidence/`.
138
+ 2. Write root metadata files: `current_claim.json`, `RUN_META.json`,
139
+ `RUN_STATUS.json`, and `timestamp_provenance.json`.
140
+ 3. Run `project_github_run(raw_evidence_dir, projected_evidence_dir, ...)`.
141
+ The raw directory must be named `raw_evidence` for the helper to write root
142
+ `lineage_manifest.json`.
143
+ 4. Call `write_scope_bundle(...)` to write user-authored scope files.
144
+ 5. Write verdict artifacts under `verdict/`.
145
+ 6. Run `check_completeness(run_dir)`.
146
+
147
+ `evidence-gate` is tied to the v0.1.0 root metadata contract above. Within that
148
+ contract, pass `ArtifactExpectation` to `check_completeness` to adapt required
149
+ raw, projected, verdict, optional hash, or lineage-covered files for another
150
+ bundle shape.
151
+
152
+ Claim semantics are caller responsibility in v0.1.0. `project_github_run()`
153
+ preserves the caller's `declared_claims` in projected artifacts, but it does not
154
+ infer whether those claims are semantically supported by the raw GitHub JSON.
155
+
156
+ ## Quarantine Rule
157
+
158
+ An empty `quarantine/` directory is accepted. A non-empty `quarantine/` directory
159
+ must include one of:
160
+
161
+ - `README.md`
162
+ - `EXPLANATION.md`
163
+ - `quarantine_explanation.json`
164
+
165
+ Without one of those files, the completeness report marks
166
+ `quarantine_empty_or_explained` as unsatisfied.
167
+
168
+ ## What This Is Not
169
+
170
+ - Not a CI runner.
171
+ - Not a replacement for branch protection.
172
+ - Not a verifier for whether the CI verdict itself is correct.
173
+ - Not a network client.
174
+ - Not a multi-platform adapter layer in v0.1.0.
175
+
176
+ ## Status
177
+
178
+ `evidence-gate` is in pre-release alpha extraction. Maintenance commitment for
179
+ v0.1.0: fix correctness bugs, keep the public API small, and avoid adding
180
+ platform support beyond GitHub Actions until there is clear demand.
181
+
182
+ ## Acknowledgments
183
+
184
+ These patterns came from repeated review of GitHub Actions evidence bundles and
185
+ the failure modes that made those bundles hard to audit.
@@ -0,0 +1,159 @@
1
+ # evidence-gate
2
+
3
+ `evidence-gate` catches green CI verdicts whose audit trail is missing, late,
4
+ or unclear.
5
+
6
+ It is a small Python library for GitHub Actions evidence bundles. It reads files
7
+ that your pipeline already captured, then reports whether the evidence trail is
8
+ complete, temporally bounded, and explicit about scope. It does not fetch from
9
+ GitHub, run jobs, validate claim semantics, or decide whether the underlying CI
10
+ result is correct.
11
+
12
+ The v0.1.0 bundle contract expects root metadata files (`current_claim.json`,
13
+ `RUN_META.json`, `RUN_STATUS.json`, `timestamp_provenance.json`, and
14
+ `lineage_manifest.json`), raw evidence under `raw_evidence/`, projected evidence
15
+ under `projected_evidence/`, and verdict artifacts under `verdict/`. Hash
16
+ manifests are supported through `ArtifactExpectation`, but they are optional in
17
+ the default v0.1.0 completeness contract.
18
+
19
+ ## The Four Patterns
20
+
21
+ ### Completeness Check
22
+
23
+ A CI verdict can be fact-correct while its audit trail is broken. The
24
+ completeness check runs after your existing verdict and verifies that the bundle
25
+ contains the expected raw evidence, projected evidence, lineage, timestamp,
26
+ verdict, and quarantine artifacts. It reports exact unsatisfied condition names
27
+ so a caller can fail closed without guessing what is missing.
28
+
29
+ ### Capture-Window Timestamp Ordering
30
+
31
+ Evidence captured after a claim should not silently support that claim. The
32
+ timestamp check recomputes whether raw authority was fetched inside the declared
33
+ capture window and by the claim time. The completeness check uses this
34
+ recomputation to catch timestamp provenance files whose stored booleans do not
35
+ match their recorded fetch times. The report names that failure as
36
+ `timestamp_provenance_self_consistent`.
37
+
38
+ A `record_fetch(label, timestamps)` helper is available for building the
39
+ `raw_github_fetch_times` mapping that `timestamp_provenance.json` consumes. It
40
+ writes a UTC timestamp into a caller-owned dict; the caller decides when to
41
+ serialize the dict to disk.
42
+
43
+ ### Raw vs Projected Evidence
44
+
45
+ Raw API responses and derived gate facts serve different purposes. This package
46
+ keeps them in separate trees and writes per-file projection lineage that names
47
+ which source files produced each projected artifact. That makes the derived
48
+ facts reviewable without mutating the raw capture.
49
+
50
+ ### Scope Bundle
51
+
52
+ An evidence bundle should state what it owns and what it does not claim. The
53
+ scope helpers validate and write `owned_scope`, `boundary_limits`, and
54
+ `honesty_credits` files. Empty honesty credits are allowed but reported as a
55
+ warning.
56
+
57
+ ## Minimal Usage
58
+
59
+ From a clone:
60
+
61
+ ```shell
62
+ python3 -m venv .venv
63
+ . .venv/bin/activate
64
+ python3 -m pip install -e .
65
+ ```
66
+
67
+ After publication:
68
+
69
+ ```shell
70
+ python3 -m venv .venv
71
+ . .venv/bin/activate
72
+ python3 -m pip install evidence-gate
73
+ ```
74
+
75
+ Save this script in the clone root to try the included fixture:
76
+
77
+ ```python
78
+ from pathlib import Path
79
+
80
+ from evidence_gate.completeness import check_completeness
81
+
82
+ run_dir = Path(__file__).resolve().parent / "tests" / "fixtures" / "sample_pass_run"
83
+ report = check_completeness(run_dir)
84
+
85
+ print(report.completeness_verdict)
86
+ print(report.unsatisfied_conditions)
87
+ ```
88
+
89
+ ## Integrating With An Existing Gate
90
+
91
+ ```python
92
+ from pathlib import Path
93
+
94
+ from evidence_gate.completeness import check_completeness
95
+
96
+ existing_ci_verdict = "PASS"
97
+ evidence_report = check_completeness(Path("/path/to/evidence-run"))
98
+ acceptable_evidence_verdicts = {"complete", "complete_with_quarantine"}
99
+
100
+ if (
101
+ existing_ci_verdict == "PASS"
102
+ and evidence_report.completeness_verdict not in acceptable_evidence_verdicts
103
+ ):
104
+ raise SystemExit("CI passed, but the audit trail is incomplete")
105
+ ```
106
+
107
+ ## Bundle Sequence
108
+
109
+ For the default v0.1.0 contract:
110
+
111
+ 1. Capture raw GitHub Actions files under `raw_evidence/`.
112
+ 2. Write root metadata files: `current_claim.json`, `RUN_META.json`,
113
+ `RUN_STATUS.json`, and `timestamp_provenance.json`.
114
+ 3. Run `project_github_run(raw_evidence_dir, projected_evidence_dir, ...)`.
115
+ The raw directory must be named `raw_evidence` for the helper to write root
116
+ `lineage_manifest.json`.
117
+ 4. Call `write_scope_bundle(...)` to write user-authored scope files.
118
+ 5. Write verdict artifacts under `verdict/`.
119
+ 6. Run `check_completeness(run_dir)`.
120
+
121
+ `evidence-gate` is tied to the v0.1.0 root metadata contract above. Within that
122
+ contract, pass `ArtifactExpectation` to `check_completeness` to adapt required
123
+ raw, projected, verdict, optional hash, or lineage-covered files for another
124
+ bundle shape.
125
+
126
+ Claim semantics are caller responsibility in v0.1.0. `project_github_run()`
127
+ preserves the caller's `declared_claims` in projected artifacts, but it does not
128
+ infer whether those claims are semantically supported by the raw GitHub JSON.
129
+
130
+ ## Quarantine Rule
131
+
132
+ An empty `quarantine/` directory is accepted. A non-empty `quarantine/` directory
133
+ must include one of:
134
+
135
+ - `README.md`
136
+ - `EXPLANATION.md`
137
+ - `quarantine_explanation.json`
138
+
139
+ Without one of those files, the completeness report marks
140
+ `quarantine_empty_or_explained` as unsatisfied.
141
+
142
+ ## What This Is Not
143
+
144
+ - Not a CI runner.
145
+ - Not a replacement for branch protection.
146
+ - Not a verifier for whether the CI verdict itself is correct.
147
+ - Not a network client.
148
+ - Not a multi-platform adapter layer in v0.1.0.
149
+
150
+ ## Status
151
+
152
+ `evidence-gate` is in pre-release alpha extraction. Maintenance commitment for
153
+ v0.1.0: fix correctness bugs, keep the public API small, and avoid adding
154
+ platform support beyond GitHub Actions until there is clear demand.
155
+
156
+ ## Acknowledgments
157
+
158
+ These patterns came from repeated review of GitHub Actions evidence bundles and
159
+ the failure modes that made those bundles hard to audit.
@@ -0,0 +1,31 @@
1
+ """How to layer evidence-gate around an existing CI verdict."""
2
+
3
+ from pathlib import Path
4
+
5
+ from evidence_gate.completeness import check_completeness
6
+
7
+
8
+ def main() -> None:
9
+ fixture_root = Path(__file__).resolve().parent.parent / "tests" / "fixtures"
10
+ run_dir = fixture_root / "sample_pass_run"
11
+
12
+ existing_ci_verdict = "PASS"
13
+ evidence_report = check_completeness(run_dir)
14
+ acceptable_evidence_verdicts = {"complete", "complete_with_quarantine"}
15
+
16
+ if (
17
+ existing_ci_verdict == "PASS"
18
+ and evidence_report.completeness_verdict not in acceptable_evidence_verdicts
19
+ ):
20
+ raise SystemExit("CI passed, but the audit trail is incomplete")
21
+
22
+ print(
23
+ {
24
+ "ci_verdict": existing_ci_verdict,
25
+ "evidence_verdict": evidence_report.completeness_verdict,
26
+ }
27
+ )
28
+
29
+
30
+ if __name__ == "__main__":
31
+ main()
@@ -0,0 +1,16 @@
1
+ """Minimal evidence-gate usage."""
2
+
3
+ from pathlib import Path
4
+
5
+ from evidence_gate.completeness import check_completeness
6
+
7
+
8
+ def main() -> None:
9
+ fixture_root = Path(__file__).resolve().parent.parent / "tests" / "fixtures"
10
+ report = check_completeness(fixture_root / "sample_pass_run")
11
+ print(report.completeness_verdict)
12
+ print(report.unsatisfied_conditions)
13
+
14
+
15
+ if __name__ == "__main__":
16
+ main()
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "evidence-gate"
7
+ version = "0.1.0"
8
+ description = "Catches green CI verdicts whose audit trail is missing, late, or unclear."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Nick Cunningham", email = "nick.lee.cunningham@gmail.com" }
14
+ ]
15
+ keywords = ["ci", "github-actions", "audit", "provenance", "evidence"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Software Development :: Quality Assurance",
25
+ ]
26
+ dependencies = []
27
+
28
+ [project.urls]
29
+ Homepage = "https://github.com/blazingRadar/evidence-gate"
30
+ Repository = "https://github.com/blazingRadar/evidence-gate"
31
+ Issues = "https://github.com/blazingRadar/evidence-gate/issues"
32
+ Changelog = "https://github.com/blazingRadar/evidence-gate/blob/main/CHANGELOG.md"
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "pytest>=8",
37
+ "ruff>=0.5",
38
+ ]
39
+
40
+ [tool.hatch.build.targets.wheel]
41
+ packages = ["src/evidence_gate"]
42
+
43
+ [tool.hatch.build.targets.sdist]
44
+ exclude = [
45
+ "/.git",
46
+ "/.pytest_cache",
47
+ "/.ruff_cache",
48
+ "/.venv",
49
+ "/.build-venv",
50
+ "/.*-venv",
51
+ "/dist",
52
+ "**/__pycache__",
53
+ "*.pyc",
54
+ ]
55
+
56
+ [tool.pytest.ini_options]
57
+ testpaths = ["tests"]
58
+ pythonpath = ["src"]
59
+
60
+ [tool.ruff]
61
+ line-length = 88
62
+ target-version = "py310"
63
+
64
+ [tool.ruff.lint]
65
+ select = ["E", "F", "I", "UP", "B"]
@@ -0,0 +1,15 @@
1
+ """Deterministic CI audit-trail checks for GitHub Actions evidence bundles."""
2
+
3
+ from evidence_gate.completeness import check_completeness
4
+ from evidence_gate.projection import project_github_run
5
+ from evidence_gate.scope import validate_scope_bundle, write_scope_bundle
6
+ from evidence_gate.timestamps import check_capture_window, record_fetch
7
+
8
+ __all__ = [
9
+ "check_capture_window",
10
+ "check_completeness",
11
+ "project_github_run",
12
+ "record_fetch",
13
+ "validate_scope_bundle",
14
+ "write_scope_bundle",
15
+ ]