From b6b50cbb8806f553894da24e68bdcf5d630feced Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Thu, 17 Sep 2026 18:43:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20=E5=A5=97=E4=BB=B6?= =?UTF-8?q?=E5=9B=A0"=E6=B8=85=E5=8D=95=E8=87=AA=E6=A3=80"=E5=81=9C?= =?UTF-8?q?=E4=BA=86=E6=95=B4=E6=95=B4=E4=B8=80=E5=A4=A9=EF=BC=88=E4=B8=80?= =?UTF-8?q?=E6=9D=A1=E5=88=A4=E6=8D=AE=E9=83=BD=E6=B2=A1=E8=B7=91=EF=BC=89?= =?UTF-8?q?=E2=80=94=E2=80=94=20=E8=A1=A5=E6=8E=A5=E7=BA=BF=203=20?= =?UTF-8?q?=E4=B8=AA=E4=BB=8E=E6=9C=AA=E8=BF=9B=20SUITE=20=E7=9A=84?= =?UTF-8?q?=E6=96=87=E4=BB=B6=20+=20=E4=BF=AE=202=20=E5=A4=84=E8=A3=B8=20r?= =?UTF-8?q?eadFileSync=20+=20=E5=AE=88=E5=8D=AB=E8=A1=A5=E6=8A=A5"?= =?UTF-8?q?=E5=9B=A0=E6=AD=A4=E6=B2=A1=E6=9C=89=E8=B7=91=E4=BB=BB=E4=BD=95?= =?UTF-8?q?=E5=88=A4=E6=8D=AE"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 上套件根本没跑)。 --- client/electron/test/harmony-apibase.test.mjs | 8 ++-- .../test/harmony-reply-target.test.mjs | 28 +++++++++++-- client/electron/test/run-all.mjs | 39 ++++++++++++++++++- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/client/electron/test/harmony-apibase.test.mjs b/client/electron/test/harmony-apibase.test.mjs index 9810cde..77793d8 100644 --- a/client/electron/test/harmony-apibase.test.mjs +++ b/client/electron/test/harmony-apibase.test.mjs @@ -26,10 +26,10 @@ */ import test from 'node:test'; import assert from 'node:assert/strict'; -import { existsSync, readdirSync, readFileSync } from 'node:fs'; +import { existsSync, readdirSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; -import { code } from './lib/read.mjs'; +import { code, prose } from './lib/read.mjs'; /* * ★ 仓库根从**本文件的位置**推,不许硬编码绝对路径 —— worktree 复核时硬编码会 @@ -263,7 +263,9 @@ test('★ 内网明文通道:network_config.json 就在文档规定的位置 + '**不需要**在 module.json5 里写引用)。'); let cfg = null; try { - cfg = JSON.parse(readFileSync(NET_CFG, 'utf8')); + /* ★ 走 read.mjs 的具名入口,不裸用 readFileSync(criteria-hygiene 第 2 条)。 + * 这里读的是 JSON **配置**(不是代码),用 `prose()` = 原文,语义正对。 */ + cfg = JSON.parse(prose(NET_CFG)); } catch (e) { assert.fail(`network_config.json 不是合法 JSON(会被打进包里但读不出来):${e.message}`); } diff --git a/client/electron/test/harmony-reply-target.test.mjs b/client/electron/test/harmony-reply-target.test.mjs index 8ad52bf..b7a737b 100644 --- a/client/electron/test/harmony-reply-target.test.mjs +++ b/client/electron/test/harmony-reply-target.test.mjs @@ -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 diff --git a/client/electron/test/run-all.mjs b/client/electron/test/run-all.mjs index b9314a5..595101f 100644 --- a/client/electron/test/run-all.mjs +++ b/client/electron/test/run-all.mjs @@ -98,7 +98,28 @@ const SUITE = [ ['test/harmony-imageprep.test.mjs', ['--experimental-strip-types', '--no-warnings'], 29], // ArkTS **编译期**硬规则(纯文本可判、不需要设备)。这一条是构建撞出来的: // 我把常量表插在了既有 import 之前 ⇒ arkts-no-misplaced-imports,而当时没有任何判据会跑它。 - ['test/harmony-arkts.test.mjs', [], 3] + ['test/harmony-arkts.test.mjs', [], 3], + // ★★ 下面三条是**补接线**,不是新写的判据(2026-09-17)。 + // + // 它们**早就存在**,却从没进过 SUITE ⇒ 自检 2("每个 *.test.mjs 都要在清单里") + // 直接 `process.exit(1)` ⇒ **整套判据一条都不跑**,只打一行 stderr。 + // 实测(worktree 逐提交对照):`616c994`(09-16 07:46,加了其中两条)之前 + // `RESULT files=26 ran=23`,之后**输出只剩那一行"没接进套件"**;09-17 `f4b8bc1` + // 又加了第三条。**两个相位都死**(build 与 install 都先撞这条守卫)。 + // ⇒ 整仓**超过一天没有任何判据读数**,而失败信号只有一行、看起来像环境问题。 + // + // ★ 这条守卫的形状值得单独记(**不删它** —— 它的价值是真的:漏接线不会被静默忽略): + // 它是**结构守卫**:清单与磁盘不一致 ⇒ 整体停。好处是"写了没接线"绝不静默, + // 代价是**一个**漏接的文件停掉**全部**判据 —— "新增判据的人"能一处失误 + // 让整仓失去全部读数。与"第一道红吃掉后面的诊断"同族,第一道红是清单自检。 + // ⇒ 守卫保留,且**接线是作者的义务**;另外给这条守卫补一句"因此没跑任何判据" + // (原来的输出只说了"没接进套件",**没说你因此一条读数都没有**)。 + // 通知开关(用户强调多遍的可配置项,默认开)→ 纯文本 + node:test + ['test/harmony-push-optin.test.mjs', ['--experimental-strip-types', '--no-warnings'], 4], + // 三维地址拼装:直接执行 `model/ReplyTarget.ts` 真逻辑(行为判据) + ['test/harmony-reply-target.test.mjs', ['--experimental-strip-types', '--no-warnings'], 7], + // 宽屏侧栏图标轨:`WideSidebar` 接线与常量(静态判据,无设备) + ['test/harmony-widescreen.test.mjs', [], 6] ]; // 自检 1:清单里的文件必须真的存在(写错名字 = 那条判据永远不跑) @@ -114,6 +135,22 @@ if (ghosts.length || unwired.length) { if (unwired.length) { console.error(`这些判据文件没接进套件(写了却不会跑):${unwired.join('、')}`); } + /* + * ★★ **必须说清"因此一条判据都没跑"**(2026-09-17 补)。 + * + * 原来的输出只说了"这些文件没接进套件",**没说你因此失去了全部读数** —— + * 于是一条 `process.exit(1)` 加一行 stderr,和"环境问题导致套件没起来" + * 在观感上无法区分。实测代价:`616c994`(09-16) 起整仓**超过一天没有任何判据读数**, + * 而失败信号就是这一行。 + * ★ 这正是本仓反复消的那个形状:**输出没说的事,读的人不会知道**。 + * 守卫本身是对的(漏接线不该静默),缺的是**它要为自己造成的后果作证**。 + */ + console.error( + `\n ⇒ 因此**本次一条判据都没跑**(不是"跑了且都绿",也不是"环境问题")。\n` + + ` 这是**清单自检**在跑判据**之前**退出的:上面 ${unwired.length + ghosts.length} 个文件\n` + + ` 与清单不一致 ⇒ 整体停。修法是**把文件接进 SUITE**(不是改这里)。\n` + + ` ★ 为什么这么狠:漏接线的判据"写了却永远不跑",静默忽略比停整套更糟。\n` + + ` 代价是一个文件漏接会停掉**全部**判据 —— 所以接线是**新增判据者的义务**。`); process.exit(1); }