Skip to content

ci(test-suite-registration): 止住孤儿套件的增量 —— 新套件要么进 CI,要么写明为什么不进 - #1003

Merged
vansin merged 1 commit into
mainfrom
ci/test-suite-registration-ratchet
Aug 18, 2026
Merged

ci(test-suite-registration): 止住孤儿套件的增量 —— 新套件要么进 CI,要么写明为什么不进#1003
vansin merged 1 commit into
mainfrom
ci/test-suite-registration-ratchet

Conversation

@vansin

@vansin vansin commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

#861。那条 issue 要的是一次逐个分类;这条 PR 不做分类,只止住增量

数字(用 #861 的原口径复量,2026-08-18)

套件 = tests/<dir>/run.sh 存在的目录;已注册 = 目录名出现在 scripts/qa.sh
或任意 .github/workflows/* 里。

                          今天    #861 当时(08-13)
套件                       197         194
  已注册                    33          21
  🔴 孤儿                  164         173

5 天里接进去 12 个,方向对,绝对数没有实质变化。而缺口还在按每个新 PR 的速率长:
#812 正在新增的 tests/test812-tmux-target-semantics/ 就是下一个,而那条 PR 的目的
恰恰是「把文档里那几行 tmux 命令绑到实测语义」。

🔴 这道门不要求清零

#861 正文自己说了,把 173 个一股脑塞进 CI「只会把 CI 变慢并制造噪音」——里面有一次性
验证、事故复现件、已被后续套件取代的。基线记着今天这 164 个,门只对新增的孤儿变红。

理由与 check-home-path-baseline.py 一字不差:一道只因积压而红的门,等积压清完就
再也不会红,到时没人知道它还有没有效。

判据

情形 结果
1 目录名出现在 qa.sh 或任意 workflow OK
2 目录里有 NOT-IN-CI.md OK(明确声明不进 CI)
3 在基线里 OK(存量)
4 都不是 🔴 红

判据 1 刻意沿用 #861 的口径,两边数字可直接比——换口径的对比会把方法差异伪装成进展。

它不判「这个套件该不该进 CI」,那是 #861 要的分类,门做不了。门只保证:新增一个
套件时,这个问题被回答过一次。

验证

结果
绿起点 suites=197 registered=33 exempt=0 orphans=164 baseline=164 new=0 rc=0
见红 A 新增 tests/test999-probe-new-suite/run.sh,无人引用 → rc=1,错误消息给出 (a)(b) 两条出路
见绿 B 同一个套件补上 NOT-IN-CI.md → rc=0
note C 把已注册的 test831 塞进基线 → 打 note 提示删行,不判红 rc=0

绿起点那三个数与我在 #861 上复量
的完全一致(197/33/164),互为交叉验证。

C 这条是刻意对齐既有立场check-home-path-baseline.py 对「存量变好但基线没跟着降」
也是打 note 不判红。新门不该比产品对同一条件的既有立场更严。

判据只有一份实现

main()selftest() 都调 classify()。selftest 里重写一遍判据只能证明「我写的两遍
一样」——今晚自造判据四次,四次都比真判据松。

变异验证:去掉 NOT-IN-CI.md 那条豁免 → selftest 4/5 红并点名 test901-exempt

其它

不加 paths(带 paths 的 workflow 做不了 required check),job name
test-suite-registration 经核全仓唯一,自检先于扫描跑,取集为空或基线缺失时退 2。

#861 的普查:2026-08-13 是「194 个套件只有 21 个被 CI 引用」。2026-08-18 我用**它的
原口径**复量(`tests/<dir>/run.sh` 存在 = 套件;目录名出现在 `scripts/qa.sh` 或任意
`.github/workflows/*` = 已注册):

    197 个套件 / 33 个被引用 / 🔴 164 个孤儿      (当时 194 / 21 / 173)

5 天里接进去 12 个,方向对,**但绝对数没有实质变化**,而且缺口还在按每个新 PR 的
速率继续长 —— PR #812 正在新增的 `tests/test812-tmux-target-semantics/` 就是下一个,
而那条 PR 的目的恰恰是「把文档里那几行 tmux 命令绑到实测语义」。

🔴 **这道门不清理存量。** 那需要 #861 说的那次逐个分类(一次性验证/事故复现件/
已被后续套件取代的),把它们一股脑塞进 CI 只会让 CI 变慢并制造噪音 —— #861 正文
明确写了这一点。基线记着今天这 164 个,门只对**新增的**孤儿变红。

理由与 `check-home-path-baseline.py` 一字不差:**一道只因积压而红的门,等积压清完
就再也不会红,到时没人知道它还有没有效。**

判据(对每个 `tests/<dir>/run.sh`):
  1. 目录名出现在 qa.sh 或任意 workflow  → OK
  2. 目录里有 `NOT-IN-CI.md`             → OK(明确声明不进 CI)
  3. 在基线里                            → OK(存量)
  4. 都不是                              → 🔴 红

判据 1 刻意沿用 #861 的口径,两边数字可直接比 —— 换口径的对比会把方法差异伪装成进展。

验证:
  绿起点  suites=197 registered=33 exempt=0 orphans=164 baseline=164 new=0   rc=0
          (三个数与我在 #861 上复量的完全一致,互为交叉验证)
  见红 A  新增 tests/test999-probe-new-suite/run.sh,无人引用          rc=1
  见绿 B  同一个套件补上 NOT-IN-CI.md(门给的第二条出路)              rc=0
  note C  把已注册的 test831 塞进基线 → 打 note 提示删行,**不判红** rc=0
          (存量变好不判红,与既有棘轮立场一致,不在这里收紧)

判据只有一份实现:`main()` 和 `selftest()` 都调 `classify()`。selftest 里重写一遍
判据只能证明「我写的两遍一样」—— 今晚自造判据四次,四次都比真判据松。
变异验证:去掉 NOT-IN-CI.md 那条豁免 → `selftest 4/5` 红并点名 `test901-exempt`。

workflow 沿用本仓惯例:不加 paths(带 paths 的做不了 required check),job name
`test-suite-registration` 经核全仓唯一,自检先于扫描跑。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vansin
vansin merged commit 01b383c into main Aug 18, 2026
16 checks passed
@vansin
vansin deleted the ci/test-suite-registration-ratchet branch August 18, 2026 14:19
vansin added a commit that referenced this pull request Aug 18, 2026
…1004)

* fix: fail closed on broken Grok CommHub MCP

* test: exercise Grok CommHub MCP readiness handshake

* test: add isolated Grok MCP readiness gate

* test: exercise the real Grok MCP doctor

* docs: report Grok vendor MCP readiness

* test: gate Grok readiness on product startup path

* test: keep Grok gate dependency layers source-independent

* test: anchor Grok readiness to runtime events

* docs: record exact Grok MCP readiness evidence

* fix(grok): 把 #825 的 MCP 就绪 fail-closed 落到 main(rebase + 补两处今天新门抓到的)

#825(`fix(grok): fail closed when CommHub MCP is not ready`)从 2026-08-15 起是
draft,落后 main 120 个提交,上次 CI 只跑了 10 个 check(今天一个 PR 跑 13–23 个)。
它是 grok 栈 `#825#826#830 → {#836,#867}` 的**唯一出口**,它不落地,
上面四条谁都到不了 main。

**没有 force-push 那条共享 draft 分支** —— 本 PR 从我自己的分支发,内容是它那 9 个
补丁 rebase 到 `origin/main`(`rc=0`,0 冲突)再加下面两处修补。

## 今天新合的两道门抓到了它两处

上一轮我测过「#825 引入新失败 0」,那句话当时是真的 —— 但那两道门是**今天晚些时候**
才合进 main 的,门槛抬高之后它就红了:

  1. `test-suite-registration`(#1003)
     `tests/test813-grok-mcp-readiness/` 是新增套件,没有任何 CI 会跑它。
     🔴 这条特别值得修而不是豁免:**#825 的目的就是「MCP 没就绪时 fail closed」,
     而验证这件事的套件如果不进 CI,fail-closed 这个保证就没有任何东西持续守着。**
     照 test831 的同构做法接进 qa.yml:两处 `paths` + build/run 两个 step。
     ⚠️ 它的 Dockerfile 收的 build-arg 叫 `SOURCE_COMMIT`(不是 831 的
     `TEST831_SOURCE_COMMIT`),容器里由 `ENV TEST813_SOURCE_COMMIT` 承接 ——
     照抄 831 的参数名会静默拿不到值。

  2. `doc-symbol-pins`(#1002)
     `docs/message-lifecycle.md` 把 `shouldSkipMessage` 钉在 `cli.ts#L4639`,
     而 #825 给 cli.ts 加了 54 行,真值现在是 **4662**。
     文本 `cli.ts:4639` 和 URL `#L4639` 是同一句话的两副面孔,两处都改 ——
     只改 URL 会留下渲染出来给人读的那个错数字。

## 验证

    rebase 到 origin/main            rc=0,0 冲突,9 个补丁
    test-suite-registration          rc=0   suites=198 registered=34 orphans=164 new=0
    doc-symbol-pins                  rc=0
    l1-paths-sync / qa-trigger-coverage / workflow-structure / docs-integrity /
    no-escaped-comments              全部 rc=0

`registered` 从 33 变 34、`orphans` 仍是 164 —— 新套件是接进 CI 了,不是塞进基线蒙混。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(test813): 一条从写下起就是空的变异 —— 接进 CI 的第一次运行就把它照出来了

把 test813 接进 CI(本 PR 上一个提交)之后,它在 GitHub runner 上第一次运行就红:

    MCP_READINESS_PASS tools=commhub_get_all_status,commhub_send_message,commhub_send_task,commhub_upload_file
    FAIL: mutation survived: upload-tool-removed
    MCP_READINESS_PASS tools=…(同一份列表,commhub_upload_file 仍在)

不是产品没拦住,是**变异根本没发生**:

    sed -i '/^[[:space:]]*"commhub_upload_file",[[:space:]]*$/d' agent-network/src/node-server.ts

那个模式要求整行只有 `"commhub_upload_file",`,而真实那行是
`      name: "commhub_upload_file",`(对象字面量的字段)。实测命中 **0** ——
在 origin/main 上也是 0,**它从写下那天起就没匹配过任何一行**。
套件此前不在任何 CI 里(#861 说的 164 个孤儿之一),所以没人见过它红。

删整行会破坏对象字面量语法,改成改名:

    sed -i 's/name: "commhub_upload_file"/name: "commhub_upload_file_MUT"/' …

干跑验证:文件确实变了(`243:      name: "commhub_upload_file_MUT",`),已还原。

## 顺带堵住这一类,不只这一条

给 `expect_red` 加空变异防护:跑完变异命令后,若两个源文件**都**没被改动就直接判红,
并说清楚是「sed 模式和源码对不上」而不是「产品没拦住」。

这两种结论指向完全不同的下一步 —— **去改产品 vs 去改测试** —— 而它们在没有这道防护
时打印出来是同一句 `mutation survived`。

同一个套件里另外三条 sed 都逐条查过,各自命中 1(其中打 fake-grok.mjs 那条还自带
`grep -Fxc … -eq 1` 基数守卫),只有这一条是空的。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: t <internlmorg@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant