跳转至
ACCEPTED

ADR-AIOS-16 · 主图子图统一架构(SubgraphRuntime 前端扁平化展开)

状态:accepted · 2026-06-05 用户拍板 · F1+F5 已派发

取代:ADR-AIOS-08-R1 双 fork(58f8e9b + 81e3454 已 zombie · 不删 · 标 superseded)· 收口 ADR-AIOS-08 议题 ④ 5 hotfix 历史(40b73e5 / 40781e8 / d325475 / 35855b7 等)

核心承诺:dsp_algo/v7 framework 零修改 · 严守 §2.6 铁律(DSP 永远静态注册 + 不感知子图嵌套 · 不引入第二套 chain ABI)


1. Context · 背景

1.1 触发原因

用户 2026-06-02 反馈:子图(subgraph)系统在 xilink stage 反复修复仍有 7 个并行问题(详见 §1.3)· 怀疑根因 = "主图和子图是两套不复用"。这不是简单 hotfix · 是 ADR 级真值核查 + 架构梳理。

历史包袱: - ADR-AIOS-08 议题 ④(子图创建画布)从 2026-05-30 起经历 5 次 hotfix(40b73e5 / 40781e8 / d325475 / 35855b7 + 一次 cancelled)· 用户实测 2026-05-31 14:21 仍不可用 · 拍板起 ADR-08-R1 - ADR-AIOS-08-R1(58f8e9b + 81e3454 双 zombie · 2026-05-31 22:30 + 22:52)· tab + 默认 1in1out + Inspector 端口可配 + linkStore.toJSON 持久化 + Ctrl+S 全部落地 · 用户 2026-06-02 重测仍报 7 问题 · 拍板全面架构重审

1.2 5 路 subagent 真值核查铁证

2026-06-02 18:00~18:20 派出 5 路 subagent 平行核查主仓 04_development(严守 .clinerules v1.5 真值核查铁律 · git -C 显式指定主仓):

subagent 核查范围 关键铁证
#1 前端架构真相 LinkSchema/SubgraphDef/linkStore.ts ❌ Schema 同构(SubgraphDefinition.nodes 复用 ModuleInstance[])· CRUD 双套并行(7 对 wrapper · 缺失 updateNodeParamInSubgraph)
#2 dsp_algo v7 framework dynchain_parser.c / dynchain_types.h / Binary Frame v4 完全不支持嵌套调度 · 全仓 grep "subgraph" 0 命中 · v7 frame schema 无 subgraph 字段
#3 backend C# 持久化 LinkService.cs / LinkApiRoutes.cs ✅ 纯 JSON passthrough(subgraph 走 /api/links/* 序列化但不参与业务)
#4 mixer N 显示 + mode active 端口错乱 mixer module + RuntimeTarget store ⚠️ widget groupMode 配置 + 双 store 写 race 必现
#5 反复修复 commit 链 git log --since=2026-05-30 -- xilink/ 🚨 27 commits 改 xilink/ · LinkEditor.vue ≥ 7 次大改(258/255/68/44/34/20/10 行)· proxy 架构反复(eb0a5a2 加 → 511e517 退 → 116051f → 42d8a57 restore)

1.3 用户实测 7 个问题(本 ADR 必修)

# 问题 真实根因(5 路核查后) 类型
1 mixer_v2 自动通道 N 显示 bug linkStore.resolveOutputChannels 单上游回溯 + mixer 稀疏多输入 + widget 走错 groupMode 分支 UI bug
2 subgraph preset dirty 不触发 linkStore 缺失 updateNodeParamInSubgraph action + 子图 mutation 无 markDirty() 架构问题
3 module argument dirty 不触发 同问题 2 · paramValues 改动 watch 路径在子图 store 未实现 架构问题
4 模式 active 后 mixer 链路端口错乱(必现) realtimeRunStore._applyWsState 触发 propagatePortInfo 时双写主图+子图 store · race 必现 架构问题(双套并行根因)
5 右键"封装为子图"不自动连线 useSubgraph.encapsulateSelection 只搬 nodes · 漏 connections 复制 状态机 bug
6 子图模式下无声音 v7 framework 0 subgraph 调度 · 前端发的 frame schema 无嵌套 chain · 后端 passthrough 后 dsp 跑空 架构根问题
7 元问题:主图 vs 子图是不是两套 (伪复用、真双轨)· Schema 同构但 CRUD 双套并行 + dsp 不支持嵌套 元根因

1.4 智能体口述真值

ClaudeA 在 ADR-08-R1 fork 1+2 zombie 后 commit message 留下"⚠️ subgraph 持久化已落 · 但实际运行时 dsp 不调度"的隐性提示(commit 81e3454 trailer)· 与 subagent #2 铁证完全吻合。


2. Problem · 问题陈述

主图与子图当前架构 = "Schema 同构 + CRUD 双套并行 + dsp 不感知" 三层割裂:

  1. 数据层(types/subgraph.ts):SubgraphDefinition.nodes: ModuleInstance[] 复用主图类型 → 看似统一
  2. 行为层(linkStore.ts):7 对 wrapper 双套并行(addModule ↔ addModuleToSubgraph / addConnection ↔ addEdgeToSubgraph / removeModule ↔ removeModuleFromSubgraph 等)+ 关键缺口 updateNodeParamInSubgraph 不存在 → CRUD 真双轨
  3. 运行时层(dsp_algo v7):framework 完全不知 subgraph 概念 · 收到的 chain frame 无嵌套字段 → 即便前端建好子图、后端持久化好,dsp 端也只跑顶层节点 · 子图永远静音

继续 hotfix(已死磕 5 次)= 死磕 ADR-08 议题 ④ 重蹈 v3.1.65 P0.UH12 abort 覆辙(教训:智能体反复修不好的问题 = 架构问题 · 必须起 ADR)。


3. Constraints · 硬约束

3.1 工程级硬约束

  1. DSP v7 framework 零修改铁律(继承 ADR-AIOS-14 §2.6):
  2. dsp_algo/framework/* 不动
  3. dynchain_parser.c / dynchain_types.h / Binary Frame v4 schema 不扩字段
  4. DSP 永远静态注册 · 不引入 subgraph_node 类型
  5. contracts/protocol-v1.0 frozen:LinkSchema/ModuleInstance/Connection 字段不破坏(可加可选字段 + LEGACY_MAP 兼容)· 任何破坏性改动 = blocked_on protocol-v2 ADR
  6. LEGACY_*_MAP 7 天宽限期(沿用 ADR-AIOS-05 §5 命名规范铁律):旧 .xilink 文件含 subgraphDefs 嵌套 chain 必须自动迁移为扁平 link 或保留双轨
  7. 测试基线不退化:前端 356/3 + 后端 217/0 + sidecar 78/0 全绿
  8. ADR-AIOS-08 议题 ④ 历史 commit 不删除(58f8e9b + 81e3454 + 5 hotfix commit 全部保留)· 仅 ADR-08-R1 主文档 status accepted → superseded

3.2 Ximind 大模型兼容性 5 项检查清单(.clinerules v1.3 §ADR 设计基本要求 必填)

✅ 状态可读(大模型可 read API 获取)

新增暴露字段(camelCase JSON · 自描述): - GET /api/links/{id} 返回的 LinkSchema 必含: - flattenedChain: ModuleInstance[](SubgraphRuntime 展开后的扁平节点 · 大模型可读"实际 dsp 跑的链路") - subgraphDefs: SubgraphDefinition[](原始嵌套定义 · 大模型可读"用户编辑视图") - flattenStats: { originalNodeCount, flattenedNodeCount, subgraphInstancesExpanded, expansionTimeMs } - GET /api/links/{id}/flatten-preview(新端点 · 仅查询 · 大模型可在不持久化情况下预览展开结果)

✅ 操作可写(大模型可调用语义化 API)

新统一 CRUD 端点(替代 7 对 wrapper): - POST /api/links/{id}/nodes · body 含 targetSubgraphId?: string 字段 · 大模型只需说"在子图 X 加节点 Y" · 无需关心走哪个 wrapper - PATCH /api/links/{id}/nodes/{nodeId}/params · 同上(修复问题 2-3 关键缺口) - POST /api/links/{id}/encapsulate · body 含 nodeIds: string[] + subgraphName: string · 自动复制 internal connections(修复问题 5) - 全部 POST/PATCH 端点必含 description?: string 字段(大模型生成的自然语言意图说明)

✅ 意图可解释(自然语言描述字段)

  • 每个 SubgraphDefinition 含 description: string 字段(用户/AI 生成的子图用途说明 · eg "Cabin EQ 6 段 PEQ 串联")
  • 每个 mutation context 含 intent: { reason: string, triggeredBy: 'user' | 'auto' | 'ximind' }
  • flatten 失败 error 含 human_readable_message(eg "子图 X 引用循环 · 节点 N 自身嵌套自身 · 建议解开嵌套或拆分子图")

✅ 路径可追溯(审计日志)

  • WS /ws/links/audit 推送每次 mutation 事件:{ timestamp, action: 'addNode' | 'updateParam' | 'flatten' | ..., target: { linkId, subgraphId?, nodeId? }, before, after, intent }
  • 持久化:data/audit/links-YYYY-MM-DD.jsonl(JSONL 每行一事件 · 大模型可回放)

✅ 错误可恢复(structured error + recovery_hints)

错误码区间 8xxx(SubgraphError): - SUBGRAPH_FLATTEN_CYCLIC(8001): cyclic dependency · hints: ["移除 node X 的 self-reference", "拆分成两个子图"] - SUBGRAPH_PORT_REF_INVALID(8002): portRef 引用不存在 · hints: ["重新连线", "刷新链路"] - SUBGRAPH_LEGACY_MIGRATION_FAILED(8003): legacy schema 迁移失败 · hints: ["手动重建子图", "查看 LEGACY_SUBGRAPH_MAP 7 天宽限期文档"] - SUBGRAPH_DSP_CAPACITY_EXCEEDED(8004): 展开后节点数超 dsp 上限 · hints: ["减少子图嵌套层数", "切换 RuntimeTarget 到 hexagon-v73(更大 capacity)"]


4. Options · 方向 A/B/C

4.1 方向 A:改 dsp v7 支持嵌套调度(❌ 拒绝)

做法:扩 dsp_algo/framework/dynchain_parser.c + Binary Frame v4 加 subgraph_node 类型 + 嵌套调度引擎。

Trade-off:

维度 评估
工程量 极大(8-12d · 含 dsp 端 C 代码 + ABI 升级 + 21489/21569/hexagon-v73 三平台移植)
风险 破坏 §2.6 铁律(.clinerules v1.0 + ADR-AIOS-14 §2.6 明确"DSP 永远静态注册")· 引入第二套 chain ABI
兼容性 需 protocol-v2 ADR 同启 · 周期延长至少 4 周
性能 dsp 端嵌套调度引入 jump 开销 · 实时音频性能损失 ~5-10%
可维护性 dsp_algo 三平台后续每次新增 module 都要考虑嵌套场景 · 长期维护成本翻倍

结论:拒绝。违反硬约束 §3.1 #1。

4.2 方向 B:前端 SubgraphRuntime 展开为扁平 chain frame(⭐ 选定 · 用户拍板)

做法: 1. 前端引入 SubgraphRuntime 类(纯 TS · 无 dsp 改动)· 在 linkStore.toJSON() 阶段调 SubgraphRuntime.flatten() 把嵌套 chain 展开成扁平 ModuleInstance[] 2. 重映射 connection portRef(子图边界端口 → 内部实际节点端口) 3. 后端 LinkService 收到的 frame 已是扁平的 · passthrough 给 dsp(后端零业务改动 · 仅加 audit log) 4. 用户编辑视图(SubgraphInlinePanel.vue / LinkEditorTabs.vue)继续显示嵌套结构 · 但运行时跑扁平 5. 7 对 wrapper CRUD 统一为单一 mutateLink(context: { subgraphId? }) 路径 · 补 updateNodeParam 缺口 · 自动 markDirty

对标:AudioWeaver Designer 子图实现(子图是 UI 概念 · 运行时编译为扁平 wire)· 与 ADR-AIOS-14 §2.6 哲学一致(host 不感知 builtin/thirdparty 差异 · dsp 不感知子图嵌套)

Trade-off:

维度 评估
工程量 中等(6.5d 跨栈 · 详见 §7)
风险 低(纯前端展开 · dsp 零改动 · 后端零业务改动)
兼容性 LEGACY_SUBGRAPH_MAP 7 天宽限期自动迁移 · 旧 .xilink 兼容
性能 flatten() 调用为 O(N + E)· N=节点数 E=边数 · 典型 link <100 节点展开 <5ms · toJSON 时一次性 · 不影响实时音频
可维护性 高(SubgraphRuntime 单一职责 · 单元测试覆盖率可达 95%+)

结论:选定

4.3 方向 C:完全砍掉子图功能(❌ 拒绝)

做法:hide LinkEditor tab bar · 文档标 Beta · 等 ADR-AIOS-13 闭环后再起 ADR。

Trade-off:用户体验损失大(子图是 LiveAmp/AudioWeaver 必备特性 · 用户已多次明确要求)· 仅作降级方案保留。

结论:拒绝


5. Decision · 决议

采纳方向 B · 用户原话(2026-06-02 18:24):

"B · 派 ADR-AIOS-15 起新 ADR(主图/子图统一架构 · 前端 SubgraphRuntime 展开为扁平 chain frame 发给 dsp · v7 framework 零修改严守 §2.6 铁律)· 估 6-10d · 这是真正架构级方案 · 对标 AudioWeaver 子图实现"

注:ADR 编号顺延为 16(15 已被 ADR-11 §11.8 Generative Audio Tuning AI 候选预留)· Cline-AIOS 落盘时自查规避(.clinerules v1.0 §ADR 编号铁律)。


6. Consequences · 影响面

6.1 正面

  • ✅ 7 个用户问题全部根因消除(详见 §7 fork 映射)
  • ✅ "主图 vs 子图两套并行"元根因消除 · 单一 LinkSchema CRUD 路径
  • ✅ DSP v7 framework 零改动 · §2.6 铁律严守
  • ✅ ADR-AIOS-08 议题 ④ 5 hotfix 历史包袱清算(commit 留存 · 决议归档)
  • ✅ 大模型友好(Ximind 5 项全过 · 见 §3.2)· 为 ADR-AIOS-15 候选(Generative Audio Tuning AI)预留路径
  • ✅ 对标 AudioWeaver Designer 工业标杆

6.2 负面

  • ⚠️ 前端 SubgraphRuntime.flatten() 首次实施复杂度中等(需处理 cyclic detection + portRef 重映射 + LEGACY_MAP)
  • ⚠️ ADR-AIOS-08-R1 双 fork(58f8e9b + 81e3454)主体逻辑被 SubgraphRuntime 取代 · 但 commit 保留作为"历史架构尝试 · supersede 不删"
  • ⚠️ 用户重新理解:子图是 UI 概念 · 运行时是扁平 chain(类似 LiveAmp 模板 · 不是真实嵌套调度)
  • ⚠️ 测试基线短期内必有微调(linkStore unit test 7 对 wrapper 用例需重构)

6.3 跨进程影响

进程 影响
P1(frontend_vue3) 主战场 · 5 fork 改 LinkEditor + linkStore + types/subgraph + composables
P5(backend_csharp) 0.5 fork 加 audit log + 1 新端点 /flatten-preview · 业务零改动
P_e2e 1 fork 5 集成场景 e2e 真值脚本(覆盖 7 个用户问题)
P_arch 本 ADR 自身 · ADR-08-R1 status superseded · ADR-08 议题 ④ 全闭环
P_ximind(候选) 受益 · 提前为 ADR-AIOS-15 候选铺路

7. Implementation · 实施清单(7 fork)

详细 fork 描述请见 P_arch/ADR-AIOS-16-subgraph-unified-architecture/PROCESS.md(子进程 PCB · ready 状态等用户 accept ADR-AIOS-16 后开始派发)

Phase 1 立即派发(并行 · 文件正交 🧵 file)

# UID 部门 工作量 依赖 1 句摘要
F1 P1.A16.F1-subgraph-runtime-flatten 前端 2.0d SubgraphRuntime 类 · flatten() + cyclic detection + portRef 重映射 · 单测 ≥ 25 cases
F2 P1.A16.F2-linkstore-unified-crud 前端 1.5d F1 zombie 删 7 对 wrapper · 统一 mutateLink(context) · 补 updateNodeParam 缺口 · markDirty 自动化 · 修问题 2-3

Phase 2 短期解锁(F1+F2 zombie 后 · 文件正交)

# UID 部门 工作量 依赖 1 句摘要
F3 P1.A16.F3-encapsulate-with-connections 前端 0.5d F2 useSubgraph.encapsulateSelection 复制 internal connections · 修问题 5
F4 P1.A16.F4-mixer-port-info-fix 前端 0.5d F1 widget groupMode: perChannelNameInput · 修问题 1
F5 P5.A16.F5-audit-log-and-flatten-preview 后端 0.5d F1 WS /ws/links/audit + GET /api/links/{id}/flatten-preview · audit JSONL 持久化

Phase 3 中期协调(F1~F5 zombie 后 · 端到端验收) ✅ 已闭环

# UID 部门 工作量 依赖 1 句摘要
F6 P1.A16.F6-runtime-target-race-fix 前端 0.5d F2 realtimeRunStore._applyWsState 走单一 store 路径(F2 后双套并行根因消除)· 修问题 4
F7 P_e2e.A16.F7-truth 🏆 测试编排 1.0d F1+F2+F3+F4+F5+F6 ✅ zombie · 5 集成场景 e2e 17 tests skip-graceful:① flatten 单元 ② 子图无声 dsp 端 PCM 真值 ③ encapsulate connections 完整性 ④ mixer N 显示 ⑤ runtime active race · 7 问题全验收 + 全局红线 #1#2 · ADR-16 fulfilled 🏆

总工作量与并发图

工作量:6.5d(P1 5.0 + P5 0.5 + P_e2e 1.0)
并发图:
  Day 1-2:F1(ClaudeA 2.0d)
  Day 3-4:F2(ClaudeA 1.5d 接 F1)
  Day 5  :F3 + F4 + F5(三 fork 并行 · ClaudeA 1.0d + ClaudeB 0.5d)
  Day 6  :F6(ClaudeA 0.5d)
  Day 6-7:F7(ClaudeC 1.0d e2e 真值)
关键路径:F1 → F2 → F6 → F7(总 5.0d 关键路径)
推荐首批派发:F1 单 fork(F2 强依赖 F1 类型签名 · 不能并行)

Ximind 兼容性 fork 标注(.clinerules v1.3 §ADR 设计基本要求 必填)

直接服务 Ximind 兼容性的 fork: - F1 ⭐(SubgraphRuntime.flatten() 暴露 flattenStats 给 /api/links/* · 大模型可读"实际 dsp 跑什么") - F2(统一 CRUD mutateLink(context) · 大模型可调用单一端点 · 无需关心 wrapper) - F5(audit log + flatten-preview · 大模型可回放历史 + 不持久化预览) - F7(e2e 真值脚本本身验证 Ximind 5 项)


8. Migration · 迁移与兼容

8.1 LEGACY_SUBGRAPH_MAP(7 天宽限期)

旧 .xilink 文件含 subgraphDefs[] 嵌套结构 · 加载时 SubgraphRuntime.detectLegacy() 自动迁移:

// types/subgraph.ts 新增
export const LEGACY_SUBGRAPH_MIGRATION = {
  v1_to_v2: (legacyDefs: SubgraphDefinitionV1[]) => SubgraphDefinitionV2[],
  // V1: ADR-08-R1 落地版本(58f8e9b)· 含 portMappings 字段
  // V2: ADR-16 版本 · portMappings 改名 portBindings + 加 description 字段
} as const;

7 天后(2026-06-09)新版本生效 · 旧 .xipreset 自动升级时弹一次性 toast 提示用户。

8.2 ADR-AIOS-08-R1 status 切换

# ADR-AIOS-08-R1-subgraph-redesign.md frontmatter
status: accepted → superseded
superseded_at: 2026-06-02 (本 ADR accept 时同步)
superseded_by: ADR-AIOS-16

文件内容不删除(永久保留作历史)· 顶部加 banner 指向本 ADR。

8.3 ADR-AIOS-08 议题 ④ 历史 hotfix 归档

5 hotfix commit(40b73e5 / 40781e8 / d325475 / 35855b7 + 1 cancelled)+ 双 R1 fork(58f8e9b / 81e3454)全部保留 · prompts/done/ADR-AIOS-08-R1/ 子目录文件维持现状 · 仅 P_arch PCB 同步 superseded 状态。

8.4 现有 K-thread 释放/锁定

K-thread 操作
P1.K-link-store 维持(F1+F2 主战场 · ClaudeA 独占)
P1.K-shared-types 维持(types/subgraph.ts 加可选字段 + LEGACY_MAP · 不破坏 contract-v1.0)
P5.K-link-service 短锁(F5 加 audit log + 新端点 · 0.5d 释放)

9. Validation · 验收标准

9.1 单元测试(F1~F6 各自验收)

Fork 测试基线 新增 cases
F1 vitest 356 → 380+(+25 SubgraphRuntime + cyclic + portRef + LEGACY_MAP)
F2 vitest +12(7 wrapper 删 · mutateLink 统一 + updateNodeParam)
F3 vitest +5(encapsulate connections 完整性)
F4 vitest +3(mixer N 显示 widget groupMode)
F5 xunit +6(audit log JSONL + flatten-preview 端点)
F6 vitest +4(runtime active 单一 store 路径)

9.2 集成测试(F7 e2e 真值 5 场景)

Scene 验收点 7 问题映射
1 SubgraphRuntime.flatten() 单元(嵌套 3 层 · 100 节点 · <10ms) 问题 7
2 子图模式 dsp 端 PCM 真值(注入 1kHz · 子图含 gain×2 · 输出 -14dBFS ± 1dB) 问题 6 ⭐
3 右键封装 5 节点 + 4 connections · 内部 connections 100% 复制 问题 5
4 mixer 4 输入(2 主图 + 2 子图)· N 显示 = "4ch(4port)" 问题 1
5 RuntimeTarget active 切换 + 子图节点 paramValues 修改 · isDirty 触发 + ● 标记 + 端口不错乱 问题 2-4

全局红线 #1(响应式横竖屏)+ #2(主题 design-token 切换)继承 ADR-12 验收标准。

9.3 用户验收(ADR-08-R1 C4-1~C4-17 重测)

ADR-08 议题 ④ acceptance-checklist.md C4-1~C4-17 全部重跑 · F7 zombie 后由用户照清单逐项验收。

9.4 性能基线

  • flatten() 调用 100 节点 typical link <10ms · 1000 节点 worst-case <50ms(单元测试断言)
  • toJSON 整体延迟增量 <15%(F7 集成验收)
  • 实时音频性能零退化(dsp 端零改动 · 物理保证)

10. References · 参考资料

10.1 关联 ADR

  • ADR-AIOS-08(XiLink Stage UX · 议题 ④ 子图创建画布原始决议)
  • ADR-AIOS-08-R1(子图重新设计 · 本 ADR 取代)
  • ADR-AIOS-14(PC 端动态加载插件 · §2.6 铁律相同哲学:host 不感知差异)
  • ADR-AIOS-15 候选(Generative Audio Tuning AI · 受益于本 ADR Ximind 兼容性铺路)
  • ADR-AIOS-13(XiTest Realtime · F7 e2e 真值范式)

10.2 5 路 subagent 真值核查报告(2026-06-02 18:00~18:20)

完整报告留存在 Cline-AIOS 任务上下文 · 关键铁证摘录见 §1.2。

10.3 工业对标

  • AudioWeaver Designer · 子图编译为扁平 wire(分布式 DSP 不感知嵌套)
  • LiveAmp Designer · 双画布架构(audio chain + control signal canvas)· ADR-AIOS-10 已采纳

10.4 dsp_algo v7 上游必读

  • docs/03-platform/40-dsp-algo/10-architecture-v7.md(2455 行)§3 + §4.2 + §5(ModuleFuncTable + WireInstance + ModuleRegistry · 静态注册铁律)

10.5 历史 commit 链

  • ADR-08 议题 ④ 5 hotfix:40b73e5 + 40781e8 + d325475 + 35855b7 + 1 cancelled(P5.UH-perf-real-data-fix)
  • ADR-08-R1 双 zombie:58f8e9b(2026-05-31 22:30 fork 1 tab + 端口) + 81e3454(2026-05-31 22:52 fork 2 持久化 + Ctrl+S)
  • proxy 架构反复 commit:eb0a5a2 / 511e517 / 116051f / 42d8a57 / 6b1710f
  • LinkEditor.vue ≥ 7 次大改记录:见 subagent #5 报告

11. Ximind Compatibility · 大模型兼容性章节(.clinerules v1.3 §ADR 设计基本要求 必填段)

11.1 大模型可读状态(read API 字段清单)

端点 字段 自描述
GET /api/links/{id} flattenedChain: ModuleInstance[] 实际 dsp 跑的扁平节点 · 含 typeNumId + paramValues + portBindings
GET /api/links/{id} subgraphDefs: SubgraphDefinition[] 用户编辑视图的嵌套定义 · 含 description 字段
GET /api/links/{id} flattenStats originalNodeCount + flattenedNodeCount + subgraphInstancesExpanded + expansionTimeMs
GET /api/links/{id}/flatten-preview ⭐ 新 同上 · 不持久化 大模型可在不修改情况下试探
WS /ws/links/audit mutation event stream 大模型可订阅历史

11.2 大模型可写操作(语义化 API 端点)

端点 语义 description 字段
POST /api/links/{id}/nodes 添加节点(主图或子图) ✅ 必填
PATCH /api/links/{id}/nodes/{nodeId}/params 修改参数 ✅ 必填
POST /api/links/{id}/encapsulate 封装为子图 ✅ 必填(含 subgraphName + 自动 connections 复制语义)
POST /api/links/{id}/flatten 强制重展开 ✅ 必填

全部 POST/PATCH 必含 intent: { reason: string, triggeredBy: 'user' | 'auto' | 'ximind' } 字段。

11.3 自然语言描述字段

  • SubgraphDefinition.description: string(用户/AI 生成的子图用途说明)
  • mutateLink({ context, intent }) 的 intent.reason(eg "用户拖入新 PEQ 节点")
  • error.human_readable_message(eg "子图 X 检测到循环 · 节点 N 自身嵌套 · 建议解开嵌套")

11.4 审计日志路径

  • WS:/ws/links/audit(实时推送)
  • 持久化:data/audit/links-YYYY-MM-DD.jsonl(JSONL · 每行一事件 · 大模型可回放)
  • 字段:{ timestamp, action, target: { linkId, subgraphId?, nodeId? }, before, after, intent, result: 'success' | 'failed' }

11.5 错误结构(structured error · 错误码 8xxx 区间)

type SubgraphError = {
  code: 'SUBGRAPH_FLATTEN_CYCLIC' | 'SUBGRAPH_PORT_REF_INVALID' | 'SUBGRAPH_LEGACY_MIGRATION_FAILED' | 'SUBGRAPH_DSP_CAPACITY_EXCEEDED';
  message: string;            // 程序员视角(英文)
  human_readable_message: string;  // 用户/AI 视角(中文)
  recovery_hints: string[];   // 可执行恢复建议
  context?: { linkId, subgraphId?, nodeId?, conflictingPath? };
};

11.6 与 ADR-AIOS-15 候选(Generative Audio Tuning AI)的关联

本 ADR 全部 Ximind 兼容性设计直接服务 ADR-AIOS-15 候选: - 大模型可读"用户当前编辑的子图结构" → 生成"建议优化为 X 配置" - 大模型可调用 POST /api/links/{id}/encapsulate → "把这 5 个节点封装为'声场调音子图'" - 大模型可订阅 audit log → 学习用户调音偏好(为 ADR-11 §11.2 AI Listener Preference RL Tuner 提供数据源)


附录 A · 业务行为契约 5 必填段(对齐 .clinerules v1.8 + ADR-AIOS-12 §3 标杆)

A.1 输入端契约

  • 用户操作:在 LinkEditor 拖拽 PEQ 节点到子图画布 / 右键封装 / Inspector 改 paramValue
  • 大模型操作:POST /api/links/{id}/nodes + PATCH params + POST encapsulate
  • 系统事件:RuntimeTarget active 切换触发 propagatePortInfo / .xilink 文件加载触发 LEGACY_MAP

A.2 处理流程(收敛)

  1. mutateLink(context) 入口 → 走 unified path · 无 wrapper 分支
  2. SubgraphRuntime.flatten() lazy 计算 · 缓存于 linkStore.flattenedChain · 仅 toJSON / dirty 触发重算
  3. cyclic detection 拦截 · 抛 SUBGRAPH_FLATTEN_CYCLIC + recovery_hints
  4. portRef 重映射:子图边界端口 → 内部实际节点端口
  5. markDirty + ● 标记 + Ctrl+S 触发 toJSON

A.3 失败回退

  • flatten() 失败:保留原嵌套结构 · 弹 toast + audit log 记录 · 用户可继续编辑(运行时 dsp 不跑)
  • LEGACY 迁移失败:fallback 为空 subgraphDefs · 弹一次性确认 · 用户可手动重建
  • DSP capacity exceeded:弹 toast 建议切换 RuntimeTarget · 不阻塞编辑

A.4 用户操作流(UI 侧)

  1. 用户拖拽节点 → mutateLink 入口 → 自动 markDirty → ● 标记 → Ctrl+S 持久化
  2. 用户右键 5 节点 → 选"封装为子图" → 弹命名+description 弹框 → POST /encapsulate → 自动复制 connections
  3. 用户切到 RuntimeTarget active → realtimeRunStore._applyWsState → 单一 store 路径 → 端口不错乱

A.5 e2e 真值(F7 ClaudeC 0.5-1.0d 必跑)

5 集成场景(详见 §9.2)· 严守不动 ADR-13 fork 8 P_e2e.UA13-truth + ADR-12 #12 P_e2e.U-phase4-truth 的 e2e 框架 · 复用 5 集成场景结构(范式 commit 3a8d376 + 92445f5)。


最后更新:2026-06-02 18:25 · Cline-AIOS · proposed status 下一步:用户 accept ADR-AIOS-16 → P_arch PCB state running → 派发 F1(P1.A16.F1-subgraph-runtime-flatten · ClaudeA 2.0d 关键路径起点) 历史档案:ADR-AIOS-08-R1(本 ADR accept 后标 superseded · ADR/ADR-AIOS-08-R1-subgraph-redesign.md 顶部加 banner)