Files
MailUI4Agents/client/electron/test/mutants/baseline.sha
JianFeeeee 21332de5e7 test(判据): criteria-hygiene 的 AGC 探针自检改用临时仓合成对照
## 为什么要改

那条判据("AGC 真身从未进过远端历史")的自检原本要求
**本地可达历史里确实有该路径**,用它证明 `git log -- <路径>` 这套查法可用。

★ 那个前提**已经不成立**了:真身**从未被提交过**
  (`client/harmony/.gitignore:26` 一直在挡它),所以本地历史里
  本来就查不到 ⇒ 这条判据**永久红、且无法自查**。
  (注释里引用的 `7647c24` / `320c93f` 在本树也**不存在**。)

而判据的分诊早已确认:真身确实从未进过历史(被 ignore 正确挡住),
红的是**探针的假设**失效,不是缺陷存在。

## 改法:合成阳性 + 阴性对照

在**临时仓**(`mkdtemp`)里造两个提交 —— 一个含待查路径、一个不含 ——
对两者跑同一套查法,断言**双向有分辨力**。临时仓不碰本仓任何状态
(`GIT_CONFIG_GLOBAL=/dev/null` 避免读用户配置),造完即删。

为什么**必须**有阳性对照:一条用来抓泄露的判据,
**正确工作**时恰好永远看到"空"(没泄露 ⇒ 查不到)。
**"真值恰好是空"与"查法坏了"在输出上同形**(都是空串 + exit 0)
⇒ 真实历史里没有阳性样本可用,只能现造。

## ★ 阴性对照第一版写错了(变异测试打出来才发现)

我先写成查一个**真实存在**的无关文件 `unrelated.txt`。
变异把它改成查阳性那个 `leaf.json`,判据**照样绿** ——
因为查 unrelated 本来就该命中,那不叫"查法在乱报"。

⇒ 阴性对照要证明的是「**不存在的**目标查不到」,也就是**查法有边界**。
改成查 `no-such-file-ever.json`,并**额外**验一次 sanity
(真实但无关的文件**应当**查得到)—— 两个方向都对才算有分辨力。

改后双向变异都能打红(阳性查不到 ⇒ 红;阴性恒命中 ⇒ 红)。
2026-09-28 08:46:02 +08:00

178 lines
17 KiB
Plaintext
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.

# 变异体基线的**自证底本**:每个被变异过的文件在此记下"未变异"时的 sha256。
# 跑完变异后 `sha256sum -c baseline.sha` 必须全 OK(summary.py 把结果打进 RESULT 行)。
#
# 取基线是**有意的动作**,不是随手重算 —— 重算会把"某次变异没还原"永久掩盖掉。
# 每次重算都要在此记一行"为什么":
# 2026-09-20 10:xx baseline 重算(第 8 次)—— 用户:「所有顶栏统一玻璃圆框」「抽象统一顶栏组件」
# 「发件箱太大了」「各组件带响应点击动画了吗」「转场动画呢」「还有其他行为要一一对齐」。
# ① 有意编辑:`MainPage.ets`(SentTab/PermissionTab 顶栏改 AppHeader、挂按压反馈)、
# `SettingsPage.ets`(标题行改 AppHeader)、`AdminUsersPage.ets`(Header 改 AppHeader)。
# ② 两个都跑过 `git diff --quiet HEAD -- <f>` 取证。
# ★ 本轮最大的收获是**两个「看起来做了、其实没生效」的坑**:
# · `.attributeModifier()` **一个组件只能挂一个**,链两个是后者覆盖前者 ——
# 会话组头卡同时挂了玻璃与按压反馈,结果只生效一个,编译器不报错。
# 修法:`CompositeModifier` 显式合成(CSS 的类名天然叠加,ArkUI 是单一插槽)。
# · `applyPressedAttribute` **只对自带按压状态机的组件**(Button)回调;
# 纯 `Row`/`Column`(全仓 117 处 onClick 的主体)一次都不触发 ——
# 实测:挂上去后按下与常态逐像素相同。改用 `onTouch` + 系统点击效果色。
# 2026-09-19 22:xx baseline 重算(第 7 次)—— 用户:「玻璃要更透明/磨砂更有质感」+「判据去芜存菁」。
# ① `pages/SettingsPage.ets` / `pages/MainPage.ets`:有意编辑 ——
# 页面里的玻璃三连(`backgroundColor` + `backgroundBlurStyle`)收敛成
# `.attributeModifier(GlassCardModifier.of(this.bgActive))` / `PaneModifier.of(...)`
# (用户:「定义一个基础玻璃容器给各个组件引用」)。
# ★ 途中一度把 `@Styles glassCard()` 里也替换成了 `attributeModifier`,
# 造成该页 ProfileSection/AppearanceSection/PushSection **整块不渲染**
# (设备实测:Scroll 直接跳到「客户端连接密钥」)。已删掉那个死 `@Styles`。
# ② 两个都跑过 `git diff --quiet HEAD -- <f>` ⇒ 非空(是"我改的",不是变异残留)。
# ★ 本轮到目前为止判据侧修了 4 个**判据自身的缺陷**(都不是放水,是补上它声称却漏判的类):
# · 材质来源只扫 `backgroundBlurStyle` —— 玻璃改成 `backgroundEffect` 后整类漏判
# (实测:塞一行裸 `backgroundEffect({radius:99,saturation:9.9})` 照样全绿);
# · 参数抽取用 `[^)]*`,对 `this.materialOf()` / `{...}` 对象字面量都截断 ⇒ 误伤合法写法;
# · 嵌套判定**没比文件**,拿 A 文件的偏移比 B 文件 ⇒ 判出物理上不可能的红;
# · `harmony-appearance` 数的是**内联字面量**("三元出现 ≥5 次"),
# 收敛成组件后写法变了、行为没变却变红 ⇒ 改成判不变式。
# 2026-09-19 21:0x dsh:baseline 重算(第 6 次)—— 用户要求「基础玻璃容器 + 补出现/消失动画」。
# ① `pages/AdminUsersPage.ets`:有意编辑 —— 「新建用户」表单补 `paneRiseIn()` 过渡
# (原来挂着 `if (this.showCreate)` 却硬弹;用户:「元素的出现消失动画呢?」)。
# 过渡挂在**调用点的 Column** 上,不是 `CreateForm()` 内部:`@Builder` 调用返回 void,
# 链不上修饰符(第一版就写错在内部,是新判据抓出来的)。
# ② `pages/SettingsPage.ets`:有意编辑 —— 所有卡片面 `Theme.surface` →
# `bgActive ? Transparent : surface` + `Theme.cardMaterial`(玻璃卡);
# 并**去掉**两处内层容器的材质(账号列表 / 密钥列表)——
# 那两处是"卡里面的一段列表",两层都铺材质 = 嵌套玻璃(判据 C 条会红)。
# ③ 两个都逐个跑过 `git diff --quiet HEAD -- <f>` ⇒ 非空(是"我改的");
# 另 grep 确认无裸 `BlurStyle.XXX` 残留、无变异留下的空 transition。
# ★ 本次判据侧也改了:C 条从"逐处登记白名单"改成"材质必须来自设计令牌"
# (玻璃从少数例外变成**默认**,白名单挡不住新写的裸枚举)。
# 2026-09-15 11:22 dsh:`AdminUsersPage.ets` 的哈希变了,**不是变异残留**。
# 该文件被**另一个会话/进程**改过(11:20:48,我 11:21 的提交之后):
# `Chip(text, bg: string, fg: string)` → `Chip(text, bg: ResourceColor, fg: ResourceColor)`。
# 核实过是**正确的 ArkTS 修法**(`Theme.surfaceMuted`/`textSubtle` 是 `Resource`,
# `Theme.chipNeutralBg` 是 `string` ⇒ 旧签名编译不过)。我没有提交也没有回退它。
#
# 2026-09-15 11:50 dsh:三个文件漂移,全部核实为**有意改动、不是变异残留**:
# · `model/Appearance.ts` + `pages/MainPage.ets`:**我自己**按 pi 的裁定把方案 (b) 落地成 (a)
# (删 `navMaterialFor` 与 `NAV_MATERIAL_OF`、导航条改回 `Theme.navMaterial`、
# 重写那段"注释说 (a)、代码是 (b)"的自相矛盾注释)。
# · `api/ApiClient.ets`:**别的会话**的提交 `69c2059`(JianFeeeee,11:43:22,
# 推送客户端契约层)动过它;当前内容与 HEAD 逐字节相同(`git diff HEAD` 空)。
# 复核"是不是变异残留"的方法:`git diff HEAD -- <文件>` + 上面这些记录。
#
# 2026-09-18 dsh:三个文件漂移,**已逐个核实是提交态、不是变异残留**(重算前的前提):
# · `AdminUsersPage.ets`、`SettingsPage.ets`:提交 `1be8318`(09-17 21:15,
# "底栏黑带 / 联系人点不开"那批)改过;`git diff --quiet HEAD` 为空 ⇒ 与 HEAD 逐字节相同。
# · `ApiClient.ets`:提交 `fce5b91`(09-15 15:15,"鸿蒙客户端连不上服务器")改过;同上。
# ★ 为什么必须先证这一步:底本**过期**与**变异残留**在 `sha256sum -c` 眼里一模一样,
# 而重算会把真正的残留**永久掩盖** —— 所以"重算"必须是一次**有记录**的动作。
# ★ 顺带修了播报:原来一律打"有文件没还原"(指向最危险的结论),
# 而真因只是底本没跟上提交 ⇒ 现在两种分开报,并各自给出判别方法。
#
# 2026-09-19 13:0x dsh:四个文件漂移,**已逐个核实是提交态、不是变异残留**(重算前的前提):
# · `pages/AdminUsersPage.ets`:提交 `6693e96`(09-18 11:47,"登录页那个 emoji 是 Unicode…")
# · `common/BackgroundPicker.ets`、`pages/SettingsPage.ets`:提交 `7e1120a`
# (09-19 12:30,"顶栏不再自己铺白条 + 日历改左右两栏…")
# · `api/ApiClient.ets`:提交 `7e10bfa`(09-18 12:55,"鸿蒙日历补 .ics 导入导出")
# 四个都 `git diff --quiet HEAD -- <f>` ⇒ **与 HEAD 逐字节相同** ⇒ 底本过期,不是残留。
# ★ 为什么必须逐个证这一步:底本**过期**与**变异残留**在 `sha256sum -c` 眼里一模一样,
# 而重算会把真正的残留**永久掩盖** —— 所以"重算"必须是一次**有记录**的动作。
# ⚠️ 这次漂移正是 `baseline-stale`(rc=0、只提示)那一档的又一次实例:
# 它**不假红**(正常提交不会天天红),但也**不会被自动发现** ——
# 我是靠"核每个文件的登记/实际读数"这条主动核查撞上的,不是它自己报的。
#
# 2026-09-19 18:2x baseline 重算(**先核过不是残留,才重算的**):
# ① `pages/AdminUsersPage.ets`、`pages/SettingsPage.ets` —— 我本次的**有意编辑**:
# 给所有"压在彩色底上的字/图标"换前景色(`Theme.surface` → `Theme.accentFg`),
# 并把品牌蓝前景接入 `Theme.accentFor()`(深色下提亮到 WebUI 的 `--c-blue-600`)。
# ② `api/AppearanceApi.ets` —— **与 HEAD 逐字节相同**(`git diff --quiet HEAD` 为空),
# 但底本哈希对不上 ⇒ 说明它在底本取完之后被**合法改过**(提交 `3b5cc63`,
# 09-19 那次"外观保存 400"的修:`payloadFromLocal` 改用 `AppearancePayload`)。
# ⇒ 这是 `stale`(底本过期),不是 `residue`(变异残留)。
# ★ 三个都逐个跑过 `git diff --quiet HEAD -- <f>` 取证,没有一个是"改动忘了还原"。
# ★ 这正是这份文件里那条纪律的第 3 次执行:"重算必须是一次有记录的动作"。
#
# 2026-09-19 20:2x baseline 重算(第 4 次,**仍先核过不是残留**):
# ① `pages/AdminUsersPage.ets` / `pages/SettingsPage.ets` / `common/BackgroundPicker.ets`
# —— 本次的**有意编辑**:语义色前景接入 `dangerFor()/approveFor()/warnFgFor()`
# (深色下红/绿/琥珀要提亮,对齐 WebUI `.dark --c-red/green/amber-700`),
# 以及三级文字接入 `textSubtleFor()`(深色下换二级,见 Theme.ets 里那段理由)。
# ② 三个都逐个跑过 `git diff --quiet HEAD -- <f>` ⇒ 全部**非空**(工作树有改动)
# ⇒ 是"我改的",不是"变异忘了还原"。
# ★ 取证命令留在这里,下次照着做:
# git diff --quiet HEAD -- <file> && echo STALE || echo INTENTIONAL
#
# 2026-09-19 20:4x baseline 重算(第 5 次):
# ① AdminUsersPage.ets / SettingsPage.ets -- 有意编辑:修三元里的裸 Theme.accent
# (前景位置漏改的那 2 处)+ 那一批 textSubtleFor()。
# ② 本次格外重要的一步:我批量替换 Theme.accent -> accentFor() 时,
# 误把 6 处 backgroundColor 也换了(accentFor() 深色给浅蓝 #80AFF9,
# 白字压上去约 1.4:1,主按钮文字会看不见)。发现后已逐处还原。
# 重算前专门复核过三件事(不能只看 git diff 非空就放行):
# - grep -c "backgroundColor(Theme.accentFor())" 得到 0
# - 三个涉及文件里都无 accentFor 背景
# - git diff HEAD~1 里 backgroundColor 只有 calendar 那一处
# (原本是 accentSoftFor,属本次有意改动)
# => 确认无「改错了没还原」的残留在。
# ③ 新增判据 C2(*For() 入口只能用于前景、不得当背景)把这整类钉住,
# 下次再手滑批量替换会直接判红,不必再靠事后复核。
# 2026-09-20 21:5x baseline 重算(第 9 次)—— 照 `arkts-grammar-standards` skill 的规则表回扫,
# 修掉两处「编译器只告警、判据也不管」的隐形债:正则字面量、废弃的全局 router API。
# ① 有意编辑:`SettingsPage.ets`(`performLogout` 多传一个 `UIContext`)。
# ② 取证:`git diff --quiet HEAD -- <f>` → INTENTIONAL(与 HEAD 不同);
# 再逐行核过 diff **只有这一处一减一加**,确认不是变异残留。
# ★ 为什么改这一行:`performLogout` 内部原来用**已废弃的全局 `router`** 做退出跳转;
# 改成 `ui.getRouter()` 就需要 `UIContext`,而它是独立函数(没有 `this`),
# 只能由调用方传 —— 两个调用点(`MainPage` 侧栏 / `SettingsPage` 我的页)都持有它。
# ★ 为什么这类债能活这么久:编译器对它们**只告警不挡构建**,全仓也**没有判据**管,
# ⇒ 规则事实上不存在。已补两条判据(正则字面量 / 废弃全局 API),都做了变异验证。
# 2026-09-21 1x:xx baseline 重算(第 10 次)—— 用户:「2in1 快捷键」「上下键切换发信目标」。
# ① 两个文件漂移:`pages/AdminUsersPage.ets`、`pages/SettingsPage.ets`
# (都**不是**我这次为 2in1 改的,而是上一提交 `d6e9603` 动的)。
# ② 取证(照这份文件里那条纪律逐条做):
# · `sha256sum -c baseline.sha` → 这 2 个 FAILED(另外 5 个 OK)
# · `git diff --quiet HEAD -- <f>` → **空**(与 HEAD 逐字节相同)
# ⇒ 底本**过期**,不是变异残留(两者在 sha256 眼里一模一样,必须分开判)
# · `git log --oneline -3 -- <f>` → 最后一次动它们是 `d6e9603`
# (「修卡片投影/页签条圆角/日视图/周视图」—— 我那一批里有意的编辑)
# ③ ★ 为什么这次漂移值得记一笔:漂移的是**上一轮**的文件,而我这一轮
# 完全没碰它们。如果只看"`git diff HEAD` 空就放行",那这条**永远发现不了
# 自己漏了一次重算** —— 这次是靠 `summary.py` 的 `baseline-stale` 主动报出来的。
# ④ 顺带修掉一条**变异锚点过期**(同一轮的另一个"守具没挂上"):
# `jobs/jobs-all.json` 里「写死色值 + 去卡片圆角」那条的锚点,
# 被 `dabf1e6` 插进去的 `.attributeModifier(PressEffectModifier.of())` 隔断
# ⇒ `hits=0`、`skipped=1`,**但没有任何东西变红**(守具有齿,只是没挂上)。
# 已把锚点补成当前代码的形状,`ran` 从 51 回到 52、`skipped=0`。
# ⇒ 这是同一形状的第 N 次:**"清单没跟上代码"不会自己报警**,
# 得靠 `hits=0` 那条判据;而它本次确实报出来了(`diag=mutant-anchor-stale`)。
# 2026-09-23 09:5x baseline 重算(第 11 次)—— 用户:「修改密码也应该做成弹窗吧」一批弹层迁移。
# ① 三个文件漂移,**两类成因已分别取证**(这一步不能省 —— 底本过期与变异残留在 sha256 眼里一样):
# · AdminUsersPage.ets、BackgroundPicker.ets —— `git diff --quiet HEAD` ⇒ **空**(与 HEAD 逐字节相同),
# 最近提交 `aa10427` / `9064ead` ⇒ **底本过期(stale)**,不是残留。
# · SettingsPage.ets —— `git diff --quiet HEAD` ⇒ **非空** ⇒ **我的有意编辑**,逐块核过 diff 只有重构、无半截/占位。
# ② 有意编辑的内容(用户:「修改密码也应该做成弹窗吧」):
# 修改密码 / 新增账号 → 官方 `bindSheet`(`FIT_CONTENT` + `showClose: true`,两者同形);
# 删掉自绘遮罩(该文件里 `Theme.overlay` 只剩注释引用);
# 候选列表补 `Theme.menuIn()`(WebUI `AddressInput.tsx:261` 同款,鸿蒙此前是硬弹)。
# ③ 复算后 `sha256sum -c baseline.sha` 应全 OK(11/11)。
# 2026-09-28 baseline 重算(第 9 次)—— 两个文件**有意编辑**(审查报告驱动的修复)。
# (1) pages/AdminUsersPage.ets:管理台门禁改**三态**。原先 `roleKnown && !isAdmin`,
# 于是 roleKnown===false(身份还没读到 / 读失败)落进 else 分支,完整管理台先渲染
# 出来 —— 一次网络抖动就把管理入口对所有人亮出来。改为 !roleKnown 时显示
# 「正在确认身份…」。服务端 AdminOnly 仍拦着,所以不是越权,是信息泄露面。
# (2) pages/SettingsPage.ets:performLogout 里补 MailStore.clear() 并加 hilog
# 记录失败 —— 登出不清内存,下一个登录的人会先看到上一个人的邮件。
# · 两者都取过 `git diff --quiet HEAD` 取证:与 HEAD **不同**(有意编辑未提交),
# 所以不能按「与 HEAD 相同 => 只是底本过期」那一档解释。
# ★ 但「底本过期」这一档仍然成立,关键依据是**可证伪的范围**:
# 这两个文件**不在** jobs.manifest.json 里(已实测),而底本覆盖的是**清单内**
# 被变异过的文件 => 它们不会被变异,哈希变了只可能是**有意编辑**。
# 若哪天它们被加进变异清单,本条推理作废,须重新核对有无变异残留。
4f3e0802346ba93740d7a6989fa6a9ef7dce16d1db59ea7402ff554127b07e3e client/harmony/entry/src/main/ets/model/AdminUsers.ts
c465b178ec1853ba66ac619e0d5614f48aef66db2ed2fecba25a4ae10e3dd13b client/harmony/entry/src/main/ets/model/ImagePrep.ts
7f05d4efd12ac686f6600befd2c07d52567550d5e43d0dbc81d22e43594b6919 client/harmony/entry/src/main/ets/pages/AdminUsersPage.ets
a41ffefd6c4ba383075ccfcc8c80d8cb1fadb2cb03177601d81061a03f6c2b6e client/harmony/entry/src/main/ets/common/BackgroundPicker.ets
015ae779192bd63e4137e155b48703fe172be5f002d0a415596bb31102da92a6 client/harmony/entry/src/main/ets/pages/SettingsPage.ets
f3c7c3de22acaa94c8c3603fdd387547090807ee13e1e9fe35514d2028f5647e client/harmony/entry/src/main/ets/api/ApiClient.ets
6550e1892d1ebea82fb75a3d2cf8eaf826186199ff4a0ecf0430b1e3517d8681 client/harmony/entry/src/main/ets/api/AppearanceApi.ets