跳转至

P5.U-error-channel · 链路错误广播扩展(ADR-AIOS-08 §2.2 fork)

目标 worker:ClaudeB(主仓 04_development/ · P5-backend-csharp 主战场) [涉及部门]:后端 (backend-csharp) · 推荐 skill:dotnet-realtime-communication 预计:0.5d · 优先级:P1 · 状态:⚪ ready(2026-05-30 09:07 派发 · ADR-AIOS-08 accepted v1.1)


🔍 触发与解锁链

触发 hash 状态 影响
ADR-AIOS-08 accepted v1.1 2026-05-29 17:25 ✅ 用户拍板 10 fork U-thread 启动 · 后端三线先派
用户拍板方向 A 就地扩展 2026-05-30 09:00 ✅ 用户原话 "zhujian" ❗ 不许重写 · 必须扩展现有 error_event 形态
MetricsAggregator.cs error_event 已实装 167 行 ✅ Phase 8 落地 现状 2 类码(UNDERRUN/OVERRUN) · 本任务扩到 7 类链路码
WsBroadcastService 注入 已实装 ✅ 永久 复用既有 broadcast · 不另起 channel

→ 跨栈独立(后端 .NET) · 不修改 contract-v1.0(已 frozen) · error_event WS 形态扩展(留 K2-protocol-v2 时正式入)。


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

[U-thread]   P5.U-error-channel
[部门]       后端 .NET · ADR-AIOS-08 §2.2 链路错误检查机制 · skill: dotnet-realtime-communication
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies]   P5.K-services(write · 新增 LinkErrorBroadcaster) + P5.K-ws-broadcast(write · 扩展现有 error_event 形态) + P5.K-link-validator(write · LinkStateManager / RefreshLinkHandler 触发点)
[优先级]     P1 · 0.5d · 跨栈独立 · 与 P5.U-perf-service / P5.U-runtime-mode-refactor 同 ClaudeB 并行(三 fork 文件正交 · 同 commit 周期内可全部完成)
[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.2 + §3.2 边界铁律 #4 + §4.1 fork P5.U-error-channel)
[参考文档]
  - 上述 ADR 主文(accepted v1.1)· 重点读 §2.2 链路错误检查机制(7 类错误码 + 2 字段集)+ §3.2 边界铁律 #4(warning/info 不阻断 audio path)+ §4.1 fork 列表
  - 同部门标本(强制 read · 4 维度对齐):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P5.U-meter-tap-multi-tool--48cf0ba.md(同部门 ClaudeB · 同 P5 · WS 广播 + 路由模式参考)
  - **🚨 现状必读(本 fork 核心 · "就地扩展"方向用户已拍板)**:
    · backend_csharp/Services/Metrics/MetricsAggregator.cs(167 行 · Phase 8 已实装 · 重点读 154-165 行 `error_event` WS 广播 · 现有形态 `{type,level,code,message}` 仅 2 类码 UNDERRUN/OVERRUN)
    · backend_csharp/Services/WebSocket/WsBroadcastService.cs(WS 广播服务 · 复用 `BroadcastExcept` 接口)
    · backend_csharp/Services/Link/LinkStateManager.cs(链路状态管理 · 加 LinkError 触发点)
    · backend_csharp/Services/Link/RefreshLinkHandler.cs(链路刷新处理 · 加 LinkError 触发点)
    · backend_csharp/Services/Link/LinkService.cs / LinkParamApplyService.cs(链路服务 · 看是否有现成校验逻辑)
  - 上游 ADR:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-07-p3-p4-overlap.md(三层分工铁律 · 必读)
  - contract-v1.0(已 frozen · 不修改):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/contracts/protocol-v1.md(本任务走 error_event WS 扩展 · 待 K2-protocol-v2 正式入)

【背景】
ADR-AIOS-08 已 accepted v1.1(2026-05-29 17:25)· 用户 2026-05-30 09:00 拍板「方向 A 就地扩展」原话"zhujian"。

🚨 **真值核查发现**(.clinerules v1.3 §🚨 真值核查铁律):
ADR-08 §1.3 第二份 subagent 核查写"无 PerformanceService / MetricsService / TelemetryService"是字面正确(类名确实没有) · 但 **`MetricsAggregator.cs` 已存在 167 行 · 已实装 `error_event` WS 广播**(154-165 行 · 含 `level/code/message` 三字段)· 只是仅 2 类码(UNDERRUN/OVERRUN · 都是音频运行时错误)· 没有链路验证错误。

**本任务核心**:**扩展不重写**。把现有 `error_event` 形态升级支持 7 类链路验证错误码 · 不另起 `/ws/errors` channel · 不重新设计 WS 形态。

**ADR §2.2 要做的功能**(7 类错误码):
- MODULE_NOT_CONNECTED(模块未连接 · 用户原话核心场景)
- MODULE_PORT_MISMATCH(端口类型不匹配)
- MODULE_PARAM_MISSING(必要参数缺失)
- CHAIN_CYCLE_DETECTED(链路成环)
- CHAIN_ORPHAN_NODE(孤立节点)
- RUNTIME_PLATFORM_MISMATCH(运行平台不兼容 · 关联 fork P5.U-runtime-mode-refactor)
- SUBGRAPH_INTERFACE_INVALID(子图接口无效 · 关联 ADR-08 §2.5 · 本期不实施)

**字段升级**:`{type, level, code, message}` 4 字段 → `{type, level, code, message, moduleId?, portId?, timestamp, source}` 8 字段(向后兼容 · 旧 UNDERRUN/OVERRUN 形态保留)

**契约策略**:不修改 contract-v1.0(已 frozen) · `error_event` WS 形态扩展走 dev-channel(待 K2-protocol-v2 正式入)。

【执行步骤】
1. 自查 + 读现状(必读 · 本 fork 核心):
   git status                                           # 工作区干净
   git branch --show-current                            # = xistudio
   git pull origin xistudio --no-rebase
   # 必读现状:
   cat backend_csharp/Services/Metrics/MetricsAggregator.cs          # 154-165 行 error_event 广播现状
   cat backend_csharp/Services/Link/LinkStateManager.cs              # 看链路状态管理
   cat backend_csharp/Services/Link/RefreshLinkHandler.cs            # 看链路刷新流程
   cat backend_csharp/Services/Link/LinkService.cs                   # 看链路服务接口
   grep -rn "error_event" backend_csharp/Services/                   # 看现有触发点(应仅 MetricsAggregator)

2. 新增 backend_csharp/Models/Error/(目录新建 · 错误模型):
   - LinkErrorCode.cs(enum · 7 类码字符串值与 ADR §2.2 对齐):
     · MODULE_NOT_CONNECTED / MODULE_PORT_MISMATCH / MODULE_PARAM_MISSING
     · CHAIN_CYCLE_DETECTED / CHAIN_ORPHAN_NODE
     · RUNTIME_PLATFORM_MISMATCH / SUBGRAPH_INTERFACE_INVALID
     · 兼容旧码:UNDERRUN / OVERRUN(MetricsAggregator 已用 · 保留)
   - LinkErrorSeverity.cs(enum · "error" / "warning" / "info" 字符串)
   - LinkErrorSource.cs(enum · "frontend" / "backend" / "dsp" 字符串)
   - LinkError.cs(record · 8 字段 · code/severity/message/moduleId?/portId?/timestamp/source 对齐 ADR §2.2 前端 types/link-error.ts schema)

3. 新增 backend_csharp/Services/Error/LinkErrorBroadcaster.cs(集中 publisher):
   - public interface ILinkErrorBroadcaster {
       void Publish(LinkError err);
       void PublishMany(IEnumerable<LinkError> errs);
       void ClearByModule(string moduleId);  // 模块删除时清理对应错误
     }
   - 内部:复用 WsBroadcastService.BroadcastExcept(null, json) · JSON 形态向后兼容:
     {
       "type": "error_event",     // ⚠️ type 不变 · 兼容旧客户端
       "level": "error",          // 兼容字段
       "code": "MODULE_NOT_CONNECTED",
       "message": "...",
       "severity": "error",       // 新增 · 与 level 同义但前端契约名
       "moduleId": "eq.high",     // 新增 · 可选
       "portId": "in",            // 新增 · 可选
       "timestamp": 1717024027000,// 新增 · ms epoch
       "source": "backend"        // 新增 · "frontend"/"backend"/"dsp"
     }
   - ❌ 不新建 /ws/errors channel · 复用现有 WsBroadcastService

4. DI 注册(Program.cs):
   - AddSingleton<ILinkErrorBroadcaster, LinkErrorBroadcaster>()
   - 验证 WsBroadcastService 已注册(应已落)

5. 触发点接入(本任务最小落地 · 1 个触发点示例 + 接口预留):
   - LinkStateManager.cs / RefreshLinkHandler.cs:链路刷新时检测"模块未连接"(端口未挂边)→ Publish(LinkError{code=MODULE_NOT_CONNECTED, severity=warning, source=backend, moduleId=..., portId=...})
   - 至少 1 个真触发点(MODULE_NOT_CONNECTED · 用户原话核心场景)· 其余 6 类码留接口由后续 fork 接入(ChainValidator / 子图 / 运行平台等)
   - ❌ **本 fork 不做 ChainValidator 完整实装**(留 ADR-08 后续 fork 或 ADR-09)· 仅做 MODULE_NOT_CONNECTED 一类的最小演示路径

6. 单测 + 验收:
   cd backend_csharp
   # 新增 Tests/Services/Error/LinkErrorBroadcasterTests.cs(>= 3 case:Publish 单条 + PublishMany 批量 + ClearByModule)
   # 新增 Tests/Models/Error/LinkErrorTests.cs(>= 2 case:序列化 JSON 字段名对齐 + severity/level 双名兼容)
   # 至少 5 个新 case
   dotnet build                                         # 零错误零警告
   dotnet test                                          # 通过 + 新增 >= 5 用例(基线 147/0 → >= 152/0)
   # 手动 e2e(可选):前端 chrome devtools WS 抓 error_event 帧 · 看新字段是否 backward-compat

7. Commit + push:
   git add backend_csharp/Models/Error/ \
           backend_csharp/Services/Error/ \
           backend_csharp/Services/Link/LinkStateManager.cs \
           backend_csharp/Services/Link/RefreshLinkHandler.cs \
           backend_csharp/Tests/Services/Error/ \
           backend_csharp/Tests/Models/Error/ \
           backend_csharp/Program.cs
   git commit -m "..."(见下)
   git push origin xistudio

【验收】
- 6-8 文件落地(Models/Error ×4 + Services/Error ×1 + Link/* ×2 改动 + Tests ×2 + Program.cs DI)
- dotnet build 零错误零警告 · dotnet test 全绿(基线 147/0 → >= 152/0 · +5 用例)
- ✅ **现状未破坏**:旧 UNDERRUN/OVERRUN 路径(MetricsAggregator 154-165 行)零修改 · 旧客户端继续收到原 4 字段 + 新增 4 字段(JSON 向后兼容)
- ✅ **新增 1 个真触发点**:MODULE_NOT_CONNECTED 在 LinkStateManager / RefreshLinkHandler 中可触发(单测覆盖)
- ❌ **PR 自查 1**:确认未新建 /ws/errors WS channel(grep ws/errors 应在 Tests 之外零命中)
- ❌ **PR 自查 2**:确认未删除或修改 MetricsAggregator.cs 第 154-165 行 `error_event` 现有广播(diff 对此区域应为空)
- 三元组 trailer 完整 · commit hash 7 位

【commit】
commit subject:`feat(P5): extend error_event WS to 7 link error codes (in-place expansion · backward-compat) [ADR-AIOS-08 §2.2 fork]`

trailer(必须精确):
[step=1/1] [pid=P5] [uid=U-error-channel] [occupies=P5.K-services+P5.K-ws-broadcast+P5.K-link-validator]
[files=backend_csharp/Models/Error/**, backend_csharp/Services/Error/LinkErrorBroadcaster.cs, backend_csharp/Services/Link/LinkStateManager.cs, backend_csharp/Services/Link/RefreshLinkHandler.cs, backend_csharp/Tests/Services/Error/**, backend_csharp/Tests/Models/Error/**, backend_csharp/Program.cs]
[ipc=ws/error_event(extended-fields)]

回告格式参考 done/P5.U-meter-tap-multi-tool--48cf0ba.md 末尾(同部门 · 同 WS 广播模式)。

【禁止】
- ❌ **不许新建 /ws/errors WS channel**(用户拍板方向 A 就地扩展 · 必须复用现有 error_event 形态)
- ❌ **不许删除或修改 MetricsAggregator.cs 第 154-165 行 `error_event` 现有广播**(零回归)
- ❌ **不许把 LinkError severity 字段改成枚举 int**(ADR §2.2 前端契约 string · 必须 JSON serialize 为字符串)
- ❌ 不许修改 contracts/protocol-v1.md(已 frozen 永久 sleeping · LinkError 留 v2)
- ❌ 不许在 .NET 实装 ChainValidator 完整闭环(7 类码全触发点)· 本 fork 仅做 MODULE_NOT_CONNECTED 一类示例 + 接口预留 · 其余 6 类留后续 fork
- ❌ 不许改前端代码(P1.U-link-error-check 由 ClaudeA 跑 · 等本任务 zombie)
- ❌ 不许改 P6-dsp_algo / pysidecar 代码
- ❌ 不许跳验收 · dotnet build/test 任一红必须修到全绿
- ❌ 不许省略三元组 trailer
- ❌ 不许自改本 prompt 文件

解锁链(本任务 zombie 后)

  • ✅ P1.U-link-error-check 解锁(前端 ClaudeA · 1.5d · BottomProblems 订阅扩展后的 error_event · 显示 7 类码)
  • ✅ ADR-AIOS-08 §2.2 后端侧首落地 · ChainValidator 完整 7 类码触发留后续 fork
  • ✅ K2-protocol-v2 起草时(P_contracts.U-protocol-v2-bootstrap)有 LinkError 实测数据支撑

风险评估

风险 缓解
前端 BottomProblems 旧客户端不识别新字段 JSON 向后兼容 · 旧 4 字段(type/level/code/message)保留 · 新增字段为 optional · 旧客户端 ignore 即可
MODULE_NOT_CONNECTED 触发逻辑误报(链路初始化中态) LinkStateManager 在"完成态 ready"时才推送 · 中间态 transient 不推 · 单测覆盖 ready 态
单测 mock WsBroadcastService 复杂 用 Func Action mock · 仿 MetricsAggregator 现有测试模式
LinkError severity vs level 字段双名混淆 severity 是 ADR §2.2 前端契约名(规范) · level 是历史遗留 · 文档注释明确"new code use severity, legacy code use level, both filled"

历史

时间 事件 hash
2026-05-30 09:07 首次派发(ADR-AIOS-08 accepted v1.1 后第 1 个后端 fork · 用户拍板方向 A 就地扩展 · 真值核查发现 ADR §1.3 第二份漏报 MetricsAggregator 已存在 error_event 现状) -