DeepSeek Harness 插件

Lumos-789/baton

Star 数 ★ 0 分类 工作流与自动化 收录于 2026-11-02

把已批准的 OpenSpec change 跑到完成,同时让模型只做机械转发:内置本地 MCP 服务计算票据 DAG 前沿、原子认领任务、为每个 assignment 准备独立 git worktree,并返回确定的 actions。会话用 DSH subagent 派发每个 action,完成后按在干净且已前进的 HEAD 上重跑验证命令得到的哈希绑定回执来 reconcile,子代理口头说“做完了”不算成功。运行中改范围就是直接改 tasks.md。需要 PATH 上有 Python 3.10+,且目标项目使用 OpenSpec 的 git 仓库。

安装

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:Lumos-789/baton

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

OpenSpec 变更唯一的 ticket / DAG / 会话子代理控制面。 本地 MCP server 返回确定性的会话动作;主会话用 DSH subagent 工具派发每个任务包、 绑定子代理 id,并依据密封回执(sealed receipt)结算完成通知。

Discussions

解决什么问题

OpenSpec 擅长规格驱动的分解(proposal -> tasks -> archive),但不负责执行。 Baton 把一个已批准的变更确定性地变成完成的工作:主会话从不自行决定 ticket 状态, 而是原样转发 Baton MCP server 返回的确定性 actions 给 DSH 子代理,再把每个完成 通知对照密封回执(任务的验证命令在隔离 worktree 中全绿)结算。子代理的自由文本 输出不被采信。

密封回执是 receipt.py 在本地产生的哈希绑定证据(任务包哈希 + 干净前进的 HEAD + 退出码为 0 的验证结果)。它是完整性证据,不是对抗恶意子代理的密码学证明。

三条接缝由确定性机制桥接:

接缝 Baton 的答案
依赖(按 section 顺序的 DAG -> 下一步跑什么) SessionController.actions() 每次调用重算前沿并原子认领不同任务
并发(<=5 个并行任务) 每个任务一个隔离 git worktree;集成由仓库级锁串行化
状态(子代理结束 -> 任务完成) 密封回执是唯一成功证据;控制器集成分支、落定尝试、回写 tasks.md 的 [x]

Baton 是指挥。SessionController 是唯一确定性调度器;主会话是机械转发器; OpenSpec 是计划面。

安装(DSH)

Baton 是一个 DSH bundle:一个包同时挂载 baton 技能并启动本地 MCP server。 要求 DSH 0.2.1-rc.2 或更新、提供 subagent 工具的 profile(自带的 dsh-base 即可)、PATH 上有 Python 3.10+(或用 BATON_PYTHON 指定)。

# 从 checkout 安装
dsh plugin add /path/to/baton

# 发布后
dsh plugin add dsh-openspec-baton

自检(自包含,只需 python3 + git;通过 stdio 驱动真实 MCP server,健康则退出 0):

python3 tests/mcp_smoke.py

包名用 dsh-openspec-baton 以避开无关的 dsh-baton 插件;仓库名与品牌保持 baton,MCP 命名空间保持 mcp__baton__*。

安装(ZCode,仅本地开发)

同一仓库还带有 ZCode 插件形态(.zcode-plugin/plugin.json,未发布到任何公开 marketplace):挂载同一份 skills/baton/SKILL.md,并以同样的 stdio 方式启动 python3 + mcp-servers/baton-server.py,mcp__baton__* 工具在 ZCode 会话中 行为一致。要求 python3 可达且为 Python 3.10+。

快速开始

在业务项目里按项目自身的 openspec 工作流写一个变更并获批:

openspec/changes/<change-id>/proposal.md + tasks.md   (未勾选的 N.M 任务)

tasks.md 就是 ticket 源:section 是阶段,任务带 N.M 编号,一个任务被它之前 所有 section 的任务阻塞(同一 section 内并行)。最小形态:

# Tasks: add-login

## 1. 后端

- [x] 1.1 token 端点
- [ ] 1.2 会话持久化

## 2. 前端

- [ ] 2.1 登录表单

[x] = 已完成,[ ] = 就绪(没有草稿态);精确解析规则见 docs/ticket-format.md。

然后对会话说:

run baton on <project_path> <change-id>

技能会驱动 actions -> subagent -> bind_agent -> 完成通知 -> reconcile, 直到批次返回 complete。

架构

主会话(机械转发器 — 不做任何模型驱动的状态决策)
  |- mcp__baton__actions(project_path, feature, session_id, capacity<=5)
  |     -> SessionController.actions():恢复/结算密封回执、计算前沿、原子认领、
  |        准备隔离 worktree 与不可变任务包,返回
  |        dispatch/recover/resolve_merge/wait/blocked/complete 动作
  |- subagent(dispatch.prompt, cwd=dispatch.cwd) -> 子代理 id
  |- mcp__baton__bind_agent(assignment_id, claim_token, agent_id)
  |- 运行时送达子代理完成通知
  `- mcp__baton__reconcile(assignment_id, claim_token, agent_terminal, ...)
        -> 密封回执 -> 成功并集成;否则 unknown + recover

SessionController(唯一确定性调度器)
  |- 持久计划存储(.dsh/baton/queue.db):修订、尝试、租约、密封回执、完成事实
  |- 隔离的任务 worktree + 共享集成 worktree
  |- 串行 git 集成;合并冲突保留(从不自动放弃)
  `- 按最新计划判定完成(全部必需 ticket 已验证并集成)

能力

会话子代理执行(唯一路径):

  • 确定性调度 — 认领、租约、worktree、回执验证、集成、完成判定全部脚本化, 模型不决定状态。
  • 隔离 worktree — 每个任务一个分支;容量 <=5 的滑动窗口;集成由仓库级锁串行。
  • 密封回执 — scripts/receipt.py 的 verify / seal 是唯一被采信的成功 证据;没有回执的完成通知把尝试翻成 unknown。

控制面:

  • OpenSpec 原生的认知阶段 — “用 baton 完成 X” 指先跑项目的 OpenSpec 工作流 (对齐 -> 写变更 -> 用户批准),再驱动执行到 complete。
  • 活计划 = 直接改 tasks.md — 运行中增删任务,下一次 actions() 记录新计划 修订并重算前沿;在飞的任务包保持不可变。

可观测性:scripts/ticket_board.py 为项目的 OpenSpec 变更生成纯静态 HTML 看板(零进程、零端口):

python3 scripts/ticket_board.py build-all /path/to/project
# -> .dsh/baton/board-all.html   (所有变更一板)
python3 scripts/ticket_board.py build /path/to/project <change-id>
# -> .dsh/baton/<change-id>/board.html

独立协同内核:scripts/queue.py 不依赖 MCP server、不依赖会话 — 把任意 shell 命令包进资源闸门、提交后台任务、冻结资源、全量审计。状态在一个 SQLite 库 (默认 ~/.baton/coordination/queue.db,--db 可覆盖)。核心是排空屏障 (drain barrier):破坏性命令(迁移、重建索引)与资源上的其他使用者不再竞速 — 新的认领排队,在飞租约跑完,屏障始终会解冻:

python3 scripts/queue.py gate --resource db:prod --reason "schema migration" \
  -- ./migrate.sh

包内容

路径 用途
index.js 挂载内置 skills/ provider 与 stdio MCP server
cordis.patch.yml DSH bundle insert 行(dsh-openspec-baton)
.zcode-plugin/plugin.json ZCode 插件清单(本地开发安装;同一技能 + MCP server)
skills/baton/SKILL.md baton 技能(actions -> subagent -> reconcile)
mcp-servers/baton-server.py 本地 stdio MCP server(mcp__baton__*)
scripts/ 确定性控制器、计划存储、回执、队列 CLI

回归

标准回测入口 — 完整 pytest 套件(含临时 git fixture 的 e2e)、真实 MCP stdio 冒烟、文档/文件一致性检查:

./tests/regression.sh

文档

许可

MIT

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。