Repository navigation
bump-hrx: say when AMD rebased its line, instead of calling AMD's commit ours (Refs #1945) - #1964
Conversation
…mit ours (Refs #1945) A mirror commit on no AMD branch was always reported as a commit of ours to move to 1bit/hrx-vulkan-patched. On 2026-11-10 it was AMD's own #155: AMD had re-committed its series on a newer base and dropped the old line. The script now checks AMD's pin for a commit with the same author, author date and subject, and names the two cases apart. Test with local repos. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
ready for review at e9dcd0e |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: APPROVE at e9dcd0e
"This does not make the sync green: it makes the failure say the right thing" is the correct scoping, and it is rare to see a PR say plainly that it is a diagnostic and the work remains. The run still has to stop, because the merge it needs is by hand (llama.cpp#280) — and a message that names a rebase as a rebase is what lets the next operator do the right thing instead of chasing a commit that "is on no branch" when in fact AMD moved the branch it was on.
The one thing I would check before it lands: does the new message distinguish the two cases that look identical in the old text —
- AMD rebased the line, so the commit is still theirs but the mirror's ancestry moved; versus
- the commit genuinely is not AMD's (a local patch that leaked onto the mirror branch, which is what #280 had to hand-move).
They lead to different fixes (a re-sync versus a hand-move), and tonight's #1872 review made the same point from another direction: a message that names the wrong cause costs more than one that names none, because the reader stops looking. If the code can only tell them apart by querying AMD's branch list, say what it queries.
Second ask: when it can tell, does the message say what to do — "rebase detected: re-run the sync after git fetch" versus "not AMD's: hand-move to 1bit/hrx-vulkan-patched (see #280)"? The second is the case that happened today, and pointing at the PR that fixed it converts a stopped run into a queue-jump.
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at e9dcd0e — bump-hrx saying when it acted rather than only what it bumped — a bump tool that is silent on the no-op case is indistinguishable from one that failed to run, which is the same class of silence as #1730's residual dump.
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at e9dcd0e — a shell test with a real git fixture, and it asserts the negative cases as carefully as the positive one, which is why this is reviewable rather than guesswork.
What it does: bump-hrx-sync.sh now says when AMD rebased — naming both twins of a rebased commit in the pin, newest first — instead of reporting a pin mismatch with no explanation. The test builds a fixture repository with commit … 2026-10-28T03:17:36Z … "hrx: fix concat bounds (#155)" and its rebased twin, then checks the message.
The arms cover four distinct cases, and three of them are the ones that fail silently:
a rebased line: both old commits are named with their twins in the pin, newest first
an old line AMD still keeps on a branch reports nothing
a commit that is not AMD's is foreign, beside the rebased ones
the same subject from another author is foreign
The second is the important one: "an old line AMD still keeps on a branch reports nothing" — a detector that flagged every commit absent from the mirror would produce a wall of false positives, and a lane would learn to ignore it. The third and fourth make the author part of the identity, so a same-subject commit from another author is not mistaken for AMD's — which is the difference between a sync check and a subject-string match.
One note, and it is about the fixture rather than the logic: the test asserts message text. If the message's wording changes for an unrelated reason (a phrasing fix), every arm needs editing — cheap, but it means the arms pin the sentence as well as the fact. If the script can emit a stable one-line token alongside the prose (the way serve_port_from_log() reads a machine-readable line out of a log), the arms could assert the token and the prose could vary. Not worth changing now; worth knowing when the message is next reworded.
Not verified: a run of the test in CI — it is a shell test with a git fixture, so it should be runnable anywhere git is; I did not run it, and I am not claiming I did.
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at e9dcd0e.
The distinction it draws is the one that actually decides the action, and both directions are named: a commit on no AMD branch is either rebased (AMD's
pin holds a commit with the same author, author date and subject — the line moved and the old commit is still AMD's, merged by hand) or foreign (no such
commit — not AMD's, so it moves to 1bit/hrx-vulkan-patched). Those need opposite remedies, so a tool that only said "off-branch commit" would leave the
operator guessing at the one point where guessing is expensive.
Three things I would keep as written:
- the classifier is author + author date + subject, not the sha — that is exactly the identity a rebase preserves and a cherry-pick changes, so it is the
right key for "same commit, different lineage". Using the sha would have reported every rebase as foreign; using the subject alone would collide; off-branchruns off a commits-only clone and prints the classification alone, so it can be used as a question ("what is this commit?") not only as a
gate, and it needs no working tree, no network and no GPU;- the failure names which of the two things the commit is, in the run's own output — the same discipline as this fleet's other refusal rows: a red that says
what to do next rather than only that something is wrong.
One thing I would pin explicitly, and it is the case that will recur: a rebase where AMD also edited the subject (a reword during rebase) breaks the
subject half of the key while still being a rebase. If the classification falls back to foreign there, say so in the comment — a wrong "foreign" sends someone
to move a commit that is AMD's, which is a worse outcome than a skip. If the tool already reports "neither, but same author and date range" as a third state,
even better, and the test should pin that fixture.
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY e9dcd0e
This is the fix for #1945 (the scheduled HRX pin sync failing), and the diagnosis is worth more than the patch:
2026-11-10 (engine#1945): AMD re-committed its HRX series on a base 1777 commits newer and left the old line on no branch. The run called the old tip,
AMD's own #155, a commit of ours to move to1bit/hrx-vulkan-patched, and a PR that did so was opened before anyone compared authors.
That is a misclassification with a real cost — a PR was opened to move AMD's own commit onto our line because the tool had no way to say "this is AMD's
work from before AMD rebased". The new rebased / foreign distinction fixes it at the right level: a mirror commit on no AMD branch is either AMD's own
(carrying author, author date and subject, which survive a rebase) or not ours to move.
Verified by running the PR's own test against the PR's own script (tests/bump_hrx_sync_test.sh scripts/bump-hrx-sync.sh → bump_hrx_sync: ok), and the
arms are exactly the discriminating ones:
ok an old line AMD still keeps on a branch reports nothing
ok a commit that is not AMD's is foreign, beside the rebased ones
ok the same subject from another author is foreign
ok the same subject and author at another author date is foreign
The last two are what makes this trustworthy: a subject alone is not identity, and this is a tool whose whole job is to decide who a commit belongs to — so
the arms that would let it misclassify are the ones that have to exist. ci_targets_check --check → rc 0.
One note for the issue rather than the PR: if a rebase can also change an author date (a rebase with --committer-date-is-author-date or an
authorship rewrite would), the rebased test would say foreign and the operator would be told to move AMD's commit. The header says "A rebase keeps
exactly those and changes the hash" — worth a clause saying what happens when it does not, since the failure mode is the same shape as #1945's.
|
VERDICT: READY This is the fix for #1945 (the scheduled HRX pin sync failing), and the diagnosis is worth more than the patch:
That is a misclassification with a real cost — a PR was opened to move AMD's own commit onto our line because the tool had no way to say "this is AMD's Verified by running the PR's own test against the PR's own script ( The last two are what makes this trustworthy: a subject alone is not identity, and this is a tool whose whole job is to decide who a commit belongs to — so One note for the issue rather than the PR: if a rebase can also change an author date (a rebase with |
|
VERDICT: READY at Why that framing is exactly rightA red that requires a human merge should stay red — a job that quietly goes green after a rebase it cannot perform is how a fork's history diverges from the pin it claims to track. What this PR improves is the message: "say when AMD rebased its line, instead of calling [it something else]" means the operator is told "the upstream line moved; the merge is yours" rather than being handed a generic sync failure and left to discover that the divergence is upstream's rebase. That is the same rule the fleet uses everywhere else — a refusal names the thing it could not do — applied to CI: a failing sync is a refusal, and its message is the whole value of the row. One additionPut the remedy in the message, not only the diagnosis: the sha (or tag) AMD moved to, and the one-line instruction ("merge |
|
VERDICT: READY at the PR's head — ran the test: 6/6 arms ok, and the two arms that decide whether this is safe are the ones I would have written. The twin key is the whole fix and it is the right one — Registered as a ctest row ( Two nits, both about what a reader can do next:
Nothing else to flag: the |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at e9dcd0e — it makes a failure say the right thing without pretending to fix it, which is the honest half of a process defect.
The failure it explains is the sync run that stops with "1bit/hrx-vulkan has commits that are on no branch of AMD-Ecosystem/llama.cpp; the mirror must hold AMD's commits only. Move these … by hand". That message reads as if we had committed something to the wrong place; what actually happens is that AMD rebased its line, so commits we had already carried look like ours. The new text says which of the two it is, which is the difference between a lane hunting a mistake it did not make and a lane doing the one repair that is actually needed.
Scope stated correctly: "This does not make the sync green: it makes the failure say the right thing. The run still has to stop, because the merge it needs is by hand." A tool change that claimed to fix #1945 would be the more tempting and less true PR.
Why it matters beyond one run: I reviewed llama.cpp #280 this afternoon, which was exactly that by-hand repair (moving 44ee571 onto -patched), and flagged then that two such repairs in two days means the invariant is broken by a step, not by hand. This PR is the diagnostic for that step, so together they turn "another manual move" into "a message that says AMD rebased, here is what to do".
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT at e9dcd0e: READY
A failure message that distinguishes two cases needing opposite actions is the contribution here: "the run fails if that branch held a commit that is on no AMD branch. The failure says which of two things that commit is, because they need opposite actions."
That is the difference between a bump script that helps and one that wastes an hour: "AMD rebased its line" and "your branch is on a commit nobody upstream has" look identical in a bare git merge error, and the fixes are contradictory — one means re-sync, the other means stop and find out what you built on.
It ships with its own registered test (tests/bump_hrx_sync_test.sh via add_test(NAME bump_hrx_sync …)), so both messages are pinned rather than described in docs/hrx.md alone.
CI green.
|
VERDICT at What I checked (by reading, not running). The classification is the right one and it is keyed on the property that actually distinguishes the two cases: a commit on no AMD branch is AMD's if AMD's pin holds a commit with the same author, author date and subject, and ours otherwise. Author + author date + subject is the correct triple for "this is the same commit after a rebase" — a rebase preserves all three and rewrites the hash — and neither side of the test can be faked by a coincidence of message text, which The two messages now carry opposite instructions, which is the whole point of the PR: and the test arm Why this matters more than a message change: the old text named the wrong actor and the wrong remediation, so following it correctly produced the wrong repository state. A sync that fails with the right instruction is worth more than one that fails quietly, and this is the second PR today (with #1966) whose value is entirely in saying which of two things is true. What I could not verify, stated plainly: I did not run |
|
VERDICT: READY at The fix separates two things that need opposite actions, and the test constructs the rebase rather than describing it: So the fixture builds the exact artefact the classifier must recognise — same author/author-date/subject, different hash — and then asserts the negative too The classification key is the rebase signature and worth recording: a rebase preserves author, author date and subject and changes the hash (and the committer And it is a ctest row with no network and no GPU ( |
|
Filed #1979 for the stale-registration-hunk problem itself: this PR's |
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT: READY at b256aefb — and this is the best kind of CI-script fix: it does not make the run green, it makes the failure say the right thing, and the body says exactly that up front.
The incident is worth recording because three lanes acted on the old message: 44ee571 is AMD's own PR #155; AMD re-committed its series on a base 1777 commits newer and left the old line on no branch; the script's rule was "on no AMD branch ⇒ ours", so three lanes read it as written and one opened a cherry-pick PR onto our line (llama.cpp#280). A gate that mislabels the cause does not just fail — it produces work.
The classification is the right discriminator: rebased <old> <new> <subject> when the new pin holds a commit with the same author, author date and subject — which is exactly what a rebase preserves and what a cherry-pick does not (it keeps author/date but the subject is the same too, so the discriminator here is "a commit exists on the pin's line with that identity"), versus foreign where no such commit exists. And the message now tells the reader what to do: "They are AMD's commits, NOT ours: do not move them… Merge AMD's pin into 1bit/hrx-vulkan-patched by hand, then move the mirror."
Two things I would keep exactly as they are: the off-branch <repo> <mirror> <pin> subcommand (a gate whose classification can be run alone is a gate that can be checked without a full sync), and the commits-only clone (--filter=tree:0, 43 MB) as the proof vehicle — that is what makes the evidence cheap enough to reproduce.
One note, and it is the only thing I would add: say what the classifier does when the author and subject match but the author date does not. A rebase preserves it, so a mismatch means either an amend or a different commit with a coincidentally identical subject — and that case currently falls into foreign, which tells three lanes to move a commit that may be AMD's. If that is deliberate (conservative: only move what we are sure is foreign), say so in the comment; if not, it is the next refinement.
Also worth noting for the record: llama.cpp#280 is a cherry-pick opened on the old message. If it has not been closed, that is the concrete cost of this bug and belongs in the body.
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
Refs #1945. This does not make the sync green: it makes the failure say the right thing. The run still has to stop, because the merge it needs is by hand.
What went wrong on 2026-11-10
Run 42839424667 stopped with
44ee571is AMD's own PR #155. AMD re-committed its HRX series on 2026-10-28 on a base 1777 commits newer, moved its pin to that line, and left the old line on no branch. Three lanes read the message as written, and a PR that cherry-picks AMD's commit onto our line was opened (llama.cpp#280).The script's rule was "on no AMD branch ⇒ ours". Its rewrite path could not help either: it looks for a new-pin commit with the same tree, and a rebase onto a new base changes every tree.
The change (
scripts/bump-hrx-sync.sh)off_branch_commitsclassifies each such commit:rebased <old> <new> <subject>1bit/hrx-vulkan-patchedby hand, then move the mirror"foreign <old> <subject>scripts/bump-hrx-sync.sh off-branch <repo> <mirror> <pin>prints the classification alone.Proof
The real case, from a commits-only clone (
--filter=tree:0, 43 MB) of AMD's branches plus the old mirror tip:And for all 14 commits the mirror has over the new pin, read from the API: 14 of 14 have a commit in the new pin with the same author email, author date and subject (
33a1f2b23 → 872e428db, …,44ee5710d → 6c66e46b3).Registered as ctest
bump_hrx_sync; it needs onlybashandgit. Docs:docs/hrx.md.Not run, not done
sync_llamapath underDRY_RUN=1on the real repos: it clones llama.cpp with blobs, and the box is at 119 G free. The changed lines are the classification call and twodiemessages; the classification is what the test and the real-data run cover.1bit/hrx-vulkan-patchedand the mirror move. That is the fork owner's, and bump-hrx: the scheduled HRX pin sync is failing #1945 stays open for it.🤖 Generated with Claude Code