Seven stages, a prompt on every arrow, and a hook on every arrow that can refuse the move. This is what the pipeline does today and where each part lives.
The seven stages are hardcoded in the engine: Inbox, Prepare, Doing, Review, Deliver, Verify, Close. Nothing adds a stage or renames one, and a move to a name the engine does not know is refused. What varies is the walk. A card type can skip stages, so a research card never sees Prepare or Verify and an agent card walks only Inbox, Doing, Verify and Close (see cards). Deliver is per project, through the project's deliverAfter value, which defaults to review.
| VALUE | WALK AFTER REVIEW |
|---|---|
off |
Review, Verify, Close. Approving a review goes straight to Verify. |
review |
Review, Deliver, Verify, Close. Ship first, then verify on the deployed environment. This is the default. |
verify |
Review, Verify, Deliver, Close. Prove it locally first, then ship. |
Settings has no switch for deliverAfter yet; it is set on the project through the daemon's project route. Approve is the one arrow where Grid Console picks the target: the next stage the card's type walks, or the stage deliverAfter names.
There is no workflow document format, no front matter and no parser. The workflow on the SDLC page is the sdlc.workflow contribution of the bundled grid-sdlc-default plugin: seven rows of from, to, a trigger sentence and a verification sentence. The same plugin contributes card.section, the contract chips each stage shows. A trigger is prose for the page ("on your plan approve"); nothing in the engine reads it as a vocabulary.
Alternative workflows as installable plugins are not built. The SDLC page lists trunk-flow and regulated as not installed, and grid workflow check exits 6 until a document format exists.
Every move from the board, from Close, from your Approve, from a stored answer or from a session starting on an Inbox card passes through one chokepoint. The agent does not call it. An agent moves its own card by writing status: into the card's front matter; the watcher sees the write and runs the same hooks as an observation, which can advise but not refuse. One exception: an agent that writes Verify back to Review after a failed verification is held in Verify for your decision. Before any hook runs, the engine refuses a move into a stage the card's type does not walk.
A plugin, or the core, registers hooks by name: before:<stage> and after:<stage> for each of the seven stages, and on:attention when a card asks for you. A hook answers with one of three verdicts.
| VERDICT | EFFECT |
|---|---|
pass |
The move goes on to the next hook. |
block with {reason, fix} |
The card stays put. reason says why; fix is a sentence written for the card's own agent, and it is what grid card move prints with exit 4. |
amend with {sections} |
Sections are appended to the card body before the move. Amendments apply after the whole list has run, so no hook sees another's write. |
Hooks run in registration order, mutating core hooks last, and the first block ends the run. A hook that throws counts as a pass. A plugin hook runs in the plugin's own child process with a budget of five seconds; when it does not answer in time, the move proceeds and the log says so. A blocked move is recorded on the card as blocked_move with the hook, the plugin, the reason and the fix.
The shipped workflow registers one gate, before:review. It checks that the card's last ## Review block carries ### Needs your eyes, ### Assumptions, ### What changed, ### Files touched and ### Branch, presence only. A card opts out with contract: off in its front matter; the plugin's requireSections setting turns the gate off for the workspace. The core's own hooks cut the worktree on before:doing and hold after:review while an adversarial review round is running. Landing (merge, push, pull or merge request, cleanup) runs as one of Deliver's own tracked steps once the work is committed. before:closed lands again as a safety net, and by the time it runs there is usually nothing left for it to do. Deliver registers a gate of its own on before:verify and before:closed: a card leaving Deliver with a step that has actually failed is refused, with the step and its detail as the reason, unless you shipped it anyway on the panel.
Each arrow carries a prompt, and the prompt is typed into the agent's session as text, never run as a shell command. Delivery is retried up to three times and confirmed through the agent's own prompt hook. The text comes from three sources; the first one present wins.
| SOURCE | WHERE |
|---|---|
| Your override | YOUR PROMPT on the Agents tab, per provider and stage. |
| A file in the repo | The provider's command file. Claude Code reads .claude/commands/prepare.md, start.md, build.md, self-review.md, deliver.md and verify.md; Codex reads the same names under .codex/prompts/. Grid never writes these files. |
| The shipped default | The provider plugin's own text, with the engine's builtin behind it. |
There is a seventh prompt behind those six command names: the adversarial reviewer's. It is not an arrow of its own but the text a fresh reviewer is started on when Review hands the card over, and it is editable on the Agents tab, as the Adversarial reviewer, like the other six. It tells the reviewer it did not build the card, caps it at five findings, allows a [critical] tag only for a failure it reproduced, and asks for a verdict line under its own heading in the card's Review block.
Below the prompt, Grid appends the sections the card must carry when it leaves the stage. Prepare carries Summary, What I will change, How I will know it works, Requires your attention, Expected files I will touch, Related cards, List of tasks, and Questions asked with your answers. Doing carries Summary, Changes so far, Changes still to do, the ticked task list with deviations marked, and Requires your attention. Review carries the ## Review block above; Deliver one ### Delivery line with the PR or MR link and the pipeline verdict; Verify one ### Verification line with pass or fail and the evidence. A card type without Prepare starts on the start prompt when it enters Doing.
The Agents tab holds the workspace-wide toggles under "Grid also requires": decide on a worktree, work out how to run, test, deliver and verify it, and find related open cards, at Prepare; run it locally, verify it there, and do an adversarial review, at Review. Each is on unless you turn it off; none is per project.

The model is chosen by role. Inbox, Prepare and Review run "Research and planning", Doing runs "Implementation", and Deliver, Verify and Close run "Delivery and validate". The workspace budget (eco, balanced, quality, max) and the card's difficulty (easy, normal, hard, vhard) pick a model and effort from a fixed table; you can override any cell in Settings, and a card can pin a cell of its own per stage. See models.
Some arrows hand the card over rather than carry on with the agent that has it: Prepare to Doing, every arrow into Deliver or Verify, and Doing to Review when the adversarial review is on for the card's difficulty (on by default for hard and vhard, off for easy and normal). Two of those always end the conversation and start an agent that really is new: any arrow into Deliver, and the reviewer's arrow into Review. The rest keep the running agent when the next stage wants the same model, the same effort and the same directory, and type the stage's prompt into it; otherwise the session is killed and a fresh one takes the card. Deliver and Verify share a column of the model matrix, so Deliver to Verify normally keeps its agent. Whether the other arrows into Verify keep or replace depends on the budget and the difficulty: on the default balanced rungs the implementation and delivery columns are the same model and effort, so Doing to Verify usually keeps too, while Review to Verify usually replaces, because Review sits with research and planning, which is a different column. Either way the session gets the next stage's prompt, along with the matching notice: new here, or the card has moved and stays with you. Handoffs never gate. At boot, a card sitting in Deliver or Verify with no live session is rescued the same way, with a fresh agent for the stage it is in.
How work leaves is set per project under the project's Delivery group in Settings, with a per-repo override that otherwise inherits. A mode's first word says whether the card branch survives as a branch: Push lands it on origin as a branch of its own, while Merge folds it into the base ref. What follows says what reaches origin. Push the branch (branch) commits on the card branch and pushes it: nothing is merged, nothing is opened, and the branch is the deliverable. Push the branch, open a PR (github-pr) does the same and opens a pull request on GitHub; Push the branch, open an MR (gitlab-mr) is that on GitLab, a valid engine value awaiting a settings chip. Merge, don't push (local) commits on the card branch and Grid merges it into the base ref in your checkout, with nothing reaching origin, and Merge, then push (push) is that same merge followed by a push of the base branch. No commits (none) leaves the work in the tree for you to commit yourself, and is also what a project reads before it has chosen. A project that has chosen none of them is asked by the first card to reach its shipping stage, and the answer is recorded with grid project delivery <name> branch|pr|local|push; it can be changed the same way at any time, and live sessions are told. Those four are the four chips in Settings. The merges Grid performs are the landing of the card's branch on its base under the two Merge modes, at Deliver, at Close as a safety net, or on grid card land; it never merges a pull or merge request itself. Pushes to protected branches are refused by the agent permissions, see security.