[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 文件