The merge normalizes button utility classes in AgentsView, swapping 12 lines of CSS class references for their standardized counterparts for consistency and maintainability. Fusion-Task-Id: FN-3448
6.5 KiB
Multi-Project
Fusion can coordinate multiple repositories from one installation, with shared visibility and global concurrency control.
Why Use Multi-Project Mode?
Use multi-project mode when you need to:
- Operate many repos from one dashboard/CLI
- Standardize settings and workflows across projects
- Monitor global activity and system-wide execution capacity
Central Database Architecture
Multi-project metadata is stored in:
~/.fusion/fusion-central.db
Core tables:
projectsprojectHealthcentralActivityLogglobalConcurrencynodespeerNodessettingsSyncState__meta
Per-project task data remains in each repo’s .fusion/fusion.db.
Peer/mesh coordination spans core + engine, with startup ownership in CLI process entrypoints:
NodeDiscoveryandNodeConnectionin@fusion/corehandle discovery and remote node connectivity/auth primitives.PeerExchangeServicein@fusion/enginecoordinates node-to-node sync/exchange workflows.- Canonical replication semantics live in
docs/shared-mesh-protocol.md. That protocol separates strongly coordinated shared state from append-only streams, queued replay classes, and node-local runtime state. runServe()andrunDashboard()(CLI) own process-level mesh service lifecycle:- start one process-wide
PeerExchangeServiceinstance - call
CentralCore.startDiscovery()only after the HTTP server is listening and the real bound port is known - stop peer exchange + discovery on shutdown
- start one process-wide
InProcessRuntimeremains project-scoped (scheduler/executor/heartbeat/missions) and does not start mesh services, which avoids one peer-exchange instance per project.
Registering and Managing Projects
fn project add my-app /path/to/app
fn project list
fn project show my-app
fn project set-default my-app
fn project detect
fn project remove my-app --force
--project Flag and Resolution
You can target a project explicitly:
fn task list --project my-app
fn task create "Fix oauth callback" --project my-app
Resolution order without --project:
- explicit flag
- default project
- current-directory auto-detection
Project Health Tracking
Central health tracking keeps mutable project metrics, including:
- active task counts
- in-flight agent counts
- project status (
initializing,active,paused,errored)
Global Concurrency Management
A singleton central record enforces system-wide limits so one project cannot monopolize all execution slots.
Isolation Modes
Projects can run with:
in-process(default): low overhead, shared processchild-process: stronger isolation with independent process boundary
Node Routing
Multi-project deployments use two related node fields at different layers:
- Project runtime placement (
projects.nodeIdin~/.fusion/fusion-central.db)- Decides where a project runtime is hosted in multi-project orchestration.
- Task dispatch default (
defaultNodeIdin project settings)- Decides where tasks route when they do not have a per-task override.
These fields are intentionally distinct.
Runtime placement (projects.nodeId)
ProjectManager uses project registration data plus isolation mode to pick runtime type:
isolationMode: "child-process"→ alwaysChildProcessRuntimeisolationMode: "in-process"+ remoteprojects.nodeId→RemoteNodeRuntimeisolationMode: "in-process"+ local/unset/missing node assignment →InProcessRuntime
So projects.nodeId is a project host-node assignment, not a per-task override.
Task routing defaults (defaultNodeId + Task.nodeId)
Within a project runtime, effective task routing resolves as:
- task override (
Task.nodeId) - project default (
defaultNodeId) - local execution
This allows each project to maintain independent routing behavior even when managed from one central registry.
Unavailable node policy in multi-project context
unavailableNodePolicy is project-scoped and can be set differently per project (block or fallback-local).
Current behavior: scheduler dispatch records effective node/source for each task, but health-based block/fallback enforcement is not yet applied in the scheduler dispatch path.
Example: different node defaults per project
- Project A (
projects.nodeIdassigned to remote host): runtime executes viaRemoteNodeRuntime;defaultNodeId=edge-aroutes unpinned tasks to edge-a. - Project B (
projects.nodeIdunset): runtime stays localInProcessRuntime;defaultNodeId=edge-bstill marks its task dispatch default independently.
See also:
- Settings Reference → Node Routing settings
- Task Management → Node Routing
- Architecture → Task Routing Architecture
Auto-Migration from Single-Project
On first run after upgrade:
- Existing project databases are detected
- Projects are registered into central DB automatically
- Existing single-project workflows continue working
Migration is idempotent and designed to avoid repeated re-registration.
Rollback Procedure
If central registry behavior needs to be reverted:
- Delete
~/.fusion/fusion-central.db - Keep using per-project
.fusion/fusion.dbdata - Fusion falls back to legacy/single-project behavior
- Re-register projects later with
fn init/fn project add
Runtime Architecture
ProjectRuntime interface
Each project runtime supports start/stop/status/metrics and access to scheduler/task store (for in-process mode).
HybridExecutor
HybridExecutor orchestrates all project runtimes and forwards project-attributed events.
IPC Protocol (child-process mode)
Host → worker commands include:
START_RUNTIMESTOP_RUNTIMEGET_STATUSGET_METRICSGET_TASK_STOREGET_SCHEDULERPING
Worker → host events include:
TASK_CREATEDTASK_MOVEDTASK_UPDATEDERROR_EVENTHEALTH_CHANGED
HybridExecutor Diagram
flowchart TD
HE[HybridExecutor]
PM[Project Manager]
CC[CentralCore]
HE --> PM
HE --> CC
PM --> A[Project A Runtime\n(in-process)]
PM --> B[Project B Runtime\n(child-process)]
PM --> C[Project C Runtime\n(in-process)]
B --> IPC[IPC Worker Channel]
See also: Architecture, CLI Reference, and Missions.