DEV Community

Ordewell
Ordewell

Posted on Originally published at ordewell.ai

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 first: 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.

  • Task ids are stable. A task keeps its identity across edits, so "task 5" means the same task before and after your change. References also accept #order or a bare order number.
  • Dependencies are data, not prose. The edge between two tasks is an id in a list. It can be read, checked and refused without a model anywhere near it.
  • Some fields are system owned. Status, verdict and id are not whatever the last reply said they were. The model may edit a task's title, description, prompt, dependencies, runner, model, mode, effort and type. The rest belongs to the thing that runs the plan.
  • Edits are atomic and validated as a set. When a model proposes several changes at once, either all of them apply and the result validates, or nothing applies and you get the errors. A half-applied multi-step edit is how a plan ends up in a state nobody designed.

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.

# 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
Enter fullscreen mode Exit fullscreen mode

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

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

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:

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

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

  • There is no supported text editor route. The session is written to disk as JSON and it is indented nicely, but editing that file by hand is not supported. The supported direct paths are the keys, the CLI, the extension and the API.
  • A manual completion is recorded as manual. When you mark a task done by hand, the verdict says that no automatic verification was performed. That is honest, and it should read as a warning rather than a pass.
  • Edits do not undo themselves. There is no undo stack, and letting you reach a running task means you can cancel work with a keystroke that a model would have been stopped from touching.
  • The pickers are only as good as discovery. Model, effort and mode choices come from what the runner reports, so an undiscovered runner shows an empty list.

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.

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
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (1)

Collapse
 
reidmarlow profile image
Reid Marlow

The sharpest edge with hybrid plans is protecting human edits when an upstream step dynamically expands downstream work. If task 3 succeeds and an agent generates subtasks to finish the goal, the runtime needs a hard immutability lock on hand-added nodes and explicit dependency edges. Without a system-enforced ownership flag on human-authored steps, the agent will happily absorb the manual task into a broader prompt or bypass the dependency entirely.