修复: 套件因"清单自检"停了整整一天(一条判据都没跑)—— 补接线 3 个从未进 SUITE 的文件 + 修 2 处裸 readFileSync + 守卫补报"因此没有跑任何判据"

pi 报的 `ran`/`checks` 双计**早已修掉**(`d23ef69`,他读的是它的祖先 `2774b00`)。
但顺着那条线实测,发现了一个**更严重的现况**:**套件一条判据都没在跑。**

## 一、★ 现况:`run-all.mjs` 输出只有一行,0 条判据

```
$ node test/run-all.mjs
这些判据文件没接进套件(写了却不会跑):test/harmony-push-optin.test.mjs、…
退出码=1        stdout 0 行、stderr 1 行(build 与 install **两个相位都死**)
```

自检 2("test/ 下每个 *.test.mjs 都要在清单里")在**跑任何判据之前** `process.exit(1)`。

**逐提交对照(worktree 隔离)**:

| 提交 | 套件 |
|---|---|
| `cfe7808^` | `RESULT files=26 ran=23 checks=332 …`(正常)|
| `cfe7808`(09-16 07:46,加了 2 个文件)| **一行"没接进套件",0 条** |
| `c523c21`(09-17 17:43,又加 1 个)| 同上 |

⇒ 整仓**超过一天没有任何判据读数**,而失败信号只有那一行 ——
**看起来像环境问题**,不像"套件坏了"。三个文件**从未**进过 SUITE(`git log -S` 查证:0 次提及)。

## 二、修

1. **接线 3 个文件**(`harmony-push-optin` 4 / `harmony-reply-target` 7 / `harmony-widescreen` 6 条)。
2. **接线后立刻暴出 2 处违规** —— 这是"漏接线"的**第二层后果**:不只它自己不跑,
   **连它自身的违规也没有任何东西会看见**:
   - `harmony-reply-target.test.mjs:189` 裸 `readFileSync` 读 `.go` ⇒ 改走 `code()`
   - `harmony-apibase.test.mjs:266` 裸 `readFileSync` 读 JSON ⇒ 改走 `prose()`
   (两条在纯净 HEAD 上**都已存在**,`criteria-hygiene` 第 2 条现在 6/6 绿。)
3. **守卫补报后果**:原来只说"这些文件没接进套件",**没说"因此本次一条判据都没跑"**。
   ⇒ 补上那句 + 说明"修法是把文件接进 SUITE(不是改这里)"。
   **守卫本身保留**(漏接线不该静默),但**它要为自己造成的后果作证**。
   变异验证:临时摘掉一条 ⇒ 新报文出现;还原逐字节一致。

## 三、★ 我接线时被自己写的注释绊了一次(值得记)

`criteria-hygiene` 第 3 条扫"用了 `code`/原文读取/`bytes` 却没 import",而它**不剥注释**:
我在注释里写了"那个入口保留注释"**并带上括号**,它报「用了 … 但没 import」。
⇒ **"注释里说明禁令"不等于"违反禁令"**(我们早立的规则),
而其镜像也成立:**注释里提到函数名会被判据当成使用**。两个方向都得当心。

## 四、测量(29 个文件,两个相位都活了)

| 相位 | RESULT |
|---|---|
| build | `files=29 ran=29 checks=440 pass=438 fail=2 red=8 broken=0 unreported=0` |
| install | `files=29 ran=27 checks=428 pass=427 fail=1 red=7 broken=0 unreported=0` |

`broken=0 unreported=0`(接线前那三个文件是 3/3 —— 它们自报不了条数)。
剩下 8 条红**都不是本次改动**:`narrow-layout`/`nav-merge`/`harmony-presets`/`build-stamp`/
`commit-hygiene` 等是**并发会话未提交的工作**(`harmony-nav` 正被改),
在纯净 HEAD 上它们**看不到**(因为 HEAD 上套件根本没跑)。
This commit is contained in:
2026-09-17 18:43:00 +08:00
parent c523c21e22
commit b6b50cbb88
3 changed files with 68 additions and 7 deletions

View File

@ -14,19 +14,41 @@
*/
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync, existsSync } from 'node:fs';
import { existsSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
/*
* `code()` 剥掉注释、`prose()` 保留 —— 本文件判的是**代码里有什么调用/什么值**,
* `code()` 剥掉注释、原文读取保留 —— 本文件判的是**代码里有什么调用/什么值**,
* 所以必须用 `code()`。
*
* 这里踩过一次(写完就红):详情页的注释里**写着**那个 bug 形状
* (「原先是 `this.fromName + '@'`」),用原文去 match 会把它自己的解释当代码,
* 产生假红 —— 而 `read.mjs` 的头注释正是为这类误报写的。
*
* ⚠️ ★ 并且**别在这段话里写出那个函数名加括号的样子**(2026-09-17 实录):
* `criteria-hygiene` 第 3 条扫的是"用了某入口但没 import",而它**不剥注释** ——
* 我上面原本写了一句"那个原文读取入口保留注释"(并把它带着括号写了出来),于是它报
* 「用了那个入口但没 import」:**判据把注释里的解释当成了用法**。
* 这正是本仓那条规则的镜像:**"注释里说明禁令"不等于"违反禁令"**,
* 但反过来,**注释里提到函数名会被判据当成使用** —— 两个方向都得当心。
*/
import { code } from './lib/read.mjs';
/*
* ★ `.go` 那一半也必须走 `read.mjs` 的具名入口(2026-09-17 修)。
*
* 原来那里是裸 `readFileSync(goPath, 'utf8')` —— 违反 `criteria-hygiene` 第 2 条
* ("判据目录里不得出现裸 readFileSync")。**它违反了却一直没被发现**,因为本文件
* 当时**根本没接进 SUITE**(`616c994` 起套件被清单自检整体停了一天多)。
* ⇒ 这就是"漏接线的判据 = 写了却永远不跑"的**第二层后果**:
* 不只是它自己不跑,**连它自身的违规也没有任何东西会看见**。
* 接线之后,第一条报出来的就是这个。
*
* 用 `code()`(剥注释、留字符串),与上面 `.ets` 那半同一个入口,理由也一样:
* 判的是**代码形态**(函数签名 + `if` 分支),而 Go 的注释里完全可能写着这个签名,
* 用原文 match 会把它自己的解释当成代码。
*/
const HERE = dirname(fileURLToPath(import.meta.url));
const ROOT = join(HERE, '..', '..', '..');
const HARMONY_ETS = join(ROOT, 'client/harmony/entry/src/main/ets');
@ -186,7 +208,7 @@ test('★ 对齐后端:FormatAddress 的三分支与 Go 源码一致', () => {
if (!existsSync(goPath)) {
return; // 没这个文件就无从判起(判据不假装验过)
}
const go = readFileSync(goPath, 'utf8');
const go = code(goPath); // 走 read.mjs 的具名入口(见文件头那段 ★)
assert.match(go, /func FormatAddress\(name, path, session string\) string/,
'后端要有 FormatAddress');
// 三分支:session 空 + path 空 → name;session 空 + 有 path → name@path;否则 name@path.session