P5.U-autotune-channel-measure · ADR-AIOS-11 v1.2 fork 1b · 后端车配持久化 + 多通道测量端点
目标 worker:ClaudeB(主仓 04_development/ · P5-backend-csharp 主战场)
[涉及部门]:后端 (backend-csharp) · 推荐 skill:dotnet-realtime-communication
预计:1.5d · 优先级:P1 · 状态:⚪ ready(2026-05-29 19:10 · 等用户 start)
🔍 触发与解锁链
| 触发 | 时间 | 状态 | 影响 |
|---|---|---|---|
| ADR-11 v1.2 修订 | 2026-05-29 19:00 | ✅ 用户拍板 5 决策点 | §4.1 新增 fork 1b · 真接口必须 |
P3.U-autotune-phase1-measure(714ace2) |
aborted-pending | ⚠️ v1 不合格 | v2 重写需要本任务真接口 |
| P5.U-autotune-batch-pipeline | 1898c6f zombie |
✅ 已落 | PysidecarAutotuneBridge 桥接模式直接仿写扩展 |
| P5.U-meter-source-tap | 4adda88 zombie |
✅ 已落 | HttpClient + PysidecarProcessManager 注入复用 |
| ADR-07 §1.3.4 三层分工 | accepted | ✅ 永久 | 后端零数学 · 严守 |
→ 跨栈独立(后端 .NET) · 不修改 contract-v1.0(已 frozen) · /api/auto_tune/* dev-api 桥接(类比 fork 5 已落模式 · 留 v2)。
任务定义(基于 ADR-AIOS-11 v1.2 §1.3.1 + §4.1 fork 1b)
按 ADR-11 v1.2 §1.3.1 Step A/C/D,实装 P5 后端 3 个新端点支撑 P3 fork 1 v2 Phase 1 全 4 测试模式真接口联调:① /api/auto_tune/vehicle_config(GET/POST · 车辆配置持久化到调音工程文件 · 决策 1B)② /api/auto_tune/measure_channel(POST · 单通道扫频分析 · 模式 ⅔ 调用)③ /api/auto_tune/measure_position(POST · 位置声学合成 · 模式 4 整体收音调用)。严守三层分工铁律(后端零数学 · FFT/相位/合成全交 P7 pysidecar)。
完整 prompt(直接复制粘贴 worker 终端)
[U-thread] P5.U-autotune-channel-measure
[部门] 后端 .NET · ADR-AIOS-11 v1.2 §4.1 fork 1b 多通道测量后端能力(I/O 编排 + P7 桥接 + 工程文件持久化 + 不做数学) · skill: dotnet-realtime-communication
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies] P5.K-api-routes(write · 新增 /api/auto_tune/{vehicle_config,measure_channel,measure_position} 3 端点)+ P5.K-services(write · 扩展 PysidecarAutotuneBridge + 新增 VehicleConfigService + MultiChannelMeasureService)+ P5.K-controllers(write · 扩展 AutoTuneController)
[优先级] P1 · 1.5d · 跨栈独立 · 阻塞 P3 fork 1 v2 真接口联调
[ADR] d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-11-xitune-autotune.md(v1.2 必读 §1.3.1 Step A/C/D + §1.3.4 + §2.2 边界铁律 + §4.1 fork 1b)
[业务行为契约引用] ADR-11 v1.2 §1.3.1 Step A 车配持久化 · Step C/D 单通道扫频 + 位置声学测量 · §2.2 三层分工铁律(后端零数学)
[参考文档](绝对路径)
- 上述 ADR 主文(accepted v1.2)
- ADR-07:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-07-p3p4-business-boundary.md(§1.3.4 三层分工铁律 · 必读)
- **同部门标本**(强制 read · 4 维度对齐):
· d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P5.U-autotune-batch-pipeline--1898c6f.md(同 ADR-11 · 同 fork 5 模式 · PysidecarAutotuneBridge + AutoTunePipelineService + AutoTuneController · 直接仿写扩展)
· d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P5.U-meter-source-tap--4adda88.md(更早同部门 · HttpClient + PysidecarProcessManager 注入)
- backend_csharp/Services/AutoTune/PysidecarAutotuneBridge.cs(已实装 · 1898c6f · 你扩展新增 3 个 method)
- backend_csharp/Services/AutoTune/AutoTunePipelineService.cs(已实装 · 1898c6f · 参考编排模式)
- backend_csharp/Controllers/Dev/AutoTuneController.cs(已实装 · 1898c6f · 你扩展新增 3 端点)
- backend_csharp/Services/PysidecarProcessManager.cs(已实装 · HttpClient 注入)
- backend_csharp/Services/WorkspaceFileHelper.cs(已实装 · 工程文件持久化模式参考)
- pysidecar/main.py(P7 已暴露 28 端点 · 复用)· 本任务关键端点:
· POST /auto_tune/realtime_frame(已实装 · measure_channel 调它做单通道 FFT/相位)
· POST /auto_tune/deviation(已 fork 6 落 · 备用)
· POST /auto_tune/simulate_apply(已 fork 6 落 · measure_position 可借助合成)
- 同期派 P3 fork 1 v2:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/active/P3.U-autotune-phase1-measure-v2.md(前端 schema 期望 · 你的 3 端点必须能映射)
- contract-v1.0(已 frozen · 不修改):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/contracts/protocol-v1.md
【背景】
ADR-11 v1.2 修订新增 fork 1b(用户决策 5A "必须真接口" + 决策 1B "车配后端落盘")· P3 fork 1 v2(前端)需要 3 个真后端端点支撑车载 30+ 通道 4 测试模式。
**架构契约 ADR-07 §1.3.4 三层分工铁律(本任务核心红线)**:
- **P5(本任务)= I/O 编排 + 工程文件持久化** · 调 P7 + 工程文件读写 + 通道循环编排 + WS 推送 · ❌ **不做任何数学计算**(不许做 FFT / RMS / 相位 / 偏差曲线 / 多通道合成 / 位置声学波束合成 / 混响识别 全部禁止)
- **P7-pysidecar(已 28 端点齐全)= 数学分析** · numpy/scipy 全栈 · 端口 8001
- **前端 P3 fork 1 v2(同期派 ClaudeC)= UI + 状态机** · 订阅本任务端点 · 不做数学
**业务流程**:
- **端点 1 /api/auto_tune/vehicle_config(GET/POST)**:VehicleConfig schema 持久化到 .xivehicleconfig 工程文件(JSON · workspace/projects/{projectId}/.xivehicleconfig)· GET 加载 · POST 保存覆盖
- **端点 2 /api/auto_tune/measure_channel(POST)**:接收 {channelId, sweepDurationSec, mode: 'manual'|'auto-xilink', muteOthers: bool} → 编排 mute 其他通道(走 set_params 协议)→ 调 P5 已有 /dev-api/meter/stream 拉 raw FFT 帧 → 转发 P7 /auto_tune/realtime_frame 拿 freq/mag/phase → 包装 ChannelMeasureResult 返回
- **端点 3 /api/auto_tune/measure_position(POST)**:接收 {positionId, allChannelsActive: bool, micArray: string[]} → 同时所有通道 unmute → 拉多 mic 同步 raw 帧 → 转发 P7(借助 simulate_apply 或新增 P7 端点 · 本任务先用 simulate_apply 占位)→ 包装 PositionMeasureResult 返回
**契约策略**:不修改 contract-v1.0(已 frozen) · 走 /api/auto_tune/* dev-api 桥接(沿用 fork 5 模式)
【执行步骤】
1. 自查 + 同步同期前端类型(若已 push):
git status
git branch --show-current # = xistudio
git pull origin xistudio --no-rebase # 拿同期派 P3 fork 1 v2 已落 types(若已 push)
ls frontend_vue3/src/stages/xitune/modes/auto/types.ts # 看 VehicleConfig + ChannelConfig + ChannelMatrix schema
ls backend_csharp/Services/AutoTune/ # 看 fork 5 已落实状(PysidecarAutotuneBridge + AutoTunePipelineService)
2. 扩展 backend_csharp/Models/AutoTune/(沿用 fork 5 record 模式):
- VehicleConfigRequest.cs(record · projectId, channelCount, channels[{id, label, position3D, cutoffRange, cutoffCurve?}])
- VehicleConfigResponse.cs(record · saved bool, savedAt, fileSize)
- ChannelMeasureRequest.cs(record · channelId, sweepDurationSec=5.0, mode: 'manual'|'auto-xilink', muteOthers=true)
- ChannelMeasureResponse.cs(record · channelId, freqHz[], magnitudeDb[], phaseDeg[], measureDurationMs)
- PositionMeasureRequest.cs(record · positionId, allChannelsActive=true, micArray[])
- PositionMeasureResponse.cs(record · positionId, micResults[{micId, freq, mag, phase}], synthesizedResponse?)
- 与 P3 fork 1 v2 types.ts schema 对齐(看 git pull 后前端代码)
3. 新增 backend_csharp/Services/AutoTune/VehicleConfigService.cs(工程文件持久化):
- public interface IVehicleConfigService {
Task<VehicleConfig?> LoadAsync(string projectId, CancellationToken ct);
Task<bool> SaveAsync(string projectId, VehicleConfig config, CancellationToken ct);
}
- 内部用 WorkspaceFileHelper(已实装)· 路径 workspace/projects/{projectId}/.xivehicleconfig(JSON · System.Text.Json)
- ❌ 不做任何数学 · 仅 I/O · 校验 channelCount 1-32 · 校验 channels.length == channelCount
4. 扩展 backend_csharp/Services/AutoTune/PysidecarAutotuneBridge.cs(沿用 1898c6f 模式 · 新增 3 method):
- Task<RealtimeFrameResult> AnalyzeChannelFrameAsync(byte[] rawFrame, int channelId, double sampleRate, CancellationToken ct);
· 调 POST http://localhost:8001/auto_tune/realtime_frame · 复用现有桥接逻辑
- Task<PositionSynthesisResult> SynthesizePositionAsync(MicFrame[] micFrames, string positionId, CancellationToken ct);
· 调 POST http://localhost:8001/auto_tune/simulate_apply(借用 · P7 现有能力 · 后续 fork 1c 可新增专用端点)
- 错误重试 3 次指数退避(沿用 1898c6f Polly 模式)
- ❌ Bridge 不做任何数学 · 仅 HTTP 转发 + JSON 反序列化
5. 新增 backend_csharp/Services/AutoTune/MultiChannelMeasureService.cs(编排层 · 核心):
- public interface IMultiChannelMeasureService {
Task<ChannelMeasureResponse> MeasureChannelAsync(ChannelMeasureRequest req, CancellationToken ct);
Task<PositionMeasureResponse> MeasurePositionAsync(PositionMeasureRequest req, CancellationToken ct);
}
- MeasureChannelAsync 实施:
· ① 若 muteOthers=true · 调 set_params 协议 mute 其他通道(走 PysidecarProcessManager 转发 · ❌ 不在 .NET 算 mute 矩阵)
· ② 调 P5 既有 /dev-api/meter/stream 拉 raw FFT 帧(read-only 复用 · 不改其代码)
· ③ 转发 PysidecarAutotuneBridge.AnalyzeChannelFrameAsync 拿 freq/mag/phase
· ④ 包装 ChannelMeasureResponse 返回(❌ 不做任何曲线计算 · 仅字段映射)
- MeasurePositionAsync 实施:
· ① 调 set_params 同时 unmute 所有通道
· ② 多 mic 同步拉 raw 帧(若 micArray 为空报 400)
· ③ 转发 PysidecarAutotuneBridge.SynthesizePositionAsync 拿合成结果
· ④ 包装 PositionMeasureResponse 返回
- ⚠️ 关键:任何"位置声学合成 / 波束 / 混响识别"必须调 P7 · 不在 .NET 自算 · 严守 §禁止 #1
6. DI 注册(Program.cs 增量):
- AddSingleton<IVehicleConfigService, VehicleConfigService>()
- AddSingleton<IMultiChannelMeasureService, MultiChannelMeasureService>()
- 验证已注册 IPysidecarAutotuneBridge / WorkspaceFileHelper / PysidecarProcessManager(应已 1898c6f / 4adda88 落)
7. 扩展 backend_csharp/Controllers/Dev/AutoTuneController.cs(沿用 1898c6f Route + 错误码 · 新增 3 端点):
- GET /api/auto_tune/vehicle_config?projectId=xxx → IVehicleConfigService.LoadAsync · 返回 VehicleConfig 或 404
- POST /api/auto_tune/vehicle_config → IVehicleConfigService.SaveAsync · 返回 VehicleConfigResponse · 校验 channelCount 1-32 否则 400
- POST /api/auto_tune/measure_channel → IMultiChannelMeasureService.MeasureChannelAsync · 返回 ChannelMeasureResponse · channelId 越界 400 / P7 不可达 503 / 超时 504
- POST /api/auto_tune/measure_position → IMultiChannelMeasureService.MeasurePositionAsync · 返回 PositionMeasureResponse · 同错误码语义
- **不修改既有** /api/auto_tune/{calculate,analyze,iterate} 端点(c039075 + 1898c6f 已实装)
8. 单测 + 验收:
cd backend_csharp
# 新增 Tests/Services/AutoTune/VehicleConfigServiceTests.cs(>= 4 case:save 正常 + load 正常 + load 不存在 + channelCount 越界)
# 新增 Tests/Services/AutoTune/MultiChannelMeasureServiceTests.cs(>= 5 case:measure_channel 正常 / muteOthers=false / channelId 越界 / measure_position 正常 / micArray 空)
# 至少 9 个新 case 总计(基线 147/0 → >= 156/0)
dotnet build # 零错误零警告
dotnet test # 全绿 + >= 9 用例
# 手动 e2e(若 P3 fork 1 v2 已 push 联调):
curl -X POST http://localhost:5000/api/auto_tune/vehicle_config -H "Content-Type: application/json" -d '{"projectId":"test","channelCount":16,"channels":[...]}'
9. Commit + push:
git add backend_csharp/Models/AutoTune/ \
backend_csharp/Services/AutoTune/ \
backend_csharp/Controllers/Dev/AutoTuneController.cs \
backend_csharp/Tests/Services/AutoTune/ \
backend_csharp/Program.cs
git commit -m "..."(见下)
git push origin xistudio
【验收】
- 12-14 文件落地(Models/AutoTune ×6 新增 + Services/AutoTune ×2 新增 + PysidecarAutotuneBridge 扩展 ×2 method + Controllers/Dev/AutoTuneController.cs 扩展 ×4 endpoint + Tests ×2 新增 + Program.cs DI)
- dotnet build 零错误零警告 · dotnet test 全绿(基线 147/0 → >= 156/0 · +9 用例)
- 3 新端点可达 · Swagger UI 可见 · 错误码语义正确
- ❌ **PR 自查**:确认 .NET 代码零 FFT/RMS/相位/合成/波束/混响计算(grep MathNet|System.Math.Sqrt|FFT|fft|beamform|reverb 应在 .Tests 之外零命中)· 全部数学走 PysidecarAutotuneBridge HTTP 转发
- 工程文件持久化:save → load 数据完整 · channelCount 1-32 校验生效
- 三元组完整 · commit hash 7 位
- 端到端验证(若 P3 fork 1 v2 已 push):前端车配 Tab 保存 → 后端 .xivehicleconfig 写入 · 测量 Tab 模式 2 选通道 1 → /measure_channel 返回真 freq/mag/phase
【commit】
commit subject:`feat(P5): add /api/auto_tune/{vehicle_config,measure_channel,measure_position} 3 endpoints (P7 bridge · pure I/O orchestration) [ADR-AIOS-11 v1.2 §4.1 fork 1b]`
trailer(必须精确):
[step=1/1] [pid=P5] [uid=U-autotune-channel-measure] [occupies=P5.K-api-routes+P5.K-services+P5.K-controllers]
[files=backend_csharp/Models/AutoTune/**(6 new), backend_csharp/Services/AutoTune/{VehicleConfigService,MultiChannelMeasureService,PysidecarAutotuneBridge(extend)}, backend_csharp/Controllers/Dev/AutoTuneController.cs(extend 4 endpoint), backend_csharp/Tests/Services/AutoTune/**(2 new), backend_csharp/Program.cs(DI)]
[ipc=api/auto_tune/vehicle_config(GET/POST), api/auto_tune/measure_channel(POST), api/auto_tune/measure_position(POST), pysidecar/auto_tune/realtime_frame(reuse), pysidecar/auto_tune/simulate_apply(reuse)]
回告格式参考 done/P5.U-autotune-batch-pipeline--1898c6f.md 末尾(同 ADR · 同部门 · 同三层分工 · 同模式)。
【禁止】
- ❌ **不许在 .NET 里实装任何数学计算**(FFT / RMS / 相位 / 群延迟 / 偏差曲线 / 多通道合成 / 位置波束 / 混响识别 / 共振峰 / 平滑 / 平均 全部禁止)· 数学全归 P7 · 见 ADR-07 §1.3.4 + ADR-11 §2.2 边界铁律 #1
- ❌ **不许引入 MathNet.Numerics / System.Numerics.Vector(数学用途) / Accord.NET / 任何 .NET 数学库**
- ❌ 不许修改 contracts/protocol-v1.md(已 frozen 永久 sleeping · auto_tune-api 留 v2)
- ❌ 不许修改既有 /api/auto_tune/{calculate,analyze,iterate} 端点(c039075 + 1898c6f 已实装)
- ❌ 不许改 P5 现有业务服务 read-only 列表(SourceListService / RefreshLinkService / WorkspaceFileHelper / PysidecarProcessManager / PresetProfileService / MeterTapService / AudioDeviceService / PysidecarMeterBridge / 1898c6f 落的 AutoTunePipelineService)· 严格新增范围(可调用不可改)
- ❌ 不许改前端代码(P3 fork 1 v2 由 ClaudeC 跑)
- ❌ 不许改 pysidecar/* 代码(本任务复用 P7 现有 28 端点 · 后续 fork 1c 若需 P7 新增由本任务回告)
- ❌ 不许改 P6-dsp-algo 代码
- ❌ 不许跳验收 · dotnet build/test 任一红必须修到全绿
- ❌ 不许省略三元组 trailer
- ❌ 不许自改本 prompt 文件
解锁链(本任务 zombie 后)
- ✅ P3.U-autotune-phase1-measure-v2 解锁切真接口(vehicle_config + measure_channel + measure_position 3 端点)
- ✅ ADR-11 v1.2 §4.1 fork 1b 收尾 · P5 后端多通道能力齐全
- ✅ Phase 1 v2 端到端联调路径打通(前端 4 Tab + 4 模式 → 真后端 → P7 数学层)
- ✅ contract-v2 ADR 起草时(P_contracts.K2)有 /api/auto_tune/{vehicle_config,measure_channel,measure_position} 实测数据支撑
风险评估
| 风险 | 缓解 |
|---|---|
| P3 fork 1 v2 还没 push · types.ts schema 不可见 | Step 1 git pull · 若未就绪本任务先按 ADR-11 v1.2 §1.3.1 锁定 schema 实施 · 联调 diff 即修 |
| 工程文件 .xivehicleconfig 与现有 .xipreset 命名冲突 | 用 .xivehicleconfig 后缀(ADR-05 7 后缀外新增 · 不冲突)· 若需正式入 ADR-05 留 fork 1c |
| HttpClient 超时(单通道扫频 5s + P7 ~10ms · 总 ~5.5s) | 默认 timeout 30s · measure_channel 显式设 60s buffer · 错误重试 3 次指数退避 |
| 多 mic 同步采集 P5 现有 meter/stream 不支持阵列 | measure_position 借用 simulate_apply 占位 · 若需真 mic 阵列同步留 P5 fork 1c 独立子任务 |
| .NET 误引入数学库 | PR 自查 grep MathNet/Math.Sqrt/beamform/reverb 等关键词 · §禁止 第 1 条 + §验收 自查项 |
历史
| 时间 | 事件 | hash |
|---|---|---|
| 2026-05-29 19:10 | ready · ADR-11 v1.2 fork 1b 起草 · 用户决策 5A "必须真接口" + 决策 1B "车配后端落盘" 触发新增 | (待 stop 时回填) |