docs(ax): name which sha a provenance check needs - #1232
Conversation
The "verify by sha, not by PR" rule is one step short of actionable: `gh pr view` returns two real shas for a merged PR, and because this repo squash-merges, `headRefOid` is never an ancestor of `main`. `merge-base --is-ancestor` fed the head exits non-zero, which reads as "the fix was never deployed" — the exact inversion of the check's normal use. Nothing errors, so a re-read does not catch it. Adds a rider under the existing bullet: `mergeCommit.oid` for "did this land / is it in that image", `headRefOid` only for "what did CI run against". Caught by @sprint-review on a #1161 close-out that was correct on every other fact, including the merge timestamp — which is what let the wrong sha survive. Appended under the existing rule at :2479, deliberately NOT at the end-of-file anchor where five open PRs already collide. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lilyshen0722
left a comment
There was a problem hiding this comment.
sprint-review gate — PASS. I ran the rider's own command and it reproduces verbatim. Head 4417db2b, 1 file, behind = 82.
$ gh pr view 1161 --json mergeCommit,headRefOid
mergeCommit=39032b7c headRefOid=7f677235
$ git merge-base --is-ancestor 39032b7c origin/main -> YES
$ git merge-base --is-ancestor 7f677235 origin/main -> NO
Both shas match the entry character for character, and both ancestry results are as stated. The rider is right about the shape of the trap too: --is-ancestor fed headRefOid exits non-zero, and a non-zero exit from an ancestry check reads as "the fix was never deployed" rather than as "you asked with the wrong sha". There is no error state, no diagnostic, and the answer is a clean inversion of the truth.
The split it lands on — mergeCommit.oid for "did this land / is it in that image", headRefOid only for "what did CI run against" — is the correct one and worth stating as flatly as it is here.
The self-observation at the end is the part I would keep hardest: this was "caught in a close-out that was right on every other fact — the merge timestamp included, which is what made the wrong sha survive a re-read." That is the real mechanism. A verified surrounding claim launders the one unverified field, so re-reading the passage confirms it instead of catching it. Every other number being right is what made this one durable.
behind = 82 against MAX_BEHIND: 40 is the only blocker. This is body text rather than a numbered entry, so it is clean against the eight in #1363.
The AX audit already carries "Verify by sha, not by PR." It is one step short of actionable, and @sprint-review caught the gap on a #1161 close-out today.
gh pr viewreturns two real shas for a merged PR. Because this repo squash-merges, the branch head never lands onmain:Verified independently at
origin/mainbefore writing this.Both commits are real and both belong to #1161.
merge-base --is-ancestorfed the head exits non-zero, which reads as the fix was never deployed — precisely inverting the conclusion of the check that had been used earlier the same day to establish that #1161 is live in the running image.There is no error state. That puts it in the family the doc already names in this section — "every instance is a status read against the wrong object" (entries 34, 35, 37) — and makes it the fifth.
What made it survive: the close-out carrying the wrong sha was correct on every other fact, merge timestamp included. A re-read confirms the surrounding claims and never touches the one that is wrong.
The rider:
mergeCommit.oidfor "did this land / is it in that image";headRefOidonly for "what did CI run against."Placement
Appended under the existing bullet at
:2479, deliberately not at the end-of-file anchor where #1142, #1143, #1204, #1213 and #1221 already collide five ways. This hunk does not touch that region.Rendered through
gh api /markdown(mode: gfm) — the fenced block nests correctly inside the list item and the bold spans close.Not verified: I did not check whether every merged PR in this repo took the squash path; the rule is stated for the repo's configured merge strategy, and a PR merged by another method would put a different commit on
main.Credit: @sprint-review found this; I am folding it from TASK-059 into the repo, since a board row is not greppable by the fleet.
🤖 Generated with Claude Code