Files
Agent-System-Dev/DESIGN.md
T
weichen c79458793e
ci / svc-realcombo (pull_request) Successful in 3m0s
ci / test (pull_request) Failing after 4m49s
ci / test-pg (pull_request) Successful in 13m36s
Integrate work companion visibility across components
Why: The fast and slow channel UI duplicated work cards and hid intermediate output after the final reply.

Evidence: SELF isolated-network make test and make build; 15 browser scenarios; independent component review; component PRs #55, #199, #85.

Impact: Pin merged Backend, Frontend and UI revisions and update DESIGN.md for one detail location and durable folded history.

Refs: .task/feature-work-companion-visibility.md; Agent-System-UI #55; Agent-System-Backend #199; Agent-System-Frontend #85
2026-10-14 14:52:04 +00:00

327 lines
21 KiB
Markdown
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.
# Agent-System-Dev 设计系统(DESIGN.md)
写给 Agent 与人:在本仓生成或修改任何 UI 之前,先遵循本文,再发明新的视觉规则。
违反本文视为**设计系统缺陷**,不是风格偏好。
四原则:**美观、现代、简洁、易用**。每条规则都是四原则在某一维度上的可执行化。
参照体系:ZCode(zai-org/ZCode)开源仓的 DESIGN.md、`packages/ui/src/styles.css`
主题真值与动效配方。本文的色板、字号标尺、圆角层级、动效参数均逐条对照其源码校准。
---
## 1. 产品性格
Agent-System-Dev 是桌面优先、Web 兼容的 AI 工作台。界面应**冷静、高密度、可操作**,而非装饰性的。
为长会话、高信息密度、可读的对话与工具输出、键盘驱动的工作流而设计。
避免:营销式大留白、默认渐变装饰、大面积品牌色铺底、背景/卡片/浮层层次含混。
## 2. 主题
- 用户可选主题:跟随系统 / 浅色 / 深色。实现为 `:root[data-theme='dark' | 'light']`。
- 深色基准为 Zai Dark 复刻;浅色基准为 Zai Light。**令牌唯一来源:`@ui/tokens.css`**。
- 禁止在组件里出现裸色值(hex/rgb 字面量);一切颜色经语义令牌消费。
守护测试(`design-guard.test.ts`)以基线棘轮拦截新增裸值。
### 2.1 表面阶梯(层次靠背景阶梯,不是描边堆叠)
| 令牌 | 深色 (Zai Dark) | 浅色 (Zai Light) | 用途 |
|---|---|---|---|
| `--bg-inset` | `#101010` | `#ececee` | 窗口间隙(面板化布局的"底座")、代码底 |
| `--bg` | `#161616` | `#f8f8f8` | 应用底、主区背景 |
| `--bg-panel` | `#202020` | `#ffffff` | 侧栏/面板/头部 |
| `--bg-raised` | `#2b2b2b` | `#ffffff` | 卡片、输入、菜单、浮层 |
| `--bg-hover` | `rgba(255,255,255,.05)` | `rgba(13,13,13,.05)` | 通用悬停 |
| `--bg-active` | `rgba(255,255,255,.10)` | `rgba(13,13,13,.08)` | 选中态 |
### 2.2 边框(发丝三档)
`--border-soft: rgba(255,255,255,.06)` / `--border: rgba(255,255,255,.10)` /
`--border-strong: rgba(255,255,255,.15)`(浅色对应 13,13,13 的 .08/.10/.16)。
边框只做轮廓;选中优先用 `--bg-active` 填充而非换边框色。
### 2.3 文本
`--text`(主读文本,深 `#d4d4d4` / 浅 `#262626` / 墨绿 `#082d4f`)。
`--text-dim`:深 66% / 浅 68% / 墨绿 70%。
`--text-faint`:深 52% / 浅与墨绿 58%。
用文本层级制造信息密度,先于增加更多边框或颜色。
门槛(`contrast-guard.test.ts`,WCAG 2.1):
- `--text` 与 `--text-dim` 在主区表面(`--bg`、`--bg-panel`、`--bg-raised`、代码底 `--bg-inset`)不低于 **4.5:1**。
- `--text-faint` 不低于 **3:1**,并且**只用于装饰**:占位符、chevron、kbd、关闭图标的默认色。
- 承载决策或需要读完的文字从 `--text-dim` 起步:表头、确认详情、工具清单、空态说明、设置项描述、状态词。不要把 faint 当内容色。
侧栏另用 `--text-sidebar-dim`(墨绿 78%)与 `--text-sidebar-faint`(墨绿 62%),门槛与主区相同,只跟 `--bg-sidebar` 对拍。
侧栏会把 `--text*` 重映射成侧栏色。挂在侧栏 DOM 里、但画在主区纸面上的浮层(账户菜单)改用 `--text-workspace*`,这是同一套文字的不被重映射的副本。
### 2.4 强调与语义色
- 交互强调蓝:`--accent`(深 `#4099ff` / 浅 `#0b7fff`)。**只用于**链接、选中指示、聚焦环、
进行中指示;不做大面积铺底、不做主按钮底色。
- 主按钮:单色系反色——`--primary`(深 `#ffffff` / 浅 `#0d0d0d`)配 `--primary-foreground`
(反向黑/白)。品牌色保持克制。
- 语义图形色:`--ok #46bf72`、`--warn #ff8a30`、`--err #ff5c5c`(浅色与墨绿 `#1e8a3e` / `#d17300` / `#e03131`)。
语义色只表语义。图形色(状态点、描边、色条)在 `--bg` / `--bg-panel` / `--bg-raised` 上不低于 **3:1**。
**图形色不作文字。** 链接、状态词、差异文字、空闲状态字用下面的文字档。
- 文字档(同一色相,专门保证 4.5:1,含铺在 `*-soft` 上):
| 令牌 | 深色 | 浅色 / 墨绿 | 用途 |
|---|---|---|---|
| `--accent-text` | `#58a6ff` | `#0858b0` | 链接、动作字 |
| `--warn-text` | `#ff8a30` | `#8d4d00` | 警告文字;也作警告徽标底 |
| `--err-text` | `#ff7272` | `#a92525` | 错误文字;也作错误徽标底 |
| `--ok-text` | `#46bf72` | `#17682f` | 成功状态字 |
| `--idle-text` | `#929292` | `#636363` | 空闲状态字 |
| `--diff-add-text` | `#7dcea0` | `#17682f` | 差异增加的文字 |
| `--diff-remove-text` | `#ff9b9b` | `#a92525` | 差异删除的文字 |
徽标:底用对应 `*-text`,字用 `--text-on-semantic`(深 `#101010` / 浅与墨绿 `#ffffff`)。
- 等你确认用 `--wait`(深 `#8b93ff` / 浅 `#3a46c8` / 墨绿 `#3d5a9a`)和 `--wait-soft`。
不借用成功绿,也不用红或橙装饰等待。
- 差异视图:增加用 `--diff-add` / `--diff-add-text`,删除用 `--diff-remove` / `--diff-remove-text`。
- 空闲任务的图形用 `--task-idle`,文字用 `--idle-text`。定时任务用 `--task-scheduled`。两者不要混成同一种灰。
### 2.5 墨绿主题(可选,`data-theme='molv'`)
暖纸白工作区、深海军蓝左栏与顶栏、翠绿强调。只覆盖表面与语义色;字号标尺、圆角、间距沿用 §3–§5,不另起一套。左栏与顶栏消费 `--bg-sidebar` / `--text-sidebar*`(深色与浅色下别名到面板与正文,墨绿下翻成海军蓝)。
| 令牌 | 墨绿 | 用途 |
|---|---|---|
| `--bg-inset` | `#e0e0db` | 窗口间隙 |
| `--bg` | `#f2f2f0` | 对话主区 |
| `--bg-panel` | `#fbfbfa` | 右栏等面板 |
| `--bg-sidebar` | `#082d4f` | 左栏、顶栏 |
| `--text` | `#082d4f` | 主读文本 |
| `--text-sidebar` | `#e9f0f6` | 左栏与顶栏文字 |
| `--accent` | `#165f49` | 主区交互强调(翠绿)。不用于侧栏 |
| `--accent-sidebar` | `#8fd4b4` | 侧栏内的强调:active 图标、聚焦边、选中条 |
| `--primary` / `--primary-foreground` | `#082d4f` / `#f3f8f5` | 主区主按钮 |
| `--primary-sidebar` / `--primary-sidebar-foreground` | `#e9f0f6` / `#082d4f` | 侧栏上的主按钮(「新建任务」) |
深色与浅色下,侧栏三令牌别名到主区:`--primary-sidebar` 同 `--primary`,深色 `--accent-sidebar` 同 `--accent`。浅色侧栏是白底,`--accent-sidebar` 改走 `--accent-text`(`#0b7fff` 在白底上不足 4.5:1)。侧栏内的 active、聚焦和主按钮只消费这组令牌,不直接用主区 `--accent` / `--primary`。
### 2.6 文档纸面(主题不变量)
Office 分页预览是**内容**,不是界面。纸面与默认墨色固定,三套主题同值:
| 令牌 | 值 | 用途 |
|---|---|---|
| `--paper` | `#ffffff` | docx 页、幻灯片等文档纸面 |
| `--paper-ink` | `#000000` | 纸面上没有自带颜色的文字的默认墨色 |
规则:保留文档自己的字号、颜色、表格和图片样式。禁止用 `--bg` / `--text` 等主题令牌覆盖这些内联样式。界面只负责纸面周围的底座(`--bg-inset`)和按栏宽等比缩放。
## 3. 字号标尺(唯一字号体系)
全局唯一可调变量 `--ui-font-size`(默认 14px),派生:
| 令牌 | 公式 | 默认 | 角色 |
|---|---|---|---|
| `--fs-ui-xl` | +4px | 18 | 阅读标题 h1 |
| `--fs-ui-lg` | +2px | 16 | 阅读标题 h2 |
| `--fs-ui-base` | = | 14 | 正文、常用按钮、区块标题 |
| `--fs-ui-caption` | −1px | 13 | 紧凑辅助文案 |
| `--fs-ui-sm` | −2px | 12 | 次要信息、行内代码 |
| `--fs-ui-xs` | −3px | 11 | 仅徽标与图标性字符 |
| `--fs-ui-tooltip` | 同 `--fs-ui-sm` | 12 | 提示气泡。不另起字号 |
| `--fs-code` | −2px | 12 | 代码块、终端、Diff。随 `--ui-font-size` 缩放 |
规则:UI 组件一律用标尺令牌;禁止行内 `font-size` 数值与 Tailwind 式任意字号
(守护测试棘轮拦截)。用户调字号只改 `--ui-font-size`,不改根字号;图标、间距、圆角不随字号缩放。
设置中心「界面字号」提供 13 / 14 / 16 / 18 四档,写入 `--ui-font-size`,只存在本机(`localStorage`),不进账号设置。
表头用 `--fs-ui-sm` + `--text-dim`,不用 xs,也不要对中文做 `uppercase`。
例外:文档正文保留自己的阅读字号(约 13.5px),不跟界面标尺走。
字体:`--font` 系统栈优先(-apple-system/PingFang SC…);路径、命令、代码、快捷键用 `--mono`。
## 4. 间距
基数 4px。节奏:4(图标与文字)→ 8(控件内边距/行内间隙)→ 12(紧凑列表行)→
16(卡片/面板标准内边距)→ 20–24(大区块/对话框内部)。用少量重复间距,不用任意值。
## 5. 圆角(按嵌套层级,不按组件重要性)
| 令牌 | 值 | 用途 |
|---|---|---|
| `--radius-xs` | 4 | 最内层(嵌在 6px 控件里的小元素) |
| `--radius-sm` | 6 | 基础控件(嵌套时降档)、chip |
| `--radius` | 8 | 输入、菜单壳、工具行 |
| `--radius-lg` | 12 | 卡片、气泡、工具调用块、**面板(见 §6)** |
| `--radius-xl` | 16 | 对话框、全屏视图壳 |
| `--radius-full` | 999 | 仅用于刻意的胶囊/圆形 |
嵌套降档:12 → 8 → 6 → 4;最内层不低于 4。对话框内部重新从 12 起算。
禁止任意值。`rounded-full` 不因组件类型自动获得。
## 6. 布局:三栏工作台
桌面工作区 = 浮在 `--bg-inset` 底座上的**独立圆角面板**(左栏 / 对话主区 / 第三栏):
面板 `--radius-lg` 圆角 + `--border-soft` 发丝描边,面板之间 **4px 间隙**,应用四周 4px 内衬。
拖拽分隔条:透明 4px 命中区,hover/拖拽时显示 2px `--border-strong` 指示线(两端留出面板圆角)。
**左栏(找上下文)**:顶部切换项目(项目身份在此集中显示一次,含阶段徽章),
中段放会话列表与搜索,底部沉底放文件、领域工作区与账户。
**第三栏(右栏,双入口「工作 / 文件」)**:工作入口承载待处理事项、后台任务、执行记录
与当前任务卡;文件入口承载文件搜索、多标签预览、编辑与下载——文件预览不再是独立第四栏。
工作档宽度可拖(280–560);文件入口在有预览标签时切到阅读档(420–1100),不受工作档上限约束。
打开文件自动进入文件入口的预览子视图;关掉最后一张标签回到文件列表。标签按会话记住,
切回该会话时恢复。全屏展开是文件预览的放大,不是第二落位。
层次规则:左栏与第三栏用 `--bg-panel`,对话主区与文件预览内容用 `--bg`;窄屏可退化为通栏。
信息架构原则:**对话优先**——普通用户仅凭对话即可完成全部工作,第三栏纯辅助、可完全收起;
系统管理类视图独立成区(管理员专属入口),不混入用户设置。
中右栏按对象分工:中栏按回合顺序保留用户输入、最终回复、文件入口和该轮可折叠的完整过程记录;
右栏「工作」是当前进度、待确认事项与成果卡的详细落位,右栏「文件」是文件列表与唯一预览。
右栏工作可见时,中栏只给需要定位的短入口,不复制完整工作卡或操作按钮;右栏关闭或切到文件时,
中栏承担完整卡片与操作。桌面顶栏的「工作/文件」入口只在右栏关闭时出现,窄屏保留导航。
当前工作卡的阅读表面使用 `--work-focus-surface` / `--work-focus-border`,两者由 UI 令牌定义。
## 7. 海拔(Elevation)
克制深度,分层顺序:背景对比 > 发丝描边 > 浮层阴影 > 注意级阴影。
- 基础层:无阴影,靠背景阶梯;
- 卡片:无阴影或 `--shadow-md` 极弱;
- 菜单/弹层:`--shadow-md`;
- Toast/重要浮卡:`--shadow-lg`。
禁止用大软阴影做普通布局分层。
## 8. 动效(MotionKit)
动效解释状态变化,不装饰屏幕。快、低调;禁止长弹簧(仅点赞/完成反馈可用一次过冲)。
**全部动效经 `@ui/motion.css` 的 `mk-*` 工具类消费;组件文件禁止私有 `@keyframes`**
(守护测试拦截)。所有动效在 `prefers-reduced-motion: reduce` 下禁用。
| 工具类 | 参数 | 用途 |
|---|---|---|
| `mk-stream-in` | opacity,900ms `cubic-bezier(0.16,1,0.3,1)` | 流式内容进场(可按 token 加延迟) |
| `mk-rise-in` | fade + translateY(4px),180ms | 列表行/卡片进入 |
| `mk-waterfall` | clip-path + translateY(−12px),260ms `cubic-bezier(0.22,1,0.36,1)` | 建议列表逐条瀑布 |
| `mk-col` / `mk-col-inner` | 高度 grid-rows 300ms ease-in-out + 内层 fade | 折叠/展开(@ui Collapsible) |
| `mk-sweep` | 文字扫光,300% 渐变 4s linear | **运行态指示(不用 spinner)** |
| `mk-breathe` | opacity .4↔1,1.2s | 状态点呼吸 |
| `mk-pop` | 450ms `cubic-bezier(0.34,1.56,0.64,1)` | 点赞/完成过冲反馈(唯一弹性) |
| `mk-shimmer` | 背景扫光 1.8s linear | 加载占位 |
| `mk-overlay-in` / `mk-modal-in` | 140ms fade / 160ms fade+translateY(6px)+scale(.99) | 弹层进入 |
| `mk-panel-grow` | flex-grow 过渡 200ms ease-out(用时挂、transitionend 摘) | 面板开合 |
## 9. 组件范式
### 9.1 工具调用块(ToolBlock 契约,参照 ZCode ToolLayout)
单行摘要:`[图标][工具名][主文本][副文本][状态词]`。
- 运行中:工具名文字扫光(`mk-sweep`),状态词最弱色;**不用旋转图标**(长流式期省渲染);
- 完成默认收起;`autoOpen`(如 edit/read 类)运行时自动展开一次,用户可再收起;
- 完成边沿(running→completed)自动收起一次,不阻止用户手动展开;
- 展开态按 id 记忆,切回不丢;
- 失败不强制展开:状态词虚线下划线,hover tooltip 给报错,支持一键复制;
- 内容懒渲染,收起后延迟卸载(300ms,配合高度动画)。
- 模型、卡片和文档里的 HTML 只经 `@ui` `safeHtml` 写入。外部图片和音视频不直接加载,改成带来源域名的链接;同源地址、`data:image` 和 `blob:` 照常显示。
### 9.2 折叠(@ui Collapsible 原语)
一切折叠区(过程输出、长回复、任务卡)用它:外壳高度动画 + 内容 fade 两层分离、
300ms 延迟卸载、展开态记忆。禁止再写 `<details>` 折叠。
### 9.3 一个动作一个入口
同一对象只允许一个主要操作路径:一个工件 = 一个预览落位(第三栏「文件」入口)+ 预览
工具栏上的一个下载。对话里的文件卡片负责打开这个预览;卡片菜单里的下载是同一下载动作
的就近入口,不另开预览器。全屏 overlay 是文件预览的放大,不是第二落位。禁止弹窗套弹窗。
### 9.4 按钮
Primary(`--primary` 反色)、Ghost(透明,hover 出表面)、Danger(语义红)。
同一面板内保持动作层级,不把每个动作都升为 primary。
### 9.5 菜单与浮层
菜单壳 `--radius`(8) + `--shadow-md` + 紧凑行(`--radius-sm` 6 的行、`--fs-ui-base`);
菜单是紧凑动作行,不是迷你按钮。交互浮层必须盖过被动 tooltip。
### 9.6 工作时间线与标签条
助手消息默认先展示结论、必要确认与文件;工作状态用一行说明,技术执行记录按需展开。
- 默认运行中过程块也收起;块头是用户可理解的工作阶段,带 `mk-sweep`。用户手动展开或关闭自动折叠设置时可查看执行记录。
过程解说、已有的思考文本、工具调用与输出保留在同一轮折叠记录中;以已保存消息的顺序和内容为准,事件只补齐缺失输出与协作进展,不覆盖已保存文字。思考文本只在用户主动展开后可读,不作为最终结论。
查阅和搜索合并成一行;执行、写入、委派每次一条 ToolBlock:
编写参数时显示「编写中」和脚本尾部,运行时显示计时和输出尾部,结束后可展开看完整参数与结果。
终轮检查在过程区单独一行(通过,或未通过及原因),不写进给用户的回复。
- 终轮结束后,过程段收进 Collapsible,触发行为「已工作 X 分 Y 秒 · N 次工具调用 · N 个文件」。
用户在运行中手动折过的,结束后沿用这次选择。最终回复(终轮正文、交付物、错误)留在折叠行下面;
交付物卡片等到最终回复出来、这一轮结束后才出现,工作过程中不挂预览条。
若这次没有终轮正文,把最后一段解说提到折叠行下面,不把回复藏进过程里。
折叠区展开时按会话和 run 归属分页读取已保存的事件,补齐终态消息不带回的工具输出与子任务进展/结果;
读取失败时明确说明并只展示已有摘要,不暗示完整记录可用。旧记录缺失的内容不凭前端重造。
不在每一轮 `responding` 时来回折叠。同一轮同名工件只留最新一张,并注明更新次数。
- 文件卡片:图标、名称、「类型 · 大小」、右侧「预览」。正文里的 `art_` 编号若对得上工件,在正文后补一张卡片;
对不上则显示「未找到该文件」,不伪装成可打开的文件。
- 标签条用 `@ui` `TabStrip`:点击激活、× 关闭、中键关闭,溢出横向滚动。只消费令牌与 `mk-*`。
## 10. 信息架构与文案
- 普通用户界面只暴露任务与对话;插件/代理/治理类能力归系统管理区(管理员可见)。
- 右栏收起时功能零缺失(D31:弹层不承载唯一步骤,每个操作另有对话内路径)。
- 中文文案:动宾结构、不带句点结尾;快捷键用 `⌘`/kbd 标注。
- 布局按 `--text-expansion`(1.3)给按钮和标签留膨胀空间。不要把宽度定死成当前中文的字数。截断不是唯一生存手段。
### 10.1 快捷键
| 动作 | 按键 |
|---|---|
| 新建任务 | ⌘N / Ctrl+N |
| 折叠或展开左栏 | ⌘B / Ctrl+B |
| 打开第 n 个工作区 | ⌘1–9 / Ctrl+1–9 |
## 11. 禁止清单(守护测试覆盖项)
1. 组件/样式文件里新增裸色值(hex/rgb 字面量)——走令牌;
2. 组件文件里私有 `@keyframes`——走 MotionKit;
3. TSX 行内 `font-size`——走字号标尺;
4. 运行态用旋转 spinner——用 `mk-sweep`/`mk-breathe`;
5. 弹窗套弹窗;
6. 同一对象出现第二个预览落位(预览只在预览区,全屏是它的放大);
7. `<details>` 折叠——用 Collapsible。
8. 绕过 `safeHtml` 直接把 HTML 字符串写进页面(`dangerouslySetInnerHTML` 或非空的 `innerHTML` 赋值)。
9. 文字与背景的对比度低于门槛(正文与文字档 4.5:1,装饰 faint 与图形语义色 3:1)——`contrast-guard.test.ts`。
## 12. 演进规则
改风格须在**同一变更集**中成对修改:UI 仓 PR 调整 `tokens.css`(必要时 `motion.css`),
Dev 组合 PR 更新 `DESIGN.md` 并固定对应 UI 提交;两者互链,附前后值对照并验证精确组合。
不允许只改代码不改文档。新增视觉规则先问:它属于结构、表面、交互还是状态?
拿不准时,选更安静的方案、用更强的信息层级。
### 12.1 对比度与字号(2026-10-05)前后值
| 令牌 | 之前 | 之后 |
|---|---|---|
| `--text-dim` | 三主题 62% | 深 66% / 浅 68% / 墨绿 70% |
| `--text-faint` | 深 38% / 浅与墨绿 42% | 深 52% / 浅与墨绿 58% |
| `--text-sidebar-dim` / `faint`(墨绿) | 72% / 46% | 78% / 62% |
| `--warn`(浅色、墨绿) | `#e07b00`(白底 2.99:1) | `#d17300` |
| `--fs-ui-xs` | −4px(10px) | −3px(11px),仅徽标 |
| 文字档 `*-text`、`--text-on-semantic`、`--accent-sidebar`、`--primary-sidebar`、`--fs-code`、`--idle-text` | 无 | 见 §2.4–§3。图形色不再当文字用 |
### 12.2 三栏工作台信息架构(2026-10-11)
布局与入口收敛(无令牌变更,仅消费既有令牌):预览从「对话与右栏之间的独立第四栏」
并入第三栏「文件」入口(原「打开预览收起右栏」行为随之取消);左栏改为项目切换置顶、
会话与搜索居中、文件/工作区/账户沉底;顶栏不再重复项目身份;停止操作收敛到输入区,
输入框上方保留快慢通道轻量状态提示。工件 ⌘1 弹层撤销,文件浏览并入「文件」入口
(代理成为首个内置体系工具)。依据:三栏工作台方案(2026-10-11 评审);
实现为 Frontend `feature/ui-three-column-workbench` 组合变更。
### 12.3 渐进工作台(本次批准的界面设计)
沿用三栏、现有令牌与唯一文件预览。新用户默认浅色、辅助右栏收起,已有主题和布局偏好保留。中栏先给每轮结论,过程、会话设置和消息次要操作按需展开;后台工作通过同一任务卡显示。右栏「工作」打开时,工作卡详细内容与动作只在右栏;中栏保留对话顺序以及必要的定位入口。右栏收起或切到「文件」时,中栏提供完整工作卡。状态和动作只消费服务端已有内容。窄屏单面板提供上下文、对话、工作、文件与返回入口;不丢失同一预览的状态。
这是结构与信息层级调整;UI 仓新增当前工作卡的语义表面令牌,字号、圆角和动效仍使用现有标尺与原语。UI 组件与 Dev 精确 gitlink 组合验证后交付。设计与实施依据见 Documents 的 work-companion-ui-design r0.2 / plan r1,以及本次任务卡 I1。