Skip to content

Pipeline States

Every Colony issue is in exactly one state at any given time. The state determines what work happens next and which executor type will claim it. For a conceptual introduction, see Core Concepts — States. This page covers the complete state machine: all 15 states, forward progression, every backward loop, pause/resume rules, the canonical diagram, and the per-executor transition constraints.


StateLabelDescription
unlabeled(none)Issue exists but Colony hasn’t picked it up yet
newcolony:newMayor has ingested the issue and enqueued an analyze task
planningcolony:planningPlanner agent is decomposing an epic-scale issue into subtasks
analyzingcolony:analyzingAnalyzer agent is triaging the issue (complexity, labels, plan)
needs-clarificationcolony:needs-clarificationAnalyzer found ambiguity — waiting for the issue author to respond
ready-for-devcolony:ready-for-devAnalysis complete; the developer agent picks up issues here and implements them
dependency-blockedcolony:dependency-blockedIssue depends on another issue that isn’t done yet
failure-blockedcolony:failure-blockedFailure or operator-intervention block — needs explicit /colony:retry to resume
changes-requestedcolony:changes-requestedReviewer requested changes — re-queued for the developer agent
in-reviewcolony:in-reviewReviewer agent is checking the PR
merge-pendingcolony:merge-pendingMerger agent is rebasing and merging the PR
human-review-readycolony:human-review-readyPR passed automated review — waiting for a human approver
waiting-for-subtaskscolony:waiting-for-subtasksEpic parent is waiting for child issues to complete
donecolony:doneIssue is complete and the PR has been merged
pausedcolony:pausedAn operator manually paused the issue

The happy path moves left-to-right through ISSUE_STATE_ORDER:

unlabeled → new → planning → analyzing → needs-clarification → ready-for-dev
→ dependency-blocked → failure-blocked → changes-requested → in-review
→ merge-pending → human-review-ready → waiting-for-subtasks → done

Any transition where the target state appears later in this order than the current state is automatically valid.

paused is a side-state and is not part of the linear order.

Both states are blocked (is_blocked = true) but have different lifecycles:

  • dependency-blocked — issue is waiting on a known relationship (depends_on edges, file overlap with another in-flight PR). Mayor auto-unblocks it as soon as the dependency resolves.
  • failure-blocked — issue hit a failure or operator-intervention block (build failure, cost cap, exhausted retries, parse failure, review-cycle limit, identical repeated failure, manual block). Mayor will not auto-unblock; an operator must investigate and run /colony:retry (or another slash command) to resume.

The state machine defines 24 explicit backward loop exceptions for real-world scenarios like review cycles, dependency races, and scope overflow.

FromToWhy
in-reviewchanges-requestedReviewer found issues with the PR
merge-pendingin-reviewRebase failed or PR not yet approved — return to reviewer
FromToWhy
in-reviewready-for-devNo open PR found — re-queue for development
merge-pendingready-for-devClose PR, fresh start from ready-for-dev
human-review-readyready-for-devPR closed without merge — return to development queue
dependency-blockedready-for-devDependencies resolved — return to development queue
failure-blockedready-for-devOperator unblocked the failure — return to development queue (also targets analyzing / planning / new / in-review / changes-requested / merge-pending depending on blockedFromState)
FromToWhy
needs-clarificationanalyzingAuthor responded — re-run analysis
changes-requestedanalyzingOperator-triggered full restart
human-review-readyanalyzingOperator-triggered full restart
in-reviewanalyzingOperator-triggered full restart
ready-for-devanalyzingDeveloper escalates issue back to analyzer for re-triage
merge-pendinganalyzingClose PR, re-analyze against current main
FromToWhy
analyzingnewReset prematurely analyzed issue (dependency recovery)
needs-clarificationnewReset prematurely analyzed issue (dependency recovery)
ready-for-devdependency-blockedMayor detected a dependency race while developer is active
ready-for-devfailure-blockedBuild failure, cost cap, exhausted retries, or other non-dependency block
ready-for-devnewScope-overflow auto-routing back to New for decomposition
changes-requestednewScope-overflow auto-routing back to New
ready-for-devplanningScope-overflow direct-to-planning for decomposition
changes-requestedplanningScope-overflow direct-to-planning
FromToWhy
needs-clarificationplanningEpic SI routing for epic-scale self-improvement issues
analyzingplanningAnalyzer escalates epic-scale issues to Planner
human-review-readymerge-pendingMayor detects PR became dirty — send to merger

Any issue in a “pauseable” state can be paused by an operator.

Pauseable states: planning, analyzing, ready-for-dev, changes-requested, in-review, merge-pending

  • Pause: Any pauseable state → paused (valid)
  • Resume: paused → any state except paused and unlabeled (valid)

stateDiagram-v2
direction LR
unlabeled --> new
new --> planning
new --> analyzing
planning --> analyzing
analyzing --> needs_clarification : needs info
analyzing --> ready_for_dev : ready
analyzing --> planning : epic escalation
analyzing --> new : dependency reset
needs_clarification --> analyzing : author responded
needs_clarification --> new : dependency reset
needs_clarification --> planning : epic SI routing
ready_for_dev --> dependency_blocked
ready_for_dev --> failure_blocked : failure block
ready_for_dev --> in_review
ready_for_dev --> analyzing : re-analyze
ready_for_dev --> new : scope overflow
ready_for_dev --> planning : scope overflow
dependency_blocked --> ready_for_dev : deps resolved
failure_blocked --> ready_for_dev : operator retry
failure_blocked --> analyzing : operator retry
failure_blocked --> planning : operator retry
changes_requested --> in_review
changes_requested --> analyzing : full restart
changes_requested --> failure_blocked : failure block
changes_requested --> new : scope overflow
changes_requested --> planning : scope overflow
in_review --> human_review_ready
in_review --> changes_requested : changes needed
in_review --> merge_pending
in_review --> ready_for_dev : no PR found
in_review --> analyzing : full restart
in_review --> failure_blocked : failure block
merge_pending --> done
merge_pending --> in_review : rebase failed
merge_pending --> ready_for_dev : reimplement
merge_pending --> analyzing : re-analyze
merge_pending --> failure_blocked : auto-merge exhausted
human_review_ready --> done
human_review_ready --> merge_pending : PR dirty
human_review_ready --> ready_for_dev : PR closed
human_review_ready --> analyzing : full restart
human_review_ready --> failure_blocked : failure block
waiting_for_subtasks --> done
state "paused" as paused
planning --> paused
analyzing --> paused
ready_for_dev --> paused
changes_requested --> paused
in_review --> paused
merge_pending --> paused

State identifiers in the diagram use underscores (a Mermaid requirement). The actual GitHub labels use hyphens — for example, colony:ready-for-dev, colony:changes-requested.


Each executor type may only request specific target states. Requesting any other state fails validation and moves the issue to failure-blocked.

TransitionMeaning
ReadyForDevAnalysis complete, issue is ready for development
NeedsClarificationIssue is ambiguous, needs author input

The developer executor runs on issues in ready-for-dev (initial implementation) and changes-requested (applying reviewer feedback). In both cases the executor opens or updates a PR and transitions to in-review on success.

TransitionMeaning
InReviewImplementation complete, ready for review
NeedsClarificationCannot implement without more information
TransitionMeaning
HumanReviewReadyAutomated review passed, ready for human approval
ChangesRequestedPR has issues that need fixing
TransitionMeaning
DonePR merged successfully
TransitionMeaning
ReadyForDevPlanning complete, issue is ready for development
WaitingForSubtasksEpic decomposed into child issues

If an executor returns a requestedTransition that doesn’t match its task type or names an invalid state, the Worker throws a validation error:

  1. A comment is posted on the GitHub issue explaining the invalid result.
  2. The issue is moved to failure-blocked.
  3. The colony:needs-human label is added.
  4. The Worker throws a Blocked: error — the task is not retried.

Transition validity is workflow-snapshot-relative — there is no static isValidTransition() export in @runcolony/sdk. Instead, call allowedTransitionsForState(snapshot, state), which returns the precomputed set of reachable target states for a given state from a WorkflowSnapshot. Check membership with .includes():

import type { WorkflowSnapshot } from '@runcolony/sdk';
import { IssueState, allowedTransitionsForState } from '@runcolony/sdk';
// snapshot is the WorkflowSnapshot for this repo's active workflow,
// provided by the framework at task dispatch time.
const target = IssueState.InReview;
if (allowedTransitionsForState(snapshot, IssueState.ReadyForDev).includes(target)) {
return { outcome: 'success' };
}