跨端: 预设色板两套(pi:这不是"观感未验"而是机制上确定不同)+ 手写色清册跨文件 + TMPDIR 按会话分家 + 提交归属可判

pi 读完 `model/Wallpaper.ts` 后指出四处,全部处理。这一提交同时改了
`client/harmony/` 与 `client/electron/`(跨端改动),所以 subject 按新约定自报家门。

## 1 预设色板不随主题 —— **类别判错了:不是"未验",是机制上确定不同**

我上一版把"深色档预设"记成"观感未验"。pi 指出:WebUI 的 `.bg-preset-*` 写的是
`rgb(var(--c-blue-100))`,而 `--c-*` 在 `.dark` 里整体换了一套(blue-100 → `30 43 67`),
所以 **WebUI 的预设自动随主题变**;这边只有浅色那套 = 深色主题下"浅色渐变垫在深色系统表面之下",
正是这一整轮在治的病。**它不需要真机就能判**(机制写在代码里)—— 我把可判的东西
记成了"未验",这跟上一轮把"没做"写成"没验"是同一类错。

选 pi 倾向的那条(跟随主题,与 WebUI 一致):

- 色板两套:`LIGHT_*` 取 CSS `:root`、`DARK_*` 取 CSS `.dark`;`paletteFor(dark)` 选一套,
  `layersFor(id, dark)` 按主题出层;
- `isDarkMode(theme, systemColorMode)` 放在纯逻辑里:选了 dark/light 就照办,
  `system` 看系统当时的 `colorMode`(锚到 SDK:`COLOR_MODE_DARK = 0` / `COLOR_MODE_LIGHT = 1`;
  读不到按浅色,与 WebUI 的 `:root` 默认一致);
- 系统深浅从 `resourceManager.getConfigurationSync().colorMode` 读
  (`Context` 基类没有 `config`;`UIAbilityContext.config` 要转型;两个枚举取值一致,都核过 SDK);
- 判据:两套值与 `:root`/`.dark` **逐个相等**;每个预设的深浅两套**必须真的不同**
  (否则"两套"是抄了两遍);网格线色也要换;`isDarkMode` 五种输入。
- **未做**:运行期间改系统深浅色不会自动重算(要重进页面)——系统侧正确做法是订阅
  `applicationContext.on('environment', …)`,记在 §7.17b。

变异:`DARK_BLUE_100` 偏一位 → 红;`paletteFor` 永远返回浅色(= 我原来那个状态)→ 红;
`isDarkMode` 把系统深浅记反 → 红;页面把深浅写死成 false → 红。

## 2 手写色清册**跨文件按类扫**(原 A2 只保护 `Theme.ets`)

`Wallpaper.ts` 也有手写色。若对照是"按名字枚举"的,第 15 个色就会逃掉 ——
与 A2 要防的是同一件事,只是换了文件。现在一份清册按类扫:全 `ets/` 树里每个
`X: string = '#RRGGBB'` 都必须登记(Theme 的品牌/业务语义色,或预设色板 ——
后者常量名必须带 `LIGHT_`/`DARK_` 前缀,值由 CSS 两段比对负责)。反向也判清册过期。

变异:`Theme.ets` 加未登记色 → 红;`Wallpaper.ts` 加未登记色 → 红;
加一个"看着合规"的 `DARK_EXTRA` → 红。

## 3 `TMPDIR` 互踩(pi 提出)

这个 worktree 可能同时有多个 agent 跑构建,而 fpm 会把 291MB 的 `linux-unpacked`
**整份复制**进 `TMPDIR` —— 撞车就是随机的产物损坏。`whoami` 区分不开(大家都是 root),
所以按**会话**分家:`TMPDIR=$PWD/.tmp/${DSH_SESSION_ID:-$(id -un)-$$}`
(进了 `npm run build:linux` 与 BUILD.md 的手敲命令;普通终端退化成"用户+PID")。

## 4 提交归属变成**跑判据就看得出来**(pi 给的形状)

新的 `test/commit-hygiene.test.mjs`:扫最近 40 条提交,**同时改两侧目录**的提交
必须在 subject 里自报家门(`跨端:`)。两条防腐:基线 = 该判据文件自己的引入提交
(**历史不改**,规则管从今往后);分类逻辑拿合成输入自检
(未标注的混合提交必须判红、标注过的不许红)——否则"解析没跑起来"时它会全绿。
变异:`COMMIT_HYGIENE_BASELINE` 指到老提交 → 历史里那两个被卷进去的提交立刻判红。

## 验证

`hvigorw assembleHap` BUILD SUCCESSFUL;`npm test` 退出码 0
(12 个判据文件全绿 + vitest 258/258;`commit-hygiene` 在本提交落地后基线生效)。
This commit is contained in:
2026-09-14 14:57:18 +08:00
parent 0ce8b29546
commit 22c9be7181
10 changed files with 530 additions and 44 deletions

View File

@ -158,7 +158,7 @@ WebUI 侧 `npm test` 在 **HEAD 上就是红的**`test/background.test.mjs`
| P2a | 信息架构:「通信一项内部页签 收件箱/发件箱/授权未读红待决策橙徽标 | **点页签 → 断言落到哪个 pane**不是断言页签个数)—— 页签状态机判据已落地 §7.15 |
| P2b | 发件箱页`GET /me/mail/sent`复用列表项 | 判据接口路径行上主角是收件人空态有说明主句与 WebUI 逐字一致 |
| P3 主体完成 | 授权页`GET /permission/pending` + `POST /permission/decide` | 未决口径与 WebUI 一致 `permission_result`)✅;拒绝可填备注且备注送出 ✅;`expired` 当场说清"这次批准不会恢复原调用" ✅。**未验**真机上点同意/拒绝后状态是否"立刻变"判据只钉到"决策后重新拉列表"这一层 |
| P4 ✅(P4c 上传除外 | 主题/壁纸`/me/appearance` | 换账号外观跟随 ✅(缓存键带账号服务端无记录时以本地为准 ✅(§7.16**预设 6 档都能画出来** ✅、图片壁纸渲染 ✅(§7.17 —— 这一版补的第一版只有数据没有画面)。**未做**P4c 上传入口。**未验**真机观感与深色档预设 |
| P4 ✅(P4c 上传除外 | 主题/壁纸`/me/appearance` | 换账号外观跟随 ✅(缓存键带账号服务端无记录时以本地为准 ✅(§7.16**预设 6 档都能画出来** ✅、图片壁纸渲染 ✅(§7.17 —— 这一版补的第一版只有数据没有画面)。**未做**P4c 上传入口。**未验**真机观感配色/对比 |
| P5 未做 | 悬浮玻璃导航取代系统 TabBar | 模糊只由壁纸层负责列表项每项一张卡命中区 44vp现状底栏仍是系统 `Tabs`只有自绘的 tabBar builder 带了 `backgroundBlurStyle`(§7.10 |
| P6 未做 | 日历`/calendar/events` ics 导入导出 | 手势阈值与 WebUI 一致水平 40px、≥1.5× 垂直、<600ms)。**有意排序**入口与内容一起上不留空页签(§7.15 |
@ -767,5 +767,54 @@ pi 指出"邻接不是结构"这条已经在同一个仓库露头**三次**
不阻塞别的阶段),照 WebUI 踩过的三条做:**先压缩再上传**(手机直出照片 48MB
**失败必须给原因**(别静默失败)、**上传成功后仍以服务端为权威**`saved` 那套规则对图片同样适用)。
**未验**:预设渐变与图片壁纸在真机上的实际观感(尤其是**深色模式**下预设的表现 ——
色板现在取的是 CSS 的浅色档,深色档要不要另给一套,等真机看过再定)。
**未验**:预设渐变与图片壁纸在真机上的实际观感(配色是否好看、对比够不够)。
### 7.17b 预设色板**两套**:这不是"观感未验"是机制上确定不同pi 指出)
我上一版把"深色档预设"记成"观感未验"pi 读完 `Wallpaper.ts` 后指出这是**判错的类别**
那边的预设写的是 `rgb(var(--c-blue-100))`,而 `--c-*``.dark` 里**整体换了一套**
blue-100 → `30 43 67`)—— WebUI 的预设**自动随主题变**;这边若只有浅色那套,
深色主题下就是"浅色渐变垫在深色系统表面之下",正是这一整轮在治的那个病。
**它不需要真机就能判:机制写在代码里。**
处理(选 pi 倾向的那条:跟随主题,与 WebUI 一致):
- 色板做成**两套**`LIGHT_*` 取 CSS `:root``DARK_*` 取 CSS `.dark`
`paletteFor(dark)` 选一套,`layersFor(id, dark)` 按主题出层;
- 深浅色的判定放在纯逻辑 `isDarkMode(theme, systemColorMode)`:用户选了 dark/light 就照办,
`system` 时看系统当时反馈的 `colorMode`(数值锚到 SDK`COLOR_MODE_DARK = 0`
`COLOR_MODE_LIGHT = 1`;读不到/未设置按**浅色**,与 WebUI 的 `:root` 默认一致);
- 系统当时的深浅从 `resourceManager.getConfigurationSync().colorMode`
`Context` 基类没有 `config``UIAbilityContext.config` 要转型;两个枚举取值一致,都核过 SDK
- 判据:两套值与 `index.css``:root` / `.dark` 段**逐个相等**;每个预设的深浅两套
**必须真的不同**(否则"两套"是抄了两遍);网格线色也要跟着换;`isDarkMode` 五种输入。
**已知边界(未做)**:用户在应用**运行期间**改系统深浅色,这边不会自动重算
(要重进页面/重进应用)。系统侧的正确做法是订阅 `applicationContext.on('environment', …)`
的配置变化回调 —— 记在这里,没做。
### 7.17c 手写色清册升级成**跨文件按类扫**pi 建议)
原来的 A2 只保护 `Theme.ets`;而 `Wallpaper.ts` 也有手写色14 个预设色)。
那边靠"从 CSS 读出来逐个对照"抓到了 `#BFDCFE`,手法是对的 ——
但若对照是**按名字枚举**的,第 15 个色就会逃掉:这正是 A2 要防的同一件事,只是换了个文件。
现在并成**一份清册、按类扫**:全 `ets/` 树里每个 `X: string = '#RRGGBB'` 都必须在清册里 ——
要么是 `common/Theme.ets` 的品牌/业务语义色,要么是 `model/Wallpaper.ts` 的预设色板
(后者的值由 CSS 两段比对负责,且常量名必须带 `LIGHT_`/`DARK_` 前缀,判据才知道跟哪一段比)。
反向也判:清册里登记了却不存在 → 清册过期。
变异:`Theme.ets` 加一个未登记色 → 红;`Wallpaper.ts` 加一个未登记色 → 红;
加一个"看起来合规"的 `DARK_EXTRA` → 红(不在清册里就是不在)。
### 7.17d 并发写入的两个坑:`TMPDIR` 互踩、提交归属pi 提出)
- **`TMPDIR` 互踩**:这个 worktree 可能同时有多个 agent 跑构建,而 fpm 会把
`release/linux-unpacked`(约 291MB**整份复制**进 `TMPDIR` —— 两边落到同一个临时目录
就是随机的产物损坏/构建失败,比"归属错"难查得多。`whoami` **区分不开**(这里大家都是 root
所以按**会话**分家:`TMPDIR=$PWD/.tmp/${DSH_SESSION_ID:-$(id -un)-$$}`
(已进 `npm run build:linux` 与 BUILD.md 的手敲命令)。
- **提交归属可判**:同时改 `client/harmony/``client/electron/` 的提交**必须在 subject 里
自报家门**`跨端:`)—— 那种提交是合法的("跨端判据要两侧一起改"),只是要标出来;
不标的多半是被 `git add -A` 卷进去的。判据在 `test/commit-hygiene.test.mjs`
基线 = 该判据文件自己的引入提交(**历史不改**,规则管从今往后),
配分类逻辑的合成自检(否则"解析没跑起来"时会全绿)。