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-module→log_module(保持)· 砍xilink-module+xitune-module2 类(链路 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 | — |