Skip to content

[Feature] 引入 Cordis 插件运行时,并以语义差分迁移现有能力 #394

Description

@kachofugetsu09

想解决什么问题

Akashic 的插件系统最初服务于 Agent 自举:插件不仅扩展能力,还要经过候选安装、真实 child turn 验证、generation 绑定和稳定版本晋升。因此,它比普通 hook 系统更安全,但当前扩展接口正在变重:

  • PluginBasePluginContributions 和固定 lifecycle 把工具、Prompt、Memory、主动流程、调度、UI、MCP 与交付能力压进一组预定义挂载点。
  • 新能力常需要修改 Core 的接口、phase 或管理器;插件依赖和执行顺序容易退化为名字、权重或约定,而不是可解析的服务依赖。
  • after_reasoning 等粗粒度 lifecycle 同时承担数据传递、控制流、状态写入和副作用,难以独立组合、并行、替换和回收。
  • Default Memory 与 Akasha、不同 proactive 实现、Wake/Scheduler 等能力的互斥或组合关系缺少统一且 fail-loud 的表达。
  • Dashboard/Mobile UI 已有插件贡献,但 Host、Client、RPC、slot、generation 与回退仍是分散的专用协议。
  • 当前安全语义很强,却缺少一套能证明“大规模运行时重构前后效果一致”的通用差分收据。

目标不是把现有 lifecycle 改名,也不是给每个 hook 增加 priority 数字,而是引入 DeepSeek Harness 使用的 Cordis 思想:用 Context、Service、Fiber、effect/disposer 和显式依赖组成能力,让 ReAct 主循环保持极薄,同时保留 Akashic 独有的递归自验证与稳定晋升。

参考:

  • DeepSeek Harness
  • Cordis paper
  • Akashic 当前 docs/decisions/0024-plugin-self-validation-uses-stable-and-latest.md
  • Akashic 当前 docs/decisions/0026-plugin-rollout-is-owned-by-the-parent-turn.md

希望得到什么结果

1. 目标运行时

┌───────────────────────────────────────────────────────────────┐
│ Cordis Host                                                   │
│                                                               │
│ Session → Turn → Step → model request → tool result → Step … │
│                    极薄 ReAct 控制循环                         │
└──────────────┬────────────────────────────────────────────────┘
               │ Context / Service / Event / Slot
       ┌───────┼──────────────┬──────────────┬──────────────┐
       ▼       ▼              ▼              ▼              ▼
    Prompt   Tools       Memory Provider   Flow Driver   Host/Client UI
                         default/Akasha    passive/wake   RPC + typed slots
                                          proactive/job
  • AgentLoop 只拥有 Step 循环、模型调用、工具结果回灌和终止判断,不包含插件特判。
  • 每项能力按 Service Definition / Provider / Consumer 拆分;插件通过依赖声明获得能力,而不是依赖全局 manager 或任意权重。
  • 所有注册都是可释放 effect;Fiber 停止时,listener、tool、slot、process、timer、MCP、route 和 UI contribution 必须递归卸载。
  • 顺序由数据依赖表达。只有确实需要 waterfall 的同一扩展点才允许链式 listener;必须显式调用 next()。并行任务使用明确的并发组合器和取消/失败规则,不由两个作者各写一个 priority 数字决定。
  • 模型可见内容必须进入 Session log;任意模型请求都能重建当时的 system prompt、messages、tool schema、generation 与 capability set。
  • “七个 lifecycle”不作为新内核。现有 lifecycle 逐项翻译成更小的 capability、事件、投影或 flow driver;无法证明拥有独立事实的 hook 删除。

2. 保留并收紧自验证与晋升

Cordis 负责运行时装配和卸载;Akashic 保留持久化的 PluginRollout 服务:

artifact
   │
   ▼
candidate Fiber ── load/readiness ──► child turn + frozen ValidationPlan
   │                                      │
   │ fail                                 │ domain oracle + receipts pass
   ▼                                      ▼
dispose + discard                   validated candidate
                                           │
                         next Step scoped overlay(仅安全能力)
                                           │
                         parent terminal success
                                           ▼
                                  atomic stable promotion
  • stablecandidate、artifact digest、generation lease、journal、验证收据与 promotion policy 仍由 Akashic 的持久 owner 管理,不修改 vendored Cordis 核心来承载产品状态。
  • 验证计划在 candidate 执行前冻结;candidate 可以建议测试,但不能定义自己的通过标准。
  • ValidationReceipt 至少绑定 artifact digest、generation、plan digest、child session/turn、tool trace、允许 write set、领域状态和外部副作用。
  • 导入失败、配置错误、依赖缺失、readiness 失败或验证失败均 fail-loud,旧 stable Fiber 与指针保持不变。
  • 提议把状态拆成 validated → adopted → promoted
    • child/domain oracle 通过后,当前 owner turn 可在下一个 Step获得 candidate-only scoped overlay;
    • 同一 Step 内的模型重试继续使用冻结装配,不热切换;
    • 只有 parent terminal success 后才修改全局 stable;
    • parent 后续失败时释放 overlay 并丢弃 candidate。
  • 第一阶段 scoped overlay 只允许加法、无状态且可回收的 tool、skill、只读 MCP consumer 或安全 Prompt section。Memory provider、调度器、channel、数据库迁移、listener/proactive 与独占 endpoint 不允许当轮采用。
  • 上述“当轮后半段采用”是对当前“parent 全程只见 S0”语义的有意变化,必须先写决策记录;未批准前保持现状。

3. 明确互斥、依赖和主动流程

  • Default Memory 与 Akasha 实现同一个 typed MemoryProvider 服务。配置必须明确选择一个;重复 provider 在加载时失败。若以后允许组合,必须由单独的 CompositeMemoryProvider 明确拥有排序、去重、预算和 provenance,不能隐式同时运行。
  • Citation/Meme 作为首批真实迁移样本:用 capability 依赖、必需服务和显式 waterfall 表达“谁生产事实、谁消费事实、谁先谁后”,禁止依靠相同权重下的偶然注册顺序。
  • Passive、Wake、Default Proactive、其他 Proactive、Scheduler/Job 不复制 ReAct:
    • 它们作为 FlowDriver 创建无用户输入的 Turn;
    • 每个 driver 选择自己的 prompt profile、tool capability set、预算、delivery policy 与 terminal policy;
    • 共用同一个薄 ReAct engine,但不强行复用被动链路的 Prompt 和工具组。
  • Scheduler 只负责触发与持久 job;Proactive/Wake 负责为何运行和构造输入;Delivery 负责是否以及向哪里发送。三者不得互相取得状态所有权。

4. UI 也进入同一插件模型

一个插件可同时包含两个相互绑定的 Fiber:

Host Fiber                              Client Fiber
remote/query/projection/permission ─RPC─ React component/store/theme/slot
                  └──── 同一 generation + digest 原子发布 ────┘
  • Dashboard 和 Mobile UI 迁移成稳定语义 slot,而不是任意 DOM 注入。
  • Host 拥有 SessionDB、Memory、plugin data、credentials、schedule 与业务写入;Client 只保存临时视图状态,通过 typed RPC 读取投影。
  • candidate UI 先在隔离/preview realm 加载、渲染和验证;Host/Client digest 一起晋升。加载失败保留旧 UI,不接受无 rollback 的直接 HMR 作为发布机制。
  • 保留现有 generation binding、catalog revision、content hash、stale rejection、snapshot lease、timeout 和容量控制。

5. 用语义差分证明迁移一致

先建立独立于新旧实现的 SemanticReceipt,再迁移生产插件。相同固定输入与固定模型 replay 分别运行在一次性 old/new workspace:

fixed input/model replay
          │
     ┌────┴────┐
     ▼         ▼
 old runtime  Cordis runtime
     │         │
     └────┬────┘
          ▼
 normalized SemanticReceipt diff

收据至少比较:

  • model:system prompt、messages、tool schemas、请求次数和可见 generation;
  • session:Turn/Step/event 顺序、terminal messages 与错误分类;
  • tool:调用、结果、异常与 owner;
  • state:DB/file/memory write set、保留与删除;
  • effects:process、listener、MCP、outbox、delivery 和外部调用;
  • rollout:stable/candidate pointer、lease、journal、validation receipt;
  • UI:bundle/slot/RPC/interactions、视觉快照和 accessibility。

只归一化 timestamp、UUID、临时端口、PID 与性能抖动;不得归一化 Prompt、tool schema、Turn 顺序、错误分类、Memory 写入、外部发送、generation identity 或 UI 行为。

判定由三部分共同决定:

  1. projectneed.md/决策中的显式不变量;
  2. old runtime 的真实收据;
  3. 经维护者批准的 intentional delta。

旧实现不是唯一真理;发现旧 bug 时先单独修改规格或修复,再继续等价迁移。

迁移顺序

  • Phase 0:建立插件语义账本、全部已安装/公开插件能力矩阵、SemanticReceipt schema 和 old/new differential Gate。
  • Phase 1:引入最小 Cordis Host,跑通 Session → Turn → Step 的极薄 ReAct spine,不迁移生产能力。
  • Phase 2:实现 PluginRollout、candidate Fiber、ValidationPlan/Receipt、lease、失败恢复和 atomic swap。
  • Phase 3:迁移 Citation/Meme,验证服务依赖、链式顺序、并行和 disposer。
  • Phase 4:迁移低风险 tools/skills/MCP 与 self-install;证明插件可以给自己编写、安装、验证和晋升能力。
  • Phase 5:迁移 Dashboard/Mobile Client Fiber、typed RPC 和 UI preview/rollback。
  • Phase 6:迁移 Default Memory/Akasha,并验证互斥、provenance、预算与持久化等价。
  • Phase 7:迁移 Passive/Wake/Proactive/Scheduler/Delivery,并验证无用户输入 Turn、重启恢复和外部发送 exactly-once/at-most-once 语义。
  • Phase 8:迁移其余已安装插件,完成 full Gate 后删除旧 plugin manager/lifecycle;不保留双运行时兼容壳。

每个 Phase 拆成可独立评审的 PR;一个 PR 只改变一组高风险语义。预计是月级平台工程,而不是单个大 PR。

验收标准

  • 真实 Citation/Meme 在缺依赖、重复 provider、错误顺序和卸载后调用时均 fail-loud。
  • Default Memory 与 Akasha 各自通过同一 consumer 套件;未配置选择或重复选择时拒绝启动。
  • Passive、Wake、两种 Proactive 和 Scheduler 使用同一 ReAct engine,但产生各自正确的 prompt/tools/budget/delivery 收据。
  • candidate 写崩、超时、进程崩溃、teardown 失败、pointer 提交前崩溃、UI 加载失败时,stable 能继续服务且 degraded/failure 可观察。
  • 正常安装在下一个 Turn 生效;获准的安全 scoped overlay 在验证完成后的下一个 Step 生效,同一 Step 重试不变。
  • 每项模型可见变化都有 Session event;可从 log 重建任意 Step 的模型请求。
  • 全部现有插件逐项有 old/new SemanticReceipt,未批准差异为零。
  • 结构测试、真实插件 Gate、双运行时差分、故障注入、keyless assembled snapshot 与必要的 real-runtime 验收全部通过。
  • 最终删除旧 manager、固定 lifecycle 和迁移期桥接层;没有两个并存的权威 runtime。

不包含什么

  • 不在一个 PR 中整体重写并直接切换正式 workspace。
  • 不把 Cordis vendored core 改造成 Akashic 状态数据库。
  • 不允许插件自报“行为正确”后直接晋升。
  • 不以随机 priority/weight 作为跨作者依赖的主要机制。
  • 不用 Node sidecar 为每个 hook 做长期 RPC;若迁移期存在 Python provider,必须有明确退出阶段。
  • 不在迁移中顺带改变 SessionDB、Memory 保留范围、主动发送、移动协议或凭据安全语义。
  • 不为了让 Gate 变绿而同时降低 oracle、修改 baseline 或吞掉失败。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions