Multi-Agent Orchestration
Run multiple AI agents on one project in parallel, without them stepping on each other. luvus coordinates the team through a shared task board: every worker can run in an isolated git worktree or an explicit shared workspace task tab. Path leases coordinate intended edits, quality gates verify work before it counts, and a merge gate integrates finished worktree branches without touching your checkout.
The concepts
Section titled “The concepts”| Concept | What it is |
|---|---|
| Task | A unit of work: title, the file globs it will touch, dependencies, and an optional quality-gate command. Gets an id like t1. |
| Automation | A durable one-time or recurring definition. Each due occurrence creates a fresh ORCH task and starts its configured agent. Future work owns no pane, lease, or worktree before it is due. |
| Lease | A reservation on file paths. Two workers can’t hold overlapping globs, so conflicting work can’t be assigned. |
| Worker | A task-owned pane. Worktree mode uses a dedicated branch and checkout; workspace mode uses a dedicated task tab in an existing shared checkout. |
| Quality gate | A command (e.g. cargo test) that runs when a task is marked done. It must pass before the task can merge. |
| Merge gate | Integrates a finished branch into luvus/integration inside a dedicated worktree, never your working checkout. A conflict blocks the task instead of corrupting anything. |
Task lifecycle: queued → claimed/running → done when the gate passes.
A failed gate enters review; fixing the work and retrying the gate returns it
to done. Only done or a merge-conflict blocked task can enter merging,
then finish as merged or return to blocked on conflict. Only one task
integrates at a time. An interrupted integration restores its prior done or
blocked state after restart. Branch-backed dependents wait for merged, so
they never start before their dependency is available in the integration
history. Each named server session owns its own orch.json ledger inside that
session’s Luvus directory.
Automation definitions and bounded run history live in the selected server
session’s automations.json. The detached server owns their deadlines, so
closing the TUI does not pause them. Stopping the server does; on restart Luvus
reconciles persisted ORCH provenance before starting anything and applies the
definition’s missed-run policy. A scheduled agent cannot survive its owning
server, so an in-progress task from the previous server lifetime is recorded as
failed instead of being left running or launched twice. A task whose durable
provenance was saved before its worker started resumes that same pending run.
An active-agent target is different: it creates no ORCH task and is bound to
one live terminal lifetime. Restarting the server disables that definition
instead of sending its prompt to a restored or unrelated pane.
For schedule syntax, access profiles, missed-run policies, UHP requests, and a copyable example, see Agent Automation.
Every new task is bound to the project of the selected workspace. Git
worktrees from one repository share a project identity, while unrelated
repositories have independent task queues and path leases. task next only
selects work from its workspace’s project, so changing the focused workspace
cannot launch an older task in the wrong repository. Commands run inside a
Luvus pane infer its workspace. Callers outside a pane must pass
--workspace-id when multiple repositories or multiple non-Git projects are
open; use luvus workspace list to discover the stable id. When the focused
workspace belongs to the session’s only Git repository, an incidental non-Git
launch-directory workspace does not make that repository ambiguous. Legacy
tasks use the same rule when acquiring project metadata.
task start validates the task’s path lease before it creates a worktree or
workspace worker pane. If another task already holds an overlapping path, start
returns lease_conflict and leaves the queued task untouched. After a server
restart, leases follow workers that were restored to new pane IDs; leases with
no live task owner are discarded so stale reservations cannot block the queue.
Overlapping paths conflict only inside the same project. If older persisted
state contains two already-running workers with overlapping paths, Luvus keeps
the existing holder and marks the unprotected task blocked.
When an agent is selected, Luvus queues a short private-runner command and Enter as one submission before it marks the task running. The runner reloads the claimed task and passes its complete briefing directly to the agent process, so long or multiline prompts never cross the shell’s terminal-input line buffer. A queue failure closes the new pane and leaves the task unclaimed without closing any pre-existing worker. Any workspace, worktree, or branch created only for that failed attempt is removed, and the previous workspace selection is restored. Multiline prompts and progress notes remain structured in both task storage and the briefing delivered to the agent.
The board
Section titled “The board”Open the ◇ orch tab with Ctrl+Space o. It shows every task (status ·
id · title · dependencies · mode · worker location once started) and the active
leases, live. Navigate with j/k, the wheel, or click a row. On a wide
terminal, the selected task’s branch, paths, gate, output, and notes stay visible
in a detail panel.
The header switches between Tasks and Automations BETA. The automation view
shows the definition state, retained schedule, next UTC deadline, target agent,
target mode, and target workspace. Use e to pause or re-enable the selected definition,
r to request one run without advancing its schedule, and D to delete an
idle definition. Press o or Enter to inspect its trigger, timezone, next five
occurrences, execution policy, task template, and bounded run history; click
outside that detail popup or press Esc to close it. Armed
definitions also appear in the sidebar’s Active agents section as scheduled;
the placeholder is replaced by the normal live agent row when a new ORCH task
starts. An active-agent definition instead delivers into its already-visible
agent row. Clicking a scheduled placeholder or a Mission Control automation row
opens the same read-only detail. Mission Control shows aggregate armed, live,
review, and failed automation health without polling usage data.
Mouse controls follow the same validated actions as the keyboard and CLI:
- click a task to select it;
- select a task to inspect it in the wide details panel;
- double click a task to jump to its worker pane, the same as
Enter; - use
oor Details in the context menu for longer output and note history; - click its worker label to jump to the worker pane;
- right click a task for the actions valid in its current state;
- click New task or New automation to open the contextual form, then click the Task/Automation tab, fields, and form actions;
- choose worktree or workspace in the first start-worker step, then choose an agent in the second step;
- when the board is empty, click the Worktree/Workspace labels in the Flow panel to compare their lifecycle diagrams. This is informational and does not change the next worker’s mode.
The task menu stays bound to the task that opened it, even if the board changes before an action is chosen.
| Key | Action |
|---|---|
Tab |
switch between the Tasks and Automations views |
a |
new: open Task creation from Tasks or Automation creation from Automations (Tab switches type, ↑/↓ moves fields, ⏎ creates) |
o / Enter |
inspect the selected automation when the Automations view is active |
s |
start: choose worktree/workspace mode, then choose an agent |
d |
done: runs its quality gate (pass → done, fail → held at review) |
m |
merge into luvus/integration |
⏎ |
jump to its worker pane |
x |
release an active task and its path leases |
q |
close the board without stopping tasks or workers |
The form starts on a compact Task · Automation choice. The active board view
selects its matching type by default. Task shows Title, Paths, Deps, Gate, a
Manual/Now Start choice, and a three-row Prompt editor; Agent appears only
for Now. Automation
hides concrete dependencies and owns a registry-backed Agent, an explicit
Run in choice for an isolated Worktree or the existing Workspace, an Access
choice (Read only, Workspace, or Full access), Once later,
Hourly, Daily, or Weekly, and Schedule, followed by a three-row Prompt editor. Use
Tab to switch between Task and Automation, Down or Up to move between fields,
Left/Right to change the selected Agent, Run in, Access, or Start value, and
Shift+Enter to add a new line to either prompt. Plain Enter creates the task
or automation. Pasted task prompts preserve line breaks, and long titles scroll
horizontally with the active cursor instead of hiding the end. Agent
choices come from the built-in adapters that declare at least one reviewed
unattended launch profile. A selected agent/access combination that is not supported
is rejected before Luvus creates a task, worktree, lease, or pane. Task and Automation
retain independent drafts while the modal is open, so switching type and returning
restores that type’s inputs, selections, and focused field.
Manual preserves ordinary task creation. Now creates and starts one ORCH
task. Automations store a template and do not create the concrete task until it
is due. The form detects the server user’s IANA timezone and shows it beside the
Automation Start choice. Schedule input uses that local wall-clock time:
YYYY-MM-DD HH:MM for Once, a minute from
00 through 59 for Hourly, HH:MM for Daily, and mon,fri HH:MM for
Weekly. Changing Start fills Schedule with a valid editable value; the first
typed character replaces that suggestion. CLI and UHP continue to require
explicit UTC or timezone fields.
Calendar schedules retain their IANA timezone but persist each execution deadline as UTC. Across daylight-saving changes, Luvus keeps the requested wall-clock time, shifts a nonexistent time forward by the transition gap, and uses only the first occurrence of a repeated time. Preview deadlines before arming remote definitions when timezone behavior matters.
The current beta is time-triggered. ORCH task dependencies can make a task ready after another task completes, but they do not automatically trigger an Automation definition.
A worked example
Section titled “A worked example”Say you want an auth module and an API layer that depends on it:
a→ TitleOAuth token module, Pathssrc/auth/**, Gatecargo test auth, PromptImplement the token parser and cover rollback behavior,⏎.a→ TitleAPI layer, Pathssrc/api/**, Depst1,⏎.- Select
t1and presss. luvus creates a worktree on branchluvus/t1, opens a pane in it, and takes you there. Run your agent in that pane (or pass--agentvia the CLI to launch one automatically). - When the work looks finished: back to the board,
d. The gate (cargo test auth) runs in the background. Pass andt1is done. Fail and it’s held at review with the output saved on the task. - Select
t1, pressm, and its branch merges intoluvus/integrationin an isolated worktree. The task moves through merging to merged and records the exact integration commit. A conflict aborts Git and marks the task blocked rather than leaving a half-merge. - Once
t1is merged,t2becomes claimable. Select it, presss, and repeat.
Your own checkout on main was never touched at any point.
Driving it from the CLI (and from agents)
Section titled “Driving it from the CLI (and from agents)”Everything the board does is a command, which is how an orchestrator agent can run the whole loop itself:
# create + inspectluvus task add "OAuth module" \ --prompt "Implement the token parser and cover rollback behavior." \ --paths "src/auth/**" --gate "cargo test auth" \ --workspace-id workspace_exampleluvus task list · get t1luvus task update t1 --prompt-file ./task-brief.md # editable until the task startsluvus task update t1 --status running --note "learning: …"
# start workers (worktree remains the default)luvus task start t1 --agent "claude"luvus task next --start --agent "claude" --workspace-id workspace_example
# stage a worker without leaving the workspace, tab, or pane you are viewingluvus task start t3 --agent "codex" --workspace-id workspace_example --no-focus
# run directly in an existing checkout (no branch or merge step)luvus task start t2 --mode workspace --agent "codex"
# finish + mergeluvus task heartbeat t1 --context-used 0.6 # 60% of the model context window is usedluvus task done t1 # runs the quality gateluvus task merge t1
# retry without deleting the previous pane, branch, worktree, or resultluvus task retry t1luvus task start t1 --agent "claude" # worktree attempt 2 uses a new branch
# leases (usually automatic via task start)luvus lease acquire "src/auth/**" --task t1
# schedule a weekday agent in a retained IANA timezoneluvus automation create "Morning review" \ --title "Review changes" --prompt "Review and report risks" \ --agent codex --workspace-id workspace_example \ --weekly mon,tue,wed,thu,fri --at 08:00 --timezone Asia/Makassar \ --mode workspace --access workspace
luvus automation listluvus automation preview --daily 08:00 --timezone America/New_Yorkluvus automation run a1 --idempotency-key manual-review-1
# react to everything, live (newline-delimited JSON)luvus eventsFor an unregistered agent, --agent accepts an executable followed by quoted
arguments. Luvus parses that argv directly; shell pipelines and redirections are
not evaluated. The task briefing is always appended as the final argument.
Inside a luvus pane, commands default to the calling pane via
$LUVUS_PANE_ID, so a worker agent can luvus task heartbeat itself.
--context-used is the fraction of the model’s context window already consumed:
0.6 means 60% consumed. It is not task-completion progress. Use task update --note for work progress and omit the heartbeat when context-window usage is
unknown. The older --context spelling remains accepted for compatibility.
Luvus also puts the running server binary first in that pane’s PATH. A worker
created by a debug server therefore reports through the matching debug CLI,
while an installed server uses its matching release CLI. The existing PATH
entries remain available after it.
Events on the bus: task.added · task.claimed · task.started ·
task.ready · task.gate_running · task.gate_passed · task.gate_failed ·
task.needs_compaction · task.done · task.merge_started · task.merged ·
task.merge_conflict · task.merge_failed · task.released · task.retried ·
lease.acquired · lease.released · automation.created ·
automation.updated · automation.enabled · automation.disabled ·
automation.rebound ·
automation.deleted · automation.run_queued ·
automation.run_materialized · automation.run_started ·
automation.run_updated · automation.run_finished ·
automation.run_failed.
The safety model
Section titled “The safety model”task retry <id> accepts terminal done, failed, review, and blocked
tasks. It archives a bounded attempt summary, releases leases, detaches the old
worker, and queues a fresh attempt without closing the pane or deleting its
branch, worktree, output, or notes. A retry is rejected once a dependent task
has started, and merging or merged tasks remain immutable. Worktree retries
use luvus/<task-id>-retry-<attempt> by default. Retrying an automation-owned
task creates a new automation run from the original run’s captured contract
while preserving the original records. Retrying from review or blocked
finishes the superseded run as cancelled without closing its worker pane.
- Only armed agent automations spawn unattended. Manual tasks still start
only when you press
sor runtask start. Every automation stores one explicit agent, workspace, prompt, worker mode, access policy, and bounded schedule. - No arbitrary scheduled shell action. The scheduler launches only a reviewed built-in agent adapter through its separate one-shot automation profile; detection-only manifests and interactive task commands do not gain unattended execution authority.
- No blind approval.
Read only,Workspace, andFull accessmap to the selected agent’s native per-run flags. Luvus never typesyor Enter into an unknown permission prompt and never rewrites the agent’s permanent config. - No background poller. Definitions cache the nearest UTC deadline and use the existing server wake path. No thread, timer, network request, or process scan is created per automation.
- Worktree mode is isolated by default. Workers edit in their own worktrees and merges happen in a dedicated integration worktree.
- Workspace mode is intentionally shared. It creates a task tab without a branch or nested workspace. Leases coordinate Luvus tasks but do not prevent agents or external tools from writing outside declared paths.
- Conflicts can’t corrupt. The merge gate aborts cleanly on conflict and
surfaces it (task →
blocked). - Two layers of isolation. Leases prevent overlapping work from being assigned, and worktrees mean even a misbehaving agent’s clash only surfaces (safely) at merge time.
- A context gate. Workers may report model context-window consumption via
heartbeat. Above 85%,doneis blocked until the agent compacts, hands off, or corrects a mistaken heartbeat to 85% or below, so there are no half-remembered finishes. This value is never work progress.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Fix |
|---|---|
s → not a git repo |
Worktree mode needs Git. Select workspace mode to run a branchless worker in the current directory. |
s → deps not done |
A dependency task isn’t done yet. |
s → lease conflict |
Another task owns an overlapping path. Finish or release that task before retrying. No worker was created. |
d → needs compaction |
The worker’s model context window is over 85%. Compact if the agent supports it, hand off, or correct a mistaken report with luvus task heartbeat <id> --context-used <0..1>, then retry. |
Stuck at review |
The gate failed. luvus task get <id> shows the output. Fix and d again. |
blocked after m |
Merge conflict. Resolve in the task’s worktree, then m again. |
| Worker reports that Luvus server access was denied | The agent or OS sandbox cannot reach the session socket. Approve that exact local Luvus command or adjust the agent’s own reviewed permission policy. Luvus does not silently disable the sandbox. |
| Agent/access combination is unsupported | Choose an access level that the selected adapter explicitly supports. Luvus fails before creating any worker resources. |
| Scheduled worker still needs attention | ORCH marks the automation task blocked and records the detected prompt. Resolve it in the visible pane; Luvus does not approve unknown requests automatically. |
Clean up a finished worker with luvus worktree remove <path> (the branch is
kept).