Skip to content

e2e attest silently deletes other branches' attestation receipts #1041

Closed

Description

@thekevinbot

What happens

just e2e-attest-python / just e2e-attest-ts (and the other attest recipes) call the local testing-conventions python CLI, currently 0.0.85, which prunes stale receipts as a side effect of e2e attest and auto-commits those deletions alongside the receipt it adds.

Two PRs hit this in a single session on 2026-09-04:

Why CI does not catch it

The e2e-verify gate is diff-based: it asserts only that a branch adds or updates its own receipt. Deleting every other branch's receipt is invisible to it. #1036 was fully green — 65 passing checks — with the deletions in its diff.

Attestation commits on main are add-only, so this is a change in tool behavior, not repo convention.

Why it matters

It will keep happening to every agent that attests locally until something changes. Each occurrence is a silent, unrelated 28-file deletion inside an otherwise-scoped feature PR, and the only thing standing between it and main is a human noticing an attestation entry marked removed in the file list.

Options

  1. Pin testing-conventions to a version whose e2e attest is add-only.
  2. Stop the just e2e-attest-* recipes from auto-committing — write the receipt, stage nothing, let the author commit it.
  3. Add a check asserting no PR deletes a receipt it does not own. Complements the diff-based gate rather than replacing it.

(2) is the smallest and removes the whole class: the tool can prune whatever it likes in the working tree if nothing commits on the author's behalf.

Detecting it on an open PR

gh api repos/thekevinscott/dirsql/pulls/<n>/files --paginate \
  --jq '.[] | select(.filename | test("e2e-attestations")) | "\(.status)\t\(.filename)"'

Every entry should read added.

Activity

  1. self-assigned this
    on Sep 4, 2026
  2. thekevinbot commented on Sep 5, 2026

    @thekevinbot
    CollaboratorAuthor

    Resolved by upgrading the local install rather than constraining the version in the repo.

    The pruning behavior exists only in testing-conventions below 0.0.91; upstream removed it in 2bb445e6 ("Green: e2e attest only ever adds"), released in 0.0.91 on 2026-08-02. This machine's uv tool install was stuck at 0.0.85 (2026-07-17), and just e2e-attest-python / -ts invoke a bare testing-conventions off PATH, so they picked it up. e2e-attest-internals-checks already used uvx and was never affected.

    uv tool upgrade was a no-op — the tool had been installed at a fixed version — so it took uv tool install testing-conventions@latest --force. Now resolving 0.0.104.

    Upstream's own reason for the fix is worth recording: a delete paired with an add is what git's rename detection reads as a rename, so two branches off one parent rename the same source to two names, producing an unresolvable rename/rename conflict. The receipt wipe was the visible symptom of a bug that also broke stacked branches.

    PR #1044 (flooring the version in the justfile) was closed deliberately — a repo-side version constraint is a permanent workaround for a temporary condition. #1043 tracks the independent guard: nothing asserts a PR does not delete receipts it does not own, which is true at any tool version.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions