Baton: Deterministic Scheduling of Tickets and Subagents for OpenSpec Changes

前言

OpenSpec 擅长把变更拆成 proposal、tasks、archive 等规格步骤,但规格本身不执行。主会话若自行判断「哪张票算完成」,容易与任务清单脱节,子智能体的自由文本输出也难以当作可核验的成功依据。下面介绍 Lumos-789 维护的 DSH 插件 Baton:它把已批准的 OpenSpec 变更转成可执行的 ticket/DAG,用本地 Python CLI 给出确定性动作,主会话只机械转发,成功仅以 sealed receipt 为准。

这是什么

Baton 是覆盖 OpenSpec 变更的 ticket / DAG / session-subagent 控制面。一句话定位:OpenSpec 是计划面,SessionController 是唯一确定性调度器,主会话是指挥棒下的机械转发者。 插件在 SkillHub 分类为工作流;仓库为 Lumos-789/baton,DSH 包名为 dsh-openspec-baton(与无关的 dsh-baton 区分),当前 package 版本为 0.3.0,许可证 MIT。

它解决的核心问题是:把已批准变更 deterministically 跑完——主会话不自行决定 ticket 状态,只按 Baton CLI 返回的 actions 原样交给 DSH subagent,再用 sealed receipt(任务包哈希 + 干净 worktree 上 HEAD 前进 + 验证命令 exit 0)对账完成通知;无 receipt 的完成会记为 unknown 并走 recover。Free-text 子智能体输出不参与成功判定。

核心功能

三条接缝的确定性桥接

接缝 Baton 的做法
依赖(章节顺序 DAG → 下一步跑什么) SessionController.actions() 每次重算 frontier,并原子认领不同任务
并发(最多 5 个并行任务) 每个 assignment 一个隔离 git worktree;集成由仓库级锁串行
状态(子智能体完成 → 任务 resolved) sealed receipt 是唯一成功证据;集成分支、finalize attempt、在 tasks.md 把对应项标为 [x]

Session-subagent 执行(唯一路径)

  • 确定性调度:认领、租约、worktree、receipt 校验、集成、完成均由脚本驱动,模型不决定状态。
  • 隔离 worktree:每个 assignment 一条分支;容量滑动窗口 <=5;集成串行加锁。
  • Sealed receipts:scripts/receipt.py 的 verify / seal 是唯一接受的成功证据(本地完整性证据,非对抗性密码学证明)。

控制面与可观测

  • OpenSpec 原生认知阶段:「用 baton 做完 X」意味着先走项目 OpenSpec 流程(对齐 → 写变更 → 用户批准),再驱动执行至 complete。
  • 活计划 = 编辑 tasks.md:运行中增删任务或章节时,下一次 actions() 记录新 plan revision 并重算 frontier;在途 Task Packet 保持不可变。
  • 看板:scripts/ticket_board.py 生成纯静态 HTML Kanban(无进程、无端口),输出在 .dsh/baton/ 下,可用 file:// 打开。

Bundle 主要路径包括:skills/baton/SKILL.md(baton skill)、scripts/session_control.py(actions / bind / reconcile / status / cleanup)、持久化计划存储 .dsh/baton/queue.db 等。

安装与启用

Baton 是 DSH bundle:挂载 baton skill,执行经 bundled Python CLI scripts/session_control.py。需要 DSH 0.2.1-rc.2 或更新(package.json 约束为 >=0.2.1-rc.2 <0.3.0)、提供 subagent 工具的 profile(随附的 dsh-base 即可)、以及 Python 3.10+ 在 PATH 上(或通过 BATON_PYTHON 指定)。

官方安装方式如下(勿自行拼接 github:owner/repo 形式):

# 本地 checkout
dsh plugin add /path/to/baton

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

自检 bundle(仅需 python3 + git,对临时 git 仓库驱动真实 CLI,健康时 exit 0):

python3 tests/cli_smoke.py
# CLI SMOKE PASS: actions dispatch, status snapshot, error exit - all green

插件以当前 DSH 进程权限运行;安装前请阅读仓库源码与 MIT 许可证,确认与你的工作流和合规要求一致。

典型用法

1. 准备 OpenSpec 变更与 tasks.md

在业务项目中按项目惯用的 openspec/AGENTS.md 流程编写变更并获批准,例如:

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

tasks.md 是 ticket 源:章节表示阶段,任务带 N.M id;较早章节中的任务会阻塞后续章节(同章内可并行)。最小形态示例:

# Tasks: add-login

## 1. Backend

- [x] 1.1 token endpoint
- [ ] 1.2 session persistence

## 2. Frontend

- [ ] 2.1 login form

[x] 表示已 resolved,[ ] 表示 ready;精确解析规则见仓库 docs/ticket-format.md。

2. 在会话中驱动 Baton

对会话说明:

run baton on <project_path> <change-id>

Skill 会循环:actions → subagent → bind → 完成通知 → reconcile,直到 batch 返回 complete。

架构上,主会话调用例如:

session_control.py <project> <change> actions --session-id ... --capacity<=5

返回 dispatch / recover / resolve_merge / wait / blocked / complete 等动作;绑定子智能体 id 后,在 reconcile 阶段用 --agent-terminal 等对账 sealed receipt。

3. 可选:生成 ticket 看板

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

项目仅有一个 change 时,build / scan 可省略 <change-id>;零个或多个 change 时会明确报错并列出候选。

适用场景与注意

适合谁:已在用 OpenSpec 管理变更、且 DSH profile 具备 subagent、希望在规格与执行之间用同一粒度(约 one assignment ~ one task)做确定性编排的团队或个人。

注意:

  • 集成 merge 冲突会保留,不会自动 abort。
  • 并发上限为 5;集成始终串行。
  • 同一仓库还提供 ZCode 插件形态(.zcode-plugin/plugin.json),挂载相同 skill 与同一 CLI;DSH 用户以上述 bundle 安装为准。
  • DSH 社区目录(如 SkillHub)是独立站点,与 DeepSeek / 幻方无官方从属关系;星标与发布状态以 GitHub 与目录页为准。

结尾

Baton 把 OpenSpec 已批准变更变成可核验的完工路径:调度 deterministic、worktree 隔离、成功只看 sealed receipt。若要进一步了解参数与内部命令,以仓库 README 与 docs/ 为准。

  • 目录页:https://www.skillhub.cn/plugins/Lumos-789/baton
  • GitHub:https://github.com/Lumos-789/baton
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye