修复: 判据注释说"这个值来自 Go 源",实际**一个字节没读** —— 服务端上限真漂移 29 pass/0 fail 一个字不变

pi 报的那格(4b 的 if(false))已由并发会话的自检 4c 补上,我变异验证通过(三种恒假写法都红)。
这轮顺着"第 2 列现在每次运行都可见"去读那 6 条理由,挖出**同族的另一条缝**:

`harmony-imageprep` 的
  /** 服务端壁纸上限(appearance.go 的 appearanceMaxBytes() 默认值) */
  const SERVER_LIMIT = 4 << 20;
注释说它来自 Go 源,而它一个字节的 Go 源都没读。实测(同刻 A/B):
把 Go 里那个默认值改成 8<<20(真漂移)⇒ 本文件 **29 pass / 0 fail 一个字都没变**
⇒ 这条判据存在的全部理由(客户端上限要留在服务端那道门之内,否则必然 413 /
白扔分辨率)在服务端那道门真动了时**不会红**。危险处在于注释让读者以为已对齐。

修法(三件):
① 从**真源头**解析,且**两处都读、要求相等** ——
   ⚠️ 我第一版只读了 appearance.go 的 `return 4<<20`,那是**兜底分支**;
   生产里 config.C 非 nil ⇒ 生效值来自 config.go 的
   `MaxAppearanceBytes: getEnvInt64("AGENTMAIL_MAX_APPEARANCE_BYTES", 4<<20)`。
   "读了源"还不够,还得问"读的是不是生效的那一处"(同族缝的下一层)。
② 解析失败必须红,**不许静默回退到硬编码**(回退 = 把"我读不到"变成"值是对的")。
③ 新增一条判据钉住"真的读出来了":两处都无 err、生效值等于 config 那处、等于兜底那处、且 >0。
   并**如实标出标签范围**:这证明"与默认值对齐",**不证明**"与运行值对齐" ——
   AGENTMAIL_MAX_APPEARANCE_BYTES 可覆盖;别把本条读成"413 已不可能发生"。

变异验证(每个只动一处):config.go 默认值→8MB ⇒ fail=2;
appearance.go 兜底→8MB(两处不一致)⇒ fail=1(恰为"两处相等"那条,
余量那条**故意不红**,因为生效值没变 ⇒ 所以"两处相等"必须单独存在);
config.go 那行删掉 ⇒ fail=2(不许静默)。基线 30 pass / 0 fail。

另:`STATIC_ONLY` 第 2 列里那句「+ 服务端,三样本机都没有」是**假话** ——
`server/internal/handler/attachments.go` 在本机、其 Go 测试 `-run Attach` 跑得通、
且本判据根本没连服务端。已改成"欠的只有设备侧那一半"(列每次运行都播报,假话会被读出来)。
注册条数 29→30 已同步。全套:files=31 checks=396 pass=384 fail=12 red=9 broken=3(跑在隔离 worktree)。

`CRITERIA.md §16.4`:通用规则 —— **注释里写"这个值来自 X"不构成读 X**;
凡"必须与别处一致"的判据先问:它真读了别处,还是抄了一份?
This commit is contained in:
2026-09-19 12:42:32 +08:00
parent 36ef15a8f2
commit a0e950109a
3 changed files with 142 additions and 4 deletions

View File

@ -112,7 +112,7 @@ const SUITE = [
['test/harmony-admin.test.mjs', ['--experimental-strip-types', '--no-warnings'], 22],
// P4c 图片上传:阈值与两档策略 / 失败必带原因 / 退档判定只有一处 /
// release 都 await / 解码按目标尺寸 / multipart 字段名 / 上传后重新同步
['test/harmony-imageprep.test.mjs', ['--experimental-strip-types', '--no-warnings'], 29],
['test/harmony-imageprep.test.mjs', ['--experimental-strip-types', '--no-warnings'], 30],
// ArkTS **编译期**硬规则(纯文本可判、不需要设备)。这一条是构建撞出来的:
// 我把常量表插在了既有 import 之前 ⇒ arkts-no-misplaced-imports,而当时没有任何判据会跑它。
['test/harmony-arkts.test.mjs', [], 5],
@ -1289,7 +1289,17 @@ const STATIC_ONLY = [
['test/appearance-defaults.test.mjs', '默认值契约里 `.ets` 那半:运行时行为要设备', 'device'],
// P4c 同批的两条:判的是 `.ets` 里的页面/组件,本机没有设备也没有模拟器
['test/harmony-admin.test.mjs', '用户管理页:`.ets` 页面要 hvigorw 才能编译、要设备才能点(本机两者都没有)', 'device'],
['test/harmony-imageprep.test.mjs', '图片上传链:要 `@ohos.multimedia.image` + 相册 + 服务端,三样本机都没有', 'device']
/*
* ★ 第 2 列的**事实修正**(dsh 2026-09-19,把这一列变成每次运行都可见之后的第一件事
* 就是去读它,结果读到一句假话):
* 原文是「要 `@ohos.multimedia.image` + 相册 + **服务端**,三样本机都没有」——
* **"服务端"这一项不成立**:`server/internal/handler/attachments.go` 在,
* 且它的 Go 测试在本机能跑通(`go test ./internal/handler/ -run Attach` ⇒ ok)。
* 而且这条判据**根本没连服务端**:它读的是 `appearance.go` 里
* `appearanceMaxBytes()` 的默认值(本笔刚把它从硬编码改成**真读 Go 源**)。
* ⇒ 服务端那一半由本判据**静态覆盖**,欠的只有**设备侧的相册/解码真跑**。
*/
['test/harmony-imageprep.test.mjs', '上传链的设备侧:`@ohos.multimedia.image` + 相册要设备才能真跑(服务端那半本判据直接读 `appearance.go` 的源码,已覆盖)', 'device']
];
for (const [file, why, probe] of STATIC_ONLY) {