gsxdsm 90f6319b79 batch-engine tail: re-land the ASYNC half; the sync-resolved half was inert (engine −15) (#2785)
Tail of `batch-engine` (#2773). That PR merged as a squash while later
engine work was still in flight, so `self-healing.ts`, `executor.ts` and
`worktree-pool.ts` landed at their pre-conversion counts. This re-lands
**only the half that is real**, and the reason the other half is not
here is the substance of this PR.

## Census, per file (measured, `--strict` verified)

| file | main | here |
| --- | ---: | ---: |
| `engine/src/self-healing.ts` | 107 | 97 |
| `engine/src/executor.ts` | 15 | 12 |
| `engine/src/worktree-pool.ts` | 3 | 2 |
| `engine/src/ephemeral-worker-manager.ts` | 1 | 0 |
| `engine/src/agent-tools.ts` | 5 | **0** |
| `engine/src/gridlock-detector.ts` | 3 | **0** |
| `engine/src/triage.ts` | 4 | 1 |
| `engine/src/mission-execution-loop.ts` | 2 | **0** |
| **net** | | **−28** |

Baseline re-recorded; `--strict` tightened exactly these 4 entries and
no others.

## Finding: a whole class of conversions in this program is INERT, and
the census scores it as progress

`resolveTaskWorkflowIrSync` returns the **default** workflow IR for
every task in production. The sync selection reader behind it is a
PostgreSQL-cutover stub:

```ts
// packages/core/src/task-store/workflow-definitions.ts:505
export function getTaskWorkflowSelectionImpl(_store, _taskId) {
  return undefined;   // "Backend mode cannot synchronously read PostgreSQL"
}
```

So a guard written as
`resolveLifecycleColumns(store.resolveTaskWorkflowIrSync(id))?.hold`
resolves an IR, asks for a trait, and answers **from the default
workflow for every custom board** — silently. It reads as converted and
the census counts it as converted. `main` gained
`sync-workflow-ir-callsite-allowlist.test.ts` for exactly this after my
branch point; it is what caught me.

I had built three sync resolvers on that reader — `resolveMoveLanesSync`
(self-healing, executor) and a widened `resolveTaskParkedColumnsSync`
(scheduler) — reasoning that a *synchronous* `task:moved` listener needs
a *synchronous* reader. That reasoning was sound about the shape and
never checked whether the reader reads anything.

**Dropped from this PR, deliberately, and NOT re-landed anywhere:**

- `scheduler.ts` 12 → 1 (the widening; the pre-existing narrow helper on
main is untouched)
- the executor `task:moved` handler, incl. the Move-Task hard-cancel
lane comparison
- self-healing's `task:moved` fan-out,
`classifyPausedAbortWorkflowRecovery`, `reconcileInReviewBranchRebind`,
`recoverWedgedActiveMerge`, `recoverPausedAbortFailures`, and 12
single-row lane conversions

Those sites are back to their literals. The allow-list's own guidance is
the standard I applied:

> An unconverted `=== "todo"` is strictly better, because it is at least
honest about being a literal.

I did not add my call sites to the allow-list. Six entries would have
turned the gate green in two minutes and buried the defect; the list's
contract requires proving the async resolver is genuinely unreachable,
and for a fire-and-forget listener it is not — the listener can `void`
an async lane resolution the same way `NotificationService` already
does. That is the correct fix and it is a behaviour-shaped change, so it
is out of scope here.

**Fleet-wide consequence:** any conversion routed through
`resolveTaskWorkflowIrSync` is fake progress, and the census cannot see
the difference. `pnpm test:gate` can: the allow-list test is the
detector. Its passing here (161/161) is this PR's evidence that nothing
inert survived the split.

## What IS in this PR — all async-resolved

1. **`self-healing.clearStaleBlockedBy`** — lanes resolved per
**REFERENCED** task, not per iterated task. A blocker's own workflow
decides whether it is still blocking.
2. **`executor` dependency satisfaction** — resolved per **DEPENDENCY**
via `columnsWithFlag`. Preserves the load-bearing asymmetry that a
dependency in *review* already satisfies a dependent; a bulk sweep
flattens that to complete-only and deadlocks the board.
3. **`agent-tools` — the agent task tools listed FINISHED cards as
active.** `fn_task_list` says it lists "tasks that aren't done or
archived"; `fn_task_search` offers `includeDone: false`. Both filtered
on `task.column !== "done"`, so a renamed complete lane returned
finished cards as outstanding work **to an agent**, which then reasons
and acts on them. `includeArchived` was always enforced by the QUERY and
survived a rename; `"done"` was only ever a TS predicate, which is why
exactly that half broke.

Plus the two **dedup** guards in the same file. The cross-parent
diagnostic filter kept a *shipped* card as a candidate on a renamed
board, so the guard adopted it as canonical and returned `wasDuplicate:
true` — absorbing new diagnostic work into a task nobody is working on
(the eval-followup defect shape again). The defined-feature bootstrap
preflight is **not** the query-filter class: its query passes
`includeArchived: true`, so the TS predicate is the *only* archived
guard there; on a renamed archive lane the archived sibling became the
bootstrap canonical and `claimDefinedFeatureTask` then rejects the
non-live row, so a valid first task fails to be created at all.

Both dedup invariants **already had tests** — asserted against the
legacy ids only, so both passed for the very comparison being replaced.
Extended in place into vocabulary differentials rather than added as
parallel files. Two helpers rather than one parameterised one: "is this
finished?" and "is this archived?" are different questions, and merging
them would make the archived-only guard also reject completed rows.

The list/search half re-landed **with the test it originally shipped
without.** No suite exercised either tool, so the original commit's
"304/304 green" said nothing about the change — the optional-flags
failure mode exactly. Both call sites are covered; converting two copies
and testing one is the Surface Enumeration failure this program has
already hit twice.

4. **`gridlock-detector` — FALSE dependency alarms.** The gate compared
each blocker against `done`/`in-review`/`archived`; on a renamed board
all three are true for a *finished* blocker, so no dependency ever
counted as met and the detector reported dependency gridlock for tasks
that are not blocked — `notifyGridlock` then pages the operator.
Resolved per dependency using the **same five flags** as the executor's
gate (`complete`, `archived`, `mergeOrchestration`, `mergeBlocker`,
`humanReview`) — `review` is not a trait, and two gates answering "is
this dependency satisfied?" differently is a split brain. Every
pre-existing case in that file omits a workflow, so none could detect
the change; added the renamed case plus a non-vacuous companion.

5. **`triage` — its OWN copies of the same two tools.**
`createTriageTools` carries a `fn_task_list` and `fn_task_search`
byte-identical in intent to the agent-tools pair, plus a third site
filtering duplicate candidates. Same defect on all three. Reused the
(now exported) agent-tools helper rather than adding a third copy —
deliberately stronger than the two-parallel-tests reading of Surface
Enumeration, since the copies now share one implementation and cannot
drift. **Not claiming call-site coverage:** `createTriageTools` is
private and not drivable without standing up a TriageAgent; the helper
is revert-proofed, those two call sites are covered only through it.

6. **`mission-execution-loop` — a finished fix task read as LIVE,
stalling remediation.** The comment above that line states the rule it
implements: *only an open task makes duplicate triage safe to suppress.*
On a renamed board the rule inverts — a finished fix task is not
`done`/`archived`, so it reads as live, remediation for a fresh
validation failure is suppressed indefinitely, and the mission stalls
with no error surfaced.

**Not revert-proven, and I am not claiming it is.** No test reaches the
`hasLiveFixTask` branch, and the only case that mints a fix feature is
git-gated and heavyweight; building that fixture is larger than the
conversion. The change strictly *widens* the finished set (resolved
roles ∪ the two legacy ids), so default boards are byte-identical — that
is the argument for shipping it unproven, not a substitute for coverage.

7. **Four census-invisible membership guards**, each inverted on a
renamed board — `worktree-pool` (merger-managed branch reclaim could
delete a branch out from under an in-flight merge), `agent-assignment`
(assignment load counted nothing), `ephemeral-worker-manager`
(`isAgentIdle` inverted on both sides), and the dead constants their
conversion orphaned. These are `SET.has(task.column)` shapes the census
does not count, so the −15 understates them.

## Revert results (measured, each run)

| conversion | reverted → |
| --- | --- |
| `clearStaleBlockedBy` per-referenced lanes | renamed-vocabulary case
fails; stale `blockedBy` never clears |
| executor dependency satisfaction | dependent never unblocks on a
renamed review lane |
| `worktree-pool` merger-managed set | reclaim proceeds against an
in-flight merge |
| `ephemeral-worker-manager.isAgentIdle` | idle agent reads busy on a
renamed board |
| `fn_task_list` terminal filter | RENAMED case fails — shipped card
listed as active |
| `fn_task_search` terminal filter | RENAMED case fails — same,
independently |
| cross-parent diagnostic dedup | RENAMED case fails — `wasDuplicate:
true`, new work absorbed |
| bootstrap preflight archived guard | RENAMED case fails — `validate`
called with the archived sibling |
| gridlock dependency gate | RENAMED case fails — false gridlock raised
for an unblocked task |

`agent-assignment`'s widened `taskStore` type is compile-time; its
revert is a tsc failure, not a test failure — stated rather than claimed
as coverage.

## Verification

- `pnpm test:gate` — 161 + 487 + 13 + 71, all green (161 includes
`sync-workflow-ir-callsite-allowlist`)
- `npx tsc -p packages/engine/tsconfig.json --noEmit` — clean
- `pnpm lint` — clean

One commit is a pure import restore: `columnsWithFlag` arrived in a
sibling commit that built on the inert resolver and was left behind. The
engine tsconfig excludes `src/__tests__/**`, so the gate was green while
tsc was not — worth knowing that on this package a green gate is not a
green build.


## Verified NOT a gap — measured, so the next worker does not re-open
them

- **`restart-recovery-coordinator` (5 counted).** Four already take an
optional `reviewColumns` set and the counted literals are the documented
**fallback** arm, which must stay for the same reason `columnRoles.ts`
keeps its id fallback. The sole production caller
(`self-healing.ts:12151-12154`) already passes the resolved set. The
fifth is documented at the site as a re-assertion behind a `listTasks({
column: "in-progress" })` query filter. Nothing to convert.
- **`notification/notification-service` (5 counted).** Already
documented in-file as deliberately counted with no exemption marker: the
wedge-episode site needs per-task serialisation of wedge handling (a
delivery-semantics change to operator notifications), and
`isManualMergeHold` needs a pre-resolved `LifecycleColumns` threaded
through `handleTaskUpdated`, which would pay resolution on every task
update. Both are behaviour/placement judgements, not conversions.
- **`planner-overseer` (3 counted).** `resolveWatchedStage`'s two
literals are fed by `pollPlannerOverseer`, which calls `listTasks({
column: "in-progress" })` and `{ column: "in-review" }` — hardcoded
**query** filters. On a renamed board those queries return no rows, so
the predicate never sees a renamed column. Converting it alone would
drop 3 from the census and change nothing an operator can observe. The
real fix is at the query layer; that is the tracked query-filter-bounded
class, not this PR.
- **`triage:695`** reads `resolvePlannerLanes` → the allow-listed sync
IR reader. Left as an honest literal per the rule above.

**Still open in `packages/engine`, deliberately not in this PR:**
`self-healing.ts` (97, of which ~31 are the query-filter-bounded class
and the rest need per-site classification in a 13k-line file),
`scheduler.ts` (12, blocked on the sync reader above), `executor.ts`
(12), and a tail of ~13 more copies of the "is this task finished?"
question across eight small files (`agent-reflection`,
`auto-merge-finalization`, `merger-scope-auto-widen`,
`backlog-pressure-reporter`, `merger-orphan-rehome`,
`merger-integration-worktree`, `plugin-runner`, `cli-agent/*`). That
tail is a clean follow-up: one question, eight call sites, and the
exported `resolveTerminalColumnsForTasks` helper already exists for it.

That is the same discipline as the sync-resolver finding: a census
number that drops without a behaviour change is not progress, and four
of these files would have handed over exactly that.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 10:47:44 -07:00
2026-07-11 22:35:36 -07:00
2026-07-26 18:11:47 -07:00

Fusion

From rough idea to production code — automatically.

🏭 A software factory, run by a multi-agent orchestrator.

Describe what you want — a team of AI agents plans, builds, reviews, and ships it for you. Fusion is your software factory: an assembly line for code that runs across tasks, agents, missions, git, files, and worktrees, with any model, local or cloud.

runfusion.ai → · Docs · GitHub · npm · Discord

English · 简体中文 · 繁體中文 · Français · Español · 한국어

License: MIT npm Discord Status Shipping


Fusion reel: from rough idea to production code

Fusion dashboard: Planning, Todo, In Progress, In Review, Done kanban columns with active task cards

Your entire dev environment. On a single pane of glass.

Describe a task in plain language. A planning agent reads your project, understands context, and writes a full PROMPT.md plan — steps, file scope, acceptance criteria. Then Fusion plans, reviews, executes, and reviews again, in an isolated git worktree, with a human approval gate wherever you want one.

One board. Controlled from anywhere. Laptop, Mac mini, Linux server, cloud VM, phone — all connected.

Like Trello, but your tasks get specified, executed, and delivered by AI. Built on the great work of dustinbyrne/kb.


Quick start

Zero install, straight from npm:

npx runfusion.ai

That launches the dashboard. Subcommands forward through: npx runfusion.ai task create "fix X", npx runfusion.ai --help, etc. (Or verbosely: npx @runfusion/fusion dashboard.)

One-line installer (macOS & Linux — auto-picks Homebrew, falls back to npm):

curl -fsSL https://runfusion.ai/install.sh | sh
fusion dashboard

Homebrew (macOS & Linux):

brew install runfusion/fusion/fusion
fusion dashboard            # or: fn dashboard

Fully-qualified install auto-taps and, on Homebrew 6.0+, trusts only the Fusion formula. If you already ran brew tap runfusion/fusion and short-name install fails with “untrusted tap”, run brew trust --formula runfusion/fusion/fusion then brew install fusion.

npm global:

npm install -g @runfusion/fusion
fn dashboard                # or: fusion dashboard

From a clone (for development):

pnpm dev dashboard

Then click the Open: URL printed in the terminal. It embeds a bearer token (http://localhost:4040/?token=fn_...) that the browser captures to localStorage on first visit and reuses automatically thereafter. On the server side, Fusion now persists the dashboard/daemon token in ~/.fusion/settings.json on first authenticated run and reuses it on later starts unless you override it (--token, FUSION_DASHBOARD_TOKEN, FUSION_DAEMON_TOKEN) or disable auth with --no-auth. See CLI reference → fn dashboard → Authentication for full precedence and reset/revocation options.

First-run setup

On first launch, Fusion opens the onboarding wizard with three guided steps:

  1. AI Setup — Use a simplified quick-start provider list (recommended providers plus any already-connected providers), then expand Advanced provider settings only if you need additional providers or setup details. You only need one provider to get started. Deprecated Google Gemini CLI / Antigravity provider entries are intentionally hidden; Google/Gemini API key, Google Generative AI, Vertex, and Cloud Code paths remain supported.
  2. GitHub (Optional) — Connect GitHub for issue import and PR management
  3. First Task — Create your first task or import from GitHub (if no project is active, onboarding first prompts you to register/select a project directory)

The wizard is dismissible and non-blocking — click Skip for now to use the dashboard immediately. Re-trigger it later from Settings → Authentication → Reopen onboarding guide.

Mobile

For Capacitor + PWA workflow, see MOBILE.md.


The flow

  ①  Describe          ②  Planning             ③  The board           ④  Isolated worktree
  ─────────────        ─────────────         ─────────────          ─────────────────────
  "Add dark mode   →   Agent writes    →   Plan → Review →    →   fusion/FN-123 branch
   toggle to           PROMPT.md           Execute → Review        concurrent, zero
   settings panel"     (steps, scope,      (per step, until        file conflicts
                       acceptance)         done)

See every step, before the merge

Fusion task detail: workflow steps visible on an in-progress task with diffs and file changes

Every task shows its plan, its reviews, its diffs, and its file changes in real time. Jump into an active task and nudge direction, tighten constraints, pause, or re-prompt.


What makes it different

🧠 AI planning Describe a task in plain language. Planning agents turn it into a PROMPT.md plan with steps, file scope, and acceptance criteria.
🔁 Selectable workflows Built-ins cover coding, quick fixes, review-heavy work, stepwise execution, plugin-gated Compound Engineering, and PR lifecycle fragments. Pick a workflow per task or author custom ones in the Workflow Editor.
🛡️ Planner oversight Per-task or per-workflow oversight level (off / observe / steer / autonomous) governs how closely a planner overseer watches and intervenes — merge/PR and destructive actions always require explicit human confirmation. See Settings Reference and Dashboard Guide.
🌳 Worktree isolation Each task runs in its own branch and worktree (fusion/{task-id}). Parallel tasks. Zero conflicts. Optional worktrunk delegation via worktrunk.enabled (see WorktreeBackend abstraction).
🗄️ PostgreSQL by default Fusion uses zero-config embedded PostgreSQL for local runtime metadata. Legacy SQLite files are one-time migration inputs only; use a shared external database for multi-project and multi-node setups. (Storage)
⚡ Smart merge controls Passing every gate? Fusion squash-merges and moves on. Opt into manual approval anywhere, inherit the live global auto-merge default, or set explicit per-task auto/manual overrides.
🛰️ Multi-node mesh Laptop, Mac mini, Linux server, cloud VM, phone — all synced. Desktop, mobile, web.
🧩 Any model Anthropic, OpenAI, Ollama, Google Generative AI, Z.ai, Kimi K3, local runtimes, and user-defined custom providers. Local and cloud coexist, with workflow model/fallback lanes configurable per project.
🏢 Agent companies Import pre-built teams — 440+ agents across 16 companies — and run them autonomously for weeks.
📬 Inter-agent messaging Built-in mailbox between agents. Delegate, clarify, coordinate; engineer-role agents can opt into backlog auto-claim when you want implementation help beyond executor-only pickup.
🗨️ Agent chat Direct chat, task chat that proactively narrates step progress, failures, and review outcomes, attachments, in-chat question cards, resumable streams, and experimental multi-agent Chat Rooms where mentioned members respond directly and ambient members can join up to a cap. (Chat docs)
🗺️ Missions Hierarchical planning (Mission → Milestone → Slice → Feature → Task) with autopilot and validation contracts.
🔬 Research Bounded research runs with web search, GitHub, local docs, and LLM synthesis (plus runtime builtin WebSearch/WebFetch support in planning + synthesis flows when available). Turn findings into tasks. (Docs)
🧪 Self-improvement Agents reflect on their own output and update their prompts as they learn your codebase.
🔓 Open source. MIT. No vendor lock-in. Run it on your own hardware. Shipping weekly.

See it in action

The newest surfaces in Fusion, at a glance — the live board, your agent team, mission control, visual workflows, agent chat, multi-agent rooms, and inter-agent mail.

📋 The board & your agent team — live, from a real fleet

Fusion board: Triage, Todo, In Progress, In Review, Done columns with live task cards across the Tokyo Night theme

Every task, every column, every step — live. Cards carry GitHub links, step counts, review levels, and promote/move/archive actions. Switch to the Graph view to see task dependencies as an interactive node graph:

Fusion board: Triage, Todo, In Progress, In Review, Done columns with live task cards
Board — kanban columns
Fusion graph view: task dependency graph with connected nodes
Graph — dependency map

Here is the same fleet re-skinned into the Ember theme (dark graphite with an orange accent), alongside the Agents roster:

Fusion board in the Ember theme
Board — Ember
Fusion Agents view: CEO, Product Manager, CTO, and engineers with roles and heartbeat status
Agents — Tokyo Night

Import a team and every agent shows up here — role, reports-to chain, heartbeat, and token share. Each agent card's heartbeat dropdown shows Disabled when scheduling is persisted off; choose Disabled to pause heartbeats while retaining its cadence, or select an interval to re-enable them. The Agents roster in Ember:

Fusion Agents view in the Ember theme

🛰️ Command Center — mission control for your agent fleet

Fusion Command Center: live concurrency gauges, token charts, and fleet telemetry across tabs

One screen for everything your agents are doing. Tune live scheduler capacity, watch token spend by model in real time, and prove the value with hard numbers. The Overview tab opens with live gauges and charts:

Fusion Command Center Overview: concurrency gauges, engine status, and fleet charts

Every tab is a different lens on the same live fleet:

Tokens by model, token trend, and tokens-over-time charts
Tokens — spend by model, cached vs. input vs. output, over time.
Productivity: commits, human-hours saved, task duration percentiles, and files by language
Productivity — outcomes, duration percentiles, language mix.
Agent org chart with token share and tokens-by-agent breakdown
Team — agent org chart and token share per agent.
Activity: task throughput and event timeline charts
Activity — task throughput and event timelines.
Signals: anomaly detection and fleet signal charts
Signals — anomaly detection and fleet health.
Command Center tab
More — Tools · Ecosystem · GitHub · System · Reliability.

Tokens · Tools · Activity · Productivity · Team · Ecosystem · GitHub · Signals · System · Reliability · Mission Control — every tab is a different lens on the same live fleet.

The same fleet, your way — Command Center (and the whole dashboard) re-skins live across 70+ color themes, including Cobalt, Clay, and Moss. Here it is in Shadcn Light, Shadcn Dark Gray, and Ember:

Command Center in Shadcn Light theme
Shadcn Light
Command Center in Shadcn Dark Gray theme
Shadcn Dark Gray
Command Center in Ember theme
Ember
A dozen light themes & a dozen dark themes (click to expand)
Command Center across 12 light color themes

Command Center across 12 dark color themes

🔁 Selectable workflows, authored visually

Fusion Workflow Editor: switching between built-in workflow graphs

A task's journey from idea to merge is a workflow — and it's yours to choose and shape. Pick a built-in (Coding, Quick fix, Review-heavy, Stepwise, PR lifecycle, Compound engineering, and more), inspect its graph, then duplicate and customize columns, gates, model lanes, and review policy in the visual Workflow Editor. No engine fork required.

Here's the Stepwise coding graph — plan, execute, and review every step before the next — explored node-by-node in Shadcn Light, Dark Gray, and Ember:

Stepwise coding workflow graph in Shadcn Light, panning across nodes
Shadcn Light
Stepwise coding workflow graph in Shadcn Dark Gray, panning across nodes
Shadcn Dark Gray
Stepwise coding workflow graph in Ember, panning across nodes
Ember

🗨️ Agent chat — talk to your agents, mid-flight

Fusion agent chat: a threaded conversation with an agent diagnosing a failed task

Direct chat and per-task chat with any agent, on any model. Ask why a task failed, steer an approach, drop attachments, answer in-chat question cards, and resume streams where you left off — full markdown and code rendering throughout.

Agent chat thread in Shadcn Light
Shadcn Light
Agent chat thread in Shadcn Dark Gray
Shadcn Dark Gray

👥 Multi-agent chat rooms

Fusion chat room: CEO, Product Manager, and CTO agents coordinating in #leads

Put multiple agents in a room and let them coordinate. Mention a member and it responds directly; ambient members can join the conversation up to a cap. Here the CEO, Product Manager, and CTO agents align on task ownership in #leads — no human in the loop. (Chat docs)

Multi-agent chat room in Shadcn Light
Shadcn Light
Multi-agent chat room in Shadcn Dark Gray
Shadcn Dark Gray
Multi-agent chat room in Ember
Ember

📬 Agent mail — an inbox between your agents

Fusion mailbox: inter-agent messages with triage summaries and approvals

A built-in mailbox for delegation, clarification, and hand-offs. Agents file triage summaries, request approvals, and coordinate work across the fleet — with Inbox, Outbox, Agents, and Approvals views, so you can audit every exchange.

Agent mailbox in Shadcn Light
Shadcn Light
Agent mailbox in Shadcn Dark Gray
Shadcn Dark Gray
Agent mailbox in Ember
Ember

📱 Fusion is an AI factory in your pocket

The full board, Command Center, missions, agents, and chat travel with you — native iOS and Android apps (Capacitor) plus an installable PWA. Start a run on your laptop, steer it from your phone.

Fusion mobile: board Fusion mobile: Command Center Fusion mobile: missions
Fusion mobile: agents Fusion mobile: agent chat Fusion mobile: chat list

See MOBILE.md for the Capacitor + PWA workflow.


How it works

graph TD
    H((You)) -->|rough idea| T["Planning<br/><i>auto-planning</i>"]
    T --> TD["Todo<br/><i>scheduled for execution</i>"]
    TD --> IP["In Progress<br/><i>for each step:<br/>plan, review, execute, review</i>"]

    subgraph IP["In Progress"]
        direction TD
        NS([Begin step]) --> P[Plan]
        P --> R1{Review}
        R1 -->|revise| P
        R1 -->|approve| E[Execute]
        E --> R2{Review}
        R2 -->|revise| E
        R2 -->|next step| NS
        R2 -->|rethink| P
    end

    R2 -->|done| IR["In Review<br/><i>ready to merge,<br/>or auto-complete</i>"]
    IR -->|direct squash merge<br/>or merged PR| D["Done"]

    style H fill:#161b22,stroke:#8b949e,color:#e6edf3
    style T fill:#2d2006,stroke:#d29922,color:#d29922
    style TD fill:#0d2044,stroke:#58a6ff,color:#58a6ff
    style IP fill:#1a0d2e,stroke:#bc8cff,color:#bc8cff
    style P fill:#1a0d2e,stroke:#bc8cff,color:#e6edf3
    style R1 fill:#1a0d2e,stroke:#bc8cff,color:#e6edf3
    style E fill:#1a0d2e,stroke:#bc8cff,color:#e6edf3
    style R2 fill:#1a0d2e,stroke:#bc8cff,color:#e6edf3
    style NS fill:#1a0d2e,stroke:#bc8cff,color:#bc8cff
    style IR fill:#0d2d16,stroke:#3fb950,color:#3fb950
    style D fill:#1a1a1a,stroke:#8b949e,color:#8b949e

Tasks with dependencies are processed sequentially. Independent tasks run in parallel. Optionally require manual approval before tasks move from Planning to Todo (requirePlanApproval setting).


Workflow overview

Fusion workflows define how a task moves from idea to delivery. The default coding path is still the familiar Plan/Triage → Execute → Workflow steps → Review → Merge loop, but the policy now lives in a selectable workflow rather than being only hard-coded engine behavior.

  • Select per task: choose a workflow from the dashboard task/board workflow controls, or assign one through fn_workflow_select / workflow_id when creating tasks.
  • Built-in catalog: Coding (builtin:coding), Quick fix (builtin:quick-fix), Review-heavy (builtin:review-heavy), Compound engineering (builtin:compound-engineering, plugin-gated), Stepwise coding (builtin:stepwise-coding), and the PR lifecycle (builtin:pr-workflow, a reusable PR graph fragment).
  • Customize safely: inspect built-ins, duplicate them, or author custom workflows in the visual Workflow Editor. Workflow-specific settings cover model lanes, review/approval policy, step execution knobs, task fields, and columns.

Read Workflow Steps for runtime semantics, built-in workflow behavior, and workflow-step templates; read Workflow Editor for the dashboard authoring guide.

Planner oversight

Each workflow (and optionally each task) can set a planner oversight level — off, observe, steer, or autonomous (default) — controlling how closely a planner overseer watches and intervenes in that task's execution. Even at autonomous, merge/PR progression and any destructive or external-service side effect always require an explicit, recorded human confirmation before they run. Notification verbosity is controlled separately. Set the default in the Workflow Editor → Values tab, or override per task from the New Task dialog / Task Detail edit form. Read Settings Reference for the full setting semantics and Dashboard Guide for the UI controls.


Multi-node. One board. Every platform.

Fusion mesh: laptop, Mac mini, Linux server, cloud VM, phone — all synced

macOS Windows Linux Web iOS Android

Laptop, Mac mini, Linux server, cloud VM, phone — every node is a peer. Your task state, agents, logs, and diffs stay synchronized across the mesh. The same Fusion ships as:

  • 🖥️ Desktop app — Electron for macOS (Intel + Apple Silicon), Windows 10/11, and Linux
  • 📱 Mobile app — Capacitor for iOS/iPadOS and Android (MOBILE.md)
  • 🌐 Web dashboard — any modern browser, served from the fn dashboard daemon
  • 🔌 CLI — fn binary + extension for terminal-first workflows

Start the daemon on any node, connect your other devices, and the board follows you everywhere.


Run an agent company

Fusion agent company: import a team, run it autonomously for weeks

Import a team. Run it autonomously for weeks. 440+ agents across 16 companies, wired for missions, mailboxes, and inter-agent delegation.

npx companies.sh add paperclipai/companies/gstack

Compatible with the tools you already use.

Fusion integrates with the tools you love. Hermes, Paperclip, and OpenClaw all ship as first-class plugins — route any workspace to whichever runtime fits the task. And any Paperclip agent-company imports with a single command.

Hermes

Hermes experimental

Nous Research

The open-source autonomous agent from Nous Research. Install the Hermes plugin and run agents through Hermes for long-running, context-growing work — route any Fusion workspace to it.

OpenClaw experimental

OpenClaw runtime support is available as an experimental plugin (fusion-plugin-openclaw-runtime) for runtime discovery/configuration parity. Configure agents with runtimeConfig.runtimeHint: "openclaw" after installing the plugin.


Paperclip

Paperclip experimental

paperclip.ing

The human control plane for AI labor. Install the Paperclip plugin to run agents through Paperclip inside Fusion.

Fusion also natively supports the companies.sh agent-company standard: import a prebuilt team — 440+ agents across 16 companies — and let them coordinate over Fusion's mailbox, missions, and workflow gates for weeks of autonomous work. Same company format, same agents, same skills as Paperclip.

npx companies.sh add paperclipai/companies/gstack

Hermes, Paperclip, and OpenClaw are experimental runtime plugins — APIs and wire formats may shift between minor releases.


Documentation

Guide What it covers
Getting Started Installation, onboarding, first task, and workflow-selection basics
Dashboard Guide Board/list views, chat, workflow editor, git manager, settings, and UI tools
Task Management Task lifecycle, prompt specs, comments, archiving, and GitHub integration
CLI Reference Full fn command and daemon reference
Settings Reference Global/project settings, model hierarchy, workflow settings, and custom providers
Workflow Steps Workflow runtime, built-in workflows, gates, templates, and phases
Workflow Editor Visual authoring, importing/exporting, custom fields/columns/settings, and mobile editor
Research Bounded research runs, findings, exports, and task integration
Agents Agent management, spawning, heartbeat, and mailbox workflows
Missions Mission hierarchy, planning, autopilot, and validation contracts
Plugin Management Discovering, installing, enabling, configuring, and troubleshooting plugins
Plugin Authoring Building plugins with lifecycle hooks, routes, tools, runtimes, and dashboard surfaces
Remote Access Tokenized remote dashboard access, Tailscale/Cloudflare setup, and troubleshooting
Multi-Project Central registry, isolation modes, and migration paths
Storage PostgreSQL runtime storage, migration compatibility, and file-backed payloads
Docker Container deployment

Core features

  • AI Planning — Planning agent generates detailed PROMPT.md with steps, file scope, and acceptance criteria
  • Step-by-step Execution — Plan → Review → Execute → Review cycle for each task step, with graph-mode workflows able to model per-step parse/execute/review/rework explicitly
  • Git Worktree Isolation — Each task runs in its own worktree (fusion/{task-id} branch)
  • Selectable workflows — Pick Coding, Quick fix, Review-heavy, Stepwise coding, plugin-gated Compound Engineering, custom workflows, or PR lifecycle fragments where appropriate (overview; Workflow Steps)
  • Visual Workflow Editor — Inspect read-only built-ins, duplicate/customize workflows, and edit graph nodes, columns, task fields, typed settings, and per-project values (Workflow Editor)
  • Workflow Steps — Configurable quality gates (pre-merge: blocks merge; post-merge: informational), plus workflow-declared optional steps such as opt-in Browser Verification
  • Workflow-native policy — Fast-mode planning (leanPlanning / autoApproveSpec), typed triage thresholds, review/approval, step execution, and model/fallback lanes are workflow settings, not hard-coded engine constants (Settings Reference; workflow settings)
  • Planner oversight — Workflow-native plannerOversightLevel (off/observe/steer/autonomous), with an optional per-task override and a separate notification-verbosity setting; merge/PR progression and destructive actions always require explicit human confirmation, even at autonomous (overview; Settings Reference)
  • GitHub + PR lifecycle — Import issues with optional translation and screenshot attachments, skip previously imported issues even after edits or repository casing changes, create PRs, display real-time PR/issue badges, and use workflow-mode PR lifecycle graph fragments where enabled
  • Dashboard — Real-time kanban/list/graph views, a project Overview with local codebase token estimate and on-disk size, agent management, terminal, git manager, mission planner, chat, workflow editor, custom provider setup, and one-click update action
  • Missions — Hierarchical planning (Mission → Milestone → Slice → Feature → Task) with autopilot, validation contracts, fix-feature retries, mission-goal linking, and blocked-handoff semantics
  • Multi-Project — Manage multiple projects from a single installation with project isolation
  • Custom Providers — Add OpenAI-compatible, OpenAI Responses, Anthropic-compatible, or Google Generative AI providers; saved models appear in Project Models and workflow model dropdowns (Dashboard Guide; settings shape)
  • Smart merge controls — Global auto-merge stays live for default tasks, while explicit per-task overrides can force auto/manual behavior (Settings Reference)
  • Inter-Agent Messaging — Built-in messaging for coordination between agents and users; engineer-role agents can opt into backlog auto-claim for implementation tasks (Settings Reference)
  • Agent Chat + Chat Rooms — Direct/task chat supports attachments, resumable streams, question response cards, and renameable conversations; experimental rooms route mentioned members as direct responders with optional ambient replies (Dashboard Guide → Chat View)

Provider authentication

Fusion supports OAuth-based authentication for AI providers configured via Settings → Authentication. For most OAuth providers, when the dashboard is accessed via a non-localhost host (remote node, LAN host/IP, or reverse proxy), provider login URLs are rewritten to route OAuth callbacks through a bridge endpoint (/api/auth/oauth-callback) so redirects reach the active browser session.

  • Anthropic (Claude) — Uses a pasted authorization-code flow in Settings/onboarding: sign in, then paste the final redirect URL (or code) back into Fusion to complete login
  • OpenAI Codex — Uses the same pasted authorization-code flow with secure state validation
  • Factory AI — via Droid CLI (optional) — requires local Droid CLI install + droid auth login; detection follows the effective runtime binary path (default droid, or plugin droidBinaryPath when configured), then enable in Settings → Authentication and restart Fusion
  • llama.cpp — via HTTP server (optional) — configure your llama.cpp server URL (default http://127.0.0.1:8080) and optional API key, then enable in Settings → Authentication
  • Other providers — Authenticate via API key entry in Settings (including Google/Gemini API key, Google Generative AI, Vertex, and Cloud Code aliases)
  • Custom providers — Add user-defined OpenAI-compatible, OpenAI Responses, Anthropic-compatible, or Google Generative AI endpoints from Settings → Authentication → Custom Providers; saved model IDs become selectable in project and workflow model lanes (Dashboard Guide)

Model system

Fusion uses a dual-scope model hierarchy with independent lanes. Global settings define baseline defaults; project settings provide per-project overrides.

Lane Purpose Global Baseline Keys Project Override Keys
Executor Task execution agent executionGlobalProvider + executionGlobalModelId executionProvider + executionModelId
Planning Task planning agent planningGlobalProvider + planningGlobalModelId planningProvider + planningModelId
Validator Plan/code reviewer validatorGlobalProvider + validatorGlobalModelId validatorProvider + validatorModelId
Merger Merge conflict / clean-room merge agent mergerGlobalProvider + mergerGlobalModelId mergerProvider + mergerModelId
Title Summarization Auto-title generation titleSummarizerGlobalProvider + titleSummarizerGlobalModelId titleSummarizerProvider + titleSummarizerModelId
Workflow Step Refinement AI prompt refinement (uses defaultProvider/defaultModelId) (uses modelProvider/modelId on WorkflowStep)

Workflow lanes: The default workflow exposes Plan/Triage, Executor, Reviewer, and fallback model lanes in Settings → Project Models, and advanced workflow settings can declare additional typed model/policy values (Settings Reference).

Per-Task Overrides: Quick Add and Inline Create let tasks override the planning, executor, validator, and merger lanes; planning, validator, and merger selections also support task-specific thinking levels. (modelProvider/modelId, validatorModelProvider/validatorModelId, planningModelProvider/planningModelId, and merger model/thinking overrides.)

Precedence: Per-task → Project override → Global lane → defaultProvider/defaultModelId → Automatic resolution.

For full settings documentation, see Settings Reference.

Scheduled tasks / automations

Fusion supports scheduled task automation via the /api/automations endpoints. Automations can run shell commands or multi-step workflows on a configurable schedule.

Scheduling scope

Automations and routines can run in two scopes:

  • Global — Runs across all projects. Use this for cross-project maintenance, backups, or unified reporting.
  • Project — Runs only within a specific project. Use this for project-specific CI, testing, or deployment tasks.

When you create a schedule without choosing a scope, Fusion defaults to project scope with the default project ID for backward compatibility.

To explicitly target a scope:

  • In the dashboard Scheduled Tasks modal, use the Global / Project toggle.
  • Via the API, pass ?scope=global or ?scope=project&projectId=<id> on automation/routine endpoints.

Scope resolution rules:

  • scope=global always resolves to the global automation/routine lane, independent of the active project.
  • scope=project requires a projectId. If omitted, it falls back to "default".
  • CRUD, run, toggle, and webhook operations are strictly scope-isolated: a global schedule cannot be mutated from a project-scoped request, and vice versa.

Operational guidance for multi-project setups:

  • Prefer global schedules for shared infrastructure (e.g., nightly backups, memory insight extraction).
  • Prefer project schedules for per-repository automation (e.g., per-project test runners, deployment hooks).
  • Global and project lanes are polled independently by the engine, so due runs in one lane do not block the other.

Automations

Endpoint Method Description
/api/automations GET List all automations (filtered by scope if specified)
/api/automations POST Create automation (scope defaults to project)
/api/automations/:id GET Get automation by ID
/api/automations/:id PATCH Update automation
/api/automations/:id DELETE Delete automation
/api/automations/:id/run POST Trigger manual run
/api/automations/:id/toggle POST Toggle enabled/disabled
/api/automations/:id/steps/reorder POST Reorder automation steps

Routines

Routines are AI agent tasks triggered by cron schedules, webhooks, or manual execution. Routines share the same global/project scope model as automations.

Endpoint Method Description
/api/routines GET List all routines (filtered by scope if specified)
/api/routines POST Create routine (scope defaults to project)
/api/routines/:id GET Get routine by ID
/api/routines/:id PATCH Update routine
/api/routines/:id DELETE Delete routine
/api/routines/:id/run POST Manual trigger
/api/routines/:id/trigger POST Canonical manual trigger
/api/routines/:id/runs GET Get execution history
/api/routines/:id/webhook POST Webhook trigger (signature verification supported)

CLI quick examples

fn task create "Fix the login bug"                    # Quick entry → planning
fn task plan "Build auth system"                      # AI-guided planning
fn task import owner/repo --labels bug                # Import GitHub issues
fn task show FN-001                                   # View task details
fn task logs FN-001 --follow                          # Stream execution logs
fn task steer FN-001 "Use TypeScript"                 # Guide the agent mid-execution

fn project add my-app /path/to/app                    # Register a project
fn project list                                       # List all projects

fn settings set maxConcurrent 4                       # Configure settings
fn settings export                                    # Export configuration

fn mission create "Auth System" "Build auth"          # Create mission
fn mission activate-slice <slice-id>                  # Activate a slice

fn skills search react                                # Search skills.sh
fn skills install firebase/agent-skills               # Install agent skills

Packages

Package Description
@fusion/core Domain model — tasks, board columns, PostgreSQL stores
@fusion/dashboard Web UI — Express server + kanban board with SSE
@fusion/engine AI engine — planning, execution, scheduling, workflow steps
@runfusion/fusion CLI + extension — published to npm

Development

pnpm install                  # Install dependencies
pnpm local                    # Start local dashboard/API + AI engine on a non-4040 port
pnpm local --no-engine        # Start local dashboard/API only
pnpm build                    # Build default workspace packages (excludes desktop/mobile)
pnpm build:all                # Build all packages (including desktop/mobile)
pnpm dev dashboard            # Run dashboard + AI engine
pnpm dev:ui                   # Dashboard only (no AI engine)
pnpm lint                     # Lint all packages
pnpm typecheck                # Type-check all packages
pnpm test                     # Run all tests

Build a standalone executable

Build a single self-contained fn binary using Bun:

pnpm build:exe                # Build for current platform
pnpm build:exe:all            # Cross-compile for all platforms

License

MIT — open source, no vendor lock-in. See LICENSE.

Description
Fork of github.com/Runfusion/Fusion with Coolify-friendly Dockerfile
Readme MIT 547 MiB
Languages
TypeScript 94.3%
CSS 2.9%
JavaScript 2.6%