跳转至
SUPERSEDED

⚠️ 本 ADR 已 SUPERSEDED · 2026-06-01 19:23 · 由 ADR-AIOS-14 取代

撤回原因(2026-06-01 用户 + Cline-AIOS 真值核查): 1. 与 dsp-algo v7 架构文档(docs/03-platform/40-dsp-algo/10-architecture-v7.md · 2455 行)的 ModuleFuncTable + WireInstance + ModuleRegistry 95% 重叠 · 本 ADR 自定义的 plugin_abi.h 是重复发明 2. §2.4 + §4.1 #2 DSP 端 per-module STATIC 拆分是伪需求 · v7 §4.4 modules_config.h + §5 module_registry_all.c 已用更轻方案实现"静态库 + 配置注册" 3. §2.5 xivst-sdk dsp/ 部分不合理 · DSP 端没有"插件" · 只有"静态注册模块" 4. 真正净新增内容仅 PC 端 LoadLibrary 一项 · 工作量 17.5d → 6.5d

替代决议:docs/08-implementation/40-aios/ADR/ADR-AIOS-14-pc-dynamic-plugin-loading.md

本 ADR 保留为只读历史档案 · 任何编辑必须先撤回 superseded 标记 + 起 ADR-AIOS-14-RX

被废弃的 4 个 fork prompt(已 abort,见 prompts/done/*UA9*.aborted-2026-06-01-superseded-by-ADR-14.md): - P6.UA9-plugin-abi-v1-design - P6.UA9-cmake-per-module-refactor-phase1 - P5.UA9-plugin-registry-service - P1.UA9-module-library-from-registry


ADR-AIOS-09 · 动态加载插件架构决议(SUPERSEDED · 历史归档)

1. 上下文(Context)

1.1 触发事件

2026-05-28 17:58 用户在 ADR-AIOS-08 起草需求中将议题 ⑥ 描述为"最重要的系统架构问题",要求"给出一个详细方案"。Cline-AIOS 经 5 路 subagent 真值核查后判定议题 ⑥ 复杂度独立(≥ ADR-07 整体规模),Plan 模式给方向 B 双拆。用户 2026-05-28 18:26 拍板方向 B + 议题 ⑦ 归属 X → 议题 ⑥ 单独成 ADR-AIOS-09。

1.2 用户原话(2026-05-28 17:58 · 议题 ⑥ 部分)

"最重要的系统架构问题:当前所有的功能 module 都是源码编译在 PC 的 dll 中的,那针对第三方的 xivst 插件来说,这应该是不能满足的,链路需要支持动态加载 lib 或者 dll 架构,按照 awe 的架构目前是在 PC 上可以动态加载,在 DSP 中是通过将 lib 打包编译的方式来实现,前一种架构上应该不难实现,静态库的方式就一定不能动态加载,那就意味着,新发布的 lib 一定要编译到总包中才能够实现链路上动态加载;关于这个架构的适配需要给出一个详细方案"

1.3 真值核查发现(prompt_2 dsp_algo 构建系统)

单一根 CMakeLists.txt · AlgoDepartment/04_development/dsp_algo/CMakeLists.txt: - ❌ 无子目录 CMake(dll/ modules/ framework/ 全部无独立 CMakeLists) - ✅ 2 个 add_library target: - L85: add_library(DSPAlgo SHARED ...) — Windows DLL - L125: add_library(DSPAlgoStatic STATIC ...) — 嵌入式固件用静态库

module 编译方式: - modules/source/sink/gain/eq/... 全部源码 OBJECT 编译进单 dll - 没有 per-module STATIC lib 拆分 - 主 dll(dll/dspalgo_dll.c)集中聚合所有 module 入口

module ABI: - 接口头(modules/source/source_module.h 等)各自定义 · 无统一 module_descriptor 工厂结构 - 关键导出符号:__declspec(dllexport) + WINDOWS_EXPORT_ALL_SYMBOLS ON 全开 · 无显式插件 ABI 版本号

C ABI for P/Invoke: - dll/dspalgo_dll.c 暴露 facade 函数 · C# 端 DllImport 引用单 dll 名(DSPAlgo.dll)

第三方插件痕迹: - ❌ 0 命中 LoadLibrary / GetProcAddress / dlopen - ❌ 无 plugin 目录 / plugin manifest

事实判断: - 当前架构:① 全静态库源码编译(无动态加载) - DSP 端"打包 lib"模式:部分存在(DSPAlgoStatic target)· 但未按 per-module 拆分 - PC 端动态加载改造工作量:(已有 SHARED target · 缺 ABI 设计 + 加载器 + 注册表) - DSP 端 lib 打包改造工作量:(需 CMake 重构 + per-module STATIC + 链接器脚本 + 二进制体积优化)

1.4 AWE 对标参考(prompt_4 历史调研)

  • AWE Core 模式:platform_api.h + .awd 驱动文件 + AWE Server 运行时加载
  • AWE Designer SubLayout 通过 .awd manifest 描述模块清单 · 加载到 AWE Core 运行时
  • 用户原话明确"按照 awe 的架构 PC 上动态加载 / DSP 端 lib 打包" → 与 AWE Core 双轨架构一致

2. 决议(Decision)

2.1 主决议 · 双轨动态加载架构

核心理念: - PC 端:走 OS 原生动态库加载(Windows LoadLibrary / Linux dlopen) · 运行时插件目录扫描 - DSP 端:走 lib 静态打包模式 · 编译期注入 · "新发布的 lib 编译到总包" - 共享统一 ABI:PC 和 DSP 共用 plugin ABI 接口 · 不同的是加载机制

2.2 共享插件 ABI(C 接口 · v1)

plugin_abi.h(新建 · dsp_algo/plugin/include/plugin_abi.h):

#ifndef XISOUND_PLUGIN_ABI_H
#define XISOUND_PLUGIN_ABI_H

#include <stdint.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

// ABI 版本号 · 用于运行时兼容性检查
#define XISOUND_PLUGIN_ABI_VERSION_MAJOR  1
#define XISOUND_PLUGIN_ABI_VERSION_MINOR  0

// 插件信息描述
typedef struct {
    uint32_t abi_major;              // 必须 = XISOUND_PLUGIN_ABI_VERSION_MAJOR
    uint32_t abi_minor;              // 向前兼容(host minor >= plugin minor)
    const char* plugin_uid;          // 插件唯一 UID(反向域名风格 'com.xisound.eq.parametric')
    const char* plugin_name;         // 显示名
    const char* plugin_version;      // 语义化版本 '1.0.0'
    const char* plugin_vendor;       // 供应商
    uint32_t module_count;           // 该插件提供的 module 数量
} XisoundPluginInfo;

// Module 描述
typedef struct {
    const char* module_uid;          // module UID(对齐 ADR-04 §2.1.2)
    const char* module_name;         // 显示名
    const char* category;            // 'source' / 'sink' / 'eq' / 'dynamics' / 'utility' / 'custom'
    uint32_t input_port_count;
    uint32_t output_port_count;
    uint32_t param_count;
    uint32_t flags;                  // bit0 = supports_pc / bit1 = supports_dsp / bit2 = stateful
} XisoundModuleDescriptor;

// Module 实例(opaque · 由插件内部定义)
typedef struct XisoundModuleInstance XisoundModuleInstance;

// Module 工厂接口
typedef struct {
    // 创建实例
    XisoundModuleInstance* (*create)(const char* module_uid, uint32_t sample_rate, uint32_t block_size);

    // 销毁实例
    void (*destroy)(XisoundModuleInstance* instance);

    // 处理音频块(in-place 或 out-of-place)
    int32_t (*process)(XisoundModuleInstance* instance,
                       const float** inputs, uint32_t input_count,
                       float** outputs, uint32_t output_count,
                       uint32_t frames);

    // 设置参数
    int32_t (*set_param)(XisoundModuleInstance* instance, uint32_t param_id, double value);

    // 获取参数
    int32_t (*get_param)(XisoundModuleInstance* instance, uint32_t param_id, double* out_value);

    // 获取状态(可选 · 用于序列化)
    int32_t (*get_state)(XisoundModuleInstance* instance, void* buf, size_t* inout_size);

    // 恢复状态(可选)
    int32_t (*set_state)(XisoundModuleInstance* instance, const void* buf, size_t size);
} XisoundModuleFactory;

// === 插件入口函数(每个插件 .dll/.lib 必须导出) ===

// 1. 查询插件信息(host 加载后第一个调用)
typedef const XisoundPluginInfo* (*XisoundPluginGetInfoFn)(void);

// 2. 枚举插件提供的 module(返回 module_count 个 descriptor)
typedef const XisoundModuleDescriptor* (*XisoundPluginGetModulesFn)(void);

// 3. 获取 module 工厂(host 调用以创建实例)
typedef const XisoundModuleFactory* (*XisoundPluginGetFactoryFn)(const char* module_uid);

// 4. 插件初始化(host 加载后调用一次 · 用于全局资源)
typedef int32_t (*XisoundPluginInitFn)(void);

// 5. 插件清理(host 卸载前调用一次)
typedef void (*XisoundPluginShutdownFn)(void);

// 标准导出函数名(host 通过这些名字 GetProcAddress)
#define XISOUND_PLUGIN_GET_INFO_SYMBOL      "xisound_plugin_get_info"
#define XISOUND_PLUGIN_GET_MODULES_SYMBOL   "xisound_plugin_get_modules"
#define XISOUND_PLUGIN_GET_FACTORY_SYMBOL   "xisound_plugin_get_factory"
#define XISOUND_PLUGIN_INIT_SYMBOL          "xisound_plugin_init"
#define XISOUND_PLUGIN_SHUTDOWN_SYMBOL      "xisound_plugin_shutdown"

#ifdef __cplusplus
}
#endif

#endif // XISOUND_PLUGIN_ABI_H

2.3 PC 端动态加载机制

插件目录约定:

<install_root>/plugins/
  ├── builtin/                  # 内置插件(随主程序发布)
  │     ├── xisound-core-eq.dll
  │     ├── xisound-core-dynamics.dll
  │     └── xisound-core-utility.dll
  └── thirdparty/               # 第三方插件(用户安装)
        ├── vendor-A/
        │     └── effect-pack.dll
        └── vendor-B/
              └── rev-pack.dll

加载流程(host 启动时):

① 扫描 plugins/builtin/ + plugins/thirdparty/ 下所有 .dll
② 对每个 dll:
   a. LoadLibrary(dll_path)
   b. GetProcAddress("xisound_plugin_get_info")
   c. 调 get_info() 返回 XisoundPluginInfo
   d. 校验 abi_major == 1 · abi_minor <= host_supported_minor
   e. 不通过 → 卸载 + 记录到 plugin-load-errors.log
   f. 通过 → 调 xisound_plugin_init() · 注册到 PluginRegistry
③ 调 xisound_plugin_get_modules() 枚举 module · 注册到 ModuleRegistry
④ 前端 ModuleLibrary 通过 IPC 拉取 ModuleRegistry 内容显示

PluginRegistry(P5 后端持有):

public interface IPluginRegistry
{
    IReadOnlyList<LoadedPlugin> LoadedPlugins { get; }
    IReadOnlyList<ModuleDescriptor> AllModules { get; }

    Task<PluginLoadResult> LoadPluginAsync(string dllPath);
    Task UnloadPluginAsync(string pluginUid);          // 热卸载(必须先停链路)
    Task ReloadPluginAsync(string pluginUid);          // 热重载(开发期用)

    Task<IModuleInstance> CreateModuleInstanceAsync(string moduleUid, int sampleRate, int blockSize);
}

public record LoadedPlugin(
    string PluginUid,
    string FilePath,
    XisoundPluginInfo Info,
    DateTime LoadedAt,
    PluginLoadStatus Status      // Loaded / Failed / Unloading
);

热卸载安全协议: - 卸载前必须确认无 active ModuleInstance(后端 reference count = 0) - 否则返回 PLUGIN_IN_USE 错误 · 用户必须先停链路 - 开发期 ReloadPluginAsync 必须先 stop chain → unload → load → restart chain

2.4 DSP 端 lib 打包机制

CMake 重构方案:

# 当前(单 CMakeLists)
add_library(DSPAlgo SHARED <all_module_sources>)

# 重构后(每 module 独立 STATIC)
# dsp_algo/modules/CMakeLists.txt
add_subdirectory(source)
add_subdirectory(sink)
add_subdirectory(eq)
add_subdirectory(dynamics)
# ...

# dsp_algo/modules/eq/CMakeLists.txt
add_library(xisound-module-eq STATIC
    eq_module.c
    eq_module_factory.c
    eq_param_table.c
)
target_include_directories(xisound-module-eq PUBLIC include)
target_compile_definitions(xisound-module-eq PRIVATE XISOUND_BUILTIN_PLUGIN=1)

# dsp_algo/CMakeLists.txt(顶层)
# DSP 固件总包 · 链接所有 builtin module
add_library(DSPAlgoStatic STATIC
    framework/dsp_engine.c
    framework/plugin_registry_static.c   # 编译期注入 builtin module 列表
)
target_link_libraries(DSPAlgoStatic
    xisound-module-eq
    xisound-module-dynamics
    xisound-module-source
    # ... 所有 builtin
)

# PC DLL 总包 · 同样链接 builtin · 也支持运行时加载第三方
add_library(DSPAlgo SHARED
    dll/dspalgo_dll.c
    framework/dsp_engine.c
    framework/plugin_registry_dynamic.c   # 运行时扫描 plugins/ 目录
)
target_link_libraries(DSPAlgo
    xisound-module-eq
    xisound-module-dynamics
    # ... builtin 仍编译进
)

第三方 lib 集成流程(DSP 端):

① 第三方提供 .lib 文件(MSVC)/ .a 文件(GCC)+ 描述 .json
② 集成时:
   a. 把 .lib 放入 dsp_algo/modules/thirdparty/<vendor>/
   b. 把 .json 描述加入 dsp_algo/modules/thirdparty/<vendor>/manifest.json
   c. 修改 dsp_algo/modules/CMakeLists.txt 加 add_subdirectory(thirdparty/<vendor>)
   d. 重新编译 DSPAlgoStatic 总包(用户原话"新发布的 lib 编译到总包")
③ DSP 固件烧录 → 第三方 module 编译期已注入 plugin_registry_static

plugin_registry_static.c(编译期注入):

// 由 CMake 生成 · 列出所有 builtin / thirdparty 注册的 module
extern const XisoundModuleFactory* xisound_eq_get_factory(const char*);
extern const XisoundModuleFactory* xisound_dynamics_get_factory(const char*);
// ... 所有静态链入的 module

const XisoundPluginInfo* xisound_static_plugins[] = {
    &xisound_eq_plugin_info,
    &xisound_dynamics_plugin_info,
    // ...
};
const size_t xisound_static_plugin_count = sizeof(xisound_static_plugins)/sizeof(xisound_static_plugins[0]);

2.5 xivst 第三方插件 SDK

SDK 包发布(xivst-sdk-1.0.zip):

xivst-sdk-1.0/
  ├── README.md                      # 使用说明
  ├── include/
  │   └── plugin_abi.h               # 共享 ABI 头(§2.2)
  ├── lib/
  │   ├── windows/
  │   │   ├── x64/xisound-host.lib   # PC host 提供的工具函数(可选 · 如日志)
  │   │   └── arm/xisound-host.lib
  │   └── dsp/
  │       └── adsp-21489/xisound-host.a
  ├── templates/
  │   ├── hello-world-plugin/        # 最小可运行示例
  │   │   ├── CMakeLists.txt
  │   │   ├── src/hello_module.c
  │   │   └── src/plugin_entry.c
  │   └── stateful-eq-plugin/        # 含状态的复杂示例
  ├── tools/
  │   ├── xivst-validator.exe        # 校验插件 ABI 合规性
  │   └── xivst-package.exe          # 打包 + 签名工具
  └── docs/
      ├── abi-reference.md
      ├── pc-build-guide.md
      ├── dsp-build-guide.md
      └── certification.md           # xivst 认证流程

xivst 认证流程(类比 VST3 / Steinberg): 1. 第三方按 SDK 模板开发 module 2. 用 xivst-validator 校验 ABI 合规 + 单元测试 3. 提交插件包到 Xisound 认证中心 4. 通过后获得数字签名 → 用户可信任安装 5. 未签名插件:用户可手动启用("开发者模式") · 默认拒绝加载

2.6 边界铁律(强制约束)

  1. ABI v1 永久冻结:本 ADR accepted 后,plugin_abi.h v1 不允许字段变更/删除 · 仅允许向前兼容追加(minor 版本+)
  2. PC 加载错误不阻塞 host 启动:任何插件加载失败 → log + skip · host 仍能启动(只是缺少该 module)
  3. DSP 不支持运行时加载:用户原话锁定 · 必须 CMake 重新编译总包 · 不允许走任何"伪动态"方案
  4. builtin module 仍编译进主 dll:不允许把 builtin module 拆成可单独删除的 plugin(防御性 · 保证 host 最小可用集)
  5. xivst 签名机制必选:第三方插件默认要求签名 · 仅"开发者模式"允许未签名
  6. module UID 全局唯一:不同插件不允许提供相同 module_uid · 加载冲突时按"先到先得 + 后者跳过 + log warn"

3. 后果(Consequences)

3.1 正面后果

第三方生态打开:xivst SDK 让外部 vendor 开发 module · Xisound 算法生态扩张 ✅ builtin/thirdparty 解耦:核心 module 不再"原子化捆绑" · 用户可选装第三方 effect pack ✅ PC/DSP 双轨架构对齐 AWE:用户原话"按照 awe 的架构" · 行业惯例 ✅ CMake 重构红利:per-module STATIC 拆分让单个 module 可独立测试 / 复用 / 维护 ✅ ABI v1 长期合约:plugin_abi.h frozen 后,2026-2030 年第三方插件二进制兼容 ✅ K2-protocol-v2 推动:与 ADR-08 + ADR-10 合并启 v2 · 新增 §plugin-loading 段

3.2 负面后果与缓解

后果 影响 缓解措施
⚠️ CMake 大重构 dsp_algo 单 CMakeLists → N 子 CMakeLists · 工作量大 分 Phase 拆 · Phase 1 仅 builtin 拆分 · Phase 2 第三方接入
⚠️ ABI v1 冻结后无法改 早期设计错误代价高 本 ADR 落盘前必须有第二轮 ABI 评审 · 邀请 ClaudeB(P6 主战场) review
⚠️ 第三方插件崩溃影响 host 第三方代码缺陷可能 crash 整个 host PC 端可选进程隔离方案(plugin-host-process · 类比 VST3 sandbox)· MVP 不做 · 留下季度
⚠️ 签名机制基础设施 需要 PKI · 证书签发流程 · 撤销机制 MVP 走"自签名 + 用户白名单" · 正式签名流程留商务侧
⚠️ DSP lib 打包工作量 每个 module 单独 STATIC + 链接器脚本 · 嵌入式工具链复杂 优先 PC 端 · DSP 端晚 1-2 个 Phase 跟进
⚠️ 兼容旧 module 注册方式 现有源码注册全部要改 LEGACY_BUILTIN_MODULE_REGISTRY 兼容路径 · 新旧并存 1 个 release · 然后强制迁移

3.3 关键非目标(Non-Goals · 本 ADR 不解决)

  • ❌ 不实施 plugin-host-process 进程隔离方案(MVP 走 in-process · 下季度评估)
  • ❌ 不建立正式 PKI 签名机构(MVP 自签名 + 用户白名单)
  • ❌ 不解决插件版本依赖图(MVP 假设插件无相互依赖 · 类比 VST 不允许 plugin 调 plugin)
  • ❌ 不实施热加载(运行中加载新插件)· MVP 仅 host 启动时扫描
  • ❌ 不修改 protocol-v1.0 frozen(全入 v2)
  • ❌ 不进议题 ⑦ 控制信号(ADR-10)

4. 实施清单(Implementation)

4.1 立即行动(本 ADR accepted 后立即派 · 优先级 P1)

# U-thread 部门 CPU 工作量 描述
1 P6.U-plugin-abi-v1-design DSP ClaudeB 2.0d plugin_abi.h v1 起草 + 第二轮评审 · ABI 字段冻结 + 文档 + 单元测试骨架
2 P6.U-cmake-per-module-refactor-phase1 DSP ClaudeB 3.0d dsp_algo/modules/ 拆 N 个子 CMakeLists · per-module STATIC lib · 顶层 DSPAlgo SHARED 仍编译所有 builtin · 不破坏现有 P/Invoke

4.2 短期解锁(立即行动后 1-2 周内 · 优先级 P2)

# U-thread 部门 CPU 工作量 描述
3 P6.U-plugin-registry-static DSP ClaudeB 1.5d plugin_registry_static.c 实装 · CMake 自动生成 builtin 注册表 · DSPAlgoStatic + DSPAlgo 都用
4 P6.U-plugin-loader-pc DSP ClaudeB 2.5d PC 端 plugin_registry_dynamic.c · LoadLibrary + GetProcAddress + ABI 校验 + plugins/ 目录扫描
5 P5.U-plugin-registry-service 后端 ClaudeB 2.0d C# IPluginRegistry 接口 + Service 实现 · 通过 P/Invoke 调 plugin_registry_dynamic · REST /api/plugins/list + /api/plugins/load + /api/plugins/unload
6 P1.U-module-library-from-registry 前端 ClaudeA 1.5d ModuleLibraryPanel 改造:从 hardcode 列表 → 从 /api/plugins/list 拉取 · 显示 builtin/thirdparty 分类

4.3 中期协调(下个迭代 · 优先级 P2)

# U-thread 部门 CPU 工作量 描述
7 P6.U-cmake-per-module-refactor-phase2 DSP ClaudeB 2.0d thirdparty/ 子目录约定 · manifest.json 描述 · 第三方 .lib 集成示例
8 xivst-sdk.U-bootstrap DSP+Docs ClaudeB+Cline-AIOS 3.0d xivst-sdk-1.0 包 · include/lib/templates/tools/docs 全套 · hello-world + stateful-eq 两示例
9 P_contracts.U-protocol-v2-bootstrap(与 ADR-08/10 共享) 契约 ClaudeB (共享) 见 ADR-08 §4.3 · 本 ADR 贡献 §plugin-loading 段

4.4 长期演进(下季度+)

# 议题 触发条件
10 plugin-host-process 进程隔离方案(VST3 sandbox 风格) 第三方插件崩溃事件首次发生后
11 正式 PKI 签名机构 + 证书撤销机制 商务侧确定生态合作伙伴 ≥3 家
12 热加载(运行中加载新插件) 开发者反馈强烈 + 进程隔离落地后
13 插件版本依赖图 + 解析器 生态 ≥10 个插件 + 出现版本冲突
14 xivst-validator 静态分析增强 SDK 1.0 落地 + 第三方反馈认证流程

5. 验收(Acceptance)

5.1 文档验收(本 ADR 自身)

  • ADR-AIOS-09 主文件落盘(本文件 · status: proposed)
  • P_arch/ADR-AIOS-09-plugin-architecture/ 子进程目录创建
  • P_arch/ADR-AIOS-09-plugin-architecture/PROCESS.md(子进程 PCB)
  • P_arch/PROCESS.md 加 ADR-09 子事件 user_thread
  • DASHBOARD.md v2.7.27 → v2.7.28(§⚡ 加 ADR-09 起草 · §📋 加 8 fork U-thread ready)

5.2 实施验收(§4 全部 U-thread 完成)

检查项 通过条件
P6.U-plugin-abi-v1-design plugin_abi.h v1 落盘 · ClaudeB 第二轮评审通过 · ABI 字段 frozen · 单元测试 ≥10 case
P6.U-cmake-per-module-refactor-phase1 modules/ 子目录全部独立 STATIC · DSPAlgo SHARED 仍可编译 · 现有 P/Invoke 单测全过
P6.U-plugin-registry-static CMake 自动生成 plugin_registry_static.c · DSPAlgoStatic 链接 builtin 集合
P6.U-plugin-loader-pc plugins/builtin/ 目录扫描可加载 · ABI 不匹配的 dll 被拒 + log · GetProcAddress 失败处理
P5.U-plugin-registry-service /api/plugins/list 返回当前加载列表 · /api/plugins/load 测试可成功加载 hello-world 示例
P1.U-module-library-from-registry ModuleLibrary 改用 API 数据源 · builtin/thirdparty 分类显示 · 拖拽创建实例正常
P6.U-cmake-per-module-refactor-phase2 thirdparty/ 子目录约定 · manifest.json schema · 示例第三方 .lib 集成成功
xivst-sdk.U-bootstrap xivst-sdk-1.0.zip 发布包 · hello-world + stateful-eq 编译通过 + 加载到 host 工作正常

5.3 边界铁律验收(长期)

  • 任何 ABI 字段变更 → 必须先起 ADR-09-RX 修订 + 评估 minor 版本+
  • 任何"运行时加载新插件"提议 → 必须先起 ADR-09-RX(本 ADR 仅支持 host 启动时扫描)
  • DSP 端任何"伪动态加载"方案 → 拒绝 · 维持"lib 打包编译总包"约定
  • builtin module 拆出 dll 主包提议 → 拒绝(§2.6 边界铁律 #4)

6. 替代方案(Alternatives Considered)

6.1 替代方案 A(已废弃)· 全 OS 运行时加载(PC + DSP 都用 dlopen)

  • 描述:DSP 端也走运行时加载(类似 Linux DSP 框架)
  • 废弃理由:
  • 用户原话明确锁定"DSP 端 lib 打包编译总包"
  • 多数嵌入式 DSP 工具链不支持运行时加载(SHARC / Hexagon RTOS)
  • 即使支持,内存碎片+加载延时不可接受(实时音频)
  • 本 ADR 选择:PC 运行时加载 + DSP 编译期注入

6.2 替代方案 B(已废弃)· VST3 ABI 直接复用

  • 描述:不自定义 plugin_abi.h · 直接用 VST3 ABI(Steinberg SDK)
  • 废弃理由:
  • VST3 ABI 太重(类厂模式 + COM 风格 IID/CID)
  • 不支持 DSP 端嵌入式编译
  • 第三方插件需付费授权 Steinberg SDK
  • 本 ADR 选择:自定义轻量 C ABI · 概念借鉴 VST 但实现独立

6.3 替代方案 C(已废弃)· LV2 / CLAP 等开源 ABI 复用

  • 描述:用 LV2(Linux 音频)或 CLAP(开源新协议)作为 ABI
  • 废弃理由:
  • LV2 与 Linux/RDF 强耦合 · Windows/嵌入式适配差
  • CLAP 仍在演进 · ABI 不稳定
  • 都没有"DSP 编译期注入"路径
  • 本 ADR 选择:自定义 + 概念借鉴

6.4 替代方案 D(已废弃)· in-process 但用 LuaJIT/WASM 沙箱

  • 描述:第三方插件用脚本 / WASM 编写 · 沙箱执行
  • 废弃理由:
  • 性能损耗(实时音频 30 fps 不可接受)
  • 与"对标 AWE 架构"用户原话不符
  • 复杂度高于本 ADR 方案
  • 本 ADR 选择:原生 C ABI + 编译期签名

7. 相关决议与文档

7.1 相关 ADR

  • ADR-AIOS-01:multi-agent-collaboration(P_contracts B1-B4 · contract-v1.0 frozen) — 本 ADR 推动 K2-protocol-v2
  • ADR-AIOS-04:XiForge 架构(Module UID 规范) — 本 ADR plugin_abi.h XisoundModuleDescriptor.module_uid 必须符合 ADR-04 §2.1.2
  • ADR-AIOS-05:XiStudio Workspace(LEGACY_*_MAP 三件套) — 本 ADR LEGACY_BUILTIN_MODULE_REGISTRY 沿用
  • ADR-AIOS-06:OS 化任务调度 — 本 ADR 全程使用其调度协议
  • ADR-AIOS-07:P3-xitune / P4-xitest · P0.K-shared-meter-dock — 不直接相关
  • ADR-AIOS-08(平行):议题 ①~⑤ XiLink Stage UX — 共享 K2-protocol-v2 启动
  • ADR-AIOS-10(平行):议题 ⑦ 控制信号画布 — 共享 K2-protocol-v2 启动

7.2 相关 PROCESS.md

  • processes/P6-dsp-algo/PROCESS.md(本 ADR 主战场 · 新增 5 fork U-thread)
  • processes/P5-backend-csharp/PROCESS.md(本 ADR 新增 1 fork U-thread)
  • processes/P1-xilink/PROCESS.md(本 ADR 新增 1 fork U-thread · ModuleLibrary 改造)
  • processes/P_contracts/PROCESS.md(K2-protocol-v2 启动 · 三 ADR 共享)
  • processes/P_arch/PROCESS.md(本 ADR 子事件 user_thread)
  • processes/P_arch/ADR-AIOS-09-plugin-architecture/PROCESS.md(子进程 PCB · 本 ADR 派生)

7.3 关联契约

  • contracts/protocol-v1.md(frozen · 不修改)
  • contracts/protocol-v2.md(本 ADR + ADR-08 + ADR-10 共同启动)
  • §plugin-loading(本 ADR 贡献)
  • dsp_algo/plugin/include/plugin_abi.h(本 ADR 新建 · v1 永久冻结)

8. 状态流转(Status History)

日期 状态 操作 说明
2026-05-28 17:58 起草触发 用户提议题 ⑥ "最重要架构问题" + 要求"详细方案" DASHBOARD §🤔
2026-05-28 18:10 真值核查 Cline-AIOS 5 路 subagent 并行核查 dsp_algo 构建系统 单 CMakeLists + 全静态 · 0 动态加载痕迹
2026-05-28 18:18 方案研判 plan_mode_respond 议题 ⑥ 单独成 ADR-09 推荐 工作量 ≥ ADR-07
2026-05-28 18:26 方案拍板 用户选方向 B + 议题 ⑦ X · 议题 ⑥ 独立 K2-protocol-v2 启动
2026-05-28 18:35 proposed(本版) ADR-AIOS-09 v1.0 落盘 status: proposed 等用户 accept ADR-AIOS-09

9. 关键术语表(Glossary)

术语 定义
plugin_abi.h Xisound 插件统一 C ABI 头文件 · v1 永久冻结 · PC + DSP 共用
XisoundPluginInfo 插件描述结构 · ABI 版本 + UID + 版本 + 供应商 + module 数
XisoundModuleDescriptor module 元描述 · UID + 名称 + 类别 + 端口数 + 标志位
XisoundModuleFactory module 工厂接口 · create / destroy / process / set_param / get_state 等
PluginRegistry host 持有的插件注册表 · LoadedPlugins + AllModules · 增删改查接口
plugin_registry_static DSP/PC 编译期注入的 builtin 插件列表 · CMake 生成
plugin_registry_dynamic PC 运行时加载的第三方插件列表 · LoadLibrary + GetProcAddress
xivst Xisound VST 风格第三方插件 · 类比 VST3 但自定义 ABI
xivst-sdk xivst 第三方开发者 SDK · include + lib + templates + tools + docs
xivst-validator 插件 ABI 合规性校验工具 · SDK 自带
K2-protocol-v2 契约 v2 · 由 ADR-08 + ADR-09 + ADR-10 共同启动 · 本 ADR 贡献 §plugin-loading
LEGACY_BUILTIN_MODULE_REGISTRY 兼容路径 · 旧 module 源码注册方式过渡到新 plugin_abi

10. 决议者签名(Approvers)

  • 拍板:用户(2026-05-28 18:26 选方向 B + 议题 ⑥ 独立成 ADR-09 · 启动 K2-protocol-v2 · 立即开始 fork)
  • 起草:Cline-AIOS · cwd=d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/
  • 真值核查:Cline-AIOS 5 路 subagent 并行核查(2026-05-28 18:10) + AWE 历史调研材料汇总
  • ABI 评审(待):ClaudeB(P6 主战场)在 P6.U-plugin-abi-v1-design 实施时第二轮评审
  • 后续修订:任何修改本 ADR 必须先 fork ADR-09-RX(R = Revision)子进程 · ABI 字段变更必须 minor 版本+

本 ADR 落地 = AIOS v7 OS 化模型下"长周期架构 ADR"实践 · 与 ADR-08(短平快 UX) + ADR-10(信号画布)平行起草 · 三者共同启动 K2-protocol-v2 · 议题 ⑥ 单独深挖回应用户"详细方案"诉求。