跨端: feat(预设): 静默兜底留一条可观测痕迹;"只写不读"在鸿蒙侧也补上判据(照 LEGACY_BACKUP_KEY 照搬);§10 出处落地

pi 2026-09-14 的三小条。

1. **§3 静默兜底要留可观测痕迹**:`normalizePreset` 把认不出的 id 换成 aurora 这件事,
   原先在真实环境里**不留任何痕迹** —— §10 的登记只防"被误报成 bug",防不住
   "没人知道它正在发生"。现在 `BackgroundPlan.presetSubstitutedFrom` 带出**原来那个 id**
   (换过非空、没换过空串),页面据此打一行日志 ⇒ 后果从"可能发生"变成"**可数**"。
   **痕迹记在返回值里而不是在这一层直接打日志**,理由写进代码:这一层是**纯逻辑**
   (无 `@ohos` 依赖 ⇒ 判据能用 node strip-types 直接跑它);为打一行日志引入 `@ohos.hilog`,
   等于把"能真跑的行为判据"换成"只能读源码的形态判据"——不划算的交易。
   **判据两条方向都钉**:替换必须留痕(且带出原 id);**没替换时必须为空**
   (痕迹退化成噪声就等于没有)。变异与正反例都在(5 条全绿)。

2. **§2 §10 的"谁批准"落成出处**:那一格原写"产品决定" —— 按 pi 的话这是**事后追认**。
   现在写的是 **「无人类批准:这是实现时的默认行为(随 `model/Wallpaper.ts` 引入,
   `git log --diff-filter=A` 可查出处,2e42aac),本行是补登记」**,并把**意图**与**批准**分开写
   (不拿意图冒充批准)。另两行也补了出处(`Appearance.ts:39,52,88,104,133` /
   `AppearanceStore.ets:142-195` / `backgroundStore.ts:200`)。

3. **§1 "可扫的字段清册"不必先造 —— 同形状已有一边是判据**:他说得对。
   WebUI 的 `LEGACY_BACKUP_KEY` 早就钉着"只写不读",鸿蒙的 `bgBlur` 只有文档
   ⇒ 差的是**同一个形状只有一边有判据**。已照搬:`harmony-appearance.test.mjs` 新增
   **"消费侧出现次数必须为 0"**;豁免**按文件登记 + 写理由**(域模型 / 状态同步 / 线上 DTO
   三处是搬运与传输,不是消费)——与 `mail_status_readers_test.go` 的豁免同一形状,
   登记表本身就是清册,不必另造一张。
   变异验证:让 MainPage 读一次 `bgBlur` → 判据红,红的信息写着"**停下:那时必须先补
   px ↔ 材质档位的映射判据**,而不是把登记值从 0 改成 1"。

SUITE 计数同步:harmony-presets 4→5、harmony-appearance 24→25。
This commit is contained in:
2026-09-14 17:13:19 +08:00
parent eeb8f277fd
commit f5c4f56682
5 changed files with 101 additions and 4 deletions

View File

@ -105,3 +105,29 @@ test('深色档必须与浅色档不同("深色没换色" → 红)', () => {
`${id} 的深色档与浅色档完全一样 ⇒ 深色模式下这一档没有换色`);
}
});
/*
* ★ 静默兜底必须留下**可观测的痕迹**(pi 2026-09-14)。
*
* §10 登记了"未知 id 静默换成 aurora"这条缺省语义,但**登记只防"被误报成 bug"**,
* 防不住"没人知道它正在发生" —— 真实环境里它不留任何痕迹。所以返回值里带
* `presetSubstitutedFrom`:换过就是原来那个 id,没换过是空串,页面据此打一行日志。
*
* 这条判据同时钉住两件事:① 替换**必须**留痕;② 没替换时**不许**留痕
* (否则痕迹会退化成噪声,等于没有)。
*/
test('★ 静默兜底留痕:换过要带出原 id,没换过必须是空串', () => {
const unknown = 'ocean-v2-这个档还不存在';
const bad = W.resolveBackground('preset', unknown, 0.2, false, false);
assert.equal(bad.presetId, 'aurora', `自检:未知 id 应当被换成默认档(实际 ${bad.presetId})`);
assert.equal(bad.presetSubstitutedFrom, unknown,
'认不出的 id 被静默替换了,却没留下痕迹 ⇒ 版本偏移时无法确认它在发生(只能猜)');
for (const id of IDS) {
for (const dark of THEMES) {
const plan = W.resolveBackground('preset', id, 0.2, false, dark);
assert.equal(plan.presetSubstitutedFrom, '',
`${id}(${themeName(dark)})是已知档,不该留下"替换过"的痕迹(痕迹变成噪声就等于没有)`);
}
}
});