Skip to content

Fix PortfolioTruth security receipt same-cycle binding - #205

Merged
saagpatel merged 1 commit into
mainfrom
codex/security-receipt-binding
Jul 31, 2026
Merged

Fix PortfolioTruth security receipt same-cycle binding#205
saagpatel merged 1 commit into
mainfrom
codex/security-receipt-binding

Conversation

@saagpatel

Copy link
Copy Markdown
Owner

Summary

  • Adds immutable GitHub security receipt identity and exact byte digest propagation into PortfolioTruth publication.
  • Holds security receipt writer intent across truth read, prior receipt read, collection, validation, and atomic replacement.
  • Makes PortfolioTruth fail closed when a same-cycle collector is active or when the bound receipt pointer, bytes, freshness, or metadata changes before publication.
  • Preserves legacy receipt readability while refusing legacy receipts as canonical publication evidence.

Root cause

The collector previously advertised writer intent only during final receipt replacement. PortfolioTruth could publish R0 while R1 was already being produced but not yet visible at the canonical pointer.

Validation

  • Focused exploit regression: 4 passed.
  • Touched-file tests: 124 passed, 1 warning.
  • Full pytest in isolated CI-shaped uv env: 2962 passed, 2 skipped, 2 warnings.
  • Ruff: All checks passed.
  • CI mypy slice: Success, no issues found in 15 source files.
  • Gitleaks repo scan: pass.
  • Semgrep focused Python scan: pass.
  • Independent read-only review: no P0/P1/P2 findings after the pre-truth-read lock gap was fixed.

Notes

  • Prior data-integrity work remains preserved at rescue/20260731-githubrepoauditor-data-integrity-takeover.
  • This PR does not merge, alter schedules, trigger production jobs, remediate Dependabot alerts, or claim natural scheduler proof.
  • Natural post-fix scheduler evidence remains pending until the next real maintenance cycle is observed.

with security_coverage_receipt_writer(canonical):
raise RuntimeError("collector interrupted")

assert canonical.with_name(f".{canonical.name}.lock").is_file()
receipt = _collect(cohort_count=DEFAULT_EXPECTED_GITHUB_COHORT_COUNT)
canonical = tmp_path / GITHUB_SECURITY_RECEIPT_FILENAME
write_security_coverage_receipt(receipt, canonical)
binding = load_security_coverage_receipt(
@saagpatel
saagpatel marked this pull request as ready for review July 31, 2026 19:35
@saagpatel
saagpatel merged commit 470f78e into main Jul 31, 2026
4 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1608722fd

ℹ️ 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".

staged.replace(path)
published.append(path)
except Exception:
with publication_guard:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bind the overlay payload to the verified receipt

When a caller supplies a valid binding but passes security_alerts_by_name from another receipt—or metadata whose ID, digest, and path match but whose state or producer fields do not—this guard revalidates the receipt file but discards the returned LoadedSecurityCoverage; the snapshot has already been built from the caller-provided mappings. Canonical output can therefore report security findings or provenance not present in the bound bytes, so publication should compare against or build from the reloaded entries and complete metadata before replacing outputs.

AGENTS.md reference: src/AGENTS.md:L5-L10

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants