From 5cbbb311686b2d33fa57e9f75da65aa77d839775 Mon Sep 17 00:00:00 2001 From: zpyoung Date: Mon, 19 Oct 2026 14:06:55 -0500 Subject: [PATCH] docs(sync-skill): stack a directed sync on an open older sync PR, and recognize tag-tip workflow swaps --- .claude/skills/sync-upstream/SKILL.md | 7 +++++ .../sync-upstream/references/sync-lessons.md | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/.claude/skills/sync-upstream/SKILL.md b/.claude/skills/sync-upstream/SKILL.md index 9abd2c1500e8..db7d95c456f3 100644 --- a/.claude/skills/sync-upstream/SKILL.md +++ b/.claude/skills/sync-upstream/SKILL.md @@ -199,6 +199,13 @@ resolution and races it. Stop before Step 3 — nothing backed up, merged, or pu next run syncs `$STABLE_TAG` fresh. Hit on 2026-09-10 (#48, v1.4.198 vs v1.4.199) and 2026-09-26 (#92, v1.4.209 vs v1.4.212). +That stop is for the unattended run. When a person directs the run past it, stack instead of +racing: back up `main`, `git reset --hard` to the older PR's head, merge `$STABLE_TAG` onto it with +`-X ours`, and resolve from Step 6 as usual, with the older tag's resolution already in the tree. +Open the result as a new PR. Landing it lands both tags in one merge commit, and GitHub marks the +older PR merged because its head becomes an ancestor of `main`. Proven 2026-10-19: #122 (v1.4.230) +on #120 (v1.4.227). + A PR titled `sync: absorb upstream $STABLE_TAG` is this run's work, already done. **Adopt it — do not re-merge.** Verify it before you build on it, because its body is its own account and not evidence: diff --git a/.claude/skills/sync-upstream/references/sync-lessons.md b/.claude/skills/sync-upstream/references/sync-lessons.md index 3ac4231bc5c9..b6ddc372b274 100644 --- a/.claude/skills/sync-upstream/references/sync-lessons.md +++ b/.claude/skills/sync-upstream/references/sync-lessons.md @@ -356,3 +356,32 @@ want the same action for opposite reasons — so say which one happened in the r `v1.4.206` at `b10226a7ed`, the next run sees a tag `main` does not contain and merges it, leaving `main` with two distinct "release: v1.4.206" commits. That merge is legitimate — the tag would be a real new release — but the duplicate is worth expecting rather than diagnosing from scratch. + +## A tag whose last commit swaps in main's workflows + +**What happened.** Upstream now tags some stable releases on top of a release-branch commit that +replaces that branch's `.github/workflows/` files with `main`'s, so the release token is allowed to +push the tag. v1.4.227 carried `a220036892` ("ci: carry main's workflow files so the release tag +can be pushed", 63 files) and v1.4.230 carried `597425845e` ("ci: match main's workflow files so the +release token can tag this branch", 9 files) directly below `release: v1.4.230`. The release +branch's `config/scripts/` tests stayed at the branch's own age, so the tag disagrees with itself: +on PR #122, 8 workflow-contract tests were red with the test and every file it reads byte-identical +to `v1.4.230`. `pr.yml` also gained main's `dependency_isolation` job (+65 lines) without the scope +script that emits its selection, so `verify` failed every PR with "missing or invalid selection". +Step 6 resets upstream-owned workflows to the tag, which is exactly what imports the mismatch. + +**The tell.** The commit directly below `release: ` touches only `.github/workflows/`: + +```sh +git log --oneline -3 "$UPSTREAM_TARGET" +git show --stat --format='%h %s' "$UPSTREAM_TARGET^" | tail -3 +``` + +A test red in CI whose file and inputs all match the tag (`git diff --quiet "$UPSTREAM_TARGET" -- + `) is the same thing seen from the other end. It is not merge damage and not flake. + +**The right move.** For every upstream-owned workflow that commit touched, take its parent's copy +(`git checkout "^" -- `), which is the release branch's own consistent pair of workflow +and test. For a fork-owned workflow such as `pr.yml`, rebuild from the parent too, or strip that +commit's hunks out of it by hand. Do not take main's version of the scripts to match the workflows, +and do not edit the red tests: they are upstream-owned and correct for the release they ship in.