Core

Tickets and workflow

Tickets carry a type, status, priority, labels, relationships, comments, and history. The workflow is deliberately strict: only some status edges exist, review is a real gate, and the tracker would rather refuse a move than let state drift.

Creating and editing

ticket CRUD
tracker ticket create --project APP --title "Add health check" \
  --type task --actor human:owner --reason "planned work"
tracker ticket view APP-1
tracker ticket edit APP-1 --actor human:owner --reason "retitle"
tracker ticket list --project APP --status ready
  • Types: epic, task, bug, subtask. Templates from tracker templates list can pre-fill new tickets via --template.
  • Priority, labels, and assignee have their own commands: ticket priority, ticket label add/remove, ticket assign.
  • Ticket titles are normalized before rendering: control characters and bidirectional overrides are stripped so a hostile title cannot scramble a board or a terminal.

Statuses and legal edges

Six working statuses plus two terminals. Not every move exists, and that is the point.

the edges
backlog     -> ready, blocked, canceled
ready       -> in_progress, blocked, canceled
in_progress -> in_review, ready, blocked, canceled
in_review   -> done, in_progress, blocked
blocked     -> ready, in_progress, canceled
done        -> (terminal)
canceled    -> (terminal)

backlog -> in_progress is forbidden and always will be; work goes through ready. An illegal move exits with code 4 and a clear message. That exit 4 is the workflow working, not a crash, and retrying the same move gets the same 4.

in_review and done are special: you reach them through request-review, approve, or complete rather than move, because those commands also run the completion policy and any gates. Under review_gate, reviewer approval is the final transition to done; there is no second completion command.

the review path
tracker ticket request-review APP-1 --reviewer agent:reviewer-1 \
  --actor agent:builder-1 --reason "ready for review"
tracker ticket approve APP-1 --actor agent:reviewer-1 --reason "review passed"
tracker ticket reject APP-1 --reason "tests missing" --actor agent:reviewer-1

request-review opens or reuses a review gate, so gate list, approvals, and inbox show the pending review explicitly. When --reviewer is omitted, Atlas uses the ticket reviewer or the effective project, epic, or ticket required_reviewer. Use ticket complete for open-mode work or policies whose separate required gates have passed; it cannot bypass the request-review and approval lifecycle.

Claims and leases

A claim is a lease that keeps two workers off the same ticket. Claim before you touch code.

lease lifecycle
tracker ticket claim APP-1 --actor agent:builder-1 --reason "start work"
tracker ticket heartbeat APP-1 --actor agent:builder-1
tracker ticket release APP-1 --actor agent:builder-1 --reason "handing back"

Claiming a ticket someone else holds is exit 4, not a queue. When the queue and a ticket seem to disagree, tracker inspect APP-1 --actor agent:builder-1 answers "why can't I move this" in one call: policy, lease, queue position, and history together.

Dependencies

linking work
  • blocked_by is enforced for unsafe progress: moving to in_progress or in_review, approval, and completion are rejected while any blocker is unresolved.
  • Only done unblocks dependents. A canceled blocker does not, on purpose.
  • human:owner can push through with --override-deps --reason "...". The event records a dependency_override payload naming the unresolved blockers, so the shortcut is visible forever.

Comments and history

the durable trace
tracker ticket comment APP-1 --body "retry logic now exponential" \
  --actor agent:builder-1 --reason "progress note"
tracker ticket history APP-1 --json

History is the append-only event stream rendered for one ticket: every move, claim, comment, gate decision, and override, each with its actor and reason.

Bulk operations

Grooming sessions get real tooling instead of a shell loop.

preview, then apply
tracker bulk move ready --ticket APP-3 --ticket APP-4 --dry-run --actor human:owner
tracker bulk move ready --ticket APP-3 --ticket APP-4 --yes \
  --actor human:owner --reason "sprint planning"
tracker bulk assign agent:builder-1 --view sprint-42 --yes \
  --actor human:owner --reason "assign sprint"
  • --dry-run previews without mutating; live batches require --yes.
  • --view expands a saved view into ticket IDs in the view's own order; duplicates are removed.
  • Every committed per-ticket event carries the same metadata.batch_id, so a batch is auditable as a unit.
  • bulk covers move, assign, request-review, complete, claim, and release.

Archiving is soft: tracker ticket archive removes a ticket from active views while the file and history stay in the repo. ticket delete survives as a compatibility alias for the same thing.