BATON is the human-attention control plane for agent swarms.
It helps a solo operator keep valuable agent work in motion by answering:
- What should I touch next?
- Why now?
- What action sends this work back into motion?
- Can this touch be automated next time?
Canonical repository: trippyogi/baton. This repo is the source of truth (not a generated mirror of a parent app). See docs/specs/control-plane-overhaul/phase-0-evidence.md.
The primary daily surface is a ranked touch queue (Flow UI) plus a command box. Overview, board, runs, queue, cost, memory, and diagnostics remain secondary views.
Governing Spec Kit artifacts for the control-plane overhaul (BATON v1 = Phases 0–4):
.specify/constitution.mddocs/specs/control-plane-overhaul/
Implemented phases:
-
Next-Touch Engine stabilization pass
- Runs screen read endpoints and SSE stub.
- Extension routes load before the SPA fallback.
- Snoozed touches resurface after expiry;
passedtouches no longer suppress new generated touches. - Touch actions are authorized by touch type; non-review touches cannot be accepted as done.
- Delegation/assignment is truthful: configured agents dispatch through a run lifecycle; unconfigured agents remain visible and do not fake motion.
- Invalid review packets create evaluator/refinement touches; valid packets create review touches.
- Flow command submit force-refreshes after action.
- User-controlled text is escaped across Flow-adjacent task/board/run surfaces.
- Task deletion is soft archive.
GET /api/flowis read-safe and preserves manual escalation boosts.idle agentsuses the real agent registry and assignment candidates avoid duplicate ready-task matches.- Tasks API accepts ranking/autonomy fields.
- Webhook signature/payload handling is hardened.
npm run check:js,npm run smoke,npm run smoke:dispatch,npm run audit, andnpm testscripts are available.
-
Phase 0 — Local app stabilization
- Declared missing
dotenvandioredisdependencies. - Fixed internal extension loading by importing
dbinserver/index.js. - Redis-backed queue/webhook paths now degrade cleanly when Redis is unavailable during local development.
- Declared missing
-
Phase 1 — Flow Home MVP
- New default route:
/#/flow. - Mode selector and airspace strip.
- Deterministic next-touch generation from existing tasks.
- Ranked touch queue with explainable
why_nowstrings. - Command box support for capture, delegate, mode changes, review-next, and “what needs me”.
- Basic touch actions: accept, refine, delegate, answer, process, snooze, archive, inspect, escalate.
- Board renamed into Flow language as the secondary Airspace Map.
- New default route:
-
Phase 2 — Review packet quality gate
- Review packet API and validation.
- Valid packets create linked review touches.
- Invalid packets are marked
needs_evaluatorand routed as refinement/evaluator work instead of normal human review.
-
Phase 3 — Agent capacity layer
- Seeded agent registry.
/api/agentsendpoint.- Idle-agent counts in Flow airspace.
- Idle-agent candidate generation against ready tasks.
- Assigning an idle-agent touch creates a dispatch run when the agent has configured transport. BATON marks agents running only after ACK.
-
Spectre webhook dispatch v1
- Spectre is seeded as the first real dispatch-capable orchestrator agent.
delegate Spectre ...creates a Spectre-owned ready task and one assignment touch.- Prepare/Assign creates a run, sends a compact
baton.dispatch.v1envelope by webhook, waits for ACK, then marks the run/agent/task in motion. - Spectre review packets advance runs to
review_ready; accepting the review completes the task and run. npm run fake:spectreandnpm run smoke:dispatchexercise the full local loop.
BATON treats the true unit of work as a human touch: a brief moment where human judgment, taste, context, approval, prioritization, or feedback unlocks more valuable agent motion.
Core concepts:
- Task — broader body of work.
- Run — one execution attempt by an agent.
- BatonTouch — ranked human touch required to keep work moving.
- Airspace — compact state of running, waiting, review, idle, stale, failed, ready, and inbox work.
- Flow Mode — current operator mode that changes ranking behavior.
- Review Packet — structured agent output required before human review.
- Agent — worker status/capacity record used for assignment.
Supported modes:
deep_buildtriagereviewstrategy_creativelaunchadmincleanuprecovery
Mode affects touch scoring and prioritization.
git clone https://github.com/trippyogi/baton.git
cd baton
nvm use
npm install
cp .env.example .env
npm startDefault local URL:
http://127.0.0.1:4200/#/flow
If port 4200 is already in use:
VMC_PORT=4420 npm startFor private same-tailnet development, bind to a specific private interface instead of all interfaces and set an API bearer token:
BATON_HOST=100.x.y.z VMC_PORT=4200 BATON_API_TOKEN=replace-with-a-long-random-token npm startKeep the default 127.0.0.1 for ordinary local development. Non-localhost API routes require BATON_API_TOKEN and expect Authorization: Bearer <token>; /api/health remains open for readiness checks. Do not bind BATON to 0.0.0.0 unless you also have strict network restrictions.
Redis is optional for local Flow development. Queue diagnostics gracefully return empty queue data when Redis is unavailable.
BATON is safe to run with your own tasks and agents locally. Keep private data in ignored local/ files or the local SQLite DB, then use npm run audit:private before committing. See docs/guides/private-local-use.md.
The Requests screen is optional and token-protected; set SHARED_REQUESTS_TOKEN in .env to enable it locally.
BATON is pinned to Node 24 via .nvmrc; package.json supports Node >=24 <25.
BATON follows Semantic Versioning.
Current version: 0.1.0.
Because BATON is still pre-1.0, minor versions may include breaking changes while the Next-Touch Engine stabilizes. Patch versions should be reserved for compatible fixes. Release notes should be recorded in CHANGELOG.md.
Recommended release flow:
- update
package.jsonversion - update
CHANGELOG.md - run checks/audit
- commit as
release: vX.Y.Z - tag with
vX.Y.Z - push commit and tag
See SECURITY.md for supported versions, vulnerability reporting, and the release security checklist.
Key defaults:
.env, local DB files, logs, and secrets are ignored and should never be committed.- Webhooks validate HMAC signatures before doing work.
- User-controlled UI output is escaped.
- Touch actions are authorized by type.
- Delegation/assignment only marks tasks airborne and agents running after configured dispatch ACKs. Unconfigured dispatch remains visible and honest.
npm run auditandnpm run audit:privateshould pass before release tags.
npm test
npm run smoke:dispatch
npm run audit
npm run audit:privatenpm test runs syntax checks and a self-contained Flow smoke test. npm run smoke:dispatch starts BATON plus a fake Spectre webhook on isolated temp state and verifies the dispatch/review loop. npm run audit:private checks that private local data and high-signal secrets are not tracked.
Flow:
GET /api/flow
PATCH /api/flow/mode
POST /api/flow/command
Touches:
GET /api/touches
POST /api/touches/rebuild
PATCH /api/touches/:id/action
Agents:
GET /api/agents
GET /api/agents/:id
PATCH /api/agents/:id
Review packets:
GET /api/review-packets
POST /api/review-packets
Dispatch:
POST /api/dispatch/test
POST /api/runs/:id/ack
POST /api/runs/:id/status
Existing routes remain available for tasks, runs, overview, queue, costs, performance, memory, team, shared requests, and creatives.
capture improve onboarding copy for the demo product
idea make review packets mandatory before human review
delegate audit checkout funnel copy
delegate Spectre review launch plan draft
mode launch
mode review
review next
triage
what needs my judgment?
idle agents
Unknown command text falls back to inbox capture.
A valid review packet requires:
goalsummarysuggested_next_action- at least one
evidenceitem confidence_scorequality_score
Invalid packets are stored with packet_status = needs_evaluator.
Create baton-internal/extension.js alongside your baton directory:
module.exports = {
register(app, db) {
app.get('/api/my-route', (req, res) => {
res.json({ ok: true });
});
}
};BATON detects and loads it at startup. It falls back gracefully if absent.
See CONTRIBUTING.md for local setup, product invariants, PR checklist, and security expectations.
See CHANGELOG.md.
MIT — see LICENSE.