- backend_csharp/Models/Plugin/(全新 · LoadedPlugin / PluginInfo / PluginLoadResult / ModuleDescriptor records)
- backend_csharp/Services/Plugin/PluginRegistry.cs(全新 · IPluginRegistry 接口 + Service 实现)
- backend_csharp/Services/Plugin/PluginInteropMock.cs(Phase A · mock P/Invoke · 等 fork 4 zombie 后切真接口)
- backend_csharp/Controllers/Plugin/PluginController.cs(全新 · /api/plugins/* REST)
- backend_csharp/Tests/Services/Plugin/PluginRegistryTests.cs(新增)
- backend_csharp/Tests/Controllers/Plugin/PluginControllerTests.cs(新增)
- backend_csharp/Program.cs(DI 注册一行) occupies: [P5.K-services-plugin(写), P5.K-models-plugin(写), P5.K-controllers-plugin(写)] adr: docs/08-implementation/40-aios/ADR/ADR-AIOS-09-plugin-architecture.md ref_section: §2.3 PC 端动态加载机制 + §4.2 fork 5 derived_from: ADR-AIOS-09 created: 2026-05-30 last_modified: 2026-05-30 12:16 dispatched_at: 2026-05-30 12:16 estimated: 2.0d unblocks:
- P1.UA9-module-library-from-registry(前端 ModuleLibrary 改造 · 调 /api/plugins/list 真接口) related_zombie:
- P5.U-meter-tap-multi-tool--48cf0ba(同部门 ClaudeB · 标本 · Service + Controller + Test 模式参考)
- P5.U-autotune-batch-pipeline--1898c6f(同部门 · DI 注册 + REST 模式参考) related_dispatched:
- P6.UA9-plugin-abi-v1-design(P6 · ABI 头 · 文件正交 · Phase A mock 不强等其 zombie)
- P6.UA9-cmake-per-module-refactor-phase1(P6 · 文件完全正交)
- P1.UA9-module-library-from-registry(前端 · 文件完全正交 · 同期 Phase A mock)
P5.UA9-plugin-registry-service · C# IPluginRegistry + REST API(ADR-AIOS-09 §2.3 fork)
Worker:TBD(用户分配 · isolation: 🧵 file · 主仓 04_development/ 任一空闲后端 worker)· 部门:后端 (backend-csharp) 预计:2.0d · 优先级:P1 · 状态:dispatched 隔离:🧵 文件隔离(backend_csharp/{Models,Services,Controllers}/Plugin/ 全新子目录 · 与 ADR-08 / ADR-11 后端 fork 完全正交 · 与 ADR-09 P6 fork 跨栈正交)
🔍 触发与解锁链
| 触发 | 状态 | 影响 |
|---|---|---|
| ADR-AIOS-09 accepted v1.1 | ✅ 2026-05-30 09:18 | 8 fork 启动 · 用户拍板派首批 4 fork |
| .clinerules v1.4 §任务隔离类型分配准则 | ✅ | 本 fork 标 isolation: file(同 worktree 同 branch xistudio · 与 ADR-08 后端 zombie 文件正交) |
| Phase A mock 策略 | ✅ | 不强等 fork 1(plugin_abi.h)+ fork 4(plugin_loader_pc)zombie · 内置 PluginInteropMock |
| ADR §2.3 PluginRegistry 接口定义 | ✅ 永久 | C# IPluginRegistry 接口字段对齐 ADR §2.3 line 217-237 |
→ 跨栈独立(纯后端 C#) · 不修改 contract-v1.0 · /api/plugins/* 走 dev-api 桥接(待 K2-protocol-v2 §plugin-loading 正式入)。
任务定义(基于 ADR-AIOS-09 §2.3)
按 ADR-09 §2.3 PC 端动态加载机制 · 实装 C# 后端 PluginRegistry Service + REST API:
- Models/Plugin/(全新 · ADR §2.3 line 230-237 字段对齐):
LoadedPlugin.cs(record · PluginUid / FilePath / Info / LoadedAt / Status)PluginInfo.cs(record · 对齐 ADR §2.2 XisoundPluginInfo · abiMajor/abiMinor/pluginUid/pluginName/pluginVersion/pluginVendor/moduleCount)ModuleDescriptor.cs(record · 对齐 ADR §2.2 XisoundModuleDescriptor · moduleUid/moduleName/category/inputPortCount/outputPortCount/paramCount/flags)PluginLoadResult.cs(record · success/loadedPlugin?/error?/abiMismatch?)-
PluginLoadStatus.cs(enum · Loaded / Failed / Unloading) -
Services/Plugin/PluginRegistry.cs(全新 · IPluginRegistry 接口 + 实现):
-
Services/Plugin/PluginInteropMock.cs(Phase A · mock 数据源):
- 返回 hardcoded 的 builtin plugins 列表(eq / dynamics / source / sink 等 · 与 dsp_algo/modules/ 实际目录对齐)
- 模拟 abiMajor=1/abiMinor=0
-
给 PluginRegistry 注入 · DI 通过 environment 切换 mock vs real(real 等 fork 4 zombie 后切)
-
Controllers/Plugin/PluginController.cs(全新):
GET /api/plugins/list→ 返回 LoadedPlugins + AllModulesPOST /api/plugins/loadbody { dllPath } → 调 LoadPluginAsync → 返回 PluginLoadResultPOST /api/plugins/unloadbody { pluginUid } → 调 UnloadPluginAsync-
POST /api/plugins/reloadbody { pluginUid } → 调 ReloadPluginAsync(开发期用) -
Tests + DI 注册
Phase A → Phase B 切换路径: - Phase A:PluginInteropMock 内置 hardcoded 数据 · 单测 + 集成测试 mock 跑通 - Phase B(fork 4 zombie 后):新建 PluginInteropReal.cs · DllImport plugin_loader_pc 函数 · 切换 DI 注入
完整 prompt(直接复制粘贴 worker 终端)
[U-thread] P5.UA9-plugin-registry-service(alias: P5.U-plugin-registry-service)
[部门] 后端 .NET · ADR-AIOS-09 §2.3 PC 端动态加载机制 · skill: dotnet-realtime-communication
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/(主仓 · 同 worktree 同 branch xistudio)
[Occupies] P5.K-services-plugin(写 · IPluginRegistry + Service + Mock) + P5.K-models-plugin(写 · 5 records) + P5.K-controllers-plugin(写 · /api/plugins/* REST)
[隔离] 🧵 文件隔离(.clinerules v1.4 §任务隔离类型分配准则)· 仅写:
- backend_csharp/Models/Plugin/(全新)
- backend_csharp/Services/Plugin/(全新)
- backend_csharp/Controllers/Plugin/(全新)
- backend_csharp/Tests/Services/Plugin/ + Tests/Controllers/Plugin/(全新)
- backend_csharp/Program.cs(DI 注册一行)
严禁动 Services/Error/ · Services/Metrics/ · Services/Runtime/(ADR-08 已 zombie 后端拥有)· Services/AutoTune/(ADR-11 拥有)
[优先级] P1 · 2.0d · ADR-09 fork 5 · 跨栈独立 · Phase A mock 先跑(不强等 fork 1+4 zombie)· Phase B 切真接口(等 fork 4 zombie 后零 UI 改动)
[ADR] d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-09-plugin-architecture.md(必读 §2.3 PC 端动态加载机制 + §4.2 fork 5)
[业务行为契约引用] ADR-AIOS-09 §2.3 PluginRegistry 接口(line 217-237 完整 C# 代码示例)+ §2.2 ABI 字段对齐
[参考文档](绝对路径)
- d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-09-plugin-architecture.md(主 ADR · §2.3 必读 + §2.2 ABI 字段)
- d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/active/P6.UA9-plugin-abi-v1-design.md(同期 P6 fork · 看 ABI 字段定义 · 本任务 PluginInfo / ModuleDescriptor 字段一对一)
- 同部门标本(强制 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 · Service + Controller + Test 模式参考)
- 同部门标本 2:d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/prompts/done/P5.U-autotune-batch-pipeline--1898c6f.md(DI 注册 + REST 模式)
- 现有后端结构:d:/work/25_claude/workspace/AlgoDepartment/04_development/backend_csharp/Services/(看 Error/Metrics/Runtime/Autotune 已 zombie 子目录的 namespace + DI 模式)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/backend_csharp/Program.cs(看 DI 注册风格)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/backend_csharp/Controllers/(看现有 Controller 风格)
- d:/work/25_claude/workspace/AlgoDepartment/04_development/dsp_algo/modules/(列目录 · mock 数据 hardcoded plugin 列表参考实际 module 名)
- contract-v1.0(已 frozen · 不改):d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/contracts/protocol-v1.md
【背景】
ADR-AIOS-09 accepted v1.1 · 议题 ⑥ 动态加载架构 · §2.3 PC 端动态加载机制要求 C# 后端持有 IPluginRegistry · 通过 P/Invoke 调 plugin_registry_dynamic(C 端 · fork 4)· 暴露 REST `/api/plugins/list` + `/api/plugins/load` + `/api/plugins/unload`。
🚨 **真值核查**:
- 当前 backend_csharp/Services/ 无 Plugin/ 子目录(0 命中)
- 当前 backend_csharp/Controllers/ 无 PluginController(0 命中)
- 与 ADR-09 P6 fork 1(plugin_abi.h)+ fork 4(plugin_loader_pc)依赖 · 但本 fork 用 PluginInteropMock 解耦 · 不强等
**Phase A mock 策略**(不强等 fork 1+4 zombie):
- PluginInteropMock 提供 hardcoded plugin 列表(模拟 builtin 4-6 个 plugin · 与 dsp_algo/modules/ 子目录对齐)
- 单测 + REST 端到端验证全跑 mock 数据
- DI 注册时按 environment 选 Mock 还是 Real(Real = PluginInteropReal · 等 fork 4 zombie 后实装)
**Phase B 切换**(fork 4 zombie 后):
- 新建 PluginInteropReal.cs · DllImport plugin_registry_dynamic 的 4 个 C 函数(scan / load / unload / get_info)
- DI 切换 Mock → Real(单行 Program.cs 修改)
- UI 零改动 / REST 端点零改动
**ADR §2.3 PluginRegistry 接口完整 schema**(line 217-237):
```csharp
public interface IPluginRegistry {
IReadOnlyList<LoadedPlugin> LoadedPlugins { get; }
IReadOnlyList<ModuleDescriptor> AllModules { get; }
Task<PluginLoadResult> LoadPluginAsync(string dllPath);
Task UnloadPluginAsync(string pluginUid); // 热卸载(必须先停链路)
Task ReloadPluginAsync(string pluginUid); // 热重载(开发期用)
}
public record LoadedPlugin(
string PluginUid,
string FilePath,
XisoundPluginInfo Info,
DateTime LoadedAt,
PluginLoadStatus Status // Loaded / Failed / Unloading
);
契约策略:不修改 contract-v1.0(已 frozen) · /api/plugins/* REST 走 dev-api 桥接 · K2-protocol-v2 §plugin-loading 起草时正式入。
【执行步骤】
Step 1 · read 已有基础(只读 · 必做) - read ADR-AIOS-09 §2.3 全文(line 187-242 · PluginRegistry 接口完整定义 + 加载流程 4 步)+ §2.2 ABI 字段(line 88-184 · PluginInfo/ModuleDescriptor 字段) - read 同期 prompts/active/P6.UA9-plugin-abi-v1-design.md(看 ABI 字段最终定义 · 本任务 PluginInfo C# record 字段一对一) - read backend_csharp/Services/Error/LinkErrorBroadcaster.cs / Services/Metrics/MetricsAggregator.cs / Services/Runtime/RuntimeTargetService.cs(同期 ADR-08 已 zombie · 看 Service + DI 风格) - read backend_csharp/Program.cs(DI 注册风格) - read backend_csharp/Controllers/(看现有 Controller 命名 · /Dev/AutoTuneController.cs · /Runtime/RuntimeController.cs) - ls dsp_algo/modules/ 列出实际 builtin module(给 PluginInteropMock hardcoded 数据用) - read 标本 prompts/done/P5.U-meter-tap-multi-tool--48cf0ba.md + P5.U-autotune-batch-pipeline--1898c6f.md(同部门 4 维度对齐)
Step 2 · 新建 backend_csharp/Models/Plugin/(5 records) - LoadedPlugin.cs:public record LoadedPlugin(string PluginUid, string FilePath, PluginInfo Info, DateTimeOffset LoadedAt, PluginLoadStatus Status) - PluginInfo.cs:对齐 ADR §2.2 XisoundPluginInfo · public record PluginInfo(uint AbiMajor, uint AbiMinor, string PluginUid, string PluginName, string PluginVersion, string PluginVendor, uint ModuleCount) - ModuleDescriptor.cs:对齐 ADR §2.2 XisoundModuleDescriptor · public record ModuleDescriptor(string ModuleUid, string ModuleName, string Category, uint InputPortCount, uint OutputPortCount, uint ParamCount, uint Flags) - PluginLoadResult.cs:public record PluginLoadResult(bool Success, LoadedPlugin? LoadedPlugin, string? Error, bool? AbiMismatch) - PluginLoadStatus.cs:public enum PluginLoadStatus { Loaded, Failed, Unloading } - 全部 namespace TuningTool.Backend.Models.Plugin
Step 3 · 新建 backend_csharp/Services/Plugin/PluginInteropMock.cs(Phase A 数据源)
- public interface IPluginInterop {
Task> ScanPluginsAsync();
Task
> GetModulesAsync(string pluginUid);
}
- public class PluginInteropMock : IPluginInterop {
// 返回 hardcoded builtin 4-6 个 plugin · 每个含 1-3 个 module
// PluginInfo:abiMajor=1 abiMinor=0 pluginUid="com.xisound.builtin.
Step 4 · 新建 backend_csharp/Services/Plugin/PluginRegistry.cs(IPluginRegistry 实现)
- public interface IPluginRegistry { ... ADR §2.3 schema ... }
- public class PluginRegistry : IPluginRegistry, IHostedService {
private readonly IPluginInterop _interop;
private readonly List
public PluginRegistry(IPluginInterop interop) { _interop = interop; }
public IReadOnlyList<LoadedPlugin> LoadedPlugins => _loaded;
public IReadOnlyList<ModuleDescriptor> AllModules => _modules;
// IHostedService.StartAsync · host 启动时扫描
public async Task StartAsync(CancellationToken ct) {
var plugins = await _interop.ScanPluginsAsync();
foreach (var p in plugins) {
_loaded.Add(p);
var modules = await _interop.GetModulesAsync(p.PluginUid);
_modules.AddRange(modules);
}
}
public async Task<PluginLoadResult> LoadPluginAsync(string dllPath) { ... 调 _interop · 成功后加入 _loaded + _modules ... }
public async Task UnloadPluginAsync(string pluginUid) { ... 调 _interop · 成功后从 _loaded + _modules 移除 ... }
public async Task ReloadPluginAsync(string pluginUid) { ... unload + load ... }
public Task StopAsync(CancellationToken ct) => Task.CompletedTask;
} - 线程安全:操作 _loaded / _modules 时加 lock 或 ImmutableList(简单 lock 即可)
Step 5 · 新建 backend_csharp/Controllers/Plugin/PluginController.cs - [ApiController][Route("api/plugins")] - public class PluginController : ControllerBase { private readonly IPluginRegistry _registry; public PluginController(IPluginRegistry registry) { _registry = registry; }
[HttpGet("list")]
public IActionResult List() => Ok(new { plugins = _registry.LoadedPlugins, modules = _registry.AllModules });
[HttpPost("load")]
public async Task<IActionResult> Load([FromBody] LoadPluginRequest req) {
var result = await _registry.LoadPluginAsync(req.DllPath);
return result.Success ? Ok(result) : BadRequest(result);
}
[HttpPost("unload")]
public async Task<IActionResult> Unload([FromBody] UnloadPluginRequest req) {
await _registry.UnloadPluginAsync(req.PluginUid);
return Ok();
}
[HttpPost("reload")]
public async Task<IActionResult> Reload([FromBody] ReloadPluginRequest req) {
await _registry.ReloadPluginAsync(req.PluginUid);
return Ok();
}
} - LoadPluginRequest / UnloadPluginRequest / ReloadPluginRequest 内联或加到 Models/Plugin/
Step 6 · DI 注册(Program.cs)
- builder.Services.AddSingleton
Step 7 · 单元测试 + 集成测试 - 新增 Tests/Services/Plugin/PluginRegistryTests.cs(>= 6 case:StartAsync 扫描 builtin / LoadPluginAsync 成功 / LoadPluginAsync abi mismatch / UnloadPluginAsync / ReloadPluginAsync / LoadedPlugins 线程安全) - 新增 Tests/Services/Plugin/PluginInteropMockTests.cs(>= 3 case:ScanPluginsAsync 返回 4-6 / GetModulesAsync 字段正确 / LoadPluginAsync 无效路径) - 新增 Tests/Controllers/Plugin/PluginControllerTests.cs(>= 4 case:GET /list 200 / POST /load 200 / POST /load 400 abi 错误 / POST /unload 200) - 至少 13 个新 case - dotnet build → ✓ 零错误零警告 - dotnet test → 基线 147/0 → 目标 ≥ 160/0(+13 用例)
Step 8 · 端到端 mock 真值 - 启动 backend · curl http://localhost:5000/api/plugins/list → 返回 4-6 个 builtin plugin + N 个 module - curl POST /api/plugins/load body {"dllPath":"plugins/thirdparty/foo.dll"} → 模拟 mock 返回(可能 abiMismatch) - 验证 ResponseType + 字段名严格对齐 ADR §2.2 / §2.3
Step 9 · Commit + push - git status / git pull origin xistudio --no-rebase / git add backend_csharp/Models/Plugin/ Services/Plugin/ Controllers/Plugin/ Tests/Services/Plugin/ Tests/Controllers/Plugin/ Program.cs - git commit -m "..."(见下) - git push origin xistudio
【验收】
形式合规: - dotnet build → ✓ 零错误零警告 - dotnet test → ≥ 160/0(基线 +13 用例) - 9-11 文件落地(Models/Plugin ×5 + Services/Plugin ×2 + Controllers/Plugin ×1 + Tests ×3 + Program.cs DI 一行改)
业务行为契约自查清单(ADR §2.2 + §2.3): - [ ] ① IPluginRegistry 接口字段严格对齐 ADR §2.3 line 217-237 - [ ] ② PluginInfo C# record 字段一对一对齐 ADR §2.2 XisoundPluginInfo(7 字段) - [ ] ③ ModuleDescriptor C# record 字段一对一对齐 ADR §2.2 XisoundModuleDescriptor(7 字段 · 不含 flags 子位说明 · flags 留 uint 透传) - [ ] ④ ABI 版本检查:abiMajor 必须 == 1 · 否则 PluginLoadResult.AbiMismatch=true · Error="ABI major mismatch" - [ ] ⑤ /api/plugins/list 返回 { plugins, modules } JSON · 字段名 camelCase - [ ] ⑥ Phase A mock 跑通 · ScanPluginsAsync 返回 4-6 个 builtin(eq / dynamics / source / sink + 现有 dsp_algo/modules/ 实际目录) - [ ] ⑦ Phase B 切换路径预留:PluginInteropReal.cs TODO 注释 · DI 切换点明确(Program.cs 一行改) - [ ] ⑧ 线程安全:LoadedPlugins / AllModules 多线程读不 crash(单测覆盖 ≥ 100 并发读) - [ ] ⑨ ADR §2.3 热卸载安全协议:UnloadPluginAsync 不实施 reference count(本任务 mock · 留 fork 4 真接口实施)· 但接口签名预留 cancellation
【commit】
subject:feat(P5.UA9-plugin-registry-service): IPluginRegistry + PluginInteropMock + /api/plugins/* REST(Phase A mock) · ADR-09 §2.3 frontend backend bridge
trailer(必须精确): [step=9/9] [pid=P5] [uid=UA9-plugin-registry-service] [occupies=P5.K-services-plugin+P5.K-models-plugin+P5.K-controllers-plugin] [files=backend_csharp/Models/Plugin/, backend_csharp/Services/Plugin/PluginRegistry.cs, backend_csharp/Services/Plugin/PluginInteropMock.cs, backend_csharp/Controllers/Plugin/PluginController.cs, backend_csharp/Tests/Services/Plugin/, backend_csharp/Tests/Controllers/Plugin/**, backend_csharp/Program.cs] [ipc=api/plugins/list, api/plugins/load, api/plugins/unload, api/plugins/reload] [isolation] file(同 worktree 同 branch · 文件正交于 ADR-08 已 zombie 后端 + ADR-11 + ADR-09 P6/P1 fork) [phase] A=mock(internal PluginInteropMock) → B=real(PluginInteropReal via P/Invoke · 等 fork 4 zombie) [derived_from] ADR-AIOS-09 §2.3 fork 5
【禁止】 1. ❌ 不许新建 PluginInteropReal.cs(留 fork 4 zombie 后)· 本任务仅 PluginInteropMock 2. ❌ 不许真调 LoadLibrary / GetProcAddress(本任务纯 mock · 留 fork 4 P6.UA9-plugin-loader-pc) 3. ❌ 不许动 Services/Error/ · Services/Metrics/ · Services/Runtime/(ADR-08 已 zombie 拥有) 4. ❌ 不许动 Services/AutoTune/(ADR-11 拥有) 5. ❌ 不许动 dsp_algo/ 任何文件(P6 fork 拥有) 6. ❌ 不许动 frontend_vue3/ 任何文件(P1 fork 6 拥有) 7. ❌ 不许修改 contracts/protocol-v1.md(已 frozen · §plugin-loading 入 v2) 8. ❌ 不许在 Models/Plugin/ 加 ADR §2.2 未提的字段(PluginInfo / ModuleDescriptor 严格对齐 ABI · 多余字段破坏 P/Invoke 兼容性) 9. ❌ 不许嵌入完整 C# 类骨架(.clinerules v1.6 · worker 自决) 10. ❌ 不许跳验收(dotnet build/test 任一红必须修到全绿) 11. ❌ 不许省略三元组 trailer(含 [phase] + [isolation] 特殊标记) 12. ❌ 不许自改本 prompt 文件 ```
解锁链(本任务 zombie 后)
- ✅ fork 6 P1.UA9-module-library-from-registry 解锁(前端 ModuleLibrary 改造 · 调 /api/plugins/list 真接口 · 即使本任务是 Phase A mock · 接口字段稳定)
- ✅ ADR-09 §2.3 C# 后端层就位 · Phase A mock 给前端验证完整业务路径
- ✅ Phase B 切换路径预留(fork 4 P6.UA9-plugin-loader-pc zombie 后 · DI 一行切 Mock → Real)
- ✅ 给 K2-protocol-v2 §plugin-loading 起草提供 REST schema 实测数据
风险评估
| 风险 | 缓解 |
|---|---|
| ⚠️ Phase A mock 字段与 fork 1 plugin_abi.h v1 字段最终不一致 | step 1 强制 read fork 1 prompt + 等 fork 1 第二轮评审 approved 后 · 本任务 commit 前同步字段 · 若 ABI 字段已 frozen 仍冲突 · 起 ADR-09-RX 处理 |
| ⚠️ IHostedService.StartAsync 阻塞启动太久 | mock 数据 4-6 个 plugin 应 < 100ms 完成 · 真接口阶段(fork 4 zombie 后)需测量 |
| ⚠️ /api/plugins/load 路径不安全(允许任意 dllPath) | 路径校验:必须在 plugins/ 目录下 · 拒绝绝对路径 / .. 路径 · mock 阶段简单校验 · 真接口阶段加严格 sandbox |
| ⚠️ 与 ADR-08 三 zombie 后端 Service 的 DI 顺序冲突 | step 7 跑 dotnet test 全部 · 若 DI 链被破坏 · 修 Program.cs 注册顺序 |
| ⚠️ Phase B 切换时 PluginInteropMock vs Real 字段不兼容 | 接口 IPluginInterop 抽象层稳定 · Real 实现纯 P/Invoke 转发 · UI 零改动 |
| ⚠️ 与 cpu1 派 fork 1b(P5.U-autotune-channel-measure)文件冲突 | fork 1b 在 Services/AutoTune/ · 本任务在 Services/Plugin/ · 文件正交 |
历史
| 时间 | 事件 | hash |
|---|---|---|
| 2026-05-30 12:16 | dispatched · ADR-09 4 fork 首批派发(B 方向 · fork 5 后端 · Phase A mock 不强等 fork 1+4 zombie · isolation: file 同 worktree)· UID v1.4 命名 P5.UA9 | — |