docs(plan): private-board restrictions + scheme B bubbles plan ready

Plan document finalized after 4 rounds of ce-doc-review:
- F4-A exclusion list extended from 5 to 9 card-bearing types
- Verified root class names for all 9 card components
- Corrected chrome description (2 full chrome + 7 partial chrome)
- Added U1 modal focus restoration note (WAI-ARIA)
- Documented R4-DA1/R4-A3/R4-A4 as Open Questions for implementation
This commit is contained in:
chiguyong 2026-07-03 01:14:37 +08:00
parent 6826ceb2a9
commit 981a794a54
1 changed files with 42 additions and 10 deletions

View File

@ -8,7 +8,7 @@ status: ready
## Summary
收尾私董会(@board模块的 UI 细节与单会话状态约束,四处协同改动:(1) 在 `ChatInput.vue` 的"私董会"按钮 click 处拦截"当前会话已存在进行中的私董会"场景,弹 a-modal 提示并提供快捷新建会话按钮;(2) 将 `BoardBannerCard.vue` 从带边框/紫条/进度条/专家 chip 的重样式简化为单行标题+副标题;(3) 给 `MessageShell.vue` 中所有 `role === 'assistant'` 的消息内容添加方案 B 风格的浅灰圆角矩形气泡F1-A 独立 token / F4-A 排除 conclusion / D4-方案1 `:empty` 隐藏);(4) 将 `UserBubble.vue` 普通文本消息改为 demo 中的深色右对齐气泡(`--color-primary` + `--text-inverse`@board/@team 命令卡片保持现有浅色背景。改动范围仅限前端 Vue 组件与少量 store/type/token 文件,不动后端、不动方案 B 调色板、不动 StickyModeHeader 顶部条。
收尾私董会(@board模块的 UI 细节与单会话状态约束,四处协同改动:(1) 在 `ChatInput.vue` 的"私董会"按钮 click 处拦截"当前会话已存在进行中的私董会"场景,弹 a-modal 提示并提供快捷新建会话按钮;(2) 将 `BoardBannerCard.vue` 从带边框/紫条/进度条/专家 chip 的重样式简化为单行标题+副标题;(3) 给 `MessageShell.vue` 中所有 `role === 'assistant'` 的消息内容添加方案 B 风格的浅灰圆角矩形气泡F1-A 独立 token / F4-A 排除所有 card-bearing 类型 / D4-方案1 `:empty` 隐藏);(4) 将 `UserBubble.vue` 普通文本消息改为 demo 中的深色右对齐气泡(`--color-primary` + `--text-inverse`@board/@team 命令卡片保持现有浅色背景。改动范围仅限前端 Vue 组件与少量 store/type/token 文件,不动后端、不动方案 B 调色板、不动 StickyModeHeader 顶部条。
## Problem Frame
@ -38,9 +38,9 @@ status: ready
- R9`MessageShell.vue` 的 `.message-shell__content``background: var(--bg-message-bubble)` + `border-radius: var(--radius-md)` + `padding: var(--space-3) var(--space-4)` + `border: 1px solid var(--border-color)` + `color: var(--text-primary)`,仅 `role === 'assistant'` 时生效。**F1-A 决策**:引入独立 token `--bg-message-bubble`light `#ffffff` / dark `#1f1f1f`),与 `--bg-secondary`inline code/table 背景)解耦,避免气泡背景与代码/表格背景视觉冲突
- R10不使用 `!important`,不覆盖代码块/表格/路由 tag 样式
- R11不影响 `BoardRoundCard``AssistantText` 渲染
- R12私董会专家发言、普通 chat、@team 阶段、Debate 等都通过 `MessageShell + AssistantText` 统一获得气泡
- R12私董会专家发言、普通 chat 通过 `MessageShell + AssistantText` 统一获得气泡;@team 阶段使用 `TeamPlanCard`、Debate 使用 `DebateArgumentCard`/`DebateSummaryCard`/`DebateBannerCard` 等自带 card chrome 的组件(通过 `MessageShell` 渲染但不走 `AssistantText`),由 R14 排除气泡
- R13气泡宽度继承现有 `width: 100%; max-width: 100%`,不强制固定最大宽度
- R14**F4-A 决策**:气泡选择器排除 `board_conclusion` 类型——`BoardConclusionCard` 自带 card chromebackground/border/border-radius/shadow保留其自身样式不再被气泡包裹。实现方式`MessageShell.vue` 通过 `messageType` prop 或 `:not(:has(.board-conclusion-card))` 选择器排除
- R14**F4-A 决策Round 4 扩展)**:气泡选择器排除所有自带 card chrome 的 assistant 消息类型(共 9 种):`board_conclusion``BoardConclusionCard` → `.board-conclusion-card`full chromebg + border + radius + shadow、`team_plan``TeamPlanCard` → `.team-plan-card`full chrome、`debate_banner``DebateBannerCard` → `.debate-banner`partial chromebg + left-border + radius、`debate_argument``DebateArgumentCard` → `.debate-argument`partial、`debate_summary``DebateSummaryCard` → `.debate-summary`partial、`debate_resolved``DebateConclusionCard` → `.debate-conclusion`partial + 4 变体 bg、`collaboration_graph``CollaborationGraphCard` → `.collab-graph`partial、`review_result``ReviewResultCard` → `.review-card`partial + 3 变体 bg、`risk_flagged``RiskFlagCard` → `.risk-card`partial。**chrome 区分Round 4 修正)**:仅 `BoardConclusionCard` + `TeamPlanCard` 有完整 chromebg + border + radius + shadow其余 7 种只有 bg + left-border + radius无 shadow、无 full border。**已验证根 class 名Round 4 R4-F1**:注意 7 种 partial chrome 卡片 root class 名与组件名不匹配,不带 `-card` 后缀(`.debate-banner` / `.debate-argument` / `.debate-summary` / `.debate-conclusion` / `.collab-graph` / `.review-card` / `.risk-card`)。实现方式:在 `MessageShell.vue` 通过 `messageType` prop 或 `:has()` 选择器排除(具体机制依 G3 决策)。**第三种架构替代方案Round 4 R4-A3**:在 `MessageRenderSpec` 接口(`useMessageRenderer.ts:44-48`)新增 `bubble: boolean` 字段,在 renderer 层集中决策是否包裹气泡,避免 messageType prop 污染或 `:has()` 选择器脆弱性——见 Open Questions Round 4。**未来防护Round 4 R4-A4**:新增 card-bearing 类型时需手动加入 F4-A 排除列表,或采用上述 `bubble` 字段方案由 renderer 集中管理——见 Open Questions Round 4
- R15**D4-方案1 决策**:空 slot 内容pre-stream thinking / tool-call-only时气泡不渲染背景——通过 `:empty` 选择器隐藏 `background / border / padding`,仅显示 thinking dots。有内容流入后自动恢复气泡样式
**UserBubble 普通文本深色气泡R16-R19**
@ -55,10 +55,10 @@ status: ready
- **私董会状态判定取 `discussing | concluding`**`BoardState.status` 类型为 `"discussing" | "concluding" | "completed" | "dissolved"`chatStream.ts:65 确认)。`completed | dissolved` 的旧私董会不阻塞新私董会发起,符合 origin R3 要求。
- **"新建会话"按钮流程:`createConversation()` → `selectConversation(newId, true)`** — `createConversation()` 是同步函数chatStore.ts:333 确认),自动设置 `currentConversationId` 但不加载服务端会话;后续 `selectConversation(newId, true)` 强制 reload 确保状态干净。不自动打开 `BoardMeetingModal`,由用户在新会话中再次点击"私董会"按钮继续(见 origin R2
- **BoardBannerCard 简化为单行标题+副标题,不删除组件本身** — 保留 `BoardBannerCard.vue` 文件,仅重构 template + style。`useMessageRenderer.ts` 的 `board_started` 渲染路径不变origin R8保持 streaming 期间与 reload 后视觉一致。
- **气泡样式挂在 `MessageShell.vue` 的 `.message-shell__content` 上,不挂在 `AssistantText.vue`**`MessageShell` 是所有 assistant 消息的统一外壳,挂在这里可一次性覆盖 board_speech / board_summary / 普通聊天 / @team / Debate 等场景origin R12且不影响 `UserBubble.vue` 的 user 消息样式。**board_conclusion 例外**F4-A`BoardConclusionCard` 自带 card chrome,不被气泡包裹。
- **气泡样式挂在 `MessageShell.vue` 的 `.message-shell__content` 上,不挂在 `AssistantText.vue`**`MessageShell` 是所有 assistant 消息的统一外壳,挂在这里可一次性覆盖 board_speech / board_summary / 普通聊天 / @team / Debate 等场景origin R12且不影响 `UserBubble.vue` 的 user 消息样式。**card-bearing 类型例外F4-A Round 4 扩展,共 9 种)**`board_conclusion`/`team_plan`/`debate_banner`/`debate_argument`/`debate_summary`/`debate_resolved`/`collaboration_graph`/`review_result`/`risk_flagged` 渲染的 card 组件自带 card chrome详见 R14,不被气泡包裹。
- **气泡使用 CSS 变量,禁止硬编码** — 新增 `--bg-message-bubble: #ffffff` (light) / `#1f1f1f` (dark) 到 `tokens.css`,与 `--bg-secondary`inline code/table 背景 `#fbfbfa`解耦F1-A 决策。dark mode 自动切换。禁止硬编码 `#f3f4f6` / `#fbfbfa` / `#ffffff` 等值project rules 硬约束)。
- **`role === 'assistant'` 时启用气泡,`role === 'user'` 不启用** — 通过 `.message-shell--assistant .message-shell__content` 选择器限定,避免污染 user 消息的 `UserBubble` 样式。
- **F4-A 排除 conclusion 类型** — `board_conclusion` 消息渲染的 `BoardConclusionCard` 自带 `background: var(--bg-primary)` + `border` + `border-radius: var(--radius-card)` + `box-shadow`,气泡选择器需排除该类型,避免"白卡片嵌套在白气泡里"的视觉冲突。实现方式:在 `MessageShell.vue` 增加 `messageType` prop`:not(:has(.board-conclusion-card))` 选择器conclusion 类型不加气泡样式
- **F4-A 排除所有 card-bearing 类型Round 4 扩展,共 9 种)** — 排除 9 种 card-bearing assistant 消息类型:`board_conclusion`/`team_plan`/`debate_banner`/`debate_argument`/`debate_summary`/`debate_resolved`/`collaboration_graph`/`review_result`/`risk_flagged`。**chrome 区分Round 4 修正)**:仅 `BoardConclusionCard``.board-conclusion-card`+ `TeamPlanCard``.team-plan-card`)有完整 chromebg + border + radius + shadow其余 7 种(`DebateBannerCard`→`.debate-banner`、`DebateArgumentCard`→`.debate-argument`、`DebateSummaryCard`→`.debate-summary`、`DebateConclusionCard`→`.debate-conclusion`、`CollaborationGraphCard`→`.collab-graph`、`ReviewResultCard`→`.review-card`、`RiskFlagCard`→`.risk-card`)只有 bg + left-border + radius无 shadow、无 full border。气泡选择器需排除这些类型避免"card 嵌套在气泡里"的视觉冲突。实现方式:在 `MessageShell.vue` 增加 `messageType` prop`:has()` 选择器card-bearing 类型不加气泡样式。具体机制依 G3 决策。**第三种替代方案**:在 `MessageRenderSpec` 新增 `bubble: boolean` 字段由 renderer 集中决策(见 Open Questions Round 4 R4-A3。**未来防护**:新增 card 类型需手动加入排除列表或采用 `bubble` 字段方案(见 Open Questions Round 4 R4-A4
- **D4-方案1 `:empty` 隐藏空气泡** — 空 slot 内容pre-stream thinking / tool-call-only时通过 `:empty` 选择器隐藏 `background / border / padding`,仅显示 thinking dots 动画。有内容流入后自动恢复气泡样式,无需 JS 判断。
- **U4 仅普通文本消息深色气泡,命令卡片保持浅色**`UserBubble.vue` 同时渲染三种内容(普通文本 / @board|@team 命令卡片 / 文件附件命令卡片含结构化信息header + experts list深色背景会降低可读性。通过 `isPlainText` computed + `.user-bubble--text` modifier 精确限定深色样式仅作用于普通文本,命令卡片和文件附件继承 `.user-bubble` 默认 `--bg-tertiary` 浅色背景。
- **U4 用 `--color-primary` + `--text-inverse` 自动适配 dark mode**`--color-primary` 在 light mode 为 `#1a1a1a`dark mode 为 `#fbfbfa`(浅);`--text-inverse` 反之。user 气泡在 dark mode 下自动反转为浅色背景 + 深色文字,无需额外 dark mode 覆盖。
@ -89,6 +89,7 @@ status: ready
- `await chatStore.selectConversation(chatStore.currentConversationId!, true)`
- 不设置 `showBoardModal.value = true`(让用户在新会话中再次点击)
- "私董会"按钮 `@click` 改为 `handleBoardClick`
- **焦点恢复Round 4 R4-D3**a-modal 关闭时(无论"我知道了"还是"新建会话")需将焦点返回到触发按钮("私董会"按钮),符合 WAI-ARIA modal 对话模式。Ant Design Vue 的 `<a-modal>` 通过 `@cancel` / `@ok` 事件触发关闭,关闭后焦点默认落在 modal 本身;需在 `handleCreateNewConversationForBoard` 和"我知道了"按钮 click 后显式 `nextTick(() => boardButtonRef.value?.focus())`(或使用 autofocus 属性)。新建会话跳转后焦点自然落于新会话输入框,无需额外处理
**Patterns to follow:**
- `ChatInput.vue:63-71``showTeamModal` 模式v-model:open + ref + handleXxxSubmit
@ -164,7 +165,7 @@ status: ready
### U3. MessageShell 浅灰气泡方案B
**Goal:** 在 `MessageShell.vue``.message-shell__content` 上增加方案 B 风格的浅灰圆角矩形气泡样式,仅 `role === 'assistant'` 时生效,使用 CSS 变量绑定dark mode 自动切换。**F1-A 决策**:气泡用独立 token `--bg-message-bubble`(与 inline code/table 的 `--bg-secondary` 解耦);**F4-A 决策**:排除 `board_conclusion` 类型**D4-方案1 决策**:空内容通过 `:empty` 隐藏气泡。
**Goal:** 在 `MessageShell.vue``.message-shell__content` 上增加方案 B 风格的浅灰圆角矩形气泡样式,仅 `role === 'assistant'` 时生效,使用 CSS 变量绑定dark mode 自动切换。**F1-A 决策**:气泡用独立 token `--bg-message-bubble`(与 inline code/table 的 `--bg-secondary` 解耦);**F4-A 决策Round 4 扩展,共 9 种)**:排除所有 card-bearing assistant 类型(`board_conclusion` / `team_plan` / `debate_banner` / `debate_argument` / `debate_summary` / `debate_resolved` / `collaboration_graph` / `review_result` / `risk_flagged`),这些类型由各自 card 组件自带 card chrome2 种 full chrome + 7 种 partial chrome详见 R14**D4-方案1 决策**:空内容通过 `:empty` 隐藏气泡。
**Requirements:** R9, R10, R11, R12, R13, R14, R15
@ -186,7 +187,11 @@ status: ready
padding: var(--space-3) var(--space-4);
color: var(--text-primary);
}
/* F4-A: board_conclusion 类型不加气泡,保留 BoardConclusionCard 自身 card chrome */
/* F4-A: 所有 card-bearing assistant 类型不加气泡(共 9 种Round 4 扩展)。
已验证根 class 名:`.board-conclusion-card` / `.team-plan-card`full chrome含 shadow /
`.debate-banner` / `.debate-argument` / `.debate-summary` / `.debate-conclusion` / `.collab-graph` / `.review-card` / `.risk-card`
7 种 partial chrome仅 bg + left-border + radius无 shadow 无 full border注意 root class 名与组件名不匹配,不带 -card 后缀)。
实现期依 G3 决策扩展选择器或 messageType prop 排除列表 */
.message-shell--assistant.message-shell--conclusion .message-shell__content,
.message-shell--assistant:has(.board-conclusion-card) .message-shell__content {
background: transparent;
@ -220,7 +225,7 @@ status: ready
- 气泡内代码块slot 内含 `<pre><code>` → 代码块背景 `--code-bg` 不被气泡背景覆盖(视觉可区分)
- 气泡宽度:`.message-shell__content` 计算样式 `width: 100%``max-width: 100%`(跟随消息列宽)
- Dark mode切换到 dark mode → `.message-shell__content` 计算样式 `background-color: rgb(31, 31, 31)``--bg-message-bubble: #1f1f1f`
- **F4-A 排除 conclusion**:渲染 `<MessageShell role="assistant" messageType="board_conclusion">` + `BoardConclusionCard` slot → `.message-shell__content` 计算样式 `background-color: transparent``border: none`(不加气泡,`BoardConclusionCard` 自身 card chrome 保留
- **F4-A 排除 card-bearing 类型Round 4 扩展,共 9 种)**分别渲染 `<MessageShell role="assistant" messageType="board_conclusion|team_plan|debate_banner|debate_argument|debate_summary|debate_resolved|collaboration_graph|review_result|risk_flagged">` + 对应 card slot`BoardConclusionCard` / `TeamPlanCard` / `DebateBannerCard` / `DebateArgumentCard` / `DebateSummaryCard` / `DebateConclusionCard` / `CollaborationGraphCard` / `ReviewResultCard` / `RiskFlagCard`)→ 每种类型 `.message-shell__content` 计算样式 `background-color: transparent``border: none`(不加气泡,card 自身 chrome 保留2 种 full chrome + 7 种 partial chrome 详见 R14
- **D4-方案1 空内容隐藏**:渲染 `<MessageShell role="assistant">` + 空 slot → `.message-shell__content` 计算样式 `background-color: transparent``border: none``padding: 0``:empty` 选择器生效)
- **D4-方案1 有内容恢复**:渲染 `<MessageShell role="assistant">` + 非空 slot → `:empty` 不匹配,气泡样式正常应用
- 渲染契约:样式**不**使用 `!important`
@ -230,6 +235,7 @@ status: ready
- 启动 Tauri 客户端,发起普通 chatassistant 消息应有浅灰(实际为 `#ffffff` 纯白,与 `#fbfbfa` 的 inline code 区分)圆角矩形气泡
- 发起私董会专家发言board_speech应有同款气泡
- 发起私董会结论消息board_conclusion应保留 `BoardConclusionCard` 自身 card 样式,**不**被气泡包裹
- 同理验证 `team_plan` / `debate_banner` / `debate_argument` / `debate_summary` / `debate_resolved` / `collaboration_graph` / `review_result` / `risk_flagged` 消息保留各自 card chrome`TeamPlanCard` / `DebateBannerCard` / `DebateArgumentCard` / `DebateSummaryCard` / `DebateConclusionCard` / `CollaborationGraphCard` / `ReviewResultCard` / `RiskFlagCard`**不**被气泡包裹F4-A Round 4 扩展,共 9 种)
- 切换 dark mode气泡背景应自动变为深色`#1f1f1f`
- user 消息(右侧)应显示为 demo 中的深色气泡(`--color-primary` 背景 + `--text-inverse` 白字),@board/@team 命令卡片保持现有浅色背景(见 U4
- assistant 消息在 thinking 阶段(空内容)不应显示空气泡矩形,仅显示三点动画
@ -330,7 +336,7 @@ status: ready
- **F1feasibilityP1— 已决策 F1-A**U3 气泡背景与 inline code/table 背景冲突。**决策**:引入独立 token `--bg-message-bubble`light `#ffffff` / dark `#1f1f1f`)区分气泡背景与 inline code/table 背景(保持 `--bg-secondary: #fbfbfa`)。已固化到 R9、U3 Approach、Key Technical Decisions。**⚠️ Round 2 G5 挑战**`#ffffff` 与 `#fbfbfa` 色差 <1% 低于 JND `#ffffff` `--bg-primary` 相同导致气泡仅靠边框可见——见下方 G5
- **F3feasibilityP2— 已决策 F3-A**U2 删除 `BoardBannerCard``experts` prop 后 `useMessageRenderer.ts:145` 的 fallthrough 风险。**决策**:在 U2 Files 列表中加 `useMessageRenderer.ts`,删除 `board_banner` case 中 `experts` prop 传参。已固化到 U2 Files、U2 Approach、U2 Test scenarios。
- **F4feasibilityP2— 已决策 F4-A**U3 气泡包裹 `BoardConclusionCard` 的嵌套冲突。**决策**:气泡选择器排除 `board_conclusion` 类型,`BoardConclusionCard` 保留自身 card chrome 不被气泡包裹。已固化到 R14、U3 Approach、U3 Test scenarios、Key Technical Decisions。**⚠️ Round 2 G2/G3 挑战**`:has()` 事实错误 + `messageType` prop 选项需 ChatMessage.vue不在 Files——见下方 G2/G3。
- **F4feasibilityP2— 已决策 F4-A**U3 气泡包裹 `BoardConclusionCard` 的嵌套冲突。**决策**:气泡选择器排除 `board_conclusion` 类型,`BoardConclusionCard` 保留自身 card chrome 不被气泡包裹。已固化到 R14、U3 Approach、U3 Test scenarios、Key Technical Decisions。**⚠️ Round 2 G2/G3 挑战**`:has()` 事实错误 + `messageType` prop 选项需 ChatMessage.vue不在 Files——见下方 G2/G3。**⚠️ Round 3 扩展**F4-A 排除列表从 1 种扩展到 5 种(新增 `team_plan`/`debate_banner`/`debate_argument`/`debate_summary`)。**⚠️ Round 4 扩展R4-A1**:进一步扩展到 9 种(新增 `debate_resolved`/`collaboration_graph`/`review_result`/`risk_flagged`),并修正 chrome 描述2 种 full chrome + 7 种 partial chrome。详见 R14 与 Open Questions Round 4。
- **C2coherenceP2— 已应用 safe_auto**R7 表述已修订为"删除 `.board-banner-card` 的重样式background/border/border-radius/box-shadow`__bar / __chip` 等重样式类,保留 `.board-banner-card` 容器(仅 margin/padding+ `__title / __meta` 最小样式"。
- **D4design-lensP2— 已决策 D4-方案1**U3 空内容气泡表现。**决策**:通过 `:empty` 选择器隐藏 `background / border / padding`,仅显示 thinking dots。已固化到 R15、U3 Approach、U3 Test scenarios、Key Technical Decisions。**⚠️ Round 2 G1 推翻**`:empty` 永不匹配AssistantText 总渲染根 div——见下方 G1实现期必须替换方案。
@ -372,9 +378,35 @@ status: ready
- **D4-R2design-lensP2conf 75— U2 简化 banner 缺乏视觉分隔**:删除所有 chrome 后,两行纯文本 bannerfont-md semibold + font-xs tertiary可能融入消息流失去"section divider"作用。BankOutlined 图标删除后无视觉锚点。**待选方案**(a) 保留 2px 左边框 `--accent-board`(匹配私董会身份,克制);(b) 加小色点前缀;(c) 纯排版足够("私董会 —" 文本前缀即锚点)。
#### Round 3 复审新增2026-07-03
**P1 manualorigin scope 边界):**
- **R3-A1scope-guardianP1conf 100— U4 UserBubble 深色气泡超出 origin 范围**origin `docs/brainstorms/2026-07-02-private-board-restrictions-and-scheme-b-bubbles-requirements.md` 的 Key Decisions 明确声明"role === 'user' 的用户消息气泡保留现有 UserBubble.vue 的右对齐独立样式,不加 AssistantText 风格的浅灰块"。但本 plan U4 改动 `UserBubble.vue`,将普通文本消息改为 `--color-primary` 深色背景 + `--text-inverse` 白字的深色气泡R16-R19属于 origin 之外的 scope creep。**待选方案**(a) Drop U4 及 R16-R19保持 origin 不变U3 仍完成 assistant 气泡统一);(b) 保留 U4 但正式 amend origin requirements doc补充"用户普通文本消息改为深色右对齐气泡"决策。建议 (b),因为 U4 视觉冲击显著、demo 已确认方向,但需走 origin amend 流程避免 plan/origin 漂移。
**P2 gated_auto事实修正**
- **R3-F2feasibilityP2conf 50— selectConversation `force=true` 对 local 会话不生效**plan U1 Approach 中关于"切换会话时通过 `selectConversation(force=true)` 强制重新加载消息"的描述有事实偏差。`chatStore.ts:233` 的守卫为 `!conv?.is_local && (force || ...)`,对 `is_local=true` 的会话(含新建会话)会跳过 reload 调用——状态干净实际由 `createConversation` 保证(新建即清空 boardState/selectedExpert 等)。**建议 fix**:在 U1 Approach / Key Technical Decisions 条目中明确归因——"切换会话时 boardState 清空由 `createConversation` 在新建会话时执行;对非 local 会话调用 `selectConversation``force=true` 仍生效"。无需修改代码,仅修正 plan 文档归因。
#### Round 4 复审新增2026-07-03
**已应用auto-resolve 决策汇总):**
- **R4-C1coherenceP1conf 100safe_auto applied** — Lines 58 & 389 "board_conclusion 例外" 已更新为 "card-bearing 类型例外F4-A Round 4 扩展)"
- **R4-F1feasibilityP2conf 75gated_auto applied** — 已验证 9 种 card root class 名并添加到 R14、Key Technical Decisions F4-A、U3 CSS 注释(注意 7 种 partial chrome 卡片 root class 名不带 `-card` 后缀)
- **R4-A1adversarialP1conf 100auto-resolve applied** — F4-A 排除列表从 5 种扩展到 9 种(新增 `debate_resolved` / `collaboration_graph` / `review_result` / `risk_flagged`)。已更新 R14、Key Technical Decisions F4-A、U3 Goal、U3 CSS 注释、U3 Test scenarios、U3 Verification
- **R4-D1design-lensP2conf 100auto-resolve applied** — F4-A card chrome claim 已修正:仅 `BoardConclusionCard` + `TeamPlanCard` 有完整 chromebg + border + radius + shadow其余 7 种只有 partial chromebg + left-border + radius无 shadow 无 full border。已更新 R14、Key Technical Decisions F4-A、U3 CSS 注释
- **R4-D3design-lensP2conf 75auto-resolve applied** — U1 Approach 新增焦点恢复说明a-modal 关闭后焦点返回"私董会"按钮WAI-ARIA modal 对话模式)
**P2 manual待后续处理**
- **R4-DA1design-lens + adversarial cross-persona promoteP2conf 100— 7 种 partial chrome 卡片硬编码浅色dark mode 下与 F4-A 排除气泡后视觉冲突加剧**`DebateBannerCard``#f9f0ff`)、`DebateArgumentCard``#fafafa`)、`DebateSummaryCard``#fff7e6`)、`DebateConclusionCard`4 变体 `#fff7e6`/`#f6ffed`/`#fffbe6`/`#f5f5f5`/`#fff2f0`)、`CollaborationGraphCard``#f0f8ff`)、`ReviewResultCard`3 变体 `#fafafa`/`#f6ffed`/`#fffbe6`/`#fff2f0`)、`RiskFlagCard``#fff7e6`均使用硬编码浅色背景。U3 气泡用 `--bg-message-bubble` token 自动适配 dark mode但这些 card 被 F4-A 排除后dark mode 下仍显示硬编码浅色背景,对比度刺眼。**这是 pre-existing 问题,超出 U3 scope**U3 仅负责气泡,不负责修复 card 颜色)。**建议**:新建独立 unit如 U5: Card Dark Mode Adaptation将这 7 种 card 的硬编码颜色迁移到 CSS 变量,与 U3 并行但不阻塞。或暂记为 follow-up tech debt。
- **R4-A3adversarialP2conf 75— F4-A 遗漏第三种架构替代方案**:当前 G3 决策在 `messageType` prop 与 `:has()` 选择器间二选一。存在第三种方案:在 `MessageRenderSpec` 接口(`useMessageRenderer.ts:44-48`)新增 `bubble: boolean` 字段,在 renderer 层(`ChatMessage.vue`集中决策是否包裹气泡card-bearing 类型在 spec 定义时设 `bubble: false`。**优势**:新增 card 类型时无需改 `MessageShell.vue` 排除列表,避免 R4-A4 的未来防护问题spec 集中管理,单一数据源。**劣势**:需修改 `MessageRenderSpec` 接口和所有 spec 定义点12+ 类型),改动面比 prop/selector 方案大。**建议**:实现期若 G3 二选一难以决断,可考虑此方案作为 tie-breaker否则记为 future refactor 候选。
- **R4-A4adversarialP2conf 75— F4-A 排除列表对未来新增 card 类型无防护**:当前 F4-A 排除列表硬编码 9 种类型,新增 card-bearing 类型时需手动加入 `MessageShell.vue` 排除列表prop 或 selector 方案),否则新 card 会被气泡错误包裹。**与 R4-A3 关联**:采用 `MessageRenderSpec.bubble` 字段方案可从根本上解决renderer 集中决策),但需更大重构。**建议**:若采用 G3 prop/selector 方案,需在 `useMessageRenderer.ts` 新增 card 类型时强制走 code review checklist 验证 F4-A 排除列表是否同步更新;或采用 R4-A3 的 `bubble` 字段方案一劳永逸。
## System-Wide Impact
- **前端用户**:所有 Tauri 客户端和 Web GUI 用户将看到 (a) 私董会按钮在已有私董会的会话中弹提示而非 modal(b) 私董会开始消息显示为简洁两行文本;(c) 所有 assistant 消息有浅灰圆角气泡(`--bg-message-bubble: #ffffff`board_conclusion 例外(保留自身 card(d) thinking 阶段不显示空气泡。视觉变化明显但符合方案 B 整体取向。
- **前端用户**:所有 Tauri 客户端和 Web GUI 用户将看到 (a) 私董会按钮在已有私董会的会话中弹提示而非 modal(b) 私董会开始消息显示为简洁两行文本;(c) 所有 assistant 消息有浅灰圆角气泡(`--bg-message-bubble: #ffffff`card-bearing 类型例外(保留自身 card(d) thinking 阶段不显示空气泡。视觉变化明显但符合方案 B 整体取向。
- **后端/运维**:无影响(不动后端、不动部署、不动配置)。
- **其他团队**:无影响(仅前端 Vue 组件)。