AT-E007 / WX-E007 FAIL:证据记录器把「零收集」记成 exit_code:0 的通过 manifest——§11 那条「collected 为零必须失败」在证据链上没有任何实现
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 7m
- Merged PRs (30d)
- 969
Description
> 来自 #3004(AT 验收 B3 + 平台前置)的 **AT-E007 元验收**。定级:**FAIL**(已执行且行为不符合契约,不是 BLOCKED——记录器存在、能跑、只是判据缺失)。
> exact SHA:`938d16bf3a49c4047f42bbc697833cd921d1053e`(= #2996 基线,工作树 clean)。
## 契约
`acceptance-test-plan.md` §5 AT-E007 的必测反证逐字是:
> 空测试集合、静态文件或 skipped lane 不能报告通过
§11 再钉一次:
> 把全套测试过滤成零条,runner 必须因 collected/executed 数量为零而失败。
## 反证实测:把「零条」喂进证据链,它给出一份通过 manifest
`.harness/scripts/record-readiness-evidence.ts` 是 CI 里唯一生成 readiness 证据 manifest 的脚本
(`.github/workflows/harness-verify.yml:411` 的 `fullstack-smoke` 调它)。它对日志的唯一要求是
**存在且非空**(`record-readiness-evidence.ts:23`),`exit_code` 是**字面量硬编码 0**
(`record-readiness-evidence.ts:30`),全程不读日志内容。
实测(本机,baseline SHA):
```console
$ printf 'RUN v2.1.9\n\n Test Files no tests\n Tests no tests\n Duration 164ms\n' > zero-collection.log
$ pnpm exec tsx .harness/scripts/record-readiness-evidence.ts \
--phase 01 --kind runtime --commit 938d16bf3a49c4047f42bbc697833cd921d1053e \
--command "pnpm --filter api exec vitest run tests/kernel tests/mcp tests/skill" \
--log zero-collection.log --output zero-collection-manifest.json
[readiness-evidence] kind=runtime commit=938d16bf3a49c4047f42bbc697833cd921d1053e manifest=...
$ echo $?
0
```
产出的 manifest:
```json
{
"schema_version": 1,
"phase": "01",
"kind": "runtime",
"command": "pnpm --filter api exec vitest run tests/kernel tests/mcp tests/skill",
"exit_code": 0,
"commit": "938d16bf3a49c4047f42bbc697833cd921d1053e",
"recorded_at": "2026-09-08T02:04:11.863Z",
"artifacts": ["zero-collection.log"]
}
```
**日志正文逐字是 `Test Files no tests` / `Tests no tests`,manifest 报 `exit_code: 0` 并绑定了真实 SHA。**
## 为什么校验器拦不住
`.harness/scripts/lib/phase-readiness.ts` 的 `parseEvidenceManifest` 确实有反假绿判据,但都不指向用例数:
| 行 | 判据 | 拦得住零收集吗 |
| --- | --- | --- |
| `:100` | `command` 不得是 `echo` / `printf` / `\|\| true` 占位符 | ✗ 上面那条是真命令 |
| `:102` | `exit_code` 必须为 0 | ✗ 恰恰是它让零收集合法 |
| `:107` | `artifacts` 至少一条非空路径 | ✗ 日志非空即可 |
**没有任何一处读 artifact 的内容,也没有任何 collected/executed 字段。** §11 那条反证在证据链上是零实现。
## 影响不止于「一份纸面 manifest」
该 manifest 是 `pnpm harness phase-readiness --phase NN --to ready --runtime-evidence ` 的输入
(`.harness/scripts/cli.ts:143`),也由 `doctor.ts:17` 的 `auditPhaseReadiness` 审计。
也就是说:**一次零收集的运行足以把一个 phase 推到 `ready`,且 doctor 复查时同样看不出来**——
它看到的是一份命令真实、SHA 真实、退出码 0 的合规 manifest。
## 建议修法(不自行动手,本 issue 只定级并上报)
在 `record-readiness-evidence.ts` 落一条 collected/executed 判据,而不是在调用方各写一遍:
1. manifest 增加 `executed: number` 字段,由记录器**从日志解析**(vitest 的 `Tests N passed`、
playwright 的 `N passed`、pytest 的 `N passed`);解析不到 ⇒ 抛错,不是记 0 放行。
2. `parseEvidenceManifest` 增加 `executed >= 1` 校验,与既有三条并列。
3. 反证测试:喂一份 `Tests no tests` 的日志,记录器必须非零退出——**拆掉该判据这条测试要变红**
(对齐本仓其余门控「每道门都实测过拆掉它会红」的做法)。
## 与已有 issue 的边界(不重复立案)
- #2991:方案 §10 写下的**命令**本身零收集。本 issue 是**证据链**不识别零收集,两者互不覆盖——
就算 §10 的命令全部改对,记录器照样接受任何零收集日志。
- #2084:`e2e-full` 门控空转、main 仍报 success。那是 **lane 没跑**;本 issue 是 **跑了但等于没跑**。
## 同轮实测的另两条假绿向量(登记备查,不在本 issue 修法范围)
1. `pnpm --filter run <不存在的脚本>` → 打印 `None of the selected packages has a "..." script`,**退出 0**。
`pnpm --filter <不存在的包> run test` → `No projects matched the filters`,**退出 0**。
任何写成这种形态的验收命令,脚本改名/包改名后会静默变成「通过」。
2. `.github/workflows/harness-verify.yml:394` 的 `fullstack-smoke` 是 job 级 `continue-on-error: true`
且**没有**复判步骤,check run 结论恒为 success(#633 人类裁决,对合并门是有意为之)。
对比之下 `real-model-chat-evidence.yml:120`、`s013`、`s016`、`office-editing` 四条真实模型 lane
都带「spec 红 ⇒ job 红」的复判步骤,是正确形态。
⇒ **引用一次绿的 `harness-verify` 不能证明 fullstack-smoke 跑过或跑绿。**
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with .harness/scripts/record-readiness-evidence.ts and .harness/scripts/lib/phase-readiness.ts, then inspect .github/workflows/harness-verify.yml:411 and the phase-readiness input at .harness/scripts/cli.ts:143. Reproduce the supplied `Test Files no tests` log and add or run the regression test. Done means zero-collection evidence is rejected while a nonempty run remains accepted.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, typescript
- Domain
- ci-cd, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100