The governance layer for agentic delivery.
IssueFlow provides the rails — gates, routing, recovery, and audit — around the agents you already use. Here is what that looks like end to end.
Full-lifecycle triage
IssueFlow starts where the work actually starts — a messy report. It reproduces the issue, root-causes it, and decomposes it into concrete tasks. A target allowlist keeps agents from misfiling or hallucinating a repo, and a source issue only closes once every child task is terminalized.
Design-first human gates
Gating at the pull request is low-leverage busywork; once an agent has a validated spec, it follows it well. Place the human gate at design instead, and catch architectural errors before a line of code exists. Approve or reject from the portal — or straight from a GitHub comment with [hr:go] / [hr:fail].
Bring your own agent, per stage
IssueFlow bundles no agent, no LLM, and no fixed prompts. You declare the frameworks available on each worker and assign one to each stage — Claude Code, Copilot, Cursor, or your own. The engine composes each prompt from your charter plus execution context; it never dictates content.
A self-healing supervisor
Hand-rolled loops are fragile. A reconciler continuously checks every run against invariants, recovers lost, stale, or displaced workers, and re-queues attempts — without you watching a terminal. This is infrastructure recovery, not an agent guessing at fixes.
Failure-aware routing
Every stage emits an outcome, and a failure carries a reason. You route on that reason — send a failed validation to a remediation stage, a design error somewhere else — with attempt limits and escalation. Routing fails closed to a catch-all rather than stranding an issue.
Your infrastructure, your audit trail
Workers are self-hosted — your code and agent runs never leave your machines. Every command and event is stamped with the acting user for a full audit trail, and the entire operator surface is available from the portal, an MCP tool, or a GitHub comment.
It all lives in your workflow config.

IssueFlow is GitHub-native today; the engine is built in a modular way so other source-control and project-management adapters can follow, but only the GitHub adapter exists right now. Workers are self-hosted by design — there is no managed fleet — so your code and keys stay with you. We'd rather tell you what a feature does today than what it might do someday.
The full inventory.
For the evaluator who wants to find the one capability that decides it. Everything below ships today and is dogfooded on IssueFlow's own repo — anything still hardening is marked as such.
Configure everything
The workflow, the gates, the routing, the agents — all yours to define.
Configurable workflow
Name your own stages; the engine runs whatever pipeline you draw — no fixed template.
Define a solution once; override only what differs per repo or stage. No config sprawl.
solution.yaml / repo.yaml / workstation.yaml, joined by a slug — what to build / where / on what machine.
Each stage carries its own config blob (agent, model, prompt, tools, env) the engine passes through untouched.
The graph is checked before it runs — valid targets, no orphans or dead-ends. Errors surface at load, never mid-run.
A .issueflow push or portal edit rebuilds config in place; solutions pick it up in seconds — no engine bounce.
Configurable human gates
A human gate can sit at any stage boundary — the design gate before build is the flagship placement.
Resolve a gate straight from a GitHub comment (hr:go / hr:fail) — human- or agent-resolve, no portal round-trip.
“Blocked” is a hold on a run an operator resolves directly at any time — it never needs the ladder to reach a human first.
A working agent can pause, pose a question, and suspend without an outcome; the stage re-runs with the durable Q&A injected.
An escalation can present an ordered option/tradeoff menu rendered as a real decision, not a free-text guess.
Ask a read-only consult agent about a parked run before committing a routing decision — multi-turn, zero state change.
Configure exactly which GitHub logins may drive a solution's control verbs. Fails closed if unset.
Multi-dimension routing
“How execution went” is separated from “what the work decided,” so an agent crash is never misread as a real failure verdict.
Declare your own routing vocabulary (needs-info, blocked, no-change-required…) above the pass/fail layer.
Route on per-solution dimensions (lane, priority, issue-type, anything) extracted from prefixed labels.
Route by outcome, fail-reason, and per-dimension conditions — failing closed to a catch-all rather than stranding a run.
done / previous / escalate / resolved-without-merge — terminal and control directives, not just next-stage pointers.
A stage can be told exactly which branch to work from.
Routing writes an explicit next-stage cursor; dispatch never re-computes “where was this run?” — kills resumption bugs.
Framework & model agnostic
Every framework — Claude Code, Copilot, Cursor, any process tool, or a human — plugs into one uniform contract.
Your subscriptions and LLM keys run the work; model is a per-stage parameter, mixable across the pipeline.
A stage can be an automated agent, a scripted process, or a human step — all first-class.
Per-workstation launcher templates; a typo is a typed refusal at boot, never a silent per-issue decline.
Agents launch from a constructed env allowlist; code-mode launches strip SCM write credentials — defense against rogue self-publish.
Each stage's agent gets exactly the tools, MCP servers, and env it's granted — nothing more.
Every stage has its own editable charter, system prompt, and permission set — canonical or per-repo override.
The merge/PR step runs as its own launched process, keeping the worker domain-free.
Full-lifecycle intake
A whole-solution triage stage reads an unclear report and spawns concrete component issues in the right repos.
Every decomposition target is validated against declared repos; a hallucinated target is rejected loudly, never mis-filed.
Decomposed children inherit the parent's routing directives, so they route in the parent's context.
The source issue closes only once every child terminalizes; a child that fails escalates the source instead of a half-done close.
Each child is claimed on a unique engine-side row, so an at-least-once retry never duplicates issues.
Close an issue as genuinely “nothing to do” (duplicate / already fixed) — distinct from a real merge and from a give-up.
Govern & control
Trustworthy, not autonomous — every run is gated, resolvable, and auditable.
Escalation & the human floor
Declare an ordered ladder of resolvers (worker → process → human), each with its own attempt bounds; safe default if unset.
An exhausted level advances to the next and actively dispatches it — a worker-to-worker ladder never freezes.
Reaching a human level converts the blocked hold to a gate a person resolves via verbs — idempotent and crash-self-healing.
The human handoff carries the actual failure reason + resolver verdict, not a bare escalation-level label.
Operator control
Pause, resume, restage, cancel, restart, set-status, respond, ask, admit, escalate, set-priority, drain, evacuate, and more.
Every operator action exposed as an MCP tool for IDE/agent use; a bad call returns a structured error, never a crash.
Every call mints a fresh client token, so a retried call collapses through the bus's dedup key.
Re-stage picks from the issue's own workflow stages, so a typo can't produce an invalid restage.
Control center (portal)
Hold-state pills, per-row actions, group/sort/filter that persist across reloads.
Current stage/status/outcome, prominent hold, full event trail, attempts, and every maintain-action.
Every run whose hold is human-owned, with the question/reason inline and one-click resolve.
Every live blocked hold with reason, evidence, and its server-driven applicable actions — nothing invented client-side.
ELK layered graph, drag-to-rearrange, fanned parallel edges, persisted node layout.
Edit a stage's routing (outcome / fail-reason / directive / when: → target) from the designer's inspector.
Register solutions and edit dimensions, fail-reasons, ladder, admission order, repo settings, charters — no raw YAML.
Create and immediately start an issue without waiting on a webhook.
KPI cards + breakdowns by outcome / status / stage / failure-category over the run event trail.
Ownership & audit
A thin worker owns all git/worktree/publish plumbing; your code and agents run on your machines, engine stays hosted.
Every command/event stamped with the acting user for a real audit trail.
Authenticate as one or many GitHub Apps, resolved per repo-owner, with PAT fallback and a loud failure on an uncovered owner.
An IdentityProvider port with a GitHub OAuth adapter and CSRF-safe login, mounted only when configured.
Reliability & recovery
The self-healing supervisor that makes “just build it myself” irrational.
Self-healing engine
A continuous supervisor classifies every run against invariants and emits the cheapest corrective command.
Reclaims an in-flight attempt whose worker died or was replaced and re-queues it — without charging the issue's failure bounds.
A run blocked for lack of a capable worker auto-requeues the moment a matching worker rejoins — no human nudge.
Escalates a run whose attempt/rework/decline counters exceed limits, with a loud alert on repeated launch failures.
Kills an attempt that blew its execution-time ceiling; a wedged agent can't run forever.
A human/supervised stage gone silent is reclaimed and escalated to a person, never headlessly re-dispatched.
Reuse the pinned workstation + worktree when possible, rebuild from SCM if not, start over only when state is unrecoverable.
An unresolvable route lands a blocked hold with a config-error reason, never a silent skip-loop.
Repairs structural inconsistencies (a running attempt on a terminal run) by re-queuing or fixing pointers.
Each rule's command is deduped per run+occurrence, so the same violation across ticks acts exactly once.
Raises a system-wide stall incident — but suppresses it when a degraded dependency (a real outage) is the cause.
Fleet liveness & crash safety
A long run keeps its lease fresh from side threads, so a healthy 12–18 min stage is never wrongly reclaimed.
Session-activity liveness terminates a framework that stopped making progress rather than hanging forever.
Drain a worker so it finishes current work then exits when idle — without yanking running stages.
On a displacement signal the old daemon cancels, drains, and reclaims its own in-flight work to the replacement.
A run-state-aware reaper reclaims leaked worktrees and stray branches after crashes, failing safe toward KEEP.
Catches C-level fatal signals (SIGSEGV/SIGABRT) and dumps every thread's stack — the one mode no Python exit path sees.
Capped-backoff retry on connection/timeout/5xx, escalating a sustained outage instead of retrying silently forever.
Ingest & health
GitHub deliveries are persisted and acked immediately, then drained idempotently — nothing is lost on a restart.
Only issues deliberately given the onboarding label are tracked; add/remove is a clean on/off switch.
Returns 503 on a migration mismatch that freezes the reconciler, so a load balancer sees a frozen engine as unhealthy.
No hold interrupts a live attempt; the stage runs to its boundary and the hold takes effect there.
On resume, the already-computed routing decision is applied verbatim without re-running routing.
Scale & orchestration
Multi-repo, multi-worker, multi-tenant — with dependencies and epics.
Cross-issue orchestration
New runs for a gated solution park un-claimable until an orchestrator admits them — stage work in before it consumes workers.
A priority spec (lane → priority → issue-type) decides which claimable run a free worker gets first; FIFO as tiebreak.
An issue depends_on others and parks until every prerequisite succeeds; never runs past a failed prerequisite.
Rejects an edge that would create a cycle or self-loop — no silently unusable dependency that strands a run.
Cap how many runs of a semantic group (e.g. same code-area) run at once; excess park and release by priority-then-age.
Every transition back into the queue re-evaluates dependency + concurrency, so a release can't sneak past its cap.
A standing sweep releases holds whose constraints cleared and escalates ones that never can.
Epic management
A passing epic stage spawns child issues, links them to the parent, and starts each child's run.
The epic parks waiting-on-children and auto-advances into doc → merge → e2e → cleanup once every child terminalizes.
The parent advances only once all expected children have actually materialized — closes zero-children and partial races.
Epic children inherit the parent's run-branch and truncate their routing (same-repo epic model).
A child-creation failure escalates and retries, reusing already-created children — no silent loss.
Fleet & tenancy
Many concurrent worker machines, each declaring which solutions and frameworks it serves; dispatch goes only to a capable one.
One worker serves multiple solutions and resolves each solution's canonical + member repos from a registration manifest.
A bounded thread pool runs up to max_concurrency claim/build/execute/report cycles at once per worker.
Every run gets its own git worktree, so concurrent stages never collide on working state.
Only an alive, capable worker with free capacity is matched; no match = WAIT, never a lost issue.
A TenantContext stamps tenant_id on every command/event and scopes every read/write; the domain stays tenant-agnostic.
Orchestration work (Orchestrator, Blocker-Resolver) runs as first-class runs sharing one state machine and recovery path.
Depth & learning
The operational long tail — and the parts still hardening, marked honestly.
Operational depth
Map complexity to a small/medium/large model per stage; spend the expensive model only where it pays.
Named agent identities carried across stages.
Stages designed to pause for human input as their normal mode.
Stages triggered by solution-level events, not just the linear issue flow.
All external side effects run as idempotent outbox effects, so retries converge without duplication.
Internal states project onto a human vocabulary (PENDING/READY/IN_PROGRESS/WAITING/COMPLETED/CANCELLED), mirrored to the PM tool.
Every finished run is tagged SUCCESS / REJECTED / CANCELLED / RESTARTED / RESOLVED — “shipped it” vs “gave up” vs “nothing to do.”
Routing back to an iteration stage advances a rework counter the breaker watches.
worker workspaces list / prune (dry-run default) to inspect and clean isolated worker workspaces.
register / claim / heartbeat / progress / complete / drain / orphan-check / advisory — the full fleet control plane.
The entire portal config editor is also a REST API — everything the UI does, scriptable.
IssueFlow builds itself through itself — the strongest possible reliability demonstration.
In hardening
A human's resolution can propose a durable, context-scoped learning future agents match against.
Recorded lessons are scored by stage + dimensions + keywords to enrich agent charters.