Skip to content

ci(design-system): DS-7 启用成熟范围的设计检查 - #4215

Merged
kirozeng merged 5 commits into
makecindy:mainfrom
kirozeng:ds/7-design-guards
Sep 10, 2026
Merged

kirozeng merged 5 commits into
makecindy:mainfrom
kirozeng:ds/7-design-guards

Conversation

@kirozeng

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

修复设计颜色审计把语义主题颜色和 PR 编号误报为裸色的问题,并将成熟范围的新增颜色检查接入现有 verify。同时在同一界面台账登记 Mobile 的实际入口。界面外观和产品行为不变。

变更类型

  • fix 缺陷修复
  • docs / test / chore 文档、测试或工程维护
  • 其他:ci 设计检查增量接线

范围

  • 关联需求:Cindy 设计系统 DS-7;承接 feat(design-system): DS-6 完成表单与确认组件复用 #4135
  • 本 PR 包含:共用颜色 matcher、明确 base/head 与工作区候选审计、窄颜色例外、可见层报告、Mobile 入口发现、必要测试及 CI/文档。
  • 明确不包含:产品 UI、Token 数值/JSON、依赖、权限/凭证/配置语义、协议/用户数据、Mobile 原生构建输入、DS-8—12 实施。
  • 用户可见变化:无;贡献者新增违规会得到文件、行列、原因和改法。
  • 是否存在 breaking change:无产品兼容性变化;成熟 Desktop 消费者新增字面颜色会新增 CI 阻断。

UI 变化

不涉及:仅门禁与台账,不改 UI 实现。

  • 引用的设计规范:docs/design-rules/DESIGN.md §5;docs/design-rules/design-governance.md §8/§13。
  • 圆角、间距、广泛表单采用和未决命中方案保持报告,不根据 DOM 标签猜形状。用户 radius 覆盖不变。
  • Mobile 仅补14类真实入口并保持 legacy;不锁定手机端布局或组件。后续 DS-10/未成熟规则待同事重构方案明确后一起评估。Mobile 新路由仍需同步台账,已有 Mobile 设计检查保留。

怎么验证的

自动验证

VITE_CINDY_AUTH_REGION=global pnpm test:unit:related
  CI/根脚本命中全量调度,退出0;28个workspace通过、6个原有notApplicable,runner527通过/1个原有跳过。
pnpm --filter desktop run --if-present typecheck
pnpm --filter mobile run --if-present typecheck
  均通过。
pnpm check:design-inventory
  49个surface;生成区与真实入口匹配,人工区保留。
node scripts/hardcoded-color-audit.mjs --base-ref fd4c1d03348daa670d09e6713841420a3f8c48df --worktree --json
  unexpected=0。
pnpm check:endpoints / check:i18n / check:brand-terminology / check:i18n-glossary
pnpm ci:scheduler-guard
pnpm --filter mobile test:scope
  均通过。

固定版本复现 DS-6 raw13/allowed2/unexpected11,候选消除全部11项误报。20张历史 PR 按冻结 base/head、脚本 SHA256 及逐项预期重新回放通过;真实违规另有反向注入。

E2E 使用隔离临时 Git 仓的真实 base/head,执行本次 workflow 的实际 pnpm 命令及 verify 汇总 shell。7个场景:语义色/原批准Toast色通过;HEX/fallback/新未批准Toast色使脚本及汇总失败;Mobile布局颜色仅报告;错误引用非零退出。新接线之外整个 workflow 对象与主干一致,保留全部既有检查。

手工验证

执行者按用户明确要求完成完整 diff review,未发现未修复 P0/P1。核对颜色分类/窄例外、可见层边界、Mobile真实入口与人工区、CI失败传播及声明范围。用户明确跳过独立双审,本次不声称双审完成。

文本证据:docs/design-evidence/2026-09-10/ds7-guards.md,同目录 JSON 保存完整历史 ref、预期和脚本 hash。

未执行的验证

未运行产品 UI 实机 E2E或新增截图,本批没有 UI 实现变化;上述 E2E为设计检查链路验证。Windows 本机未运行,保留现有 Windows CI 全量分片。G2独立贡献者试用、历史69张图片公开交接与 DS-6 平台待项继续登记,由 kirozeng 安排、Codex核对修复,2026-09-17复查。

风险

风险分类

  • 跨平台差异
  • 其他:CI 门禁调整;误报与静态发现盲区

影响与回滚

  • 影响范围:新增 Desktop renderer 字面颜色与 fallback 阻断;来源/测试/正式窄例外合法。未知几何、动态值和非成熟范围保留报告;Mobile旧守卫不降级。静态图不冒充原生/服务端动态呈现覆盖。
  • 回滚 / 降级方式:仅将新增颜色步骤改回 report 或撤回新增接线,保留现有主题、排版、Mobile、单测、类型、Windows及verify汇总,不改用户数据或远端required。
  • 治理 §8:合并前仍须管理员对本批 CI 接线实际批准。 本 PR 不修改远端保护,不自动合并。只读核对实际 required 为 DCO(外部App)、Windows unit tests、verify。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名
  • 不涉及产品 UI,已写明设计规则依据
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

Signed-off-by: kirozeng <kirozeng@gmail.com>
Signed-off-by: kirozeng <kirozeng@gmail.com>
@kirozeng
kirozeng requested a review from a team as a code owner September 10, 2026 04:40
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-09-10T04:40:56.258424Z 07502e8 PR opened
🔒 Security Review Completed 2026-09-10T04:47:36.926105Z 07502e8 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 将成熟 Desktop 消费者的新增字面颜色审计及设计台账新鲜度检查接入现有 verify,统一颜色词法匹配,收窄历史颜色例外,并将 Mobile 生产路由纳入设计台账。

  • 颜色审计支持明确的 base/head 和工作区候选,并区分 block、allowed 与 report 范围
  • 新增可见层圆角、间距及表单采用的报告级分类
  • 新增 Mobile 路由覆盖和本地 import/re-export 静态闭包
  • 补充历史回放、隔离 Git fixture、CI 失败传播及台账测试
  • 当前仍有两处会削弱门禁准确性的阻断问题:例外上下文过宽,以及普通字符串中的颜色函数误报

Confidence Score: 3/5

本 PR 暂不宜合并,因为颜色门禁既能放行同文件中的未批准语义复用,也会把普通字符串中的数值颜色文本误判为阻断违规。

两个问题都位于新增的强制 CI 路径:属性级例外缺少角色身份约束,会削弱门禁;函数颜色匹配缺少上下文判断,会让无设计变化的 Desktop renderer 文本修改失败。

Files Needing Attention: scripts/hardcoded-color-audit.mjs, scripts/shared/hardcoded-color-match.mjs

Important Files Changed

Filename Overview
scripts/hardcoded-color-audit.mjs 重写新增行审计、候选读取和窄例外逻辑;例外仍未绑定获批对象或具体角色,允许同文件复用批准颜色。
scripts/shared/hardcoded-color-match.mjs 统一语义包装、注释、PR 编号和字面 fallback 的匹配;数值颜色函数缺少样式上下文限制,会阻断普通文本。
scripts/shared/design-inventory.mjs 增加 Mobile 路由目录、静态依赖闭包和双端台账渲染;当前生产路由覆盖完整。
.github/workflows/ci.yml 将颜色审计和台账 freshness 接入现有 verify-checks,失败可传播到 verify 汇总。
scripts/tests/hardcoded-color-audit.test.mjs 覆盖 matcher、例外、工作区候选、错误引用和 CI 汇总,但缺少普通字符串函数色及同文件跨对象例外的反例。
scripts/tests/design-inventory.test.mjs 覆盖当前 Mobile 路由映射、入口变化、平台组件闭包和人工区保全。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Event[PR / main push] --> Refs[解析 base 与 head]
  Refs --> Audit[新增行颜色审计]
  Audit --> Scope{文件范围}
  Scope -->|Desktop renderer| Block[违规时阻断]
  Scope -->|来源 / 测试 / 窄例外| Allow[允许并记账]
  Scope -->|Mobile / 文档 / 其他| Report[仅报告]
  Event --> Inventory[生成设计台账事实]
  Inventory --> Fresh{与已提交台账一致}
  Fresh -->|否| Fail[verify-checks 失败]
  Fresh -->|是| Pass[进入现有 verify 汇总]
  Block --> Pass
  Allow --> Pass
  Report --> Pass
Loading
Prompt To Fix All With AI
### Issue 1
scripts/hardcoded-color-audit.mjs:54
**颜色例外范围过宽**

`approvedColor` 只校验文件 glob、相邻属性名和颜色值,没有确认颜色是否位于获批对象或具体角色中。例如,在 `Toast.tsx` 的任意新对象里加入 `color: '#417CDD'`,也会复用本来只属于 `VARIANT_MAP` 信息色的例外并通过检查。这样会让未批准的语义用色绕过新增门禁;请将例外绑定到获批对象、变体或其他可验证的上下文。

### Issue 2
scripts/shared/hardcoded-color-match.mjs:42-56
**普通字符串触发颜色门禁**

这里会在任何字符串中匹配完整的数值颜色函数,并不要求它位于样式属性、CSS 声明或任意值语境中。成熟 Desktop renderer 若新增普通帮助文案或诊断文本,例如 `const label = 'RGB(1, 2, 3)'`,它会被当成裸色并使 `verify` 失败,尽管没有设计变化。请像 HEX 分支一样检查颜色上下文,或排除普通文本字符串。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "Merge latest main and record DS-7 submis..." | Re-trigger Greptile

Comment thread scripts/hardcoded-color-audit.mjs
Comment thread scripts/shared/hardcoded-color-match.mjs Outdated
@MagicLizi MagicLizi added status:ci-failed CI 失败(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示) labels Sep 10, 2026
@MagicLizi MagicLizi added status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) and removed status:ci-failed CI 失败(review-pr 自动维护,仅展示) labels Sep 10, 2026
- 窄 matches 规则新增 object 绑定(对象字面量键路径,结构校验):Toast 四色
  绑定 VARIANT_MAP.<变体>,AgentIsland mascot 配色绑定
  MASCOT_PREVIEW_CONFIGS.<皮肤>;同文件其它对象/变体复用批准色即违规
- 数值颜色函数(rgb()/hsl()/oklch 等)补齐 HEX 分支同款上下文检查,且
  不把裸引号字面量当语境:需位于样式属性、CSS 声明/函数或任意值语境,
  普通文案/诊断字符串里的颜色函数文本(如 const label = 'RGB(1, 2, 3)')
  不再计入裸颜色、不再阻断 verify
- 台账口径同步:matcher 说明、DS-7 治理表更新,design-inventory.md 重算

Signed-off-by: Kirozeng <kirozeng@gmail.com>
@kirozeng

kirozeng commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

两条 P1 都已修复,提交 972288971

1. 例外范围过宽 → 绑定获批对象

matches 规则新增 object 字段,写明获批对象字面量的键路径;approvedColorobjectPathAt() 做结构校验(正向扫括号栈、跳过字符串内容、匿名块不计段)。命中必须同时匹配值、属性名,且落在获批对象路径里才算 allowed。

  • Toast 四色按变体各绑一条:"object": "VARIANT_MAP.info" / .success / .warning / .error
  • AgentIsland mascot 配色按皮肤绑:"object": "MASCOT_PREVIEW_CONFIGS.cindy" 等;同一值出现在多个皮肤的用数组列出

所以评审里的反例——在 Toast.tsx 任意新对象里写 color: '#417CDD'——现在是 block;跨变体复用(error 变体用 info 的色)也是 block;脱离 MASCOT_PREVIEW_CONFIGSeyeColor 同样 block。这些反例都进了测试(hardcoded-color-audit.test.mjs 的 cases 表)。

绑定是 fail-closed 的:对象改名或挪位后例外失效、重新报 block,需要更新例外条目。globals.css 的 selector、new-chat 的 var(--composer-pill-*)、WorkLouder 的 --wl-* 自定义属性名本身就唯一标识获批角色,维持原样。

2. 普通字符串里的函数色 → 补上下文检查

scripts/shared/hardcoded-color-match.mjs 的函数色分支现在要求颜色位于样式语境:样式属性(backgroundColor:eyeColor:style.boxShadow =、SVG fill=)、CSS 自定义属性('--panel-shadow':)、颜色函数(var() / color-mix() / 渐变)或 Tailwind 任意值。与 HEX 分支同一套纪律,但裸引号字面量不再算语境——带引号的 RGB(1, 2, 3) 经常只是文案。

评审给的例子 const label = 'RGB(1, 2, 3)' 现在不命中,verify 不会再被帮助文案或诊断文本打红。属性名按 camelCase / 连字符分段匹配颜色词:borderColor 算,keyboardBasefulfillment 不算。

一个明说的取舍:属性名不含颜色词的函数色(如 keyboardBase: 'rgb(38 43 69)')不再报告——这些值本来就有例外记录,审计结论不变,同位置的 hex 值仍照旧拦截。台账按新口径重算(desktop.settings colors 119→109,mobile 各 surface −27~−28),治理文档 DS-7 表格同步更新。

验证

  • node --test scripts/__tests__/hardcoded-color-audit.test.mjs — 12/12 通过
  • node --test scripts/__tests__/design-inventory.test.mjs — 51/51 通过
  • pnpm test:unit:related — exit 0(本 PR 早前改过 ci.yml,runner 自动升级为全量单测)。备注:在带 ANTHROPIC_SMALL_FAST_MODEL / CLAUDE_CODE_DISABLE_EXPLORE_INHERIT_CAP 环境变量的 agent 会话里直接跑,maker-core 的 env-builder 测试会因环境泄漏误报,清掉后全绿
  • pnpm check:design-colors --base-ref 56c0e500 --head-ref HEADunexpected=0
  • pnpm check:design-inventory — ✅ GENERATED 区块最新(49 个 surface)

🤖 pr-autopilot 修复跟进 · dispatch:bab218785a994f91

main 前进后本 PR 与之冲突(design-inventory.md 生成区块),GitHub 无法构建
merge ref,pull_request workflow(client-ci)不创建 run,required context
Windows unit tests 缺席。合入 origin/main 并以 pnpm design:inventory 在合并
结果上重新生成台账;两个脚本测试 12/12、51/51,check:design-colors 对
origin/main 意外命中 0,test:unit:related 全绿。

Signed-off-by: Kirozeng <kirozeng@gmail.com>
@kirozeng

Copy link
Copy Markdown
Contributor Author

这轮信号是「required context 在当前 head 上缺席: Windows unit tests」,已修复,提交 0728e0cb1

根因:不是 Windows 测试挂了,是 PR 与 main 冲突

main 前进后(56c0e500b27f99d51),本 PR 与之出现合并冲突(冲突文件只有 docs/design-rules/design-inventory.md 的生成区块)。GitHub 对冲突 PR 无法构建 merge ref,pull_request 触发的 workflow(client-ci、pr-design-basis)整个不会创建 run——所以所有 required context 都"缺席",看起来就像只有 Windows unit tests 消失了(DCO 之类的 App 检查不吃 merge ref,照常上报,更容易误导)。

证据:push 前对 head 972288971 查询 actions/runs?head_sha=... 结果为 0 条 run,同时 PR mergeableCONFLICTING;两者同时成立即此根因。

修法

合入 origin/main(merge commit 0728e0cb1)。唯一冲突文件是生成文件,不手合并:冲突块解开后在合并结果上重新跑 pnpm design:inventory,一次性吸收 main 侧的 mobile 统计变化与本分支的匹配口径。

证据

  • mergeableCONFLICTINGMERGEABLEmergeStateStatus: BLOCKED 只是 required checks 还在跑的正常态)
  • 新 head 0728e0cb1 上 workflow run 恢复创建:client-ci in_progress、pr-design-basis completed——Windows unit tests 会随 client-ci 正常上报
  • node --test scripts/__tests__/hardcoded-color-audit.test.mjs — 12/12
  • node --test scripts/__tests__/design-inventory.test.mjs — 51/51
  • pnpm check:design-colors --base-ref origin/main --head-ref HEADunexpected=0
  • pnpm check:design-inventory — ✅ GENERATED 区块最新(49 个 surface)
  • pnpm test:unit:related — exit 0(含 main 合入后的全量单测;agent 会话需清掉 ANTHROPIC_SMALL_FAST_MODEL / CLAUDE_CODE_DISABLE_EXPLORE_INHERIT_CAP 等环境变量,否则 maker-core env-builder 测试有环境泄漏误报)

🤖 pr-autopilot 修复跟进 · dispatch:8477c6d6c49d7f66

merge commit 0728e0c 只带进了冲突解决版台账,pnpm design:inventory 的
重新生成结果停留在工作树未暂存,CI checkout 到旧台账导致
check:design-inventory / test:runner 的 CLI --check 在 verify-checks、
Windows unit tests (1/2)、Desktop Git integration 三处同因失败。本提交
补上生成结果(desktop.bots 等 surface 的 files/tokens/radii 对齐 main 合入后的闭包)。

Signed-off-by: Kirozeng <kirozeng@gmail.com>
@kirozeng

Copy link
Copy Markdown
Contributor Author

这轮信号还是「Windows unit tests 缺席」,实际查下来是 head 0728e0cb1 上三处真实失败,已修复,提交 cdaef3f80

实际失败与根因

client-ci 在 0728e0cb1 上挂了三处:verify-checksWindows unit tests (1/2)Desktop Git integration——拆日志看是同一个测试design-inventory.test.mjs 的「CLI --check 在当前台账上通过」(台账新鲜度检查)。

根因是我上一轮合 main 时的流程失误:merge commit 0728e0cb1 里只提交了冲突解决版的 docs/design-rules/design-inventory.md,之后 pnpm design:inventory 重新生成的结果停留在工作树、没有重新 git add。本地校验读的是工作树所以全绿,CI checkout 到的是提交里的旧台账,重算不匹配(desktop.bots 等共 6 行统计差异,如 files=247 vs 248)→ 三处同因失败。是提交内容陈旧,不是平台差异。

修复与验证(这次验证跑在提交后的树上,工作树与 HEAD 一致)

  • cdaef3f80 补上重新生成的台账(1 file changed, 6 insertions, 6 deletions)
  • node --test scripts/__tests__/design-inventory.test.mjs — 51/51(含 CI 上挂的 CLI --check 子测试)
  • node --test scripts/__tests__/hardcoded-color-audit.test.mjs — 12/12
  • pnpm check:design-inventory — ✅ GENERATED 区块最新(49 个 surface)
  • pnpm check:design-colors --base-ref origin/main --head-ref HEADunexpected=0
  • 新 head cdaef3f80 上 client-ci 已恢复创建并 in_progress,pr-design-basis 已通过

🤖 pr-autopilot 修复跟进 · dispatch:a4d66aa14145c48e

@kirozeng
kirozeng merged commit 4f03ea9 into makecindy:main Sep 10, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants