Skip to main content
Experimental version.This is the latest in-development version of AI-Implement. Features may change without notice and behavior is not guaranteed. Switch to the latest stable version here.
The admin UI at /admin is the control panel for your AI-Implement orchestrator. It is enabled when either ADMIN_ACCESS_CODE or a sign-in provider is configured — with neither, the UI is disabled and all /admin and /api/* routes return 503, with a response body naming the missing configuration. Every panel below is also reachable programmatically through the JSON API at the bottom of this page. The sidebar organizes panels into groups:
  • Work — Overview, Issues, Pipelines, Pull requests, Blockers, Reports, Knowledge Graph Pipelines
  • Configure — Projects, Pipelines & steps, Models & providers, Triggers & channels, Policies & risk
  • Platform — Runners, Sessions, Deployments, Reaper, Access, Secrets, Settings
  • Developer — Webhooks, Audit log, Customizations, Updates
Some are placeholders for planned functionality and have no section below:
  • Triggers & channels
  • Policies & risk
  • Webhooks
  • Updates.
Opening one tells you which panel does that job today.
These panels are live but not yet documented in full here:
  • Deployments — release a new version of the orchestrator itself: whether an update is available against the running build, the last deploy’s outcome, and a self-deploy that pauses new dispatch until in-flight work drains.
  • Access — control who may sign in to the orchestrator and at what role: manage the allowlist of emails and domains, set admin-versus-user roles, choose which panels ordinary users may open, and review recent access changes.
The headings below follow the sidebar order, covering the panels that have a section of their own.

Work

Overview

The main dashboard. Shows real-time orchestrator health:
  • Running jobs (with duration)
  • Failed jobs in the last 24 hours
  • Capacity utilization across all projects
  • Projects at concurrency cap
  • Stale workflow templates in target repos
  • A 24-hour dispatch trend chart
Environment-status checks (ticketing connection, runner callback, gap-fill trigger) appear here too — this is the first place to look if a run hasn’t dispatched as expected.

Issues

The AI-Implement inbox. Shows every issue matched by the configured project mappings, its current state (started / completed / cancelled), and whether each is ready for implementation or still has planning pending. A second table breaks down in-progress counts by project mapping for real-time visibility into which scopes are currently working.

Pipelines (jobs)

The dispatch log under its real internal name (jobs in the sidebar). Shows dispatch entries (timestamped) across all teams with full execution history:
  • Issue ID
  • Repo
  • Team (the teamKey shown in the row)
  • Runner mode (GitHub Actions or Fly Machines)
  • Session image
  • Combined planning-and-implementation statuses
  • Pull-request links
  • Dispatch number (for re-dispatches)
Planning and implementation dispatches for the same issue are grouped visually as a single job. Unfiltered, the panel shows the most recent 100 entries. Applying a time-range filter narrows the view to a chosen window, but shows the full retained history during that window rather than the newest 100.
Use this log to audit activity or diagnose why an issue was or was not picked up.
The log retains only the most recent 500 dispatches. Older entries are deleted permanently, so no filter will surface them.

Pull requests

Lists every bot-opened pull request the orchestrator is tracking, with the following information:
  • Issue link
  • Repo
  • Current job status (running / completed / failed / review_failed / timed_out)
  • Iteration count (the dispatch number)
  • Time since last dispatch
  • Direct links to GitHub
Useful for spotting PRs that are stalled or failing review without scanning each repo individually.

Blockers

Surfaces issues that are currently not being picked up despite being eligible. KPI cards show:
  • Total blocked issues
  • Teams affected (distinct teams with at least one blocked issue)
  • Count blocked by concurrency cap
  • Count blocked by dedup window
Per-issue rows include:
  • Issue identifier
  • Project mapping
  • Blocking reason
  • Detail (further context on the blocking reason)
  • Direct link back to the ticket

Reports

Fleet-wide outcome analytics across every tracked repository, over a window you choose — the last 7, 30, or 90 days, defaulting to 30. Each card settles a different fleet-level question:
  • Fleet by repo — how repositories compare on throughput, completions, failures, merges, and cost, a row apiece.
  • Outcomes — how cleanly work lands: how often it is approved on the first dispatch versus eventually, and how often merged work needed a human edit afterward (the escape rate).
  • Planning A/B — whether planning pays for itself, setting issues that went through planning against those that did not on the same outcome and cost measures.
  • Runaways — which issues are consuming dispatches without landing: those with three or more dispatches, or three or more consecutive failures.
The Cost (USD) column, and the average cost in the Planning A/B card, are estimates computed from token usage at list prices — not billed spend. The estimate counts every model invocation a run makes: its implementation and review passes alike, including retried attempts and the review that runs after changes are pushed.
The figure takes no account of how a run authenticated, so a subscription-authenticated run that bills nothing per run still reports a cost here.

Knowledge Graph Pipelines

Everything about refreshing the orchestrator’s knowledge graph, in one place. Admins only — this panel cannot be granted to users, because it starts refreshes. The Knowledge graph card shows:
  • The refresh stage (checking, running, landing, staging, serving, reverted, failed, degraded, or stale)
  • The served graph stamp, and whether the knowledge-graph sidecar is answering
  • The last refresh outcome, or the last dry-run’s verdict with its per-part table
  • Refresh graph now, Dry-run refresh, and Accept new baseline & refresh
  • The Backend, Materialize, and Fly machine settings for the next refresh, explained below

Refresh settings

The rows under the refresh buttons control where and how the next refresh runs. Each shows its current value and where that value came from. Backend sets where the next refresh runs — on GitHub Actions (the knowledge-graph source repo’s), or on Fly machines (a kept machine reused between runs). The global runner mode overrides this setting:
  • gha forces GitHub Actions
  • fly forces Fly
  • local forces local Docker
  • default uses this setting
With nothing saved, the backend defaults to Fly when Fly is configured (FLY_SESSIONS_TOKEN and the sessions app both set), otherwise GitHub Actions. A deployment with no Fly configuration therefore refreshes on GitHub Actions with no action needed, and the backend reads Fly not configured. The next run: line names the effective backend and why it was chosen, such as:
  • KG setting
  • runner mode gha overrides the KG setting
  • Fly not configured
For a knowledge-graph-only change, prefer this setting over runner mode gha. Runner mode is global, so setting it to gha also forces every project otherwise set to Fly onto GitHub Actions.
The GitHub Actions backend needs:
  • a project mapping for the knowledge-graph source repo
  • that repo’s synced claude-implement.yml workflow
  • available Actions minutes
Measured on 2026-10-10 in a small sample, a refresh took about 40–47 minutes on GitHub Actions’ default runner, against about 35 minutes on a 2-CPU / 8 GB performance Fly machine. Materialize controls how the orchestrator turns the pushed snapshot into the graph it serves. This step runs inside the orchestrator after either backend finishes, so it does not change where the refresh runs.
  • rdflib re-serializes every snapshot part into one combined graph — about 99 MB peak memory at 31k triples.
  • direct copies the snapshot parts and serves them unchanged, with no re-serialization — about 29 MB peak.
Prefer direct. Choose rdflib only when the knowledge-graph source repo is built on a base that does not support the direct path: the direct step then fails and the refresh reverts safely to the graph it was already serving. The setting applies to the next refresh, with no restart. Fly machine sets the size of the kept Fly machine the refresh reuses between runs. This row appears only when the effective backend is Fly. It covers:
  • CPU kind — shared or performance
  • CPUs
  • Memory (MB)
  • Idle (hours) — how long the machine may sit unused before it is destroyed
After the idle time passes with no refresh (7 days by default), the machine is destroyed, so an unused Fly backend stops costing anything. Below the card, Runs lists the knowledge-graph refresh runs from the dispatch log, with the same time filter as Pipelines, a Logs link, and Stop for a run that is still in flight.
The same runs also appear on the Pipelines panel, which stays the complete dispatch log.

Configure

Projects (team/repo mappings)

The Projects panel is where you connect ticketing scopes (Linear teams or Jira JQL clauses) to GitHub repositories and control exactly how AI-Implement dispatches runs for each scope.
See Configure project mappings for the full field reference and defaults.
A project’s Edit dialog also carries an Agents tab, where the project opts in to per-stage agent settings and chooses to inherit or override each field. See Agent settings per stage.

Create a new project mapping

1

Open the stepper

Click Configure → Projects → + New project. The stepper walks through the configuration one step at a time.
2

Fill in Ticketing System and Source

Pick Linear or Jira as the ticketing system, fill in the provider-specific config (Linear team key, or Jira JQL + repo-field value), then enter the target repo’s GitHub Owner, Repository Name, and Default Branch.
Default Branch is required and must match the repo’s actual primary branch (commonly main, master, or development).
Once the owner and repository are filled in, Check installation confirms the GitHub App can reach that repo. It reports one of these outcomes:
  • The App is installed and can access the repository.
  • The App is not installed on that owner, with a link to install it.
  • The App is installed but the repository is not among its selected repositories, with a link to add it.
3

Step through the remaining configuration

Runner, Provider, Capacity, and Secrets steps follow, then a final Review step confirms your settings before you create the project. For a first run, defaults are reasonable.The Capacity step exposes these optional fields:Leave any field blank to use the default. Setting these tighter than the defaults is the recommended way to control cost and reliability per project.The project’s Reviewers list is not in this stepper. Set it from the project’s Edit dialog — see reviewers.
Setting provider to bedrock requires awsRegion and is not compatible with executionMode: fly-machines.You must also add AWS_BEDROCK_ROLE_ARN as a secret in the target repo. Nothing else is needed for /ai-implement comment-triggered runs — they use this same mapping.
4

Create the project

Click Create project. The new mapping appears in the Projects table automatically — if it does not, reload the page.
Each row in the Projects table also exposes a Sync workflows action, which opens or updates a pull request in the target repo containing the workflow files and starter prompts. This is the normal way to push workflow updates from the orchestrator into target repos.Saving a project also syncs its workflows, so a newly created mapping gets its pull request without any extra step. Reach for the row action when a sync is all you need — saving runs a full mapping update alongside it.

Pipelines & steps

Shows the pipeline YAML definitions (the built-in src/pipeline/*.yml plus any custom/pipelines/*.yml overrides) as collapsible details, each listing the steps that run and their module IDs. A second table lists every step module with:
  • Built-in path
  • Custom override path (if present)
  • Status (built-in / override / additive)
Useful for visualizing the extension hierarchy when you’ve added custom steps. See Add custom pipeline steps for the override mechanism.

Models & providers

Beyond the read-only per-project summary below, this page hosts the orchestrator’s agent-configuration controls:
  • Orchestrator stage defaults — the per-stage agent, provider, model, account profile, and elapsed time limit that opted-in projects inherit. See Agent settings per stage.
  • Account profiles — the stored credentials runs authenticate with, and the projects each one may serve. See Use Codex with OpenAI.
For a legacy project, the model ids live in its target repo’s WORKFLOW.md and PLANNING.md front matter. For an opted-in project, the model comes from the stage defaults or the project’s own override — see Agent settings per stage.
KPI cards show:
  • Projects (total)
  • Anthropic (count of projects using the Anthropic provider)
  • Bedrock (count of projects using the Bedrock provider)
  • Bedrock regions (count of distinct regions in use)
The table lists each project’s:
  • Team (the teamKey)
  • Repo
  • Provider badge (anthropic or bedrock)
  • Bedrock region (or a “missing” badge if required and unset)
  • Planning status
  • Runner mode

Platform

Runners

High-level runner-infrastructure dashboard. KPI cards show:
  • Current runner-mode override (default / gha / fly / local / shadow)
  • Live Fly session count
  • Capacity utilization (in-progress runs vs. total cap across mappings)
  • 24-hour reaper destructions

Runner mode

The toggle offers four options: default, gha, fly, and shadow. local is a valid runner mode too, but the toggle doesn’t expose it — set it through the environment or the API instead.
If the RUNNER_MODE environment variable is set on the orchestrator process, it takes precedence over this database value and the UI flags that an env-var lock is active.If you change runner mode via the UI or API while RUNNER_MODE is set in the environment, the new value is persisted to the database but has no effect until the env var is removed and the orchestrator is restarted.

Live Fly sessions

A table of the most recent eight, linking into the Sessions panel for the full list.

Per-project execution mode

A table shows each mapping’s:
  • Configured execution mode
  • Effective mode (after applying any global override)
  • Capacity-utilization meter

Parked issues

Issues the dispatch breaker has parked. This section renders at the top of the panel, above the runner-mode controls, and stays hidden while nothing is parked. An issue is parked once enough consecutive dispatches fail for the same issue and phase, and is skipped on every poll from then on. Planning and implementation are counted separately, so an issue can be parked in one while the other keeps running, and a successful dispatch resets the count — only an unbroken run of failures parks anything. A failure classified as transient — an outage upstream of the ticket rather than the ticket’s own problem — does not count at all, so an unlucky run against a flaky provider cannot park an issue. Transient failures are:
  • provider overload
  • rate limiting
  • transport errors
  • git server errors
Every other failure counts. Each row shows:
  • Issue identifier
  • Repo
  • Phase (planning or implementation)
  • Consecutive failure count
  • Last conclusion
  • How long ago it was parked
  • An Unpark action
Unpark is the only thing that releases a parked issue — a later successful dispatch resets the failure count but leaves the park in place. Unparking clears it for every phase and resets the counter, so the orchestrator dispatches the issue again on the next poll.

Sessions

Lists every Fly Machine session currently in started, starting, or created state. Each row shows:
  • Machine ID and name
  • Current state
  • Uptime duration
  • Associated issue identifier (linked to the ticketing system), where available
  • Target repo, where available
You can destroy a stuck session directly from this panel. Destroying a session also:
  • Removes the in-progress marker from the associated issue (the AI-Working label on Linear, or Implementing status on Jira)
  • Clears it from the deduplication window, so the orchestrator can pick it up again on the next poll
If a Fly Machine appears stuck and is not progressing, destroying it from the sessions panel is the cleanest recovery path.

Reaper

The reconciliation-sweep dashboard. A summary card shows the 24-hour total of machines and jobs the reaper destroyed, broken down by rule:
  • orphan
  • stale-terminal-job
  • max-age-exceeded
  • issue-terminal
Plus the last sweep timestamp. A recent-actions table lists the latest destructions with:
  • Timestamp
  • Rule matched
  • Machine ID
  • Tenant
  • Associated issue
  • Age at destruction (in seconds)
  • dry-run or destroyed badge (indicating whether the action was a no-op or executed)

Secrets

The Secrets panel itself is a placeholder — a consolidated browse-and-rotate view is not built yet. Secrets are managed in two places today:
  • Global secrets on the Settings panel
  • Per-project secrets from each project’s row on the Projects panel.
Both are backed by the endpoints below.

Per-team secrets

Each project mapping has its own per-team secrets at /api/mappings/:teamKey/secrets. Secrets are stored as Fly app secrets with the team key as a prefix (e.g. a secret named MY_TOKEN for project ENG is stored as ENG_MY_TOKEN).
Secret names must contain only letters, digits, and underscores.

Global secrets

Global secrets are Fly app secrets that do not belong to any specific project mapping. They are listed, created, and deleted from /api/global-secrets.
Global secret names must not start with any project key prefix (to keep the per-team scoping unambiguous).

Settings

The settings panel manages orchestrator-level configuration:
  • flySessionsApp — the Fly.io app name used for Fly Machine sessions.
  • flySessionsRegion — the default region for new Fly Machine sessions.
  • Linear Pickup Label — the label the orchestrator polls Linear for, default AI-Implement, stored in the orchestrator database and effective at the next poll with no restart.
Both Fly values can be overridden at the environment level via FLY_SESSIONS_APP and FLY_SESSIONS_REGION. When an env override is active, the UI shows the runtime value alongside the database value and flags that the env var is winning. LINEAR_PICKUP_LABEL seeds the pickup label once at first boot, then goes inert, the same as KG_BASE_REPO. It is not a runtime override the way FLY_SESSIONS_APP is, so editing the environment variable after first boot changes nothing. Change the pickup label only for a planned migration, since issues on the old label stop dispatching at the next poll, as Triggers and status indicators explains. GET /api/settings returns linearPickupLabel as { value, effective, default }, and POST /api/settings accepts linearPickupLabel as a string, or null to reset it to the default.
Changes to settings that differ from the running process take effect after a restart. The pickup label is the exception: it takes effect at the next poll.

Orchestrator Agent Defaults

The Orchestrator Agent Defaults card carries Defaults mode, which turns stage agent configuration on or off for the whole orchestrator:
  • legacy — stage defaults are off. This does not opt projects out.
  • configured — stage defaults are available for projects to opt in to.
Turning it on enrolls no project on its own. The per-stage default values are set on the Models & providers page. See Agent settings per stage.
Opt configured projects out before selecting legacy. Otherwise, their next configured runs cannot start. See Opting back out.

Retry Policy

The Retry Policy card sets the orchestrator’s global retry and backoff policy, and the post-push reviewer turn cap. A blank field uses its default.
  • Request Retries — re-spawns of one Claude invocation on a transient failure. Default 2.
  • Stage Retries — re-runs of a whole implement/review stage. Default 1.
  • Push Retries — retries of a failed push. Default 2.
  • Backoff Initial (ms) — the first retry’s backoff delay, in milliseconds. Default 30000.
  • Backoff Max (ms) — the largest backoff delay, in milliseconds. Default 300000.
  • Backoff Jitter — the fraction of each delay subtracted as jitter. Default 0.2.
  • Review Max Turns — the post-push reviewer turn cap, from 5 to 200. Default 30.
Review Max Turns is the turn limit a reviewer uses when its project Reviewers row leaves Max turns blank and the reviewer has no default of its own. See Turn limit.

Developer

Audit log

Shows the dispatch-deduplication ledger — every issue currently in the dedup window. Each row includes:
  • Issue identifier and title
  • When the issue was dispatched
  • A delete button to remove it from the dedup window
An issue gets an entry when it’s dispatched, which stops the orchestrator from picking up the same issue again. Entries don’t expire on a timer. They’re cleared under any of these conditions:
  • The issue is completed or cancelled. The orchestrator notices on its next poll, which is how an entry normally clears once the issue’s pull request merges and the issue closes.
  • No configured tracker returns the issue anymore, because it was deleted or moved out of scope.
  • The dispatch attempt fails before a run starts.
  • A run fails or times out while the issue is within its retry budget. Once the budget is used up, the entry stays and the issue is left for a person to investigate.
  • A session is destroyed from the Sessions panel.
  • The reaper ends a session that ran past the maximum session age, or whose issue was already completed or cancelled.
  • An operator removes the entry with its delete button, or with the clear_dispatch_dedup MCP tool.
If none of these happens, the entry stays. The usual case is a successful run on an issue that is never completed or cancelled. Remove an entry with its delete button so the orchestrator can pick the issue up again on the next poll.
The roadmap calls for richer audit-log content here over time; the current implementation is focused on the dedup window.

Customizations

Lists every file under the custom/ directory in the orchestrator’s working tree that overrides a built-in. The table shows each file’s:
  • Path
  • Category (pipeline / step / provider / other)
  • Status (override / additive / — for the other category)
  • Upstream counterpart path it shadows
  • File size
  • Last-modified time
A CI workflow (protect-custom.yml) flags upstream PRs that modify files under custom/ outside the allowed paths (custom/README.md and .gitkeep files). The check is currently advisory — it won’t hard-block a merge but will surface a warning in CI. The team has it tracked to restore as a hard fail.See Add custom pipeline steps for the resolution rules.

Admin API reference

Operator-facing /api/* endpoints require a signed-in session, which lasts 24 hours. A request carries it in the cookie the browser sets at sign-in, or in an Authorization: Bearer header when you are scripting. The session-machine endpoints at the end of this section are the exception — they authenticate by a per-session nonce instead.

Authentication

In the browser, sign in with single sign-on or the access code — the session lands in a cookie and nothing else is needed. For scripting, mint a token with the access code and pass it as a bearer header. This works only where an access code is configured: with single sign-on alone the orchestrator refuses access-code sign-in, so there is no bearer flow.
1

Obtain a bearer token

POST your access code to /api/auth:
The response contains a token field. Store it for subsequent requests.
2

Pass the token on subsequent requests

Include the token as a Bearer header:
Access-code sign-in is deprecated in favor of single sign-on, so this is not a supported basis for new tooling.

Endpoint reference

Authentication

The /api/auth/* sign-in endpoints above are reachable without a session — they are how you get one, and they stay open even when no access code is configured. Every other operator-facing endpoint on this page returns 401 Unauthorized when the session cookie or bearer token is missing or expired.
A session is not a blanket gate on /api/*: a separate handful of endpoints used by runner sessions authenticate by a different mechanism, and the GitHub webhook endpoint authenticates by signature. Account for all three when writing ingress rules. See Session-machine endpoints below.

Project mappings

Jira field helpers

Issues, jobs, and pull requests

Reports

Sessions, reaper, and deduplication

Dispatch breaker

Runner mode and settings

Secrets

Orchestrator status

Session-machine endpoints

The /api/* endpoints below are called by Fly Machine and local Docker runner sessions, not by operators, and — unlike the rest of /api/* — do not require an operator session. Each authenticates with a per-session nonce instead, issued when the session starts and rejected once it expires.
These are internal to the orchestrator and its runner sessions. They are listed here so monitoring and ingress rules account for them correctly — not as an interface to build against. Their paths, payloads, and authentication may change without notice, and nothing outside a runner session should call them.

Runner callback endpoints

The endpoints below are called by runners (GitHub Actions workflow jobs, Fly Machine sessions, or local Docker containers running an issue), not by operators. Some sit outside the /api/* namespace and some inside it, but all are authenticated by a runner token rather than by an operator session. All of them respond 501 Not Implemented when the orchestrator has no RUNNER_TOKEN_SECRET configured, since none can validate tokens without it.
Operators do not normally call these directly. They’re documented here so that monitoring tools, ingress configurations, and debugging sessions can account for runner-side traffic correctly.

Webhook and trigger endpoints

These endpoints sit outside the operator API but are operator-configurable: you set their URLs and secrets in your target repos (or at the organization level), and the orchestrator validates incoming requests against those secrets. Documented here so monitoring tools, ingress rules, and integration testing can account for them.
Both endpoints require their corresponding secret to be configured on the orchestrator.See GITHUB_WEBHOOK_SECRET and GAP_FILL_TRIGGER_SECRET