qalatra/docs/Dispatch & scheduling

Dispatching & scheduling

How agents actually run.

Four ways an agent runs in Qalatra:

1. Task assignment

Put an agent name in a task: Write weekly retro &weekly-review. Select the task, press R. The agent runs against that task; its stdout streams into the task's detail panel.

2. Manual dispatch

Open the agent picker from the menu bar, pick an agent, optionally supply input, and run it. Output streams into a dispatch panel.

3. Scheduled

Any agent with a schedule: in its config runs on that cron. Qalatra uses your local timezone. See the Dispatch view for the live schedule.

4. Programmatic

Other agents can trigger an agent via mcp:dispatch_agent. Useful for chains — a morning-briefing agent that dispatches a doc-cleanup agent as one of its recommendations.

5. From FlightDesk

(Qalatra 1.9.45+) FlightDesk can act as the orchestrator: it decides when an agent should run and records that as a dispatch request; Qalatra polls for those every 30 seconds, runs each as a job, and reports acknowledged, running, done or failed back — with the result tail, the reason for a failure, and whether the session can be resumed. Nothing calls into your box; the only traffic is outbound. An empty poll costs no model tokens, so no periodic "anything to do?" agent is needed. From 1.9.62 the done and failed reports are saved and retried until FlightDesk confirms them, so a network drop or a restart never leaves a finished turn showing as running.

It is opt-in per agent folder: put a .flightdeskrc holding that agent's FlightDesk API key in the folder. Folders without one are never polled, and Qalatra without FlightDesk behaves exactly as before. FlightDesk can also ask Qalatra to perform simple operations on a cloud session — relay a CI failure, click Create PR, archive after a merge, check whether the session ended asking a question — which Qalatra does directly through claude-bridge with no agent turn at all. Settings → Integrations shows each bound folder's last poll and any errors.

The credential is the folder's identity, for the job as well as the poller (1.9.49+): every job that runs in a bound folder gets FLIGHTDESK_API_KEY and FLIGHTDESK_API_URL from that folder's rc, which the flightdesk CLI honours over any file it would find by walking up from its working directory. An agent that works from its repo root still reports turns as its own folder's agent user. An organizationId in the rc travels as FLIGHTDESK_ORGANIZATION_ID (1.9.50+). These names are set before your agent config env entries expand — so an entry can reference them, e.g. an MCP header of Bearer ${FLIGHTDESK_API_KEY} — and they override entries of the same name; a dispatch cannot set them from outside.

From 1.9.52, session-state reports also preserve native Claude permission requests, including the approval card and whether a human decision is needed. A pending approval never counts as idle. With the matching FlightDesk support, these reports become human questions and are reconciled when answered directly in Claude. Qalatra reports the request; granting permission remains an explicit action. From 1.9.54, with Claude Bridge 0.1.18, the reports also carry the history of resolved card pages — including ones answered directly in Claude — so FlightDesk can reconcile its open questions.

Each FlightDesk task maps to one Qalatra task, which every dispatch for it reuses — plan, build, closeout. From 1.9.53 that task is always a coding task, so it appears in the Code view and never in your priority view, inbox, briefings, triage or stale reviews. It closes itself once the FlightDesk task is done, archived or deleted and none of its jobs is queued or running. Qalatra checks when a job ends and every 15 minutes. Closing sends nothing back to FlightDesk, and a new dispatch on a finished task reopens the same task.

Queue & concurrency

Up to 3 agents run concurrently by default (configurable). Excess dispatches queue. See queue state in the status bar: 2/3 running · 4 queued.

Within that ceiling, at most one job runs per agent folder at a time (1.9.45+). Jobs in a folder share its working tree, so two at once would fight over one checkout. Folders that share a checkout — a repo split into plan, execute and pipeline agents — can be given the same concurrency_key in their agent config so they serialize together.

A folder that sets "worktrees": true (1.9.55+) gives each task its own git worktree instead, so jobs for different tasks — such as several FlightDesk dispatches — run in parallel up to the ceiling, while jobs for the same task still run one at a time. Jobs with no task, like heartbeats, keep running in the folder itself.

Cancellation

Select the running task and cancel it from the detail panel, or call mcp:agent_cancel. Qalatra sends SIGTERM, then SIGKILL after 10s.

Job status

A job is queued, running, done, failed, timed_out, or orphaned.

orphaned (Qalatra 1.9.32+) means the app or server running the job stopped mid-run — a restart, an update, a crash — and the job's process was gone when it came back. From 1.9.60 a job that is still running is picked up again instead, and one that ended while the server was down is finished as usual, so only work that is really lost is orphaned; it keeps its session id and partial output, and the task's next job resumes that session. That's an infrastructure event rather than an agent failure, so it gets its own amber badge instead of a red one and doesn't pollute failure counts. Orphaned jobs are never re-run automatically: partial work may already have landed, so requeueing is your call. The job records the start time of the instance that killed it, so a late-arriving result can be checked against it to see whether the work finished. If you consume job status programmatically, branch on orphaned separately from failed.

Output handling

Configured per-agent:

  • task_notes — appended to the triggering task's notes field
  • append_to_today — appended to today's daily note under ## agent
  • file:./logs — written to a file relative to the agent folder
  • discard — exit code only