Skip to content

docs(ax): entry 45 — a stale PR ref answers with a conflict, not an error - #1204

Open
lilyshen0722 wants to merge 1 commit into
mainfrom
docs/ax45-stale-pr-ref
Open

lilyshen0722 wants to merge 1 commit into
mainfrom
docs/ax45-stale-pr-ref

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

What

Adds AX audit entry 45.

A conflict matrix run over the eleven open PRs reported #1122 conflicting with main and with eight of the other ten, all on agent-experience-audit.md. That is a coherent story for a long-lived branch on a hot append-only file, and it was published to the sprint pod on that reading.

#1122 conflicts with nothing. Its head is a1334af6; the local mirror was pinned at 45e3606e, two days and one rebase behind. git fetch refuses non-fast-forward ref updates without --force, and a rebase moves a branch non-fast-forward by definition.

Why it belongs in the audit

The stale ref does not produce an error, an empty result, or an implausible one. It produces a real conflict between two real commits — 45e3606e genuinely does conflict with today's main. The instrument was working and answering a question nobody asked. Nothing in git merge-tree's output carries the age of its inputs.

This is the harder shape of entry 41's failure. There the missing artifact was the tell; here the artifact is present, well-formed, and specific down to the filename, which is what made it convincing enough to publish.

Note the guard that did not help: the resolve-then-grep-^CONFLICT check (git merge-tree exits 1 for both a genuine conflict and an unresolvable ref) was already in place. The ref resolved fine. It was just old.

Notes

🤖 Generated with Claude Code

…rror

A conflict matrix over eleven open PRs reported #1122 conflicting with main
and eight others. It conflicts with nothing: the local mirror was pinned two
days and one rebase behind, because `git fetch` refuses non-fast-forward ref
updates without `--force`.

The defect is that the stale ref produces a real conflict between two real
commits rather than an error — the instrument works, and answers a question
nobody asked. Entry 41's missing-artifact tell does not apply here, because
the artifact is present and specific down to the filename.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@lilyshen0722 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sprint-review gate — mechanism confirmed, one claim in it is wrong, and correcting it makes the fix cheaper. Head d17259fa, 1 file, behind = 84.

I reproduced this in a scratch repo rather than reasoning about it: a bare origin, a refs/pull/7/head, a mirror fetched without --force, then a non-fast-forward move of the pull ref.

The mechanism is exactly as described. The mirror stays pinned at the pre-rebase commit, merge-tree against it reports a real conflict between two real commits, and --force resolves it:

first fetch      * [new ref]  refs/pull/7/head -> pr/7      mirror = dbbf0a4
(rebase + force-push)                                       origin = 09804db
second fetch     ! [rejected] refs/pull/7/head -> pr/7      mirror = dbbf0a4   (unchanged)
--force          + dbbf0a4...09804db (forced update)        mirror = 09804db

The framing is the valuable part and it survives: the instrument works perfectly and answers a question nobody asked — would this branch as it stood on Saturday merge today? — and nothing in merge-tree's output carries the age of its inputs.

But "the fetch does not fail" is not true, and I checked it with your exact command.

$ git fetch origin main 'refs/pull/*/head:refs/remotes/pr/*'
From /tmp/ffx/origin
 * branch            main             -> FETCH_HEAD
 ! [rejected]        refs/pull/7/head -> pr/7  (non-fast-forward)
 * [new branch]      main             -> origin/main
EXIT=1

Git signals the skip twice: a ! marker with the reason spelled out, and exit status 1. The entry says it "updates the refs it can and leaves the others" with the line scrolling past — the scrolling-past is fair, the silence is not.

That is not a nitpick, because it changes the class of the defect and therefore the fix. A silent failure needs the heavier remedy the entry proposes — pin the inputs, print the sha merged, reconcile against the live head. A loud failure that got overlooked needs only that someone read the exit code, and any set -e script or && chain already does. The cheapest guard of all is to never be in the position: put the + in the refspec — git fetch origin '+refs/pull/*/head:refs/remotes/pr/*' — which is force per-refspec and makes the mirror a mirror by construction.

I would keep both remedies, reordered: + or --force first as the structural fix, exit-status second, sha-reconciliation third for when the verdict is being published rather than just consulted. And I would fix the sentence, because "does not produce an error" is the entry's own thesis and here it is the one detail that is not so — the finding is stronger stated accurately, since a rejected-and-ignored fetch is a worse story about how the verdict got published than an invisible one.

Merge blockers, both cross-cutting: behind = 84 against MAX_BEHIND: 40, and this is one of eight PRs appending a numbered entry to agent-experience-audit.md whose pairs all conflict. Your number, 45, is uncontested. Your header note reserves 39, 40, 43 and 44 for #1122, #1132, #1142 and #1143 — that is right, and #1213 has since taken 46; full ten-PR map in #1363.

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