Back to all guides

Your AI dev team

Assign AI agents to specialized roles (Lead, Coder, Tester, Reviewer, Researcher, Designer) so they work together as a team, hand work off to each other, and ask for your approval at the right moments.

The idea: a team, not one agent

Most tools point a single AI agent at your whole task. Castforge runs a small team instead. You give each agent a role (a clear job), and the roles pass work between each other the way a real dev team would: a Lead breaks the request into a plan, a Coder writes the code, a Reviewer checks the diff, and so on.

You stay in control. The Lead can be made to wait for your approval before any work runs, and any agent that wants to touch a file or run a command can be made to ask you first. Everything the team does shows up in the chat as it happens, with a banner each time work passes from one role to another.

You set the team up once per project, in that project's settings. The same team then drives the work in chat and on the board (the "course").

The team's work is organized into milestones: each milestone groups a run of board phases under one workload (for example "v1 launch"), and the board stacks them so the one you are working in stays in front while finished ones collapse to a one-line summary. The agents manage this for you, starting a new milestone when they pick up distinct new work, reordering the pending ones, or archiving one you no longer need (archiving asks you to confirm first unless the project is autonomous, and it keeps the phases). See "The board: course, dispatcher, and milestones" for the full picture.

The roles

Castforge ships six roles. Each has a default job, its own color tint, and an icon:

A role is just a job description. The agent that fills it (GitHub Copilot, Claude, Codex, Gemini, Cursor, Muse Code, or another connected agent) is something you choose separately, so you can put your strongest model on the role that needs it.

The Designer authors a visual identity up front

On a new web project, the Designer's first turn is not "style this screen". It is "decide what this product looks like", before any screen exists to style.

The Designer works through a fixed set of decisions and has to justify each one against what your project actually is:

Those decisions are then materialized as real code. The Designer writes the theme tokens into the project's stylesheet, including a working dark mode, and records the reasoning in .castforge/ui-spec.md. Because they are real tokens, every screen the Coder builds afterwards inherits the look automatically, instead of each screen inventing its own colors and spacing.

If your brief rules out frameworks, the Designer follows it

If your plan says the project uses no frameworks and no build step, the Designer authors the identity in plain CSS instead of Tailwind. It still makes all seven decisions above and still writes a real theme with a working dark mode, but it writes them as ordinary custom properties in the shared stylesheet your plan names (or styles.css at the project root if it names none), and it writes the CSS rules that actually use them. Nothing it produces needs a build step, so the pages open directly in a browser.

Castforge reads that constraint from your own words first. Your original request is kept as you typed it, so the constraint holds even when the plan the Lead writes describes the work in different words. It also reads the plan and the Designer's card, so a constraint that appears only in the Coder's cards is still honored.

For everything else, which is most web projects, the Designer authors the identity as Tailwind theme tokens in src/index.css exactly as before. Castforge only takes the plain-CSS path when your plan explicitly rules a framework or a build step out, so a normal React project is never quietly downgraded.

Three things worth knowing about when this runs:

How the Designer grades: measured facts and seat-tiered vision

When the Designer reviews a screen, it no longer grades source code alone. Castforge measures the running UI and hands the Designer the actual facts: computed text contrast with an AA and AAA pass or fail on each pair, spacing that falls off the grid, horizontal overflow, an inventory of the fonts, sizes, and colors actually in use, and a lite accessibility lint (missing alt text, unlabeled inputs, buttons without an accessible name). The Designer grades against those measurements, so contrast and spacing notes are exact instead of eyeballed.

On top of those measured facts, each agent seat gets a different level of picture:

All three seats get the measured facts regardless of the agent, so no seat reviews blind.

When a design check runs without a screenshot, Castforge tells you at the moment it happens and says why: the seat's agent cannot read images, the preview is not on screen, the project has no running UI yet, or the capture was refused. The Designer's own review then states that it graded without a picture and sticks to what it could actually check. So a text-only review is never mistaken for a visual one, either while it runs or later when you read it back.

Checking work across lanes

When the Designer is sent to check work produced elsewhere, Castforge points the check at the tree that holds that work. If Castforge cannot identify that tree, the check is refused instead of reading the Designer's own files. The refusal names the checking role and says in plain language what went wrong, for example that the check was pointed at the wrong working copy, rather than printing an internal path at you. The full technical detail, including which trees were involved, is recorded in the project's history. The usual fix is to re-run the writer turn after recreating or integrating that tree. A refused check is safer than a confident answer based on the wrong files.

If queued review or test work cannot safely be connected to a Course card, Castforge refuses it before starting the checking role and retains it as one held verification. It does not read the wrong tree or mark the card done or blocked. To recover it, right-click the intended Course card, open Recover held verification, and choose one listed held check. Castforge binds only that choice and re-runs it through the tree that owns the card's work. Held verifications survive a restart, a stale choice stays available after the menu refreshes, and Stop intentionally discards them.

One scope note: the measured facts come from a small bridge script that Castforge serves inside the projects it scaffolds (Castforge-aware projects). A project you brought yourself that does not serve that bridge falls back to a text-only review of the code and diff, with no measurements.

Known limits in this first version (documented, not yet solved): the measurement cannot see inside Shadow DOM internals used by some web-component frameworks, a very large page can be slow to traverse, and the alignment check is fixed to an 8px grid.

The claude.ai/design round-trip (Claude seats only)

A Claude Designer can take the round-trip further: it can generate or refine components in claude.ai/design and then pull them back into your project as real presentational code. The pulled components land directly in the project files (the same view-layer files the Designer already writes), not in a separate holding area, so you can build on them right away. Castforge asks you to confirm the pull before it runs, unless the project is set to autonomous mode. You never handle any token for this: the Claude process brings its own design credentials.

This cloud round-trip is available only on Claude Designer seats. A Codex or Gemini Designer seat does not do the cloud round-trip; it works from the per-project visual identity described above (the theme code written into src/index.css and the notes in .castforge/ui-spec.md). Every seat authors that identity, so every seat gets a coherent look, and Claude seats additionally get the claude.ai/design pull.

Team presets

You do not have to build a team from scratch. Pick a preset to seed the roles and the handoff rules, then adjust:

Every preset seats a Lead: the Lead is the permanent overseer on top of the worker roles, so the preset name counts the workers it oversees (Solo is one worker, Pair two, Trio three).

A preset seeds every seat onto an agent you have actually connected, so a new project is runnable the moment it is created. If you have connected only Claude, Codex, Gemini, Cursor, Droid, or a local model, every seat starts there. GitHub Copilot is the one agent where that does not hold for every role: a Copilot-only team starts its Coder on Copilot and holds the Lead, Reviewer and Researcher back until you connect Claude, Codex or Muse Code. Their role cards say why and offer to seat them, as described under "What the read-only roles are allowed to do" below. Muse Code is the one exception, and it is worth knowing: because the muse tool publishes no way to confirm a sign-in, Castforge never reads a Muse Code connection as a definite yes, so a new project will not seed its seats onto Muse Code even if it is the only agent you have connected. Every seat stays selectable, so put Muse Code on the seats you want by hand and it runs from there. If you have connected several agents, the seats start on your paid subscription rather than on a metered free plan, so a free allowance is not spent on you by default. You can change any seat afterwards, and doing so flips the preset to Custom.

Picking a preset replaces the current roles and their assignments. The moment you edit anything (change an agent or model, add or remove a role, change a plugin), the preset flips to Custom automatically, because the team no longer matches a named preset. Two seats cannot be removed: the Lead (the permanent overseer) and the Coder (the role that always does the building).

Seats: assigning an agent and a model to each role

A "seat" is a role plus the agent assigned to it. In the team settings, each role is a card where you:

  1. Pick the agent. Click the agent button on the role card and choose any connected agent (GitHub Copilot, Claude, Codex, Gemini, Cursor, Muse Code, and so on). If an agent is not connected yet, the picker lets you connect it inline (it launches that CLI's own sign-in). If the agent's CLI is not installed, an install card appears right there so you are never stranded.
  2. Pick a model (optional). Below the agent button is a model picker. Leave it unset and Castforge sends no model to the CLI, so the agent runs on its own account default (the model your subscription actually supports). Or choose a specific model from that agent's built-in list. That list is a curated quick-pick, not a live mirror of what your CLI offers. It is maintained by hand, so it can lag the CLI you have installed by several models, and leaving a seat unset is what keeps you on the CLI's own current default. Below the quick-pick list you can also type a custom model id for that agent, which is the way to reach a model your CLI has and the built-in list does not name yet. The id must be for the same provider as the seat's agent (it has to start with that agent's model prefix, so a Claude seat only accepts a claude- id and a Codex seat only a gpt- id). An id that is not valid for the agent is refused inline with a hint and is not applied, so a model is never sent to the wrong agent. A few shapes are refused for safety rather than for the prefix: an id that starts with a dash (so it cannot be mistaken for a command-line flag), an empty id, and an id longer than 200 characters. Castforge also checks the id again on its own side just before it starts the agent, so the picker is there to make the right choice easy rather than to be the only thing standing between a typed id and the tool. Changing the agent clears a model that does not exist for the new agent. The card shows exactly what the seat resolves to; see "What a seat's model label tells you" below for what an unset seat's own phrasing does and does not mean.
  3. Add plugins (optional). Plugins that are compatible with the role show as chips you can toggle on the seat.

Each role gets its own agent and model, so a team can mix agents (for example, a Claude Lead with a Gemini Coder).

Model preferences: which model each tier uses per agent

When a project runs on a model strategy other than Max (Smart, Economy, or one of the Alloy variants), cards are matched to a tier (Top, Mid, or Cheap) instead of always using the top model. For Claude, the tiers map to Claude's model aliases: Top runs opus, Mid runs sonnet, and Cheap runs haiku, and the Claude CLI itself resolves each alias to the newest version of that model, so you always run current models without Castforge storing a version number. Explicit model preferences override this mapping. For every other agent, a tier runs on that CLI's own default model unless you set an explicit model preference for that tier: Castforge never picks a stored model for those agents on its own, so you are never forced onto a model your account does not support. Model preferences let you choose, for each connected agent, which concrete model each tier resolves to. The per-agent lists here are the same curated quick-pick as the seat picker, so the same thing applies: the list can lag your installed CLI, a tier you leave unset stays on that CLI's own default, and a valid same-provider custom id reaches a model the list does not name yet.

There are two places to set this:

Each agent row shows a Top, Mid, and Cheap picker. Until you change one, a Claude tier shows its alias default (for example "Claude Opus (latest)") followed by "(default)", and a tier for any other agent shows "CLI default" because no stored model will be sent for it. Pick a model from the agent's list (or type a valid same-provider custom id, exactly like the seat model picker) and that tier uses it from then on. A small Reset returns a single tier to the default, and a per-project block can reset a whole agent back to the account default. Setting a Top preference also takes effect under the Max strategy, so you can say "Top for Claude is Claude Fable 5" and have that model actually run. Leaving everything unset changes nothing: dispatch is exactly as it was before you touched it.

The order of precedence when a card runs is: a model pinned directly on the seat wins first, then the project tier preference, then the account tier preference, then the built-in alias mapping (Claude only). When nothing in that chain is set, no model is sent at all and the agent's CLI uses its own default.

What a seat's model label tells you

A seat's card in Team & roles, in the onboarding team step, and in the new-project team step now names the model that seat resolves to, instead of the bare word "Default" it used to show. A plain model name with no note next to it is the seat's own pin: change or clear it right there, in that seat's own model picker.

Your team in the workspace's right-hand panel can additionally see one level a role card cannot: if it names a model with (project default) written after it, that model is not the seat's own pin, it is this project's preferred model. Change that with the /model command, which opens the model picker for the project, not from the seat.

If a seat reads Default model, it means this seat pins nothing of its own, so a default decides what it runs. That is not the same as no model being sent. A tier preference set for this agent, at your account level or for this one project, can still supply a model the card has no way to show you, and so can the strategy and routing covered by the precedence order above. To see whether a tier preference is quietly supplying one, check Model preferences directly (App Settings, General, for your account default, or the project's own Behavior section for its override) rather than reading the seat.

The panel is narrow, so a long model name can run out of room. When it does, hover the model line to see the full name and, where the panel knows it, the level that chose it. The line underneath, when it appears, is the resolved answer from Castforge itself rather than anything the seat stores, and it wraps onto a second line instead of being cut short, because the end of that line is the part naming which level picked the model.

None of this changes which model actually runs: the precedence order above is unchanged, and this is only what a seat now displays. You can also ask an in-app agent whether a seat's pinned model still matches what its installed command-line tool currently reports; it runs a read-only check and cannot change anything.

Charters: standing instructions per role

A charter is the standing brief a role works to, applied before any specific task. Think of it as the role's operating rules ("always write tests for new functions", "prefer small diffs", "explain tradeoffs").

In team settings, the Role charters section gives you one editor per role. Each role has a sensible built-in default. Leave the editor blank (or matching the default) to use the built-in default, or type your own to override it. A Reset to default button removes your override. Edits apply at the next time that role starts a turn, and they save automatically (there are no save buttons).

A role at its built-in default shows a short summary first, not the raw prompt. Below the role's name, a plain sentence or two describes what that role actually does (for example, the Lead's reads: "Plans the work; does not write code itself. Decomposes requests into tasks, keeps the plan current, and hands off to the Coder. Marks a card's complexity and how a turn should settle when it needs to."), followed by a line on what breaks if you edit the charter away from its default. The full raw text, including any internal instructions the role always receives, sits behind a View full prompt disclosure below the summary, collapsed until you open it. The moment a role carries a real override, the summary is replaced by a neutral Custom charter. label instead, because a summary written for the built-in default should never be shown next to text you actually changed.

Every one of these summaries describes the role's real, current charter text, not a paraphrase invented on the fly: a hidden check compares the summary against the actual charter each of Castforge's own tests run, and it fails if the underlying prompt ever changes without a human re-reading and re-approving the summary above it.

A few instructions are always added after yours

Your charter replaces the role's standing brief, but it is not the last word. A small set of instructions is added after your text every time, and you cannot edit them away. They are the ones the rest of Castforge depends on to keep working.

The main ones are how each role reports its result. Whatever you type, the Reviewer still reports approve or request-changes, the Tester still reports pass or fail, and the Designer still reports block, flag or pass on the UI. That is how a run knows what happened and what to do next, so a custom charter cannot accidentally leave a check with no way to say no. If you deliberately removed that wording from your own charter, you will still see the role reporting it, and that is why.

A few others work the same way and are worth knowing about, because they have been there longer: the Lead is always told the plan format the board is built from, the Designer is always held to the presentational scope of the work rather than the whole app, and every role is always told how to record a decision, a stack choice, or a worktree it created. Everything else in the editor is genuinely yours.

Roles run on their charter and your project, not your personal setup

A role turn in Castforge runs isolated from your own agent customizations. Anything you have installed in your home directory for your personal terminal use, such as your own skills, a personal instructions file, or personal hooks, does not reach a Castforge role and cannot change how it behaves.

Configuration that lives inside the project you opened still applies normally. A project's own conventions file and project-level setup are read as usual, because that is context the role should have.

This keeps a role predictable: it behaves according to its charter and your project on your machine and on a teammate's, instead of picking up whatever each person happens to have installed.

What the read-only roles are allowed to do

Three roles run read-only: the Lead, the Reviewer, and the Researcher. They read, review, and report. They are also not authorized to invoke plugin tools that change things, or plugin tools whose effect Castforge cannot classify, such as one that runs arbitrary code inside another program on your machine.

How that limit is enforced depends on which agent is in the seat, and the difference is worth knowing before you rely on it.

On a Claude seat, Castforge sees each tool call as the agent makes it and refuses the ones it should not run, so the tool never runs. Castforge starts these roles without the file-editing tools, and the shell stays available, because reading your code needs it. Castforge checks each shell command as the role makes it. A command from the Lead, the Reviewer or the Researcher that Castforge recognizes as changing your files, such as writing into a file with a redirect, rm, mv, cp, sed -i or git commit, is refused before it runs, on Careful, Balanced and Autonomous alike, and the role is told why. Commands that only read, such as git log, grep or cat, still run. Castforge decides this from the command text, so it is a guardrail rather than a sandbox, and once in a while a command that only reads but looks like a write to it, an inline script containing an arrow function being the common case, is refused too. What stays available is everything those roles actually need: the built-in Castforge tools they use for reading, and the plugin tools Castforge recognizes as read-only, such as documentation lookups. A Reviewer can still read your code, search it, look things up, and write its review, meaning the review text itself, saved as its own file that Castforge names and places. See "Where a Reviewer and a Researcher save their work" just below.

On a Codex seat, the limit is stricter. Codex never asks Castforge for permission while it works, so there is no moment at which a call can be judged. Instead, a read-only role on a Codex seat is not given any third-party MCP server in the first place. It gets Castforge's own tools and nothing else. That does mean a documentation-lookup server your Reviewer can use on a Claude seat is not available to your Reviewer on a Codex seat. The reason is the same one behind the whole limit: Castforge cannot judge what a third-party tool will do, and a role whose only job is to read and report should not be able to reach one.

Roles that can change your project are not limited this way. The Coder, the Tester, and every other writable role still get the MCP servers you configured yourself, exactly as they always have, plus the marketplace plugins assigned to their seat. The limit above applies to read-only roles only. See "Templates and plugins" for how your own MCP servers reach a Castforge agent.

On a Muse Code seat, the read-only limit is enforced by the tool itself. When Castforge starts a read-only role on Muse Code it switches off that tool's file writing and its shell execution before the turn begins, and it does that at every permission mode, so a stricter or looser project setting cannot relax it. That was measured on a real run: a turn told to write a file and then to fall back to the shell did neither, and reported that both were disabled. Note what this covers and what it does not. It covers the tool's own ability to change your files or run commands. It does not do what the Claude seat does, which is judge each plugin tool call as it is made, so the paragraph below applies to Muse Code too.

Gemini, Cursor, Muse Code, and other connected agents do not have the plugin-tool limit yet. If you are counting on a read-only role being unable to reach a plugin tool that changes things, check which agent is sitting in that seat first. GitHub Copilot is not on this list because a read-only role cannot be seated on it at all, as described just below.

On a GitHub Copilot seat, a read-only role cannot run yet. A Lead, Reviewer or Researcher cannot be seated on GitHub Copilot yet, because Copilot does not let Castforge stop it from editing your files. Copilot does not ask before it edits a file or runs a command inside your project, so Castforge never gets a moment at which it could refuse the edit, and there is no way to start Copilot that Castforge has confirmed would hold a read-only role. We have not yet tested GitHub Copilot's read-only controls on a live session, so Castforge does not claim that any of them works. Until that is proven, Castforge refuses the seat instead of letting a role that is meant to read and report change the code it is reviewing. The Coder is not affected: it is allowed to write, so Copilot works as a Coder seat exactly as before. Here is what you will see:

On a Claude seat, if Castforge cannot get the refusal through to the agent, it ends that role's turn instead of letting it carry on. You would see the turn stop early. Nothing is lost: re-running the role picks the work back up.

Where a Reviewer and a Researcher save their work

Castforge gives a Reviewer and a Researcher one tool of their own for saving their work. A Researcher's findings and a Reviewer's reasoning now land in a file of their own, rather than being squeezed into the body of a card.

Castforge picks the file, the agent does not. The tool that saves it takes no location from the agent at all. Castforge chooses the path itself, inside its own folder in your project, one file per role per card. There is no field on that tool an agent could put one of your source paths into.

This tool leaves their other limits as they are. Castforge still does not hand them the file-editing tools on a Claude seat, and the plugin-tool limit described above still applies to them exactly as it did. This one tool widens neither.

It stays on your machine. The first save into that folder also marks it as ignored by git, so nothing in it is committed or pushed. It is evidence from a run, not project history a teammate inherits.

A verdict still comes from the project's own record. Whether a review passed or failed is read from Castforge's own ledger, and the file carries no pass or fail field of any kind. Reach for the file when you want to read the reasoning behind a verdict.

How work hands off between roles

When a role finishes its part, the work passes to the next role. What actually travels is the previous role's own output, marked as either complete or partial: partial when the turn produced real work and then stopped before it was done, complete otherwise. When a turn produced no usable work at all, for example because the provider refused it, nothing travels forward. The next role is told the previous turn did not produce work, rather than being handed the failure itself to act on as if it were the previous role's answer. See "Recovery and troubleshooting" for what a provider refusal, an interruption, or an unreadable turn each look like from your side.

This is governed by handoff rules you can toggle in team settings (the section is filtered to show only rules that apply to the roles you actually have), grouped under four stage headings, PLAN, BUILD, REVIEW, and FOLLOW-UP, in that order, with any stage that has no applicable rule left out entirely:

PLAN

BUILD

REVIEW

FOLLOW-UP

The handoff banner

Every time work passes from one role to another, a banner appears in the chat: it names the role and agent the work came from and the role and agent it went to (for example, "Coder, Claude to Reviewer, Claude"), with an optional short reason. A turn-start banner also marks when a role begins its turn (for example, "Claude is now planning"). The verb in that banner follows the turn rather than the seat, so a turn with no board card behind it reads "Claude is now working" instead. These are read-only markers; they are how you follow the baton as it moves.

What each role's status means

Every role carries a short status word in two places: beside its name on the relay strip, and on that role's send-to chip above the composer (or in the idle menu described below). The two always agree, with one deliberate exception covered just below: the relay strip stays silent for a role that has nothing assigned, while the send-to row counts it in the N idle group, or gives it its own chip marked idle when it is the only idle role.

The send-to row above the composer gives the weight to the roles that matter right now. A role that is working gets a filled chip in its own color. A role with something to tell you (queued, waiting, blocked or failed) keeps its own quieter chip. When two or more roles are simply idle, or done with nothing left to do, they fold into one N idle chip at the end of the row instead of taking a chip each. That chip is still a way to reach them: click it, or tab to it and press Enter, and a menu lists every folded role with its status. Pick one and the next message goes to that role directly, with no team handoff, exactly like clicking its own chip. The role you picked comes out of the menu and shows as its own chip with a small pin, so you can always see where your next message is going. Click the pinned chip again to go back to automatic routing. A single idle role never folds: it keeps its own chip. A role only moves into or out of the idle menu once its status has settled, so the row does not jump around while a turn is finishing, and it always agrees with the relay strip and the Team list in the right-hand panel about who is working.

The relay strip is one compact row of role names with a live lane strip under it, and it stays the same height whether one role is working or all six are. A quiet, idle role shows just its name; a role with something to report shows its status right beside the name. Hover or tab to a role name for what that role does. When several roles run at once they share that one lane strip, each getting a slice of the same single row, so at five or six lanes the lanes drop the elapsed time and the agent name to keep the live text readable. That is the design, not a rendering fault, and nothing is lost: hover or tab to a lane and the full detail comes straight back.

Under the row of role names, the relay shows the work itself. A role that is working on a board task holds a small chip with that task's title, in the role's color, so you can see which card each role has in hand. When one role hands a task to the next, the chip travels along the relay to the role that receives it, the connectors it crosses light up in the sending role's color, and a caption underneath says what happened and why, for example Coder passed Offline queue retries to Reviewer, ready for review. When work comes back, it reads as coming back: the chip gets a dashed amber edge and a return arrow, and the caption names whoever owns the card, so it reads, for example, Reviewer sent the homepage hero restyle back to Designer, changes requested, the same way it already names the Tester when tests failed and the Designer when a design check blocked. The chip only moves when a real handoff happens, never on a timer, and opening a project draws the chips where the work already is instead of replaying old handoffs. A handoff that carries no specific task reads the work in the caption. If your system asks for reduced motion, the chip goes straight to the receiving role without travelling. Every connector between the roles now takes an equal share of the row, so the names stay evenly spaced; with six roles the row clips at the edge rather than wrapping onto a second line.

You can collapse the relay by clicking its RELAY header, and it keeps telling you what is happening. The header carries one small colored dot per role, so you can still see at a glance who is working, who has finished, and who is idle. Beside the dots it names the roles that are running right now, and hovering or tabbing to one of those names shows that role's agent, what it is doing, and how long it has been at it. With five or six roles running at once the header switches to a count, "5 lanes running", because the dots are already telling you which roles those are. Clicking anywhere on the header row opens the relay back up. If the team is waiting on you, the collapsed header turns the same coral as the rest of the app and says so, but it does not open itself: the prompt is in the chat where you are already looking. Open, that same summary is only a count, because the lane strip below it is already carrying the detail. Either way, collapsing hides nothing: everything the open relay tells you is still on the header row or one hover away.

Most of those statuses are calm. A role with nothing assigned to it shows no status word at all on the relay strip: just its name, sitting quietly. Nothing is wrong when you see that. A role with nothing to report says nothing, and the strip keeps the room for the roles that do have something to say; if you want it spelled out, open the N idle group on the send-to row, where every folded role is listed with its status and can still be asked directly. Every other status shows on the strip. Running means the role is working right now. Handing off means the baton is moving to the next role. Done means its work is finished. Waiting means it still owns work that has not started yet. Queued means its turn is lined up behind the work in front of it, and Failed means its last turn ended in an error. There is one more: when a role's next task is queued behind another role's task, the status names that role, for example Waiting on the Coder. Hover the status and it tells you the exact task it is waiting for. This one is normal and needs nothing from you; it clears by itself the moment the other task finishes.

While a role is Running, that word is replaced by a verb, and the verb describes the turn rather than the seat's job title. A turn working a task the board holds shows that task's kind of work. A turn with no task behind it shows a neutral word instead of claiming work it may not be doing. The next section covers what that word is and why.

Blocked is deliberately narrow. A role reads blocked only when it is genuinely stuck and will not free itself, for example a task parked with nothing running behind it. A step the team declined to take is not that on its own: when nothing stays parked behind the refusal, the role keeps its true status and the refusal is recorded as an outcome instead. Everything else that looks like a pause is one of the calm states above. Blocked is the one worth looking at.

That narrowness is enforced, not just intended. When Castforge declines to start a check and the run carries straight on afterwards, the role keeps whatever status it already had (usually Done or Idle) rather than flipping to Blocked. The declined check is still recorded: it appears as an outcome in the orchestration panel with a plain-language reason, so nothing is hidden. Blocked is reserved for the case where the work really is parked and needs you.

What the activity word means while a role is running

While a role is running, the status is replaced by what it is doing: planning, implementing, reviewing, researching, testing, or reviewing the UI. You will see the same word in every place that reports live activity: the relay strip, the board's activity line, the line at the bottom of the chat, and the turn-start banner.

That word describes the turn, not the seat's job title. Castforge reads it from the card the role is holding on the board right now.

When the running role is holding no card, every one of those surfaces says "working". That is deliberate. It is the one word that is true of any turn, so it can never claim something that is not happening. It replaces a specific-sounding but wrong label: a bug report that gets routed to the Coder seat and turns into a planning turn used to read "Coder is implementing", because the word came from the seat rather than from the work. A turn that has just started, before the board has caught up, also reads "working" for a moment. Briefly vague is on purpose; briefly wrong is the thing being fixed.

So "working" is not a warning and needs nothing from you. It means the role is running and Castforge is not going to guess at what kind of turn it is.

One writer to the board

The Lead is the only role that adds cards to the board. Every other role, and every automated check Castforge runs against your project, reaches the board the same way: it raises what it found, and the Lead decides whether and how it becomes a card. That is true of a role's own mid-run follow-up request below, and it is also true of the phase verification gate's findings when a phase fails its build-and-test check (see "Quality and review gates"): a failed check does not add cards on its own, it routes its findings to the Lead like any other raised item, and the Lead is the one that turns them into fix cards. If the Lead cannot be reached or declines to act on what a check raised, nothing is silently dropped: the run pauses and tells you what is still unmet, the same as it does when a phase does not clear its fix rounds.

One card, one writer, keeps the board something the Lead can actually reason about: a Lead that plans a phase and then finds cards on it that it never decided on cannot keep the plan and the board describing the same thing.

Mid-run follow-up requests

Sometimes a role notices work the goal needs that was not in its current task: a missing test, an edge case, a piece of cleanup. When the Roles can request follow-up work through the Lead rule is on, any first-party role can raise a short follow-up request in the middle of a run, not just the roles that write code. The Coder, Tester, Lead, Reviewer, Researcher, and Designer can all flag follow-up work this way.

A request never becomes work on its own. It always goes to the Lead, which adjudicates it:

Both outcomes are written to the project's decision ledger, so an accepted request and a rejected one are equally visible after the fact (a rejection is never a silent drop). Accepted requests show up as a new card on the board with a "request" origin; the run does not settle as done while an accepted request card is still open. The number of follow-up requests a single run can service is capped, so this cannot loop.

An accepted request does not mint a separate card for each role that touches it. If answering it raises a question for another role, that happens inline through "Role-to-role consultation" below, as the owning role works the one card. And once the owning role's own work is done, the run still gets the checks those separate cards used to stand for: a coder card runs through the standing "Quality gates: plan-check and verification" and "Who writes the tests" automatically, with no second card required to make that happen.

This rule is on by default for a new project, and the roles are actually taught the mechanism when it is on. Turn it off in team settings if you want every run held to exactly the plan you approved with nothing added mid-run.

Role-to-role consultation

A follow-up request surfaces work for the Lead to decide on later. Consultation is different: it lets a role ask another seated role a direct question in the middle of its own turn and get a real, reasoned answer back before it continues, the way you might lean over and ask a teammate a quick question instead of filing a ticket.

The asking role picks which seated role to ask (for example, the Coder asking the Designer whether a new screen should reuse an existing pattern) and waits for the answer inline. While it waits, the card it is working reads as waiting on the role it asked, so a paused lane never looks like a stuck one, and the question and the answer both appear in the chat transcript, nested under the turn that asked, once the exchange finishes.

Three things keep this from becoming a side channel around the single-writer rule:

Every consultation, however it ends (answered, timed out waiting on the other role, or refused because the card had already asked its limit), always clears the waiting state, so you never see a card left waiting on a question that is not actually in flight.

Who writes the tests

Writing tests and running them are two different jobs held by two different roles, on purpose. The Coder writes the tests and sets up the test tooling, and the Tester runs them and reports what passed and what failed. The role that grades a test is never the role that wrote it, so a passing suite means something.

The Lead also plans the test setup itself when a project does not have one. If a project has no test setup at all (no test runner, no test script, no test files) and the work involves correctness-critical behavior (money or payments, sign-in and permissions, data integrity, database migrations, or a rule that later work will build on), the plan includes one early Coder task that sets up the test runner and writes the first tests pinning those rules, and the tasks that depend on that behavior are wired to run after it.

This is deliberately narrow. A small change, a one-off, or a project that has no correctness-critical behavior gets no test-setup task, and a project that already has tests is left alone. It is not a rule that every plan must add tests.

When there is nothing to run

A test card can land on a project that has nothing to test yet: no test runner, no test script, no test files, or the thing the card names has not been built. In that case the Tester does not invent a result and does not report a failure. It reports that the check could not run, and says why in one line.

The run records that as its own outcome, shown on the card as Could not run with the Tester's reason, in neutral gray rather than the red of a real failure. It is not a pass and it is not a failure:

This matters because the two are easy to confuse and expensive to confuse. A red "Tests failed" on a project that simply has no tests sends you looking for a bug that was never there. The Tester now reports that no tests exist instead of reporting a failure.

Castforge also tries to avoid the situation entirely: when it can tell ahead of time that a project has no test setup at all, it holds the test card back rather than spending a turn discovering the absence. "Could not run" is what you see when that check was not conclusive and the Tester had to look for itself.

Quality gates: plan-check and verification

Beyond the handoffs, the team runs two automatic quality gates so work is checked coming and going:

Which gates run depends on the project's Quality tier (Draft, Standard, or Max): Draft skips the heavier gates for speed, Standard adds plan-check and verification, and Max runs the full stack including research. See "Quality and review gates" for the full detail on both gates and the tiers.

Lead plans and the Approve / Edit / Reject flow

When the User approves Lead plans before execution rule is on, a Lead plan does not run on its own. Instead, the plan arrives in chat as a distinct card (coral border, "action required") that lists the proposed phases and their tasks. The plan is also placed onto the board so you can see it, but it stays gated until you act. You have three choices:

  1. Approve: releases the plan so the Coder can start. The work begins.
  2. Edit: opens an inline editor where you can rewrite phase titles and task titles. Saving marks the plan as edited; the next Approve materializes your edited version onto the board (it merges your edits in rather than duplicating).
  3. Reject: opens a short note box. Your note is sent back to the Lead, and the still-pending plan cards roll off the board. Work you or the team already did is never deleted.

While a plan is awaiting your approval, its column on the board shows an "Awaiting approval" pill and is dimmed. Tip: manually dispatching (running) a card from a pending plan also counts as approval, since a board you cannot run would be a dead end.

The "needs you" permission prompts

Separately from plan approval, an agent may need your go-ahead to take an action (edit a file, run a shell command, answer a question it raised). When that happens, a permission prompt appears with a shield icon and a danger rail. It tells you what the agent wants to do and, for a shell command, shows the exact command so you can read it before deciding. The prompt reaches you wherever you are looking: it shows in chat, and it also surfaces on the Course board, so a run that needs you is never a silent stall you only notice after switching tabs.

You get three buttons:

Once you answer, the prompt collapses to a compact line showing your decision. How often you see these prompts depends on the project's permission level (Careful, Balanced, or Autonomous) in settings: Careful shows every prompt, Balanced auto-allows routine tool actions, and Autonomous auto-allows more. If a prompt belongs to a session that has ended (for example, after restarting the app), it shows a non-actionable "Session ended" line instead of buttons, so you can never click a dead gate.

Not every seat raises these prompts, and Muse Code raises none at all. A Muse Code seat decides its own tool calls and never sends Castforge a request to turn into a prompt, so you will not see a shield card from one. What your project's permission level does on that seat is pick the approval tier Castforge hands the muse tool when the turn starts, before any work begins, and Careful gets the strictest of them. When Muse Code's own policy refuses a tool call, the refusal happens inside the tool and the turn tells you which decision it recorded. If Muse Code raises a question mid-turn, its own tool cancels the question and carries on, and Castforge puts a line in the transcript saying so, so an answer that rested on an assumption is visible rather than silent. The seat never sits there waiting for an answer nobody can give it.

One kind of question is never auto-answered, even in Autonomous: when the Lead pauses to ask you a genuine decision (for example, a mid-run request that conflicts with the project's brief, like adding a login to a project that was meant to have none), it waits for your real choice and surfaces on the Course board so you can answer it there. Autonomous speeds routine tool actions along, but it never picks an answer to a design decision on your behalf, so your intent is never silently dropped.

That call is made once, by Castforge itself, at the moment the question arrives, and the app window then follows it. If Castforge cannot confirm it is safe to answer a question for you, the question waits for your click rather than being answered on a guess. In practice you may see this on a one-off question in Chat: it stays on screen for you to pick, which is the safe direction, and you are already looking at it when it happens.

The waiting-for-you park

Sometimes a role reaches a point where it genuinely cannot go on without you: a real decision, or a missing piece only you can supply. When that happens, Castforge does not guess and does not spin. The run pauses and shows a visible waiting banner in the chat, for example "Waiting for you. This item is parked until your next reply." The work is held right there.

What is held is that one item. Any other lanes that were already running carry on working, so on a multi-role run you can see a parked banner and a live role at the same time. The moment you reply, the parked work picks up from your answer and continues. You do not need to restart anything or re-approve the team; your next message is what resumes it.

The waiting banner appears right in the chat where the run is happening, so a parked run reads as a clear "your turn" prompt rather than a silent stall. Your next reply in that chat is what resumes it.

Background agents (a role's own helpers)

A role can spin up its own short-lived background agents to gather context in parallel. The clearest example is the Researcher: when it fans out several background helpers to research different questions at once, its relay node shows a small cluster of child dots beside its name, one per live helper, and its send-to chip shows an "N agents" badge. Hover a child dot to see what that helper is working on; click it to open that helper's own stream in a side drawer.

While these helpers are still working, the owning role reads Running: N background agents rather than Done, and the team waits: the next role (for example the Lead planning from the research) does not start until the helpers finish reporting, so the plan is formed from the full research and not from a partial brief. If a helper stops responding, the wait ends on its own after a short bound so the run never gets stuck.

The Researcher does this on purpose, not by chance. On work that warrants a full investigation (a brand new project, a new feature area, an explicit stack or architecture decision, or a question that genuinely spans several separate areas) it splits the work by area and runs one helper per area at the same time: the stack recommendation, the problem domain, the technical landscape and prior art, and the existing code and its constraints. On a small or narrow ask it deliberately does not fan out, and just answers the question directly, so a one-line bug fix never turns into a broad audit. If the agent you gave the Researcher seat has no background agents of its own, it covers the same ground one area at a time instead.

These background agents are the role's own helpers, separate from the team roles you assign in settings. You do not configure them; they appear only while a role is using them and clear as each one finishes.

Serial vs parallel work

The team can run tasks in parallel across isolated lanes, each task on its own branch, merged back with a review gate, or one task at a time when you turn parallel off. The dispatcher on the board sends ready work to the active agents and advances as tasks complete (you see "task N of M" while a task runs). Either way, the handoffs, the plan gate, and the permission prompts stay easy to follow and easy to control.

With parallel on, several lanes run at once and land in order behind the review gate, so nothing merges unreviewed. Approved work merges onto your repository's main branch whenever the run finishes, pauses, or reaches a checkpoint, and merging always targets your main branch even if the folder was left on another branch. Work approved before an app restart is picked up and merged on the next run. Each role is started in its own lane and sets up its own test state there, which keeps lanes apart in ordinary work; it is a working arrangement, not a sandbox. A role checking another role's work does not assume its own lane contains that work, so Castforge points the check at the tree that does. Turn parallel off in the project's Settings, Behavior and the team works as a relay instead: one baton at a time, focused and simple to steer.

If a role reports a task complete during a turn but its review of that same task is blocking, Castforge holds the completion instead of recording it. The card stays in progress, nothing is lost, and the completion lands on the next turn if the review passes.

How routing decides who works

You do not have to assemble the whole team for every message. When you send a request, Castforge reads it for intent and routes it to the right depth (adaptive intent routing, covered in "Working in a project"). That routing also decides which of your roles actually participate, so a small change stays light and a big one gets the full team.

Routing only ever seats roles you have actually configured for the project. It picks how many of them to involve for a given message; it never invents a role you did not set up. If you want a request handled at a different depth than the one it chose, use the one-click override on the announcement to re-run it with more (or less) of the team involved.

When a big-looking ask is really one edit

Routing can also correct itself the other way. Sometimes a request reads like pipeline work but, on a closer look, is really a single small edit. When that turns out to be the case, Castforge does not stand up the whole team and a board for it. It handles the request as a fast edit instead, so the one change is made and committed directly, with no plan and no board cards. You see the same kind of announcement as any other route, for example "Simpler than planned: doing it now." carrying the same one-click override, so if you did want the full plan after all you can promote it back in a click.

Setting up your team

  1. Open the project, then open its Settings.
  2. Go to the Agents and roles tab.
  3. Pick a preset (Solo, Pair, Trio) as a starting point, or start from Custom.
  4. On each role card, assign an agent and, optionally, a model and plugins. Connect or install an agent inline if prompted.
  5. Open Role charters and customize any role's standing instructions, or leave them on the defaults.
  6. Review the Handoff rules and toggle them to taste. Turn on "User approves Lead plans before execution" if you want a gate before any code runs.
  7. There is no Save button: changes persist automatically.

You can also pick a team while creating a new project (the wizard's "The team" and "Charters" steps mirror these same controls), or when adopting an existing folder (Castforge proposes a team and maps it to your connected agents).

Common questions

Do I need all six roles? No. Every team keeps a Lead and a Coder (those two seats cannot be removed); the rest are optional. Start with Solo or Pair and add roles (Tester, Reviewer, Researcher, Designer) as you want more structure.

Can different roles use different agents? Yes. Each seat has its own agent and model. A common setup is a stronger model on the Lead or Reviewer and a faster one on the Coder.

What is the difference between a charter and a handoff rule? A charter is the standing brief for a single role (how it should behave). A handoff rule governs how work moves between roles (who passes to whom, and when).

I rewrote the Reviewer charter and it still reports a verdict. Why? Because that instruction is added after your text and cannot be edited away, along with a handful of others. It is what keeps the handoffs working: without it a review would have no way to say no, and the run would read every review as approved. The same applies to the Tester and the Designer. See "A few instructions are always added after yours" above.

What is the difference between approving a Lead plan and a permission prompt? Plan approval gates the whole plan before any work starts (Approve / Edit / Reject). A permission prompt is a per-action go-ahead during the work (Deny / Allow once / Allow always).

Why did my preset change to Custom? Any edit to the team (agent, model, role, or plugin) means it no longer matches a named preset, so it is labeled Custom. Your configuration is intact; only the label changed.

Can the team run several tasks at once? Yes. With parallel turned on, the dispatcher runs independent tasks at the same time, each on its own branch, merged back in order onto your main branch behind a review gate. Turn parallel off in Settings, Behavior and work runs one task at a time.

Why did my design check get refused? A design check is refused when Castforge cannot find a tree that holds the work it was sent to review. The refusal names the checking role and says in plain language what went wrong, for example that the check was pointed at the wrong working copy, rather than printing an internal path at you. The full technical detail is still recorded in the project's history, so nothing is lost. The usual fix is to re-run the writer turn after recreating or integrating that tree. See "Recovery and troubleshooting" for the next steps.

One other thing is worth knowing about that refusal: it does not park anything, so the run keeps going and the Designer keeps its real status instead of reading Blocked.

The Designer already finished its card. Does it still check the UI after an approval? Yes. When a UI-bearing task is approved, the Designer takes another look even if its own design card for that phase is already done: Castforge reopens that card, the Designer works it again, and the card returns to done when the check finishes. You see the card move back to doing on the board while it runs, which is the honest picture of what is happening. Earlier builds refused the check in this situation and the Designer went quiet after the first pass.

The Designer has no card at all in this phase. Does it still check the UI after an approval? Yes, as long as another role finished work in that same phase. Castforge points the check at the work under review, whichever role wrote it, so a Designer with nothing of its own to reopen still grades the screen the Coder just built. Nothing is reopened on the Designer's side and no card moves on the board for it; the Designer simply checks the other role's finished card directly. This is the same "any role can check another role's work" model the Reviewer already uses.

Why does my decision log say a Designer re-check was skipped? Because it was, and Castforge would rather tell you. That entry is written only when the Designer owns no card at all in the phase that is currently active AND no other role has finished any work there either, so there is genuinely nothing to check. The run continues without the check and the entry records that choice, naming the phase. It is written once per phase, not once per approval, and you can read it in the Memory tab or in the project's .castforge/decisions.md. If a phase you expected the Designer to grade shows up there, the fix is to give the Designer a card in that phase, or to make sure another role's card in that phase is actually finished.

What does "Waiting on the Coder" mean on a role? That role's next task is queued behind the Coder's current task, so it cannot start yet. It will start on its own as soon as that task is done, and hovering the status names the exact task it is waiting for.

Where do I see what the team is doing? In chat you see each role's output, the turn-start banners, and the handoff banners. On the board (the course) you see tasks move through their states. See "The board: course and milestones" for the board.

How do I tell which role wrote a message? Each message in chat is headed by the role that produced it, followed by the agent that ran it, for example "Lead, Claude". The dot on that header and the bubble's left edge carry that role's own color, the same color the role uses on the relay strip, so you can scan a long conversation and see who did what.

Reopening a project replays the conversation from history, and the role behind each message is recovered from that history too, so a reopened transcript stays color-coded exactly as it was live. Where the recovered history genuinely cannot say which role owned a turn (for example a very old turn from before the point the replay starts, or a plain single-agent chat with no roles involved), the message is headed by just the agent that ran it rather than being labeled with a guessed role.

What does "Running: N background agents" mean on a role? That role has spun up N short-lived background helpers (for example, the Researcher researching several questions at once). Each shows as a child dot beside the role's name on the relay strip; click a dot to watch that helper's own stream. The team waits for the helpers to finish before the next role starts, so a plan is never built from half the research. See "Background agents" above.

Written and maintained by Julien Abenhaim, founder of Castforge. See the editorial guidelines.