文档: CRITERIA.md §16.1.3 —— 判据锚在"字面相邻"隐含断言"不许再多一层"(假红的来源)
记 pi `7d98245a` §三 报的那条假红(`Motion.dur(...)` 包一层 ⇒ `duration:\s*Theme\.durRise`
失配),连同我自己量到的两半:
· 无障碍层**零判据**:`isAnimationReduceEnabled`/`Motion.dur`/`Motion.reduced`
在 test/ 里 grep 各 0 次;WebUI 侧**有**(animation-audit.test.mjs:112)。
变异(`Motion.dur` 恒 return want)⇒ 失败集合逐条相同 ⇒ **零反应**。
· ★ 绕过面比"都包了"更大:**11 个真动画时长站点里 5 个绕过开关**
(CalendarPage:373,410 / MainPage:2607,2845,2884 裸 `Theme.durX`)
⇒ "收成一个入口"的设计意图**只落了一半**。
通用纪律:**判据锚在"字面相邻"时,它其实断言了"两层之间不许再有一层"** ——
而那个隐含断言几乎从不是作者本意(本意是"这个令牌要被引用")。
二者在实现多一层合法卷绕(包装函数/无障碍开关/单位换算/类型转换)时**必然分叉**,
方向是**假红**。
⇒ 与 §16.1.2 合成一条:**判据的严格度必须与它真正想守的那件事对齐,
而不是与"当时那版实现的写法"对齐。**
This commit is contained in:
@ -1054,6 +1054,73 @@ hook / CI / cron 调用它。**而它当时正红着**:
|
||||
> 本仓 `stripComments` 自己那段注释早警告过"判据开始消费散文",
|
||||
> 但警告的是**字符串**,**没覆盖"另一种语言的注释"** —— 这一格是那个洞的实例。
|
||||
|
||||
#### 16.1.3 ★★ 第六个落点:**判据锚在"字面相邻",而实现合法地多了一层**(pi 报 + dsh 复现,2026-09-20)
|
||||
|
||||
`harmony-nav.test.mjs:441` 断言:
|
||||
|
||||
```js
|
||||
assert.match(body, /duration:\s*Theme\.durRise/, '★ paneRiseIn 里入场时长必须引用 Theme.durRise')
|
||||
```
|
||||
|
||||
它要防的**真 bug** 是 2026-09-18 那笔:把"壁纸淡入的时长"(`durBase`) 当成"面板入场的时长"。
|
||||
**动机完全正确。** 但它的形状是"`duration:` 与 `Theme.durRise` **字面相邻**"。
|
||||
|
||||
而无障碍动效开关落地后,`Theme.paneRiseIn()` 合法地变成:
|
||||
|
||||
```ets
|
||||
).animation({ duration: Motion.dur(Theme.durRise), curve: Theme.easeRise })
|
||||
```
|
||||
|
||||
`Motion.dur(x) = reduced() ? 0 : x`(系统开"减少动效"就折成 0ms)。
|
||||
⇒ **语义上 `durRise` 仍被引用**,只是多了一层卷绕 ⇒ 正则失配 ⇒ **假红**。
|
||||
|
||||
**实测**(dsh,隔离 worktree,同刻对照):
|
||||
|
||||
| 树 | `harmony-nav` |
|
||||
|---|---|
|
||||
| A 干净 HEAD | 19 tests / **18 pass / 1 fail**(`not ok 16`,设备条) |
|
||||
| B HEAD + 未提交的无障碍改动 | **17 pass / 2 fail**(多出来的正是 `not ok 8`) |
|
||||
|
||||
**修法**(放宽**包装**,不放宽**令牌**):
|
||||
|
||||
```js
|
||||
/duration:\s*(?:Motion\.dur\()?Theme\.durRise/
|
||||
```
|
||||
|
||||
★ **区分力实测未动**(3 个方向):
|
||||
|
||||
| 变异 | 结果 |
|
||||
|---|---|
|
||||
| `Motion.dur(Theme.durBase)`(换令牌) | 仍红 ✓ |
|
||||
| 裸 `Theme.durBase`(不包了,直接换) | 仍红 ✓ |
|
||||
| 干净 HEAD 形状但换令牌 | 仍红 ✓ |
|
||||
|
||||
且**下面那条 `!/Theme\.durBase/` 逐字仍在**、扫的是**整个函数体**
|
||||
⇒ `Motion.dur(Theme.durBase)` 这种"包一层蒙混"**照样红**。
|
||||
修后全套 `red 5 → 4`(`harmony-nav` 从红名单出去,其余 4 条红是别的会话的)。
|
||||
|
||||
★★ **同一次量出的更值钱一条:那个无障碍层本身"零判据",而且只落了一半**
|
||||
|
||||
- `client/electron/test/` 里 `isAnimationReduceEnabled` / `Motion.dur` / `Motion.reduced`
|
||||
grep **各 0 次**;对照 **WebUI 侧有**判据(`animation-audit.test.mjs:112` 的
|
||||
`prefers-reduced-motion` 覆盖 `.rise-in`)。**同一份无障碍义务,Web 侧有守、鸿蒙侧没有。**
|
||||
- **变异零反应**(dsh 复现 pi 的):把 `Motion.dur` 改成恒 `return want`
|
||||
(整个开关失效,源里 6 处受影响)⇒ `harmony-nav` 失败集合与变异前**逐条相同**(`17/2`)。
|
||||
- ★ 而**绕过面比"6 处都包了"更大**:11 个真·动画时长站点里 **5 个绕过开关** ——
|
||||
`CalendarPage.ets:373,410`、`MainPage.ets:2607,2845,2884` 是裸 `Theme.durX`。
|
||||
即"**收成一个入口,漏掉的人写不出忘了判断的代码**"这个设计意图**目前只落了一半**。
|
||||
(另外 6 处:`Theme.ets` 5 处 + `Surface.ets:276`。)
|
||||
|
||||
> **通用纪律(这一格的抽象):判据锚在"字面相邻"时,它其实断言了"两层之间不许再有一层"。**
|
||||
> 那个隐含断言**几乎从来不是作者的本意** —— 作者本意是"**这个令牌要被引用**"。
|
||||
> 二者在实现多一层合法卷绕(包装函数、无障碍开关、单位换算、类型转换)时**必然分叉**,
|
||||
> 而分叉的方向是**假红**。
|
||||
> ⇒ 写"源码里找写法"的判据时问一句:**我要的是"这两个字面上挨着",还是"这个令牌在这条链上"?**
|
||||
> 若是后者,正则要给**卷绕**留位(`(?:Wrapper\()?`),而**"令牌"那一格一个字都不放**。
|
||||
> ★ 与 §16.1.2 同源:那一格是"判据读的语言不对",这一格是"判据读的形状比实现更死"。
|
||||
> 两次的教训合成一条:**判据的"严格度"必须与它真正想守的那件事对齐,
|
||||
> 而不是与"当时那版实现的写法"对齐。**
|
||||
|
||||
### 16.2 ★★ **同一优先级写了两遍 ⇒ 两个顺序**:不变式只在**对角线**上被验过(pi + dsh 2026-09-18)
|
||||
|
||||
§16.1 讲"结论到不了决定颜色的那一格"。这一节是它的**镜像**:
|
||||
|
||||
Reference in New Issue
Block a user