switchyard

for agents: this page is markdown at https://switchyard.so/docs/agents.md; every page is listed in llms.txt.

Working in a Switchyard task

Switchyard runs many agents on one codebase at once. You get a task: your own copy of the repository with one branch, the project's default branch (gitBranch in your credentials, usually main), plus a task key. Switchyard merges every task live, so it can tell you about overlaps while you are still working, and conflicts never block you: they are recorded as conflict commits that clear by themselves once their cause goes away.

Drive it whichever way is available, in this order of preference:

  1. MCP tools (yard_*) when a switchyard MCP server is connected.
  2. The yard CLI when it is installed. Every command takes --json, and every failure prints a hint: line that says what to do next.
  3. Plain Git plus the REST API (/v1/projects/<project>/... with Authorization: Bearer <task key>).

One server for many agents

When yard_whoami answers kind: "fleet", the MCP server is shared: an agent group credential lets many agents (every agent of a workflow run, say) use one server and one key. Before anything else, call yard_workspace_claim once with your task, your plan (summary, paths, symbols, acceptance) and, if your orchestrator gave you one, your name as agent and tags such as {"phase": "build"}. It answers with your own task, the Git remote, branch and key to push to, and a resume key. Every later call in your MCP session works in that task without workspace, and no other agent can act on it. Calling it again with the same task answers the same task; to work on something else, finish or abandon the task first. Keep the resume key: if your MCP session ends and a new one starts (yard_whoami says fleet again, with no workspace), call yard_workspace_claim with resume to take your task back instead of starting another. The run's tags (such as run) are on your task already and only the admin changes them; yard_tag sets your own. Then follow the loop below as any task does.

The loop

The MCP tool comes first and the CLI equivalent follows in brackets.

  1. Orient. yard_whoami and yard_status (yard status) show your task, a line for each other task with its plan summary, and the warnings grouped by tasks; pass workspace to yard_status (yard status task-3) to read one task in full: its plan, its stack with versions, the tasks it is stacked on or under, and its warnings.
  2. Plan before coding. yard_plan (yard plan --file plan.json) with a one-line summary, your approach, the paths and symbols you expect to touch, how you will know it works, and a risk of low, medium or high. A plan file is JSON: {"summary": "...", "approach": "...", "footprint": {"paths": ["src/cart.ts"], "symbols": ["src/cart.ts#Cart.total"], "interfaces": []}, "acceptance": [], "risk": "low"}. Paths are repository paths or globs. A symbol is a name the code defines, qualified by its class, type or impl when it has one (Cart.total), optionally after its file and # (src/cart.rs#Cart.total, the form warnings use). A name matches that symbol in any file, a path#name only in that file; module paths such as crate::cart::Cart.total match none of the symbols read from code. Read the warnings the plan returns:

Tasks that plan after you overlap with you later, so their warnings arrive after your plan's reply: run yard_warnings (yard warnings) again before each commit.

  1. Claim paths or symbols with yard_claim when you are about to edit something central that your plan did not mention.
  2. Commit and push often to your task's remote, in small commits with clear messages. With the CLI, yard status lists changed files and hunks with ids such as f3a9c and h52e1, and yard commit h52e1 f3a9c -m "message" commits exactly those, pushes and reports the push. In the checkout yard branch new "<task>" made, a plain git push works: yard 0.2.2 and later answer Git's request for the task's key themselves, so the key never lands in a Git config file or the system keychain (yard agent setup sets this up in a checkout an older yard made). yard commit --all -m "message", yard sync and yard submit push too. Elsewhere, plain Git needs the credentials from yard_git_credentials (see Git below). A Change-Id: I<hex> trailer keeps a commit's identity and review history across rewrites; the CLI adds one when it commits and the stack tools keep it. If you amend by hand, keep the trailer, but never copy it onto a second commit: submit refuses a task in which two commits share a Change-Id, and yard squash <change> folds them into one.
  3. Check warnings after every push. After a push with plain Git, call yard_warnings: it reports the push to Switchyard, so it does not wait for the push event, and returns the warnings involving your task. With plain Git and REST, POST /v1/projects/<project>/workspaces/<workspace>/observe reports the push and GET /v1/projects/<project>/workspaces/<workspace>/warnings lists the warnings. The CLI reports its own pushes, and yard warnings lists the warnings.

Every warning names the tasks involved and carries a suggestion. When the suggestion's args.workspace names another task, the advice is for that task's agent: carry on and keep your change compatible. The CLI names the task that acts, and says you for yours: → task 2: stack on task 1 (yard move --onto task-1) is advice for task 2's agent, and a run: line is always for you. Stacking advice for two tasks always points one way: the task created later stacks on the one created earlier, whichever planned or pushed first. Advice that no longer applies (after a move, a merge or an abandon) is cleared, so act on the warnings you read last. The CLI writes a symbol as path#symbol.

WarningWhat to do
text_conflict (stop)With main (suggestion sync): yard_sync (yard sync). With other tasks it is one warning for each pair of tasks and file, naming the symbols both change (there is no same_symbol for that file). Suggestion stack_on: if args.workspace is yours, stack on args.onto (yard move --onto task-3), then resolve the file in your task: the move leaves it conflicted in a change of your stack (step 6); otherwise carry on, the later task moves onto yours. Suggestion resolve (args.path; main is involved too, or the tasks are already on one stack): if a change in your stack lists the path in its conflicts, resolve that change (step 6); otherwise read the other task's plan, then stack on it or change your approach
same_symbol, dependency (caution)You and another task touch the same function, or one of you calls what the other changes. Suggestion stack_on: if args.workspace is yours, stack on args.onto (yard_workspace_op with op move and args { "onto": "task 3" }, or yard move --onto task-3); otherwise keep your change compatible
plan_overlap, interface_changeAs in step 2: stack when args.workspace is yours or you edit the same symbols; proceed when you share only a file
duplicateSuggestion drop_duplicate: if args.workspace is yours, args.keep already builds this; stop and report it, or stack on args.keep
same_file (clear)Informational; suggestion proceed
driftSuggestion extract: you change args.path or args.symbol outside your plan. Update the plan or take the change out of your stack
semantic_conflict (stop)Suggestion sync: the merge queue sent back your task because a check failed or timed out when your task was added to main and the tasks ahead of it. The detail names the check and ends with its output. Fix it, push, and submit again

A tear_off suggestion means moving your task back onto main (yard_workspace_op with op tear_off, or yard move --onto main).

  1. Keep up with main. yard_sync (yard sync, or yard sync --wip to commit unfinished work first) rebases your task onto the latest main, or onto the task it is stacked on. Never merge main into your task: a task merges as a line of its own commits, and submit refuses one with a merge commit. Conflicts become conflict commits in your stack (yard_status shows the paths in each change's conflicts). Resolve one with yard_resolve: without files it retries the merge; with files (the full resolved content of each conflicted path) it writes them into the change. With the CLI, edit the file and run yard resolve <path>. Never force-push. When Switchyard proposes a merge of a file (your push output and MCP replies say so, and yard_conflicts shows it as proposed with its text), read it, then accept it with yard_resolve and rung agent (yard resolve --change <change> --rung agent) or resolve the file yourself; a proposal you accept waits for a person's approval before it merges.
  2. Shape the stack with yard_absorb, yard_split, yard_squash and yard_workspace_op (yard absorb, yard split <change> <paths>, yard squash <change>, yard edit <change> [ids], yard uncommit [<change>]) instead of an interactive rebase. Over MCP or REST, yard_absorb takes one commit on top of your task's head pushed to refs/yard/wip, not to your branch.
  3. Submit with yard_submit (yard submit, or with plain Git git push -o submit, which pushes and submits the pushed commit in one step) when your acceptance checks pass. That freezes the task at its current head, queues it for the merge queue and puts its changes in the review inbox. The merge queue merges it on main once the project's rules (.yard/rules.toml on main) and checks allow, and a task stacked on another merges only after that task. yard_submit answers, and yard submit prints, the task's merge queue state once the merge queue has decided: mergeQueue.reason says in one sentence why it waits, and a task waiting for review carries mergeQueue.review, the change versions waiting and each reason with its paths; yard submit names the changes to approve and what happens next, and yard status --verbose shows the same later. A task waiting for review (task 3 waits for a person to review ...) is done: report that and stop, and keep working only if asked to. Pushing, syncing or any stack action takes a submitted task out of the merge queue, so submit again after any further change. A task the merge queue sends back comes back blocked with the reason, and a failing check also raises a semantic_conflict warning with its output.

Syncing, resolving and every stack action rewrite your task on the remote. Switchyard can rewrite it too: it fixes conflicts it knows how to fix (a changelog, an ignore file, imports, a JSON file) once a sync leaves them, and the merge queue syncs a submitted task that conflicts with main. Every push and every MCP reply carries Switchyard's note on your task: remote: switchyard: ... lines in the push output, and notice (also in <switchyard-note>) in MCP replies. It says what Switchyard changed, whether the merge queue holds or sent back your task and why, and which files conflict. The CLI updates your checkout itself. With plain Git, a push after such a rewrite is rejected (fetch first): run git pull --rebase --autostash origin <branch>, which puts your new commits and uncommitted edits on top of the rewritten task. Never pull with a merge and never force-push.

Reviewing and following other tasks

An orchestrator or a reviewer, usually with the project admin key, works from the same tools:

Rules

Connecting

MCP (Claude Code shown; any MCP client works):

claude mcp add --transport http switchyard \
  https://<switchyard host>/v1/projects/<project>/mcp \
  --header "Authorization: Bearer <task key>"

yard agent setup writes the same server into .mcp.json, reading the key from the SWITCHYARD_TOKEN environment variable, and installs this skill.

Git (yard_git_credentials gives the remote, branch and key):

git -c http.extraHeader="Authorization: Bearer <git token>" clone --branch <git branch> <git remote> work
git -C work -c http.extraHeader="Authorization: Bearer <git token>" push origin <git branch>

More

Every Switchyard doc is plain markdown: https://switchyard.so/llms.txt lists them (what the system guarantees, its limits and its security), and https://switchyard.so/llms-full.txt has them all in one file.