跳转至

会话适配器契约

本文档定义了 ecc.session.v1 的规范 ECC 会话快照契约。

该契约实现在 scripts/lib/session-adapters/canonical-session.js 中。本文档是适配器和消费者的 规范性规范。

目的

ECC 有多个会话来源:

  • tmux 编排的工作树会话
  • Claude 本地会话历史
  • 未来的执行框架和控制平面后端

适配器将这些来源规范化为一种对控制平面安全的快照结构,以便检查、持久化和未来的 UI 层不依赖于特定执行框架的文件或运行时细节。

规范快照

每个适配器必须返回一个可 JSON 序列化的对象,并具有此顶层结构:

{
  "schemaVersion": "ecc.session.v1",
  "adapterId": "dmux-tmux",
  "session": {
    "id": "workflow-visual-proof",
    "kind": "orchestrated",
    "state": "active",
    "repoRoot": "/tmp/repo",
    "sourceTarget": {
      "type": "session",
      "value": "workflow-visual-proof"
    }
  },
  "workers": [
    {
      "id": "seed-check",
      "label": "seed-check",
      "state": "running",
      "health": "healthy",
      "branch": "feature/seed-check",
      "worktree": "/tmp/worktree",
      "runtime": {
        "kind": "tmux-pane",
        "command": "codex",
        "pid": 1234,
        "active": false,
        "dead": false
      },
      "intent": {
        "objective": "Inspect seeded files.",
        "seedPaths": ["scripts/orchestrate-worktrees.js"]
      },
      "outputs": {
        "summary": [],
        "validation": [],
        "remainingRisks": []
      },
      "artifacts": {
        "statusFile": "/tmp/status.md",
        "taskFile": "/tmp/task.md",
        "handoffFile": "/tmp/handoff.md"
      }
    }
  ],
  "aggregates": {
    "workerCount": 1,
    "states": {
      "running": 1
    },
    "healths": {
      "healthy": 1
    }
  }
}

必需字段

顶层

字段 类型 说明
schemaVersion string 对于此契约,必须恰好为 ecc.session.v1
adapterId string 稳定的适配器标识符,例如 dmux-tmux 或 claude-history
session object 规范会话元数据
workers array 规范工作器记录;可以为空
aggregates object 派生的工作器计数

session

字段 类型 说明
id string 适配器域内的稳定标识符
kind string 高层会话类别,例如 orchestrated 或 history
state string 规范会话状态
sourceTarget object 打开该会话的目标的来源信息

session.sourceTarget

字段 类型 说明
type string 查找类别,例如 plan、session、claude-history、claude-alias 或 session-file
value string 原始目标值或解析后的路径

workers[]

字段 类型 说明
id string 适配器作用域内的稳定工作器标识符
label string 面向操作者的标签
state string 规范工作器状态(生命周期)
health string 规范工作器健康状态(运行状况)
runtime object 执行/运行时元数据
intent object 该工作器/会话存在的原因
outputs object 结构化结果和检查
artifacts object 适配器拥有的文件/路径引用

workers[].runtime

字段 类型 说明
kind string 运行时类别,例如 tmux-pane 或 claude-session
active boolean 运行时当前是否处于活动状态
dead boolean 运行时是否已知死亡/结束

workers[].intent

字段 类型 说明
objective string 主要目标或标题
seedPaths string[] 与工作器/会话关联的种子或上下文路径

workers[].outputs

字段 类型 说明
summary string[] 已完成的输出或摘要项
validation string[] 验证证据或检查
remainingRisks string[] 未解决的风险、后续事项或备注

aggregates

字段 类型 说明
workerCount integer 必须等于 workers.length
states object 从 workers[].state 派生的计数映射
healths object 从 workers[].health 派生的计数映射

可选字段

可选字段可以省略,但如果输出,则必须保持文档中记录的类型:

字段 类型 说明
session.repoRoot string \| null 已知时的仓库/工作树根目录
workers[].branch string \| null 已知时的分支名称
workers[].worktree string \| null 已知时的工作树路径
workers[].runtime.command string \| null 已知时的活动命令
workers[].runtime.pid number \| null 已知时的进程 id
workers[].artifacts.* 适配器定义 适配器拥有的文件路径或结构化引用

适配器特定的可选字段应位于 runtime、artifacts 或其他已记录的嵌套对象内。适配器不得在未更新此契约的情况下发明新的顶层字段。

状态语义

该契约有意保持 session.state 和 workers[].state 足够灵活,以支持多个执行框架,但当前适配器使用以下值:

  • dmux-tmux
  • 会话状态:active、completed、failed、idle、missing
  • 工作器状态:从工作器状态文件派生,例如 running 或 completed
  • claude-history
  • 会话状态:recorded
  • 工作器状态:recorded

消费者必须将未知的状态字符串视为有效的适配器特定值,并优雅降级。

版本策略

schemaVersion 是唯一的兼容性门控。消费者必须基于它进行分支处理。

允许在 ecc.session.v1 中

  • 添加新的可选嵌套字段
  • 添加新的适配器 id
  • 添加新的状态字符串值
  • 添加新的健康字符串值
  • 在 workers[].artifacts 内添加新的工件键

需要新的 schema 版本

  • 移除必填字段
  • 重命名字段
  • 更改字段类型
  • 以不兼容的方式更改现有字段的含义
  • 在保持相同版本字符串的同时,将数据从一个字段移动到另一个字段

如果发生上述任何情况,生产者必须发出新的版本字符串,例如 ecc.session.v2。

适配器合规要求

每个 ECC 会话适配器必须:

  1. 精确发出 schemaVersion: "ecc.session.v1"。
  2. 返回满足所有必填字段和类型的快照。
  3. 对未知的可选标量值使用 null,对未知的列表值使用空数组。
  4. 将适配器特定的详细信息嵌套在 runtime、artifacts 或其他已记录的嵌套对象下。
  5. 确保 aggregates.workerCount === workers.length。
  6. 确保 aggregates.states 与发出的 worker 状态匹配。
  7. 确保 aggregates.healths 与发出的 worker 健康值匹配。
  8. 仅生成可 JSON 序列化的普通值。
  9. 在持久化或下游使用前验证规范结构。
  10. 通过会话记录垫片持久化规范化后的规范快照。 在本仓库中,该垫片会先尝试 scripts/lib/state-store,并且仅在状态存储模块尚不可用时,才回退到 JSON 记录文件。

消费者预期

消费者应当:

  • 仅依赖 ecc.session.v1 的已记录字段
  • 忽略未知的可选字段
  • 将 adapterId、session.kind 和 runtime.kind 视为路由提示,而不是穷举枚举
  • 预期在 workers[].artifacts 内存在适配器特定的产物键

消费者不得:

  • 从未记录字段推断测试框架特定行为
  • 假设所有适配器都有 tmux 窗格、git 工作树或 Markdown 协调文件
  • 仅因为状态字符串不熟悉就拒绝快照

当前适配器映射

dmux-tmux

  • 来源:scripts/lib/orchestration-session.js
  • 会话 ID:编排会话名称
  • 会话类型:orchestrated
  • 会话源目标:计划路径或会话名称
  • worker 运行时类型:tmux-pane
  • 产物:statusFile、taskFile、handoffFile

claude-history

  • 来源:scripts/lib/session-manager.js
  • 会话 ID:存在时使用 Claude 短 ID,否则使用由会话文件名派生的 ID
  • 会话类型:history
  • 会话源目标:显式历史目标、别名或 .tmp 会话文件
  • worker 运行时类型:claude-session
  • 意图种子路径:从 ### Context to Load 解析
  • 产物:sessionFile、context

验证参考

仓库实现会验证:

  • 必填对象结构
  • 必填字符串字段
  • 布尔运行时标志
  • 字符串数组输出和种子路径
  • 聚合计数一致性

适配器应将验证失败视为契约缺陷,而不是用户输入错误。

记录回退行为

JSON 回退记录器是专用状态存储落地前的临时兼容垫片。其行为如下:

  • 最新快照始终就地替换
  • 历史记录仅保存不同的快照主体
  • 未变化的重复读取不会追加重复历史记录

这可防止 session-inspect 和其他轮询式读取针对同一未变化的会话快照产生无界增长的历史记录。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC