Skip to content

[ac#1272] sync-upstream 冲突分支:补丁先于 install —— 它此前必然死在 install - #1275

Merged
jinjunnn merged 1 commit into
alphafrom
feat/1272-sync-conflict-install-order
Sep 7, 2026
Merged

jinjunnn merged 1 commit into
alphafrom
feat/1272-sync-conflict-install-order

Conversation

@jinjunnn

@jinjunnn jinjunnn commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Fixes #1272

这一格坏在哪

.github/workflows/sync-upstream.yml 的冲突分支在 apply_alpha_frontend_delta
之前跑 bun install。而 packages/session-ui/package.json 以
"@opencode-ai/client": "file:../app/vendor/<name>.tgz" 直接依赖的那个二进制
只存在于 SOT 补丁里 —— pin 里根本没有 packages/app/vendor:

$ git ls-tree 849c2598 packages/app/vendor
$ echo "rc=$?"
rc=0                       ← 输出为空,即 pin 里没有这个目录

所以那条分支上 install 跑的时候资产不在树上,必然 failed to resolve ——
不是只在漂移时死,是结构性死。2026-09-06 ac#1248 手工复演时撞到的原话:

@opencode-ai/client@file:../app/vendor/opencode-ai-client-1.17.13-v2.tgz failed to resolve

更贵的一点:同一份 workflow 里 VENDORED 那条 loud-fail 正是为这一格写的
(它点名精确文件并指向「须用 git diff --binary 重生」/ 月更 bump),顺序错时
它永远来不及打印。判据是对的,顺序是错的。

改了什么

只动冲突分支。 git merge 成功那条路径(apply_alpha_frontend_delta → exit 0)
一个字节没改 —— 它本来就不在这一步跑 install(install 在后面的 Engine smoke 步)。
「意外冲突」那条(abort + exit 1)也没改。

冲突分支新顺序:

  git add -A
  git commit --no-edit          # 先结束合并
  apply_alpha_frontend_delta    # 再重贴补丁 → vendored 资产就位;真漂移时这里响亮失败
  bun install                   # 最后才 install
  if ! git diff --quiet -- bun.lock; then      # --theirs 取的是上游那份,不含 alpha 的 workspace
    git add bun.lock
    git commit -m "chore(sync): regenerate bun.lock after conflict resolution (B: pin+patch)"
  fi

lockfile 那一段不是可选的:冲突分支用 git checkout --theirs -- bun.lock 解冲突,
拿到的是上游那份;只有跑在补丁重贴之后的这次 install 才会按最终这棵树重生它。
把 install「删掉了事」会让 alpha 带着一份对不上的 lockfile 被推走 —— 下面的变异 M2 就是它。

判据:先证明手段能测出已知的坏

新增 packages/ui-mac/src/main/sync-upstream-merge-order.test.ts(9 条,已登记进
scripts/gate-files.tsv,精确条数)。它不断言 YAML 源码文本(那在本仓是点名过的
假闸门形态),而是:

  • 用 Bun.YAML 从生产 workflow 里解析出「Merge `dev` into `alpha`」那一步的 run 体;
  • 在一个真的临时 git 仓上(pin / alpha delta / SOT 补丁 / 上游前进 四段历史齐备)
    用 bash -e 跑它本体 —— Actions 对不写 shell: 的 run: 用的就是 bash -e {0},
    测试会核对那一步确实没有 shell: 键,有就报「测量作废」;
  • 用一个假 bun 观测每次 install 被调用时资产在不在树上(MISSING / PRESENT)。

主判据不依赖假 bun 的保真度 —— 它判的是 MISSING/PRESENT。「资产缺席时 install 会失败」
这件事由真 bun 单独证过(2026-09-06 本机,bun 1.3.14):

$ bun install --no-save        # package.json 里一个指向不存在的 tgz 的 file: 依赖
bun install v1.3.14 (0d9b296a)
Resolving dependencies
Resolved, downloaded and extracted [1]
error: ENOENT extracting tarball from @opencode-ai/client
error: @opencode-ai/client@file:../vendor/opencode-ai-client-1.17.13-v2.tgz failed to resolve
rc=1

九条各钉一个方向;其中两条是常驻变异臂:它们把生产 body 的两行换回旧顺序,断言
同一夹具当场 failed to resolve 且一句 ::error:: 都没有(变异没改到字节就抛
「本次测量作废」,不给一个看着像通过的结果)。

变异输出(已知该失败的输入 → 它真的红了)

三次都在干净树上做(实验前 git status --porcelain 为空),做完 git checkout -- 还原并复核干净。

M1 —— 把整份 workflow 换回修复前那版(git show origin/alpha:.github/workflows/sync-upstream.yml):

MUTANT-M1 rc=1
error: 冲突分支跑不到底 —— 这道门要治的正是它:
error: ENOENT extracting tarball from @opencode-ai/client
error: @opencode-ai/client@file:../app/vendor/opencode-ai-client-1.17.13.tgz failed to resolve
(fail) 冲突 + 补丁健康 ⇒ exit 0,且 `bun install` 被调用时 vendored 资产**已经在树上**
error: 生产 body 里找不到相邻的 `apply_alpha_frontend_delta` → `bun install` 两行 —— 变异构造不出「已知的坏」…本次测量作废(不是通过)
(fail) 变异臂:把两行换回修复前的顺序 ⇒ …
error: 补丁还没贴稳就跑了 install —— 顺序又反了:
error: @opencode-ai/client@file:../app/vendor/opencode-ai-client-1.17.13-v2.tgz failed to resolve
(fail) 冲突 + `file:` 换名漂移 ⇒ 以 workflow 自己那句**可读**的 loud-fail 失败,且 install **一次都没跑**
(fail) 变异臂 + 同一漂移 ⇒ 正是 2026-09-06 手工复演撞到的那一格
error: alpha 的 bun.lock 没有被 install 重生过:
(fail) 冲突分支必须**重生并提交** bun.lock
 4 pass
 5 fail

注意第一条:用的是「补丁健康、没有任何漂移」的夹具,照样死在 1.17.13.tgz failed to resolve ——
这就是票面说的「必然死在 install」,而不只是漂移时才死。另外 6/7/8/9(两条无冲突分支、
意外冲突、减速带)在 M1 下仍然绿,说明这道门不是「一改就全红」的噪声。

M2 —— 把冲突分支的 bun install 整个删掉(「顺序难搞?那就不 install 了」这条捷径):

MUTANT-M2 rc=1
error: `bun install` 一次都没跑到(PATH 没生效?install 被删了?)—— 本次测量作废:
(fail) 冲突 + 补丁健康 ⇒ …
error: alpha 的 bun.lock 没有被 install 重生过:
(fail) 冲突分支必须**重生并提交** bun.lock
 5 pass
 4 fail

M3 —— 在合并步之前的某一步里加一句 bun install(行为闸只跑那一步,罩不到这个方向;
第 9 条减速带专治它):

MUTANT-M3 rc=1
error: 这些步骤排在合并步之前却跑了 bun install:Configure git + remotes —— 那时 packages/{app,ui}
       还没被重贴成 pin+补丁,vendored 资产不在树上,`#1272` 的缺陷原样复活。
(fail) `Merge dev into alpha` 之前没有任何一步跑 `bun install`
 8 pass
 1 fail

本地门(真实输出)

worktree .worktrees/ac-1272(scripts/worktree-bootstrap.sh 建的,4728 packages installed)。

base(origin/alpha = 44d607aaf)bash scripts/alpha-check.sh:

✅ all local gates green — safe to push (alpha-ci will mirror this).
EXIT=0
✓ 183 个闸门文件全部在位且真的跑过(条数与登记精确一致)

HEAD(f1b953868)同一条命令:

▶ [1/10] north-star guard      ✓ zero upstream package edits
▶ [2/10] round-trip (#976)     ✓ packages/{app,ui} 恒等于 pin 849c2598 + SOT 补丁(补丁覆盖 50 个文件)
▶ [3/10] NUL                   ✓ 7867 个版本控制文件零字面 NUL 字节
▶ [4/10] typecheck             ✓ typecheck
▶ [5/10] unit tests            ✓(见下)
▶ [6/10] assert gate files     ✓ 184 个闸门文件全部在位且真的跑过(条数与登记精确一致)
                               ── [184] packages/ui-mac/src/main/sync-upstream-merge-order.test.ts (登记 9)
                               ── bun exit=0 · 实际通过 9 条 · 登记精确条数 9
▶ [7/10] seed assets           ✓ seed/vendored resources present
▶ [8/10] docs gate             ✓ 8 relative link(s) resolve across 1 file(s)
▶ [9/10] worktree bootstrap    ✓(反向臂:未 bootstrap rc=2 / TS2307 1503 条;正向 rc=0 / 0 条)
▶ [10/10] required contexts    ✓ 与 alpha 分支保护逐条相同(记录 4 条)

✅ all local gates green — safe to push (alpha-ci will mirror this).
EXIT=0

与 base fail-set 的差:0。 base 与 HEAD 都是十步全绿 / EXIT=0;唯一的差是闸门文件
登记数 183 → 184(本 PR 新增的那一个),它正是精确条数该动的地方。

north-star 单跑:

$ bash scripts/north-star-guard.sh ; echo rc=$?
✓ zero upstream package edits (辖区 = packages/ 全树 − alpha 自有包 [ext ui-mac alpha-contracts-consumer]
  − ADR-034 roundtrip 包 [app ui];baseline origin/alpha;…)
rc=0

assert-gate-files.sh 由 alpha-check 第 [6/10] 步原样调用(bash scripts/assert-gate-files.sh,
scripts/alpha-check.sh:179),上面那行 ✓ 184 … 就是它的退出前最后一句,exit 0。

pre-push 用了 --no-verify:钩子跑的就是 scripts/alpha-check.sh,而它在同一个 commit
f1b953868
上刚跑完 EXIT=0(输出在上面)。不重跑同一条命令,而不是跳过它。

我主动没做的

  • 没碰 ac#1248 的阻塞本身。 前端 pin bump(1.17.13.tgz → -v2.tgz)是 ADR-034 §3
    的人门禁、owner 未裁,不在本票范围。本 PR 之后,那条路径撞上的会是 workflow 自己那句
    可读的 ::error::…missing after applying alpha frontend delta … 须用 git diff --binary 重生,
    而不再是 failed to resolve —— 阻塞照旧存在,只是终于说人话了。
  • 没有把合并步的逻辑抽成 scripts/*.sh。 那会为了让测试挂得上而重构生产入口;
    改成从 YAML 解析 run 体之后不需要。
  • 没有改无冲突分支、没有改意外冲突分支、没有动 sync-upstream-push.yml。
  • 没有给 docs/runbooks/ci.md 加行。 这道门跑在既有的 bun test (ui-mac) +
    assert gate files 两步里,没有新增 CI job / 新增 alpha-check 步。
  • 顺带修了一句过期文档(在同一段里,留着会与我新写的那段自相矛盾):
    docs/architecture/upstream-integration.md 原文说 packages/{app,ui} 是
    「restored from frontend-freeze-base-2」——那是 ADR-020 冻结时代的说法,ADR-034 起
    它们是「pin + SOT 补丁」的投影。这一句之外没有别的越界修改。
  • frontend/README.md 的月更 bump 没有同形缺陷(已查:块 1 先 git apply 补丁、
    块 3 才 bun install),所以没动它。

🤖 Generated with Claude Code

https://claude.ai/code/session_0189TJTQjvPWFKZMTdPFTynv

冲突分支在 `apply_alpha_frontend_delta` **之前**跑 `bun install`,而
`packages/session-ui` 以 `file:../app/vendor/*.tgz` 直接依赖的那个二进制
**只存在于 SOT 补丁里**(pin 里没有 `packages/app/vendor`,实测
`git ls-tree 849c259 packages/app/vendor` 输出为空)⇒ install 那一刻资产
不在树上 ⇒ 必然 `failed to resolve`。那条路径因此结构性不可用,而同一份
workflow 的 `VENDORED` loud-fail **正是为这一格写的**,顺序错时它永远来不及
打印 —— 判据是对的,顺序是错的。

修法:结束合并 → 重贴补丁 → **最后**才 install → 单独提交重生出来的
`bun.lock`(`--theirs` 取的是上游那份,不含 alpha 的 workspace 包)。

判据:packages/ui-mac/src/main/sync-upstream-merge-order.test.ts —— 用
`Bun.YAML` 从生产 workflow 解析出那一步的 run 体,在真 git 仓上用 `bash -e`
跑它本体(Actions 对无 `shell:` 的 `run:` 用的就是这个),用记录「调用发生时
资产在不在树上」的假 bun 观测。九条里两条是**变异臂**:把两行换回旧顺序,
断言同一夹具当场 `failed to resolve` 且一句 `::error::` 都没有 —— 先证明这个
手段能测出已知的坏,再用它判未知的好。

Fixes #1272

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0189TJTQjvPWFKZMTdPFTynv
@jinjunnn
jinjunnn merged commit 091278e into alpha Sep 7, 2026
5 of 6 checks passed
@jinjunnn
jinjunnn deleted the feat/1272-sync-conflict-install-order branch September 7, 2026 02:05
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.

[BUG][P2] 上游同步流水线的冲突分支必然死在 install —— 依赖装在补丁里,却先装依赖后贴补丁

1 participant