kanban-system
v1.0.0
Published
A kanban board + multi-agent (Claude + Codex) ops/dev harness: routing, pre-deploy gates, incident playbooks, 24h monitoring, Telegram Ops Thread mirror.
Maintainers
Readme
kanban-system
A kanban board where multi-agent operators (Claude + Codex, via their CLIs) run
24/7 ops and dev for a project: a person's instruction becomes a kanban task, the
orchestrator routes it to a specialist agent with a verification level (single-model /
review / independent cross-validation), the work happens in an isolated git worktree, a
pre-deploy gate blocks anything that doesn't build/test, a 24h watch loop turns
monitoring anomalies into tasks, and incident playbooks tell humans what to do when
something breaks. It's a template — clone it, point config.js at your front-end /
back-end repo, edit a few globs, and you have the "kanban + multi-agent" pattern
running on your codebase.
It runs alongside your application repo (it does not contain that app's code) and drives work on it.
Installation
Two ways to get started:
Option A — GitHub Template (zero config, keeps update history)
- Open github.com/Zakedu/kanban-system and click "Use this template" → "Create a new repository".
- Clone your new repo and jump straight to Quick start.
gh repo create my-board --template Zakedu/kanban-system --private --clone
cd my-boardOption B — npx CLI (zero clone, no GitHub account required)
npx kanban-system init my-board
cd my-board
cp config.example.js config.js # edit: repoPath, deployCommands
cp .env.example .env # (optional) Slack / Sentry / Vercel tokens
npm install
npm start # → http://localhost:8080The CLI also exposes thin wrappers so you can run the harness commands from the published package without cloning the repo:
npx kanban-system start # start the kanban server
npx kanban-system watch # run the 24h watch scheduler
npx kanban-system gate # run the pre-deploy gate
npx kanban-system whoami # find your Telegram chat id
npx kanban-system --versionPublishing to npm (maintainer only)
# bump version first
npm version patch # or minor / major
npm publish --access publicnpm publish requires being logged in (npm login) and having push access to the
Zakedu/kanban-system repository. The files field in package.json controls what
ships in the tarball.
Architecture
┌─────────────────────────────┐
you / Slack / API ──────────▶ │ kanban server (REST + SSE) │ ◀── browser dashboard
│ server/kanban.cjs · ui/ │
└──────────────┬──────────────┘
│ tasks
┌─────────▼─────────┐
│ orchestrator │ routes by `owns` globs,
│ agents/orch...md │ sets the `runner`, enforces
└─────────┬─────────┘ the task state machine
┌─────────────────────────┼─────────────────────────┐
┌────────▼───────┐ ┌──────────────▼─────┐ ┌────────────────▼──────┐ ┌───────────▼────────┐
│ frontend-agent │ │ backend-agent │ │ deploy-gate-agent │ │ monitor-agent │
│ pages, UI, │ │ API, DB, migra- │ │ runs the gate (build │ │ polls Sentry / │
│ routing, i18n │ │ tions, authz │ │ /test) before deploy │ │ Vercel / custom │
└────────────────┘ └────────────────────┘ └───────────┬───────────┘ └─────────┬──────────┘
│ │ │ │
reviewer:codex runner: both hard gate, no anomalies → tasks
(Claude impl, (Claude + Codex agent override (lib/watch + lib/detect)
Codex reviews) independent, diffed) (hooks/pre-push.sample)
└────────────────────┴──── lib/runner (claude/codex/both/reviewer adapters, git worktrees, budget) ────┘
incident? ──▶ playbooks/*.html (one-page runbooks: trigger → diagnose → decision tree → escalate → aftermath)- kanban server (
server/kanban.cjs+ui/) — a 4-column board (pending / in progress / needs human / completed) with a REST API, SSE live updates, an agent registry fromagents/*.md, and an optional Slack bot. - orchestrator (
agents/orchestrator.md) — the single decision-maker: turns every instruction into a task, routes it (byownsglob, by severity), sets therunner, owns the state machine. Never edits app code itself. - specialist agents (
agents/frontend-agent.md,backend-agent.md,deploy-gate-agent.md,monitor-agent.md,reviewer-codex.md) — eachownsa non-overlapping slice of your repo and declares a defaultrunner._TEMPLATE.mdto add more. - playbooks (
playbooks/*.html) — scannable incident runbooks the agents/orchestrator link from tasks._TEMPLATE.html+ four examples (build-fail,e2e-regression,sentry-spike,deploy-rollback). - watch + detect (
lib/watch/scheduler.cjs,lib/detect/*) — a 24h loop that runs the enabled detectors (sentry,vercel, or your own from_template.cjs) and posts findings as kanban tasks. Thresholds live inlib/detect/rules.json(hot-reloaded). - runner (
lib/runner/*) — executes a task per itsrunner: spawns theclaude/codexCLI in an isolated git worktree, merges the results whenrunner: both, writes the verdict + diff back to the task. Has a daily second-model budget with a fallback chain. - gate (
lib/gate/index.cjs) — runsconfig.js → deployCommandsfail-fast, inspects bundle size, auto-creates a "needs human" task on failure. Installed as a git pre-push hook viahooks/pre-push.sample.
Quick start
Three ways to install — pick whichever fits.
A. npx (zero install, fastest)
npx kanban-system init my-board
cd my-board
cp config.example.js config.js # edit: repoPath, deployCommands
cp .env.example .env # (optional) TELEGRAM_BOT_TOKEN, SENTRY_TOKEN, ...
npm install # virtually nothing
npm start # → http://localhost:8080B. GitHub Template — open the repo on GitHub and click "Use this template" →
"Create a new repository". Then git clone your new repo and follow steps from
the cp config.example.js … line above. Best for team / long-running ops.
C. Plain git clone — if you want to work directly on a fork:
git clone https://github.com/Zakedu/kanban-system.git
cd kanban-system
cp config.example.js config.js && cp .env.example .env
npm install && npm startOpen http://localhost:8080. Create a task in the UI (or curl -X POST
http://localhost:8080/api/tasks -H 'Content-Type: application/json' -d '{"subject":"Try
it"}') and watch it on the board. Run the gate: npm run gate. Run one watch sweep:
npm run watch:once. (The claude / codex CLIs are optional — without them the runner
falls back to deterministic stub verdicts.)
Adapting to your project (front-end / back-end)
The full step-by-step is in docs/adapting-to-your-project.md. In short:
config.js— pointrepoPathat your repo; setdeployCommandsto your stack's build/test chain (npx tsc --noEmit+npm run build, orcargo build+cargo test, orgo vet+go test, …); setbuildOutputDir(ornull).agents/— edit theowns:globs infrontend-agent.md/backend-agent.mdto match your directory layout. Copy_TEMPLATE.mdfor more roles.lib/detect/— enable the detector for your monitoring (sentry/vercel/ your own from_template.cjs) inconfig.js → detectors. No monitoring? Leave it empty.agents/deploy-gate-agent.md+lib/gate/— the gate runsconfig.js → deployCommands; no code change needed, just review the agent doc so it matches.playbooks/— copy_TEMPLATE.htmlfor each incident type you care about.hooks/— installpre-push.sampleinto your app repo's.git/hooks/pre-push; schedule the 24h watch vialaunchd.plist.template(macOS) or the cron line in its comment.- (optional) — wire a Slack bot token for start / progress / done reporting and the
/kanbanslash command. - (optional) — wire Telegram for 24h ops-from-anywhere. See the next section.
Ops Thread (Telegram mirror) — optional
The kanban dashboard has a right-side Ops Thread chat panel. Everything in it is mirrored to a Telegram chat in both directions, so you can run 24h ops from your phone without leaving the kanban as the source of truth.
[ kanban dashboard ] [ your Telegram DM ]
Ops Thread panel ◀──── /api/ops-thread ────▶ sendMessage / getUpdates
│ │ │
└── you type ───────────┘ │
└── operator replies ──────┘
task created / completed → 📋 / ✅ posted to both sidesSetup (~2 minutes, no PG / no external service):
- Open Telegram, message
@BotFather, send/newbot, follow the prompts. Copy the token you get. - Send any DM to your new bot from your own Telegram account (this is what lets the bot see you exist — Telegram won't deliver replies otherwise).
- Put the token + chat id in
.env:TELEGRAM_BOT_TOKEN=123456:AA...your_token TELEGRAM_CHAT_ID= # leave blank for now npm start, then in another terminal:
Copy thatcurl http://localhost:8080/api/telegram/whoami # → { "ok": true, "chats": [ { "id": 6131488858, "type": "private", ... } ] }idintoTELEGRAM_CHAT_IDin.env, restartnpm start.- Done — type in the Ops Thread panel and it appears in Telegram; reply in Telegram
and it shows up in the panel. Task
created→📋 #N <subject>,in_progress→▶️ #N,completed→✅ #N — <one-line report>.
No Telegram? Leave the env vars blank. The panel still works as a local kanban-only chat (and as a place where the server posts task lifecycle events).
Allowing only specific people: set TELEGRAM_ALLOWED_CHAT_IDS=id1,id2 to allow more
than one chat. Empty list ⇒ only TELEGRAM_CHAT_ID is accepted (recommended for solo ops).
Endpoints (you usually never call these — the UI does):
GET /api/ops-thread?since=<id>— load thread (paginated by message id)POST /api/ops-thread/append { role, text, taskId? }— agents append to the threadPOST /api/ops-thread/send { text }— you send (also mirrored to Telegram)GET /api/telegram/status—{ configured, polling, chatId }GET /api/telegram/whoami— debug: dump recentgetUpdatesso you can find a chat id
The kanban-first protocol
Every user instruction becomes a kanban task before work starts: capture it
verbatim, route it, set the runner, transition to in_progress, and only then start.
On completion, set reportPath + reportSummary. The single exception is incident
response — a production-impacting incident or a 1-line, obviously-reversible hotfix may
be done immediately, but a post-hoc task must be registered within 1 hour, tagged
metadata.source = "incident-response". Nothing else qualifies. Rationale and the state
machine: docs/the-pattern.md → "Kanban-first".
Multi-agent cross-validation
Pick the verification level per task via runner:
- single-model (
claude/codex) — deterministic / mechanical work (running tests, polling an API, a state transition); a second opinion only adds latency. reviewer:codex— Claude implements in an isolated worktree, Codex reviews the result and can downgrade the verdict toneeds_human. Default for implementation work.both— Claude and Codex independently do the work from the same spec, in separate worktrees; the orchestrator diffs them. Agreement → auto-merge; disagreement → "needs human" column. For high-stakes work (schema migrations, access-control policies, money paths) — the disagreement is the safety feature.
The orchestrator auto-promotes single-model → both above a severity threshold; a daily
second-model budget caps cost. Details: docs/the-pattern.md →
"Cross-validation".
Example: APEX
APEX is an AI-skills certification exam platform (React/Vite front end, Supabase back
end) that ran this harness in production under the codename "Sentinel": 8 generic
ops/dev agents like the ones here plus a 6-agent domain group, an exam-engine selvedge
boundary, a deliberately powerless "proctor" agent (detect-and-escalate, never enforce),
runner: both on migrations / grading prompts / credential scoring, and the
gate-before-push rule. Full write-up: docs/example-apex.md —
the one place project-specific domain content lives.
CLI reference
The kanban-system bin (also usable as npx kanban-system <cmd>):
| Command | What it does |
|---|---|
| init <name> | Scaffold a fresh checkout into ./<name> (config templates + all the harness files, minus the CLI itself) |
| start [--port N] | Run server/kanban.cjs. Prefers the local checkout's server if present (so config.js / UI edits apply) |
| watch [--once] | Run lib/watch/scheduler.cjs |
| gate | Run lib/gate/index.cjs |
| whoami | Probe a running server's /api/telegram/whoami (find your Telegram chat id) |
| --version / --help | Self-explanatory |
License / status
MIT. Status: extracted as a domain-agnostic template + npm CLI; the pieces are present and wired, but you'll want to exercise them against your own repo before relying on them in production.
