跳转至

P1.UH-xitest-meter-share-fix · 4 独立 XiTest dock 共享组件 + 节点联动 hotfix(ADR-08 §议题⑤ 验收失败修复)

Worker:ClaudeA · 前端 (frontend_vue3) / 预计:1.0d / 优先级:P1 / 状态:dispatched 隔离:🧵 文件隔离(同 worktree 同 branch · 与同期 ClaudeA 两 hotfix 文件正交)


🔍 触发与解锁链

触发 状态 影响
用户验收 ADR-08 议题⑤ 失败 ✅ 2026-05-31 11:01 原话"改为 4 独立 dock · 无法真正生效 · 不能与链路通道联动 · 应共用 xitest 的组件"
parent zombie P1.U-dock-cleanup-9to4 ✅ ad1e458 9→4 drawer + DrawerXiTest 4 tab 落地 · 但用户后续重构为 4 独立 dock · 未对接共享组件
P0.K-shared-meter-dock 已就位 ✅ ea5e9e4 (ADR-07 §2.1.2) 6 stub 组件可复用:RMSMeter / FreqResponseChart / PhaseChart / WaveformChart 等
P0.U-measurement-rms-fft-phase zombie ✅ 8379de2 (ADR-12 #5) P3-xitest 真业务标杆 · 含 1kHz 注入 → 频谱 1000Hz 峰等 e2e 真值

→ 纯前端 · 不修改 contract-v1.0 · 复用现有 6 共享组件 + WS /ws/meter/stream


任务定义

修复 ADR-08 议题⑤ "4 独立 dock(用户重构后)无法显示数据 + 应共用 xitest 组件"。根因: - ① 4 独立 dock 各自实装 meter 而非复用 P0.K-shared-meter-dock(ADR-07 §2.3 边界铁律 #2 违反) - ② 节点选择联动断了:选 sink-pre / physical-input 时 4 dock 不订阅该节点的 tap

核心范围: 1. 4 独立 dock(DrawerXiTestRMS / Freq / Phase / Scope)全部改用 P0.K-shared-meter-dock 6 stub 组件 2. 新增 useXiTestNodeBinding.ts composable:监听 linkStore 当前选中节点 → 4 dock 自动订阅 WS /ws/meter/stream?node=<id> 3. 节点变化(用户在画布选中其他 sink-pre / physical-input)→ 4 dock 自动切订阅 4. e2e 真值:复用 P0.U-measurement-rms-fft-phase 标杆(注入 1kHz 正弦 → RMS ≈ -3dB · 频响 1000Hz 峰)


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

[U-thread]   P1.UH-xitest-meter-share-fix(alias: P1.U-xitest-meter-share-fix)
[部门]       前端 (frontend_vue3) · 推荐 skill: vuejs-typescript-best-practices
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies]   P1.K-xilink-drawers(写 · 4 dock 改) + P0.K-shared-meter-dock(read · 复用 6 stub)
[隔离]       🧵 文件隔离 · 仅写:
             - frontend_vue3/src/stages/xilink/drawers/DrawerXiTest{RMS,Freq,Phase,Scope}.vue(4 文件 · 改用共享组件)
             - frontend_vue3/src/composables/useXiTestNodeBinding.ts(新增)
             - frontend_vue3/tests/components/DrawerXiTest-share-meter.test.ts(新增)
             与同期 P1.UH-link-error-bottom-fix(bottom/*)+ P1.UH-subgraph-ports-and-dblclick-fix(Subgraph*)文件正交
[优先级]     P1 · 1.0d · ADR-08 议题⑤ 用户验收失败修复
[ADR]        d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-08-xilink-stage-ux.md(必读 §2.1 议题⑤ + §3.2 边界铁律 · 复用 P0.K-shared)
[业务行为契约引用] ADR-08 §2.1 + ADR-07 §2.3 边界铁律 #2(严禁 stages/xilink 自实装 meter)+ 验收清单 C5-3~C5-6
[参考文档](绝对路径)
  - ADR-08:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-08-xilink-stage-ux.md(§2.1 议题⑤ XiTest 四件套必复用 P0.K-shared)
  - ADR-07:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-07-xitune-xitest-bondary.md(§2.1.2 P0.K-shared 6 stub 抽出 · §2.3 边界铁律 #2)
  - 验收清单:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-08-acceptance-checklist.md(议题⑤ C5-3~C5-6)
  - parent zombie:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P1.U-dock-cleanup-9to4--ad1e458.md(看 9→4 drawer 实装 · 用户后续改 4 独立 dock 的起点)
  - 共享组件就位:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P0.U-add-meter-dock-kthread--ea5e9e4.md(P0.K-shared-meter-dock 6 stub 抽出文档)
  - 真业务标杆:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P0.U-measurement-rms-fft-phase--8379de2.md(P3-xitest 真业务 · 含 e2e 真值 1kHz 正弦验证 · 本 fork 复用其组件)
  - 现状必读:
    · frontend_vue3/src/stages/xilink/drawers/DrawerXiTest*.vue(若用户已建 4 独立 dock · 看现状)
    · frontend_vue3/src/components/measurement-shared/(P0.K-shared 6 stub:RMSMeter / FreqResponseChart / PhaseChart / WaveformChart)
    · frontend_vue3/src/stores/linkStore.ts(找选中节点字段 · 通常 selectedNodeId / activeNode)
    · frontend_vue3/src/composables/useMeterStream.ts 或类似(看现有 WS /ws/meter/stream 订阅模式)

【背景】
ADR-08 议题⑤ parent zombie `ad1e458` 落了 9→4 drawer + 单 DrawerXiTest 含 4 子标签 · 但用户**后续重构**为 4 独立 dock(RMS / 频响 / 相位 / Scope 各 1 个 dock)· 重构后未对接共享组件 + 节点联动 · 用户 2026-05-31 11:01 实测原话:**"改为 4 独立 dock · 无法真正生效 · 应共用 xitest 组件"**。

🚨 **真值核查关键点**(本 fork 第一步必须 grep 验证):
- ① 4 独立 dock 是否已存在(用户原话已建 · 但代码可能在 ClaudeA 个人 worktree 未推主仓 · 第一步 ls drawers/ 确认)
- ② 4 dock 是否各自实装 meter / chart 数学(若是 → 违反 ADR-07 §2.3 边界铁律 #2 · 必须改用共享)
- ③ linkStore.selectedNodeId(或类似)字段是否存在(选中节点联动的数据源)
- ④ `useMeterStream` 或同等 WS 订阅 composable 是否已就位

**本任务核心**(1.0d · 改 4 dock + 加联动):
- ✅ 4 独立 dock 全部改用 P0.K-shared 6 stub 组件(RMSMeter / FreqResponseChart / PhaseChart / WaveformChart)· 严禁 dock 内部自实装数学
- ✅ 新增 useXiTestNodeBinding · 监听 linkStore 当前选中节点 + 节点类型(必须 sink-pre / physical-input)→ 自动订阅 WS `/ws/meter/stream?node=<id>` · 切节点自动切订阅
- ✅ 4 dock 在 onMounted 调 useXiTestNodeBinding · onUnmounted 清订阅
- ✅ e2e 真值:注入 1kHz 正弦 + 选中 sink-pre 节点 → RMS dock 显示 ≈ -3dB · 频响 dock 显示 1000Hz 峰

【执行步骤】

Step 1 · 真值核查(必跑 · 0.15d)
- git status / git pull origin xistudio --no-rebase
- ls frontend_vue3/src/stages/xilink/drawers/(看 4 独立 dock 是否已存在)
- 若存在 · cat 4 dock 看现状(grep "RMSMeter\|FreqResponse\|PhaseChart\|Waveform" · 看是否复用共享 / 自实装)
- ls frontend_vue3/src/components/measurement-shared/(确认 6 stub 路径)
- grep "selectedNodeId\|activeNode\|currentNode" frontend_vue3/src/stores/linkStore.ts(找选中节点字段)
- grep "useMeterStream\|/ws/meter/stream" frontend_vue3/src/composables/(找 WS 订阅 composable)
- 输出真值核查到 commit message body:
  · 4 dock 现状(已存在/不存在 · 复用共享/自实装)
  · linkStore 选中节点字段名
  · 现有 WS 订阅 composable 路径

Step 2 · 4 dock 改用共享组件(0.4d)
- 编辑 frontend_vue3/src/stages/xilink/drawers/DrawerXiTestRMS.vue:
  · template 仅 import + 用 `<RMSMeter :node-id="boundNodeId" />`
  · 不实装 RMS 计算逻辑
- 同理:DrawerXiTestFreq → `<FreqResponseChart :node-id="boundNodeId" />`
- DrawerXiTestPhase → `<PhaseChart :node-id="boundNodeId" />`
- DrawerXiTestScope → `<WaveformChart :node-id="boundNodeId" />`
- 4 dock 顶部加节点选择提示:若 boundNodeId 为空 → "请在画布选择 sink-pre 或 physical-input 节点"

Step 3 · 新增 useXiTestNodeBinding composable(0.25d)
- 路径:frontend_vue3/src/composables/useXiTestNodeBinding.ts
- 功能:
  · const linkStore = useLinkStore()
  · const boundNodeId = computed(() => {
      const sel = linkStore.selectedNodeId(或同等字段)
      if (!sel) return null
      const node = linkStore.modules.find(m => m.id === sel)
      if (!node) return null
      // 仅 sink-pre / physical-input 类型可绑
      if (node.type !== 'sink-pre' && node.type !== 'physical-input') return null
      return sel
    })
  · watch boundNodeId 变化 · 自动 emit 给 4 dock(或 4 dock 各自 import)
  · 暴露 { boundNodeId }(ref)
- 4 dock 中:`const { boundNodeId } = useXiTestNodeBinding()` · 传给共享组件

Step 4 · vitest 单测(0.15d)
- 新增 frontend_vue3/tests/components/DrawerXiTest-share-meter.test.ts:
  · case 1:DrawerXiTestRMS mount · 内含 RMSMeter 组件(stub)· 不含自实装数学
  · case 2:同 Freq/Phase/Scope · 各自含对应共享组件
  · case 3:linkStore.selectedNodeId = 'sink-pre.0' → boundNodeId = 'sink-pre.0' · 共享组件 props.nodeId 接到
  · case 4:linkStore.selectedNodeId = 'eq.high'(普通 module · 非 sink-pre)→ boundNodeId = null · 4 dock 显示提示
  · case 5:linkStore.selectedNodeId 切换 → 4 dock props 自动更新
- 新增 useXiTestNodeBinding 单测(>= 3 case)
- 端到端真值:复用 P0.U-measurement-rms-fft-phase 8379de2 e2e 模式 · 注入 1kHz 正弦 + 选中 sink-pre → RMS ≈ -3dB · 频谱 1000Hz 峰

Step 5 · build + test + 手动 e2e(0.15d)
- cd frontend_vue3
- npm run typecheck(零错误)
- npm run test:unit(基线 +8 用例)
- 手动 e2e:
  · npm run dev
  · 浏览器进 P1-xilink stage · 加 sink-pre 节点 + audio source(1kHz 正弦)
  · 选中 sink-pre 节点 → 打开 RMS dock · 应显示 ≈ -3dB(随时间变化)
  · 打开 Freq dock · 应显示 1000Hz 处有峰
  · 切到 physical-input 节点 → dock 自动切订阅(数据源换)
  · 选普通 eq.high 节点 → 4 dock 显示"请选择 sink-pre / physical-input"

Step 6 · commit + push(0.05d)
- git add frontend_vue3/src/stages/xilink/drawers/DrawerXiTest{RMS,Freq,Phase,Scope}.vue \
          frontend_vue3/src/composables/useXiTestNodeBinding.ts \
          frontend_vue3/tests/components/DrawerXiTest-share-meter.test.ts
- git commit subject + trailer 见下
- git push origin xistudio

【验收】

形式合规:
- [ ] npm run typecheck 零错误
- [ ] npm run test:unit 全绿(基线 +8 用例)
- [ ] 仅修动 6 文件(4 dock + 1 composable + 1 test)
- [ ] 不动 P0.K-shared-meter-dock 6 stub 组件(read-only 复用)
- [ ] 不动 stages/xilink/bottom/* / Subgraph*(同期 hotfix 区域)
- [ ] 不动 stages/xitest/* / stages/xitune/*
- [ ] 4 dock grep "FFT\|RMS calc\|Math.log" 应 0 命中(严禁自实装数学 · ADR-07 §2.3 #2)

业务行为契约(端到端真值 · 必跑):
- [ ] 4 独立 dock 各含 1 个 P0.K-shared 共享组件(RMSMeter / FreqResponseChart / PhaseChart / WaveformChart)
- [ ] 选中 sink-pre 节点 → 4 dock 自动订阅该节点 tap · 数据可见
- [ ] 注入 1kHz 正弦 → RMS dock 读数 ≈ -3dB(±1dB)· 频响 dock 1000Hz 处峰值 > -10dB
- [ ] 切换到另一个 sink-pre 节点 → 4 dock 自动切订阅(<200ms)· 数据源刷新
- [ ] 选中普通节点(非 sink-pre / physical-input)→ 4 dock 显示"请在画布选择 sink-pre 或 physical-input 节点"
- [ ] 用户回测 ADR-08 验收清单 C5-3~C5-6

【commit】
subject:`fix(P1.UH-xitest-meter-share-fix): 4 dock reuse P0.K-shared + node binding · ADR-08 §议题⑤ + ADR-07 §2.3 #2 · user acceptance C5-* fix`

trailer(必须精确):
[step=6/6] [pid=P1] [uid=UH-xitest-meter-share-fix] [occupies=P1.K-xilink-drawers+P0.K-shared-meter-dock(read)]
[files=frontend_vue3/src/stages/xilink/drawers/DrawerXiTestRMS.vue, DrawerXiTestFreq.vue, DrawerXiTestPhase.vue, DrawerXiTestScope.vue, frontend_vue3/src/composables/useXiTestNodeBinding.ts, frontend_vue3/tests/components/DrawerXiTest-share-meter.test.ts]
[isolation] file(同 worktree 同 branch · 与同期 P1 两 hotfix 文件正交)
[derived_from] ADR-AIOS-08 §议题⑤ 验收失败 · parent_zombie ad1e458 + 用户后续 4 独立 dock 重构
[truth-check] 4 dock 现状=<已存在/不存在> · 自实装/复用共享=<x>
[acceptance] 选 sink-pre + 1kHz 正弦 → RMS≈-3dB + 频响 1000Hz 峰 · 用户重跑 C5-3~C5-6

【禁止】
1. ❌ 严禁在 4 dock 内自实装 RMS / FFT / 相位 / Scope 数学(ADR-07 §2.3 边界铁律 #2 · 必须复用 P0.K-shared)
2. ❌ 不动 P0.K-shared-meter-dock 6 stub 组件(read-only 复用 · 不修改 ea5e9e4 落地)
3. ❌ 不动 stages/xilink/bottom/* / Subgraph*(同期 hotfix 区域)
4. ❌ 不动 stages/xitest/* / stages/xitune/*
5. ❌ 不新建 WS channel(复用 /ws/meter/stream · 已 freeze)
6. ❌ 不在 useXiTestNodeBinding 内做信号处理(纯绑定 · 数据流由共享组件订阅)
7. ❌ 不跳手动 e2e(必须浏览器实测 1kHz 正弦场景)
8. ❌ 不跳真值核查(Step 1 必须确认 4 dock 现状 · commit message 报告)
9. ❌ 不省略三元组 trailer + truth-check 报告
10. ❌ 不动同期 P1.UH-link-error-bottom-fix / P1.UH-subgraph-ports-and-dblclick-fix 的文件区域

解锁链(本任务 zombie 后)

  • ✅ 用户重跑 ADR-08 验收清单 §议题⑤ C5-3~C5-6
  • ✅ 4 独立 XiTest dock 真业务可用 · 与画布节点选择联动
  • ✅ ADR-07 §2.3 边界铁律 #2 验证(stages/xilink 不自实装 meter · 复用 P0.K-shared)

风险评估

风险 缓解
⚠️ P0.K-shared 6 stub 组件可能仍是 stub · 不返真数据 真业务由 P0.U-measurement-rms-fft-phase 8379de2 标杆已落实(含真 e2e)· 本 fork 复用其组件即可
⚠️ linkStore.selectedNodeId 字段可能不存在(parent zombie 未实装选择联动) Step 1 grep 后若无 · 加 selectedNodeId 字段 + 画布点击节点更新该字段 · 范围内可控
⚠️ /ws/meter/stream?node= 后端是否支持动态切节点(不仅是首次订阅) P5.U-meter-tap-multi-tool 48cf0ba 已支持 7 toolKind 路由 · 若不支持节点切换 · 起 P5 hotfix
⚠️ 4 dock 同时订阅 4 个 toolKind 性能 本 fork 不优化 · 若卡 · 后续 fork 改按需订阅(只激活的 dock 订阅)

历史

时间 事件 hash
2026-05-31 11:13 dispatched · 用户验收 ADR-08 议题⑤ 失败 "4 独立 dock 不与链路联动 · 应共用 xitest 组件" → 拍板派 5 hotfix · 本 fork P1 · 1.0d ClaudeA
2026-05-31 14:05 zombie · ClaudeA 完成 · 真值核查:4 dock 现状 = 已存在(RmsMeterDock/FreqResponseDock/PhaseDock/DrawerXiScope)· 已复用 test-aux/meter 共享组件 · 真根因 = 硬编码 node=sink-pre 不响应画布选中节点 · 修复 = useXiTestNodeBinding(28 行 · 选中模块联动 sink-pre/physical-input badge)+ 4 dock 各 77 行(共 308 行)+ index.vue(22 行调整)+ 测试 209 行(15 cases)· 共 7 文件 549 行 18 删除 · 验收:选普通模块→sink-pre badge · 选 source_device_v1→physical-input badge · 无选中→提示文案 · 15 测试全过 · ADR-08 §议题⑤ 用户验收闭环 · v1.5 铁律 truth-check 通过(uid/files/日期完全对齐) 35855b7