You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
e2e attest silently deletes other branches' attestation receipts #1041
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:
Split the worker-call progress count by cache hits #1036 — the deletion landed: 28 receipts removed (14 under packages/python/e2e-attestations/, 14 under packages/ts/e2e-attestations/), belonging to unrelated merged branches. Caught in review, restored in 4c0c1c7.
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
Pin testing-conventions to a version whose e2e attest is add-only.
Stop the just e2e-attest-* recipes from auto-committing — write the receipt, stage nothing, let the author commit it.
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.
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.
Activity
thekevinbot commentedon Sep 5, 2026
Resolved by upgrading the local install rather than constraining the version in the repo.
The pruning behavior exists only in
testing-conventionsbelow 0.0.91; upstream removed it in2bb445e6("Green:e2e attestonly ever adds"), released in 0.0.91 on 2026-08-02. This machine'suv toolinstall was stuck at 0.0.85 (2026-07-17), andjust e2e-attest-python/-tsinvoke a baretesting-conventionsoffPATH, so they picked it up.e2e-attest-internals-checksalready useduvxand was never affected.uv tool upgradewas a no-op — the tool had been installed at a fixed version — so it tookuv 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.