跳转至

P1.UA21R1.F1-dock-selector-3-categories-and-data-tap · 右 Dock 3 类固定节点 selector + 数据 tap 通路修复

Worker:ClaudeA · 前端 (frontend_vue3) / 预计:1.0d / 优先级:P0 / 状态:ready 隔离:🧵 文件隔离(同 worktree 同 branch · ADR-21-R1 fork 1 · supersede F1 a5b52de · 与同期 active fork 文件正交)


🔍 触发与解锁链

触发 状态 影响
用户 2026-06-15 10:24 反馈 4 点框架错误 "右侧 dock 应监控固定节点(source 输出/sink 数据/log module)" + "当前所有右侧 dock 都没有数据更新"
用户 11:21 二次澄清 selector 3 类:input(物理输入+source)/ output(物理输出+sink)/ log_module
用户 11:30 拍板方向 B + 11:30 起 ADR-21-R1 R1 supersede F1/F4/F6 三 fork · 起 4 R1 hotfix
parent supersede zombie F1 a5b52de 5 类 selector(physical-input/sink-pre/log-module/xilink-module/xitune-module)· 后 2 类砍 · 数据 tap WS 路由 bug 必修
Cline-AIOS 4 路真值核查 F1 DockHost 5 类 selector 在 widgetEndpoint.ts 已锁 · nodeRef→WS endpoint 通路具体 bug 根因待 worker Step 0 深查

→ 本 R1 hotfix supersede F1 a5b52de · 不删现有 selector/Drawer 框架 · 仅砍 2 类 + 归并 source/sink 语义 + 修数据 tap WS 通路 bug · 让 dock 真能拿到数据(用户实测验收点)


任务定义(基于 ADR-AIOS-21-R1 §3.1-R1 + §2.3)

实施 ADR-21-R1 §3.1 修订(selector 5→3 类)+ §2.3 数据 tap 通路修复:

  • 修订 1 · selector 砍 5→3 类:physical-input+source→input(归并物理输入与链路 source)· sink-pre+sink→output(归并物理输出与链路 sink)· log-modulelog_module(保持)· xilink-module + xitune-module 2 类(链路 analysis module 通过双击 mini-node 出 popup 看 · 不进 dock)
  • 修订 2 · 数据 tap 通路修复:nodeRef → WS endpoint 订阅通路当前 bug · 让用户切到 input/output/log_module 任一节点后 ≤ 500ms WS 帧首达 + chart 刷新 · 现有所有 5 种 dock meter(scope/fft/rms/phase/transfer)都能拿到数据
  • 不动:F1 ResizeObserver / 滚轮缩放 / channelMask 自适应 / Drawer 组件外壳(F2-R1 cleanup 时再统一)· F2 4ed8699 控件增强 · F3 8eaaf40 / F5 eb84bab 算法层

严守保留(零回归):F2 控件增强(displayMode/peakHold/peakTrack/trigger/persistence/timePerDiv 9 项)· F1 ResizeObserver / 滚轮缩放 · 现有 fft/scope/rms dock 渲染流水线(只改 selector + 数据 tap · 不动 chart 渲染逻辑)。


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

[U-thread]   P1.UA21R1.F1-dock-selector-3-categories-and-data-tap
[部门]       前端 (frontend_vue3) · 推荐 skill: vuejs-typescript-best-practices
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies]   P1.K-xilink-dock(写 · selector + 数据 tap)+ P1.K-types(写 · widgetEndpoint 砍 2 类)
[隔离]       🧵 文件隔离 · 与同期 active fork 文件正交 · 不动 stages/xitest/* / stages/xitune/* / stages/xiforge/* · 不动 dsp_algo/* · 不动 backend_csharp/*
[优先级]     P0 · 1.0d · ADR-21-R1 fork 1 · 用户实测纠错 hotfix(blocked-by 0 · 阻塞 F2-R1)
[ADR]        d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-21-R1-dock-three-selectors-and-popup-entries.md(必读 §2.3 数据 tap + §3.1-R1 三类 selector + §4.2 F1-R1 行)
[业务行为契约引用] ADR-21-R1 §3.1-R1 ① 输入/输出契约(DockNodeKind 3 类 + DockNodeRef 含 endpointUrl) + ② 收敛判据(节点切换 ≤ 500ms WS 帧首达 + 5 meter 共用 selector) + 用户原话 6/15 10:24 + 11:21 verbatim

[参考文档](绝对路径)
  - ADR 主文档:d:/.../docs/08-implementation/40-aios/ADR/ADR-AIOS-21-R1-dock-three-selectors-and-popup-entries.md(本 R1 修订)
  - 父 ADR:d:/.../docs/08-implementation/40-aios/ADR/ADR-AIOS-21-xilink-dock-and-analysis-modules.md(已 partially-superseded · §1+§2 主体保留)
  - F1 supersede 标本:d:/.../docs/08-implementation/40-aios/prompts/done/ADR-AIOS-21/P1.A21.F1-dock-host-generalize--a5b52de.md(看 5 类 selector 实装 · 本 R1 砍 2 类)
  - F7 abort 历史:d:/.../docs/08-implementation/40-aios/prompts/done/ADR-AIOS-21/P_e2e.A21.F7-...aborted-2026-06-15-1100-superseded-by-ADR-21-R1.md(看 4 路真值核查 + 用户原话)
  - 现有 fft popup 范式标杆(双路径并存证据):d:/.../04_development/frontend_vue3/src/components/popups/FftModulePopup.vue
  - 现状必读:
    · frontend_vue3/src/stages/xilink/dock/DockHost.vue(全文 · F1 a5b52de 落地 · 找 5 类 selector + 数据 tap WS 订阅位置)
    · frontend_vue3/src/stages/xilink/dock/DockNodeSelector.vue(selector UI · 砍 2 类下拉项)
    · frontend_vue3/src/composables/useChainNodeMetadata.ts(节点 metadata · 归并 source→input / sink→output 语义)
    · frontend_vue3/src/composables/useDockChannelMask.ts(channelMask 逻辑 · 看是否依赖 5 类 nodeKind)
    · frontend_vue3/src/types/widgetEndpoint.ts(endpointKey 5 类定义 · 砍 xilink-module/xitune-module 2 项)
    · 后端 WS endpoint 真实路由(grep backend_csharp 或 routes · 不改后端代码 · 仅核查前端 endpointUrl 是否对齐后端实际路由)

【背景】
ADR-21 v0.1 accepted 后 F1 ClaudeA 落地 a5b52de(13 文件 +701 行 · 5 类 selector + channelCount 自适应 + 滚轮缩放)· 但用户 6/15 实测发现:
- 原话(10:24):"右侧dock可以监控链路中所有的固定节点,比如source的输出,sink的数据,log module等特定节点的数据;当前所有右侧dock都没有数据更新"
- 11:21 二次澄清:"selector 保留三类,输入设备/source 都属于输入,输出设备sink属于输出,logmodule 输入节点监控"
- 11:30 拍板方向 B:走 ADR-21-R1 修订 + 4 R1 hotfix
- 4 路真值核查证实:F1 5 类 selector 后 2 类(xilink-module/xitune-module)语义错位(链路 module 不应进 dock · 应通过双击 mini-node 出 popup)+ nodeRef→WS endpoint 通路有 bug(具体根因待你深查)
本 R1 hotfix 是 ADR-21-R1 fork 1 · supersede a5b52de · 阻塞 F2-R1 / F4-R1 / F6-R1 三并行 fork。

【执行步骤】

Step 0 · 真值核查(必跑 · 0.15d · 不许跳)
- git status / git pull origin xistudio --no-rebase
- git -C d:/work/25_claude/workspace/AlgoDepartment/04_development log --oneline -10(看 HEAD)
- read frontend_vue3/src/stages/xilink/dock/DockHost.vue 全文(F1 a5b52de 落地 · 找 5 类 selector + WS 订阅代码)
- read frontend_vue3/src/types/widgetEndpoint.ts(看 endpointKey 5 类 + endpointLabel · 找 xilink-module/xitune-module 项)
- read frontend_vue3/src/composables/useChainNodeMetadata.ts + useDockChannelMask.ts(节点 metadata 归并点 + channelMask 是否依赖 5 类 nodeKind)
- read frontend_vue3/src/stages/xilink/dock/DockNodeSelector.vue(看 selector dropdown 数据来源)
- grep -r "physical-input\|sink-pre\|log-module\|xilink-module\|xitune-module" frontend_vue3/src(看 5 类 selector 全项目调用方)
- 找数据 tap bug 根因:
  · grep -r "useWebSocket\|/ws/\|tap_node\|dockSubscribe\|onMounted" frontend_vue3/src/stages/xilink/dock/ + composables/useDock*.ts
  · 对照后端 WS endpoint 真实路径(grep backend_csharp/Routes/* 找 ws/ 端点 · 仅核查 · 不改后端)
  · 用浏览器 devtools Network → WS 标签实测 dock 选定节点后是否真有 WS 连接 + 帧推送(若有连接但无帧 → 后端订阅参数错;若无连接 → 前端 endpoint URL 错;若有帧但 chart 不刷 → 前端 frame handler 解码错)
- 输出真值核查到 commit body:
  · DockHost 5 类 selector 实际位置(行号)+ 砍 2 类的最小改动文件清单
  · widgetEndpoint.ts 5 类→3 类的归并映射(physical-input+source→input · sink-pre+sink→output · log-module→log_module · 砍 xilink-module/xitune-module)
  · 数据 tap bug 真因 3 候选(后端订阅参数错 / 前端 URL 错 / frame handler 错)+ 你选定的根因 + 1 句话理由
  · 5 种 dock meter(scope/fft/rms/phase/transfer)是否都共用同一 WS 订阅路径(F2-R1 cleanup 前置依赖)

Step 1 · 砍 widgetEndpoint.ts 2 类 + 归并 source/sink(0.1d)
- 编辑 frontend_vue3/src/types/widgetEndpoint.ts
- 修改 endpointKey union type:
  · 砍 `'xilink-module:${...}'` + `'xitune-module:${...}'` 2 类
  · 改 `'physical-input:${deviceId}'` → `'input:${deviceId}'`(label 改 "Input: ${deviceId}")
  · 改 `'sink-pre'`(单数)→ `'output:${nodeId?}'`(归并物理输出 + 链路 sink · label "Output: ${nodeId|main}")
  · 改 `'log-module:${...}'` → `'log_module:${moduleId}'`(下划线统一)
- 不动现有 endpointLabel 函数签名 · 仅扩 input/output 的 label 模板
- LEGACY 兼容(7 天宽限):若发现旧 endpointKey('physical-input:xxx' / 'sink-pre' / 'xilink-module:yyy' 等)在持久化数据中 · 加 LEGACY_ENDPOINT_KEY_MAP 映射函数(rolling backward compat 7d · 用户配置文件能加载) — 若没找到旧持久化 · 此项可省

Step 2 · DockHost.vue selector 简化 + DockNodeSelector dropdown 砍 2 类(0.2d)
- 编辑 frontend_vue3/src/stages/xilink/dock/DockNodeSelector.vue
- selector dropdown 数据源改为 3 类(input/output/log_module)· 砍 xilink-module/xitune-module 选项
- 节点列表内含:
  · input:物理输入设备 + 链路 source 节点(从 useChainNodeMetadata 读 · 归并)
  · output:物理输出设备 + 链路 sink 节点(归并)
  · log_module:链路 log_module_v1 实例(原 log-module 类目)
- 编辑 frontend_vue3/src/stages/xilink/dock/DockHost.vue
- 移除 5 类 allowedTypes prop 中 xilink-module/xitune-module 2 项
- props.allowedTypes 默认值改 ['input', 'output', 'log_module']

Step 3 · useChainNodeMetadata 归并 source→input / sink→output(0.2d)
- 编辑 frontend_vue3/src/composables/useChainNodeMetadata.ts
- 节点 metadata getter 加归并逻辑:
  · 链路图 source 节点 → 输出 nodeKind: 'input' + endpointUrl: 'input:source-${id}'
  · 链路图 sink 节点 → 输出 nodeKind: 'output' + endpointUrl: 'output:sink-${id}'
  · 物理输入设备 → 输出 nodeKind: 'input' + endpointUrl: 'input:device-${deviceId}'
  · 物理输出设备 → 输出 nodeKind: 'output' + endpointUrl: 'output:device-${deviceId}'
  · log_module_v1 实例 → 输出 nodeKind: 'log_module' + endpointUrl: 'log_module:${instanceId}'
- 不动 channelCount / sampleRate 字段 · 不动 useDockChannelMask channelMask 逻辑(若 channelMask 不依赖 nodeKind)
- 若 useDockChannelMask 依赖 5 类 nodeKind · Step 0 真值核查发现后 · 同步改成 3 类适配

Step 4 · 修数据 tap WS 通路 bug(0.3d · 核心修复)
- 基于 Step 0 选定的根因路径修复:
  · 若是前端 endpointUrl 与后端实际路由不对齐:改 useChainNodeMetadata 输出的 endpointUrl 模板对齐后端真实 ws endpoint(eg. 后端实际是 /ws/dock/tap?node=xxx · 前端就用此模板)
  · 若是后端订阅参数错:在 DockHost 订阅时补 payload 字段(eg. nodeId / channelMask)· 与后端约定(必要时跨 ClaudeA/B 协调 · 在 commit message body 标 [need: ClaudeB] · 但不改后端代码)
  · 若是 frame handler 解码错:修 DockHost frame onmessage 解码(JSON.parse / DataView 取字段)+ 错误日志
- 加 5s timeout 自检:nodeRef 绑定后 5s 内 0 帧 → DockHost 显示 "Data tap timeout · check WS endpoint" + console.error(对齐 ADR-21-R1 §3.1-R1 ③ 失败回退)
- 5 种 dock meter(scope/fft/rms/phase/transfer · 即便 phase/transfer 当前 dock 还在 F4/F6 旧版 · 暂用 useDockMeterFrame 占位)都共用同一 WS 订阅路径(useDockMeterFrame composable 在 F2-R1 完整抽出 · 本 fork 只需修通路即可 · 不重构 composable)

Step 5 · vitest 单测(0.15d)
- 新增 frontend_vue3/tests/composables/useChainNodeMetadata-3-categories.test.ts(≥ 5 case):
  · case 1:链路 source 节点 → nodeKind === 'input'
  · case 2:链路 sink 节点 → nodeKind === 'output'
  · case 3:log_module_v1 实例 → nodeKind === 'log_module'
  · case 4:物理输入/输出设备归并到 input/output(各 1 case)
  · case 5:不再返回 nodeKind === 'xilink-module' / 'xitune-module'(2 类被砍)
- 新增 frontend_vue3/tests/components/DockHost-data-tap.test.ts(≥ 4 case):
  · case 1:dropdown 仅 3 类 selector(input/output/log_module)
  · case 2:选定 input 节点 → endpointUrl 模板正确(对齐 Step 4 后端约定)
  · case 3:5s timeout 触发 fallback UI 提示(mock WS 永不响应)
  · case 4:5 种 meter(scope/fft/rms/phase/transfer)切换节点 selector 行为一致(共用 selector)

Step 6 · build + test + 手动 e2e(0.1d · 必跑用户实测视角)
- cd frontend_vue3
- npm run typecheck(零错误)
- npm run test:unit(基线 +9 case 全绿 · 已知 3 fail 不增)
- 手动 e2e(浏览器):
  · npm run dev
  · 进 P1-xilink stage · 加载链路 · 含 source + sink + log_module_v1 节点
  · 右 dock 点 "+ fft" → 顶部 selector dropdown 仅 3 类(✅ 验 input/output/log_module · 不见 xilink-module/xitune-module)
  · 默认选 input → chart ≤ 500ms 内有数据(✅ 关键修复点:用户实测"所有 dock 无数据更新"病因消除)
  · 切 output → chart 切换刷新
  · 切 log_module → chart 切换刷新
  · 重复测 scope/rms/phase/transfer 4 种 dock meter · 共用 selector + 数据通路一致(若 phase/transfer dock 数据通路依赖 useDockMeterFrame composable · F2-R1 cleanup 后才能完整测 · 本 fork 暂用占位 ok)
  · 浏览器 devtools Network → WS 标签验有 connection + 帧推送
  · 节点删除测试:删上游 source · dock 显示 "Node removed" + 5s timeout fallback(沿用 ADR-21 §3.1 ③)

Step 7 · commit + push(0.05d)
- git add frontend_vue3/src/stages/xilink/dock/DockHost.vue \
          frontend_vue3/src/stages/xilink/dock/DockNodeSelector.vue \
          frontend_vue3/src/composables/useChainNodeMetadata.ts \
          frontend_vue3/src/composables/useDockChannelMask.ts(若改) \
          frontend_vue3/src/types/widgetEndpoint.ts \
          frontend_vue3/tests/composables/useChainNodeMetadata-3-categories.test.ts \
          frontend_vue3/tests/components/DockHost-data-tap.test.ts
- git commit subject + trailer 见下
- git push origin xistudio
- 反馈给 Cline-AIOS:zombie commit hash + 真值核查报告(数据 tap bug 真因 + 修复路径)+ 浏览器实测截图日志(用户实测验收"dock 有数据更新"是核心)

【验收】

形式合规:
- [ ] npm run typecheck 零错误
- [ ] npm run test:unit 全绿(基线 +9 case · 已知 3 fail 不增)
- [ ] 仅修动 5-7 文件(types 1 + composables 1-2 + dock SFC 2 + tests 2)
- [ ] 不破坏 F1 ResizeObserver / 滚轮缩放 / channelMask 自适应
- [ ] 不破坏 F2(4ed8699)9 控件增强(displayMode/peakHold/peakTrack/trigger/persistence/timePerDiv)
- [ ] 不动 stages/xitest/* / stages/xitune/* / stages/xiforge/* · 不动 dsp_algo/* · 不动 backend_csharp/*

业务行为契约(端到端真值 · 必跑):
- [ ] **selector 仅 3 类**:dropdown 含 input/output/log_module · **不含** xilink-module/xitune-module(ADR-21-R1 §3.1-R1 ②)
- [ ] **数据 tap 通路通**:节点选定 ≤ 500ms WS 帧首达 + chart 刷新(用户实测核心验收点 · ADR-21-R1 §2.3)
- [ ] 5 种 dock meter(scope/fft/rms/phase/transfer)共用 selector 切节点行为一致
- [ ] 5s timeout fallback UI 提示生效(mock WS 永不响应场景)
- [ ] source/sink 链路节点归并到 input/output 语义(用户原话 11:21 锁定)
- [ ] 浏览器 devtools Network → WS 标签验有 connection + 帧推送

【commit】
subject:`fix(P1.UA21R1.F1-dock-selector-3-categories-and-data-tap): selector 5→3 类(input/output/log_module) + 数据 tap 通路修复 · ADR-21-R1 §3.1-R1+§2.3 · supersede a5b52de`

trailer(必须精确):
[step=7/7] [pid=P1] [uid=UA21R1.F1-dock-selector-3-categories-and-data-tap] [occupies=P1.K-xilink-dock+P1.K-types]
[files=frontend_vue3/src/types/widgetEndpoint.ts, src/composables/useChainNodeMetadata.ts, src/composables/useDockChannelMask.ts, src/stages/xilink/dock/DockHost.vue, src/stages/xilink/dock/DockNodeSelector.vue, tests/composables/useChainNodeMetadata-3-categories.test.ts, tests/components/DockHost-data-tap.test.ts]
[isolation] file(同 worktree 同 branch · 与同期 active fork 文件正交)
[adr] ADR-AIOS-21-R1 §3.1-R1 + §2.3 + §4.2 F1-R1
[derived_from] supersede P1.A21.F1-dock-host-generalize@a5b52de(5 类→3 类 + 修数据 tap)
[parent_zombie] a5b52de(5 类 selector 落地 · 本 R1 砍 2 类)
[truth-check] 5 类 selector 砍 2 类映射=<input/output/log_module 归并清单> · 数据 tap bug 真因=<前端 URL/后端订阅/frame handler 选 1> · 修复路径=<具体>
[acceptance] selector 3 类生效 + 数据 tap 通路通(用户实测"dock 有数据更新")+ 5 meter 共用 selector + 5s timeout fallback

【禁止】
1. ❌ 不动 backend_csharp/ / dsp_algo/ / contracts/(ClaudeA 边界 · `.clinerules` 工程代码位置铁律)
2. ❌ 不动 F2 4ed8699 控件增强代码(displayMode/peakHold/peakTrack/trigger/persistence/timePerDiv 9 控件)
3. ❌ 不动 F3 8eaaf40(phase 算法层) / F5 eb84bab(transfer 算法层)
4. ❌ 不重构 useDockMeterFrame composable(F2-R1 范畴 · 本 fork 仅修通路)
5. ❌ 不动 phase/transfer popup(F4-R1 / F6-R1 范畴 · 本 fork 仅 dock)
6. ❌ 不动 LinkEditor.vue 双击协议(F4-R1 / F6-R1 范畴)
7. ❌ 不省略 truth-check 报告(数据 tap bug 真因必须明确给出)
8. ❌ 不在 vitest 基线引入新 fail(已知 3 fail 不动 · 不许第 4)
9. ❌ 不绕开手动 e2e(浏览器 Network WS 标签验帧推送是核心验收)
10. ❌ commit message 缺三元组 trailer 任一字段 → 自动拒收

解锁链(本任务 zombie 后)

  • P1.UA21R1.F2-dock-5-meters-cleanup:blocked-by F1-R1 · 用统一 3 类 selector 抽 useDockMeterFrame cleanup 5 meter
  • P1.UA21R1.F4-phase-popup-frontend:可与 F2-R1 / F6-R1 三并行(file isolation · 文件正交 · LinkEditor.vue 双击 vs DockHost selector 不同区域)
  • P1.UA21R1.F6-transfer-popup-frontend:同上
  • P_e2e.A21R1.F7-truth-e2e-popup-and-fixed-nodes:待 4 R1 hotfix 全 zombie 后 ready
  • 🏆 用户实测"右 dock 有数据更新"病因消除(ADR-21-R1 §2.3 修复目标达成)

风险评估

风险 缓解
⚠️ 数据 tap bug 真因需深查(可能在前端 URL / 后端订阅 / frame handler 任一) Step 0 真值核查必跑 · 用浏览器 devtools Network WS 标签实测 + 后端路由 grep · 选定根因 1 句话理由写到 commit body
⚠️ 后端订阅参数错(可能需协调 ClaudeB) 不擅自改后端 · commit message body 标 [need: ClaudeB] dock-tap-endpoint-routing · AIOS 后续派活
⚠️ widgetEndpoint.ts 砍 2 类破坏现有持久化数据 加 LEGACY_ENDPOINT_KEY_MAP 7d 宽限映射函数(沿用 .clinerules 工程铁律 LEGACY 兼容)· 旧持久化 'xilink-module:xxx' 自动 fallback 'log_module' 或忽略
⚠️ useChainNodeMetadata 归并 source/sink 破坏现有 ChainNodeRef 类型消费方 grep -r ChainNodeRef · 改归并不破坏字段(只新增 endpointUrl)+ TypeScript 类型一致
⚠️ 5 种 dock meter 共用 selector 但 useDockMeterFrame 抽离在 F2-R1 · 本 fork 暂占位 本 fork 修单 dock(eg. fft)数据通路 · 其他 4 dock 临时按现有路径走(F2-R1 时统一)· 不破坏现有渲染
⚠️ 浏览器手动 e2e 时序敏感 · 5s timeout 在慢 CI 不稳 单测用 mock WS 控制时序 · 手动 e2e 仅人工验证
⚠️ 与 F4-R1 / F6-R1 / F2-R1 同 ClaudeA worker 串行(若用户决定串行) 本 fork 不阻塞其他 R1 fork 启动(file isolation · 文件正交 · F4-R1/F6-R1 改 LinkEditor + popup vs 本 fork 改 DockHost selector)

历史

时间 事件 hash
2026-06-15 11:30 ADR-21-R1 v0.1 proposed · 起本 R1 hotfix(F1-R1 · ready 状态等用户 accept ADR-21-R1 + start)
(待) dispatched
(待) zombie