跳转至

P3.A26.F2-right-dock-4-categories-correction · 右侧 Dock selector 3 类→4 类校正 + DSP 模式 source/sink 自动隐藏

Worker:ClaudeA · 部门:前端 P3-xilink · 预计:1.0d · 优先级:P0 · 状态:dispatched · isolation:🧵 file(同 worktree 同 branch · 与 F1-1/F3-1 文件正交并行)

🔍 触发与解锁链

触发:用户 2026-06-18 16:50 accept ADR-AIOS-26 + 16:55 三连 start · 与 F1-1/F3-1 文件正交并行起手。

用户原话(verbatim · ADR-26 §1.1 第 1 轮 第 3 段):

"右侧 dock 中大部分应该走的 sidecar · 右侧可观察的节点只有 source · sink · 输入输出设备 · logmodule · 如果是 PC 模式 · 这些都是音频文件可获取;如果是 DSP 模式那 source 和 sink 就不可获取 · 那右侧就只能显示 logmodule 和输入输出设备"

架构契约(ADR-26 §3.3 4 类节点矩阵 · 业务契约 5 必填段): - 契约 A · 4 类节点:type RightDockNodeKind = 'source' | 'sink' | 'input-device' | 'output-device'(校正 ADR-21-R1 的 3 类归并 input/output/log_module · log_module 由 §3.6 Meter Dock 横切追踪覆盖 · 不在右侧 Dock 独立节点) - 契约 B · DSP 模式可见性:RuntimeKind=DspHardware 时 source + sink 自动隐藏/灰(disabled)· 输入设备 + 输出设备永远可见 · RuntimeKind=PcNative/PcSimulator 时 4 类全亮 - 契约 C · 节点 selector 标签:中文化 source=源/sink=汇/input-device=输入设备/output-device=输出设备(i18n key) - 契约 D · 5 种分析右键菜单:每个节点单击右键含 fft/rms/phase/scope/transfer 5 种分析(走链路 2 sidecar · 与 ADR-21-R1 popup 体系兼容) - 契约 E · 数据 tap:source/sink 走 GET /source/{id}/pcm-fork + GET /sink/{id}/pcm-fork(ADR-21-R1 F1 c780836 已落地 · 不重写)· 输入/输出设备走 GET /devices/wasapi/{id}/capture(ADR-21-R1 F1 已落地) - 5 类失败回退(ADR-26 §3.3 ③):pcm-fork 异常→toast / sidecar HTTP 504→loading + 30s / DSP 强行点 source→toast 校验 / WASAPI 拔出→自动恢复 / 大量请求→队列限流

解锁链(本任务 zombie 后): - ✅ 4 类节点矩阵在 RuntimeKind 切换下正确显示/隐藏(独立 fork · 不解锁其他 fork) - ⏳ F4-1 P_e2e.A26.F4-truth-e2e-meter-dual-link(ClaudeC 1.5d · blocked-by-F1-1+F1-2+F2-1+F3-1+F3-2 五齐)→ ADR-26 整体闭环 🏆

任务定义(基于 ADR-26 §3.3 + §2.4 + §4.1 F2-1)

子任务 ① · grep 现有右侧 Dock 真值 + 评估 ADR-21-R1 F1 c780836 supersede 范围(0.2d · Step 0)

Step 1.1:git show c780836 --stat 列出所有改文件 · 重点对照 ADR-21-R1 §3.1 selector 3 类归并逻辑(input/output/log_module · source 与 sink 归并到 input/output)。grep frontend_vue3/src/stages/xilink/drawers/RightDock*.vue + composables/useChainNodeMetadata.ts 确认现有 3 类 selector 实现位置。

Step 1.2:read useChainNodeMetadata.ts 全文 · 找出 selector 类别派生逻辑(应有 categorize(node) 或类似函数返回 3 类)· 评估改 4 类的最小改动面。

子任务 ② · selector 3 类→4 类逻辑改写(0.3d)

Step 2.1:在 useChainNodeMetadata.tsRightDockNodeKind:

// 原(ADR-21-R1):type SelectorKind = 'input' | 'output' | 'log_module'
// 新(ADR-26):
export type RightDockNodeKind = 'source' | 'sink' | 'input-device' | 'output-device'

export function categorizeNode(node: ChainNode): RightDockNodeKind | null {
  if (node.type === 'source') return 'source'
  if (node.type === 'sink') return 'sink'
  if (node.kind === 'input-device') return 'input-device'
  if (node.kind === 'output-device') return 'output-device'
  return null  // log_module / 普通 module 不在右侧 Dock(由 §3.6 横切追踪覆盖)
}

Step 2.2:删除 ADR-21-R1 c780836 的 source+sink 归并到 input/output 的逻辑(若存在)· 改为独立 4 类。

子任务 ③ · DSP 模式 source/sink 自动隐藏(0.2d)

Step 3.1:在 RightDock*.vue 模板加 v-if="canShowNode(kind, runtimeKind)":class="{ disabled: !canShowNode(...) }" 条件渲染:

// useChainNodeMetadata.ts 加 helper
export function canShowNode(kind: RightDockNodeKind, runtimeKind: RuntimeKind): boolean {
  if (runtimeKind === 'DspHardware' && (kind === 'source' || kind === 'sink')) return false
  return true
}

Step 3.2:RightDock*.vue 监听 runtimeKind ref(从 store 或 useRuntime composable 取)· 切换时自动重渲染。

子任务 ④ · i18n 中文化 + 测试 + 全测试基线零回归(0.3d)

Step 4.1:在 i18n key(zh-CN/en)加 4 类标签:source=源/sink=汇/input-device=输入设备/output-device=输出设备(若项目有 i18n 体系)· 否则用直接中文字符串。

Step 4.2:useChainNodeMetadata.spec.ts 加 ≥ 5 case: - T1 categorizeNode source 节点 → 'source' - T2 categorizeNode sink 节点 → 'sink' - T3 categorizeNode 输入设备 → 'input-device' - T4 categorizeNode 输出设备 → 'output-device' - T5 canShowNode(source, DspHardware) === false / canShowNode(input-device, DspHardware) === true

Step 4.3:RightDock*.vue 组件测试 ≥ 2 case: - T6 RuntimeKind=PcNative 时 4 类节点全显示 - T7 RuntimeKind=DspHardware 时 source/sink 隐藏(或 disabled class)· 输入/输出设备显示

Step 4.4:vue-tsc --noEmit 0 errors · npm run build 0 errors · npm run test 全测试基线零回归(前端基线 356/3 · +5 + 2 = 363)。

子任务 ⑤ · 浏览器实测(可选 · 配合 mock RuntimeKind)+ commit(0.0d 内含)

Step 5.1:启动 backend(若 F1-1 zombie 后可联调真 RuntimeKind 切换 · 否则 mock)+ frontend(npm run dev)· 切到 xilink stage · 观察右侧 Dock: - PcNative 模式:4 类节点全亮 - DspHardware 模式:source/sink 灰/隐藏 · 输入/输出设备保持亮

完整 prompt(直接复制粘贴 ClaudeA 终端)

[U-thread] P3.A26.F2-right-dock-4-categories-correction · ADR-26 §3.3 + §2.4 + §4.1 F2-1
[部门] 前端 P3-xilink
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies] P3.K-shared-xilink-right-dock + P3.K-shared-chain-node-metadata
[优先级] P0(1.0d · 与 F1-1/F3-1 文件正交并行)
[ADR] docs/08-implementation/40-aios/ADR/ADR-AIOS-26-meter-dual-link-runtime-target-tri-stage.md(必读 §3.3 4 类节点矩阵 + §2.4 ADR-21-R1 3 类→4 类校正 + §4.1 F2-1 + §5 风险表第 3 行)
[isolation] file(同 worktree 同 branch · frontend_vue3 范围内改 RightDock*.vue + useChainNodeMetadata.ts + spec)

[参考文档绝对路径]
  - 业务契约:ADR-26 §3.3 完整 5 必填段(① TS 4 类 enum / ② 节点矩阵 PC vs DSP / ③ 5 类失败回退 / ④ 5 步操作流 / ⑤ playwright e2e 4 类节点矩阵+DSP 隐藏)
  - 用户 2026-06-18 12:30 verbatim 第 1 轮 第 3 段(ADR-26 §1.1):"右侧可观察的节点只有 source · sink · 输入输出设备 · logmodule · DSP 模式那 source 和 sink 就不可获取"
  - 用户 2026-06-18 16:50 拍板 accept ADR-AIOS-26 + 16:55 三连 start
  - 教训承接标本(必读避坑 · ADR-26 §9):
    * §9.3 校正 ADR-21-R1 3 类→4 类(supersede 局部 · 主体保留)· 不整体废弃 · 类比 ADR-25-R1 §2.2/§2.3 资产保留矩阵
  - 范式 commits(worker 必读 · 强制 read 全文对齐格式):
    * P3.UA25R1.F1--0bb4422(2026-06-18 v3.0 标本 · ClaudeA combo hotfix · 8 段格式 + 七元组完美对齐)
    * P1.UA21R1.F1--c780836(同 ClaudeA 前端 xilink dock · 本 fork 局部 supersede 标本 · 必须 git show 完整 read 评估归并逻辑 revert 范围)

[现有组件 grep 真值(.clinerules v3.0 ADR-23→25→25-R1 三连教训铁律 · 派发前部分锚定 · Step 0 强制 grep 完整核查)]
  ① ADR-21-R1 F1 c780836 落地范围(Step 0 强制 git show c780836 --stat 完整 read):
     - DockHost selector 5→3 类归并逻辑(source 与 sink 归到 input/output)→ 本 fork 改 4 类隔离
     - 修 nodeRef WS endpoint 数据 tap bug → 本 fork 不动(已正确)
  ② frontend_vue3/src/composables/useChainNodeMetadata.ts:
     - 现有 categorize/categorizeNode 函数(ADR-21-R1 落地 3 类 · 本 fork 改 4 类)
     - 类型 SelectorKind / RightDockNodeKind(改名 + 4 值)
  ③ frontend_vue3/src/stages/xilink/drawers/RightDock*.vue(具体文件 Step 0 grep · 推测 RightDockSelector / RightDockHost 等):
     - selector 渲染逻辑(消费 categorizeNode)
     - RuntimeKind 监听点(若不存在则新增 useRuntime composable 接入)
  ④ ADR-26 §2.4 修订理由:用户 2026-06-18 15:45 verbatim "右侧 dock 不会有专门的 log module" · log_module 由 §3.6 Meter Dock 内部横切追踪覆盖
  ⑤ ADR-26 §4.3 文件正交矩阵:本 fork 与 F1-1(backend Runtime)+ F3-1(frontend LogModuleNode + backend LogModuleRoutes)100% 文件正交

[文件正交策略](.clinerules v3.0 §UID 命名铁律 + §isolation):
  isolation: file · frontend_vue3 范围内改 useChainNodeMetadata.ts + RightDock*.vue + spec · 不动 backend / 不动 LogModule* / 不动 RuntimeTarget*(F1-1+F3-1 范围)
  与 F1-1(backend_csharp)+ F3-1(LogModuleNode + LogModuleRoutes)文件 100% 正交 · 三 worker 同时跑零冲突

【背景】
  用户 2026-06-18 12:30 verbatim 第 1 轮 第 3 段明确 4 类右侧 Dock 节点(source/sink/输入设备/输出设备 · log_module 不在独立节点)+ DSP 模式 source/sink 隐藏。
  ADR-21-R1 F1 c780836(2026-06-15 落地)误归并为 3 类(input/output/log_module · source 与 sink 归并)· 本 fork 局部 supersede ADR-21-R1 §3.1 · 仅校正 selector 类别 · 主体保留(双击悬浮窗 + cleanup composable 等不动)· 类比 ADR-25-R1 §2.2/§2.3 资产保留矩阵。
  与 F1-1 后端(NativeSubKind enum)+ F3-1 跨栈(LogModuleNode 双击 Dialog)文件 100% 正交 · 三并行 max=1.5d。
  教训承接(ADR-26 §9.3):局部 supersede 必须逐段标注 · 不整体废弃 · ADR-21-R1 主体功能保留(本 fork 仅改归并逻辑 + 加 DSP 隐藏)。

【架构关键约束】
  ⚡ 严守 .clinerules v3.0 ADR-23→25→25-R1 三连教训铁律:用户原话名词 grep 真值锚定(Step 0 git show c780836 + read useChainNodeMetadata.ts 全文)
  🎨 ADR-21-R1 主体保留:nodeRef WS endpoint tap bug 修复(c780836)+ 双击悬浮窗(57474b0/5d69270)+ useDockMeterFrame composable(d453822)全部不动
  📋 selector 改 4 类:source/sink/input-device/output-device(中文标签 源/汇/输入设备/输出设备)· log_module 移出 selector(由 §3.6 Meter Dock 横切追踪覆盖)
  📋 DSP 模式可见性:RuntimeKind=DspHardware 时 source/sink 自动隐藏(disabled class 或 v-if)· 输入/输出设备永远可见
  📋 数据 tap 路径不动:source/sink 走 GET /source(or sink)/{id}/pcm-fork(c780836 已落地正确)· 输入/输出设备走 GET /devices/wasapi/{id}/capture
  📋 三层分工(ADR-07 §1.3.4):L3 前端纯 UI 行为修改 · 不做 DSP 数学 · 不动后端 service
  🚫 严禁动 ADR-21-R1 c780836 的 nodeRef WS endpoint tap 修复部分(只动归并逻辑)
  🚫 严禁动 PhaseModulePopup / TransferModulePopup / FftModulePopup(F4-R1/F6-R1 资产)
  🚫 严禁动 useDockMeterFrame composable(d453822 资产)
  🚫 严禁动 backend / log_module / Runtime(F1-1/F3-1 范围)
  🚫 严禁创建新 selector 5+ 类(用户原话明确 4 类 · log_module 不在 selector)

【执行步骤】
  Step 0 · 文件注入真值核查 + ADR-21-R1 F1 c780836 supersede 评估(强制门槛 · ADR-26 §9.3 教训承接)
    - git show c780836 --stat · 列出所有改文件 + 行数
    - git show c780836 -- frontend_vue3/src/composables/useChainNodeMetadata.ts(若该文件在 c780836 范围内)· 完整 read · 找 source 与 sink 归并到 input/output 的逻辑代码段
    - read frontend_vue3/src/composables/useChainNodeMetadata.ts 全文 · 确认 categorize/categorizeNode 函数 + SelectorKind 类型
    - grep "RightDock" frontend_vue3/src/stages/xilink/drawers/ · 列出所有 RightDock*.vue 文件 + 用法
    - read 1-2 个主要 RightDock*.vue · 确认 selector 渲染消费点 + RuntimeKind 监听点(若无则定位接入位置)
    - grep "RuntimeKind\|useRuntime\|runtimeStore" frontend_vue3/src/ · 确认 RuntimeKind 在前端的获取方式
    - 留 commit log:Step 0 六层核查记录 + ADR-21-R1 c780836 归并逻辑 supersede 范围结论

  Step 1 · selector 3 类→4 类逻辑改写 0.3d(子任务 ②)
    - 改 useChainNodeMetadata.ts SelectorKind → RightDockNodeKind 4 值('source' | 'sink' | 'input-device' | 'output-device')
    - 改 categorizeNode 函数:source 节点 → 'source' / sink 节点 → 'sink' / input-device → 'input-device' / output-device → 'output-device' / 其他(log_module 等)→ null(不在 selector)
    - 删除 ADR-21-R1 c780836 的 source+sink 归并到 input/output 的逻辑(若存在)
    - 加 helper canShowNode(kind, runtimeKind):DspHardware + (source|sink) → false · 其他 → true

  Step 2 · DSP 模式 source/sink 自动隐藏 0.2d(子任务 ③)
    - 修主要 RightDock*.vue 组件:加 v-if="canShowNode(kind, runtimeKind)" 或 :class="{ disabled: !canShowNode(...) }" 条件渲染
    - 监听 runtimeKind ref(从 useRuntime composable 或 store 取)· 切换时自动重渲染
    - selector 标签中文化(若项目有 i18n 体系则加 key · 否则直接中文字符串)

  Step 3 · 测试 + 全测试基线零回归 0.3d(子任务 ④)
    - useChainNodeMetadata.spec.ts 加 ≥ 5 case(T1-T5 见任务定义子任务 ④)
    - RightDock*.vue 组件测试 ≥ 2 case(T6/T7 RuntimeKind 切换可见性)
    - vue-tsc --noEmit 0 errors
    - npm run build 0 errors
    - npm run test 全测试基线零回归(前端基线 356/3 + 5 + 2 = 363)

  Step 4 · 浏览器实测 0.2d(子任务 ⑤ · 含在 1.0d 内)
    - 启动 backend + frontend(若 F1-1 已 zombie 可真切 native+VDSP · 否则 mock RuntimeKind)
    - 切到 xilink stage · 观察右侧 Dock:
      ☐ PcNative 模式 4 类节点全亮(source/sink/输入设备/输出设备)
      ☐ DspHardware 模式 source/sink 隐藏(或 disabled)· 输入/输出设备保持亮
      ☐ source/sink 节点单击右键含 5 种分析(fft/rms/phase/scope/transfer)
      ☐ log_module 节点不在 selector(已移出 · 由 §3.6 Meter Dock 横切覆盖 · F3-2 后续)
      ☐ ADR-21-R1 双击悬浮窗(phase/transfer)行为零回归
    - git add . && git commit -m "fix(xilink/right-dock): P3.A26.F2 selector 3 类→4 类校正 + DSP 模式 source/sink 隐藏

      用户 2026-06-18 16:50 拍板 accept ADR-AIOS-26 + 16:55 三连 start(F1-1+F2-1+F3-1 文件正交 max=1.5d)。
      F2-1 本 fork(ADR-26 §3.3 + §2.4 + §4.1):
      ① useChainNodeMetadata.ts SelectorKind → RightDockNodeKind 4 值(source/sink/input-device/output-device)
      ② categorizeNode 改 4 类映射 · log_module 返回 null(由 §3.6 Meter Dock 横切覆盖 · 不在 selector)
      ③ canShowNode helper:DspHardware + (source|sink) → false · 其他 true
      ④ RightDock*.vue 加 v-if/disabled 条件渲染 + 监听 RuntimeKind ref
      ⑤ i18n 中文化(源/汇/输入设备/输出设备)
      ⑥ vitest +5+2 case 全过 · vue-tsc + build 全绿 · 全测试基线零回归

      局部 supersede ADR-21-R1 §3.1 selector 3 类归并(c780836 source+sink 归到 input/output)
      ADR-21-R1 主体保留:nodeRef WS tap 修复(c780836 部分)+ 双击悬浮窗(57474b0/5d69270)+ useDockMeterFrame(d453822)全部不动
      ADR-23→25→25-R1 三连教训承接:局部 supersede + 资产保留矩阵(类比 ADR-25-R1 §2.2/§2.3)

      [step=4/4] [pid=P3] [uid=P3.A26.F2-right-dock-4-categories-correction] [type=fork] [isolation=file]
      [occupies=P3.K-shared-xilink-right-dock+chain-node-metadata] [files=3-4(2-3M+1S)] [ipc=none]
      [adr=ADR-AIOS-26 §3.3 + §2.4 + §4.1 F2-1 + 用户 2026-06-18 12:30 第 1 轮 第 3 段 verbatim + 16:50 accept]"

【验收】
  ☐ Step 0 文件注入真值核查通过(git show c780836 + read useChainNodeMetadata.ts + grep RightDock + grep RuntimeKind · commit log 留痕)
  ☐ Step 1 SelectorKind → RightDockNodeKind 4 值 · categorizeNode 改 4 类 · log_module 返回 null(移出 selector)
  ☐ Step 2 DSP 模式 source/sink 自动隐藏(canShowNode helper + RuntimeKind 监听)· PC 模式 4 类全亮
  ☐ Step 3 vitest +5+2 case 全过 · vue-tsc + build 0 errors · 全测试基线零回归(356/3 → 363/3)
  ☐ Step 4 浏览器实测 5 验收点全过(4 类全亮 + DSP 隐藏 + 5 种分析菜单 + log_module 移出 + 双击悬浮窗零回归)
  ☐ commit message 含 7 元组 trailer + ADR-26 §3.3 + §2.4 + §4.1 + 用户 verbatim 引用 + ADR-21-R1 局部 supersede 说明

【禁止】
  ❌ 禁止跳过 Step 0 文件注入真值核查(ADR-26 §9.3 教训 · 必须 git show c780836 评估归并逻辑 supersede 范围)
  ❌ 禁止动 ADR-21-R1 c780836 的 nodeRef WS endpoint tap 修复部分(只动归并逻辑)
  ❌ 禁止动 ADR-21-R1 双击悬浮窗(PhaseModulePopup 57474b0 / TransferModulePopup 5d69270)
  ❌ 禁止动 useDockMeterFrame composable(ADR-21-R1 d453822 资产)
  ❌ 禁止动 backend_csharp 任何文件(F1-1 范围)
  ❌ 禁止动 LogModuleNode.vue / Routes/LogModuleRoutes.cs(F3-1 范围)
  ❌ 禁止动 RuntimeTarget* 后端(F1-1 范围)
  ❌ 禁止创建 5+ 类 selector(用户原话明确 4 类 · log_module 不在 selector)
  ❌ 禁止跳过 vitest +5+2 case(T1-T7 验收硬门槛)
  ❌ 禁止 commit 缺七元组 trailer(.clinerules v3.0 铁律)
  ❌ 禁止嵌入完整 Vue SFC > 60 行 / TS interface > 5 行(.clinerules v3.0 · 用 diff 模式提交)

解锁链(本任务 zombie 后)

  • ✅ 右侧 Dock 4 类节点矩阵正确(source/sink/输入设备/输出设备)
  • ✅ DSP 模式 source/sink 自动隐藏(用户 verbatim 落地)
  • ✅ ADR-21-R1 §3.1 selector 归并逻辑局部 supersede(主体功能零回归)
  • ✅ log_module 移出右侧 Dock(为 F3-2 §3.6 Meter Dock 横切追踪铺路 · 待 F3-1 zombie 后 F3-2 起手)
  • ⏳ F4-1 P_e2e.A26.F4-truth-e2e-meter-dual-link 部分解锁(还需 F1-1+F1-2+F3-1+F3-2 全 zombie · 五齐后 ready · ClaudeC 1.5d → ADR-26 整体闭环 🏆)

风险评估

风险 缓解
ADR-21-R1 c780836 归并逻辑 supersede 评估不准(可能漏改某处) Step 0 强制 git show c780836 完整 read · 列出所有改文件 + grep source/sink 归并代码段 · 评估 revert 边界(ADR-26 §5 风险表第 3 行)
RightDock*.vue 文件名未确定(prompt 中标 TBD by Step 0 grep) Step 0 grep "RightDock" frontend_vue3/src/stages/xilink/drawers/ 强制定位 · 不允许凭推测起草改动
RuntimeKind 监听点缺失(前端可能没有 useRuntime composable) Step 0 grep RuntimeKind / useRuntime / runtimeStore 全前端 · 若无则评估接入方式(可能新建 useRuntime composable · 或读后端 GET /api/runtime/active · 待 F1-1 zombie 后联调真值)
ADR-21-R1 主体功能(双击悬浮窗 / cleanup composable)被误改 禁止段 ≥ 7 项明确禁止动 PhaseModulePopup/TransferModulePopup/FftModulePopup/useDockMeterFrame · 严守 ADR-21-R1 资产保留矩阵
log_module 移出 selector 后 · 用户期望仍能看到 log_module(混淆) log_module 仍在链路中(双击落盘 §3.5 由 F3-1 实施)+ 各 Meter Dock 内追踪(§3.6 由 F3-2 实施)· 仅 selector 不显示 · commit message + UI 引导文案明确说明
i18n 中文化破坏 en 语言包 加 key 同步 zh-CN + en 双向 · 若项目无 i18n 体系则用直接中文(本 fork 不引入新 i18n 依赖)
浏览器实测时 F1-1 未 zombie · RuntimeKind 切换无后端支持 mock RuntimeKind = 'DspHardware' / 'PcNative' 测试 UI 行为 · F1-1 zombie 后再做完整 e2e(F4-1 范围)
ClaudeA 排队膨胀(本 1.0d + F8 ADR-15 0.5d 收尾 + 后续 F1-2 2.0d + F3-2 1.5d) 本 fork 与 F1-1/F3-1 三并行 max=1.5d 已优化 · F1-2 等 F1-1 zombie 后接 · F3-2 等 F3-1 zombie 后接 · 串行队列约 5.0d

历史

时间 事件 hash
2026-06-18 17:00 dispatched(用户 16:50 accept ADR-AIOS-26 + 16:55 三连 start · 与 F1-1/F3-1 文件正交并行 1.0d · 局部 supersede ADR-21-R1 §3.1)