All docs/agent-coordination

docs/architecture/kanban-task-claiming.md

Kanban Task Claiming — Architecture

Problem

When multiple Claude agents run concurrently (nightly workers, on-demand agents, CI-triggered agents), they may pick up the same kanban task from the backlog. Without a locking mechanism, two agents can start implementing the same task simultaneously, wasting compute and creating merge conflicts.

Solution

A claim API on the kanban app that atomically marks a task as "In Progress" on the main branch via the GitHub REST API. Agents call a one-liner CLI script before starting work.

Flow (Step by Step)

Components

API Route — POST /api/tasks/[id]/claim

Location: apps/kanban/app/api/tasks/[id]/claim/route.ts

Runs on Vercel — no git CLI, no filesystem. All operations use the GitHub REST API via fetch.

StepGitHub API CallPurpose
1GET /repos/{repo}/contents/{path}Read task file from main
2Parse frontmatterValidate status is claimable
3GET /repos/{repo}/git/ref/heads/mainGet base SHA for branching
4POST /repos/{repo}/git/refsCreate claim branch
5PUT /repos/{repo}/contents/{path}Commit updated file to branch
6POST /repos/{repo}/pullsOpen PR
7POST /repos/{repo}/issues/{n}/labelsAdd skip-deploy + auto-merge

Responses:

StatusMeaning
200Claimed successfully — { ok, taskId, branch, prUrl }
400Invalid task ID (must be [a-z0-9][a-z0-9-]*)
404Task file not found in repo
409Already claimed (In Progress) or Done/Archived
502GitHub API error
503GITHUB_TOKEN not configured

CLI Script — scripts/llm/claim-task.ts

Location: scripts/llm/claim-task.ts

Thin wrapper that calls the API. This is what agents run.

# Basic claim
pnpm tsx scripts/llm/claim-task.ts fix-video-upload-bug

# With assignee (recorded in task frontmatter)
pnpm tsx scripts/llm/claim-task.ts fix-video-upload-bug --assignee "agent-session-xyz"

# Dry run (shows what would happen)
pnpm tsx scripts/llm/claim-task.ts fix-video-upload-bug --dry-run

Exit codes:

  • 0 — Claimed successfully, OR already claimed (409 is not an error — the task is locked either way)
  • 1 — Actual failure (network, auth, task not found)

Override URL: Set KANBAN_API_URL env var to point to a local dev server instead of production.

CI Integration

The claim flow relies on two existing CI mechanisms:

  1. [skip-deploy] in commit messagedetect-changes.ts sees this and skips all Vercel/GCP deployments
  2. auto-merge labelauto-merge-eligible.yml workflow detects that the PR only changes .kanbn/tasks/*.md files (matches the kanban-tasks pattern) and merges the PR automatically

No new CI configuration is needed.

Environment Requirements

Env VarWherePurpose
GITHUB_TOKENVercel (kanban app)PAT or fine-grained token with contents:write + pull_requests:write
GITHUB_REPOSITORYVercel (auto-detected)owner/repo format — auto-detected from VERCEL_GIT_REPO_OWNER/VERCEL_GIT_REPO_SLUG, falls back to happy-client/happyclient-monorepo
KANBAN_API_URLAgent shell (optional)Override API URL for local development

Race Condition Handling

If two agents try to claim the same task simultaneously:

  1. Both read the file from main → both see status is "Ready"
  2. Both create branches and commits → both succeed (different branch names)
  3. Both create PRs → both succeed
  4. First PR merges → status on main is now "In Progress"
  5. Second PR has a merge conflict on the same file → auto-merge fails, PR stays open harmlessly

The window for this race is small (seconds). In practice, the first agent to call the API wins. The second agent's PR will simply fail to merge and can be cleaned up by nightly hygiene.

File Changes Summary

FileChange
apps/kanban/app/api/tasks/[id]/claim/route.tsNew API route (GitHub REST API)
apps/kanban/lib/env.tsAdded GITHUB_TOKEN, GITHUB_REPOSITORY
scripts/llm/claim-task.tsNew CLI script for agents
CLAUDE.mdUpdated Kanban Task Lifecycle section