← ClaudeAtlas

stale-base-pr-silently-reverts-upstream-contentlisted

Detect and recover when a sibling PR's squash-merge silently reverts an upstream PR's content changes because the sibling was based on a pre-upstream main snapshot and its line-level rewrites overlapped the upstream PR's edits. Use when: (1) two PRs are open in parallel against the same file(s) — one refreshing numbers/values, the other rewriting copy/language, (2) the number-refresh PR merges first, the language-rewrite PR merges second, (3) the language-rewrite PR claims "all numbers preserved" in its body — true against ITS base, not against post-upstream-merge main, (4) post-merge of the second PR, displayed numbers regress to pre-fix values while OTHER files in the same upstream PR (untouched by the second PR) still hold the new values — creating a train-serve / display-vs-backend mismatch, (5) CI on both PRs was green and `mergeable: MERGEABLE` because git's 3-way merge resolves textual overlap silently (it does not see "numbers vs language" semantics). Detection: grep upstream PR's distinctive strings
wan-huiyan/agent-traffic-control · ★ 2 · AI & Automation · score 79
Install: claude install-skill wan-huiyan/agent-traffic-control
# Stale-Base PR Silently Reverts Upstream Content via Textual Overlap ## Problem You ship PR A: updates 8 specific lines in `templates/foo.html` with new numbers (`50% vs 6%`, `n=117`, etc.). PR A merges cleanly. CI green. In parallel, PR B was opened against `origin/main` BEFORE PR A merged. PR B rewrites copy in the same file for language polish — touching the same 8 lines, but with the OLD numbers (because that's what PR B's base showed). PR B's body claims "all numbers preserved." PR B rebases / `gh pr merge --squash`s after PR A. Git's 3-way merge runs: - **Base** (common ancestor): old text + OLD numbers - **Main side** (post-PR-A): old text + **NEW** numbers ← PR A's contribution - **PR B side**: rewritten text + OLD numbers ← PR B's contribution For lines where PR B's rewrite spans the same text PR A edited, the 3-way merge sees PR B as the "winning" branch-side and takes PR B's version wholesale. **PR A's numbers silently disappear from those lines.** Other files PR A touched but PR B didn't (`app.py`, `intelligence_findings.js`, `library_findings.html`) keep PR A's numbers intact. Result: a **train-serve / display-vs-backend mismatch** that no PR diff, no CI signal, and no merge conflict flagged. PR B's author was honest — the numbers WERE preserved against THEIR base. The regression is invisible until someone audits the post-merge main against PR A's intended diff. ## Context / Trigger Conditions All of these typically hold: 1. **Two PRs open in parallel**