跳转至
FROZEN

Contract · protocol-v1 · AIOS 协议契约 v1

🔒 本文档已 FROZEN(contract-v1.0)

  • Owner:ClaudeB(独占写权限)
  • Statusfrozen · §1-§9 全部完成 · tag contract-v1.0 已打 · 任何修改必须走 ADR-AIOS-NN
  • Frozen at:2026-05-27(HARD-DEADLINE B4 · ClaudeB)
  • Freeze 后规则:全员只读 · 修改须 ADR 决议 → fork P_contracts.K2-protocol-v2

其他智能体:本文档已 frozen,可直接引用,无需暂行替代文档。


0. 文档约定

  • 命名空间格式<scope>.<entity>.<action>(如 shell.slot.set
  • payload 格式:JSON · 必须含 version / timestamp / payload
  • 错误码格式:4 位数字(如 1001)· 区间分配见 §3
  • 章节锁:每章节由 ClaudeB 独立 commit · 顺序 §1 → §9

1. Store Action 命名空间总则

状态:✅ B1 草稿完成(2026-05-27)

1.1 三段式命名规范

所有 Pinia store action 的逻辑标识符(用于文档、协议追踪、错误上报)遵循三段式:

<scope>.<entity>.<verb>
段位 说明 枚举值示例
scope 归属层 shell · engine · workspace · dialog · toast · preset · history
entity 操作对象(UI 区域或数据对象) topbar · dock · inspector · bottom · statusbar · stage · module
verb 动词(祈使式) set · clear · toggle · open · close · show · hide · add · remove

重要:三段式是协议标识符,不是 JavaScript 变量名。Pinia 实现使用标准驼峰命名,见 §1.3。

1.2 消息信封(通用 payload 格式)

所有跨层消息(stage → shell / shell → stage)使用统一信封:

{
  "version": "1",
  "timestamp": 1748304000000,
  "action": "shell.topbar.set-toolbar",
  "payload": {}
}
// TypeScript 信封接口
export interface ActionEnvelope<T = unknown> {
  version:   string          // 协议版本,当前 "1"
  timestamp: number          // Unix ms
  action:    StoreActionKey  // 见 §1.5 全表
  payload:   T
}

规则: - version 在 §1-§9 全部 freeze 前始终为 "1" - timestamp 由发送方在发出时填写(单调递增,不做持久化) - payload schema 由各 action 条目单独定义(见 §1.5) - WS / Pinia / EventBus 传递时,信封可以被框架代理,不要求在运行时显式序列化

1.3 Pinia 实现映射规则

协议标识符 <scope>.<entity>.<verb> Pinia Store Action 方法签名
shell.topbar.set-toolbar useTopbarStore setToolbar(buttons: ToolbarButton[])
shell.topbar.set-modes useTopbarStore setModes(chips: ModeChip[], activeKey?: string)
shell.topbar.set-doc-tabs useTopbarStore setDocTabs(tabs: DocTab[], activeKey?: string)
shell.dock.set-left useDockStore setLeft(panes: DockPane[])
shell.dock.set-right useDockStore setRight(panes: DockPane[])
shell.inspector.set-html useInspectorStore setHtml(html: string, module: string)
shell.bottom.set-module-html useBottomStore setModuleHtml(html: string, module: string)
shell.bottom.set-hint useBottomStore setHint(html: string)
shell.statusbar.set-stage useStatusBarStore setStageHtml(html: string)
engine.state.set useEngineStore setState(info: EngineStateInfo)
dialog.module.open useDialogStore open(payload: DialogOpenPayload)
toast.message.show useToastStore show(message: string, type?: ToastType)
history.state.set useShellSlotsStore setHistory(state: HistoryState)
workspace.stage.set-ready useStageStore setReady(stage: StageKey)
preset.module.activate usePresetStore activate(id: string)

1.4 命名禁忌与保留字

禁止: - ❌ 单段命名:set · click · init - ❌ 大写字母(用 kebab-case 连字符代替 camelCase):setToolbarset-toolbar ✅ - ❌ 含 agent 代号:claudeA.xxx · ClaudeB.xxx - ❌ 含实现细节:pinia.xxx · mitt.xxx · vuex.xxx

保留 scope(禁止 stage 私用): - internal · system · aios · debug

缩写规范(唯一允许表): | 缩写 | 全称 | |---|---| | ws | workspace | | doc | document | | btn | ❌ 禁止,写 button | | msg | ❌ 禁止,写 message |

1.5 12 类 postMessage → Store Action 完整映射表

来源:../../../30-frontend-vue3/00-baseline-alignment.md §3.2

v4.3 postMessage type 方向 协议标识符 / Store Action EventBus signal 优先级
toolbar-inject ↓ shell→stage shell.topbar.set-toolbar P1
toolbar-click ↑ stage→shell toolbar:click P1
mode-switcher-inject shell.topbar.set-modes P1
mode-switch-click mode-switch:click P1
engine-control engine.state.toggle engine:control P1
engine-state-changed → shell内 engine.state.set P1
dock-inject shell.dock.set-left / shell.dock.set-right P2
inspector-inject shell.inspector.set-html P2
module-properties-inject shell.bottom.set-module-html P2
select-node node:selected P2
tuning-dialog dialog.module.open dialog:open P2
show-toast toast.message.show toast:show P1
stage-status shell.statusbar.set-stage P2
stage-hint shell.bottom.set-hint P2
doc-tabs-inject shell.topbar.set-doc-tabs P3
doc-tab-click/close/new doc-tab:{click\|close\|new} P3
stage-ready workspace.stage.set-ready P1
stage-hint shell.bottom.set-hint P2

符号:↑ = stage→shell · ↓ = shell→stage · → = shell 内部广播


2. EventBus 信号集

状态:✅ B1 草稿完成(2026-05-27)

EventBus 基于 mitt 实现(src/utils/eventBus.ts),所有 stage ↔ shell 的事件驱动通信通过此信道传递。

2.1 信号命名规范

<entity>:<verb>
段位 说明 规则
entity 操作对象(名词) 全小写 kebab-case
verb 动作(过去时或动词原形) 全小写,意义明确

示例:toolbar:click · mode-switch:click · node:selected · toast:show · history:undo

2.2 TypeScript 信号全表

权威来源:frontend_vue3/src/types/protocol.ts

// ─────────────────────────────────────────
// §2 AppEvents — EventBus 信号完整类型映射
// ─────────────────────────────────────────

export type AppEvents = {
  // ── Topbar ──
  'toolbar:click':      ToolbarClickPayload       // stage toolbar 按钮点击
  'mode-switch:click':  ModeSwitchClickPayload     // 模式切换 chip 点击
  'doc-tab:click':      DocTabPayload              // 文档 tab 切换
  'doc-tab:close':      DocTabPayload              // 文档 tab 关闭
  'doc-tab:new':        DocTabPayload              // 新建文档 tab

  // ── Stage 内容事件 ──
  'node:selected':      NodeSelectedPayload        // 节点选中(xilink → inspector)
  'dialog:open':        DialogOpenPayload          // 调音对话框打开(stage → DialogManager)

  // ── 引擎 ──
  'engine:control':     EngineControlPayload       // stage 发出引擎控制指令

  // ── 通知 ──
  'toast:show':         ToastPayload               // 显示 Toast 通知
  'toast:dismiss':      { id: string }             // 手动关闭 Toast

  // ── 历史(撤销/重做)──
  'history:undo':       { stage: StageKey }        // Shell TopbarToolbar → 当前 stage
  'history:redo':       { stage: StageKey }

  // ── 项目操作(MenuBar → 所有 stage)──
  'project:save':       void
  'project:new':        void
  'project:open':       void
  'project:propagate':  void                       // workspace 文件已变更,stage 同步
}

// ── 信号 payload 接口(同 §1.3 ActionEnvelope 中的 payload 字段)──

export interface ToolbarClickPayload {
  stage: StageKey
  id:    string               // ToolbarButton.id
}

export interface ModeSwitchClickPayload {
  stage: StageKey
  key:   string               // ModeChip.key
}

export interface DocTabPayload {
  stage: StageKey
  key?:  string               // click/close 时必填;new 时可选
}

export interface NodeSelectedPayload {
  stage: StageKey
  node:  string               // instanceId
  label: string               // 显示名(用于 Inspector 标题)
}

export interface DialogOpenPayload {
  stage:   StageKey
  module:  string             // instanceId
  label:   string
  preset?: string             // 关联的 preset id(可选)
}

export interface EngineControlPayload {
  stage:  StageKey
  action: 'toggle' | 'start' | 'stop' | 'restart'
}

export interface ToastPayload {
  id:        string           // nanoid · 由发送方生成
  type:      ToastType        // 'info' | 'success' | 'warning' | 'error'
  message:   string
  duration?: number           // ms · 默认 3000 · 0 = 不自动关闭
}

2.3 触发方 / 接收方矩阵

信号 触发方 接收方 生命周期
toolbar:click TopbarToolbar.vue 当前激活 stage fire-once
mode-switch:click TopbarModeSwitcher.vue 当前激活 stage fire-once
doc-tab:click TopbarDocTabs.vue 当前激活 stage fire-once
doc-tab:close TopbarDocTabs.vue 当前激活 stage fire-once
doc-tab:new TopbarDocTabs.vue 当前激活 stage fire-once
node:selected 当前 stage(xilink) InspectorPanel.vue fire-once
dialog:open 当前 stage DialogManager.vue fire-once
engine:control 当前 stage toolbar EngineStatusBar.vue fire-once
toast:show 任意 stage / shell 组件 ToastContainer.vue fire-once
toast:dismiss ToastContainer.vue / 定时器 ToastContainer.vue fire-once
history:undo TopbarToolbar.vue 当前激活 stage fire-once
history:redo TopbarToolbar.vue 当前激活 stage fire-once
project:save MenuBar.vue 所有 stage fire-once
project:new MenuBar.vue 所有 stage fire-once
project:open MenuBar.vue 所有 stage fire-once
project:propagate 任意 stage 所有 stage fire-once

2.4 信号生命周期说明

生命周期类型 说明 本协议使用
fire-once 发出后即消费,不持久化 ✅ 全部信号
persistent 新监听者也能收到最近值 ❌ 不使用(用 Pinia reactive state 替代)
debounced 防抖聚合 ❌ 由消费方自行处理

规则:EventBus 不持久化任何信号。需要"最新状态"的场景一律用 Pinia store reactive state。


3. 错误码体系

状态:✅ B1 草稿完成(2026-05-27)

3.1 区间分配总表

区间 归属 用途
1000-1999 shell Shell 容器层错误(slot / stage 注册 / 顶栏)
2000-2999 stage 通用 Stage 生命周期 / 状态机通用错误
3000-3999 xilink XiLink stage 错误(模块 / 链路 / 工作区)
4000-4999 xitune XiTune stage 错误(参数 / preset / profile)
5000-5999 xiforge XiForge stage 错误(widget / module-uid / codegen)
6000-6999 xitest XiTest stage 错误(测试用例 / runner / 断言)
7000-7999 engine / mode-switcher 音频引擎 + 模式切换错误
8000-8999 preset / profile Preset / Profile CRUD 错误
9000-9999 event-bus / 通用 EventBus 协议层 + 兜底通用错误

3.2 TypeScript ErrorCode 枚举

// frontend_vue3/src/types/protocol.ts — ErrorCode
// 同步到 §3(权威源在此文件)

export enum ErrorCode {
  // ──────────────── 1000-1999 · Shell ────────────────

  /** Shell slot 未注册或不存在 */
  SHELL_SLOT_NOT_FOUND         = 1001,
  /** Stage 未在 Shell 注册 */
  SHELL_STAGE_NOT_REGISTERED   = 1002,
  /** Toolbar 按钮 id 不存在 */
  SHELL_TOOLBAR_BTN_NOT_FOUND  = 1003,
  /** ModeChip key 不存在 */
  SHELL_MODE_NOT_FOUND         = 1004,
  /** DocTab key 不存在 */
  SHELL_DOC_TAB_NOT_FOUND      = 1005,
  /** Dock pane key 重复 */
  SHELL_DOCK_PANE_DUPLICATE    = 1006,

  // ──────────────── 2000-2999 · Stage 通用 ────────────────

  /** Stage 尚未初始化完成(setReady 未触发) */
  STAGE_NOT_READY              = 2001,
  /** 目标 stage key 不存在 */
  STAGE_NOT_FOUND              = 2002,
  /** Stage 初始化失败 */
  STAGE_INIT_FAILED            = 2003,
  /** Stage 已处于目标状态(无需切换) */
  STAGE_ALREADY_ACTIVE         = 2004,
  /** Stage 切换被当前操作阻塞 */
  STAGE_TRANSITION_BLOCKED     = 2005,

  // ──────────────── 3000-3999 · XiLink ────────────────

  /** 模块 instanceId 不存在 */
  XILINK_MODULE_NOT_FOUND      = 3001,
  /** 尝试添加已存在的节点 */
  XILINK_NODE_DUPLICATE        = 3002,
  /** Edge 端口类型不匹配 */
  XILINK_EDGE_INVALID          = 3003,
  /** 链路包含环路 */
  XILINK_CHAIN_CIRCULAR        = 3004,
  /** Workspace 文件加载失败 */
  XILINK_WORKSPACE_LOAD_FAILED = 3005,
  /** 模块定义 JSON 不合法 */
  XILINK_MODULE_DEF_INVALID    = 3006,

  // ──────────────── 4000-4999 · XiTune ────────────────

  /** 参数值超出范围 */
  XITUNE_PARAM_OUT_OF_RANGE    = 4001,
  /** Preset id 不存在 */
  XITUNE_PRESET_NOT_FOUND      = 4002,
  /** 目标模块 DSP 未 ready */
  XITUNE_MODULE_NOT_READY      = 4003,
  /** Profile 文件加载失败 */
  XITUNE_PROFILE_LOAD_FAILED   = 4004,
  /** 参数 id 不存在于当前模块 */
  XITUNE_PARAM_NOT_FOUND       = 4005,

  // ──────────────── 5000-5999 · XiForge ────────────────

  /** Widget 类型未在注册表中 */
  XIFORGE_WIDGET_NOT_REGISTERED = 5001,
  /** ModuleDef 结构不合法 */
  XIFORGE_MODULE_DEF_INVALID    = 5002,
  /** codegen 失败(推迟到下季度,预留码) */
  XIFORGE_CODEGEN_FAILED        = 5003,
  /** Module UID 与已有模块冲突 */
  XIFORGE_UID_CONFLICT          = 5004,
  /** Module UID 超出 xistudio 段位范围 */
  XIFORGE_UID_OUT_OF_RANGE      = 5005,

  // ──────────────── 6000-6999 · XiTest ────────────────

  /** 测试用例 id 不存在 */
  XITEST_CASE_NOT_FOUND         = 6001,
  /** 测试 runner 正忙,无法并行 */
  XITEST_RUNNER_BUSY            = 6002,
  /** 断言失败 */
  XITEST_ASSERTION_FAILED       = 6003,
  /** 测试超时 */
  XITEST_TIMEOUT                = 6004,

  // ──────────────── 7000-7999 · Engine / Mode-Switcher ────────────────

  /** 音频引擎启动失败 */
  ENGINE_START_FAILED           = 7001,
  /** 音频引擎停止失败 */
  ENGINE_STOP_FAILED            = 7002,
  /** 操作要求引擎处于 ready 状态 */
  ENGINE_NOT_READY              = 7003,
  /** 模式切换失败(当前模式不允许切换) */
  MODE_TRANSITION_FAILED        = 7004,
  /** 目标模式未授权(license) */
  MODE_NOT_ALLOWED              = 7005,
  /** 引擎重启超时 */
  ENGINE_RESTART_TIMEOUT        = 7006,

  // ──────────────── 8000-8999 · Preset / Profile ────────────────

  /** Preset id 不存在 */
  PRESET_NOT_FOUND              = 8001,
  /** Preset 写入失败 */
  PRESET_SAVE_FAILED            = 8002,
  /** Preset 读取失败 */
  PRESET_LOAD_FAILED            = 8003,
  /** Preset schema 版本不匹配 */
  PRESET_SCHEMA_MISMATCH        = 8004,
  /** Preset 名称重复 */
  PRESET_NAME_DUPLICATE         = 8005,

  // ──────────────── 9000-9999 · EventBus / 通用 ────────────────

  /** EventBus 收到未知 signal 类型 */
  BUS_EVENT_UNKNOWN             = 9001,
  /** EventBus handler 未注册 */
  BUS_HANDLER_MISSING           = 9002,
  /** payload 类型不符合协议契约 */
  BUS_PAYLOAD_INVALID           = 9003,
  /** 兜底:未分类错误 */
  UNKNOWN_ERROR                 = 9999,
}

// 错误码对应的 message 快查表
export const ErrorMessage: Record<ErrorCode, string> = {
  [ErrorCode.SHELL_SLOT_NOT_FOUND]:          'Shell slot not found',
  [ErrorCode.SHELL_STAGE_NOT_REGISTERED]:    'Stage not registered in shell',
  [ErrorCode.SHELL_TOOLBAR_BTN_NOT_FOUND]:   'Toolbar button id not found',
  [ErrorCode.SHELL_MODE_NOT_FOUND]:          'Mode chip key not found',
  [ErrorCode.SHELL_DOC_TAB_NOT_FOUND]:       'Doc tab key not found',
  [ErrorCode.SHELL_DOCK_PANE_DUPLICATE]:     'Dock pane key already exists',

  [ErrorCode.STAGE_NOT_READY]:               'Stage is not ready yet',
  [ErrorCode.STAGE_NOT_FOUND]:               'Stage key does not exist',
  [ErrorCode.STAGE_INIT_FAILED]:             'Stage initialization failed',
  [ErrorCode.STAGE_ALREADY_ACTIVE]:          'Stage is already in the target state',
  [ErrorCode.STAGE_TRANSITION_BLOCKED]:      'Stage transition is blocked',

  [ErrorCode.XILINK_MODULE_NOT_FOUND]:       'Module instanceId not found',
  [ErrorCode.XILINK_NODE_DUPLICATE]:         'Node already exists',
  [ErrorCode.XILINK_EDGE_INVALID]:           'Edge port type mismatch',
  [ErrorCode.XILINK_CHAIN_CIRCULAR]:         'Chain contains a cycle',
  [ErrorCode.XILINK_WORKSPACE_LOAD_FAILED]:  'Workspace file load failed',
  [ErrorCode.XILINK_MODULE_DEF_INVALID]:     'Module definition JSON is invalid',

  [ErrorCode.XITUNE_PARAM_OUT_OF_RANGE]:     'Parameter value out of range',
  [ErrorCode.XITUNE_PRESET_NOT_FOUND]:       'Preset not found',
  [ErrorCode.XITUNE_MODULE_NOT_READY]:       'Module DSP not ready',
  [ErrorCode.XITUNE_PROFILE_LOAD_FAILED]:    'Profile load failed',
  [ErrorCode.XITUNE_PARAM_NOT_FOUND]:        'Parameter id not found',

  [ErrorCode.XIFORGE_WIDGET_NOT_REGISTERED]: 'Widget type not registered',
  [ErrorCode.XIFORGE_MODULE_DEF_INVALID]:    'ModuleDef structure invalid',
  [ErrorCode.XIFORGE_CODEGEN_FAILED]:        'Code generation failed',
  [ErrorCode.XIFORGE_UID_CONFLICT]:          'Module UID conflicts with existing module',
  [ErrorCode.XIFORGE_UID_OUT_OF_RANGE]:      'Module UID out of xistudio range',

  [ErrorCode.XITEST_CASE_NOT_FOUND]:         'Test case not found',
  [ErrorCode.XITEST_RUNNER_BUSY]:            'Test runner is busy',
  [ErrorCode.XITEST_ASSERTION_FAILED]:       'Test assertion failed',
  [ErrorCode.XITEST_TIMEOUT]:                'Test timed out',

  [ErrorCode.ENGINE_START_FAILED]:           'Engine start failed',
  [ErrorCode.ENGINE_STOP_FAILED]:            'Engine stop failed',
  [ErrorCode.ENGINE_NOT_READY]:              'Engine is not ready',
  [ErrorCode.MODE_TRANSITION_FAILED]:        'Mode transition failed',
  [ErrorCode.MODE_NOT_ALLOWED]:              'Mode not allowed (check license)',
  [ErrorCode.ENGINE_RESTART_TIMEOUT]:        'Engine restart timed out',

  [ErrorCode.PRESET_NOT_FOUND]:              'Preset not found',
  [ErrorCode.PRESET_SAVE_FAILED]:            'Preset save failed',
  [ErrorCode.PRESET_LOAD_FAILED]:            'Preset load failed',
  [ErrorCode.PRESET_SCHEMA_MISMATCH]:        'Preset schema version mismatch',
  [ErrorCode.PRESET_NAME_DUPLICATE]:         'Preset name already exists',

  [ErrorCode.BUS_EVENT_UNKNOWN]:             'Unknown EventBus signal',
  [ErrorCode.BUS_HANDLER_MISSING]:           'EventBus handler not registered',
  [ErrorCode.BUS_PAYLOAD_INVALID]:           'EventBus payload does not match contract',
  [ErrorCode.UNKNOWN_ERROR]:                 'Unknown error',
}

// 辅助:创建协议错误对象
export function createProtocolError(code: ErrorCode, detail?: string): Error {
  const msg = ErrorMessage[code] ?? 'Unknown error'
  return new Error(`[${code}] ${msg}${detail ? ': ' + detail : ''}`)
}

3.3 错误上报约定

  • 上报字段{ code: ErrorCode, message: string, detail?: string, stage?: StageKey }
  • 上报通道:调用 toast.message.show 信号(type: 'error')向用户展示
  • 日志console.error('[AIOS]', code, detail) — 格式固定,便于 AIOS 日志过滤
  • 不抛出:协议错误不使用 throw,使用 createProtocolError() 创建 Error 对象后上报

4. sourceList 音源管理协议

状态:✅ B2 草稿完成(2026-05-27)

sourceList 协议管理 XiLink 链路中的音频源模块(moduleId 前缀为 source_*_v1)。所有操作均为 WS 消息 + Pinia store action 双格式。

4.1 音源信号类型(10 种)

来源:CLAUDE.md Phase 8 + ADR-AIOS-05

moduleId 类型 TypeNumId 参数
source_sine_v1 tone 0x10080010 frequencyHz / amplitudeDb / phaseDeg
source_sweep_v1 tone 0x10080011 startFrequencyHz / endFrequencyHz / durationSec
source_triangle_v1 tone 0x10080012 symmetry
source_square_v1 tone 0x10080013 dutyCycle
source_saw_v1 tone 0x10080014 direction
source_noise_white_v1 noise 0x10080015
source_noise_pink_v1 noise 0x10080016
source_noise_brown_v1 noise 0x10080017
source_wav_v1 file 0x10080018 filePath(structural 参数)
source_device_v1 device 0x10080019 deviceId(structural 参数)

Structural 参数filePath / deviceId)变更触发 SetLink;其他参数变更触发 SetParam

4.2 WS 消息格式

4.2.1 set_source_signal(切换信号类型)

Request

{
  "type": "set_source_signal",
  "instanceId": "source_sine#0",
  "signalType": "source_sine_v1",
  "params": {
    "frequencyHz": 1000,
    "amplitudeDb": -6.0,
    "phaseDeg": 0
  }
}

Response(set_source_signal_ack)

{
  "type": "set_source_signal_ack",
  "success": true,
  "signalType": "source_sine_v1",
  "restarted": false
}

restarted=true 表示信号类型切换触发了引擎重启(structural 参数变更)。

4.2.2 source_file_play / source_file_stop / source_file_seek

source_file_play

{
  "type": "source_file_play",
  "instanceId": "source_wav#0"
}

source_file_stop

{
  "type": "source_file_stop",
  "instanceId": "source_wav#0"
}

source_file_seek

{
  "type": "source_file_seek",
  "instanceId": "source_wav#0",
  "positionMs": 3000
}

所有 source_file_* 操作无 ack 响应(fire-and-forget)。

4.3 Store Action 命名空间

协议标识符 Pinia Store Action 签名
source.signal.set useSourceStore setSignal(instanceId: string, signalType: SourceSignalType, params?: Record<string, unknown>)
source.file.play useSourceStore filePlay(instanceId: string)
source.file.stop useSourceStore fileStop(instanceId: string)
source.file.seek useSourceStore fileSeek(instanceId: string, positionMs: number)
source.list.get useLinkStore getSourceModules(): SourceModule[]

4.4 TypeScript 接口

// ─── §4 sourceList 类型 ───────────────────────────────────────────────────

/** 10 种音源 moduleId(Phase 8 · schemaVersion: "8.0") */
export type SourceSignalType =
  | 'source_sine_v1'
  | 'source_sweep_v1'
  | 'source_triangle_v1'
  | 'source_square_v1'
  | 'source_saw_v1'
  | 'source_noise_white_v1'
  | 'source_noise_pink_v1'
  | 'source_noise_brown_v1'
  | 'source_wav_v1'
  | 'source_device_v1'

/** 音源类型分类 */
export type SourceCategory = 'tone' | 'noise' | 'file' | 'device'

/** set_source_signal WS 请求 */
export interface SetSourceSignalRequest {
  type:        'set_source_signal'
  instanceId:  string              // 目标模块 instanceId
  signalType:  SourceSignalType    // 目标信号类型
  params?:     Record<string, unknown>  // 信号参数(见 §4.1)
}

/** set_source_signal_ack WS 响应 */
export interface SetSourceSignalAck {
  type:        'set_source_signal_ack'
  success:     boolean
  signalType?: SourceSignalType    // 实际生效的 signalType(success=true 时)
  restarted?:  boolean             // true = structural 变更触发引擎重启
  error?:      string              // success=false 时的错误说明
}

/** source_file_* 控制请求(play/stop/seek 共用字段结构) */
export interface SourceFileControlRequest {
  type:        'source_file_play' | 'source_file_stop' | 'source_file_seek'
  instanceId:  string
  positionMs?: number              // seek 时必填
}

/** 链路中一个音源模块的摘要信息 */
export interface SourceModule {
  instanceId:  string
  moduleId:    SourceSignalType
  category:    SourceCategory
  displayName: string
  params:      Record<string, unknown>
}

状态:✅ B2 草稿完成(2026-05-27)

refresh_link 是 ADR-AIOS-05 §2.1.5 决议的协议,有两种语义(由 mode 字段区分):

  1. load(加载反读):从后端/目标读取当前部署的链路结构 → 填充 linkStore.deployed
  2. verify(校验对账):与 host 当前编辑态链路比较 → 返回 diff 结果

5.1 请求格式

{
  "type": "refresh_link",
  "mode": "load",
  "source": "pc_backend"
}
{
  "type": "refresh_link",
  "mode": "verify",
  "source": "pc_backend",
  "hostLink": { "id": "...", "modules": [...], "connections": [...] }
}
字段 类型 必填 说明
type 'refresh_link' 固定值
mode 'load' \| 'verify' 操作语义
source RefreshLinkSourceWire 反读源(默认 'pc_backend'
hostLink DSPLink verify 必填 host 编辑态链路,供后端对账

📌 v1.0.1 命名统一补丁(2026-05-27 用户拍板): - 正式名'pc_backend'(前端语义层与 WS 协议层统一) - 兼容期:后端旧实现接受 'host',视同 'pc_backend'1 个版本后移除 - RefreshLinkSourceWire 新值:'pc_backend' | 'target_dsp' | 'target_pc' - 'host'@deprecated,仅在兼容期(当前版本)接受

5.2 响应格式(load 和 verify 共用同一 ack type)

load 成功

{
  "type": "refresh_link_ack",
  "mode": "load",
  "success": true,
  "data": {
    "id": "link-uuid",
    "modules": [
      { "instanceId": "gain#0", "moduleId": "channel_gain_v1", "paramValues": { "gainDb#0": "6.0" } }
    ],
    "connections": [
      { "id": "conn-1", "fromModule": "source_sine#0", "fromPort": "out0", "toModule": "gain#0", "toPort": "in0" }
    ]
  }
}

verify 成功

{
  "type": "refresh_link_ack",
  "mode": "verify",
  "success": true,
  "diff": {
    "missingModules": ["limiter#0"],
    "extraModules": [],
    "paramDrift": [
      { "instanceId": "gain#0", "paramId": "gainDb#0", "host": "6.0", "target": "3.0" }
    ],
    "connectionMismatch": []
  }
}

失败

{
  "type": "refresh_link_ack",
  "mode": "load",
  "success": false,
  "code": "LINK_NOT_FOUND",
  "message": "无法从 source=host 读取链路"
}

5.3 错误码

code 触发场景
LINK_NOT_FOUND load · source=host 但 current_link.json 不存在
HOST_LINK_EMPTY verify · host 无链路数据(hostLink 字段为空)
TARGET_LINK_NOT_FOUND load/verify · target 不可达(target 传输层未实现)
UNKNOWN_MODE mode 字段不为 load/verify

5.4 TuningMode 访问限制

TuningMode load 支持 verify 支持 默认 source
pc_simulation ✅(校验 PC backend) 'pc_backend'
target_live ✅(启动时自动) 'target'
legacy_compat ❌(链路装饰性)
auto_inverse ❌(数据流反向)

5.5 TypeScript 接口

注意:完整实现见 frontend_vue3/src/api/refreshLink.ts(已实现)。以下为协议契约快照。

// ─── §5 refresh-link 类型 ────────────────────────────────────────────────

/**
 * WS 协议层的 source 字段值
 * v1.0.1 起 'pc_backend' 为正式名,'host' 为 @deprecated 兼容别名
 */
export type RefreshLinkSourceWire = 'pc_backend' | 'target_dsp' | 'target_pc'

/** @deprecated 兼容期别名,下一版协议升级时移除,使用 'pc_backend' 替代 */
export type RefreshLinkSourceLegacy = 'host'

/** refresh_link WS 请求(与 refreshLink.ts 中 RefreshLinkRequest 对齐) */
export interface RefreshLinkRequestPayload {
  type:      'refresh_link'
  mode:      'load' | 'verify'
  source?:   RefreshLinkSourceWire   // 默认 'host'
  hostLink?: unknown                 // DSPLink · verify 模式必填
}

/** verify 模式的单条参数漂移 */
export interface ParamDriftEntry {
  instanceId: string
  paramId:    string
  host:       string
  target:     string
}

/** verify 模式的单条连接不一致 */
export interface ConnectionMismatchEntry {
  connectionId: string
  reason:       string
}

/** refresh_link diff 结果(verify 模式) */
export interface LinkDiff {
  missingModules:    string[]
  extraModules:      string[]
  paramDrift:        ParamDriftEntry[]
  connectionMismatch: ConnectionMismatchEntry[]
}

/** refresh_link_ack WS 响应(load + verify 共用) */
export interface RefreshLinkAckPayload {
  type:     'refresh_link_ack'
  mode:     'load' | 'verify'
  success:  boolean
  data?:    unknown                  // DSPLink · load 成功时
  diff?:    LinkDiff                 // verify 成功时
  code?:    RefreshLinkErrorWire     // 失败时
  message?: string
}

/** refresh_link 后端错误码 */
export type RefreshLinkErrorWire =
  | 'LINK_NOT_FOUND'
  | 'HOST_LINK_EMPTY'
  | 'TARGET_LINK_NOT_FOUND'
  | 'UNKNOWN_MODE'

6. dsp-interop · P5↔P6 后端 IPC

状态:✅ B2 草稿完成(2026-05-27)

dsp-interop 定义 C# 后端(P5)与 DSP 算法层(P6,DLL 或嵌入式目标板)之间的二进制帧通信协议。前端不直接参与此层,但需要了解 DSP 连接状态和传输参数。

6.1 二进制帧格式(TLV 风格)

[0x55][0xAA] [CMD 1B] [SEQ 2B LE] [LEN 2B LE] [DATA...] [CRC8 1B]
段位 字节数 说明
HEADER 2 魔数:0x55 0xAA(帧起始)
CMD 1 命令类型(见 §6.2)
SEQ 2 序列号(Little-Endian · 用于丢帧检测)
LEN 2 DATA 字节数(LE)
DATA LEN 命令负载(格式见 §6.3)
CRC8 1 CRC-8 校验(覆盖 CMD+SEQ+LEN+DATA)

6.2 CMD 命令表

CMD 用途
CMD_SET_PARAM 0x01 设置单个模块参数
CMD_SET_LINK 0x02 发送完整链路结构(v3/v4 格式)
CMD_PING 0x03 心跳探测(DATA 为空)

6.3 DATA 格式

CMD_SET_PARAM (0x01)

[iidLen 1B][instanceId UTF-8][pidLen 1B][paramId UTF-8][valueType 1B][valueBytes...]
valueType 含义 valueBytes
0x01 float32 4 bytes LE
0x02 int32 4 bytes LE
0x03 bool 1 byte (0/1)
0x04 string UTF-8 raw(LEN - 前缀字节)
[schemaVer 1B][numChannels 2B LE][sampleRate 2B LE][blockSize 2B LE]
[M 2B LE] × M 个 ModuleEntry
[C 2B LE] × C 个 ConnEntry

ModuleEntry(固定 40 字节):

[typeNumId 4B LE][instanceIdHash 4B LE][numInPorts 1B][numOutPorts 1B][memSize 4B LE][reserved 26B]

ConnEntry(8 字节):

[fromMod 1B][fromPort 1B][toMod 1B][toPort 1B][channels 2B LE][sampleRate 2B LE]

CMD_PING (0x03)

DATA 为空(LEN=0)。后端收到 PONG(0x83)视为连通。

6.4 物理传输层(3 种)

传输类型 连接参数 用途
TCP host:port(默认 127.0.0.1:9000 PC 后端 ↔ PC DLL / 仿真器
Serial comPort@baudRate(如 COM3@115200 嵌入式目标板(RS-232/UART)
ADB FIFO Android 设备 adb forward Android DSP 调试通道

DspConnection.IsConnected 可查询当前连接状态。ConnectionType 返回 "tcp" / "serial" / "adb" / "none"

6.5 TX 队列背压策略

  • TX Channel 有界 512 帧(BoundedChannelFullMode.DropOldest
  • 满时丢旧帧(允许丢参数帧;链路帧因体积大更容易触发丢帧,需在上层重试)
  • 调用方非阻塞:DeliverAsync(frame) 立即返回,不等 ACK

6.6 DLL Mock 模式

DynChainInterop.IsDllAvailable = false 时: - DeliverAsync 直接丢弃帧(无实际 DSP 通信) - HandleSetParam 仍更新 paramStore(保证前端状态一致性) - 返回 { success: true } 避免前端报错

6.7 WS 前端通知(DSP 连接状态变更)

后端在 DSP 连接状态变化时,通过广播推送到所有前端客户端:

{
  "type": "dsp_status",
  "connected": true,
  "protocol": "tcp",
  "target": "127.0.0.1:9000"
}

TypeScript 接口

// ─── §6 dsp-interop 类型 ─────────────────────────────────────────────────

/** DSP 物理传输类型 */
export type DspTransportType = 'tcp' | 'serial' | 'adb' | 'none'

/** 后端推送的 DSP 连接状态通知 */
export interface DspStatusPayload {
  type:      'dsp_status'
  connected: boolean
  protocol:  DspTransportType
  target:    string             // "host:port" / "comPort@baud" / "adb" / ""
}

/** P5↔P6 二进制帧命令类型 */
export const enum DspFrameCmd {
  SET_PARAM = 0x01,
  SET_LINK  = 0x02,
  PING      = 0x03,
}

/** DSP 连接配置(前端 store 保存) */
export interface DspConnectionConfig {
  transport:   DspTransportType
  host?:       string   // tcp
  port?:       number   // tcp
  comPort?:    string   // serial
  baudRate?:   number   // serial
  adbSerial?:  string   // adb · 设备序列号
}

7. source-sink-api · P5 音源/录制/设备 API

状态:✅ B3 草稿完成(2026-05-27)

source-sink-api 定义 P5 C# 后端的音频设备、引擎、录制控制接口。与 §4 sourceList 的关系:§4 是链路层(信号类型/参数),§7 是引擎层(设备选择/录制控制)。

7.1 RefreshLinkSource 正式命名

📌 用户拍板(2026-05-27 14:29)'pc_backend' 为正式名,后端旧 'host'@deprecated,兼容期 1 个版本。

语义 正式值 deprecated 别名
PC 后端仿真模式 'pc_backend' 'host'(兼容期接受)
DSP 目标板 'target_dsp'
目标 PC 'target_pc'

7.2 音频设备管理 WS 消息

7.2.1 list_audio_devices / get_audio_devices

请求

{ "type": "list_audio_devices" }

响应(audio_devices_list)

{
  "type": "audio_devices_list",
  "outputs": [
    { "id": "wasapi:{guid}", "name": "扬声器 (Realtek Audio)", "type": "wasapi" }
  ],
  "inputs": [
    { "id": "wasapi:{guid}", "name": "麦克风 (Realtek Audio)", "type": "wasapi" }
  ]
}

7.2.2 set_audio_device

{
  "type": "set_audio_device",
  "deviceId": "wasapi:{guid}",
  "outputType": "wasapi"
}

响应:{ "type": "set_audio_device_ack", "success": true }

7.2.3 start_audio_engine / stop_audio_engine

{ "type": "start_audio_engine", "sampleRate": 48000, "channels": 2, "blockSize": 64 }
{ "type": "stop_audio_engine" }

响应:{ "type": "audio_engine_status", "running": true/false, "error": null|string }

7.3 Sink 录制控制 WS 消息

7.3.1 sink_record_start

{
  "type": "sink_record_start",
  "instanceId": "sink_v1#0",
  "outDir": "./output",
  "fileName": "record_01.wav",
  "channels": [0, 1]
}

7.3.2 sink_record_stop

{
  "type": "sink_record_stop",
  "instanceId": "sink_v1#0"
}

响应(sink_record_ack):

{
  "type": "sink_record_ack",
  "instanceId": "sink_v1#0",
  "wavPath": "./output/record_01.wav",
  "wavUrl": "/output/record_01.wav",
  "sizeBytes": 192044
}

7.4 REST 端点

方法 路径 说明
GET /api/status 后端状态(引擎 running / DSP 连接 / 在线客户端数)
GET /api/link 当前链路 JSON 快照
GET /api/devices TODO:设备列表 REST stub(当前由 WS 提供)

7.5 TypeScript 接口

// ─── §7 source-sink-api 类型 ─────────────────────────────────────────────

/** 音频设备描述 */
export interface AudioDeviceEntry {
  id:   string                 // "wasapi:{guid}" / "asio:{name}"
  name: string
  type: 'wasapi' | 'asio' | 'soft'
}

/** list_audio_devices 响应 */
export interface AudioDevicesListPayload {
  type:    'audio_devices_list'
  outputs: AudioDeviceEntry[]
  inputs:  AudioDeviceEntry[]
}

/** start_audio_engine 请求 */
export interface StartAudioEngineRequest {
  type:        'start_audio_engine'
  sampleRate?: number   // 默认 48000
  channels?:   number   // 默认 2
  blockSize?:  number   // 默认 64
  deviceId?:   string   // 可选,覆盖当前设备
}

/** 后端推送引擎状态变化 */
export interface AudioEngineStatusPayload {
  type:    'audio_engine_status'
  running: boolean
  error?:  string
}

/** sink_record_start 请求 */
export interface SinkRecordStartRequest {
  type:       'sink_record_start'
  instanceId: string
  outDir?:    string      // 默认 './output'
  fileName?:  string      // 默认自动生成时间戳
  channels?:  number[]    // 默认全通道
}

/** sink_record_stop 请求 */
export interface SinkRecordStopRequest {
  type:       'sink_record_stop'
  instanceId: string
}

/** sink_record_ack 响应 */
export interface SinkRecordAckPayload {
  type:       'sink_record_ack'
  instanceId: string
  wavPath:    string
  wavUrl:     string      // 静态文件路径(/output/{file})
  sizeBytes:  number
}

8. test-runner-api · P4-xitest 后端测试协议

状态:✅ B3 草稿完成(2026-05-27)

test-runner-api 定义 P4-xitest 前端与 P5 后端之间的集成测试/E2E 测试调用协议,基于 REST(不走 WS)。

8.1 测试模式覆盖范围

TestMode 触发方式 后端端点
unit 前端本地 /dev-api/test/vitest/run(Vite 插件) 不涉及后端
integration REST → 后端 POST /api/test/run-case
e2e REST → 后端 POST /api/test/run-project
perf stub(TBD)
visual stub(TBD)

8.2 REST 端点详细规范

8.2.1 GET /api/test/list-tests

列出所有可运行的集成测试项目及场景。

响应

{
  "success": true,
  "projects": [
    {
      "folder": "project-A",
      "name": "project-A",
      "scenarios": [
        {
          "file": "default",
          "configFilePath": ".../integrationtest/default.json",
          "config": { "durationSec": 3.0, "sinkCriteria": {} }
        }
      ]
    }
  ]
}

8.2.2 POST /api/test/run-case

运行单个测试用例(integration mode)。

请求

{
  "caseId": "case_001",
  "durationSec": 3.0
}

响应

{
  "success": true,
  "summary": "PASS",
  "caseId": "case_001",
  "projectFolder": "project-A",
  "durationSec": 3.0,
  "sinks": [
    {
      "sinkId": "sink_v1#0",
      "sourceId": "source_sine#0",
      "pass": true,
      "wavPath": "./output/run_case_001_sink_v1_0_1234567890.wav",
      "wavUrl": "/output/run_case_001_sink_v1_0_1234567890.wav",
      "wavSizeBytes": 576044,
      "measuredRmsDb": -6.02,
      "measuredPeakFreqHz": 440.1,
      "criteriaDetails": [
        { "check": "rms_range", "pass": true, "expected": "[-10, -3] dBFS", "measured": "-6.02" },
        { "check": "peak_freq", "pass": true, "expected": "440 ± 5 Hz", "measured": "440.1" }
      ]
    }
  ],
  "timestamp": "2026-05-27T14:00:00Z"
}

8.2.3 POST /api/test/run-project

运行整个项目的集成测试场景(e2e mode)。

请求

{
  "projectFolder": "project-A",
  "scenario": "default",
  "durationSec": 3.0
}

响应格式与 run-case 相同(内部转发至 run-case)。

8.2.4 POST /api/test/report

生成完整测试报告(带 WAV + pysidecar 频域分析)。

请求

{
  "durationSec": 2.0,
  "projectFolder": "project-A"
}

响应(含 RMS + 频响数据):

{
  "success": true,
  "summary": "PASS",
  "wavPath": "./output/report_1234567890.wav",
  "wavUrl": "/output/report_1234567890.wav",
  "wavSizeBytes": 384044,
  "rms": [
    { "channel": 0, "rms_db": -6.02, "peak_db": -3.01, "pass": true },
    { "channel": 1, "rms_db": -6.05, "peak_db": -3.02, "pass": true }
  ],
  "freqResponse": { "freq_hz": [20, 50, ...], "magnitude_db": [-3.0, -3.1, ...] },
  "timestamp": "2026-05-27T14:00:00Z"
}

8.3 TypeScript 接口

// ─── §8 test-runner-api 类型 ─────────────────────────────────────────────

/** GET /api/test/list-tests 响应 */
export interface TestListResponse {
  success:  boolean
  projects: TestProject[]
}

export interface TestProject {
  folder:    string
  name:      string
  scenarios: TestScenario[]
}

export interface TestScenario {
  file:           string
  configFilePath: string
  config:         Record<string, unknown>
}

/** POST /api/test/run-case 请求 */
export interface RunCaseRequest {
  caseId:       string
  durationSec?: number
}

/** POST /api/test/run-project 请求 */
export interface RunProjectRequest {
  projectFolder: string
  scenario?:     string      // 默认 'default'
  durationSec?:  number
}

/** 单个 sink 的测试结果 */
export interface SinkTestResult {
  sinkId:              string
  sourceId?:           string
  pass:                boolean
  wavPath:             string
  wavUrl:              string
  wavSizeBytes:        number
  measuredRmsDb?:      number
  measuredPeakFreqHz?: number
  measuredDurationSec?: number
  criteriaDetails:     CriteriaCheckEntry[]
}

export interface CriteriaCheckEntry {
  check:     string
  pass:      boolean
  expected?: string
  measured?: string
  reason?:   string
}

/** POST /api/test/run-case 响应 */
export interface RunCaseResponse {
  success:       boolean
  summary:       'PASS' | 'FAIL'
  caseId:        string
  projectFolder?: string
  durationSec:   number
  sinks:         SinkTestResult[]
  timestamp:     string
  log?:          string
  dspLog?:       string[]
}

/** POST /api/test/report 请求 */
export interface RunReportRequest {
  durationSec?:    number
  projectFolder?:  string
}

9. py-subprocess · P7-pysidecar 子进程协议

状态:✅ B3 草稿完成(2026-05-27)

py-subprocess 定义 P5 C# 后端与 P7 Python pysidecar 之间的进程管理 + HTTP 通信协议。pysidecar 以 FastAPI 进程形式运行,监听 http://localhost:8001,P5 通过 HTTP 调用其分析接口。

9.1 进程生命周期

阶段 机制 说明
spawn P5 启动时自动 Process.Start uvicorn pysidecar.main:app --port 8001
heartbeat P5 每 30s GET /health 返回 {"status":"ok"} 视为存活
restart heartbeat 失败 3 次 → 重启 超时 10s 视为无响应
kill P5 关闭时 Process.Kill 确保端口释放

当前实现:P5 在 Program.cs 启动时 spawn pysidecar;heartbeat 为被动(仅在有分析请求时探活)。kill 已通过进程树管理。

9.2 HTTP 接口规范

基础 URL:http://localhost:8001(可通过 PYSIDECAR_PORT 环境变量覆盖)

9.2.1 GET /health

{ "status": "ok", "version": "1.0.0" }

9.2.2 POST /analyze/rms

请求

{
  "wav_b64": "<base64 WAV>",
  "channel": 0
}

响应

{
  "rms_db": -6.02,
  "peak_db": -3.01,
  "duration_sec": 3.0,
  "pass_": true
}

9.2.3 POST /analyze/freq_response

请求

{
  "output_wav_b64": "<base64 WAV>",
  "input_wav_b64": null,
  "channel": 0,
  "config": {
    "point_freqs": [440.0, 1000.0, 4000.0]
  }
}

响应

{
  "freq_hz": [20.0, 50.0, 100.0, "..."],
  "magnitude_db": [-3.0, -3.1, -2.9, "..."],
  "peak_freq_hz": 440.1,
  "point_magnitudes": {
    "440.0": -6.02,
    "1000.0": -6.15,
    "4000.0": -5.98
  }
}

9.2.4 其他分析接口(摘要)

端点 用途
POST /analyze/thd 谐波失真分析(THD+N)
POST /analyze/octave_band 倍频程频带 SPL
POST /analyze/loudness LUFS / A-加权 SPL
POST /analyze/phase 相位分析 + 相位延迟
POST /analyze/tdoa 到达时间差(GCC-PHAT)
POST /analyze/room_acoustics RT60 / C50 / D50 室内声学
POST /analyze/coherence 输入/输出信号相干性
POST /analyze/waterfall 瀑布图(时频域)
POST /analyze/weighted_spl 加权 SPL(A/C/Z)
POST /analyze/signal_gen 测试信号生成(正弦/扫频/脉冲/白噪声)

9.3 P5→P7 调用约定

  • 传输格式:WAV 文件以 Base64 编码传送(不用文件路径,避免跨进程文件锁)
  • 超时:每次请求 30s(分析大文件时可能接近上限)
  • 并发:P5 串行调用,不并发(pysidecar 无全局锁,可并发,但 P5 端顺序发送)
  • 降级:pysidecar 不可达时,后端返回 { success: true, rms: [], freqResponse: null } — 测试仍执行,仅缺少频域指标

9.4 TypeScript 接口

// ─── §9 py-subprocess 类型 ───────────────────────────────────────────────

/** GET /health 响应 */
export interface PySidecarHealthPayload {
  status:  'ok' | 'error'
  version: string
}

/** POST /analyze/rms 请求 */
export interface RmsAnalysisRequest {
  wav_b64: string     // Base64 WAV
  channel: number
}

/** POST /analyze/rms 响应 */
export interface RmsAnalysisResult {
  rms_db:      number
  peak_db:     number
  duration_sec: number
  pass_:       boolean
}

/** POST /analyze/freq_response 请求 */
export interface FreqResponseRequest {
  output_wav_b64: string
  input_wav_b64?: string | null
  channel:        number
  config?: {
    point_freqs?: number[]   // 需要精确测量的频率点
  }
}

/** POST /analyze/freq_response 响应 */
export interface FreqResponseResult {
  freq_hz:          number[]
  magnitude_db:     number[]
  peak_freq_hz:     number
  point_magnitudes: Record<string, number>   // "440.0" → -6.02 dB
}

/** 后端 WS 推送的 pysidecar 状态通知 */
export interface PySidecarStatusPayload {
  type:     'pysidecar_status'
  running:  boolean
  port:     number
  error?:   string
}

10. 变更管理

10.1 freeze 后的变更流程

  1. 任一 agent 提出变更 → 在 KANBAN 标 CONTRACT-CHANGE-REQ: §X
  2. AIOS 评估影响 → 升级人类
  3. 人类拍板 → 写 ADR-AIOS-NN
  4. ClaudeB 改本文档 + bump version 到 v1.1 / v2.0
  5. Continue 打新 tag contract-v1.1.0

10.2 版本号语义

  • patch(v1.0.x):错别字 / examples 补充 · 不影响实施
  • minor(v1.x.0):新增协议 · 向后兼容
  • major(vX.0.0):破坏性变更 · 触发回滚或迁移计划

11. 关联文档


12. 演进历史

版本 日期 状态 责任人 变化
v0.1-skeleton 2026-05-19 pending-claude-a AIOS(占位) 12 章节骨架建立
v0.6-§1-§6-draft 2026-05-27 draft-b2 ClaudeB §1-§6 草稿填充(B1+B2)
v0.9-§1-§9-draft 2026-05-27 draft-b3 ClaudeB §7-§9 草稿填充 + §5 RefreshLinkSource 命名统一(B3)
v1.0 2026-05-27 frozen ClaudeB 全文首版 · freeze · tag contract-v1.0 · HARD-DEADLINE B4

📌 再次提醒:本文件 freeze 前任何具体内容均为占位。智能体在 Day 1-4 实施任务时,不要引用本文件,而是引用 baseline-alignment.md