Skip to content

scientific(validation): make exact-head receipt identity injective over head and terminal state #631

Description

@seonghobae

Finding

#630 binds scientific promotion to ScientificRecoveryExactHeadReceiptV1, but the predecessor value object's advertised receipt_sha256() identity was the caller-supplied immutable CI/test artifact digest alone. head and terminal status were stored beside that digest rather than committed into the receipt identity.

Therefore two semantically different receipt objects could have the same receipt SHA-256 identity:

  • the same artifact digest paired with Passed vs Failed/Queued/Skipped;
  • the same artifact digest paired with different tested Git heads.

Promotion already checked head/status before minting authority, so this was not a bypass of #630's immediate gate. It was a provenance/audit identity defect: ScientificRecoveryPromotionV1 retained only exact_head_receipt_sha256, so downstream evidence could not tell which head/status binding that identity represented.

RED → causal repair

Canonical owner vehicle remains Draft #488.

  • runtime RED d4154eb433df8944a4b10b48b711141b0337cc8b adds scientific_recovery_exact_head_receipt_identity.rs. Against the predecessor implementation it compiles and deterministically fails because receipts with the same artifact digest return the same receipt_sha256() even when tested head or terminal state differs. No hosted failing RED receipt is claimed because repair commits followed before a terminal workflow result.
  • causal production repair 06899ee91b536a44a5127a98a055c77e6ed2d972 separates the trusted-adapter artifact_sha256 from the canonical receipt binding identity. ScientificRecoveryExactHeadReceiptV1::new now derives receipt_sha256 from the domain tepp.scientific_recovery_exact_head_receipt.v1, parsed 20-byte Git head, canonical artifact SHA-256, and stable terminal-state wire value. artifact_sha256() exposes the underlying artifact identity separately.
  • public authority contract migration 1f36eea61108e906676b8d2172de8af16b687b64 verifies that promoted authority retains the derived binding identity while the underlying artifact digest remains separately auditable.
  • CHANGELOG/current exact head 0259dafae4e215355b548e7c9a7d910974d6351e records the distinction.

The repair deliberately does not claim signature verification, signer identity, trusted timestamp, GitHub artifact attestation, or SLSA provenance from the binding hash. The supplied artifact SHA-256 and terminal status remain trusted-adapter inputs; #631 only makes the receipt identity injective over the fields that change its represented meaning.

Current exact-head gate

#488 exact head is now 0259dafae4e215355b548e7c9a7d910974d6351e on protected base main@a243f18da4a4ca8a8d068c39922537f1f8ed6ad0. Fresh workflows are live/non-terminal:

  • Documentation Quality 35503797536 queued;
  • Rust Foundation CI 35503797542 queued;
  • Security Scan 35503797506 queued;
  • SAST Semgrep 35503797538 pending;
  • CodeQL PR 35503797549 queued;
  • Bias SE Exact-Proof Budget 35503797510 queued.

Every predecessor-head receipt is invalid after this source change. No qualifying independent current-head APPROVED review has been established. Keep Draft; do not blind-rerun, wake-commit, merge, or transfer predecessor coverage/review evidence while this generation is live.

Remaining boundary

The next hardening step is still larger than a hash-binding change: a trusted adapter must verify a signed/verifiable exact-head CI attestation (or equivalent owner-issued evidence) rather than merely supply a digest and terminal state. Pre-execution recovery-profile registration chronology also remains separate.

Keep open through exact-head Rust/coverage/security/CodeQL/proof-budget, qualifying independent review, normal #492 prerequisite/protected-main integration, and code-current TRACEABILITY/product-gap authority.

Refs #488 #630 #629 #492 ADR 0014.

Activity

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