kanban-system 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.env.example +76 -0
  2. package/CLAUDE.md +108 -0
  3. package/README.md +272 -0
  4. package/agents/_TEMPLATE.md +42 -0
  5. package/agents/backend-agent.md +81 -0
  6. package/agents/deploy-gate-agent.md +73 -0
  7. package/agents/frontend-agent.md +73 -0
  8. package/agents/monitor-agent.md +65 -0
  9. package/agents/orchestrator.md +91 -0
  10. package/agents/reviewer-codex.md +51 -0
  11. package/bin/cli.js +171 -0
  12. package/config.example.js +99 -0
  13. package/docs/adapting-to-your-project.md +155 -0
  14. package/docs/example-apex.md +86 -0
  15. package/docs/the-pattern.md +92 -0
  16. package/hooks/launchd.plist.template +66 -0
  17. package/hooks/pre-push.sample +61 -0
  18. package/lib/config.cjs +138 -0
  19. package/lib/detect/_template.cjs +63 -0
  20. package/lib/detect/rules.json +28 -0
  21. package/lib/detect/sentry.cjs +86 -0
  22. package/lib/detect/vercel.cjs +62 -0
  23. package/lib/gate/index.cjs +182 -0
  24. package/lib/runner/adapters/both.cjs +33 -0
  25. package/lib/runner/adapters/claude.cjs +119 -0
  26. package/lib/runner/adapters/codex.cjs +43 -0
  27. package/lib/runner/adapters/reviewer.cjs +91 -0
  28. package/lib/runner/budget.cjs +75 -0
  29. package/lib/runner/index.cjs +93 -0
  30. package/lib/runner/result-merger.cjs +58 -0
  31. package/lib/runner/worktree-manager.cjs +64 -0
  32. package/lib/watch/scheduler.cjs +164 -0
  33. package/package.json +59 -0
  34. package/playbooks/_TEMPLATE.html +54 -0
  35. package/playbooks/build-fail.html +57 -0
  36. package/playbooks/deploy-rollback.html +53 -0
  37. package/playbooks/e2e-regression.html +58 -0
  38. package/playbooks/playbook.css +26 -0
  39. package/playbooks/sentry-spike.html +53 -0
  40. package/server/kanban.cjs +1152 -0
  41. package/skills/archive.md +18 -0
  42. package/skills/gate.md +22 -0
  43. package/skills/standup.md +24 -0
  44. package/skills/triage.md +24 -0
  45. package/ui/kanban.html +628 -0
  46. package/ui/styles/kanban.css +436 -0
  47. package/ui/styles/progress.css +315 -0
  48. package/ui/styles/tokens.css +291 -0
package/.env.example ADDED
@@ -0,0 +1,76 @@
1
+ # kanban-system — environment variables
2
+ # Copy to .env, fill values, NEVER commit .env
3
+
4
+ # ── Server ────────────────────────────────────────────────────────
5
+ # Port the kanban dashboard listens on. Also set in config.js (config.js wins
6
+ # if both are present unless PORT is exported).
7
+ PORT=8080
8
+ KANBAN_BASE=http://localhost:8080
9
+
10
+ # ── Multi-agent / cross-validation policy ─────────────────────────
11
+ # Severity threshold for auto-promoting single-runner tasks to `both`
12
+ # (cross-validated). Values: low, medium, high, critical.
13
+ CROSS_VALIDATION_THRESHOLD=medium
14
+
15
+ # Daily cap on the second-model (Codex / GPT) invocations. Resets at UTC midnight.
16
+ # When exceeded, runner=codex/both/reviewer:codex falls back to the primary model.
17
+ DAILY_CODEX_BUDGET=200
18
+
19
+ # Model fallback chain — comma-separated, priority order. First is most capable.
20
+ MODEL_FALLBACK_CHAIN=claude-opus-4-7,claude-sonnet-4-6,claude-haiku-4-5
21
+
22
+ # ── Watch + Detect ────────────────────────────────────────────────
23
+ WATCH_INTERVAL_MS=300000
24
+ WATCH_DRY_RUN=0
25
+ # Comma-separated detector names. Empty = all enabled detectors in lib/detect/rules.json
26
+ WATCH_ENABLED=
27
+
28
+ # Sentry (optional — detector degrades gracefully when blank)
29
+ SENTRY_AUTH_TOKEN=
30
+ SENTRY_ORG_SLUG=
31
+ SENTRY_PROJECT_SLUG=
32
+
33
+ # Vercel (optional)
34
+ VERCEL_TOKEN=
35
+ VERCEL_PROJECT_ID=
36
+ VERCEL_TEAM_ID=
37
+
38
+ # ── Pre-deploy gate ───────────────────────────────────────────────
39
+ GATE_TIMEOUT_MS=600000
40
+ GATE_SKIP_E2E=0
41
+ STRICT_BUNDLE=0
42
+ # Disable the auto-created kanban task on gate failure (CI/scripts)
43
+ GATE_NO_KANBAN=0
44
+
45
+ # ── Slack (optional — start/progress/done reporting) ──────────────
46
+ SLACK_BOT_TOKEN=
47
+ SLACK_APP_TOKEN=
48
+ SLACK_CHANNEL_ID=
49
+ SLACK_AGENT_WEBHOOK=
50
+ SLACK_ADMIN_USERS=
51
+ SLACK_COMMAND=/kanban
52
+
53
+ # ── Telegram (optional — Ops Thread mirror panel) ─────────────────
54
+ # Drop in TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID and the kanban server starts
55
+ # mirroring the right-side "Ops Thread" panel to that Telegram chat (outbound
56
+ # via sendMessage, inbound via getUpdates long-poll). Both blank ⇒ the panel
57
+ # still works locally as a kanban-only chat; nothing is sent to Telegram.
58
+ #
59
+ # How to get values:
60
+ # 1. BotFather (@BotFather on Telegram) → /newbot → copy the token here.
61
+ # 2. Send any DM to your new bot from your Telegram account.
62
+ # 3. With the server running: curl http://localhost:8080/api/telegram/whoami
63
+ # → copy chat.id of your DM (a number like 6131488858) into TELEGRAM_CHAT_ID.
64
+ TELEGRAM_BOT_TOKEN=
65
+ TELEGRAM_CHAT_ID=
66
+ # Optional comma-separated allowlist (defaults to TELEGRAM_CHAT_ID only)
67
+ TELEGRAM_ALLOWED_CHAT_IDS=
68
+ # Set to 0 to disable the long-poll worker (you can still send outbound)
69
+ TELEGRAM_POLL_ENABLED=1
70
+ TELEGRAM_POLL_INTERVAL_MS=1500
71
+
72
+ # ── Anthropic / OpenAI (only if you run the CLI adapters directly) ─
73
+ # The runner adapters shell out to the `claude` / `codex` CLIs, which manage
74
+ # their own auth. These are placeholders for setups that pass keys via env.
75
+ ANTHROPIC_API_KEY=
76
+ OPENAI_API_KEY=
package/CLAUDE.md ADDED
@@ -0,0 +1,108 @@
1
+ # kanban-system — operating rules
2
+
3
+ This repo is a **kanban board + multi-agent (Claude + Codex) ops/dev harness**: a
4
+ kanban server with a REST API, an orchestrator + specialist agents, incident
5
+ playbooks, a 24h watch/detect loop, a subagent runner, and a pre-deploy gate. It runs
6
+ *alongside* an application repo (the one `config.js → repoPath` points at) and drives
7
+ work on it — it does not contain that application's code.
8
+
9
+ ## Layout
10
+ | Path | Purpose |
11
+ |---|---|
12
+ | `server/kanban.cjs` | Kanban dashboard + REST API + SSE. `npm start`. |
13
+ | `ui/` | The dashboard HTML + token CSS. |
14
+ | `agents/*.md` | Agent definitions — frontmatter (`name`, `mission`, `runner`, `owns`, …) + body. `_TEMPLATE.md` to add one. |
15
+ | `playbooks/*.html` | One-page incident runbooks. `_TEMPLATE.html` to add one. |
16
+ | `lib/config.cjs` | Config loader — reads `config.js` (or `config.example.js`) + `.env` + env overrides. |
17
+ | `lib/watch/scheduler.cjs` | 24h watch loop — runs detectors, turns findings into tasks. |
18
+ | `lib/detect/*` | Monitoring detectors (`sentry`, `vercel`, `_template`) + `rules.json`. |
19
+ | `lib/runner/*` | Subagent runner — `claude` / `codex` / `both` / `reviewer:*` adapters, git worktrees, budget. |
20
+ | `lib/gate/index.cjs` | Pre-deploy gate — runs `config.js → deployCommands` fail-fast. |
21
+ | `hooks/` | `pre-push.sample` (installs the gate as a git hook), `launchd.plist.template` (24h daemon; cron line in the comment). |
22
+ | `skills/` | Reusable Claude Code skill stubs — `/standup`, `/triage`, `/gate`, `/archive`. |
23
+ | `docs/` | `the-pattern.md` (why), `adapting-to-your-project.md` (how), `example-apex.md` (a worked case study — the only place project-specific content lives). |
24
+ | `config.example.js` / `config.js` | Per-project config. Copy the example to `config.js` (gitignored). |
25
+ | `.env.example` / `.env` | Tokens (Slack / Sentry / Vercel / Telegram / …). Copy, fill, never commit `.env`. |
26
+
27
+ ## Ops Thread (Telegram mirror)
28
+ The dashboard's right-side panel is an append-only thread the operator and the agents
29
+ share. With `TELEGRAM_BOT_TOKEN` + `TELEGRAM_CHAT_ID` set in `.env` it mirrors
30
+ bidirectionally to a Telegram chat (outbound via `sendMessage`, inbound via long-poll
31
+ `getUpdates`). The kanban server also posts `📋 #N` / `▶️ #N` / `✅ #N` on task create /
32
+ start / complete to both sides. Agents append progress via `POST /api/ops-thread/append`
33
+ (role: `claude` / `agent` / `system`). The operator types in the panel input or replies
34
+ in Telegram. Both halves are best-effort — missing token/chatId disables the mirror but
35
+ the panel still works locally. Setup is in README "Ops Thread (Telegram mirror)".
36
+
37
+ ## Server & config
38
+ - Start: `npm start` (or `node server/kanban.cjs`). Default port 8080 (`PORT` env or
39
+ `config.js → kanbanPort`).
40
+ - API base: `http://localhost:8080/api/`.
41
+ - Config resolution: `config.js` → `config.example.js` (fallback so it boots) → env
42
+ overrides on top. `.env` at the repo root is loaded automatically (so launchd / cron
43
+ see the tokens).
44
+
45
+ ## Kanban-first instruction protocol — MUST FOLLOW
46
+ Every user instruction becomes a kanban task **before** any work starts. This is the
47
+ orchestrator's first duty (`agents/orchestrator.md`), and it applies to every agent.
48
+
49
+ 1. On receiving an instruction: `POST /api/tasks` — `{ subject, description, agent,
50
+ metadata.runner, priority }`. Capture the instruction verbatim in `description`.
51
+ 2. Set `agent` / `metadata.runner` / `priority` per the routing rules in
52
+ `agents/orchestrator.md`.
53
+ 3. Transition the task to `in_progress` **only then** start the work.
54
+ 4. On completion: set `reportPath` + `reportSummary`, then `completed`.
55
+ 5. Report start / key progress / done via `POST /api/tasks/{id}/slack` (not a raw webhook).
56
+
57
+ **Exception — incident response**: a production-impacting incident or a 1-line,
58
+ obviously-reversible hotfix may be done immediately, but you must register a post-hoc
59
+ task within 1 hour tagged `metadata.source = "incident-response"` with what you did
60
+ and any follow-up. Nothing else qualifies — refactors, docs, features, ordinary bugs
61
+ all go through step 1 first. See `docs/the-pattern.md` → "Kanban-first".
62
+
63
+ ## Task lifecycle & API
64
+ States: `pending` → `in_progress` → `in_review` → `completed`. Only the orchestrator
65
+ writes status transitions. `completed` requires `reportPath` + `reportSummary`.
66
+
67
+ | Method | Path | Body | Description |
68
+ |---|---|---|---|
69
+ | GET | `/api/tasks` | — | List all tasks |
70
+ | POST | `/api/tasks` | `{ subject, description, agent?, priority?, metadata? }` | Create |
71
+ | PUT | `/api/tasks/:id` | `{ status?, reportPath?, reportSummary?, metadata?, ... }` | Update |
72
+ | DELETE | `/api/tasks/:id` | — | Delete |
73
+ | POST | `/api/tasks/:id/slack` | `{ text }` | Post a note to Slack for this task |
74
+ | GET | `/api/agents` | — | Agent registry (from `agents/*.md` frontmatter) |
75
+ | GET | `/api/agents/:name/full` | — | One agent's full definition |
76
+ | GET | `/api/activity?since=&limit=` | — | Activity log |
77
+ | GET | `/events` | — | SSE stream of board updates |
78
+
79
+ ## Multi-agent cross-validation
80
+ - `runner: claude` / `codex` — single model. For deterministic / mechanical work.
81
+ - `runner: reviewer:codex` — Claude implements, Codex reviews. Default for implementation work.
82
+ - `runner: both` — Claude + Codex independently, diffed. Disagreement → "needs human" column.
83
+ For high-stakes work (migrations, access-control, money paths). The disagreement is the safety feature.
84
+ - Auto-promote: severity ≥ `CROSS_VALIDATION_THRESHOLD` bumps single-model → `both`.
85
+ - Daily cap on the second model (`DAILY_CODEX_BUDGET`); fallback chain `MODEL_FALLBACK_CHAIN`.
86
+ See `docs/the-pattern.md` → "Cross-validation".
87
+
88
+ ## Selvedge boundaries
89
+ Each agent declares `owns:` globs (relative to `config.js → repoPath`). Agents stay on
90
+ their side; the orchestrator routes by ownership. Shared surfaces (shared types,
91
+ dependency manifests, migrations) require a cross-check → that's where `runner: both`
92
+ earns its keep. Keep `owns:` globs non-overlapping.
93
+
94
+ ## Pre-deploy gate
95
+ `lib/gate/index.cjs` runs `config.js → deployCommands` serially, fail-fast, from
96
+ `config.js → repoPath`, then an optional bundle-size inspection. The `pre-push.sample`
97
+ hook runs it on `git push` — fail → push blocked, "needs human" task auto-created. The
98
+ only override is `git push --no-verify` or `KANBAN_GATE_BYPASS=1 git push` (the latter
99
+ logged to `data/runs/overrides.jsonl`, reviewed at standup).
100
+
101
+ ## Absolute rules
102
+ 1. Don't ship without the gate passing (or an audited override).
103
+ 2. Don't force-push the main branch.
104
+ 3. Don't commit `.env` or `config.js` (both gitignored — keep it that way).
105
+ 4. Don't cross selvedge boundaries (an agent edits only what it `owns`).
106
+ 5. Don't store plaintext secrets in `data/`, logs, or committed files (use `.env`).
107
+ 6. Don't start work on a user instruction without a kanban task first (incident-response exception only).
108
+ 7. Don't auto-merge a `runner: both` disagreement — a human decides.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # kanban-system
2
+
3
+ A kanban board where **multi-agent operators (Claude + Codex, via their CLIs)** run
4
+ 24/7 ops and dev for a project: a person's instruction becomes a kanban task, the
5
+ orchestrator routes it to a specialist agent with a verification level (single-model /
6
+ review / independent cross-validation), the work happens in an isolated git worktree, a
7
+ pre-deploy gate blocks anything that doesn't build/test, a 24h watch loop turns
8
+ monitoring anomalies into tasks, and incident playbooks tell humans what to do when
9
+ something breaks. It's a *template* — clone it, point `config.js` at your front-end /
10
+ back-end repo, edit a few globs, and you have the "kanban + multi-agent" pattern
11
+ running on your codebase.
12
+
13
+ It runs *alongside* your application repo (it does not contain that app's code) and
14
+ drives work on it.
15
+
16
+ ## Installation
17
+
18
+ Two ways to get started:
19
+
20
+ ### Option A — GitHub Template (zero config, keeps update history)
21
+
22
+ 1. Open **[github.com/Zakedu/kanban-system](https://github.com/Zakedu/kanban-system)** and click **"Use this template"** → **"Create a new repository"**.
23
+ 2. Clone your new repo and jump straight to [Quick start](#quick-start).
24
+
25
+ ```bash
26
+ gh repo create my-board --template Zakedu/kanban-system --private --clone
27
+ cd my-board
28
+ ```
29
+
30
+ ### Option B — npx CLI (zero clone, no GitHub account required)
31
+
32
+ ```bash
33
+ npx kanban-system init my-board
34
+ cd my-board
35
+ cp config.example.js config.js # edit: repoPath, deployCommands
36
+ cp .env.example .env # (optional) Slack / Sentry / Vercel tokens
37
+ npm install
38
+ npm start # → http://localhost:8080
39
+ ```
40
+
41
+ The CLI also exposes thin wrappers so you can run the harness commands from the
42
+ published package without cloning the repo:
43
+
44
+ ```bash
45
+ npx kanban-system start # start the kanban server
46
+ npx kanban-system watch # run the 24h watch scheduler
47
+ npx kanban-system gate # run the pre-deploy gate
48
+ npx kanban-system whoami # find your Telegram chat id
49
+ npx kanban-system --version
50
+ ```
51
+
52
+ ### Publishing to npm (maintainer only)
53
+
54
+ ```bash
55
+ # bump version first
56
+ npm version patch # or minor / major
57
+
58
+ npm publish --access public
59
+ ```
60
+
61
+ `npm publish` requires being logged in (`npm login`) and having push access to the
62
+ `Zakedu/kanban-system` repository. The `files` field in `package.json` controls what
63
+ ships in the tarball.
64
+
65
+ ---
66
+
67
+ ## Architecture
68
+
69
+ ```
70
+ ┌─────────────────────────────┐
71
+ you / Slack / API ──────────▶ │ kanban server (REST + SSE) │ ◀── browser dashboard
72
+ │ server/kanban.cjs · ui/ │
73
+ └──────────────┬──────────────┘
74
+ │ tasks
75
+ ┌─────────▼─────────┐
76
+ │ orchestrator │ routes by `owns` globs,
77
+ │ agents/orch...md │ sets the `runner`, enforces
78
+ └─────────┬─────────┘ the task state machine
79
+ ┌─────────────────────────┼─────────────────────────┐
80
+ ┌────────▼───────┐ ┌──────────────▼─────┐ ┌────────────────▼──────┐ ┌───────────▼────────┐
81
+ │ frontend-agent │ │ backend-agent │ │ deploy-gate-agent │ │ monitor-agent │
82
+ │ pages, UI, │ │ API, DB, migra- │ │ runs the gate (build │ │ polls Sentry / │
83
+ │ routing, i18n │ │ tions, authz │ │ /test) before deploy │ │ Vercel / custom │
84
+ └────────────────┘ └────────────────────┘ └───────────┬───────────┘ └─────────┬──────────┘
85
+ │ │ │ │
86
+ reviewer:codex runner: both hard gate, no anomalies → tasks
87
+ (Claude impl, (Claude + Codex agent override (lib/watch + lib/detect)
88
+ Codex reviews) independent, diffed) (hooks/pre-push.sample)
89
+ └────────────────────┴──── lib/runner (claude/codex/both/reviewer adapters, git worktrees, budget) ────┘
90
+
91
+ incident? ──▶ playbooks/*.html (one-page runbooks: trigger → diagnose → decision tree → escalate → aftermath)
92
+ ```
93
+
94
+ - **kanban server** (`server/kanban.cjs` + `ui/`) — a 4-column board (pending /
95
+ in progress / needs human / completed) with a REST API, SSE live updates, an agent
96
+ registry from `agents/*.md`, and an optional Slack bot.
97
+ - **orchestrator** (`agents/orchestrator.md`) — the single decision-maker: turns every
98
+ instruction into a task, routes it (by `owns` glob, by severity), sets the `runner`,
99
+ owns the state machine. Never edits app code itself.
100
+ - **specialist agents** (`agents/frontend-agent.md`, `backend-agent.md`,
101
+ `deploy-gate-agent.md`, `monitor-agent.md`, `reviewer-codex.md`) — each `owns` a
102
+ non-overlapping slice of your repo and declares a default `runner`. `_TEMPLATE.md` to
103
+ add more.
104
+ - **playbooks** (`playbooks/*.html`) — scannable incident runbooks the agents/orchestrator
105
+ link from tasks. `_TEMPLATE.html` + four examples (`build-fail`, `e2e-regression`,
106
+ `sentry-spike`, `deploy-rollback`).
107
+ - **watch + detect** (`lib/watch/scheduler.cjs`, `lib/detect/*`) — a 24h loop that runs
108
+ the enabled detectors (`sentry`, `vercel`, or your own from `_template.cjs`) and posts
109
+ findings as kanban tasks. Thresholds live in `lib/detect/rules.json` (hot-reloaded).
110
+ - **runner** (`lib/runner/*`) — executes a task per its `runner`: spawns the `claude` /
111
+ `codex` CLI in an isolated git worktree, merges the results when `runner: both`, writes
112
+ the verdict + diff back to the task. Has a daily second-model budget with a fallback chain.
113
+ - **gate** (`lib/gate/index.cjs`) — runs `config.js → deployCommands` fail-fast, inspects
114
+ bundle size, auto-creates a "needs human" task on failure. Installed as a git pre-push
115
+ hook via `hooks/pre-push.sample`.
116
+
117
+ ## Quick start
118
+
119
+ Three ways to install — pick whichever fits.
120
+
121
+ **A. `npx` (zero install, fastest)**
122
+ ```bash
123
+ npx kanban-system init my-board
124
+ cd my-board
125
+ cp config.example.js config.js # edit: repoPath, deployCommands
126
+ cp .env.example .env # (optional) TELEGRAM_BOT_TOKEN, SENTRY_TOKEN, ...
127
+ npm install # virtually nothing
128
+ npm start # → http://localhost:8080
129
+ ```
130
+
131
+ **B. GitHub Template** — open the repo on GitHub and click **"Use this template" →
132
+ "Create a new repository"**. Then `git clone` your new repo and follow steps from
133
+ the `cp config.example.js …` line above. Best for team / long-running ops.
134
+
135
+ **C. Plain `git clone`** — if you want to work directly on a fork:
136
+ ```bash
137
+ git clone https://github.com/Zakedu/kanban-system.git
138
+ cd kanban-system
139
+ cp config.example.js config.js && cp .env.example .env
140
+ npm install && npm start
141
+ ```
142
+
143
+ Open `http://localhost:8080`. Create a task in the UI (or `curl -X POST
144
+ http://localhost:8080/api/tasks -H 'Content-Type: application/json' -d '{"subject":"Try
145
+ it"}'`) and watch it on the board. Run the gate: `npm run gate`. Run one watch sweep:
146
+ `npm run watch:once`. (The `claude` / `codex` CLIs are optional — without them the runner
147
+ falls back to deterministic stub verdicts.)
148
+
149
+ ## Adapting to your project (front-end / back-end)
150
+
151
+ The full step-by-step is in **[docs/adapting-to-your-project.md](docs/adapting-to-your-project.md)**.
152
+ In short:
153
+
154
+ 1. **`config.js`** — point `repoPath` at your repo; set `deployCommands` to your stack's
155
+ build/test chain (`npx tsc --noEmit` + `npm run build`, or `cargo build` + `cargo test`,
156
+ or `go vet` + `go test`, …); set `buildOutputDir` (or `null`).
157
+ 2. **`agents/`** — edit the `owns:` globs in `frontend-agent.md` / `backend-agent.md` to
158
+ match your directory layout. Copy `_TEMPLATE.md` for more roles.
159
+ 3. **`lib/detect/`** — enable the detector for your monitoring (`sentry` / `vercel` / your
160
+ own from `_template.cjs`) in `config.js → detectors`. No monitoring? Leave it empty.
161
+ 4. **`agents/deploy-gate-agent.md` + `lib/gate/`** — the gate runs `config.js →
162
+ deployCommands`; no code change needed, just review the agent doc so it matches.
163
+ 5. **`playbooks/`** — copy `_TEMPLATE.html` for each incident type you care about.
164
+ 6. **`hooks/`** — install `pre-push.sample` into your app repo's `.git/hooks/pre-push`;
165
+ schedule the 24h watch via `launchd.plist.template` (macOS) or the cron line in its comment.
166
+ 7. *(optional)* — wire a Slack bot token for start / progress / done reporting and the
167
+ `/kanban` slash command.
168
+ 8. *(optional)* — wire **Telegram** for 24h ops-from-anywhere. See the next section.
169
+
170
+ ## Ops Thread (Telegram mirror) — optional
171
+
172
+ The kanban dashboard has a right-side **Ops Thread** chat panel. Everything in it is
173
+ mirrored to a Telegram chat in both directions, so you can run 24h ops from your phone
174
+ without leaving the kanban as the source of truth.
175
+
176
+ ```
177
+ [ kanban dashboard ] [ your Telegram DM ]
178
+ Ops Thread panel ◀──── /api/ops-thread ────▶ sendMessage / getUpdates
179
+ │ │ │
180
+ └── you type ───────────┘ │
181
+ └── operator replies ──────┘
182
+ task created / completed → 📋 / ✅ posted to both sides
183
+ ```
184
+
185
+ **Setup** (~2 minutes, no PG / no external service):
186
+
187
+ 1. Open Telegram, message `@BotFather`, send `/newbot`, follow the prompts. Copy the
188
+ token you get.
189
+ 2. Send any DM to your new bot from your own Telegram account (this is what lets the
190
+ bot see you exist — Telegram won't deliver replies otherwise).
191
+ 3. Put the token + chat id in `.env`:
192
+ ```bash
193
+ TELEGRAM_BOT_TOKEN=123456:AA...your_token
194
+ TELEGRAM_CHAT_ID= # leave blank for now
195
+ ```
196
+ 4. `npm start`, then in another terminal:
197
+ ```bash
198
+ curl http://localhost:8080/api/telegram/whoami
199
+ # → { "ok": true, "chats": [ { "id": 6131488858, "type": "private", ... } ] }
200
+ ```
201
+ Copy that `id` into `TELEGRAM_CHAT_ID` in `.env`, restart `npm start`.
202
+ 5. Done — type in the Ops Thread panel and it appears in Telegram; reply in Telegram
203
+ and it shows up in the panel. Task `created` → `📋 #N <subject>`, `in_progress` →
204
+ `▶️ #N`, `completed` → `✅ #N — <one-line report>`.
205
+
206
+ **No Telegram?** Leave the env vars blank. The panel still works as a local kanban-only
207
+ chat (and as a place where the server posts task lifecycle events).
208
+
209
+ **Allowing only specific people**: set `TELEGRAM_ALLOWED_CHAT_IDS=id1,id2` to allow more
210
+ than one chat. Empty list ⇒ only `TELEGRAM_CHAT_ID` is accepted (recommended for solo ops).
211
+
212
+ **Endpoints** (you usually never call these — the UI does):
213
+ - `GET /api/ops-thread?since=<id>` — load thread (paginated by message id)
214
+ - `POST /api/ops-thread/append { role, text, taskId? }` — agents append to the thread
215
+ - `POST /api/ops-thread/send { text }` — you send (also mirrored to Telegram)
216
+ - `GET /api/telegram/status` — `{ configured, polling, chatId }`
217
+ - `GET /api/telegram/whoami` — debug: dump recent `getUpdates` so you can find a chat id
218
+
219
+ ## The kanban-first protocol
220
+
221
+ Every user instruction becomes a kanban task **before** work starts: capture it
222
+ verbatim, route it, set the `runner`, transition to `in_progress`, and only then start.
223
+ On completion, set `reportPath` + `reportSummary`. The single exception is **incident
224
+ response** — a production-impacting incident or a 1-line, obviously-reversible hotfix may
225
+ be done immediately, but a post-hoc task must be registered within 1 hour, tagged
226
+ `metadata.source = "incident-response"`. Nothing else qualifies. Rationale and the state
227
+ machine: **[docs/the-pattern.md](docs/the-pattern.md)** → "Kanban-first".
228
+
229
+ ## Multi-agent cross-validation
230
+
231
+ Pick the verification level per task via `runner`:
232
+ - **single-model** (`claude` / `codex`) — deterministic / mechanical work (running tests,
233
+ polling an API, a state transition); a second opinion only adds latency.
234
+ - **`reviewer:codex`** — Claude implements in an isolated worktree, Codex reviews the
235
+ result and can downgrade the verdict to `needs_human`. Default for implementation work.
236
+ - **`both`** — Claude *and* Codex independently do the work from the same spec, in
237
+ separate worktrees; the orchestrator diffs them. Agreement → auto-merge; disagreement →
238
+ "needs human" column. For high-stakes work (schema migrations, access-control policies,
239
+ money paths) — the disagreement is the safety feature.
240
+
241
+ The orchestrator auto-promotes single-model → `both` above a severity threshold; a daily
242
+ second-model budget caps cost. Details: **[docs/the-pattern.md](docs/the-pattern.md)** →
243
+ "Cross-validation".
244
+
245
+ ## Example: APEX
246
+
247
+ APEX is an AI-skills certification exam platform (React/Vite front end, Supabase back
248
+ end) that ran this harness in production under the codename "Sentinel": 8 generic
249
+ ops/dev agents like the ones here plus a 6-agent domain group, an `exam-engine` selvedge
250
+ boundary, a deliberately powerless "proctor" agent (detect-and-escalate, never enforce),
251
+ `runner: both` on migrations / grading prompts / credential scoring, and the
252
+ gate-before-push rule. Full write-up: **[docs/example-apex.md](docs/example-apex.md)** —
253
+ the one place project-specific domain content lives.
254
+
255
+ ## CLI reference
256
+
257
+ The `kanban-system` bin (also usable as `npx kanban-system <cmd>`):
258
+
259
+ | Command | What it does |
260
+ |---|---|
261
+ | `init <name>` | Scaffold a fresh checkout into `./<name>` (config templates + all the harness files, minus the CLI itself) |
262
+ | `start [--port N]` | Run `server/kanban.cjs`. Prefers the local checkout's server if present (so config.js / UI edits apply) |
263
+ | `watch [--once]` | Run `lib/watch/scheduler.cjs` |
264
+ | `gate` | Run `lib/gate/index.cjs` |
265
+ | `whoami` | Probe a running server's `/api/telegram/whoami` (find your Telegram chat id) |
266
+ | `--version` / `--help` | Self-explanatory |
267
+
268
+ ## License / status
269
+
270
+ MIT. Status: extracted as a domain-agnostic template + npm CLI; the pieces are present
271
+ and wired, but you'll want to exercise them against your own repo before relying on
272
+ them in production.
@@ -0,0 +1,42 @@
1
+ ---
2
+ # ── Required frontmatter ──────────────────────────────────────────────────────
3
+ name: my-agent # slug; must match the file name without .md
4
+ mission: >- # one sentence: what failure does this agent prevent?
5
+ Prevent <failure mode> in <area> by <what it does>.
6
+ runner: claude # claude | codex | both | reviewer:codex | reviewer:claude
7
+ model_default: claude-opus-4-7 # the model the runner uses by default
8
+ auto_promote_on: # optional: when to bump a single-runner task to `both`
9
+ - severity: medium
10
+ - regression_window: 30d
11
+ tools_allowed: [Read, Edit, Bash] # the tools this agent may use
12
+ worktree: isolated # isolated (own git worktree) | inline (works in place)
13
+ escalation: human # human | other-agent:<name>
14
+ owns: # globs (relative to repoPath) this agent owns —
15
+ - src/feature/** # used by the orchestrator for "which agent owns this file?"
16
+ ---
17
+
18
+ # My Agent
19
+
20
+ One paragraph: what this agent is responsible for, and what it explicitly does NOT touch.
21
+
22
+ ## Triggers
23
+ Concrete signals that create a task for this agent. Examples:
24
+ - PR touches files matching `owns`.
25
+ - A monitor detector routes an anomaly here.
26
+ - A specific incident playbook escalates to this agent.
27
+
28
+ ## Inputs
29
+ Data sources / file paths / API endpoints this agent reads.
30
+
31
+ ## Outputs
32
+ Files/reports this agent produces. Convention: `data/runs/<task-id>/report.md`.
33
+
34
+ ## Cross-validation policy
35
+ When (if ever) the second model verifies, and the decision rule when they disagree.
36
+ See docs/the-pattern.md for the three modes (`both`, `reviewer:*`, single-model).
37
+
38
+ ## Failure handling
39
+ Timeout, model unavailable, disagreement deadlock, build failure — what happens.
40
+
41
+ ## Example
42
+ One sample task lifecycle: trigger → what the agent does → output → resolution.
@@ -0,0 +1,81 @@
1
+ ---
2
+ name: backend-agent
3
+ mission: >-
4
+ Protect the server side — API handlers, database schema and migrations, access
5
+ policies, background jobs — where a bad change can corrupt or leak data.
6
+ runner: both
7
+ model_default: both
8
+ tools_allowed: [Read, Edit, Write, Bash]
9
+ worktree: isolated
10
+ escalation: human
11
+ owns:
12
+ # Edit to match YOUR layout. Examples:
13
+ # Node API: server/**, api/**, src/server/**, src/api/**
14
+ # Migrations: migrations/**, db/migrate/**, prisma/migrations/**
15
+ # Supabase: supabase/functions/**, supabase/migrations/** (one possible backend)
16
+ # Rails: app/controllers/**, app/models/**, db/migrate/**
17
+ # Go services: internal/**, cmd/**
18
+ - server/**
19
+ - api/**
20
+ - db/**
21
+ - migrations/**
22
+ - lib/**
23
+ - functions/**
24
+ ---
25
+
26
+ # Backend Agent
27
+
28
+ High-stakes territory: a bad migration or access-control rule can corrupt data or
29
+ leak it, so every change here runs cross-validated. Owns API/route handlers, the
30
+ database schema and migrations, authz/RLS-style policies, shared server utilities,
31
+ and background jobs. Does not touch the front end (that's `frontend-agent`).
32
+
33
+ > The original of this template was built for a project that used Supabase
34
+ > (Edge Functions + Postgres + RLS). Those specifics moved to `docs/example-apex.md`
35
+ > as a worked example — keep this file stack-agnostic and write your own rules below.
36
+
37
+ ## Triggers
38
+ - A PR touches files under `owns` — especially anything under a migrations path.
39
+ - A monitor detector reports a server-side anomaly (5xx burst, function timeouts,
40
+ authz-denial spike) and routes it here.
41
+ - Migration drift detected when applying to an environment.
42
+
43
+ ## Inputs
44
+ - Handler / function source.
45
+ - Migration files (forward and, ideally, backward).
46
+ - Seed data.
47
+ - A production schema snapshot (e.g. a `db dump`), so changes can be diffed against reality.
48
+
49
+ ## Outputs
50
+ - A migration plan with forward + rollback steps.
51
+ - An access-policy diff (which roles × which tables/resources change).
52
+ - `data/runs/<task-id>/migration-plan.md` and `report.md`.
53
+
54
+ ## Cross-validation policy — `runner: both`
55
+ Claude and Codex run in parallel from the same spec, independently:
56
+ - Each writes the migration / handler code on its own.
57
+ - The orchestrator diffs the two. If they produce a functionally equivalent change
58
+ (same schema delta, same policy set) → `agreed`, auto-merge.
59
+ - If they differ on *which* columns to drop, *which* policy to add, or any DDL →
60
+ `disagreed` → human review is forced. (This is by design: server-side data changes
61
+ are exactly where you want two independent reads to converge before shipping.)
62
+
63
+ Project-specific rules the cross-validation should enforce (fill these in):
64
+ - No destructive migration (`DROP COLUMN`, `DROP TABLE`) without a deprecation window.
65
+ - No access-policy change without an explicit, enumerated list of affected roles.
66
+ - No deploy without the shared CORS / auth helpers imported.
67
+ - Secrets / service-role keys never used outside the designated shared module.
68
+
69
+ ## Failure handling
70
+ - Migration applies on staging but not on the production schema → block, escalate.
71
+ - Build/deploy fails → block, log.
72
+ - Any access-control test (anonymous / authenticated / service role) fails → block.
73
+
74
+ ## Example
75
+ ```
76
+ Trigger: monitor-agent reports a 5xx spike on the payment webhook
77
+ Claude: reads logs → diagnoses a missing signature-header validation, writes the fix
78
+ Codex: reads logs independently → diagnoses the same root cause, plus suggests a rate-limit guard
79
+ Diff: agreed on root cause + fix; partial on the rate-limit (Codex extra)
80
+ Resolve: merge the fix; file a follow-up task for the rate-limit guard
81
+ ```
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: deploy-gate-agent
3
+ mission: >-
4
+ Block any push that fails type-check, build, or the chosen test/E2E suite —
5
+ the last safety net before a deploy goes out.
6
+ runner: reviewer:codex
7
+ model_default: claude-opus-4-7
8
+ tools_allowed: [Bash, Read]
9
+ worktree: inline
10
+ escalation: human
11
+ owns:
12
+ - .git/hooks/pre-push
13
+ - lib/gate/**
14
+ ---
15
+
16
+ # Deploy Gate Agent
17
+
18
+ Runs the pre-deploy verification chain (see `lib/gate/index.cjs`). It is a *hard*
19
+ gate — it cannot be bypassed without an explicit, audited override. It never edits
20
+ application code; it only runs commands and reports.
21
+
22
+ The commands it runs come from `config.js → deployCommands`, executed in order from
23
+ `config.js → repoPath`, fail-fast. Set them to whatever "this builds and the smoke
24
+ tests pass" means for your stack:
25
+
26
+ ```
27
+ Node / Vite: [{ name:"01-typecheck", cmd:"npx", args:["tsc","--noEmit"] },
28
+ { name:"02-build", cmd:"npm", args:["run","build"] }]
29
+ Rust: [{ name:"build", cmd:"cargo", args:["build","--release"] },
30
+ { name:"test", cmd:"cargo", args:["test"] }]
31
+ Go: [{ name:"vet", cmd:"go", args:["vet","./..."] },
32
+ { name:"test", cmd:"go", args:["test","./..."] }]
33
+ ```
34
+
35
+ ## Triggers
36
+ - `git push` (via the `pre-push` hook — see `hooks/pre-push.sample`).
37
+ - A manual `/gate` invocation.
38
+ - Before merging a release branch.
39
+
40
+ ## Inputs
41
+ - The git diff (HEAD vs the upstream branch).
42
+ - The commands from `config.js → deployCommands`.
43
+ - The last successful gate run (`data/runs/last-gate.json`) for bundle-delta comparison.
44
+
45
+ ## Verification chain (serial, fail-fast)
46
+ The chain is `deployCommands` in order, then an optional bundle-inspection stage
47
+ (if `config.js → buildOutputDir` is set): walks the output directory, compares total
48
+ size to the last passing run, and warns (or fails, if `STRICT_BUNDLE=1`) on a large
49
+ regression.
50
+
51
+ ## Outputs
52
+ - `data/runs/gate-<timestamp>/<stage>.log` per stage.
53
+ - `data/runs/gate-<timestamp>/report.md` — pass/fail + duration per stage.
54
+ - On failure: a kanban task is auto-created in the "needs human" column with the logs
55
+ linked (disable in CI with `GATE_NO_KANBAN=1`).
56
+
57
+ ## Cross-validation policy — `reviewer:codex`
58
+ Claude runs the gate; Codex then reviews the build output for things a green build
59
+ hides: unused exports, dynamic imports with no chunk hints, new `process.env` reads
60
+ that aren't in `.env.example`, an accidentally-bundled heavy dependency. A Codex
61
+ concern that isn't blocking the build still lets the gate pass — but it files a
62
+ follow-up cleanup task.
63
+
64
+ ## Failure handling
65
+ - A `deployCommands` stage fails → push blocked, full log saved, error returned to the
66
+ terminal with `file:line` where the tool provided it.
67
+ - Bundle-inspection warning → push allowed, follow-up task created (unless `STRICT_BUNDLE=1`).
68
+
69
+ ## Override
70
+ Only a human bypasses, via `git push --no-verify`. The `pre-push.sample` hook also
71
+ honours `KANBAN_GATE_BYPASS=1 git push`, which logs an entry to
72
+ `data/runs/overrides.jsonl` (timestamp, branch, user). Overrides are reviewed at the
73
+ daily standup.