Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Dev Pipeline panel (part 2)

The second half of the Dev Pipeline panel page: the Auto-lander tab, the QA Fleet tab and the Setup tab — the switches, the cleanup jobs and the spend caps — plus how the panel is put together for contributors.

What it is

This is part 2 of the Dev Pipeline panel page. That page covers what the panel is, where it lives, and the first four of its rail entries — Live, Timing, Agent Board and the Worktrees half of the worktree view. This half carries the remaining three rail entries — Auto-lander, QA Fleet and Setup — and, for anyone working on the code, how the panel is put together.

Where to find it

Both halves are the same surface: the built-in Dev Pipeline virtual project, which docks in the main panel beside the projects sidebar and opens from its own row in the Omniscio sidebar. On a phone the rail becomes a row of tabs across the top, so the three entries described here are reached the same way remotely.

How it behaves

Auto-lander. Its own tab on the rail is where you watch it: live daemon status, the queue of branches currently marked ready-to-merge, and the land history — every branch it has landed, handed back on a conflict, or set aside (couldn't land), kept across app restarts, plus two quick actions: pause/resume the whole lander, and pause/resume one repository. Full write-up: auto-lander-dashboard.md. Its switches live in Setup, under All settings: turn it on or off, and choose which repositories it watches (setting a repo to observe-only first). The auto-lander lands branches you've marked ready into your main branch automatically and locally; it only ever moves things forward and never pushes. A branch you mark ready is trusted as finished — the lander merges it even if the dev-pipeline's process record was never marked complete (that check is informational, so a finished branch never sits stuck waiting for a record that was never updated). If a branch you marked ready gets more commits after tagging — or is rebased onto a newer main — the auto-lander now re-checks and re-tags it for you so it still lands, instead of stranding it behind a "moved after tagging" alert; you're only notified if that automatic re-check genuinely can't land it. When a branch lands you also see it in two more places: the session that produced it gets a green "Landed … to master" note (with a check) just below its final message — even after that session has finished (it's never reopened or re-run) — and the run is marked "Landed ✓" in the Timing tab instead of just quietly disappearing when its worktree is cleaned up. If the auto-lander's integration checkout ever drifts out of sync it quietly re-syncs it — this self-heal runs silently (logged for diagnostics, never an inbox notice) and always snapshots a backup first, so nothing is lost.

Expanding a conflict row lists the conflicting files. That list is bounded and says so: the first 20 with a "+N more" tail, and — because only the first 50 conflicting paths are ever recorded per conflict — a plain note when you're at that recording limit, so a 90-file conflict never masquerades as a complete 50-file one.

Automatic master catch-up. The other thing in this panel that can move your local master on its own, which is exactly why it sits beside the auto-lander: a background check that fetches the remote and merges it into your local master for you — about five minutes after the app starts, then every six hours. Off by default, and it only applies when you run Omniscio from source. Off does not mean silent: you are still told when you have fallen behind, with a one-click catch-up — nothing moves your branch unless you ask.

Beside it is a paid sibling, also off by default: an hourly job that finishes a catch-up origin/master conflicts have blocked, by buying a capped AI session for whatever the free path cannot resolve. It is a separate switch on purpose — one of these moves a branch and the other spends money, so arming the free one must never quietly arm the paid one. Neither implies the other. Both are the sort of switch a person has to flip: they are on the CLI's patch denylist, so no agent token can turn them on for you.

QA Fleet. The QA fleet's results, in the panel — what the background QA runs found, read from the ledger they write locally (~/.amc/qa-fleet/ledger.db). Its rail entry (a flask icon, sitting between Auto-lander and Setup) shows an amber badge with the number of open findings whenever there is at least one, so you can see at a glance whether there is anything to look at without opening the tab.

Five totals lead the view — Open Findings, High/Critical Open, E2E Passing, E2E Failing and Features Covered — followed by a 14-day open-findings trend, one bar per day showing how many findings were still open at the end of it. Below that sit three lists:

  • Findings — each open one with its severity, the file it lives in, and how many times it has been seen, with three inline actions: Resolve, Dismiss and Reopen. A filter tabs between Open (n) and Resolved/Dismissed (n), so a finding you closed is still reachable rather than gone. Closing one fires straight from the row with no confirm step — it is fully reversible, and taxing every correct click to catch the rare wrong one would be the wrong trade — and a banner above the list carries an Undo for the finding you just changed, right where you are already looking.
  • E2E Coverage — each feature with a PASS / FAIL mark.
  • Least Recently Exercised — what the fleet has not touched in a while, or Never.

Everything refetches on a 30-second timer while the tab is open (the fleet produces results on a minutes-to-hours cadence, so a mount-only read would go stale the moment it landed), and there is a manual Refresh beside an "Updated <ago>" cue. Two different empty states say which problem you have: "QA fleet has not run on this machine yet" versus "QA fleet results could not be read" — a fleet that never ran is not the same as one whose records came back unreadable, and neither is dressed up as a reassuring zero.

Worktree cleanup. A live view of the automatic cleanup that reclaims disk by retiring finished git worktrees. You see a status card (when it last ran, a countdown to the next run — "in 1h 20m" — and a warning if it hasn't run in a while), four headline tiles (removed / stale entries / kept / disk reclaimed), the run history (each cycle's "removed" and "stale entries cleared" counts), a grid of every worktree with a plain reason it was kept or removed and how long ago it was touched, a recover button that restores a mistakenly-removed worktree's branch, and a Run cleanup now button. Your click on that button always runs, even while the computer is busy — it is a person asking — whereas a cleanup an agent requests through the control server is held until the load eases, so the app never slows you down to tidy worktrees. The restore list shows only the reaps that can actually be brought back right now — one you have already restored, or one whose commit git no longer holds, drops off the list instead of offering a button that would do nothing.

All four tiles describe the same run — the one the status card names — including Kept, which is that run's own count of worktrees it left alone because they held unlanded or uncommitted work. (Kept is deliberately not a tally of the verdict grid: the grid is the latest analyze output rather than the latest run, and every amber Review row would have counted as "Kept".) The Keep-vs-Review distinction lives where you can see it, on each row's verdict pill. In that grid, "last touched" is a plain local "14h ago", the same as the Worktrees section — the underlying tool writes a UTC wall clock, which is parsed to a real instant before it reaches the screen. The reaping itself is done by the same battle-tested cleanup scripts, which Omniscio now runs automatically on a schedule from inside the app — plus a catch-up when Omniscio starts, and it waits for a quiet moment if your machine is busy (so it never causes a stutter). There is no Windows scheduled task to install: Omniscio owns the schedule, removes the old task once, and auto-creates the stranded-worktree triage helper. When cleanup is on you also get two customization controls: How often to tidy (a dropdown — every 1, 2, 4, 6, or 12 hours; every hour by default), and an AI triage for stuck worktrees switch (on by default) that occasionally spends a little on a short AI session to judge worktrees that look stuck — turn it off to keep the free cleanup but skip the paid triage. This panel makes it visible and gives you the controls; it never re-implements the cleanup, so every safety protection is preserved. Windows only; off by default (turn it on with the worktree cleanup toggle in Performance, or here).

Bypass the testing gates. One Setup switch that stands down the machine's testing gates all at once, for when a broken or slow test system is what is blocking you rather than a real finding. Two things make it safe to have at all. First, the safety rules are not in the set it can reach: the rules that stop a commit to master, a destructive stash, or a deleted worktree stay armed and are never affected. Second, nothing it stands down is ever recorded as passing — every skipped check says out loud that it did not run, and reports BYPASSED, so a green after a bypass can never be mistaken for a real green.

It is off by default, it affects this machine only, and it has no expiry — nothing turns it back off for you. While it is on, the card shows a permanent, deliberately non-dismissible line — "Nothing is being verified right now. This stays on until you switch it off." — because how long it has been on is the only thing standing between a quick flip and a repo that quietly stopped being tested. It is stored in its own file (~/.amc/dev-bypass.json) rather than in your settings, since scripts and git hooks outside the app read it too. Turn it off and every gate comes back exactly as it was.

Where checks run. The card beside it holds the machine's one testing setting: Cloud first (heavy checks run in the cloud; while the cloud is down a few at a time run here), Cloud only (heavy checks never run here) or This computer (everything runs here, no cloud needed). Small test runs always stay here. Clicking a value saves it at once; under the choices the card says where the next heavy check will run and why, whether the cloud is answering, who set the value, any approved window, and which version of the check service is running. It shows exactly what npm run testing prints at a terminal. Agents cannot change it — they ask, and you approve a card. Full detail: Where checks run.

Session-based cleanup (beta). A separate, cross-platform option that goes further than the free reaper: on an intelligent cadence it removes safe worktrees for you — including branches merged via a squash PR, which the plain reaper can't recognize — and, for anything it isn't sure about, spawns one short, conservative AI investigation that scans for stray worktrees and flags anything real to your inbox, then tidies itself away if it found nothing. It runs only on your active dev-pipeline repos (plus a slower sweep for stray worktrees anywhere), never deletes uncommitted or in-use work, and is bounded by a hard daily session + spend cap so it can't run up a bill. Off by default; enable it and set the caps in this section. It runs alongside the free reaper, never replacing it.

For agents

  • Virtual project __dev_pipeline_panel__, integration id dev-pipeline-panel (manifest: src/shared/integrations/dev-pipeline-panel.ts). Distinct from the dev-pipeline skill-bundle integration (which installs the CLI skill).
  • Gating — the reveal and the Dev Pipeline switch are DIFFERENT settings. The panel's visibility comes from the dev-pipeline-panel entry in src/shared/unreleased-features.ts; its status: 'shipped' makes computeVisibility() return true BEFORE it ever looks at a setting, so its settingKey (devPipelinePanelEnabled) does not gate the panel — there is no Lab row (a shipped entry is filtered out of listInDevelopmentFeatures(), so it generates no reveal toggle and no derived settings-search entry), no file under src/renderer references it at all, and AMC_SHOW_DEV_PIPELINE_PANEL is inert. The sidebar row is gated by UNRELEASED_PROJECT_GATES in project-visibility.ts. filterVisibleProjects ALSO reveals it when settings.devPipelineSkillEnabled (the dev-pipeline skill-bundle's featureFlag) is on — a cross-feature coupling so enabling the skill surfaces its dashboard. devPipelinePanelEnabled is the Dev Pipeline's own opt-in, and it defaults to false (session-behavior-settings.ts). It is read directly — never through the registry gate — by four behaviours: whether the auto-lander is armed at all (auto-lander-repos.ts, and resolveAutoLanderRepos returns [] while it is off), the worktree-mutation lockdown (dev-pipeline-repos.ts), daily maintenance (daily-maintenance-supervisor.ts) and git-store maintenance (git-store-maintenance.ts). The only in-repo writer is the developer-machine profile (developer-setup-settings.ts), so a standard install has it off and none of the four run. Gate any NEW dev-pipeline-panel surface through isUnreleasedFeatureVisible as usual — never the raw setting — but do not add gating on the assumption the panel is hidden. It isn't.
  • Mobile / Web Access: the manifest declares mobile: { status: 'ready' }, so the panel shows + mounts on mobile via the same filterSidebarOnlyVirtualProjects gate + panelOwnsLayout routing the desktop uses (its IPC channels proxy over Web Access). The desktop-only set (declared mobile: { status: 'desktop-only' }) is exactly THIRTEEN ids — browser, native-browser, running-apps, screen-recordings, screenshots (the five with a real <webview> / desktopCapturer / keyboard constraint), plus journal, gauntlet-loop, phone-control, hooks, teach-recorder, contextdock-native, composio and memory, which are desktop-only for PRODUCT reasons rather than a platform one — contextdock-native and memory share their cause (both read the CONTEXTDOCK_STORE_* channels, which the mobile/web WS bridge blocks), while composio opens a DESKTOP browser sign-in and wires the resulting tools into locally-spawned Claude sessions. Do NOT reason from an older four-, five- or twelve-member list; the authoritative inventory is the ui-registry.test.ts guard, whose test name reads "exactly the THIRTEEN known desktop-only integrations declare mobile: desktop-only", mirrored in dev-pipeline-panel-contract.md available-on-mobile-and-web-access. (shared-sessions moved OFF this list on 2026-09-10 — mobile reached full parity and its WS channels came off the denylist — so do not re-add it.)
  • Layout (renderer): DevPipelinePanel renders a category rail (CategoryRail — Live / Timing / Agent Board / Auto-lander / QA Fleet / Setup; the DevPipelineCategory union is 'live' | 'timing' | 'board' | 'autolander' | 'qafleet' | 'setup', from DEV_PIPELINE_CATEGORIES in src/shared/dev-pipeline-panel.ts) + a content pane showing the active category. Auto-lander (AutoLanderView) and QA Fleet (QaFleetView) are BOTH first-class rail entries rendered UNCONDITIONALLY — see auto-lander-dashboard.md for the first; CategoryRail gates only board behind its optional showBoard prop. Agent Board (shown only when agentStatusBoardEnabled, via CategoryRail's optional showBoard prop) renders the shared AgentBoardList — the same board body the global Agent Board view uses — and jumps to a session via navigateToSessionInProject; the panel resets category to Live if the feature is turned off while the tab is open (see agent-status-board.md + dev-pipeline-panel-contract.md L1). Live is LiveView, which unions the flat runs list with the already-per-project worktrees via the pure buildProjectGroups (pipeline-live-grouping.ts) into one collapsible group per project, reusing RunRow + RepoGroup (worktree-rows.tsx) verbatim and one useWorktreeRemoval hook + dialog. Gate/phase labels are humanized + overflow-hardened in pipeline-labels.ts (gateLabel recovers the canonical GATE_n from a noisy value and caps an unknown one; the Waiting pill is width-capped + truncates). Timing is TimingView — a five-tile summary grid (Working · Waiting on you · Stuck · Avg wait · Spend) + a biggest-stall line, over a list of expandable RecentRunRows, each a proportional green/amber/red/idle SplitBar that opens to a per-phase working-time-and-spend + per-gate wait RunBreakdown. See dev-pipeline-panel-contract.md L1–L3.
  • Active runs are derived on demand by derivePipelineRuns() (src/main/services/dev-pipeline/dev-pipeline-panel-service.ts), which reads each non-terminal session's worktree .claude/pipeline/state.md with the same parser the Agent Status Board uses — so it does NOT depend on the (default-off) Agent Status Board feature. It also carries each run's statusChangedAt / needsYouAt so the row can render the live waiting <time> counter. IPC: PIPELINE_RUNS_GET.
  • Run timing (the Timing tab) is captured by Omniscio itself, NOT by the skill: registerPipelineRunTimeline (src/main/services/dev-pipeline/pipeline-run-timeline-service.ts) subscribes once (at handler registration → always-on) to the internal sessionEvents 'statusChanged' bus that SessionStatusManager.updateStatus fires on every committed transition (process-manager.ts notifyStatusChanged), and appends a pipeline_run_events row ONLY for dev-pipeline runs (same phase/gate test as derivePipelineRuns) — so the table is naturally scoped and capture works whether or not the panel is open (deliberately NOT the default-off status-board tick, NOT the ~165-call-site DB chokepoint). Capture is best-effort (guarded, can't perturb the status path) + idempotent (an in-memory last-tuple cache, restart-seeded from the DB via getLatestPipelineRunTuple). The pure reducer derivePipelineRunTimeline (src/shared/pipeline-run-timeline.ts, caller passes nowIso) splits each run into working / gate-wait / stuck (deterministic) + per-phase (best-effort), and summarizePipelineRuns builds the strip. History is a SEPARATE read derivePipelineRunHistory (.../pipeline-run-history-service.ts, IPC PIPELINE_RUN_HISTORY_GET) over the durable events joined to sessions (incl. finished runs), with an inline 90-day prune on write. No AI calls → zero cost. See dev-pipeline-panel-contract.md RT1–RT5.
  • Worktrees are derived on demand by deriveRepoWorktrees() (src/main/services/worktree/dev-pipeline-worktrees-service.ts): per real-repo project it reads git worktree list + branch descriptions + each worktree's state.md, cross-referenced with the sessions table — no stored registry, so it never goes stale and surfaces orphans. Removal runs the pure evaluateWorktreeRemovable guard (precedence main-checkout > not-a-worktree > keep-marker > in-use > uncommitted > unlanded — six reasons, not five; keep-marker is an ABSOLUTE veto for a branch whose DESCRIPTION carries a do-not-delete directive, so a clean/landed/orphaned-but-PINNED worktree is still refused. It reads fail-CLOSED at remove time — an unreadable branch description counts as marked. Kill switch AMC_DISABLE_WT_KEEP_MARKER_VETO), RE-gathered with real git reads in Main before any delete; live ownership includes agentDetectedWorkdir (how a self-created worktree is tracked), and deletion goes through the junction-safe removeWorktree. IPC: WORKTREES_GET (read), WORKTREE_REMOVE_ONE / WORKTREE_REMOVE_SAFE_BULK (destructive). Both removals are ALSO CLI control-server routes — POST /project/:id/worktrees/remove ({ worktreePath }) and /remove-safe — so an agent can clean up worktrees headlessly; they reuse the same service verbatim, so the same guard runs and a kept worktree comes back as a normal 200 { removed: false, blockedReason } (cli-server-project-ops-routes.ts; documented in the omniscio-control projects.md spoke). See dev-pipeline-panel-contract.md W1–W7.
  • Run cost is captured by Omniscio, not the skill: each pipeline_run_events row snapshots the owning session's cumulative cost_usd (nullable, additive migration), and the pure derivePipelineRunCost (src/shared/pipeline-run-timeline.ts) turns consecutive snapshots into run + per-phase deltas — run-scoped by construction (a session's total includes pre-pipeline chat), clamped ≥ 0, null = unknown (never a fabricated 0). The Live list closes each open run against the session's current cost via ONE batched getFirstPipelineCostSnapshots read (never N+1). See dev-pipeline-panel-contract.md RT6.
  • Stale runs + Adopt: a worktree is a stale run when it carries a non-complete pipeline state, no live session owns it, and its recorded ## Owner session is gone or terminal (isStalePipelineRun). adoptStalePipelineRun re-verifies everything at click time, serializes concurrent adopts (in-flight set), transfers the state file's ## Owner to a RESERVED session id BEFORE spawning (a failed spawn stays stale → retryable), then spawns via createSessionWithPrompt with reuseWorktree (runs INSIDE the stranded worktree; fails closed pre-insert if the path vanished) and a /dev-pipeline resume prompt — the skill's own STEP-0 discovery matches the new owner and resumes. IPC: PIPELINE_ADOPT_RUN, also the CLI route POST /project/:id/worktrees/adopt-run ({ worktreePath }). Because adopting spawns a real (paid) session, the CLI kind pipeline.adopt_run is NON_TOGGLEABLE + IRREVERSIBLE: the route only ENQUEUES an inbox approval (no in-app-session bypass — an AI can never self-approve it) and requires a source session; the pipeline-adopt-run-handler runs adoptStalePipelineRun only on approval. See dev-pipeline-panel-contract.md A1–A5.
  • Load-failure behavior: a failed panel read toasts once (while un-hydrated) and shows the empty state instead of an infinite "Loading…"; the panel's own interval keeps retrying, and a transient failure after a good load keeps the last-good data. See dev-pipeline-panel-contract.md L8.
  • Gate auto-approval is per-phase: five independent gate toggles (Plan · Red Team · Build · Elegance · Docs) + a select-all master, backed by pipelineGateAutoApprove and resolved by resolveGateAutoApprove (fallback to the deprecated pipelineAutoAdvanceEnabled / pipelineAutoApprovePlanGate; see pipeline-auto-advance-contract.md). This panel and Settings → Features render the SAME controls (GateAutoApprovalControls), so their wording can't drift.
  • The two always-on standards gates (🚦/🔬) also appear as toggles here (panel-only — Settings → Features shows the built-in five). They persist in a separate setting pipelineStandardsGateAutoApprove (NOT pipelineGateAutoApprove), default auto-approve; the panel routes their on/off through the same row list and the setting flows through the manifest so a gate set manual holds the run for you. See dev-pipeline-panel-contract.md L9. (The ops-only DEV_PIPELINE_DISABLE_BUNDLED_STANDARDS kill switch is honored by the pipeline but not reflected in this panel's display.)
  • Custom phases show up here too (when Enable custom phases is on). The panel resolves your phase manifest (phases.json) and feeds it to GateAutoApprovalControls, so BOTH the flow diagram AND the switch list weave each custom phase in at its insert point (with its emoji) — each custom gate gets its own auto-approve switch at its true pipeline position (e.g. 🚦 Standards Check between Red Team and Build), not appended after the built-in five, so the switch order matches the flow diagram above it. One list controls every stop. Settings → Features (no manifest passed) keeps the plain built-in six. See dev-pipeline-panel-contract.md L6/L7.
  • AI code review — a review step after any phase. The AI code review card offers one switch per phase (after Plan, Red Team, Build, Elegance, Docs); each one you turn on inserts a real 🧭 AI Code Review phase right after that phase, where fresh AI reviewers read the work and report what they find. Off everywhere by default, so an untouched install is unchanged. Every step that runs gets a row — including one your repo sets for everyone, which the card labels as such; its switch turns it off for you alone, leaving your team's setup untouched. These gates get NO auto-approve switch in the list above, because there is no third state for a switch to select: the review's own verdict decides. A clean review closes green and the run moves straight on; a review that found something worth your attention parks for you. Each point you turn on spends reviewer tokens on every run. Your choice is saved alongside your custom phases and your own phases are never disturbed by these switches; it applies whether or not Enable custom phases is on. See dev-pipeline-panel-contract.md L11 (ops kill switch: DEV_PIPELINE_DISABLE_BUNDLED_AI_REVIEW). Above those switches, Run AI code review steps (on by default; the devPipelineAiReviewEnabled setting) turns every review step off at once, including in runs already under way: agents stop being given review steps, a reviewer asked for from a review step is refused, and a session already waiting at one still moves on. While it is off, the per-step rows hide and the flow diagram shows no review step; the per-step choices stay saved for when it goes back on. It is the one AI-review control stored as a setting, because the app applies it itself — see dev-pipeline-panel-contract.md ai-review-switch-reaches-running-work. Under the switches, How each AI has done is the reviewer scorecard: one row per AI model with how many reviews it ran (and how many got no answer), the serious and minor problems it found that the pipeline checked and confirmed, its false alarms, how often the pipeline approved of its reviews (shown as "75% approved" once any review is rated — never 0% before that), and what it cost in total and per review. Cost is read from each reviewer's own session, so it is exact, and it stays on the scorecard even after you delete that session; a dash means the cost isn't reported (a reviewer that ran inside the pipeline's own session is billed with it, and some AI companies don't report cost to Omniscio yet). Below it, Whose work was reviewed lists each AI whose work the reviews looked at — its reviews, the serious problems found in it, and serious problems per review — so you can see which AIs need more review. Both stay empty until a review step runs. See ai-review-scorecard-contract.md.
  • Who writes the code — pick a cheaper model for the build step. The Who writes the code card sets which model actually writes code during the build phase, and whether it runs as a helper inside the run (the default, cheapest) or as its own session you can watch in Mission Control. Picking a cheaper writer is safe because it turns the pipeline's existing cheap-implementer preference into a rule: the smart model becomes an overseer that writes the failing test, hands the work over, reviews every change that comes back, sends work back with specific fixes, and keeps only what it accepts. Nothing a cheaper model writes is kept unreviewed, and the build gate has to report which model built it and how many changes were accepted versus sent back — a run that quietly skipped the loop has no counts to show. You store a speed level (Genius / Smart / Worker / Basic), never a specific model name, so your choice never goes stale when a new model ships. Default: Worker (Sonnet-level), as a helper in the session. Own-session mode starts a real session per build and costs money — turning it on is what allows the pipeline to start them. Saved alongside your custom phases in phases.json, which is the one file both Omniscio and the Claude skill read — a normal setting would be invisible to the run it configures. See dev-pipeline-panel-contract.md build-model-lives-in-the-manifest-not-settings.
  • What you set is what runs — the editor stays in sync with the project copy. The editor saves to your personal manifest (~/.claude/dev-pipeline/phases.json), but a run resolves project-over-personal, so an edit to a phase a repo ALSO commits (<repo>/.claude/dev-pipeline/phases.json) would otherwise be silently overridden. The panel bridges both directions (phase-manifest-service.ts): on save it writes the edit THROUGH into every repo that already commits that phase (syncCustomPhasesToProjectManifests — your fresh edit wins; it never adds a personal-only phase to a repo, never deletes a project phase, and never commits/pushes — you commit the file), and on read it shows the effective value (overlayProjectValuesOntoPersonal — a phase a repo commits displays that project value, so a switch can't read "on" while "off" is what actually runs). Both are fail-safe. A personal-only phase (no repo commits it) stays yours; a committed project manifest applies to every dev on that project (see dev-pipeline.md "Project-level phases"). AI Code Review steps are the exception both ways: a repo's review steps are the team default, and once you change any review setting for a step, YOUR settings are what run on your machine — so the editor shows your own values for it, and a save never writes a review step into a repo's shared file. A step you switch on without changing anything keeps (and shows) the shared settings, and a save never quietly turns that copy into your own.
  • Auto-lander reuses AutoLanderSettings (per-repo config, force-revealed via its embedded prop) + MergeDaemonStatusCard (live status). The land history is a new auto_lander_events table written fail-open by the auto-lander supervisor's per-tick sink (the three terminal outcomes only — landed / conflict / unlanded — deduped + retention-pruned); IPC: AUTO_LANDER_EVENTS_GET, refetched on the existing AUTO_LANDER_STATUS_UPDATED push. See auto-lander-contract.md.
  • QA Fleet (QaFleetView) is a read + triage surface over the QA fleet ledger at ~/.amc/qa-fleet/ledger.db. Two IPC channels: QA_FLEET_SUMMARY_GET (qa-fleet:summary) for the totals / trend / findings / E2E / coverage read, and QA_FLEET_FINDING_STATUS_SET (qa-fleet:finding-status-set) for the resolve / dismiss / reopen triage write. The CategoryRail badge counts open findings and renders ONLY when the count is above zero, so a clean fleet shows no pill. It is an UNCONDITIONAL rail entry — it carries no unreleasedFeatureId, no visibleWhen and no setting, so it ships to every user of this shipped panel; if that is ever meant to change, the missing gate is the fix, not a doc. The richer developer-facing driver for the same fleet is internal/qa-fleet-desktop-routes.md, which is repo-only (the internal/ tree is excluded from the published mirror, from extraResources and from the packaged app), so this page is deliberately the customer's only route to it.
  • Landed-session attribution + note. On a landed, the sink ALSO resolves the dev-pipeline session that authored the branch — via the SAME owner-resolver the conflict hand-back uses (worktree_branch → the branch's git worktree dir → agent_detected_workdir), so a self-created worktree is found and terminated authors count — and stamps it onto a new nullable auto_lander_events.session_id (migration 20260716130010). Two surfaces read it: the supervisor appends a PASSIVE kinded notable-system "landed" note to that session (landed-session-notify.ts → addMessage + SESSION_OUTPUT push — fail-open, idempotent on a FRESH insert, and it NEVER wakes / reopens / spawns the session, unlike the conflict hand-back's deliverPeerMessage; kill switch AMC_DISABLE_LANDED_SESSION_NOTIFY), and derivePipelineRunHistory marks the Timing run "Landed ✓" via a single listLandedSessionIds join. Runs after the status push, before the worktree retire. See auto-lander-contract.md (S26) + dev-pipeline-panel-contract.md (RT7).
  • Worktree cleanup (WorktreeCleanupSection) is a dashboard over the vendored PowerShell cleanup scripts (scripts/worktree-maintenance/, self-contained via $PSScriptRoot). A Windows-gated Main service (src/main/services/worktree-cleanup/) READS the tool outputs (per-run summary.json, the worktrees-*.tsv verdict grid, the wt-deleted-recovery.tsv restore log — read from the out-dir root AND every run-<ts>/ dir, since every app-driven reap writes it into the run dir; tail-bounded with a row cap like the sibling append-only readers, ref probes pinned with -C <resolveMergeRepoRoot()> to the same repo recoverWorktree restores into, and the recoverable flag applied at the render site), and a 5-min supervisor BOTH ingests completed runs into worktree_cleanup_runs (pushing status on-change + raising a deduped stale alert) AND is the in-app scheduler — it fires the reap on a user-configurable cadence + a startup catch-up, load-gated via isBoxHeavyOrSettling, decided by the pure decideScheduledRun (worktree-cleanup-schedule.ts). The cadence is worktreeCleanupIntervalHours (default 1 — WORKTREE_CLEANUP_INTERVAL_HOURS in src/shared/worktree-cleanup.ts, lowered from 2 on 2026-09-02 because idle unlanded worktrees filled a drive overnight; the reap retires a capped batch per run, so cadence is the throughput lever) read through resolveCleanupIntervalHours (clamp [1, 24], bad value → default), and the stale window scales with it (resolveStaleThresholdHours) so a long interval never false-alarms. There is no OS Scheduled Task: worktree-cleanup-ostask.ts removes the legacy one — only while the in-app replacement is active (toggle on + available; fail-safe skips), re-checked every boot and cleanup-settings save so a re-created task is re-detected (no permanent marker) — and worktree-triage-cron.ts auto-seeds the stranded-worktree triage-dispatch cron — active iff isWorktreeTriageActive(settings) (= worktreeCleanupEnabled && worktreeTriageEnabled), so the paid AI triage is an independent on/off while the free cleanup keeps running. The status card's "next run" is derived from the in-app cadence (scheduledTaskState is null; a load-deferred run reads "waiting", not "wedged"; the healthy label is generic, not a fixed interval). The runner is the only mutating spawn surface (a NON-detached argv-array spawn of the wrapper for the reap — a detached spawn silently never runs the script on Windows; git branch for recover — never shell:true). The reaping stays entirely in the scripts, so all their safety invariants are preserved. Flags worktreeCleanupEnabled / worktreeTriageEnabled / worktreeCleanupIntervalHours; IPC WT_CLEANUP_*. See worktree-cleanup-contract.md.
  • Session-based cleanup (worktreeSessionCleanupEnabled, cross-platform, default off) is a SEPARATE createPeriodicTask scheduler (src/main/services/worktree-cleanup/session-cleanup-*.ts) from the reaper above — it runs alongside it. Each tick, for a qualifying repo (active dev-pipeline OR a broad stray-worktree sweep — pure decideRepoCleanup in session-cleanup-decide.ts) it removes every orphaned candidate through the guarded removeOneWorktree — now PR-aware: prMergedConfirmed (gathered authoritatively at remove time via checkBranchHasPR, fail-safe false) relaxes ONLY the unlanded refusal so a squash-merged branch cleans up, while every higher veto (main-checkout / in-use / uncommitted) stays absolute. For a REFUSED residual it spawns ONE read-only investigation session (createSessionWithPrompt, isolationOverride:false → repo main checkout, source:'worktree-session-cleanup') that fs-scans for husks, raises one deduped inbox alert, and self-archives on empty — the session NEVER deletes. Feature daily session + spend caps (resolveDailyCaps, read-time clamped) sit on top of the global daily budget cap; boot start + a teardown task + a settings-apply reactor mirror the reaper. Settings worktreeSessionCleanupEnabled / ...MaxSessionsPerDay / ...DailyBudgetUsd; kill switch AMC_DISABLE_DEVPIPE_WT_CLEANUP. See worktree-session-cleanup-contract.md (its invariants) + dev-pipeline-panel-contract.md W4.

Related

Dev Pipeline panel is the first half — the panel's overview and its Live, Timing, Agent Board and Worktrees views. Dev Pipeline documents the workflow these controls drive.

Last verified 2026-10-04