Problem
Today a sortie daemon is effectively "one process per repository": it watches a
single WORKFLOW.md and all tracker, workspace, agent, and hooks config
lives in its frontmatter. That fits a single-repo user cleanly. It does not fit a
single engineer who owns several repos in the same org:
- Running N daemons means N SQLite stores, N HTTP ports, N dashboards, N log streams.
max_budget_usd is per-daemon — there is no way to cap spend across all repos a
user is working on.
max_concurrent_agents is per-daemon — idle repos can't lend capacity to busy
ones; headroom has to be partitioned manually.
- Observability and hot-reload that already work inside one daemon have to be
reassembled externally (systemd / compose / k8s) just to get a fleet view.
Proposal
Let one daemon host multiple workflows, each addressed by a stable name:
sortie --workflow ~/work/billing-api/WORKFLOW.md \
--workflow ~/work/payments-core/WORKFLOW.md
sortie --workflows ~/work/*/WORKFLOW.md
sortie --config ~/.config/sortie/fleet.yml # references workflow paths
Existing single-workflow files stay valid unchanged; multi-workflow is opt-in.
What the daemon owns globally
- SQLite store and run/session history (already single-writer WAL — no new contention).
- HTTP server / dashboard, filterable by workflow.
- Optional shared caps:
max_concurrent_agents_total, max_budget_usd_total.
- Process supervision and signal handling.
What stays per-workflow
- Tracker config and polling interval.
workspace.root (kept isolated per workflow to preserve path-containment).
- Agent config, prompt template, hooks.
- Per-workflow caps, bounded by the global caps when both are set.
Problem
Today a sortie daemon is effectively "one process per repository": it watches a
single
WORKFLOW.mdand alltracker,workspace,agent, andhooksconfiglives in its frontmatter. That fits a single-repo user cleanly. It does not fit a
single engineer who owns several repos in the same org:
max_budget_usdis per-daemon — there is no way to cap spend across all repos auser is working on.
max_concurrent_agentsis per-daemon — idle repos can't lend capacity to busyones; headroom has to be partitioned manually.
reassembled externally (systemd / compose / k8s) just to get a fleet view.
Proposal
Let one daemon host multiple workflows, each addressed by a stable name:
Existing single-workflow files stay valid unchanged; multi-workflow is opt-in.
What the daemon owns globally
max_concurrent_agents_total,max_budget_usd_total.What stays per-workflow
workspace.root(kept isolated per workflow to preserve path-containment).