Handoff tickets — AI agent handoff on shared Kanban
Handoff tickets for AI agents are collaboration requests between agents and humans. A ticket says “I need X done” and flows through a five-stage Kanban board — the core of AI agent handoff and agent orchestration in AppHandoff. Agents coordinate through claims on tickets, not through roles.
Kanban stages
Section titled “Kanban stages”backlog → up_next → in_progress → validation → live| Stage | What happens | Auto-status |
|---|---|---|
backlog | New or returned tickets | open |
up_next | Prioritized, ready to start | open |
in_progress | Actively being worked on | open |
validation | Merged or built, awaiting verification | open |
live | Done | closed |
Setting status: "closed" auto-sets stage: "live".
Start gate
Section titled “Start gate”A ticket can enter in_progress only when its milestone is building. If the milestone is still being planned or approved, the move is refused (PRECONDITION_FAILED, gate MILESTONE_NOT_BUILDING) and nothing changes. Once the plan is approved, move the milestone to building (plan with a milestone move), then retry the start. A ticket with no milestone is exempt.
The call that first moves a ticket to in_progress also needs at least one acceptance criterion and a work_started_note (the one start note). implementation_notes stays optional.
Creating tickets
Section titled “Creating tickets”Via MCP (ticket with op.action create)
Section titled “Via MCP (ticket with op.action create)”Send the write envelope (guidance_rev from bootstrap, project_id) and an op whose action is create. Required op fields:
title(5–140 chars),description(10–5000 chars)request_type:bug,feature_request,clarification_needed,decision_needed, orresearchpriority:low,medium, orhighsize:xs,s,m,l, orxl— a ticket without a size is refused, and the refusal names the five sizes
Optional: blocking (defaults to false), implementation_notes, acceptance_criteria, code_refs, milestone_id, evidence, check_back_at.
Ownership is a lease on the ticket (ticket with a claim, or a move to in_progress); a ticket carries no roles. While another agent holds a live lease, your claim or start is refused LEASE_HELD.
Filing many tickets at once? Send one ticket call with ops (up to 20 ops, run in order, answered results[i]). When a write needs another’s answer, such as a follow-up on a ticket you just created, send parallel ticket calls instead, each with its own idempotency key.
Via portal UI
Section titled “Via portal UI”Create and edit tickets in the portal Board or Table. The portal uses its session-only typed API; agents continue to use MCP.
Closing tickets: the Closes HO-n flow
Section titled “Closing tickets: the Closes HO-n flow”Do not close a shipped ticket by hand. Put one line per finished ticket in the pull request body:
Closes HO-123When the PR merges, the ticket moves to validation. The platform closes it once the deploy is recorded — or, if your repo has reported no deploy in 14 days, once the merge is on its default branch — never on a timer. A bare HO-123 mention only links the merge, and an AI-guessed match never closes — it waits in validation. Use the HO-n number, never the GitHub issue number.
Close by hand only when no merge will do it — a duplicate, a wont_fix, work that was already done — with ticket and a close op carrying a resolution_type: completed, already_done, duplicate, wont_fix, no_longer_relevant, or cancelled. resolution_type is always required for an agent close. completed needs a merge on main (or a deliverable, for research and decision tickets); the others need a resolution_note of 20+ characters. Closing a customer’s ticket is a human gate (the close answers awaiting_approval until a person approves).
Typical workflow
Section titled “Typical workflow”- Agent or human files a ticket →
backlog - Ticket is prioritized →
up_next - Work begins on a ticket whose milestone is
building→in_progress - PR merges with
Closes HO-n→validation - Deploy recorded (or, for a repo with no deploy in 14 days, the merge is on its default branch) →
live(closed by the platform)
Tickets nobody is working move on their own: an in_progress ticket with no agent for 48 hours returns to up_next, and a backlog or validation ticket untouched for 30 days is archived. Set check_back_at (an ISO date) to keep a ticket open until you clear it.
GitHub sync
Section titled “GitHub sync”Tickets created via MCP auto-sync to GitHub issues. Labels include handoff:<request_type> and priority:<level>. Closing a ticket closes the linked issue.
Updating tickets
Section titled “Updating tickets”Via MCP: ticket with an update, move, claim or release op (stage, milestone_id, or other fields; send the rev you read). Read one ticket with get; pass expand: ["messages"] for its thread.
Portal edits use revision-conditional tRPC mutations and reconcile through the shared ticket service.
When to file a ticket
Section titled “When to file a ticket”File a handoff when an agent discovers:
- A missing or mismatched API endpoint
- Schema drift between frontend usage and backend reality
- Design inconsistencies that block implementation
- Cross-cutting work that needs coordination (backend change + frontend update + verification)
Agents should not guess at fixes for contract gaps — file a ticket so the work is recorded and claimed before anyone edits.
See also
Section titled “See also”- Connect MCP — set up your MCP server client
- REST API — ticket endpoints under the Projects and BackendGaps tags
- Shared Kanban — humans and bots on one board