The plan is an artifact, not a transcript

Editing a plan without re-prompting the model

You read the plan, and task 5 is wrong. It should have waited for task 3. One of the steps is really two steps. A step you meant to do by hand got written up as something for an agent to run.

None of that is a change of intent. It is a change of data, and yet in most setups the only way to make it is to say so in a message and hope the whole plan comes back the way you wanted.

Disclosure: I build Ordewell, and direct plan editing is a thing it does. The tool is free and Apache-2.0. The interesting part is not the subcommands. It is which edits a model should never be trusted with, and what a plan has to look like for that line to be drawable at all.

Why the edit keeps going through the model

When the plan is a conversation artifact, the conversation is the data structure. Changing one dependency means sending another message, and the model re-emits the plan in prose. Two problems follow.

The first is that you cannot diff it. The old plan and the new plan are two blocks of generated text, and reading them side by side is the review. If the model also reworded task 2 or renumbered everything, that arrives inside the same reply as the change you asked for.

The second is that the edit is deterministic and the model is not. "Task 5 waits for task 3" has exactly one correct outcome, and routing it through a language model turns a field assignment into a generation.

What makes an edit deterministic

Four properties do most of the work.

The commands

In Ordewell the plan is an ordered list of tasks, and every subcommand below has a TUI key of the same name. <id> is an order number or a task id.

bash
# the plan is on disk before anything runs
ordewell plan --goal "Add rate limiting to the public API"

# task 5 should have waited for task 3
ordewell task-deps 5 3

# what that step really needed was a hand-added prerequisite
ordewell add-task --title "Backfill the limiter config" --depends-on 3

# this one was never agent work
ordewell remove-task 6

# you did this by hand, and you are saying so
ordewell complete 2

Dependency edits are checked before they land, and the refusals are plain:

bash
$ ordewell task-deps 4 7
"Backfill the limiter config" cannot depend on "Ship the limiter",
which comes after it in the plan

That check does not need a model. A task can wait for something earlier in the plan and nothing else, so cycles are unrepresentable.

In the full screen UI the same edits are keys on the plan pane: a adds a task, d removes the selected one, and opening a task lets you type into its prompt directly. None of it is a chat message.

One edit is worth calling out because it is not a single field. ordewell task-runner 2 opencode changes the executor and re-derives the model, thinking effort and mode from that runner's catalog, because a model is scoped to the runner that serves it:

bash
Task #2 runner set to opencode. Its model, effort and mode were re-picked for it.

Who is allowed to touch what

Here is the part I would copy even if you never install this tool: the same edit is governed differently depending on who asks, and that difference is deliberate.

The model's edit path refuses to modify or remove a task that is running or already finished. It does not get to reach into work in flight or delete a result it has already produced.

The direct path, meaning you, through the keys, the CLI, the extension or the HTTP API, allows both, and pays what that costs at the call site. Removing a running task cancels its runner first, so the process is dead before the task leaves the plan. Removing a finished task also releases anything parked waiting on it, which would otherwise sit blocked forever.

There is one guard rather than two rule sets, and it takes an actor parameter. Only the lock rule reads that actor. A dependency list, a model or mode assignment, and a task flipping between agent work and manual work describe the task, not who is editing it, so both paths run the same check.

That flip is where an edit turns into a deletion, and it says so. Move a task from agent work to hand work and the fields describing an executor stop meaning anything: model, effort, mode, autonomy. Move it the other way and its written-out manual steps do. The validator returns the fields the new type stripped of meaning and the caller clears them, so you are told what was lost instead of finding out later from a field that describes a task you no longer have.

The model is held to the same structural rules

This is why the validator matters beyond your own keystrokes. When you ask the planner in chat for a change, it does not get a text editor. It emits a small list of typed operations, and those operations go through the same checks your direct edits do. An invented model id is refused rather than silently swapped for something real. A dependency on a later task is refused. A change to a running task is refused.

The refusals are not silent either. The planner gets the error back, runner named, inside the bounded repair loop that handles a malformed plan, so a wrong edit becomes a correction rather than a plan that quietly lost a field.

Honest limits

The whole loop

Plan, read it, change what is wrong about it, then run. Nothing executes until the last line, and every edit above happens while the work is still text on a screen.

bash
npm install -g ordewell

ordewell plan --goal "Migrate the config loader from JSON to TOML"
ordewell task-deps 4 2
ordewell add-task --title "Keep the legacy reader for one release" --depends-on 4
ordewell run

Planning can be done by the coding agent subscription you already pay for, strictly read only, so no extra API key is needed. Source: github.com/ordewell/ordewell.