Add read-only PR evidence-to-head binding - #203
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 08a57f2c34
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if review.actor.can_count is None and review.state in { | ||
| "APPROVED", | ||
| "CHANGES_REQUESTED", | ||
| }: | ||
| unknown_eligibility = True |
There was a problem hiding this comment.
Ignore unknown reviewer eligibility when it cannot affect requirements
When the supplied rules require zero approvals and no latest-push approval, any APPROVED or CHANGES_REQUESTED review with can_count=null still sets unknown_eligibility, causing an otherwise fully covered snapshot to exit 2 as unknown even though the verdict simultaneously reports github_requirement_satisfied=true. Only propagate unknown eligibility when that review could change an applicable approval requirement or blocking decision.
AGENTS.md reference: src/AGENTS.md:L17-L19
Useful? React with 👍 / 👎.
| "coverage": { | ||
| "state": "complete" | ||
| if not coverage_reasons and not rule_reasons | ||
| else "unknown", | ||
| "reasons": sorted(set(coverage_reasons + rule_reasons)), |
There was a problem hiding this comment.
Include freshness and eligibility gaps in coverage state
For a valid snapshot with provenance.freshness="unknown", this condition emits coverage.state="complete" with no coverage reasons while the top-level state is unknown; an eligibility gap that can affect approval requirements produces the same contradiction. This breaks the documented PRHeadEvidenceVerdictV1 coverage contract and can mislead consumers that inspect the coverage object, so these gaps must participate in the coverage state and reasons.
AGENTS.md reference: src/AGENTS.md:L17-L19
Useful? React with 👍 / 👎.
| try: | ||
| raw_text = path.read_text(encoding="utf-8") | ||
| except OSError as exc: |
There was a problem hiding this comment.
Emit the versioned error verdict for invalid UTF-8
If the snapshot contains invalid UTF-8 bytes, Path.read_text() raises UnicodeDecodeError, which is not an OSError, so the command leaks a traceback and emits no JSON instead of the promised deterministic malformed-input verdict with exit code 2. Catch decoding failures here and route them through invalid_snapshot_verdict just like unreadable or syntactically invalid JSON.
AGENTS.md reference: src/AGENTS.md:L17-L19
Useful? React with 👍 / 👎.
What
Adds a fixture-first, read-only operator capability for determining whether supplied pull request approvals and checks apply to the supplied current head.
PRHeadEvidenceV1input and deterministicPRHeadEvidenceVerdictV1outputaudit pr-evidenceCLI pathWhy
Stale approvals, comments, dismissed reviews, and successful checks from older SHAs must not appear as current evidence for a newer pull request head. Missing rules, incomplete pagination, permission gaps, and malformed snapshots must fail closed instead of silently becoming green.
Review Of What Was Built
Cleanup Review
Verification Summary
Verification below is bound to head
08a57f2c34b8fc47a657cafc4a65a5495c0e1ea6.uv run pytest -q tests/test_pr_head_evidence.py tests/test_pr_head_evidence_cli.py— 37 passeduv run pytest -q— 2,988 passed, 2 skippeduv run ruff check .— passedruff format --check— passedRepository-wide format and mypy commands still expose unchanged pre-existing debt outside this diff; the feature-owned files and modules pass their scoped gates.
Shipped Summary
The branch now has a documented, versioned, deterministic way to bind supplied PR evidence to a supplied head SHA without credentials, network access, GitHub writes, or portfolio-truth changes.
Next Phase
Obtain an independent approval on the current head before merge. Any live read-only GitHub snapshot collector should remain a separate follow-up and must preserve the same completeness and claim-ceiling rules.
Remaining Roadmap