Docs / Developer mode
Plan mode
For work with several steps, ivralo writes a plan first, waits for your yes, and then runs it in waves. This page covers drafting, the plan file and its keys, how a step is judged, and what to do when one fails.
Ways in
| How | What it does |
|---|---|
Shift+Tab, or /plan alone | Toggle plan mode: every message is planned first. The top bar shows plan while it is on |
/plan <request> | Plan this one request |
/plan --job <request> | Draft a plan, approve it, then run it as a job that outlives the session |
/plan resume | Go on with a plan that was stopped |
ivralo plan "..." | Draft a plan on the command line and print it, without running it |
ivralo ask --plan "..." | Draft, show, ask, then run |
With plan mode off, ivralo still plans a request that reads as several steps: two or more files named with a deliverable's extension (revenue.png and report.pdf), or two or more distinct sequence words ("first ... then"). The transcript says why in one line. A coding request usually plans into a single step anyway.
| Setting | Default | Effect |
|---|---|---|
IVRALO_AUTO_PLAN | true | Plan a request that reads as several steps |
IVRALO_PLAN_MODE | false | Start the session in plan mode |
IVRALO_PLAN_PARALLEL | true | Run steps that do not need each other together; false runs one step at a time |
Drafting
The planner starts from a brief of the workspace that plain Python builds: every file with its size and kind, the columns of each CSV and workbook, the page count of each PDF. In a repository the brief opens with one line about the tree and the commands IVRALO.md declares:
a git repository - 137 files, mostly .py (120), .md (14), .toml (3);
commands from IVRALO.md: test `uv run pytest`, lint `uv run ruff check .`
The planning turn calls no tools at all. The main agent can read and edit, but while it plans, every call it tries is refused and any call that would ask you is rejected before you see it. Drafting a plan changes nothing.
The plan file
Every draft is written to .ivralo/plans/<stamp>-<slug>.md in the workspace, and the approval screen renders that file and names it. It holds a short approach, the numbered steps, the open questions the planner had, and a verification section. Each step names the specialist that runs it, a title of a few words, a self-contained task, and the files it must leave behind.
You can open the file in any editor, reword a task or strike a step out, and press e: the edited file is what runs.
| Key | On the plan screen |
|---|---|
Enter, y | Run the plan |
r | Revise: type what should change, and the plan comes back for another look |
e | Reload the plan file after you edited it |
Esc, n | Drop the plan |
Waves and needs
A step builds on the step before it unless it says otherwise. It can name the earlier steps it needs, the ones whose files or answer it uses, or need nothing. The plan file shows it at the end of the step's line:
1. **Librarian** - Research the market
2. **Data Analyst** - Read the sales schema *(after nothing)*
3. **Report Writer** - Write the report *(after 1, 2)*
ivralo, not a model, runs the plan in waves: every step whose needs have finished starts at once, each as its own turn. Steps 1 and 2 above run together, and step 3 waits for both. A step may only need earlier steps; a mark that points forward or at no step is reported, and the step goes back to building on the one before.
Two steps that would run together must not promise the same file. The approval screen names the clash before you run it, and if you run it anyway the two never share a wave. One specialist's steps in a wave still run one after the other, because each specialist has one Python worker. Several coding steps in one wave do run at once, each with its own Code Engineer (Parallel coders and worktrees).
While a plan runs, the plan board sits above the input bar: the step count, every step by title with its state, and under a running step what it is doing right now. Above six steps it shows only what moves; Ctrl+L shows every step. A message you type during a step reaches the specialist at its next tool call, and every later step is handed it as a note.
How a step is judged
Before each wave, ivralo takes a checkpoint: a record of the workspace that history can return to. After the step runs, every file it promised is judged against that checkpoint:
| Verdict | Counts as delivered |
|---|---|
| created, modified | yes |
unchanged, when the reply says unchanged: <name> on a line of its own | yes |
| stale (there before and never touched), empty, absent | no |
A file only the generating tool can name (a migration) is promised as a glob, alembic/versions/*.py, and counts when a matching file was created or modified. A promise with < or > in it is a placeholder and is not checked. A step also fails when its turn ended on a tool call that failed, or was refused, and nothing corrected it. A Markdown or Word file a step created gets a Sources section at its end, written by ivralo from what the step read.
When a step fails
A failed step opens the failure screen, naming each promised file with the word that judged it, such as report.pdf (stale).
| Key | On the failure screen |
|---|---|
r | Send the step's trace to the main agent, which answers with one revised step for you to approve |
b | Roll back the workspace to the checkpoint before the step's wave |
| Esc | Stop; /plan resume goes on from that step once you have fixed things |
A revised step is added after the failed one, marked (revised); the failed step stays in the plan file with its reason. A rollback restores every file the wave overwrote through history. Files the wave created are listed and deleted only after a second yes. In a wave where one step fails, the steps already running finish, no new step starts, and the plan stops when the last of them ends.
From the command line
ivralo plan "add a CSV export to the reports page and document it"
ivralo plan "..." --json # approach, steps and questions for a script
ivralo ask --plan "..." # show the plan, ask run / revise / no, then run it
ivralo ask --plan --yes "..." # in a pipe: run without asking
ivralo plan writes the plan file and prints it. ivralo ask --plan in a pipe refuses to run without --yes; a step that fails there prints what a rollback would touch, without touching anything.
Plans as jobs
A job is a run whose record lives in PostgreSQL, so it outlives the terminal that started it: ivralo resume <id> continues it, and a call that needs an approval parks the job until someone answers (Jobs).
| Command | Review step |
|---|---|
/plan --job <request> | You approve the plan in the session, then it runs as a job |
ivralo ask --plan --job "..." | The plan is shown first, then it runs as a job |
ivralo plan --job "..." | None: the drafted plan runs at once as a job |