Graph runs
Graph runs
A graph run is work split into nodes with an order between them: two jobs that can run at once, a third that needs both, and a check at the end. An agent in one of your sessions writes the graph and hands it to mechabedo, or mechabedo writes it itself from a workflow; mechabedo opens a separate session for each node the moment the nodes it waits on have finished, a few at a time, and shows you the whole graph on the conversation that started it.
Reach for it when the order is real. Jobs that are all independent are simpler as separate sessions, and a single job does not need a graph at all.
A graph can also be drawn in the chat or BedoIDE's assistant: ask it to run the work as a graph beside one of your sessions, which becomes the parent.
Starting one
Ask the agent in a session for it: "split this into a graph and run it", or name the parts you want. The agent calls graph_start with the nodes, each one a complete prompt of its own and the list of nodes it has to wait for, and ends its turn. That session is the run's parent.
Beside the nodes, the agent can write the graph's shared constraints, what every node keeps to, and put a gate where the work needs your decision before it goes on.
A node runs on the parent's loadout and in its directory unless it names another loadout or another directory. That is how one graph spans two repositories, and how a small node goes to mechabedo fast instead of the parent's model.
A node the agent marks /nohalt does not fail on a halt. When its session stops on an API error or a rate limit, mechabedo recovers it in the same session, waiting longer between tries as they repeat, and the node fails only once those tries run out. Its line in the live view says so while it waits.
Or arm Graph Shot on the session's prompt line from its Workflows tab: mechabedo writes one optimized prompt from yours, writes the graph itself from it with a loadout picked per node, and starts it with the session as its parent. The session is not asked to plan anything, so none of its context goes on planning. Graph True Shot does the same after an interview on scope and shipping, and Graph Gatling first reads your prompt for every separate goal and keeps each one as its own part of the graph. See Workflows.
The tools belong to the Graph runs category. The Plus kit carries it; the Lean kit does not, so a session on Lean is not offered them until you switch it on. Enhance, under Graph runs, has one switch per kit for exactly that, beside every run so far and a rehearsal of one playing. A graph mechabedo writes from a workflow does not need them.
Watching it
The graph's live view appears under the session title, below the card a /fork compression shows:
| Part | What it tells you |
|---|---|
| The chips | Which wave the run has reached, how many nodes are running and how many may run at once, how many are waiting for a slot, done, failed or skipped. N waiting for you counts the gates waiting on your decision and N asking the nodes whose session asks you something. When the run has them, shared constraints and N in jj copies appear too; hover either for the text or for how the work lands |
| The lines under them | What each running node's session is doing, such as the command it just ran |
| The cards | A gate waiting for your decision, and a card for each running node whose session asks you a question or for a permission, headed with the node's name and asks you, with Open its session. While any of them waits on you, the live view is tinted in the warning colour |
| The bar | How many nodes have settled |
| The picture | Every node, one column per wave from left to right, coloured by state, with a gate drawn as a pill. Hover a node for its state; click one to open its session in a tab |
| The buttons | Pause or resume, intervene, stop, retry, and close once it settled |
A wave is how deep a node sits in the graph, and it only groups the picture: a node starts as soon as its own dependencies are done, even while an unrelated node of the wave before is still running.
The parent's row in the rail says the graph is working even while the parent itself waits: its dot turns into a pulsing green ring, and its last line reads where the graph has got to, such as wave 3 of 6, 2 running, adding 1 waiting for you while a gate waits on you. Its tab shows the same ring. Open the row's tree for the graph node by node, including the nodes that have not started yet; each one with a session opens it.
A node's own conversation carries a line naming its node and graph, what state it is in, and a button back to the graph, so you always know where you are. A node in its own copy says so there too: own jj copy, where it works, and how its work landed.
The same picture draws an orchestrator job's task list, above its rows: one column per round of work, a task that reads the previous report behind the task it reads. A node is finished when its session ends its turn; its last reply is its report.
Gates
A gate is a node that opens no session: it asks you. Its prompt is a question, and it may offer up to six choices. A typical shape is research, then your decision, then the build.
Once the nodes it depends on complete, the gate reads waiting and its card appears on the parent's live view: the question, a fold with what the nodes before it reported, the choices as chips, a text box, and two buttons.
| Button | What happens |
|---|---|
| Carry on | The gate completes and your decision goes to every node below it, in its brief under What the user decided above you; a node that reads the reports before it gets it as a report. When the gate offers choices, pick one or type an answer first |
| Stop here | Everything that depends on the gate is skipped. The run ends completed, and the parent's report says it stopped where you said so |
Everything that depends on the gate waits until you answer. A gate takes none of the slots nodes run in, and a pause does not hold it back. Retry on a gate asks the question again.
Only you answer a gate, from the live view. No tool does, so the agent in the parent cannot decide it for you.
Stepping in
A node can go the wrong way: a test node that keeps tuning parameters when it should go back over the whole technique, say. You do not have to stop the graph for that.
| To | Do |
|---|---|
| Correct a running node | Type into its session, the way you would any other, or open intervene in the live view, pick the node and write a steer. Send now cuts its turn short; After its turn waits. The node stays the same node: it carries on with your correction and reports on the turn after |
| Stop more from starting | Pause. Running nodes carry on and finish; nothing new starts until you resume |
| Change the plan | In intervene, pick a node and rewrite its prompt. With restart on, the node and everything that depends on it start over on fresh sessions, even ones that already finished; nodes elsewhere keep their result. A node that already ran is always restarted when you rewrite it |
| Start over from a failure | Retry gives the failed and cancelled nodes fresh sessions on the same prompts |
The agent in the parent can do all of it too, with graph_steer, graph_pause, graph_resume and graph_amend, so you can also just tell it: "wave three is on the wrong track, restart it with this approach instead". Stopping a node's turn with nothing typed still counts as the node failing.
Shared constraints
A graph has one place for what every node keeps to: the libraries to use, such as Temporal, wording rules, files nobody touches. The agent writes them once as the graph's constraints instead of pasting them into every node's prompt, and every node's brief starts with them under Constraints every node of this graph keeps.
The live view shows a shared constraints chip; hover it to read them. The agent can change them mid-run with graph_amend, and an empty text clears them. Briefs sent after that carry the new text. Nodes already running are not told, so steer them if they need to know.
Nodes in their own copy
Nodes that run side by side in one directory share its files. A session node can instead ask for a jj working copy of its own, under .mechabedo/workspaces/ in the repository. mechabedo lands its work back into your tree when the node completes, before anything that depends on it starts.
Whether a node gets one is a machine setting, Isolation, on the Enhance page's Graph runs destination:
| Isolation | What happens |
|---|---|
| None | The default. Every node shares the directory, whatever it asks; most graphs never need a copy |
| Offer | A node that asks gets its own copy, and graph_start suggests one when nodes would run side by side in one directory. A node asking for one in a directory that is not a jj repository is refused rather than quietly sharing |
| Force | Every session node in a jj repository gets its own copy. Nodes elsewhere share, and graph_start says which |
The repository has to be a jj repository. In a git repository, jj git init --colocate makes it one; whether to do that is your decision.
How the work comes back is the run's commit setting, which the agent writes:
| Commit | How a node's work lands |
|---|---|
never | The default. Uncommitted, in your working copy |
node | Each node as a commit of its own, inserted just below your working copy |
end | Every node into one commit for the whole run, created when the first node lands |
Because the commits are inserted below your working copy, nothing else uncommitted in your tree, yours or another agent's, is swept into them. A node that changed nothing lands nothing. A node whose landing fails is failed with the reason, and its work stays in its workspace for ws_land_squash or ws_destroy to settle; a node that fails or is stopped keeps its workspace too.
When it settles
The parent session receives the run's report as its next prompt: every node's outcome and the start of what it reported. A run with a purpose, such as one mechabedo wrote from a workflow, carries it as What it was for, because the parent never saw the original prompt. The agent reads it and carries on, so a graph can be one step of a larger job.
A graph can run for hours, and a parent that sat idle that long has lost its prompt cache, so reading the report would bill its whole conversation again. When the parent has been idle longer than the run's handover time (55 minutes unless the agent set another; 0 turns it off), mechabedo writes a handover of the parent's conversation, opens a fresh session with it and the report, and that session leads the run from then on. The old session stays in the rail, and its live view says where the run went. Hand the parent over in the intervene panel does the same whenever you want it.
| Outcome | What happened |
|---|---|
| Completed | Every node finished, or you pressed Stop here on a gate. Behind a stopped gate, everything is skipped and the report says the run stopped where you said so |
| Failed | A node's session stopped, halted beyond what /nohalt could recover, was closed or ended without a report. Everything waiting on it is skipped; nodes that did not depend on it still run |
| Cancelled | You pressed stop, or the agent cancelled it. Running nodes are stopped and the rest never start. Their sessions stay in the rail |
On a failed or cancelled run the live view offers retry: the failed and cancelled nodes get fresh sessions, the skipped ones behind them go back in line, and nodes that completed keep their result. The close button takes a settled run's view away; the newest settled run stays until you close it.
Looking back
Every run is kept. In the Logbook, a session that led a graph or was one of its nodes shows a Graph line under its details. Open a run there for its picture, every node with its report, the steers it took and the attempts before the last one, and what was done to the run and when. Its shared constraints are in a fold, and a node in its own copy shows where it worked and how many paths landed. Each node links to its own session.
If mechabedo restarts while a run is live, the run is kept and marked cancelled. Retry or rewrite it to carry on; what completed keeps its result.
What is not there yet
A node that was in the middle of a turn when mechabedo restarted starts that node over on a fresh session. The files it changed are still there, but not the turn. The graph tools do not reach another machine's graphs yet: open that machine's window through Beam to step in. A node's report is a claim the agent is told to check, not a verified result, so a graph that changes code should end with a node that runs the real tests.