DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Lumos-789 /

Lumos-789/baton

Verified

Ticket/DAG/session-subagent control plane over OpenSpec changes — deterministic MCP actions, one isolated git worktree per assignment, sealed receipts as the only success evidence

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@8fa54c91

Baton

Tests Python License: MIT Stars

The sole ticket / DAG / session-subagent control plane over OpenSpec changes. A local MCP server exposes deterministic session actions; the main session delegates each assignment with the DSH subagent tool, binds the child id, and reconciles the completion notice against a sealed receipt.

Discussions

The problem it solves

OpenSpec is strong on spec-driven decomposition (proposal -> tasks -> archive) but does not execute. Baton turns an approved change into finished work, deterministically: the main session never decides ticket state itself. It forwards the deterministic actions returned by the Baton MCP server to DSH subagents verbatim, then reconciles each completion notice against a sealed receipt (the assignment's verification commands run green in an isolated worktree). Free-text subagent output is ignored.

A sealed receipt is hash-bound evidence produced locally by receipt.py (task-packet hash + clean, advanced HEAD + exit-0 verification results). It is integrity evidence, not a cryptographic proof against a hostile subagent.

The change's tasks and the execution share the same granularity (one assignment ~ one task), and three seams are bridged deterministically:

Seam Baton's answer
Dependency (section-order DAG -> what to run next) SessionController.actions() computes the frontier fresh every call and atomically claims distinct tasks
Concurrency (<=5 parallel tasks) one isolated git worktree per assignment; integration serialized by a repository-scoped lock
State (subagent done -> task resolved) a sealed receipt is the only success evidence; the controller integrates the branch, finalizes the attempt, and flips the task's [x] in tasks.md

Baton is the conductor. SessionController is the sole deterministic scheduler; the main session is a mechanical forwarder; OpenSpec is the plan face.

Install (DSH)

Baton is a DSH bundle: one package mounts the baton skill and starts the local MCP server. It requires DSH 0.2.1-rc.2 or newer, a profile that provides the subagent tool (the shipped dsh-base does), and Python 3.10+ on PATH (or BATON_PYTHON pointing at it).

# From a checkout
dsh plugin add /path/to/baton

# Once published
dsh plugin add dsh-openspec-baton

The package name is dsh-openspec-baton to avoid colliding with the unrelated dsh-baton plugin. The repository and brand remain baton, and the MCP server keeps the baton namespace (mcp__baton__*).

Quick start

# In your business project, write an OpenSpec change (the project's normal
# openspec/AGENTS.md workflow) and get it approved:
#   openspec/changes/<change-id>/proposal.md + tasks.md   (unchecked N.M tasks)

Then ask the session:

run baton on <project_path> <change-id>

The skill drives actions -> subagent -> bind_agent -> completion notice -> reconcile until the batch returns complete.

Architecture

main session (mechanical forwarder - no model-driven state decisions)
  |- mcp__baton__actions(project_path, feature, session_id, capacity<=5)
  |     -> SessionController.actions(): recover/reconcile sealed receipts,
  |        compute frontier, atomically claim, prepare isolated worktrees +
  |        immutable Task Packets, return dispatch/recover/resolve_merge/
  |        wait/blocked/complete actions
  |- subagent(dispatch.prompt, cwd=dispatch.cwd) -> child id
  |- mcp__baton__bind_agent(assignment_id, claim_token, agent_id)
  |- runtime sends the subagent completion notice
  |- mcp__baton__reconcile(assignment_id, claim_token, agent_terminal, ...)
        -> sealed receipt -> succeeded + integrated; otherwise unknown + recover

SessionController (the sole deterministic scheduler)
  |- durable plan store (.dsh/baton/queue.db): revisions, attempts, leases,
  |  sealed receipts, completion facts
  |- isolated assignment worktrees + a shared integration worktree
  |- serial git integration; merge conflicts preserved (never auto-aborted)
  `- latest-plan completion (all required tickets verified + integrated)

Capabilities

Session-subagent execution (sole path):

  • Deterministic scheduling - claim, lease, worktree, receipt verification, integration, completion are all scripted; the model never decides state.
  • Isolated worktrees - one branch per assignment; capacity <= 5 sliding window; integration serialized by a repository-scoped lock.
  • Sealed receipts - scripts/receipt.py verify / seal is the only accepted success evidence; a completion notice without a receipt flips the attempt to unknown.

Control plane:

  • OpenSpec-native cognitive phase - "use baton to finish X" means the session runs the project's OpenSpec workflow (align -> write the change -> user approves), then drives execution to complete. No self-built Grill/Brief/approval state machine.
  • Live plan = edit tasks.md - add tasks or sections at runtime; the next actions() call records a new plan revision and the frontier is recomputed. In-flight packets stay immutable.

Observability: scripts/ticket_board.py produces a pure static HTML Kanban board over a project's OpenSpec changes (zero process, zero port, colored feature tags, open via file://).

Bundle contents

Path Purpose
index.js mounts the bundled skills/ provider and the stdio MCP server
cordis.patch.yml DSH bundle insert row (dsh-openspec-baton)
skills/baton/SKILL.md the baton skill (actions -> subagent -> reconcile)
mcp-servers/baton-server.py local stdio MCP server (mcp__baton__*)
scripts/ deterministic controller, plan store, receipts, queue CLI

History

Baton v1 drove an external ralph.sh loop. v2 brought the loop into Python. v3 replaced the subprocess model with subagents but still used a shared PRD + passes flags. v4 retired the PRD/passes protocol and made SessionController the sole deterministic scheduler. v5 (current) adopts OpenSpec as the single plan face - the change's tasks.md is the ticket source (section-order DAG, [x] write-back), and the self-built cognitive/amendment engines are retired.

Requirements

  • DSH 0.2.1-rc.2 or newer, with subagent available (dsh-base)
  • Python 3.10+ (python3 on macOS/Linux, python on Windows, or BATON_PYTHON) + pytest
  • A git target project (the controller prepares isolated worktrees)
  • The target project uses OpenSpec (openspec/changes/<id>/tasks.md)

Regression

The standard regression entry - full pytest suite (incl. temp-git-fixture e2e), a live MCP stdio smoke test of the server, and a docs/file consistency check:

./tests/regression.sh

Documentation

  • docs/architecture.md - why the deterministic control plane is the core IP
  • docs/ticket-format.md - the OpenSpec change -> ticket mapping spec

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 8fa54c917426

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout