test(ci): 让 test725/test745 覆盖 tests/ 目录(两个门自称 complete 却漏了 25 个文件) - #800
test(ci): 让 test725/test745 覆盖 tests/ 目录(两个门自称 complete 却漏了 25 个文件)#800vansin wants to merge 4 commits into
Conversation
7ee79b0 to
2b2a7c2
Compare
独立对抗窄审 · PR #800 (Draft)Verdict: CLEAN — no BLOCKER, no MAJOR. One MINOR observation (structural gap, does not fire on this PR) documented at ⑦. Not a merge blocker. Reviewer: 通信IM马 (independent, read-only). First reviewer's vendor 300s timeout not consulted. Extracted PR tree via Scope framing: this PR extends the two "complete unit domain" gates (test725/test745) to actually cover the previously-excluded 25 files under Provenance
Item-by-item① base→HEAD 4 files / product 0 changed / source-report topology honest — CONFIRMED
② agent-node/tests 6 + agent-network/tests 19 denominator — CONFIRMED (independently enumerated)Independent agent-node/tests/*.test.ts (maxdepth 1) — 6 files: agent-network/tests/*.test.ts (maxdepth 1) — 19 files: Brief's 6 + 19 = 25 denominator matches ✓ Denominator load-bearing: Kind discrimination (grep 'bun:test' heuristic) verified per-file on all 25 files:
On the CURRENT 25 files, the heuristic dispatches correctly — I verified each file's ③ Dockerfile 跨包源码 + /work/feishu-attachments 权限最小且不掩盖测试 — CONFIRMEDCross-package COPY (Dockerfile L26): COPY agent-node/src ./agent-node/src
RUN install -d -o node -g node -m 0755 /work \
&& chmod 0755 ./tests/...
④ Two mutations — baseline first / target unique / byte-change / named-red — CONFIRMEDtest725 mutation (readable-attachment runtime wiring):
test745 mutation (top-level config help contract):
Not obscured by pre-front self-red or environment failure:
Report evidence (report lines 1535, 1537-1538 for test725; 2084, 2086, 2089-2090 for test745): ⑤ Secret / CI budget / current-main compat — CONFIRMED clean
⑥ "Complete unit domain" claim + implicit NOT COVERED honesty — CONFIRMED (with informational note at ⑧)The report's title and motivation explicitly acknowledge the gap the PR fixes:
After this PR, the
Implicit NOT COVERED (structurally excluded by
These exclusions are appropriate for "unit domain" (E2E and integration are separate concerns). The report describes the scope but does NOT enumerate the exclusions as explicit "NOT COVERED" items — see ⑧ for informational note. ⑦ MINOR: per-file "at least N tests ran" assertion missing — not fired on this PR, but structural gapThe finding: the tests/ dispatch loop asserts only exit code: if runuser -u node -- ... $cmd" >"/tmp/...log" 2>&1; then
tdir_ran=$((tdir_ran+1))
else
tdir_ran=$((tdir_ran+1)); tdir_failed=$((tdir_failed+1))
...
fiThere is no per-file assertion of the form
On the CURRENT 25 files, this never fires — I verified each file has real work:
Therefore the CURRENT PR's success does not rely on silent exit. But the gate would not catch the drift class if a future contributor introduces one of the three patterns above. Why MINOR (not MAJOR):
Recommend as follow-up hardening PR, not a merge blocker for this one. Additional observations (informational, not blocking)⑧ Report could enumerate NOT COVERED explicitlyThe report's motivation section ( ⑨
|
|
Gate correction — DO-NOT-MERGE current HEAD pending provenance repair, despite the otherwise positive independent review. The committed report is not anchored to this PR source. It states Positive counter-evidence, carefully scoped: GitHub Actions did execute the two changed gates on PR virtual-merge commit
Required closeout: freeze No product defect claimed, no code or production change made by reviewer. |
SUPERSEDE · PR #800 — provenance gap 更正Reviewer: 通信IM马 (independent, read-only). This comment supersedes the earlier CLEAN verdict at #issuecomment-5274674239. The prior comment is preserved unchanged for traceability. The CLEAN verdict is hereby withdrawn. Revised Verdict: DO-NOT-MERGE — pending exact HEAD Category: MAJOR — evidence provenance gap (Git-internal false anchor). Not a code correctness finding; a provenance-of-evidence finding. The prior audit correctly identified 4 files and correctly enumerated the 25 denominator, but did NOT interrogate the report's declared The provenance contradiction (independently verified)The 2091-line report But the PR's freeze coordinates are:
Since the tests/ dispatch code that emits the ...the report's contents (which include What the audit needed and what CANNOT bridge the gapPer brief: "GitHub Actions 虚拟 merge f0dd 的 6/6、19/19、双 mutation red 可作为代码行为正证,但不能修复 Git 内报告假锚" GitHub Actions runs on
These prove the CODE BEHAVIOR on HEAD 2b2a (the runners actually work, the mutations actually red, the denominators actually match) — but they do not repair the Git-internal false anchor in the committed report. A future reader picking up this report will read The bridging evidence that would repair this (and is NOT present):
Neither is present. Without one, the committed evidence claims to describe 92d while the surrounding PR files change 2b2a — this is the exact class described by What I got wrong in the earlier commentThe prior comment stated:
This was incorrect. Single-commit topology does not by itself guarantee the report was generated FROM the code IN the same commit. In this PR, the 2091-line report contains a The Focus ① check should have grepped the report body for The FOCUS 4 mutation evidence (target counts on HEAD, named-red strings existing) still stands as CODE behavior evidence. But that stands independently of the report anchor; it does not repair the anchor. What's required to move this back to CLEANAny one of:
Absent any of the above, the report's Discipline citations
Original CLEAN verdict retracted. Revised Verdict: DO-NOT-MERGE pending exact 2b2a7c2 rerun + report-only child commit. Not editing / not deleting the prior comment — supersede by append only, per audit protocol. |
同 #800 被独审抓到的那条:上一份报告声称的 source commit 是 92d9612,而那不是本 PR 的 head。 根因是我跑门时 --build-arg SOURCE_COMMIT 传的是当时的 origin/main, 不是分支自己的 head。这次是主动自查修复,不等独审再点一次。 本提交 report-only,不动被测代码。重跑结果(锚点 = 源码提交 ecf4679): test_files=69 executed_files=69 discovered_files=69 failed_files=0 MUTATION_RED registration-password-floor-weakened rc=1 RESULT: PASS 正文提到旧锚点时刻意不写成 key=value,避免本文件出现第二个可被 grep 误认的锚点。
两个门的抬头都写着 "complete agent-node/agent-network unit domain",
但只跑 src/,把 tests/ 下 25 个文件排除在外 —— 其中不乏安全相关的:
feishu-markdown-image-ssrf、secret-mask ×3、vendor-error-sanitize、feishu-tool-deny。
这些正是静默失效代价最高的那类。
这个目录里混着两种测试,任何单一命令都跑不全:
- 脚本式(16+6 个):自己打 "N/N passed",失败 process.exit(1),必须 bun <file>;
用 bun test 跑会因为 top-level 的 process.exit 把整个 run 打断在第一个文件
(实测:bun test tests/ 只跑完第一个就结束)。
- bun:test 式(3 个):describe/it,必须 bun test <file>;用 bun <file> 跑会报
"Cannot use describe outside of the test runner"。
所以按文件内容分派,并把两条判据都写进注释。
退出码可用已先验:这些脚本失败时确实 process.exit(1),不是 fail-open。
落地前实测:
agent-node/tests 6/6 直接过
agent-network/tests 单命令 14/19 → 按内容分派 17/19 → 补两处环境契约 19/19
两处契约都在 Dockerfile 内解决,并写明原因:
- feishu-envelope-compat 跨包 import agent-node/src/runtime/feishu-envelope
- feishu-bridge-ipc 硬编码绝对路径 /work/feishu-attachments,容器里 node 建不了
分母承重:tests_dir_executed 必须等于 find 出来的数,且 >0。
实测:test725 tests_dir 6/6/0 + MUTATION_RED + PASS;
test745 tests_dir 19/19/0 + MUTATION_RED + PASS。
7a04706 to
bdfd432
Compare
自查清单(#815)第 ⑤ 条「断言要精确到不合规会被拒绝」在自己门上的应用。 原来写的是 `grep -Fq 'rejects 7-char password'`。bun test 对每个用例都打 `(pass) <名字>` 或 `(fail) <名字>` —— 只 grep 名字的话,那条用例**通过**时 也会命中。于是这条断言只证明了「这条用例存在」,而不是「红落在它身上」。 A/B(把断言指向一条在该 mutation 下**不会红**的用例 `accepts 8-char strong password`,其余完全不动): 松版 grep -Fq '<名字>' → rc=0 RESULT: PASS ← 收下了不合规 严版 grep -Eq '^\(fail\).*<名字>' → rc=1 FAIL: mutation red did not reach the named… 改成锚定形式后正常绿:MUTATION_RED registration-password-floor-weakened rc=1,RESULT: PASS。 同类问题在 tests/test725-agent-node-unit-ci/run.sh 也有(它 grep 的 'the inbox choke point feeds the augmented text into processTask' 同样是测试名); 在 #800 里一并收紧,那边有单独说明。 tests/test745 那条不受影响 —— 它 grep 的是断言失败信息 `Expected to contain: "anet config [path|json]"`,只在失败时出现。
与 #798 同一类:原来 grep 的 'the inbox choke point feeds the augmented text into processTask' 是**测试名**,而 bun test 对每个用例都打 `(pass) <名字>` / `(fail) <名字>` —— 那条用例通过时也会命中,断言只证明了「它存在」,不证明「红落在它身上」。 A/B 在 #798 上做过(把断言指向一条该 mutation 下不会红的用例): 松版 → rc=0 RESULT: PASS(收下了不合规);严版 → rc=1 点名失败。 这道门不是我写的,我在本 PR 里本来就在改它的 run.sh(加 tests/ 分派), 所以顺手收紧;改动只让门更严,并在下面重跑验证仍绿。 若 owner 认为不该由本 PR 动它,我可以拆出去。
bdfd432 to
4d56276
Compare
#798 实测:只比「executed == discovered」的门,在删掉 85% 测试文件后 照样 RESULT: PASS —— 分母跟着现实自动缩水。 我在本 PR 里加的 tests/ 分派用的是同一形状,所以有同一个洞。 补 AGENT_NETWORK_TESTS_FLOOR=15(现 19 个)、AGENT_NODE_TESTS_FLOOR=5(现 6 个), 并写明「真删了测试就故意改这个数」。 范围说明:只给**我在本 PR 新加的 tests/ 分派**加下限,没有动这两个门原有的 src/ 分母判定(那是 #791/#725 的既有代码,同类下限缺失我另报,不夹进本 PR)。
4d56276 to
539a7e7
Compare
自查发现本报告里有两个不同的 source_commit:抬头是 2617987(正确,==源码提交), 但嵌入的运行输出里是 187a6ff。 根因是我上一轮的操作顺序错了:**先 `git rev-parse HEAD` 打戳、后提交下限改动**。 于是镜像里跑的是含下限的代码,戳进日志的却是提交前的 SHA —— 证据本身有效,但它自称的锚点指向一个不含该改动的提交。 这与 #798/#800/#803 早先被独审抓到的假锚点是**同一个根因的第二次发作** (那次是把 --build-arg 传成了 origin/main,这次是传成了未提交前的 HEAD)。 已在真源码提交 2617987 上重跑并重出报告,全文 source_commit 只指向一个值: test_files=69 executed_files=69 failed_files=0 MUTATION_RED registration-password-floor-weakened rc=1 RESULT: PASS
状态更新:上面那条 SUPERSEDE 提出的要求已经照做上一条评论( 那个指控是对的,根因也是我的:跑门时把 已按要求完成,且没有改字符串冒充:重跑是在真提交上做的,报告整份重出。 当前坐标(冻结中,我不再改动) 自检: 实测: 近期审查发现(经 commhub 收到;我的转录,非终审)
第一条正是 所以合并顺序是硬要求: 待决清单本 PR 目前零待改点。若你们认为正文该补一句「完整闭环依赖 #801」的交叉引用,我可以加 —— 但我在冻结中,等点头。 |
自查结论:新增块没有让既有断言变假;但
|
| 目录 | 深度1 | 递归 | 漏 |
|---|---|---|---|
agent-network/tests |
19 | 19 | 0 |
agent-node/tests |
6 | 6 | 0 |
下限也都成立:AGENT_NETWORK_TESTS_FLOOR=15 vs 实际 19;AGENT_NODE_TESTS_FLOOR=5 vs 实际 6。
所以这不是当前缺陷,不需要在本 PR 改。
但它失效的方式值得记:分母和判据用了同一个受限的发现
如果将来有人加了 agent-network/tests/foo/bar.test.ts:
tdir_total(分母)用-maxdepth 1数 → 看不见它;- 执行循环用同一个
find→ 也不跑它; - 于是
tdir_ran == tdir_total仍然成立 → 门照常绿。
没有任何东西会变红。 这道门对"新增了嵌套测试文件"这件事是完全瞎的,而且瞎得不留痕迹 —— 因为发现范围和验证范围是同一个,两者的不一致永远暴露不出来。
同族于本仓已记过的那类:一道门只要把"该做什么"和"做了什么"用同一个来源算,它就只能证明自洽,不能证明完整。
若要消除(不建议在本 PR 做,会扩大范围):分母用递归 find、执行仍可限深,让两者故意不同源,这样一旦出现嵌套文件,tdir_ran == tdir_total 立刻红。
附:我这次的扫描先是空的
第一次我在当前工作树上跑 find agent-network/tests -name '*.test.ts',得到 0,差点报出"这两个目录根本没有测试文件"。实际是这个 checkout 在别的分支、目录没铺开,而我还把 stderr 吞了(2>/dev/null)。
按 origin/main 的 tree 重查才拿到真实的 19 / 6。记一笔:枚举要打 origin/main,不要打当前 checkout;以及吞掉 stderr 的 find 返回 0 时,0 可能是"没找到",也可能是"根本没跑成"。
自审(本 PR 至今零审查):查了派发逻辑里最可疑的一处,结论是没问题 —— 但这个"没问题"是验出来的本 PR 是三条从没被任何审查器碰过的之一(另两条 #810 / #823,#823 已自审出一条 fail-open 并修)。 被查的形态:66 if grep -q 'bun:test' "$f"; then cmd="bun test $rel"; else cmd="bun $rel"; fi19 个被发现的文件里,16 个不含 这个形状有两个真实风险:
逐条核完:两个风险都不成立风险 1 —— 16 个文件全部能把失败传出去。
风险 2 —— 没有真实出口。 扫出两个「非占位 URL」命中,逐个看完都是误报:
其余全部是 结论派发逻辑是健全的:走裸 记两条判据(两次都是我的扫描器太窄)
这与我在 #815 补的那条同源:任何以「找到 N 个可疑项」为结论的扫描,报出去之前要先确认这 N 个里有没有一整类是按设计就该长这样的。 |
|
@codex review 本 PR 至今零审查记录(自动审查器只在开 PR / 草稿转就绪 / 显式 @ 时触发,push 不触发)。这是第二次请求。 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 539a7e7251
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -0,0 +1,2080 @@ | |||
| # test725/test745 扩到 tests/ 目录 | |||
There was a problem hiding this comment.
Store the evidence under the report-testN naming scheme
The new test evidence is saved as report-pkg-tests-dir-gate.txt, while the repository requires test results under docs/tests/report-testN.txt. Rename or split this combined artifact into test-numbered reports (for example, test725 and test745) so the evidence remains discoverable through the mandated convention.
AGENTS.md reference: AGENTS.md:L8-L8
Useful? React with 👍 / 👎.
| # 🔴 绝对下限:`executed == discovered` 只能抓「runner 跳过了文件」, | ||
| # 抓不到「文件消失了」—— 分母会跟着现实自动缩水。见 #798 的实测: | ||
| # 删掉 85% 的测试后,只比数量的门照样 PASS。真删了测试就故意改这个数。 | ||
| AGENT_NETWORK_TESTS_FLOOR=15 |
There was a problem hiding this comment.
Raise the floors to match the current test inventories
When up to four agent-network/tests files are deleted or renamed away from *.test.ts, discovery and execution shrink together and this 15-file floor still passes even though the current inventory is 19; the analogous 5 floor in test725 also permits one of its six tests to disappear. This preserves exactly the silent-loss gap these checks claim to close, including the possibility of dropping security tests while CI stays green, so initialize the floors to 19 and 6 and require an intentional update whenever a test is actually removed.
Useful? React with 👍 / 👎.
vansin
left a comment
There was a problem hiding this comment.
结论:前提我独立核过,属实;修法扎实,建议合并。一条 MINOR(不挡合并)
前提:我没看 PR 自述,自己对 origin/main 数了一遍
「两个门自称 complete」 —— 属实:
tests/test725-agent-node-unit-ci/run.sh:11 echo "# test725 — complete agent-node unit domain"
tests/test745-agent-network-unit-ci/run.sh:11 echo "# test745 — complete agent-network unit domain"
「只跑 src/」 —— 属实:两个门实际执行的都是 bun test src/
(test725:18、test745:24)。
「漏了 25 个文件」 —— 属实,而且数字精确。按 *.test.ts 数:
agent-node/tests/ 6 (feishu-tool-deny / outbound-secret-mask / quota-error-passthrough
/ secret-mask-spawn / secret-mask / vendor-error-sanitize)
agent-network/tests/ 19 (environ-alias / feishu-* ×16 / goal-wake-log-render / project-key)
──
25
点名的那几个安全相关文件确实都在里面:feishu-markdown-image-ssrf、
secret-mask 三件(secret-mask / secret-mask-spawn / outbound-secret-mask)、
vendor-error-sanitize、feishu-tool-deny。
顺带一个更难看见的点:test745 原本在 :47 有一道分母检查
(bun executed N file(s) but $test_files exist under src/),但它的范围本身就限定在 src/ 内。
所以「漏掉整个 tests/ 目录」这件事,连既有的那道分母门都照不到 —— 门是绿的,因为它按自己划的范围数,数对了。
修法
按文件内容分派(bun:test → bun test <f>,否则 bun <f>)、逐个跑、失败打名字和尾部日志,
再加一条绝对下限 AGENT_NETWORK_TESTS_FLOOR=15,注释里引了 #798 的实测
(删掉 85% 测试后,只比数量的门照样 PASS)。这条下限是对的,而且是这份改动里最值钱的一行。
两处环境契约在 Dockerfile 里解决、并写明了原因(feishu-bridge-ipc 硬编码 /work/...;
feishu-envelope-compat 跨包 import),没有去改产品代码迁就测试 —— 方向对。
我另外核了两个边界,当下都干净:
-maxdepth 1之下目前没有更深层的.test.ts,所以没有漏网;- 分派判据
grep -q 'bun:test':25 个文件里凡提到bun:test的都确实import ... from "bun:test",
不存在「注释里提了一嘴就被误分派」的情况。
🔴 MINOR:executed == discovered 这条断言是恒真的,和它注释说的不是一回事
test745:87 和 test725:66 都有:
[[ "$tdir_ran" -eq "$tdir_total" && "$tdir_total" -gt 0 ]] || { echo "FAIL: ran ... of ..."; exit 1; }但循环里两个分支都在给同一个计数器加一(test745:69 / :71,test725:48 / :50):
if runuser ... ; then
tdir_ran=$((tdir_ran+1))
else
tdir_ran=$((tdir_ran+1)); tdir_failed=$((tdir_failed+1))
fi所以 tdir_ran 数的是循环跑了几圈,不是执行成功了几个。我按同样结构做了最小复现,
把命令换成必然失败:
模拟「每个文件都执行失败」:executed=3 discovered=3 failed=3
→ executed == discovered 仍然成立(该断言不会 fire)
也就是说,它唯一可能 fire 的情形,是 :62 和 :77 那两次 find 之间文件被增删的竞态。
而注释写的是「只能抓『runner 跳过了文件』」—— 在这个循环结构里,没有任何东西能「跳过」。
这不是覆盖漏洞:真正兜底的是 tdir_failed -eq 0 和那条 floor,这两条都工作正常,
所以不挡合并。要改的是别让注释承诺超过它实际执行的范围 —— 要么把注释收窄成
「防两次 find 之间的竞态」,要么让计数器真的只在成功分支加(那样它就和 failed 冗余了,
删掉反而更诚实)。
对照一下就更清楚:被替换掉的 src/ 那道检查是去解析 bun 自己输出的执行数,
那个数和枚举数是两个独立来源,所以它真能抓到 runner 跳文件。新加的这条没有第二个来源。
|
补一条:这个 PR 不会关掉 #817,合并时别顺手关。 #817 复现的洞在
所以合并之后:
补法和这个 PR 里已有的一样,两行的事: (核的是本 PR head |
|
独立深审结论:CLEAN(exact head 我从 source archive 独立重建并真跑两个 Docker 门:
因此 #800 门本体可独立放行。顺序边界:#854 会与 test725 同一插入区发生 content conflict;必须先落 #800,再把 #854 rebase/人工 union,不能顺手选任一侧。未 approve、未 merge、未 deploy。 |
test(ci): 让 test725/test745 覆盖 tests/ 目录,兑现"complete unit domain"
两个门的抬头都写着 "complete agent-node/agent-network unit domain",
但只跑 src/,把 tests/ 下 25 个文件排除在外 —— 其中不乏安全相关的:
feishu-markdown-image-ssrf、secret-mask ×3、vendor-error-sanitize、feishu-tool-deny。
这些正是静默失效代价最高的那类。
这个目录里混着两种测试,任何单一命令都跑不全:
用 bun test 跑会因为 top-level 的 process.exit 把整个 run 打断在第一个文件
(实测:bun test tests/ 只跑完第一个就结束)。
"Cannot use describe outside of the test runner"。
所以按文件内容分派,并把两条判据都写进注释。
退出码可用已先验:这些脚本失败时确实 process.exit(1),不是 fail-open。
落地前实测:
agent-node/tests 6/6 直接过
agent-network/tests 单命令 14/19 → 按内容分派 17/19 → 补两处环境契约 19/19
两处契约都在 Dockerfile 内解决,并写明原因:
分母承重:tests_dir_executed 必须等于 find 出来的数,且 >0。
实测:test725 tests_dir 6/6/0 + MUTATION_RED + PASS;
test745 tests_dir 19/19/0 + MUTATION_RED + PASS。
正文最初没写、后来才加的两处(补记)
test725的 mutation 命名断言锚到(fail)行(与#798同类)。原来 grep 的
the inbox choke point feeds the augmented text into processTask是测试名,该用例通过时也会命中。收紧后重跑仍绿。
这道门不是我写的;我在本 PR 里本就要改它的
run.sh(加 tests/ 分派),所以顺手收紧,改动只让门更严。若 owner 认为不该由本 PR 动它,可以拆出去。
tests/分派的绝对下限(AGENT_NETWORK_TESTS_FLOOR=15/AGENT_NODE_TESTS_FLOOR=5)。同
#798那个洞:executed == discovered抓不到「文件消失」。双向验过:19 个 → PASS;删到 4 个 →
rc=1 FAIL: only 4 file(s) under agent-network/tests, floor is 15。范围:只给本 PR 新加的
tests/分派加下限,没动这两个门原有的src/分母判定 ——那属既有代码,同类缺失另报(见
#817)。合并顺序:本 PR 单独合入不兑现「整棵
tests/永久 complete」——find … -maxdepth 1只覆盖顶层,嵌套目录要靠#801的深度感知才闭。顺序:#798/#800→#801。