Set up review workspaces
View as markdownThe multi-workspace loop gets finished branches back to you. But reading a diff isn't the same as running the change. Most real review of an app or a site means booting the dev server, opening a URL, and clicking through it.
The routing that gets an issue to a review slot is assembled from generic
primitives: a workspace carries a tag and a status requires that tag.
On top of that, the workflow's review: block tells the Review agent how
to boot the branch, and Shelbi's review interface lets you run the change
and accept or reject it. This page wires them together end to end. For the model
underneath, see the reference:
Review workspaces.
You need a working pool first
This page assumes you already have a project with a workspace pool and can promote an issue through the board. The first task and multi-workspace pages get you there. A review workspace is an ordinary slot with a tag, not a new kind of thing.
Set up and use the review flow
New projects already have most of this: shelbi init creates a review
workspace tagged review, and the shipped task workflow's review status
already requires that tag and runs the review agent. For a new project, the
real work is giving that slot a slot: port (step 1) and adding the review:
block (step 2). The tagging steps matter for projects created earlier or with
custom workflows.
Tag a workspace for review
Add a review tag to a slot in your project YAML
(~/.shelbi/projects/<name>.yaml in global mode,
<repo>/.shelbi/project.yaml in-repo). Tag one workspace directly, or tag the
machine so every slot on it inherits the tag:
workspaces:
- { name: alpha, machine: hub }
- { name: bravo, machine: hub }
- { name: review-0, machine: hub, tags: [review], slot: 3000 }tags accepts a bare string as shorthand (tags: review). The slot: 3000
sets the numeric slot the review: recipe below resolves $PORT to, so the
dev server binds :3000. A review slot that serves a review: recipe must
set slot:. The recipe takes its $PORT only from an explicit slot:, and
without one the Review agent stops and reports a misconfiguration instead of
serving. (The declaration-order fallback applies only to $SLOT in transition
run: commands.)
One review slot is plenty to start
Each review slot holds one running server bound to its port, so give a second
review slot a different slot: value (3010) to avoid a collision. One is
enough for a first pass.
Require the tag and add a review: serve recipe
In your workflow file, require the review tag
on the review status so issues route to the tagged slot, then add a
review: block telling the Review agent
how to boot the branch:
# Excerpt: the other statuses and the `→ canceled` edges stay as they are.
statuses:
- { id: in-progress, owner: agent, agent: developer }
- { id: review, owner: user, agent: review, tags: [review] }
- { id: done, owner: user }
transitions:
- { from: in-progress, to: review, actions: [push_branch, open_pr] }
- { from: review, to: done, actions: [push_branch, merge] }
review:
setup: npm install --no-audit --no-fund
serve: npm run dev -- -p $PORT
ready: curl -sf http://localhost:$PORT
url: http://localhost:$PORTShelbi resolves $PORT (equivalently $SLOT) to the review slot's port
(3000 here) and injects the recipe into the Review agent's prompt. The agent
runs setup, launches serve, polls ready until the server answers, and
hands back the url. Swap the npm lines for whatever your project needs:
cargo run, a Makefile target, a Procfile web: line. For a monorepo, add
workdir: site (or app, docs) so each workflow serves its own
subdirectory on the slot's port.
These are the shipped task workflow's edges. Entering review pushes the branch
and opens a PR; the review → done transition is the accept edge, and it pushes
and merges the branch. Omit the review: block entirely and the Review agent falls back
to a diff-only review, booting nothing.
Reload to pick it up
shelbi reloadThe tagged slot does not show up under Workspaces. A review slot's capacity surfaces through the review sections instead, and only once an issue is routed to it.
Get an issue to the review status
Run an issue the way you normally would: promote a card and let a dev workspace pick it up, or dispatch one through the orchestrator. When the dev workspace finishes it writes its review-ready marker; the hub poller rebases the branch onto the base branch and moves the issue into the Review status, which pushes the branch and opens a PR.
Because that status requires tags: [review], the hub automatically loads the
issue onto the first free review-tagged slot (the orchestrator never does
this) and the Review agent boots the server from the review: recipe. You can
also load it yourself with Enter on its Queued for Review row or from the
paletteby clicking its Queued for review row, from the palette, or
from Go ▸ Reviews. If every review slot is busy the issue waits under Queued for
Review until one frees; nothing is preempted.
The finishing dev workspace closes its own session and returns to idle. Its
work is now waiting to be run, not edited.
Open the review interface and click through
The issue appears in the sidebar under Ready for Review (✓) with a
machine:workspace badge showing the slot it's loaded on. Select it (or press
Enter on its row) to open the review interface: a two-column layout with
the review panel on the left (its own navigation, with a back button at the
top that returns you to the dashboard) and the swappable review content on the
right.
The issue appears in the sidebar under Ready for review with a cyan check.
Click it (or press its ⌘1–⌘9 shortcut) to open the review view: the review
panel takes the sidebar's column (a back button at the top returns you to
the board, and Esc does the same) and the swappable review content fills the
main area.
From the review panel you can:
- 🤓 Reviewer: talk to the Review agent (the default view).
- 🔀 View Diff: read the review branch's changes in
Shelbi's own diff view, in the main pane. Press
?there for its keys.Entercomments on a line, andgYstarts a reject with your comments as its reason. To open another tool instead, see Using another diff tool below. - ✍️ Edit in
<editor>: open the review worktree in your configured editor: in the main pane for a command, in the app for an app. - 🌐 Open Browser: open the served
urlin your system browser. This action only appears when the workflow declares a review URL.
On a remote review slot, Edit is hidden, and View Diff is offered only for Shelbi's own view, which reads a worktree on any machine.
The views are numbered, so ⌘1, ⌘2, and so on switch between them while
the review is open.
- Reviewer: talk to the Review agent (the default view).
- View Diff: read the review branch's changes in
Shelbi's own diff view, in the main area. Press
?there for its keys.Entercomments on a line, andgYstarts a reject with your comments as its reason. To open another tool instead, see Using another diff tool below. - Edit in
<editor>: open the review worktree in your configured editor: inside Shelbi for a command, in the editor app for an app. - Web Browser: open the served
urlin your browser. It reads "loading…" until the server is up, and only appears when the workflow declares a review URL. - Shell: a shell in the review worktree, beside the content.
The worktree's folder sits above the views; Open reveals it in Finder. On a remote review slot, Edit is hidden, and View Diff is offered only for Shelbi's own view, which reads a worktree on any machine.
The built-in review agent's charter is narrow: load and serve, don't
code. It won't modify the branch or move the card. Point agent: at an agent
you've authored to change what runs there.
Approve or reject
You own the decision, and you make it from the ✅ Approve / ❌ Reject row at the bottom of the review panelApprove and Reject buttons under Actions in the review panel (or the issue's submenu under Go ▸ Reviews):
- Approve: moves the card one column forward (
review → done), firing that edge'sactions: per the workflow above, it pushes and merges the branch. The interface tears down and focus returns to the dashboard. - Reject: opens a type-the-reason dialog (
Ctrl-Dsubmits). On submit, the reason is appended to the issue body and the card bounces back to the ready status for another pass. An empty reason can't submit.
Either decision frees the review slot for the next issue routed for review, if any.
Using another diff tool
View Diff opens Shelbi's own diff view unless you choose otherwise. There are two ways to choose:
diff_toolin~/.shelbi/config.yaml, or the Diff tool picker in Settings ▸ General, picks a tool for every project.diff_tool: gitruns git's own difftool (diff.guitool, elsediff.tool). A command runs in the main pane, and an app opens in the app.review.diff_commandinproject.yamlruns a command of your own for one project, and takes precedence overdiff_tool.
Use review.diff_command for a tool that reviews a revision range rather than
a pair of files or folders (skim <base> <head>, for example). It runs in the
review worktree, with three placeholders substituted:
{worktree}: the review workspace worktree,{base}:merge-base(<base branch>, HEAD), the fork point, and{head}:HEAD.
{base} and {head} are the same range the built-in view shows:
review:
diff_command: skim {base} {head}A diff tool that exits without rendering leaves a short message in the pane rather than only git warnings.
Next
Routing an issue to a review workspace is the human path: the whole point is
human eyes on the running app. Keeping merge on the accept edge and off the
enter-review edge means a review issue waits for you rather than merging on
arrival, and while a project has a review workspace, Zen Mode never auto-merges
a handoff either. When you're ready to hand the orchestrator the cases it can
judge on its own,
enable Zen Mode to auto-promote
backlog, and (in a project without review workspaces) auto-merge finished
branches that clear a confidence bar you define.
See also
- Review workspaces: the full model: tags,
status-tag routing, the
review:serve recipe, the review sidebar, and the review interface. - Workflow config: status
tags, thereview:block, and the transition command fields. - Project config: machine and workspace
tags, and workspaceslot. - Global config: the hub-wide
editorthe "Edit in<editor>" view launches.