[#777][CODE] 门在自己的标准环境里跑不出真结果:整类枚举 + 环境咽喉 + 本地门与 CI 的对照断言 - #804
Merged
Conversation
Fixes #777 ## 大白话 一批质量门在它们被设计要跑的那个环境里跑不出真结果 —— 不是发现了问题,是跑不起来 (或者根本没被执行)。恒红的门等于没有门,假绿的门更糟。半个月内同一形态第四次 (#754 / #769 / 本票原列的 alpha-check typecheck / 2026-08-02 起主线连红两天), 所以这次不逐个修,枚举整类 + 在咽喉点收口。 ## 枚举结果 docs/architecture/quality-gate-environments.md —— 每道门 × 每个环境 × 真实状态, 两条互相独立的检索轴交叉验证(其中两条轴给出了不同答案,记在文里)。 ## 修了什么 1. 环境咽喉 packages/ui-mac/scripts/test-preload.ts(bunfig preload,父子进程同时生效): · setDefaultTimeout(120_000) —— 基线实测 31 条 spawn host 用例里 19 条从没声明超时, bun 默认 5s 让机器速度替断言下判决(CI 上已炸 3 条)。 bunfig [test] timeout 不被读取、BUN_TEST_TIMEOUT 系列全部无效、--timeout 传不进子进程, 三条都是实测排除的,只有 setDefaultTimeout 在 preload 里对父子两侧都生效。 · 平台钉桩 —— 本产品只 ship darwin/win32(ADR-026),alpha-ci 跑 ubuntu,生产安装闸 在写盘前拒掉整个 runner。host 平台不在发布清单时钉到 darwin,并打印 `PLATFORM SIMULATED this run` 自陈这是模拟不是覆盖。 2. electron 桩补齐(test-component/claude-plugin-intake.ipc.cases.ts):electron-log 在模块 顶层就调 ipcMain.on,`?.` 挡不住「ipcMain 在而 .on 缺」。按装着的 electron-log@5.4.4 源码逐条枚举补全,不是凭记忆。 3. alpha-ci 的 `assert gate files` 改 `if: !cancelled()` —— GitHub step 默认条件是 success(),于是前一步一红,77 个登记闸门集体 skipped(其中 llm/core/opencode 那几个 只在这一步执行)。已实际发生两天。 4. scripts/alpha-check.sh 从 9 步(其中 3 步降级)补到 alpha-ci 全部 12 个代码步: 补 assert-gate-files / assert-seed-assets / check-doc-links,三条测试从裸 `bun test` 换成 bun-test-floor.sh(裸的跑 0 条照样 exit 0),并在末尾打印逐步覆盖对照表。 ## 新增两道门 · src/main/gate-environment.test.ts —— 咽喉的行为闸(一条 6 秒、不写超时的子进程用例; 声明被删即红),平台那一半按 os.platform() 自陈本次跑没跑到。 · src/main/local-gate-parity.test.ts —— 把「与 alpha-ci 1:1」变成断言:双向对照 CI 代码步、 档位只允许 MIRRORED/SUPERSET:<理由>/DEGRADED:<理由>、#637 退出条件 3 的白名单防漂、 assert gate files 必须带 !cancelled()。 Refs #637 #649 #717 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
绕过实验里逐个跑了 bun 1.3.14 的三种形态: · 文件在、用例被清空/条件注册成零条 → exit 0(**唯一的假绿**) · 指定测试文件不存在 → exit 1 · 整个目录零匹配 → exit 1 仓内既有注释(alpha-ci.yml / bun-test-floor.sh)把第二种也算进 exit 0 那一档, 与实测不符。下界该立还是要立 —— 第一种恰好就是「有人把闸门文件清空」的形状。 本 PR 不动那两处注释(范围外),把更正记在勘破文档里。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
自己新加的那道门在全量里把上一版打红了: (fail) 环境咽喉对子进程也生效 [5005.06ms] ^ timed out after 5000ms 单跑该文件通过、`bun test src`(257 文件)里挂 —— 实测 bun 1.3.14 的 `setDefaultTimeout()` 从 preload 调用**只对第一个测试文件生效**, `beforeAll(() => setDefaultTimeout(...))` 也无效,跨文件唯一有效的是 CLI `--timeout`。 上一版的证据是一个**单文件探针**,而闸门跑的是多文件 —— 假绿。 修法:两处声明覆盖两种真实形状。 · 形状 B 多文件(CI 三条 test 步 / assert-gate-files 的 77 次 / alpha-check [4/7] —— 所有闸门运行的唯一入口)→ scripts/bun-test-floor.sh 加 `bun test --timeout`; · 形状 A 单文件(31 条 host 起的子进程,argv 自己拼、传不进 flag)→ 保留 preload, 并把它的真实作用范围写进注释。 行为闸相应改成两个子进程各验一半,慢用例**排在第二个文件**(占位文件 gate-environment-first.cases.ts 为此存在:让慢的当第一个,验的是本来就成立的那一半)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
真环境(alpha-ci run 30781793073)量出来的两条,开发机上一条都看不到: 1) preload 里全局 `process.platform = "darwin"` ⇒ 14 个 renderer 文件整片挂在 `error: Cannot find module @rollup/rollup-darwin-x64` —— vite/rollup 按 process.platform 选原生可选依赖,linux runner 上装的是 linux 那份。 3752 pass 掉到 3625。**为了修 2 条而弄坏 14 个文件 = 把一处假红换成一片真红。** 改法:preload 只保留「检测 + 自陈」(打 PLATFORM DEGRADED,并指名要 opt-in); 钉桩挪到 test-component/pin-shipped-platform.ts,由真正走生产平台闸的 ext-install-catalog-result.cases.ts 显式调用,同样自陈 PLATFORM SIMULATED。 2) 行为闸的形状 B 经 `bash scripts/bun-test-floor.sh`,而脚本里写的是裸 `bun`; CI 上挂在 `bun-test-floor.sh: line 55: bun: command not found` —— 从 bun 进程 spawn 出去的 bash 的 PATH 里没有 runner 装的 bun(开发机有,所以本地看不见)。 改法:把正在跑本测试的那个 bun 所在目录前置进子进程 PATH。 同一次 run 已经证明前三个修复在 Linux 上成立(全部 (pass)): 生产 ext-import-skill-folder … ← electron 桩补齐 真实 catalog MCP …不回显… secret canary ← 平台 package safe view … ExtensionHub … ← 超时 REQ-128 Phase 3 第 1→9 跳 … ← 超时(含子进程内部两条) 以及 `assert gate files` 在第 9 步红的情况下**照跑了** ← !cancelled() Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
子进程打的 PLATFORM SIMULATED / [gate-environment] 被 host 吃进变量,只在失败时抛出 —— 于是「这次降级了什么」在**绿的那一次反而看不见**,而那正是需要它的时候。 实测:上一版在 alpha-ci 全绿的 run 里 grep 不到任何一行自陈。 gate-environment.test.ts 在成功路径上转述子进程的自陈行;运行级那句由 preload 直接打。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #777
大白话
一批质量门在它们被设计要跑的那个环境里跑不出真结果 —— 不是发现了问题,是跑不起来、或者
根本没被执行。恒红的门等于没有门(大家会习惯性
--no-verify/--admin);假绿的门更糟(它主动告诉你"没事")。半个月内同一形态第四次,所以这次不逐个修:枚举整类 + 咽喉收口。
票面第三个实例已证伪
票面说
alpha-check.sh的 typecheck 步在 base 上红 202 条。实测三个包 typecheck 全部 exit 0,bun test src3756 pass / 0 fail;那 202 条来自依赖没链全的 worktree,真因是#796(
worktree-link-deps.sh不链.bin),已于alpha@10daf61b修复。今天真正在烧的是另一道门。
枚举结果
docs/architecture/quality-gate-environments.md—— 每道门 × 每个环境 × 真实状态,两条互相独立的检索轴交叉验证。其中两条轴给出了不同答案(按文件 grep
timeout漏掉 6 个数字第三参形态;按文件计数会数错,粒度必须是每条
test(...)声明),都记在文里。修了四个实例 + 两条连带伤害
unit tests (alpha packages)在alpha主线上自 2026-08-02 起连续两天全红(实测 8 个 run id,凡带代码的 run 无一例外);同一棵树开发机 0 failplatform linux not supported by this entry — refusing before any disk write—— 生产synthesizeManifest把compatibility.platforms写死["darwin","win32"](ADR-026),runner 是 ubuntuPLATFORM SIMULATED this runtimed out after 5000ms—— host 用 bun 默认 5s 去等一整套子 suite。基线实测 31 条 host 用例里 19 条从没声明过超时bun-test-floor.sh加--timeout+ preload 兜单文件TypeError: this.electron.ipcMain?.on is not a function—— electron 桩缺ipcMain.on,而electron-log在模块顶层就调它(?.挡不住"ipcMain在而.on缺")electron-log@5.4.4源码逐条补全桩assert gate files因 GitHub 默认success()被 skipped ⇒ 77 个登记闸门连续两天一次都没跑(其中 llm/core/opencode 那几个只在这一步执行)if: ${{ !cancelled() && … }}alpha-check.sh自称与 alpha-ci「1:1」(三处文档),实测只跑 12 个代码步里的 9 步,其中 3 步是裸bun test的降级档咽喉:两处声明,覆盖仓内真实存在的两种运行形状
Bun.spawnSync([bun,"test",<abs>])起的子进程(argv 自己拼,传不进 flag)packages/ui-mac/scripts/test-preload.tsassert-gate-files.sh的 77 次 +alpha-check.sh[4/7](所有闸门运行的唯一入口)scripts/bun-test-floor.sh的bun test --timeout候选机制全部实测排除(bun 1.3.14,不是推断):
bunfig.toml [test] timeout不被读取;BUN_TEST_TIMEOUT/BUN_TIMEOUT/BUN_TEST_TIMEOUT_MS全部无效;beforeAll(() => setDefaultTimeout(…))无效;preload 里
setDefaultTimeout()只对一次运行的第一个文件生效;只有 CLI--timeout跨全部文件成立。新增两道门(均已登记
scripts/gate-files.tsv)src/main/gate-environment.test.ts—— 咽喉的行为闸,两个子进程各验一半;慢用例排在第二个文件(占位文件
gate-environment-first.cases.ts为此存在:让慢的当第一个,验的是本来就成立的那一半)。平台那一半按
os.platform()自陈本次到底跑没跑到。src/main/local-gate-parity.test.ts—— 把"与 alpha-ci 1:1"变成断言:双向对照 CI 代码步、档位只允许
MIRRORED/SUPERSET:<理由>/DEGRADED:<理由>(没有"静默不跑"这一档)、#637退出条件 3 的白名单防漂、assert gate files必须带!cancelled()。两条解析自检(
ciSteps ≥ 12、ciExcludes ≥ 20)防止解析器退化后空对空全绿。绕过实验(11 次,每次都先证明手段能测出已知的坏)
setDefaultTimeout(fail) [形状 A 单文件子进程] … timed out after 5000msbun-test-floor.sh的--timeout(fail) [形状 B 多文件闸门入口] … timed out after 5000msexpected authorization pause, got {"ok":false,"reason":"platform linux not supported by this entry — refusing before any disk write"},3 pass / 2 failelectron-log@5.4.4跑旧桩 / 新桩THROWS: this.electron.ipcMain?.on is not a function…/onIpc OK!cancelled()(fail) assert gate files 不因前一步失败而被跳过#637原始形状)(fail) #637 退出条件 3(fail) alpha-ci 的每个代码步都登记在 CI_STEPS 里SKIPPED(fail) 每一行的档位只能是 MIRRORED / SUPERSET / DEGRADEDbun exit=0(真的假绿)→ 被下界抓成::error::闸门文件失守真环境实测:三轮 CI,每一轮都量出一个开发机上看不见的缺陷
CI 在这里不是"合并前等它变绿"的那个 CI —— 它是唯一存在的 Linux 环境,是本票两个
平台/解析相关修复的测量仪器。三轮各自的产出:
30781793073assert gate files在第 9 步红的情况下照跑了;但我自己引入两个回归:全局钉平台让 14 个 renderer 文件挂在Cannot find module @rollup/rollup-darwin-x64(3752→3625),行为闸挂在bun-test-floor.sh: line 55: bun: command not found30782188831Ran 3762 tests across 257 files/0 fail/✓ 79 个闸门文件全部在位且真的跑过;但绿的 run 里 grep 不到任何一行降级自陈 —— 子进程 stdout 被 host 吃进变量,只在失败时抛出30782536774第 3 轮(最终)六个 job 全 success,自陈行真的出现在运行输出里:
开发机上同一行是
host=darwin(本身就是发布平台)⇒ 平台钉桩这一半**本次没有被执行**——测不到就说测不到,不让本地的绿被读成"平台也验过了"。
本地门(真实输出,最终 commit)
base(
alpha@10daf61b)同一棵树:3756 pass / 0 fail;本分支 3762 / 0(+6 = 新增两道门)。base fail-set 为空,本分支 fail-set 为空。 本地门耗时 1m43s → 2m52s(补了 3 个此前没跑的步骤)。
--no-verifypush:同一 commit 上刚跑完完整alpha-check.sh,不重复跑第二遍。边界
unit tests (ui-mac)与真实 job 名unit tests (alpha packages)对不上(job 于 2026-07-22ebd29cda改名),每个 PR 都缺这一格 —— 归
#717,只把实测写进 runbook。#649的三份无人执行的 opencode 测试,只归类记录。alpha-ci.yml/bun-test-floor.sh里那两处被证伪的注释文字(范围外,记在勘破文档里)。Refs #637 #649 #717 #796
🤖 Generated with Claude Code