Files
MailUI4Agents/client/electron/test/mutants/jobs/jobs-all.json
JianFeeeee 2fe023735e 跨端: 3 处判据基建修正(清册正则 / 变异锚点 / 计数棘轮)+ baseline 第 10 次重算
起因:`node run-all.mjs` 报 `verdict=red` 但四个计数全是 0 ——
红来自**到期闸**(`dueFailed`)与**计数棘轮**,不是断言失败。
逐个查清,三处都做成了真问题并留证。

## ① 跨文件手写色清册的正则从 `{6}` 放宽到 6 或 8 位

`glassCard` / `glassCardWall` 是 **8 位**(`#EBFFFFFF` / `#C7FFFFFF`,
半透明白是 WebUI `.glass-card` 的本质),而那条判据的正则只认 6 位 ⇒
它看不见这两个令牌,却报出「清册里的 glassCard 已不存在(清册过期)」——
**病因报错了**:不是清册过期,是正则比被判的东西窄。

改成 `{6}(?:[0-9A-Fa-f]{2})?`。★ 不能写 `{6,8}`:那会把 7 位这种非法长度也放进来。

同一形状在另两条判据上各出现一次(`B|旧机制不得回来` 与
`遮罩:交给系统的遮罩语义色`),它们原来**全仓**扫 `#……{8}` ⇒ 把这两个
**不是遮罩**的令牌一起撞红。都改成**同名枚举白名单**(不是放宽:
遮罩那个真实约束原样保留 —— `overlay` 写成 8 位单色照样红)。

## ② 变异锚点过期(守具有齿但没挂上)

`jobs/jobs-all.json` 里「写死色值 + 去卡片圆角」那条的锚点,
被 `6ca0113` 插进去的 `.attributeModifier(PressEffectModifier.of())` 隔断 ⇒
`hits=0`、`skipped=1`,而**没有任何东西变红**。

已把锚点补成当前代码形状,`ran` 从 51 回到 52、`skipped=0`。
★ 这是本仓那个老形状的又一次实例:**"清单没跟上代码"不会自己报警**,
得靠 `hits=0` 那条判据;它本次确实报出来了(`diag=mutant-anchor-stale`)。

## ③ 计数棘轮 6 → 7

给 `cross-client-logic` 新增了 `AddressSuggest` 一组(地址补全纯逻辑),
而套件只判**下界** ⇒ 不同步这个数字,将来**删掉**那一组不会有任何东西变红。
已显式改成 7,并写清"为什么必须手改"。

## ④ baseline 第 10 次重算(先证不是残留才重算)

`AdminUsersPage.ets` / `SettingsPage.ets` 哈希对不上,逐个取证:
- `sha256sum -c` → 这 2 个 FAILED(另 5 个 OK)
- `git diff --quiet HEAD` → **空**(与 HEAD 逐字节相同)⇒ 底本**过期**,不是残留
- `git log --oneline -3` → 最后一次动它们是 `f83c233`(我上一批的有意编辑)

★ 值得记一笔:漂移的是**上一轮**的文件,我这一轮完全没碰它们。
若只按"`git diff HEAD` 空就放行",这条**永远发现不了自己漏了一次重算** ——
这次是靠 `summary.py` 的 `baseline-stale` 主动报出来的。

## 结果

`files=34 ran=34 checks=543 pass=542 fail=0 skip=1 red=0 broken=0`
`mutants=52 ran=52 skipped=0 diag=none baseline=7/7✓`
(`verdict=red` 仅剩到期闸:5 条"只能静态"的判据,其到期前提"能装能点设备"
  现已成立,需要各自升级成行为判据 —— 已登记,不由这条提交关闭。)
2026-09-21 14:32:38 +08:00

233 lines
8.4 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[
{
"file": "client/harmony/entry/src/main/ets/model/AdminUsers.ts",
"pat": "return role === 'admin';",
"repl": "return role !== undefined && role.trim().toLowerCase() === 'admin';",
"test": "admin",
"why": "角色判定放宽"
},
{
"file": "client/harmony/entry/src/main/ets/model/AdminUsers.ts",
"pat": " if \\(!found\\) \\{\n out\\.push\\(item\\);\n \\}\n return out;",
"repl": " if (!found) {\n list.push(item);\n }\n return list;",
"test": "admin",
"why": "toggled 就地改入参"
},
{
"file": "client/harmony/entry/src/main/ets/model/AdminUsers.ts",
"pat": "if \\(v === undefined \\|\\| v\\.length === 0\\) \\{",
"repl": "if (v === undefined) {",
"test": "admin",
"why": "空串不当从未登录"
},
{
"file": "client/harmony/entry/src/main/ets/model/AdminUsers.ts",
"pat": " if \\(user\\.role === 'admin'\\) \\{\n return false;\n \\}\n",
"repl": "",
"test": "admin",
"why": "管理员也打受限徽标"
},
{
"file": "client/harmony/entry/src/main/ets/model/AdminUsers.ts",
"pat": "return '操作失败(服务端没有给原因)';",
"repl": "return '操作失败';",
"test": "admin",
"why": "兜底句不说原因缺席"
},
{
"file": "client/harmony/entry/src/main/ets/model/AdminUsers.ts",
"pat": " return message;\n \\}\n if \\(!isApiError",
"repl": " return '操作失败';\n }\n if (!isApiError",
"test": "admin",
"why": "吞掉服务端文案"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "const longest: number = Math\\.max\\(width, height\\);",
"repl": "const longest: number = width;",
"test": "prep",
"why": "缩放按宽算"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "const scale: number = Math\\.min\\(1, maxEdge / longest\\);",
"repl": "const scale: number = maxEdge / longest;",
"test": "prep",
"why": "小图被放大"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "second\\.maxEdge = RETRY_EDGE;",
"repl": "second.maxEdge = MAX_EDGE;",
"test": "prep",
"why": "退档不降分辨率"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "second\\.quality = RETRY_QUALITY;",
"repl": "second.quality = FIRST_QUALITY;",
"test": "prep",
"why": "退档不降质量"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "return actualBytes > MAX_UPLOAD_BYTES;",
"repl": "return actualBytes >= MAX_UPLOAD_BYTES;",
"test": "prep",
"why": "等于上限也退档"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "if \\(sizeBytes > MAX_SOURCE_BYTES\\) \\{",
"repl": "if (sizeBytes >= MAX_SOURCE_BYTES) {",
"test": "prep",
"why": "边界 >= 而不是 >"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "if \\(!mimeType\\.startsWith\\('image/'\\)\\) \\{",
"repl": "if (false) {",
"test": "prep",
"why": "不判类型"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "return '上传失败:' \\+ serverMessage;",
"repl": "return '上传失败';",
"test": "prep",
"why": "吞掉上传失败文案"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "export const MAX_UPLOAD_BYTES: number = 3_670_016;",
"repl": "export const MAX_UPLOAD_BYTES: number = 6_291_456;",
"test": "prep",
"why": "上限超过服务端 4MiB"
},
{
"file": "client/harmony/entry/src/main/ets/model/ImagePrep.ts",
"pat": "export const MAX_EDGE: number = 2560;",
"repl": "export const MAX_EDGE: number = 4096;",
"test": "prep",
"why": "首档最长边改 4096"
},
{
"file": "client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets",
"pat": " if \\(isRestricted\\(user\\)\\) \\{",
"repl": " if (false) {",
"test": "admin",
"why": "去掉受限徽标"
},
{
"file": "client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets",
"pat": " onlyStatus\\.status = 'active';",
"repl": " onlyStatus.status = 'active';\n onlyStatus.display_name = this.editDisplayName;",
"test": "admin",
"why": "启停顺带发 display_name"
},
{
"file": "client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets",
"pat": " \\.backgroundColor\\(Theme\\.surface\\)\\n \\.borderRadius\\(Theme\\.radiusCard\\)\\n \\.attributeModifier\\(PressEffectModifier\\.of\\(\\)\\)\\n \\.onClick\\(\\(\\) => \\{ this\\.toggleEdit\\(user\\); \\}\\)",
"repl": " .backgroundColor('#123456')\n .attributeModifier(PressEffectModifier.of())\n .onClick(() => { this.toggleEdit(user); })",
"test": "admin",
"why": "写死色值 + 去卡片圆角"
},
{
"file": "client/harmony/entry/src/main/ets/pages/SettingsPage.ets",
"pat": " this\\.isAdmin = false;\n \\}",
"repl": " this.isAdmin = true;\n }",
"test": "admin",
"why": "身份读不到时乐观显示入口"
},
{
"file": "client/harmony/entry/src/main/ets/pages/SettingsPage.ets",
"pat": " if \\(this\\.isAdmin\\) \\{",
"repl": " if (true) {",
"test": "admin",
"why": "管理入口不做门禁"
},
{
"file": "client/harmony/entry/src/main/ets/pages/SettingsPage.ets",
"pat": " @State isAdmin: boolean = false;",
"repl": " @State isAdmin: boolean = true;",
"test": "admin",
"why": "isAdmin 初值 true"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": "if \\(!overLimit\\) \\{\n\\s*break;",
"repl": "if (true) {\n break;",
"test": "prep",
"why": "永远只压第一档"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": "if \\(packed === null \\|\\| overLimit\\)",
"repl": "if (packed === null)",
"test": "prep",
"why": "两档都超限不拒绝"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": "overLimit = shouldRetryWithActual\\(usedBytes\\);",
"repl": "overLimit = false;",
"test": "prep",
"why": "结论恒 false"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": "await packer\\.release\\(\\);",
"repl": "packer.release();",
"test": "prep",
"why": "packer.release 不 await"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": "await head\\.release\\(\\);",
"repl": "head.release();",
"test": "prep",
"why": "head.release 不 await"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": "desiredSize: \\{ width: size\\.width, height: size\\.height \\}",
"repl": "desiredSize: { width: info.size.width, height: info.size.height }",
"test": "prep",
"why": "按原图尺寸解码"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": " quality: Math\\.round\\(quality \\* 100\\)",
"repl": " quality: quality",
"test": "prep",
"why": "quality 不换算"
},
{
"file": "client/harmony/entry/src/main/ets/common/BackgroundPicker.ets",
"pat": " this\\.onUploaded\\(UPLOAD_OK_HINT\\);",
"repl": " this.bgKind = 'image';",
"test": "prep",
"why": "组件自己宣布成功"
},
{
"file": "client/harmony/entry/src/main/ets/api/ApiClient.ets",
"pat": "name: 'file',\n contentType: mimeType",
"repl": "name: 'image',",
"test": "prep",
"why": "multipart 字段名不是 file(uploadBytes 那一处;此前锚点命中 2 次跑不起来,已切片)"
},
{
"file": "client/harmony/entry/src/main/ets/api/AppearanceApi.ets",
"pat": "fileName, 'image/jpeg'\\);",
"repl": "fileName, 'application/octet-stream');",
"test": "prep",
"why": "上传 mime 发错"
},
{
"file": "client/harmony/entry/src/main/ets/pages/SettingsPage.ets",
"pat": " await store\\.syncFromServer\\(ctx, client\\);\n this\\.adoptSnapshot\\(store\\.current\\(\\), store\\.statusText\\(\\)\\);\n \\}\n\n /\\*\\* 把 store 里的快照复制进 @State",
"repl": " this.bgKind = 'image';\n }\n\n /** 把 store 里的快照复制进 @State",
"test": "prep",
"why": "上传成功后不重新同步"
}
]