Skip to content

fix(evidence): follow the verified-certificate retention receipt - #317

Merged
abrichr merged 4 commits into
mainfrom
fix/git-retention-verified
Aug 27, 2026
Merged

fix(evidence): follow the verified-certificate retention receipt#317
abrichr merged 4 commits into
mainfrom
fix/git-retention-verified

Conversation

@abrichr

@abrichr abrichr commented Aug 27, 2026

Copy link
Copy Markdown
Member

Replaces #314, closed on review alongside the Cloud half. Matches the Cloud writer after all three defects from that review were fixed.

The receipt drops retention_commit, transparency_log_entry_sha256 and the three assertion booleans, and gains visibility_verified.

retention_commit went because it forced a circularity: a certificate cannot name the commit it is not yet inside, which is exactly what pushed it into a second unsigned commit. The certificate is now signed and verified before it is committed, so the commit is a delivery detail rather than something the receipt must name.

The booleans went because a verified Sigstore bundle is the claim. A field asserting transparency_logged: true proves nothing the writer could not have written anyway. visibility_verified stays because it records a check against an external source — the repository API confirming the destination is private.

320 tests pass, ruff clean, and the hashed policy digest is unchanged.

Pairs with the Cloud PR. Neither side runs alone, and the import gate stays closed regardless.

abrichr and others added 4 commits August 27, 2026 14:12
…ect Lock

Decided before the first write, which was the last moment it was free. A
COMPLIANCE lock cannot be shortened by anyone including the account root, so
the first retained object would have committed storage for its full term.

The case for S3 was weaker than it looked. The Cloud writer already encrypts
the envelope client-side with an AES-256-GCM data key wrapped by KMS, so the
store holds ciphertext and confidentiality never depended on the medium. What
makes the claim credible is the signature chain and the public Rekor entry:
Object Lock stops neither the suppression of an unpublished result nor the
alteration of a published one, because the signature and the transparency log
already do both. Git is content-addressed, so a commit hash binds the
relationships between certificate, admission and campaign rather than each blob
alone.

Object Lock does buy one thing git does not. If a third party is granted direct
read access to the store, they can trust nothing was pruned before they looked.
No buyer has asked for that. The document records the trade so the next reader
does not have to reconstruct it, and says to revisit before the next write if a
buyer ever does ask.

The retention block loses retention_mode, retention_until, object_version_sha256
and object_lock_verified. It gains retention_commit, transparency_log_entry_sha256,
push_verified, commit_verified and transparency_logged. The contract destination
becomes a repository, ref and path prefix, keeping the account, region and KMS
ARN because the data key is still wrapped by KMS.

retention_commitment_days is recorded and not enforced, and both the code and
the document say so. A git commit has no expiry, and policing a number nothing
can hold would be theatre.

The hashed policy digest moves with the medium: bc013d65... -> 77130f49...

The Cloud writer must change to match before either side can run. That is a
separate lane and a separate review.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
openadapt-evidence exists and is empty by design, so the repository and path
prefix are no longer blanks. The readiness bar, the four evidence inputs, and
the retention description still described an S3 bucket with Object Lock and a
GitHub artifact attestation; both were replaced this cycle.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
AWS was in this design for one reason: a KMS key to wrap the data key. That
reason is gone. Identity Center on 992382684924 has no user for the founder;
its five members are an external vendor, and the only IAM users are claude-ops
and a vendor CLI. There was no admin identity to provision a key with.

The contract destination becomes repository, ref, path_prefix,
encryption_recipient and retention_commitment_days. account_id, region and
kms_key_arn are gone, along with the ARN validators.

kms_key_identity_sha256 becomes encryption_recipient_sha256 under the domain
'retention encryption recipient'. uploader_arn becomes uploader_identity under
'retention uploader'. The Cloud writer changed in the same commit range.

The recipient is public by design and is filled into the template. The private
half is in the founder's login keychain and never reaches CI, so the writer can
encrypt and nothing in any workflow can decrypt.

The hashed policy digest is unchanged; the retention medium did not move.

324 tests pass. ruff clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Matches the Cloud writer after the three defects from the #330 review were
fixed. The receipt drops retention_commit, transparency_log_entry_sha256 and
the three assertion booleans, and gains visibility_verified.

retention_commit went because it forced a circularity: a certificate cannot name
the commit it is not yet inside, which is what pushed it into a second unsigned
commit. The certificate is now signed and verified before it is committed, so
the commit is a delivery detail rather than something the receipt must name.

The booleans went because a verified Sigstore bundle is the claim. A field
asserting transparency_logged: true proves nothing the writer could not have
written anyway.

320 tests pass. ruff clean. The hashed policy digest is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@abrichr
abrichr merged commit 77d5514 into main Aug 27, 2026
3 checks passed
@abrichr
abrichr deleted the fix/git-retention-verified branch August 27, 2026 21:01
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.

1 participant