跳转至
ACCEPTED

ADR-AIOS-12 · XiTest Realtime Widget Workspace 架构与业务行为契约决议

v2.0 · Cline-AIOS 深化版 · 2026-05-29

基于用户起稿(§附录 A · 912 行 · 22 节功能清单)+ Demo HTML(04_development/frontend_vue3/docs/superpowers/specs/xitest-realtime-ui-demo.html · 1225 行单 widget 4 tab 示意)+ ADR-07 §1.3.4 三层分工铁律,深化为可派发决议。

核心收获:本 ADR 是 Cline-AIOS 调度内核回应用户 2026-05-28 "业务深度系统性缺失" 诊断的第一份"业务行为契约必填段"标杆示范。后续所有 ADR 必须按本 ADR §3 模板填 5 项契约,不再写"壳子框架"。


1. 上下文(Context)

1.1 触发事件

2026-05-29 11:38 用户在 06_docs/site-build/ Cline-AIOS 长会话中,基于前序 P4.U3-perf-visual-stub-upgrade(commit ceecccf)zombie 后的"业务深度核查",给出新指令:

用户原话(2026-05-29 11:38): "new ADR Xitest · 针对 xitest 的 realtime 以及右 dock 的 rms 频响 相位 scope 显示我们需要先完成,你在 07 号 adr 中只是初步的一个壳子框架。接下来我们针对这个功能做具体功能的详细设计。对标产品:1. Audio Precision APx500 2. Smaart suite 3. Ocenaudio。我让智能体初步实现了一个 demo,只是参考功能,具体的设计我会列出大体方向 D:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/docs/superpowers/specs/xitest-realtime-ui-demo.html。实时/realtime 功能详细定义以及页面布局参考 ADR-AIOS-XiTest-RealTime-Arch.md。"

2026-05-29 12:00 用户进一步纠偏 Cline-AIOS 第一轮跑偏方案:

用户原话(2026-05-29 12:00): "现在哪里有 tab,哪个 html 文件只是一个示意图,具体的布局已经在给你的 md 文件中有了啊,所有的测量都以类似控件的 widget 的方式拖入主界面,主界面的布局等规划也都给出来了 4.* 2 1 等显示格局配置,你是完全没读 md 么。realtime 的这些功能我都要,你可以先实施 realtime 的显示,后续的 sequence 实施但是不能不提这个需求。"

1.2 用户起稿(§附录 A · 912 行)真实需求图谱

真实规范 Cline-AIOS v1 误读(已纠正)
§三 整体结构 Top Toolbar + Left Dock + Realtime Dashboard(Widget-based) + Right Dock(Inspector)+ Bottom Dock 误读为 4 tab 切换
§六 Workspace Preset 4 套预设(Tuning / Electrical / Recording / Multi-channel)+ 用户自定义 误读为"任选 1 套"
§九-§十六 Measurement 库 完整 7 大类(Time Domain / Frequency / Transfer / Electrical / Recording / Validation / Utility) 误读为 4 tab 内嵌组件
§十六 Task Flow 5 类 Flow Node(Source / Measurement / Validation / Logic / Export)· 流程编排 误判为方向 B 砍掉
§十七 Dashboard Widget 拖拽 / Resize / Dock / Float / Split / Fullscreen / Save Layout / Multi-monitor · Main Widget + Mini Widget 误读为 fixed 4 tab
§十八 Right Dock Inspector 6 段通用结构(Source/Measurement/Display/Validation/Automation/Storage) + 每 widget 独立 Inspector 误读为左 sidebar 6 段固定
§十九 Snapshots 保存曲线/参数/Overlay/结果/布局 · Save/Compare/Golden/Export 仅识别为 A/B 快照(漏 Golden / 布局快照)
§二十一 Bottom Dock Console / Device Status / XRUN / Measurement Log / Task Queue / Validation Result 完全漏读
§二十二 统一工程核心 5 引擎(Measurement / Validation / Task / Storage / Visualization) 完全漏读

1.3 Demo HTML 真实定位(纠正)

xitest-realtime-ui-demo.html(1225 行)= 单个 Main Widget 全屏化呈现(等价于 Workspace = 1 widget × 4 个 tab 形态切换)· 不是整体布局蓝本。Cline-AIOS v1 把它当 MVP 蓝本,导致砍掉 Widget Workspace + 7 类 Measurement + Sequence。

Demo HTML 真实价值:展示了单个 widget 内部业务深度切片(FFT/平均/倍频/范围/曲线 6 段控件 + 频响双图 + Peak Hold 衰减 + A/B 快照 + 8 通道 RMS 网格)· 这些细节作为本 ADR §3 业务行为契约的实证素材写入(每契约段引用 Demo 哪部分 line range)。

1.4 真值核查发现(已知前置就位)

前端 P4-xitest 现状(P4.U3 zombie · ceecccf): - ✅ TestMode 5 联合(unit/integration/e2e/regression/realtime)+ stage chip - ✅ realtime mode = SpectrumChart + WaveformChart 2 stub(physical-input tap) - ✅ regression mode = RMSMeter + FreqResponseChart + PhaseChart 3 stub(sink-pre tap) - ✅ MeterNodeSelector + useMeterWs composable - ❌ Widget Workspace 框架完全缺失(无拖拽/Resize/Dock/Float/Split/Save Layout/Multi-monitor) - ❌ MeasurementNode 统一抽象完全缺失(每个 stub 是独立 vue · 无统一 input/processing/measurement/validation/visualization/automation/storage 7 子能力) - ❌ 4 套 Workspace Preset 完全缺失 - ❌ Right Dock Inspector 6 段通用结构完全缺失 - ❌ Sequence(Task Flow)schema + UI 入口完全缺失 - ❌ Bottom Dock 状态栏(Console / XRUN / Measurement Log / Task Queue / Validation Result)完全缺失

后端 P5-backend-csharp 现状(P5.U-meter-source-tap zombie · 4adda88): - ✅ MeterTapService 30fps WS + WASAPI 设备枚举 + sink-pre tap - ✅ PysidecarMeterBridge HTTP 桥接 P7 - ❌ 多 toolKind 路由完全缺失(当前只支持 RMS/FreqResp/Phase 3 类 · 不支持 Transfer/Spectrogram/Waveform/Electrical/Recorder) - ❌ WS 帧 schema 单一(无 toolKind 字段区分) - ❌ 限流策略缺失(当前所有客户端共享同一帧率)

P7-pysidecar 现状: - ✅ 19 个 REST 端点已实装(/analyze/freq_response / /analyze/rms / /analyze/phase / /analyze/coherence / /analyze/octave_band / /analyze/waterfall / ...) - ❌ 缺端点:/analyze/transfer_function(双通道传递函数 · Smaart 核心)//analyze/group_delay(群延迟)//analyze/peak_hold(P7 端 Peak Hold 状态机)//analyze/snapshot_diff(Golden 对比)//analyze/thd(THD/THD+N/SINAD)

契约 P_contracts: - ✅ protocol-v1 frozen(K1 sleeping-permanent) - ⚠️ ADR-07 §2.1.3 已记录 meter-source 扩展为 v2 候选 · 但 v2 未启动 - ⚠️ 本 ADR 触发 K2-protocol-v2 启动条件之一(与 ADR-08 / ADR-09 / ADR-10 共享 v2 命名空间)


2. 决议(Decision)

2.1 主决议 · Dockable+Workspace+Widget+Scene 混合架构(对齐 ADR-XiTune-AutoTune-layout §2)

核心理念(用户起稿 §三 + ADR-XiTune-AutoTune-layout §2 共享):

一个工程 = 一个声学工作空间(Workspace)
工作空间 = 一组 Widget × 一套布局 × 一组 Measurement Node × 一组 Engine

整体 UI 布局(用户起稿 §三 锁定):

┌─────────────────────────────────────────────────────────┐
│ Top Toolbar                                             │
├──────────────┬───────────────────────────────┬──────────┤
│ Left Dock    │      Realtime Dashboard       │ Right    │
│ Project Res  │      Widget-based Workspace   │ Inspector│
│ - Workspace  │      ┌─────┬─────┐            │ Source   │
│ - Session    │      │ FFT │ RMS │            │ Measure  │
│ - Engine     │      ├─────┼─────┤            │ Display  │
│ - Measurement│      │ Tx  │ Wav │            │ Validate │
│ - Recordings │      └─────┴─────┘            │ Automate │
│ - Snapshots  │                               │ Storage  │
│ - Validation │                               │          │
│ - Task Flow  │                               │          │
├──────────────┴───────────────────────────────┴──────────┤
│ Bottom Dock                                             │
│ Console | Device | XRUN | Measure Log | Task | Validate │
└─────────────────────────────────────────────────────────┘

2.2 子决议 · 5 引擎统一抽象(用户起稿 §二.2 + §二十二 锁定)

Engine 职责 本 ADR 实施范围
Measurement Engine 7 类 MeasurementNode 注册表 + 实时数据流 ✅ 本期完整实施(7 类)
Validation Engine Pass/Fail 判据 + Threshold/Mask/Tolerance/Golden ⏳ 本期 schema + UI 入口 · 判据算法留下季度
Task Engine 5 类 Flow Node(Source/Measurement/Validation/Logic/Export)· 流程编排 ⏳ 本期 schema + UI 入口 · 执行引擎留下季度
Storage Engine Snapshot / Recording / Workspace Layout 持久化 ✅ 本期实施 Snapshot + Layout · Recording 留下季度
Visualization Engine Widget 容器 + 拖拽 + Resize + Save Layout + Multi-monitor ✅ 本期完整实施

2.3 子决议 · MeasurementNode 统一抽象(本 ADR 核心契约)

用户起稿 §三.3 锁定的 7 子能力(每个 MeasurementNode 必含):

// types/measurement-node.ts(本 ADR v2.0 落盘 · ≤ 60 行)
export type MeasurementKind =
  | 'time-domain'      // §十(Waveform Scope / RMS Meter / Oscilloscope)
  | 'frequency'        // §十一(FFT Analyzer / RTA / Spectrogram)
  | 'transfer'         // §十二(Transfer Function · Smaart 核心)
  | 'electrical'       // §十三(Electrical Meter / Sweep Analyzer · APx500 核心)
  | 'recording'        // §十四(Recorder)
  | 'validation'       // §十五(Pass/Fail Compare)
  | 'utility'          // §九 Utility(Generator / Marker / Cursor 等)

export interface MeasurementNode {
  id: string
  kind: MeasurementKind
  type: string         // 具体子类型(如 'rms-meter' / 'fft-analyzer' / 'transfer-fn')

  // §九 7 子能力(每个 node 必含 · 本 ADR 锁定)
  input: NodeInput               // §2.4 Input(节点选择 + 通道映射)
  processing: ProcessingConfig   // 预处理(window/filter/gating)
  measurement: MeasurementConfig // 测量参数(fft-size/avg-type/threshold)
  validation?: ValidationRule    // 验证规则(threshold/mask/tolerance/golden)
  visualization: VizConfig       // 显示(scale/color/overlay/legend/dB-range)
  automation?: AutomationHook    // 自动化钩子(供 Task Flow 调用)
  storage: StorageConfig         // 持久化(snapshot/recording-buffer/golden-ref)
}

// 详细字段定义 · 见 §3 各 MeasurementNode 5 项业务行为契约

2.4 子决议 · NodeInput 节点选择(继承 ADR-07 §1.3.1 + 本 ADR 扩展)

ADR-07 已锁定 2 节点 · 本 ADR 不变更: - sink-pre:PC 模式 · 进入物理 sink 前的算法链路最终输出 · 后端 P5 sink-pre tap - physical-input:振声声卡 / mic · 后端 P5 WASAPI 采集

本 ADR 新增 NodeInput.channelMap(用户起稿 §八.1 Channel Map · 8 通道):

export interface NodeInput {
  node: 'sink-pre' | 'physical-input' | 'recording-replay'  // 第 3 类:回放录音(对接 §十四 Recorder)
  channels: number[]                  // 选通道(如 [0,1] L+R · [0,1,2,3,4,5,6,7] 8 声道)
  channelLabels?: string[]            // 用户标签(L/R/Ls/Rs/C/LFE/Lss/Rss)
  refChannel?: number                 // Transfer Function 用(参考通道)
  measureChannel?: number             // Transfer Function 用(测量通道)
}

2.5 子决议 · Widget 容器与 Workspace(用户起稿 §十七 锁定)

// types/dashboard-widget.ts(本 ADR v2.0 落盘 · ≤ 50 行)
export type WidgetState = 'docked' | 'floating' | 'fullscreen' | 'split-h' | 'split-v'
export type GridLayout = '2x2' | '4-row' | '2x1' | '1-full' | '4x1' | 'free'

export interface DashboardWidget {
  id: string
  measurementNodeId: string  // 关联 MeasurementNode
  layout: { x: number; y: number; w: number; h: number; zIndex: number }
  state: WidgetState
  monitor?: number           // 多屏 0/1/2(Multi-monitor 用)
  title?: string             // 用户自定义标题(覆盖 MeasurementNode.type 默认)
  collapsed?: boolean        // 折叠为 Mini Widget
}

export interface Workspace {
  id: string
  name: string                          // 4 套预设 + 用户自定义
  preset: 'tuning' | 'electrical' | 'recording' | 'multi-channel' | 'custom'
  widgets: DashboardWidget[]
  gridLayout: GridLayout
  measurementNodes: MeasurementNode[]   // 本 workspace 拥有的 node
  createdAt: number
  modifiedAt: number
}

§十七 8 大功能本 ADR 实施范围:

功能 本 ADR 实施 留下季度
Drag(拖拽) ✅ Phase 1 · vue-grid-layout 或自研
Resize(缩放) ✅ Phase 1
Dock(停靠) ✅ Phase 1
Float(浮动) ✅ Phase 1 · element-plus dialog 浮窗
Split(分屏) ✅ Phase 1 · Split-h / Split-v
Fullscreen(全屏) ✅ Phase 1 · 单 widget 占满 Dashboard
Save Layout(保存布局) ✅ Phase 3 · Workspace.widgets[] 持久化到 Storage Engine
Multi-monitor(多屏) ⏳ schema 留 monitor 字段 · UI 实施留下季度 🔜

2.6 子决议 · 4 套 Workspace Preset(用户起稿 §六 锁定)

Preset 用途 默认 Widget 组合 gridLayout
Tuning 调音(对标 Smaart) Transfer / FFT / Phase / RMS 2x2
Electrical AP 类电信号(对标 APx500) THD / SINAD / Scope / Generator 2x2
Recording 录音分析(对标 Ocenaudio) Waveform / Spectrogram / Markers 2x1
Multi-channel 车载多通道 RMS Matrix / Delay Matrix / Phase Matrix 4-row

2.7 子决议 · Right Dock Inspector 6 段通用结构(用户起稿 §十八 锁定)

当前选中 Widget → Inspector 显示 6 段(每段对应 MeasurementNode 的 1 个子能力):

┌─ Right Dock(Inspector · 当前 Widget=FFT) ─┐
│ § Source                                    │
│   - Node: [physical-input ▼]                │
│   - Channels: [☑L ☑R ☐Ls ...]               │
├─────────────────────────────────────────────┤
│ § Measurement                               │
│   - FFT Size: [4096 ▼]                      │
│   - Window: [Hanning ▼]                     │
│   - Average: [指数 8 次]                     │
├─────────────────────────────────────────────┤
│ § Display                                   │
│   - Scale: [对数 ▼]                         │
│   - dB Range: [80 dB]                       │
│   - Overlay: [☑ Peak Hold ☐ Golden]         │
├─────────────────────────────────────────────┤
│ § Validation                                │
│   - [+ 添加 Pass/Fail 规则]                 │
├─────────────────────────────────────────────┤
│ § Automation                                │
│   - [☐ 加入 Task Flow]                      │
├─────────────────────────────────────────────┤
│ § Storage                                   │
│   - [💾 Save Snapshot] [📁 Load Golden]    │
│   - [⏺ Start Recording]                    │
└─────────────────────────────────────────────┘

Inspector 复用机制:6 段是通用容器 · 每段内具体控件由 MeasurementNode.kind/type 决定(参考用户起稿 §十八 FFT Inspector / Transfer Inspector / Recorder Inspector 表格)。Phase 1 实施容器 + FFT/RMS/Transfer/Phase/Waveform 5 个 Inspector · 其他 Inspector(Spectrogram/THD/Sweep/Recorder)留 Phase 2-3。

2.8 子决议 · Bottom Dock 状态栏(用户起稿 §二十一 锁定)

┌─ Bottom Dock(高度 ~22-32px) ────────────────────────────────────┐
│ Console▾ │ Device Status │ XRUN: 0 │ Measure Log▾ │ Tasks: 0 │ ✓ │
└────────────────────────────────────────────────────────────────┘
内容 实施范围
Console INFO/WARNING/ERROR/DEVICE/SCRIPT 5 级日志 · 可折叠 ✅ Phase 1
Device Status Clock Lock / Sample Rate / Buffer / XRUN / CPU ✅ Phase 1(WS 推送)
XRUN 计数器 红色 badge · 累计 XRUN 次数 ✅ Phase 1
Measurement Log 最近 N 次测量结果(可点击跳回 widget) ✅ Phase 2
Task Queue 当前运行/排队的 Task Flow / Recording / Export ⏳ Phase 4 占位
Validation Result 最新一次 Pass/Fail 结果 + 链接 ⏳ Phase 4 占位

2.9 子决议 · Sequence(Task Flow)占位(用户起稿 §十六 + 用户原话"后续实施但不能不提")

本 ADR 锁定 schema + UI 入口 · 不实施执行引擎:

// types/task-flow.ts(本 ADR v2.0 落盘 · ≤ 50 行)
export type FlowNodeKind = 'source' | 'measurement' | 'validation' | 'logic' | 'export'

export interface FlowNode {
  id: string
  kind: FlowNodeKind
  type: string                  // 具体类型(如 source 下:'playback-sweep' / 'playback-pink-noise')
  config: Record<string, unknown>
  inputs: string[]              // 上游 FlowNode id
  outputs: string[]             // 下游 FlowNode id

  // 占位字段 · Phase 4 不实施执行
  status?: 'pending' | 'running' | 'pass' | 'fail' | 'skip'
  result?: unknown
  startedAt?: number
  completedAt?: number
}

export interface TaskFlow {
  id: string
  name: string
  nodes: FlowNode[]
  trigger: 'manual' | 'scheduled' | 'on-event'
  // 执行引擎相关字段 · 留下季度
}

5 类 Flow Node 抽象(用户起稿 §十六):

Kind 子类型示例 用途
Source playback-sweep / playback-pink / playback-mls / record-input 信号产生/输入
Measurement fft-snapshot / rms-1s / transfer-fn / thd-meter 触发测量 + 抓数据
Validation threshold-compare / golden-compare / mask-test Pass/Fail 判据
Logic if-condition / wait-ms / loop-n 流程控制
Export report-pdf / csv-dump / image-snapshot 结果导出

Phase 4 实施范围: - ✅ types/task-flow.ts schema 落盘 - ✅ Left Dock § Task Flow 段 UI 入口(列表 + "新建 Flow"按钮) - ✅ Bottom Dock § Task Queue 占位段 - ❌ 执行引擎不实施(无 FlowNode 真跑 · 用户期望后续季度做) - ❌ 5 类 Flow Node 具体子类型不实施(仅 schema)

2.10 子决议 · 三层分工铁律(继承 ADR-07 §1.3.4)

进程 本 ADR v2.0 新增职责
L1 I/O P5-backend-csharp ① MeterTapService 扩展 toolKind 路由(7 类 MeasurementNode 各路由 P7 端点)② WS 帧 schema 加 toolKind 字段 ③ 限流 30fps/tool/client ④ Bottom Dock Device Status 推送(WASAPI 状态 + XRUN 计数 + CPU 占用)
L2 数学 P7-pysidecar ① 新增 5 端点:/analyze/transfer_function / /analyze/group_delay / /analyze/peak_hold / /analyze/snapshot_diff / /analyze/thd ② 现有 19 端点 schema 升级(返回值加物理元信息字段:resolution / noiseFloorDb / averagedCount)
L3 显示 前端 ① Widget Workspace 框架 ② 7 类 MeasurementNode 实施 ③ Right Dock Inspector 6 段 ④ 4 套 Workspace Preset ⑤ Bottom Dock 状态栏 ⑥ Sequence schema + UI 入口 · 零数学

2.11 边界铁律(强制约束)

  1. Widget 容器内禁止业务逻辑:Widget = 容器 + Measurement 引用 · 业务逻辑必须封装在 MeasurementNode 内
  2. MeasurementNode 7 子能力不可拆:任何新 MeasurementNode 实施必须填齐 7 子能力(input/processing/measurement/validation/visualization/automation/storage)· 缺任一 = 派发拒绝
  3. 5 项业务行为契约必填:任何新 MeasurementNode 派发前必须填齐 §3 5 段(MeterDataFrame schema + 收敛判据 + 失败回退 + 用户操作流 + 端到端真值 e2e)
  4. 三层分工铁律不可破:前端零数学 · P5 零数学 · P7 全部数学(继承 ADR-07 §1.3.4)
  5. Sequence 执行引擎本期禁止实施:仅 schema + UI 入口 · 任何"顺手做执行"提议拒绝 · 必须新起 ADR 修订
  6. Workspace Preset 4 套不可减:Tuning/Electrical/Recording/Multi-channel 是用户锁定的 · 任何减项需新起 ADR
  7. Multi-monitor schema 留 · UI 不做:DashboardWidget.monitor 字段必须保留 · 但 UI 实施留下季度
  8. 响应式适配横竖屏(v2.2 新增 · 用户拍板 2026-05-30 12:50):所有 xitest Widget(主界面)+ 右 dock(Inspector)+ 底栏(Bottom Dock)必须支持横竖屏切换 · 横屏(宽 ≥ 高)布局 vs 竖屏(高 > 宽)布局两套响应式断点 · 实施侧:用 ResizeObserver 监听容器尺寸 + CSS @container query / aspect-ratio 媒体查询 + Pinia widgetLayoutStore 暴露 orientation: 'landscape' | 'portrait' 派生状态 · 后续 xitest fork prompt 必须含此约束 · 验收必须包含横竖屏 e2e(playwright 改 viewport 1920×1080 vs 1080×1920 各跑一次)
  9. 主题色系切换(v2.2 新增 · 用户拍板 2026-05-30 12:50):所有色系搭配必须满足主题切换(浅色 / 深色 / 自定义)· 严禁硬编码 hex 色值(#fff / #000 / rgba(...) 在 .vue / .css 中均禁)· 必须用 design-token / CSS variable(如 var(--xs-color-primary) / var(--xs-bg-elevated-1))· 实施侧:对齐主仓 frontend_vue3/src/styles/design-tokens.css 现有 token 体系 · 新增 token 必须先在 design-tokens.css 中声明 · 后续 xitest fork prompt 必须含此约束 · 验收必须 grep 证明本 fork 改动文件无硬编码 hex(允许在 design-tokens.css 内定义)

§2.11 第 8+9 项作为后续 xitest 任务全局红线(适用范围:ADR-12 Phase 3+ 所有 MeasurementNode fork / ADR-08 §2.1 议题⑤ DrawerXiTest 后续迭代 / ADR-11 v1.3 fork 1-v3 4 Tab Widget · 等)。已 zombie 的 ADR-12 #5/#6/#7 不追溯 · 但下一轮迭代必须补齐。本红线已于 2026-05-30 13:00 直接内联到 P0.U-measurement-thd-snr + P0.U-measurement-impulse-spectrogram 两 prompt(避免 ADR 回写延迟阻塞派发)。

§2.11 第 8+9 项前后端责任边界(v2.3 新增 · 用户 2026-05-31 11:49 洞察:"刚刚添加的内容好像都是前端 · 后端是否需要接口对应的变化"):

明确边界:第 8+9 项纯前端 UI 渲染范畴 · P5/P7 后端无需适配 · 现有数据契约不变

§2.11 第 8 项响应式横竖屏: - ✅ 前端责任(L3 显示):ResizeObserver / CSS @container query / widgetLayoutStore.orientation 派生 state / playwright viewport e2e - ❌ P5 不参与:WS 帧 schema 不带 widget 像素尺寸 · 30fps 推送频率与 widget 大小完全无关(前端按容器尺寸独立渲染) - ❌ P7 不参与:numpy/scipy 计算颗粒度由 fftSize/sampleRate 决定 · 与 widget 像素数完全无关(前端可任意缩放数据点)

§2.11 第 9 项主题色系切换: - ✅ 前端责任(L3 显示):design-token / CSS variable / 浅色/深色/自定义主题 / playwright 截图对比 e2e - ❌ P5 不参与:WS 帧 schema 仅推数值数据(rmsDb / magsDb / phaseDeg 等)· 不推任何颜色/样式信息 - ❌ P7 不参与:即使 spectrogram colormap 也是 P7 推 magDb 矩阵 + 前端 Canvas 用 design-token 渲染 · P7 端无需感知配色

历史任务后端适配核查(回应用户 2026-05-31 11:49 提问): - ADR-12 Phase 1 #1+#8(P0.U-meter-types-v3 9fc31c4 + P5.U-meter-tap-multi-tool 48cf0ba):后端只扩 toolKind 路由 + WS 帧 schema · 不涉及响应式/主题 · 无需补 - ADR-12 Phase 2 #5/#6/#7(8379de2 + 600f0fc + 729327c):全前端组件 · 后端复用 Phase 1 已就位的 toolKind 路由 · 不涉及响应式/主题 · 无需补 - ADR-09 后端 fork(P5.UA9-plugin-registry-service / P6.UA9-plugin-abi-v1):plugin 架构 · 不涉及响应式/主题 · 无需补 - ADR-08 后端三 fork(8238c4d + 41ad8d9 + b43c35a):error-channel / perf-service / runtime-mode-refactor · 不涉及响应式/主题 · 无需补 - ADR-11 v1.3 fork 1b-v2(P5.U-autotune-vehicle-config-extend · 1.0d ClaudeB · dispatched 中):VehicleConfig schema + IR 持久化 · 不涉及响应式/主题 · 无需补

结论:全栈所有历史任务无需为响应式 + 主题切换做后端适配 · 现有数据契约保持不变。后续若发现确有跨栈联动场景(如"P7 端口推送 widget 尺寸建议"等创新需求)· 必须新起 ADR-AIOS-12-RX 修订本边界。


3. 业务行为契约(Business Behavior Contract · 本 ADR 核心 · 7 类 MeasurementNode × 5 项契约)

本节是 Cline-AIOS 调度内核回应用户 2026-05-28 "业务深度系统性缺失"诊断的核心交付物。每类 MeasurementNode 必须填齐 5 项契约,任何派发缺契约 = 立即拒绝。

5 项契约必填段: 1. 输入/输出契约(MeterDataFrame schema 物理意义 · 字段单位 · 采样率 · 通道映射) 2. 收敛/成功判据(测量稳定阈值 · 信号存在判据 · 帧率达标) 3. 失败回退路径(5 类失败场景 + UI 表现 + 恢复路径) 4. 用户操作流(端到端 5 步 · 鼠标轨迹 · 关键交互) 5. 端到端真值 e2e(用户场景必跑通 · 不只是 typecheck/build/test 形式合规)

3.1 RMS Meter Node(time-domain · type='rms-meter' · §十.2)

① 输入/输出契约

export interface MeterFrame_RMS {
  kind: 'rms-meter'
  node: 'sink-pre' | 'physical-input' | 'recording-replay'
  timestamp: number          // P5 采集时间戳(ms · 单调时钟)
  sampleRate: 48000 | 44100 | 96000

  channels: number           // 通道数(默认 8)
  channelLabels: string[]    // ['L','R','Ls','Rs','C','LFE','Lss','Rss']

  // 8 通道并行数据
  rmsDb: number[]            // 各通道 RMS(dBFS · 0=满量程 · -∞=静音 · 长度=channels)
  peakDb: number[]           // 各通道瞬时 Peak(dBFS)
  peakHoldDb: number[]       // 各通道 Peak Hold(dBFS · P7 端衰减系数 0.998/帧)

  // 可选附加(用户在 Inspector 启用)
  lufsIntegrated?: number[]  // 响度(LUFS · ITU-R BS.1770)
  crestFactor?: number[]     // 峰均比(dB · peakDb - rmsDb)

  // 时间常数
  averagingType: 'fast' | 'slow' | 'instant'    // fast=125ms · slow=1s · instant=10ms

  // 物理元信息
  noiseFloorDb: number       // 当前估计噪声地板
}

② 收敛/成功判据

判据 阈值 含义
通道映射已锁定 channelLabels.length === channels 用户在 Engine.Channel Map 配过通道顺序
帧率达标 前端实测 FPS ≥ 25(目标 30) UX 可接受
静音判定 rmsDb[i] < noiseFloorDb + 3dB → 该通道 bar 灰显 区分"无信号"与"低信号"
过载判定 peakDb[i] > -1dBFS 持续 100ms → bar 红闪 提示用户降增益

③ 失败回退路径

失败 触发 UI 表现 恢复路径
WS 断开 P5 WS heartbeat 超时 5s 全 8 bar 灰显 + 顶栏红点 + "已断开 · 重连中…" 自动重连 ½/4/8/16/30s 指数退避
单通道断开 P5 WASAPI 报告 channel[i] 故障 该通道 bar 灰显 + 标签红框 不影响其他通道 · 用户检查物理接线
P7 sidecar 崩溃 P5 收到 HTTP 502 from :8001 全 bar 灰显 + "分析后端不可用" P5 自动重启 P7 + health-check
通道映射不一致 channelLabels.length ≠ channels 顶栏黄警 + "通道映射未锁定 · 请配 Channel Map" 用户跳到 Left Dock § Engine 配置
数据帧倒序 timestamp 倒退 > 100ms 静默丢弃 + 计数器 +1 · 累计 ≥ 10 帧/s 上报 dev-tools 通常是 P5/P7 时钟漂移

④ 用户操作流

Step 1 · 拖入 Widget
  Left Dock § Measurements → 拖 'RMS Meter' 到 Dashboard
  → 自动创建 MeasurementNode(kind=time-domain · type=rms-meter)+ Widget(2x1 默认)

Step 2 · 选源(Right Inspector § Source)
  Node: [physical-input ▼] · Channels: [☑L ☑R ☑Ls ☑Rs ☑C ☑LFE ☑Lss ☑Rss]
  → 实时下发 P5 · 切换时清空 Peak Hold

Step 3 · 配置(Right Inspector § Measurement)
  Averaging Type: [Fast ▼] / [Slow] / [Instant]
  ☑ Peak Hold(衰减时间:3s)
  ☑ Show Crest Factor

Step 4 · 观察
  8 bar 实时刷新(30fps)· 数值显示在 bar 下方 · Peak Hold 红线衰减
  bar 颜色梯度:< -20dB 青绿 · -20 to -3dB 黄 · > -3dB 红
  右键单通道 bar → "聚焦此通道"(联动 FFT widget filter)

Step 5 · 快照(Right Inspector § Storage)
  [💾 Save Snapshot] → 保存当前 8 通道 RMS 值 + 时间戳到 Workspace.snapshots
  [📁 Compare with Golden] → 加载 Golden RMS 值 · bar 旁显示 ΔdB

⑤ 端到端真值 e2e

// e2e/rms-meter-truth.spec.ts(Phase 4 · ClaudeC 写)
test('RMS Meter · 8 通道注入 -20dBFS 粉噪 · 8 bar 应都在 -20±1dB', async ({ page }) => {
  // 前置:测试夹具向声卡 8 通道注入 -20dBFS 粉噪 · sample-accurate
  await page.goto('/xitest?mode=realtime')
  await dragMeasurementToCanvas(page, 'rms-meter')
  await selectNode(page, 'physical-input')
  await selectChannels(page, [0,1,2,3,4,5,6,7])

  // 等稳定 8 帧
  await page.waitForFunction(() => window.__xitestDebug.getRmsAveragedCount() >= 8, { timeout: 5000 })

  // 真值断言:8 通道 RMS 都应在 -20±1dB
  for (let i = 0; i < 8; i++) {
    const rms = await page.evaluate((idx) => window.__xitestDebug.getRmsDb(idx), i)
    expect(rms).toBeGreaterThan(-21)
    expect(rms).toBeLessThan(-19)
  }
})

test('RMS Meter · 单通道 -3dBFS 1kHz 正弦 · Peak Hold 应稳定在 -3dB', async ({ page }) => {
  await injectChannel(0, '1kHz sine -3dBFS')
  // 等 Peak Hold 锁定
  await page.waitForFunction(() => window.__xitestDebug.getPeakHoldDb(0) > -4, { timeout: 3000 })
  const peakHold = await page.evaluate(() => window.__xitestDebug.getPeakHoldDb(0))
  expect(peakHold).toBeGreaterThan(-3.5)
  expect(peakHold).toBeLessThan(-2.5)
})

3.2 FFT Analyzer Node(frequency · type='fft-analyzer' · §十一.1)

① 输入/输出契约

export interface MeterFrame_FFT {
  kind: 'fft-analyzer'
  node: 'sink-pre' | 'physical-input' | 'recording-replay'
  timestamp: number
  sampleRate: 48000 | 44100 | 96000

  fftSize: 1024 | 4096 | 8192 | 16384 | 32768
  window: 'hanning' | 'hamming' | 'blackman' | 'flat-top' | 'rect'
  overlap: 0 | 0.5 | 0.75 | 0.875

  // bins 数据(物理意义明确)
  freqs: Float32Array          // bin 中心频率(Hz · 长度=fftSize/2+1)
  magsDb: Float32Array         // 幅度(dBFS · 长度同 freqs)

  // 平均状态(P7 端维护)
  averagedCount: number        // 当前已平均帧数
  averagingType: 'linear' | 'exponential' | 'peak'
  averagingTarget: number      // 目标平均次数(8/16/32/64/128)

  // 倍频程(用户起稿 §十一.2 RTA)
  octaveBand?: 'off' | '1/1' | '1/3' | '1/6' | '1/12' | '1/24'
  octaveData?: Float32Array    // 倍频程数据(若 octaveBand !== 'off')

  // Peak Hold(P7 端状态机)
  peakHoldDb?: Float32Array    // 同 magsDb 长度 · 衰减 0.995/帧

  // 物理元信息
  resolution: number           // Hz/bin = sampleRate/fftSize
  noiseFloorDb: number
}

② 收敛/成功判据

判据 阈值 含义
测量稳定 averagedCount ≥ averagingTarget AND std(magsDb[100~10kHz]) < 0.5dB 频谱稳定可读
信号存在 mean(magsDb[20~20kHz]) > noiseFloorDb + 6dB 不是纯噪声
帧率达标 前端实测 FPS ≥ 25 UX 可接受
分辨率达标 resolution = sampleRate/fftSize · 用户在 Inspector 看到状态栏更新 物理意义可解释

③ 失败回退路径

失败 触发 UI 表现 恢复路径
WS 断开 同 §3.1 图灰显 + "已断开" 同 §3.1
FFT 配置不合法 overlap=0.875 + fftSize=32768 + sampleRate=44100 → P7 计算超时 顶栏红警 + "配置过载 · 已自动降级" P7 自动降到 overlap=0.75
信号过弱 mean(magsDb) < noiseFloorDb + 3dB 顶栏黄警 + "信号过弱 ⚠️" 用户增大输入增益
频谱泄漏严重 单频信号 → 邻 bin 衰减 < 6dB(窗函数选错) Inspector § Measurement 提示 "建议选 Flat Top 窗" 用户切窗函数
过载/clipping magsDb 任一 bin > -1dBFS 持续 100ms 该频段红色闪烁 用户调输入增益

④ 用户操作流

Step 1 · 拖入 Widget
  Left Dock § Measurements → 'FFT Analyzer' → 拖到 Dashboard

Step 2 · 选源(Inspector § Source)
  Node: [physical-input ▼] · Channels: [☑ L]

Step 3 · 配 FFT(Inspector § Measurement)
  FFT Size: [4096 ▼](状态栏立即显示分辨率 = 11.7 Hz/bin)
  Window: [Hanning ▼]
  Overlap: [75% ▼]
  Averaging: [指数 8 次] · ☑ Peak Hold(3s 衰减)

Step 4 · 配显示(Inspector § Display)
  Scale: [对数 ▼]
  dB Range: [80dB] · Reference: [0dB]
  ☑ 1/3 Oct Smoothing

Step 5 · 观察 + 测量
  鼠标 hover → 十字游标 + "1.2 kHz · -23.4 dB"
  右键 → "标记此点"(添加 Cursor)
  双击空白 → 回到默认视图
  [💾 Snapshot A] → [💾 Snapshot B] → 切 [双曲线模式] 对比

⑤ 端到端真值 e2e

test('FFT · physical-input 注入 1kHz -10dBFS 正弦 · 应在 1kHz 处出现 -10±1dB 峰', async ({ page }) => {
  await injectChannel(0, '1kHz sine -10dBFS')
  await dragMeasurementToCanvas(page, 'fft-analyzer')
  await configFFT(page, { size: 4096, window: 'hanning', overlap: 0.75 })

  await page.waitForFunction(() => window.__xitestDebug.getFftAveragedCount() >= 8)

  const peakBin = await page.evaluate(() => window.__xitestDebug.getFftPeakBinFreq())
  expect(peakBin).toBeGreaterThan(950)
  expect(peakBin).toBeLessThan(1050)

  const peakDb = await page.evaluate(() => window.__xitestDebug.getFftPeakDb())
  expect(peakDb).toBeGreaterThan(-11)
  expect(peakDb).toBeLessThan(-9)
})

test('FFT · sink-pre 加载 PEQ +6dB@1kHz Q=2 · 1kHz 比 100Hz/10kHz 高 5~7dB', async ({ page }) => {
  await loadPreset(page, 'peq-plus-6db-at-1khz-q2')
  await injectChannel(0, 'pink-noise -20dBFS')
  await selectNode(page, 'sink-pre')

  await page.waitForFunction(() => window.__xitestDebug.getFftAveragedCount() >= 16)

  const ref = await page.evaluate(() =>
    (window.__xitestDebug.getFftDbAt(100) + window.__xitestDebug.getFftDbAt(10000)) / 2
  )
  const peak = await page.evaluate(() => window.__xitestDebug.getFftDbAt(1000))
  expect(peak - ref).toBeGreaterThan(5)
  expect(peak - ref).toBeLessThan(7)
})

3.3 Transfer Function Node(transfer · type='transfer-fn' · §十二 · Smaart 核心)

① 输入/输出契约

export interface MeterFrame_Transfer {
  kind: 'transfer-fn'
  node: 'physical-input'                // 仅 physical-input 双通道(ref + measure)
  timestamp: number
  sampleRate: number
  fftSize: number

  refChannel: number                    // 参考通道(发声端 · 已知信号)
  measureChannel: number                // 测量通道(mic · 实测响应)

  // 双通道传递函数核心数据
  freqs: Float32Array                   // bin 频率
  magnitudeDb: Float32Array             // 幅频响应(dB · 测量/参考)
  phaseWrapped: Float32Array            // 相位 wrapped(°· ±180)
  phaseUnwrapped?: Float32Array         // 相位 unwrapped(°· 连续)
  groupDelay?: Float32Array             // 群延迟(ms · -dφ/dω)
  coherence: Float32Array               // 相干性(0~1 · 测量可信度)

  // 延时查找(Smaart Delay Finder)
  delayFinderMs?: number                // 检测到的最佳延时(ms)· null=未锁定
  delayLocked: boolean                  // 延时已锁定

  averagedCount: number
  coherenceThreshold: number            // 用户设定阈值(默认 0.7)

  // 物理元信息
  resolution: number
}

② 收敛/成功判据

判据 阈值 含义
延时已锁定 delayLocked === true · 跨 averagedCount ≥ 16 帧不变 Smaart 双通道核心条件
相干性达标 mean(coherence[100~10kHz]) > coherenceThreshold(默认 0.7) 测量可信度高
测量稳定 std(magnitudeDb[100~10kHz]) < 0.5dB(连续 8 帧) 频响曲线稳定
信号在两通道都存在 refChannel rms > -40dBFS AND measureChannel rms > -40dBFS 双通道都有声

③ 失败回退路径

失败 触发 UI 表现 恢复路径
延时未锁定 delayFinderMs 跨 5s 仍 null "Delay Finder 未锁定 · 检查参考信号" 用户检查 ref 通道是否有信号
相干性过低 mean(coherence) < 0.3 全图灰显 + "相干性过低 · 增大信号 / 减少噪声" 用户增大发声音量
单通道断开 ref 或 measure 通道无信号 顶栏红警 + 标识哪个通道断 检查物理接线
相位环绕异常 unwrapped 相位跨 360° 跳变 "相位环绕异常 · 切 Wrapped 模式" 用户切显示模式
通道选择错误 refChannel === measureChannel 派发拒绝(Validation Engine 拦截)+ 红警 用户重选不同通道

④ 用户操作流

Step 1 · 准备(场景:扩声系统调音)
  舞台 console → 调音台 → DSP → 功放 → 扬声器 → 麦克风 → 声卡(2 通道:ch0=参考 ch1=mic)

Step 2 · 拖入 Widget · 选 Tuning Workspace Preset
  Left Dock § Workspace → "Tuning"(自动加载 Transfer/FFT/Phase/RMS 4 widget · 2x2)

Step 3 · 配 Transfer(Inspector § Source/Measurement)
  Ref Channel: [ch0 ▼] · Measure Channel: [ch1 ▼]
  Delay Tracking: [☑ 自动]
  Coherence Threshold: [0.7]

Step 4 · 启动测量
  Top Toolbar [▶ Run] → 播放粉噪 / 扫频 → 等延时锁定(3-5s)
  状态栏显示 "Delay Locked: 4.2 ms · Coherence: 0.85"

Step 5 · 阅读 + 优化
  Magnitude 曲线 → 看哪些频段超出目标 ± 3dB
  Phase 曲线 → 看分频点是否对齐
  右键 → "导出当前测量到 Snapshot" → Tuning Workspace 保存
  Right Inspector § Validation → 加 Mask 规则(如 ±3dB tolerance) → Pass/Fail

⑤ 端到端真值 e2e

test('Transfer · 已知 4ms 延时 · Delay Finder 应锁定 4±0.5ms', async ({ page }) => {
  // 前置:测试夹具 ch0=参考粉噪 · ch1=参考粉噪延迟 4ms 后注入
  await injectStereo('pink-ref', 'pink-delayed-4ms')
  await loadWorkspace(page, 'tuning')
  await configTransfer(page, { ref: 0, measure: 1 })

  await page.waitForFunction(() => window.__xitestDebug.isTransferDelayLocked(), { timeout: 8000 })

  const delay = await page.evaluate(() => window.__xitestDebug.getTransferDelayMs())
  expect(delay).toBeGreaterThan(3.5)
  expect(delay).toBeLessThan(4.5)
})

test('Transfer · 在 ch1 加 PEQ -3dB@1kHz · transfer 曲线应在 1kHz 显示 -3±0.5dB', async ({ page }) => {
  await loadPreset(page, 'peq-minus-3db-at-1khz')
  await injectStereo('pink-ref', 'pink-via-peq')

  await page.waitForFunction(() => window.__xitestDebug.getTransferAveragedCount() >= 16)

  const mag1k = await page.evaluate(() => window.__xitestDebug.getTransferMagDb(1000))
  expect(mag1k).toBeGreaterThan(-3.5)
  expect(mag1k).toBeLessThan(-2.5)
})

3.4 Phase Meter Node(frequency · type='phase-meter' · §十一/§十八 共享)

① 输入/输出契约

export interface MeterFrame_Phase {
  kind: 'phase-meter'
  node: 'sink-pre' | 'physical-input'
  timestamp: number
  sampleRate: number
  fftSize: number

  freqs: Float32Array
  phaseWrapped: Float32Array            // ±180°
  phaseUnwrapped?: Float32Array         // 用户在 Inspector 启用
  groupDelay?: Float32Array             // ms · 用户在 Inspector 启用

  averagedCount: number

  // 物理元信息
  resolution: number
}

② 收敛/成功判据

判据 阈值 含义
测量稳定 std(phaseWrapped[100~10kHz]) < 5°(连续 8 帧) 相位曲线稳定
群延迟可读 groupDelay 全段无 NaN/Inf 数值合法

③ 失败回退路径(同 FFT · 略)

④ 用户操作流(简版)

拖 'Phase Meter' → 选源 → 选模式(Wrapped / Unwrapped / Group Delay)→ 观察

⑤ 端到端真值 e2e

test('Phase · 注入纯 1kHz 正弦 · 1kHz 处相位应稳定(std < 5°)', async ({ page }) => {
  await injectChannel(0, '1kHz sine -10dBFS')
  await dragMeasurementToCanvas(page, 'phase-meter')

  await page.waitForFunction(() => window.__xitestDebug.getPhaseAveragedCount() >= 16)

  const phaseStd = await page.evaluate(() => window.__xitestDebug.getPhaseStdAt(1000))
  expect(phaseStd).toBeLessThan(5)
})

3.5 Waveform Scope Node(time-domain · type='waveform-scope' · §十.1)

① 输入/输出契约

export interface MeterFrame_Waveform {
  kind: 'waveform-scope'
  node: 'sink-pre' | 'physical-input' | 'recording-replay'
  timestamp: number
  sampleRate: number

  channels: number
  bufferSize: number                    // 抓取长度(samples · 100ms-5s)
  samples: Float32Array[]               // 各通道波形(长度=channels × bufferSize)

  // 触发(用户起稿 §十.1)
  triggered: boolean
  triggerLevel?: number                 // dBFS(-60 ~ 0)
  triggerEdge?: 'rising' | 'falling'
  preRollPercent?: number               // 0-100% · 预触发长度

  // 冻结
  frozen: boolean                       // 用户按 Freeze 后停止刷新
}

② 收敛/成功判据

判据 阈值 含义
触发已捕获 triggered === true(若启用 trigger) 抓到目标波形
缓冲已填满 samples.length === bufferSize 完整一段波形

③ 失败回退路径(简版)

失败 触发 UI 表现
触发等待超时 60s 未触发 "等待触发超时 · 降低 trigger level"
数据丢帧 后端 P5 报告 buffer underrun 顶栏红警 + XRUN 计数 +1

④ 用户操作流(简版 · 对应 Demo HTML 时域抓取 tab)

拖 'Waveform Scope' → 选源 → 配触发(level / edge / preroll)→ [⏺ Record] →
触发后停止 → [💾 Snapshot A] → 重新触发 → [💾 Snapshot B] → 切 Overlay 对比

⑤ 端到端真值 e2e

test('Waveform · 注入 1kHz 方波 · trigger 锁后 buffer 应包含完整周期', async ({ page }) => {
  await injectChannel(0, '1kHz square -6dBFS')
  await dragMeasurementToCanvas(page, 'waveform-scope')
  await configWaveform(page, { triggerLevel: -10, edge: 'rising', preroll: 20 })

  await page.waitForFunction(() => window.__xitestDebug.isWaveformTriggered(), { timeout: 5000 })

  // 真值:1ms 内应有完整方波周期(1kHz period = 1ms)
  const periodSamples = await page.evaluate(() => window.__xitestDebug.getWaveformPeriodSamples())
  expect(periodSamples).toBeGreaterThan(46)  // 48000Hz · 1kHz · 48 samples
  expect(periodSamples).toBeLessThan(50)
})

3.6 Electrical Meter Node(electrical · type='electrical-meter' · §十三 · APx500 核心)

本期 Phase 2 仅实施 schema + 显示 stub · THD/SINAD/SNR 算法实施需 P7 新增 /analyze/thd 端点。

① 输入/输出契约

export interface MeterFrame_Electrical {
  kind: 'electrical-meter'
  node: 'physical-input'
  timestamp: number

  // 用户起稿 §十三 全字段
  vrms: number[]               // 电压(V · 各通道)
  dbu: number[]                // 电平(dBu · 0.775V=0dBu)
  frequency: number[]          // 主频率(Hz)
  thd: number[]                // 谐波失真(%)
  thdN: number[]               // THD+N(%)
  sinad: number[]              // SINAD(dB)
  snr: number[]                // 信噪比(dB)

  // 校准状态
  calibrated: boolean          // 用户在 Engine § Calibration 配过校准
  calibrationDate?: number
}

②-⑤ 略(本期 Phase 2 实施 stub · Phase 4 真值 e2e 需 AP 测试夹具配合)


3.7 Recorder Node(recording · type='recorder' · §十四)

本期 Phase 3 仅实施 schema + UI 入口 + 内存 ring buffer · 文件持久化(.wav 多轨)留下季度。

① 输入/输出契约

export interface RecordingSession {
  id: string
  startedAt: number
  stoppedAt?: number
  durationMs: number
  channels: number
  sampleRate: number
  bufferMode: 'ring' | 'continuous'    // ring=固定长度循环 · continuous=持续到 stop
  bufferSizeMs: number                 // ring buffer 长度
  markers: Array<{ at: number; label: string }>
  preRollMs: number
  triggerConfig?: TriggerConfig
}

②-⑤ 略


4. 后果(Consequences)

4.1 正面后果

业务行为契约必填段:7 类 MeasurementNode × 5 项契约示范 · 后续所有 ADR 模板对齐 · 杜绝"壳子框架" ✅ Widget Workspace 解锁专业 UX:对标 Smaart/APx500/Ocenaudio 的工程师交互(拖拽/Resize/Save Layout/Multi-monitor schema) ✅ MeasurementNode 统一抽象:7 类 × 7 子能力 · 任何新 Measurement(STIPA/RT60 等)按模板派生 · 不重复造轮子 ✅ 4 套 Workspace Preset:Tuning(Smaart)/Electrical(APx500)/Recording(Ocenaudio)/Multi-channel(车载) · 用户一键切场景 ✅ Sequence 占位不丢需求:Task Flow schema + UI 入口本期落 · 执行引擎留下季度 · 回应用户"不能不提" ✅ 三层分工铁律延续:前端零数学 · P5 仅 I/O · P7 全部数学 · 继承 ADR-07 §1.3.4 ✅ 三 ADR 平行推进:本 ADR + ADR-XiTune-AutoTune + ADR-XiTune-AutoTune-layout 共享 Dockable+Workspace+Widget+Scene 架构

4.2 负面后果与缓解

后果 影响 缓解
⚠️ Widget Workspace 框架工作量大 Phase 1 需 5d · 阻塞后续 Phase 选成熟方案 vue-grid-layout · 不自研
⚠️ 7 类 MeasurementNode 全实施 Phase 2 需 8d · ClaudeA/D 并行高强度 拆 7 个独立 U-thread · 各 1.0-1.5d · 并行
⚠️ Inspector 6 段 × 7 类组合 每组合需独立子组件 · 工作量 ×N Inspector 容器抽象 · 子段按 MeasurementNode.type 路由 · DRY
⚠️ Sequence schema 落但执行不实 用户可能误以为可用 Top Toolbar [▶ Run Sequence] 按钮灰显 + tooltip "Phase 4 占位 · 执行引擎下季度"
⚠️ Multi-monitor schema 留 UI 不做 用户在 Inspector 可能看到 monitor 选项但不生效 Inspector 不显示 monitor 选项 · schema 仅为未来兼容
⚠️ P7 新增 5 端点工作量 Phase 2-3 后端阻塞 ClaudeB 主导 · 与前端并行(端点 mock 优先 · 算法后跟)
⚠️ 业务行为契约 5 段写起来重 每 MeasurementNode 派发都需填 5 段 · 派发慢 .clinerules v1.8 加自查清单 · prompt 模板带 5 段骨架(空 stub)

4.3 关键非目标(Non-Goals)

  • ❌ 不实施 Sequence(Task Flow)执行引擎(留下季度)
  • ❌ 不实施 Validation Engine 算法(threshold/mask/golden compare 仅 schema · Phase 4 占位)
  • ❌ 不实施 Recording 文件持久化(.wav 多轨 · ring buffer 仅内存 · 留下季度)
  • ❌ 不实施 Multi-monitor UI(schema 留 monitor 字段)
  • ❌ 不实施 Snapshot 跨 Workspace 共享(同 Workspace 内可对比)
  • ❌ 不实施 Spectrogram 瀑布图(Phase 2 schema 占位 · UI 实施留下季度)
  • ❌ 不实施 Generator 信号源(Sine/Pink/Chirp/MLS/Multitone · schema 留 · UI 留下季度)
  • ❌ 不实施 LUFS 响度算法(P7 端 · 留下季度)
  • ❌ 不修改 contract-v1.0(已 frozen · meter-source 扩展统一并入 v2)
  • ❌ 不与 ADR-10 SignalSink 联动(留下季度 · HMI 触发测试 sequence)

5. 实施清单(Implementation · Phase 1-4 · 12 U-thread · 总 20d)

5.1 Phase 1 · Widget Workspace 框架(5d · 优先级 P1)

# U-thread CPU 工时 业务深度核心
1 P0.U-meter-types-v3 ClaudeA 1.0d types/measurement-node.ts + types/dashboard-widget.ts + types/workspace.ts + types/task-flow.ts(占位)+ types/meter-frame-{rms,fft,transfer,phase,waveform,electrical,recording}.ts · 7 类 MeterFrame schema · workspaceStore Pinia 骨架
2 P0.U-widget-workspace-framework ClaudeA 2.5d DashboardCanvas.vue(vue-grid-layout 集成)· Widget 容器(Drag/Resize/Dock/Float/Split/Fullscreen/Save Layout)· 4 套 Workspace Preset 切换 · gridLayout 6 种
3 P0.U-measurement-node-registry ClaudeA 1.0d MeasurementNodeRegistry.ts(Map)· 7 类 NodeFactory stub · 拖拽创建 node + widget · LeftDock § Measurements 列表
4 P0.U-right-inspector-framework ClaudeD 0.5d RightInspector.vue 6 段通用容器 · 子段按 selectedWidget.measurementNode.type 路由 · stub Source/Measurement/Display/Validation/Automation/Storage 6 子组件

5.2 Phase 2 · 7 类 MeasurementNode 实施(8d · 优先级 P1)

# U-thread CPU 工时 范围
5 P0.U-measurement-rms-fft-phase ClaudeA 2.0d RMSMeterNode + FFTAnalyzerNode + PhaseMeterNode 完整实施(组件 + Inspector + 5 项业务行为契约 §3.⅓.⅔.4)
6 P0.U-measurement-transfer-waveform ClaudeD 2.0d TransferFunctionNode + WaveformScopeNode 完整实施(§3.3/3.5)
7 P0.U-measurement-electrical-recorder-stub ClaudeD 1.5d ElectricalMeterNode + RecorderNode 实施(§3.6/3.7 schema + UI · 算法依赖 P7 端点 · stub)
8 P5.U-meter-tap-multi-tool ClaudeB 1.5d MeterTapService 扩展 toolKind 路由(7 类)· WS 帧 schema 升级带 toolKind · 限流 30fps/tool/client · Bottom Dock Device Status 推送
9 P7.U-analyze-extensions ClaudeB 1.0d pysidecar 新增 5 端点:/analyze/transfer_function / /analyze/group_delay / /analyze/peak_hold / /analyze/snapshot_diff / /analyze/thd

5.3 Phase 3 · Engine + Session + Storage + Bottom Dock(4d · 优先级 P2)

# U-thread CPU 工时 范围
10 P0.U-engine-session-snapshots ClaudeA 2.0d LeftDock § Engine(Physical Input/Playback Output 设备配置)+ § Session(时钟/路由/校准状态)+ § Snapshots(Save/Compare/Golden/Export)
11 P0.U-bottom-dock + storage-engine ClaudeD 2.0d BottomDock.vue(Console 5 级日志 + Device Status WS 推送 + XRUN 计数 + Measurement Log)· Storage Engine 实施(Workspace.widgets[] 持久化 · localStorage / IndexedDB)

5.4 Phase 4 · Sequence 占位 + 端到端真值 e2e(3d · 优先级 P2)

# U-thread CPU 工时 范围
12 P0.U-task-flow-stub + e2e-truth ClaudeC 3.0d LeftDock § Task Flow UI 入口(列表 + "新建 Flow"按钮 · stub 不可执行)+ BottomDock § Task Queue 占位 + 端到端真值 e2e 5 场景脚本(粉噪/1kHz 正弦/EQ +6dB/PEQ -3dB/触发抓波形)· 替代当前形式合规测试

5.5 派发顺序(K-thread 占用约束)

Phase 1 #1 → 解锁 #2 #3 #4(并行)
Phase 2 #5 #6 #7(并行 ClaudeA/D)+ #8 #9(并行 ClaudeB)
Phase 3 #10 #11(并行 ClaudeA/D)
Phase 4 #12(ClaudeC)

总工作量 20d × 4 CPU 并行 ≈ 5 周(对齐用户起稿广度 · 不缩水)


6. 验收(Acceptance)

6.1 文档验收

  • ADR-AIOS-12-xitest-realtime-arch.md v2.0 落盘(本文件)· status: proposed
  • processes/P_arch/ADR-XiTest-RealTime/ 子进程 PCB 创建
  • processes/P_arch/PROCESS.md 加 ADR-XiTest-RealTime 子事件 user_thread
  • processes/P4-xitest/PROCESS.md state release-candidate-final → planning-v2 + 加 4 fork
  • processes/P0-xishell/PROCESS.md 加 4 fork(meter-types-v3 / widget-workspace-framework / measurement-node-registry / engine-session-snapshots / bottom-dock-storage / measurement-* / task-flow-stub-e2e-truth · 共 7 fork 给 P0)
  • processes/P5-backend-csharp/PROCESS.md 加 1 fork(meter-tap-multi-tool)
  • DASHBOARD.md v2.7.29 → v2.7.30 同步
  • .clinerules/aios-orchestration.md v1.7 → v1.8 加 §"业务行为契约必填段"

6.2 实施验收(Phase 1-4 落地后)

Phase 通过条件
Phase 1 Widget 可拖拽/Resize/Save Layout · 4 套 Preset 一键切换 · LeftDock § Measurements 7 类节点可拖入 · RightInspector 6 段框架可见
Phase 2 7 类 MeasurementNode 全部可拖入 + Inspector 配置 + 实时数据流 · §3 中 §3.⅓.⅔.3/3.4/3.5 五类 e2e 真值脚本全部跑通
Phase 3 LeftDock 8 段(Workspace/Session/Engine/Measurements/Recordings/Snapshots/Validation/Task Flow)全部可见 · BottomDock 6 段(Console/Device/XRUN/Measure Log/Task Queue 占位/Validation Result 占位)全部可见 · Workspace 布局可保存/加载
Phase 4 LeftDock § Task Flow 可见 + "新建"按钮(不可执行 + tooltip)· 端到端真值 e2e 5 场景在 CI 中绿

6.3 边界铁律验收(长期)

  • 任何"在 Widget 内塞业务逻辑"提议 → 拒绝(§2.11 #1)
  • 任何"派发 MeasurementNode 缺 5 项契约"提议 → 拒绝(§2.11 #3)
  • 任何"前端做 FFT/RMS/相位计算"提议 → 拒绝(§2.11 #4 三层分工铁律)
  • 任何"实施 Sequence 执行引擎"提议 → 必须新起 ADR-AIOS-12-RX(§2.11 #5)
  • 任何"减 Workspace Preset 1 套"提议 → 必须新起 ADR(§2.11 #6)

7. 替代方案(Alternatives Considered)

7.1 替代方案 A(已废弃 · 对应 v1 误读)· 4 tab 切换

  • 描述:不做 Widget Workspace · 全 stage 用 fixed 4 tab(频响/相位/时域/RMS)
  • 废弃理由:
  • 与用户起稿 §十七 Dashboard widget-based 直接冲突
  • 与对标产品(Smaart/APx500/Ocenaudio)专业 UX 不一致
  • 用户原话"所有的测量都以类似控件的 widget 的方式拖入主界面"明确否决
  • 失去 Multi-monitor / Save Layout / 自定义场景能力
  • 本 ADR 选择:严格 Widget Workspace + 4 套 Preset

7.2 替代方案 B(已废弃)· APx500 优先(测试自动化)

  • 描述:realtime 弱化 · 主菜单 Sequence/Step/Result/Report 4 视图
  • 废弃理由:用户原话"先实施 realtime 的显示 · 后续的 sequence 实施"明确顺序

7.3 替代方案 C(已废弃)· 三家融合全实施(含 Sequence 执行引擎)

  • 描述:realtime + Sequence 执行引擎 + Recording 文件持久化全做
  • 废弃理由:工作量 35d+ · 风险再次"广度泛滥业务浅" · 用户已说"sequence 后续实施"
  • 本 ADR 选择:realtime 完整 + Sequence 占位 schema · 执行引擎下季度

7.4 替代方案 D(已废弃)· 用户起稿原文直接落 ADR

  • 描述:不深化 · 把用户起稿 22 节直接当 ADR
  • 废弃理由:无业务行为契约 5 段 · 不可派发 · 等于"壳子框架"
  • 本 ADR 选择:保留用户起稿为 §附录 A · 主体写 5 项契约 + 实施清单

8. 状态流转(Status History)

日期 状态 操作 说明
2026-05-29 11:38 起草触发 用户给出"new ADR Xitest"指令 + 对标 3 产品 + demo 路径 + 起稿路径 用户起稿 912 行已就位
2026-05-29 11:48 信息收集 Cline-AIOS read 4 输入文件(用户起稿 + ADR-10 + Demo HTML + ADR-07) 全景图谱锁定
2026-05-29 11:50 Plan v1 Cline-AIOS plan_mode_respond 给方向 A/B/C(❌ 跑偏 · 把 Demo 当蓝本 · 砍 Sequence) 已纠正
2026-05-29 12:00 用户纠偏 用户原话"哪里有 tab" + "realtime 这些功能我都要" + "sequence 后续实施但不能不提" 强力纠偏
2026-05-29 12:04 Plan v2 Cline-AIOS 重读 md §十六-§二十二 + 对齐 ADR-XiTune-AutoTune-layout 真实需求图谱锁定
2026-05-29 12:06 用户拍板 默认推荐(1A + 2是 + 3按MeasurementNode展开 · 1500行特批) 进入 ACT 落盘
2026-05-29 12:10 用户拍板处置 方案 1 · 原路径覆写 + 起稿 §附录 A 决定本文件结构
2026-05-29 12:15 proposed v2.0(本版) ADR v2.0 落盘 · 等用户 accept ADR-AIOS-12 12 U-thread fork ready
2026-05-29 13:45 编号标准化 git mv ADR-AIOS-XiTest-RealTime-Arch.mdADR-AIOS-12-xitest-realtime-arch.md · 对齐 ADR-01~11 编号体系 用户拍板方案 A(简单顺位编号)
2026-05-29 14:18 accepted v2.1 status proposed → accepted · 用户原话"方案 1 · accept ADR-AIOS-12 + start 3 fork" · 同时 dispatched Phase 1 起手 3 fork(P0.U-meter-types-v3 + P5.U-meter-tap-multi-tool + P7.U-analyze-extensions · 全部文件隔离 · 不绑定 CPU) 与 aios-cpu1 ADR-11 实施并行 · 子目录隔离不冲突
2026-05-30 12:50 用户拍板 2 全局红线 用户原话"下一个 xitest 相关任务的 prompt 中加 · 适当的适配主界面 widget 窗口大小以及右侧 dock 横竖屏 · 所有的色系搭配要满足主题色系切换" · 同时 stop ADR-12 Phase 2 #6+#7(600f0fc + 729327c)· Phase 2 全闭环 红线先内联到 P0.U-measurement-thd-snr + impulse-spectrogram 两 prompt · 避免 ADR 回写延迟阻塞
2026-05-30 15:53 v2.2 修订 §2.11 边界铁律 7 项 → 9 项(加第 8+9 项 响应式横竖屏 + 主题色系切换 design-token)· frontmatter version v2.1 → v2.2 用户拍板 13:50 "ADR-12 §2.6 第 7+8 项铁律回写 v2.1→v2.2 · 把全局红线正式写入 ADR" · 实际写入 §2.11(铁律真位置)
2026-05-31 11:50 v2.3 修订 §2.11 第 8+9 项后追加"前后端责任边界"说明 · 明确纯前端 UI 渲染范畴 · P5/P7 后端无需适配 · 现有数据契约保持不变 · 历史 5 类后端任务核查全部确认无需补 · frontmatter v2.2 → v2.3 用户 2026-05-31 11:49 洞察:"刚刚添加的内容都是前端 · 后端是否需要接口对应的变化 · 历史任务中做了后端适配么" · 杜绝未来误解前后端责任


9. 关键术语表(Glossary)

术语 定义
Widget Dashboard 内的可拖拽容器 · 持有 1 个 MeasurementNode 引用
MeasurementNode 测量节点统一抽象 · 7 子能力(input/processing/measurement/validation/visualization/automation/storage)
Workspace 一组 Widget × 布局 × MeasurementNode × Engine 的工程文件
Workspace Preset 4 套预设(Tuning/Electrical/Recording/Multi-channel)+ 用户自定义
5 引擎 Measurement / Validation / Task / Storage / Visualization 共享引擎 · §二十二 锁定
5 项业务行为契约 输入输出 schema + 收敛判据 + 失败回退 + 用户操作流 + 端到端真值 e2e · §3 必填
Inspector 6 段 Source/Measurement/Display/Validation/Automation/Storage · 通用容器
Flow Node 5 类 Source/Measurement/Validation/Logic/Export · §十六 Task Flow 锁定
Dockable+Workspace+Widget+Scene 与 ADR-XiTune-AutoTune-layout §2 共享的混合架构理念
Smaart 风格 实时声学测量 · Transfer Function 双通道 · Live IR · Workspace=Tuning
APx500 风格 测试自动化 · THD/SINAD/Sweep · Workspace=Electrical
Ocenaudio 风格 多通道波形编辑 · 快照对比 · Workspace=Recording

10. 相关决议与文档

10.1 相关 ADR

  • ADR-AIOS-07 P3-xitune/P4-xitest 业务边界:本 ADR 继承 §1.3.4 三层分工铁律 + §1.3.1 节点选择契约 + §2.1.4 mode 命名(perf→regression / visual→realtime)
  • ADR-AIOS-11(平行 · xitune-autotune):P3 自动调音 MVP · 本 ADR 仅引用(P3 调音 measure phase 可复用 §3.3 Transfer Function)
  • ADR-AIOS-XiTune-AutoTune-layout(已归档至 ref/ · 用户手动移动):P3 调音工作区布局思路文档 · 与本 ADR 共享 Dockable+Workspace+Widget+Scene 架构理念
  • ADR-AIOS-04 XiForge 架构:Module UID 规范 · 本 ADR 不直接关联
  • ADR-AIOS-05 XiStudio Workspace · LEGACY_*_MAP:本 ADR Workspace 持久化沿用 LEGACY_LINK_FILE_MAP 协议
  • ADR-AIOS-06 OS 化任务调度:本 ADR 全程使用其调度协议
  • ADR-AIOS-08/09/10(平行):XiLink stage 议题 · 共享 K2-protocol-v2 启动 · 正交无冲突
  • ADR-AIOS-10 SignalSink 抽象:本 ADR 未来扩展(HMI 触发测试 sequence · 留下季度)

10.2 相关 PROCESS.md

  • processes/P4-xitest/PROCESS.md(本 ADR 主战场 · 4 fork U-thread · state planning-v2)
  • processes/P0-xishell/PROCESS.md(本 ADR 共享栈 · 7 fork U-thread)
  • processes/P5-backend-csharp/PROCESS.md(后端 · 1 fork)
  • processes/P_arch/PROCESS.md(本 ADR 子事件)
  • processes/P_arch/ADR-XiTest-RealTime/PROCESS.md(子进程 PCB · 本 ADR 派生)

10.3 关联契约

  • contracts/protocol-v1.md(frozen · 不修改)
  • contracts/protocol-v2.md(候选启动 · 本 ADR 贡献:§meter-tool-routing(toolKind 路由 schema)+ §measurement-node(7 类 MeasurementNode schema))

10.4 关联输入文件

  • 用户起稿:本文件 §附录 A(原路径 912 行 · v1 完整保留)
  • Demo HTML:d:/work/25_claude/workspace/AlgoDepartment/04_development/frontend_vue3/docs/superpowers/specs/xitest-realtime-ui-demo.html(1225 行 · 单 widget 4 tab 示意)
  • 现有实装:04_development/frontend_vue3/src/stages/xitest/**(P4.U3 zombie · ceecccf · realtime+regression mode 2+3 stub)
  • 后端基础:04_development/backend_csharp/Routes/MeterDevApiRoutes.cs + Services/Meter/*(P5.U-meter-source-tap zombie · 4adda88)

11. 决议者签名(Approvers)

  • 拍板:用户(2026-05-29 12:06 默认推荐 · 1A + 2是 + 3按MeasurementNode展开 · 1500 行特批 · 12:10 处置方案 1)
  • 起草:Cline-AIOS · cwd=d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/
  • 真值核查:Cline-AIOS read 4 输入文件全文(用户起稿 912 行 + Demo HTML 1225 行 + ADR-10 + ADR-07 §1-§3)
  • 后续修订:任何修改本 ADR 必须先 fork ADR-AIOS-12-RX(R = Revision)子进程

本 ADR 落地 = AIOS v7 OS 化模型下"业务行为契约必填段"标杆示范 · 回应用户 2026-05-28 "业务深度系统性缺失"诊断 · 后续所有 ADR 模板对齐本 ADR §3 5 项契约 · 杜绝"壳子框架"。


附录 A · 用户起稿(2026-05-29 · 912 行 · 22 节功能清单)

以下为用户 2026-05-29 上午起草的原始文档全文,保留作为本 ADR 决议的设计依据。Cline-AIOS v2.0 决议(§1-§11)基于本附录提炼,并补充 Demo HTML(MVP 单 widget 切片)+ ADR-07 三层分工铁律 + 业务行为契约必填段。

A.1 产品定位

XiTest / Realtime:

不是单纯频谱工具。

不是单纯录音工具。

不是单纯示波器。

其本质定位:

"实时音频测量与工程化验证工作台"

需要同时满足:

场景 目标
实时调音 实时频响 / 相位 / RMS
台架验证 THD / Delay / FR
多通道验证 Matrix / Overlay
工程回归 Golden Compare
E2E测试 流程化验证
Integration测试 多模块协同
录音分析 Waveform / Spectrogram
自动化测试 Task Flow

因此:

XiTest 中所有测量组件必须统一为:

Measurement Node

Realtime 只是:

Measurement Node 的实时可视化工作区

A.2 整体架构

A.2.1 XiTest 架构

XiTest
├── Realtime
├── Integration
├── E2E
├── Regression
├── Automation
├── Report
└── Measurement Engine

A.2.2 核心统一引擎

所有模块共享:

Measurement Engine
Validation Engine
Task Engine
Storage Engine
Visualization Engine

A.2.3 Measurement Node(核心抽象)

所有测量能力:FFT / RMS / THD / Transfer / Spectrogram / Frequency Response

统一抽象:Measurement Node

统一结构:

Measurement Node
├── Input
├── Processing
├── Measurement
├── Validation
├── Visualization
├── Automation
└── Storage

A.3 Realtime UI 总体结构

┌────────────────────────────────────────────────────────────┐
│ Top Toolbar                                               │
├──────────────┬───────────────────────────────┬────────────┤
│ Left Dock    │      Realtime Dashboard       │ Right Dock │
│ Workspace    │                               │ Inspector  │
│ Resources    │ Widget-based Measurement      │ Parameters │
│ Measurements │         Workspace             │            │
├──────────────┴───────────────────────────────┴────────────┤
│ Bottom Dock                                               │
│ Console | Device Status | XRUN | Measurement Log | Tasks │
└────────────────────────────────────────────────────────────┘

A.4 Top Toolbar(顶部工具栏)

只保留全局状态与全局操作 · 不放复杂配置 · 复杂参数统一放入 Left Dock / Right Inspector。

功能 说明
Current Project 当前工程
Current Workspace 当前工作区
Realtime Status 实时运行状态
Record 开始录制
Pause 暂停
Snapshot 当前测量快照
Overlay 曲线叠加
Sync 同步刷新
Layout 工作区布局
Fullscreen 全屏分析

A.5 Left Dock(左侧工作区)

工程资源中心 · 不是工具栏 · 而是 Workspace + Resource + Measurement 管理中心。

LEFT DOCK
├── Workspace
├── Session
├── Engine
├── Measurements
├── Recordings
├── Snapshots
├── Validation
└── Task Flow

A.6 Workspace(工作区)

Workspace 是最重要的概念之一,定义:窗口布局 + 测量组件 + 参数状态 + Overlay状态 + 通道状态。即 Workspace = 一整套实时分析环境

Workspace 功能定义

功能 说明
Save Workspace 保存布局
Load Workspace 加载布局
Export Workspace 导出
Share Workspace 分享
Clone Workspace 克隆
Lock Workspace 锁定布局

Workspace Preset(系统预设)

1. Tuning Workspace:用于调音 · 布局 = Transfer + FFT + Phase + RMS

2. Electrical Workspace:用于 AP 类电信号分析 · 布局 = THD + SINAD + Scope + Generator

3. Recording Workspace:用于录音分析 · 布局 = Waveform + Spectrogram + Markers

4. Multi-channel Workspace:用于车载多通道 · 布局 = RMS Matrix + Delay Matrix + Phase Matrix

A.7 Session(实时会话)

代表当前实时工程环境。

功能 说明
Device Profile 当前设备
Clock Status 时钟状态
Sample Rate 采样率
Buffer Size Buffer
Routing 通道路由
Calibration 校准
Active Channels 激活通道

A.8 Engine(输入输出引擎)

ENGINE
├── Physical Input
├── Playback Output
├── Generator
├── Virtual Loopback
├── CAN / RPM
└── Trigger

Physical Input:Device Select / Gain / Channel Map / Polarity / Delay / Calibration

Playback Output:Output Device / Volume / Mute / Solo / Output Routing

Generator:Sine / Pink Noise / White Noise / Chirp / Sweep / MLS / Multitone

A.9 Measurements(测量组件库)

所有测量组件都是 Measurement Node · 支持拖拽 / 复用 / 流程化 / 自动化 / Pass-Fail。

MEASUREMENTS
├── Time Domain
├── Frequency
├── Transfer
├── Electrical
├── Recording
├── Validation
└── Utility

A.10 Time Domain(时域组件)

Waveform Scope:Live Waveform / Trigger / Freeze / Buffer Replay / Zoom / Cursor

RMS Meter:实时 RMS(per-channel)/ Peak / LUFS / Crest Factor / Fast/Slow / Hold / Max/Min

Oscilloscope:XY Mode / Phase Scope / Lissajous / Trigger

A.11 Frequency(频域组件)

FFT Analyzer:FFT Size / Window / Average / Smoothing / Peak Hold / Overlay / Trace Store / Frequency Cursor

RTA:Octave / SPL Weighting / Average / Real-time Overlay

Spectrogram:Waterfall / Colormap / Time Scroll / Frequency Zoom

A.12 Transfer(Smaart 核心)

Transfer Function:Magnitude / Phase / Coherence / Delay Finder / Overlay / Golden Compare

A.13 Electrical(AP 核心)

Electrical Meter:Vrms / dBu / Frequency / THD / THD+N / SINAD / SNR

Sweep Analyzer:Log Sweep / Step Sweep / Chirp / MLS

A.14 Recording(录音组件)

Recorder:Multi-track / Loop / Marker / AB Compare / Snapshot / Buffer Cache

A.15 Validation(工程化验证)

所有组件必须支持 Pass / Fail。

功能 说明
Threshold 阈值
Mask 掩码
Tolerance 容差
Golden Compare Golden对比
Delta Compare 差异对比
Result Export 结果导出

A.16 Task Flow(工程核心)

XiTest 必须支持 流程化测试编排

Test Flow 示例:Playback → RMS → THD → FR Compare → Pass/Fail

Flow Node 分类:

类型 说明
Source Node 输入/播放
Measurement Node FFT/THD
Validation Node Compare
Logic Node IF/WAIT
Export Node Report

A.17 Realtime Dashboard(中央区域)

中央区域 = Widget-based Workspace。

功能 说明
Drag 拖拽
Resize 缩放
Dock 停靠
Float 浮动
Split 分屏
Fullscreen 全屏
Save Layout 保存布局
Multi-monitor 多屏

Main Widget:FFT / Transfer / Waveform / THD / Spectrogram

Mini Widget:RMS / Peak / Clock / THD Numeric / Latency / CPU / XRUN

A.18 Right Dock(Inspector)

右侧 = 当前 Widget 参数面板。

Inspector 通用结构:Source / Measurement / Display / Validation / Automation / Storage

FFT Inspector:FFT Size / Window / Average / Overlap / Smoothing / Scale / dB Range / Overlay

Transfer Inspector:Ref Channel / Measure Channel / Delay Tracking / Coherence / Phase Wrap

Recorder Inspector:Buffer / Trigger / Pre-roll / Auto Save / File Format

A.19 Snapshots(测量快照)

Snapshot 保存:曲线 + 参数 + Overlay + 结果 + 布局

功能 说明
Save Snapshot 保存
Compare Snapshot 对比
Golden Snapshot Golden
Export Snapshot 导出

A.20 Recordings(工程文件)

所有录音属于工程资源 · 支持回放 / 分析 / Overlay / Compare / Offline FFT。

A.21 Bottom Dock(底部状态栏)

Console
Device Status
XRUN
Measurement Log
Task Queue
Validation Result

Console:INFO / WARNING / ERROR / DEVICE / SCRIPT

Device Status:Clock Lock / Sample Rate / Buffer / XRUN / CPU

Task Queue:Recording / Export / Sweep / Regression

A.22 统一工程核心(最终核心)

XiTest 所有模块(Realtime / Integration / E2E / Regression / Automation)必须共享 5 引擎(Measurement / Validation / Task / Storage / Visualization)。

Realtime 只是 "工程化测量节点的实时观测模式"


附录 A 结束 · 用户起稿(2026-05-29 上午 · 912 行)完整保留 · 是本 ADR 决议依据。