Skip to content

security(attestation): normalize signer receipt read I/O failures #2322

Open

Description

@seonghobae

Finding

The signer-facing receipt reader in scripts/ci/validate_scientific_validation_receipt.py normalizes os.open() failures into EvidenceError, but os.fstat() and stream.read() failures after the descriptor has been opened can still escape as raw OSError/PermissionError.

main() only catches EvidenceError. A storage/read fault can therefore bypass the stable fail-closed CLI contract, emit a traceback, and return a platform-dependent process failure instead of the deterministic scientific-validation rejection boundary used by the owner workflow.

This is separate from semantic receipt validation: bounded regular-file intake must first normalize read-path failures before exact bytes can be delegated to validate_receipt_manifest().

Acceptance

  • Add a source-level RED that injects an OSError during receipt bytes read after a valid regular file has been opened.
  • The reader must convert that failure to a typed EvidenceError with the receipt role in the diagnostic.
  • The CLI must continue to return its stable invalid-receipt status rather than leaking the raw exception.
  • Preserve one-open O_NOFOLLOW | O_NONBLOCK, descriptor-pinned parent authority, 4 MiB+1 bound, exact-byte delegation, and same-inode refusal.
  • Do not weaken current tests, add skip/xfail, or move the path outside the existing 100% owned quality denominator.
  • Keep this in the .github owner; TEPP must consume only the eventual immutable/released attestation contract.

Refs #2299 #2300 #2315 #2316 #2317 #2164 ContextualWisdomLab/TEPP#637.

Activity

  1. seonghobae commented on Sep 21, 2026

    @seonghobae
    ContributorAuthor

    Implemented ordinary-forward on the existing #2300 owner branch.

    • Source-level RED: 94f12c632703444204bb7525907cceb604770b7f adds an injected post-open stream.read() OSError and requires both the reader API and CLI to keep the failure inside the role-specific EvidenceError/exit-2 contract.
    • Causal repair: 2813d50bbcee5de37fc3bd5882479cc6726b7d77 catches post-open metadata/read OSError without swallowing existing EvidenceError, returning <receipt role> read failed while preserving the existing one-open, pinned-parent, nonblocking/no-follow and byte-bound semantics.
    • CHANGELOG: 103f116ff46043a23341cecbb11d7570696ca918.
    • Doctoring/current exact head: f83237cf0a11c62b14bf391ac3576977e01a12f4.

    The existing Scientific Validation Evidence Quality workflow already includes both the reader and tests/test_scientific_validation_receipt_intake.py in PR/push path authority, 100% owned branch coverage, interrogate and compileall. No skip/xfail or denominator change was introduced.

    Hosted settlement is not claimed yet; the new exact-head workflow generation has not appeared in the commit-run query at this moment. Keep this issue open until current-head checks and qualifying independent review settle.

  2. seonghobae commented on Sep 21, 2026

    @seonghobae
    ContributorAuthor

    Current-head settlement update: PR-event generation is now visible for .github#2300@f83237cf0a11c62b14bf391ac3576977e01a12f4. Scientific Validation Evidence Quality run 35566752445 has verifier-quality job 106230013392 queued with runner_id=0, empty runner name, and steps=[]; CodeQL 35566752543, Semgrep 35566752498, Security 35566752610, and Python Security 35566752486 are also non-terminal. This is runner/admission evidence, not hosted RED/GREEN. Keep #2322 open; predecessor results do not transfer and no blind rerun/wake commit is warranted.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions