Plans before code: keeping an AI inside the architecture

Oct 17, 2026
-
A. Nardone

An AI assistant does not remember yesterday and will cross a line if that is the shortest path. How written plans, now public in the repository, set decisions and limits before the code: one real case from this week, what a plan contains, and where plans fail.

An AI assistant does not remember yesterday. It is fast, it is willing, and it will cross an architectural line if that is the shortest way to make a test pass. In Whoobe we handle this with written plans: short documents that fix the decisions, the limits and the way to know a piece of work is done, before any code is written. The plans are in the open repository under docs/plans, 72 files as of 17 October 2026. This post uses one of them to show what they do, and what they do not.

One case: a flow that started itself

On 16 October we tried an automation on a real engine. A flow received the event object.updated, changed a field of the same record through its own API client, and that change was an event too. With the protection switched off it ran three times and stopped, only because the second value was the same as the third and the third write changed nothing. With a value that changes each time (a timestamp, an id from an external service) it would never have stopped, and Whoobe had no limit of its own.

The fix was not obvious, so the first thing written was the plan: object-events-loop-guard.md. It did four things.

  • It described what happened, with the timeline of the three events, before proposing anything.
  • It split the answer in three layers, each useful alone: a circuit breaker that needs nothing from the flow, an explicit "end of flow" mark on a write, and a correlation id that needs the flow's help.
  • It listed the decisions to make and left them open for the owner: the numbers of the breaker, whether a person's edit should count, whether a stopped delivery is ever retried.
  • It set the steps, each one a commit, with the tests before the code.

Six minutes after the first version of the plan the owner's choices were in it: the mark is a plain header, X-Whoobe-Flow: stop, the same for every engine; and the breaker counts only API clients and the system, never people, so that two people (or a person and a flow) editing together are never stopped. Twenty-six minutes after the first commit of the plan, the commit with the code was in. It is 22 files and about 460 added lines: the breaker, the new delivery status stopped, the header, the badge on a subscription, the log filter, the documentation and the tests. The branch was merged later that morning.

The plan also recorded what was not built. Layer C stayed out. A per-client "exempt" switch was dropped, because a burst on one record by one client is suspicious in itself and imports are already silent. The status line at the top of the plan says so.

What a plan does for an AI

  • It is the memory. The assistant starts each session without the last one. The plan is the part of the last session that survives.
  • It moves the argument before the code. Changing a sentence costs nothing; changing a choice after the code and the tests costs a day.
  • It sets the limits. "No automation engine of our own", "credentials stay on the server" and "one workspace per organisation" are written as decisions, with their cost. A limit that is written down can be checked; one that lives in someone's head is crossed by the shortest path.
  • It lets a person review the intent instead of every line. You read the plan, then check that the code respects it.

What we put in a plan

  1. What happened or what is needed, in facts.
  2. A proposal with its alternatives, and what each costs.
  3. The decisions still open, and who takes them. When one is decided it is struck through and the choice is written beside it.
  4. The steps, each one a commit, with the tests first.
  5. What is not in the plan.
  6. A status line at the top, updated when the work is done, with what was left out.

Where plans fail

  • They go stale. A decision page last updated on 13 October says that Whoobe emitting a webhook for a record change is "not built yet". It has been built since, and the page still says otherwise. An assistant that reads that page will trust it. A plan that is no longer true is worse than none, so each one needs a date, a status, or a note that it is superseded.
  • They can say too much. A plan that lists functions and lines gets followed to the letter even when the real code has moved. Choices, reasons, costs and a way to tell it is finished last longer.
  • They verify nothing. A plan states an intention. Only a test shows that the limit holds: the route-drift test and the two-stack isolation tests guard the boundary, not the document.
  • They cannot cover what nobody foresaw. Two of the worst findings of the project (function permissions never enforced, a push key served by a public route) were in areas where no plan had anticipated the problem. They were found by reading the documentation. See what we measured.

What we do not claim

This is one project and one architect. Plans cost time, and for a small change the overhead is not worth it: a typo does not need a plan. We have no comparison of the same work done without plans, so we cannot say how much they save. What we can say is that the loop above went from a puzzling test to a bounded, tested, documented behaviour in a morning, and that every choice in it can be read afterwards, by anyone, in the repository.

If you want to try it

Start with one decision, not a template: write what you decide, why, what it costs and when you would revisit it. Add the test that would fail if the decision were broken. Date it. Then give it to the assistant before the next task.