A code generation workflow that creates clean and maintainable code
October 2026, by Maarten Nieber
Generating the code

Next, we ask the AI to split the tests in batches, enable these batches one by one, and generate the code so that it passes the tests for that batch. The AI will base the code on the building blocks - and their related instructions - that are contained in the composable solutions.

Among these instructions, the most important one is to create (what I call) focussed feature-packages that contain focussed files. A feature-package encapsulates one particular functionality or concept of the code-base, such as “hotel_rooms” or “bookings”. When you read out the list of feature-packages, then it should sound like a high-level description of your application. Within a feature-package, the code is split into models (plain data-structures, almost no logic), actions (functions that change the application state), rules (functions that query the application state), utils, and a few other (optional) categories. By insisting that the code is split up in this way, we counter the tendency of the AI agent to keep adding more features to the same files (which leads to slop code).

AI-refactoring the code (optional)

The AI agent does a great job at creating focussed feature-packages and files, but it will sometimes create a large action file that does the work of an entire feature-package. When this happens, it’s because a feature-package was missing. I identify these cases by listing the n biggest python files in the code base, and ask the agent to split up the big file by introducing a new feature-package (with a name suggested by me).

AI-generating high-level scenarios

At this point, our application requirements are encoded in the test-suite, but it would still be nice to have a user-friendly high-level description of the features. Neither the design doc nor the workflow-tests serve that purpose very well. Therefore, I ask my AI to create scenario documents that explain the main features and workflows, while leaving out the edge-cases and details (an interested user can consult the workflow-tests for those). As the scenarios are created, the related parts are deleted from the design doc (until eventually the design doc is empty).

For capturing scenarios I use a special tool called sunya, but you can of course create your own format. My scenarios start with a run_scenario function that explains a workflow by walking through pseudo-code. Next, there is a Markdown description of the scenario steps, followed by a sequence diagram. All these three components overlap, but they also complement each other in nice ways. Below is the scenario for the reminders of our todo app, and the Markdown document that sunya generates from it.

extra/spec_src/scenarios/s03_a_user_is_reminded_of_overdue_todos/scenario.py
doc/spec/scenarios/s03_a_user_is_reminded_of_overdue_todos.md
import sunya
from sunya import C as c
from sunya import R as r
from sunya import goal, it, the

scenario = sunya.add_scenario("s03_a_user_is_reminded_of_overdue_todos")

def run_scenario():
r.user = c.External.Actors.User
r.scheduler = c.External.Systems.Scheduler
r.send_reminders_action = c.Reminders.Actions.SendReminders
r.get_todos_to_remind_rule = c.Reminders.Rules.GetTodosToRemind
r.reminder = c.Reminders.Models.Reminder
r.user_settings = c.Users.Models.UserSettings

    with goal().remind_the(r.user).of_their(r.overdue_todos):

        # The reminder job sends the reminders
        with the(r.scheduler).runs_the(r.send_reminders_action).every(r.morning):
            with it().visits_each(r.user).who_enabled_reminders_in_their(
                r.user_settings
            ):
                it().skips_the(r.user).if_there_is_a(r.reminder).of_today()
                it().calls(r.get_todos_to_remind_rule).to_find_the(r.overdue_todos)
                it().sends_a(r.reminder).that_lists_the(r.overdue_todos)
                it().stores_the(r.reminder)

        # The user acts on the reminder
        with the(r.user).reads_the(r.reminder):
            it().marks_a(r.todo).as_done().or_changes_its(r.due_date)

markdown_node = sunya.add_markdown_node(
    scenario, "A user is reminded of their overdue todos"
)

markdown_node.markdown = """
A user who forgets about a todo should not have to discover this by themselves.
Therefore, the todo app sends a reminder email to each user who has overdue todos.

### Steps

#### The reminder job sends the reminders

Every morning, the scheduler runs the reminder job. For each user who did not turn
off reminders in their settings, the job finds the overdue todos (in all todo lists
of the user), and sends one reminder that lists them. The reminder is stored, so that
a user gets at most one reminder per day, and is reminded of the same todo at most
three times.</br>

#### The user acts on the reminder

The user marks the todo as done, or gives it a new due date.

### Diagram

```mermaid
sequenceDiagram
participant Scheduler
participant SendReminders as SendReminders (action)
participant GetTodosToRemind as GetTodosToRemind (rule)
actor User

    Scheduler->>SendReminders: send_reminders()
    loop each user with reminders enabled
        SendReminders->>GetTodosToRemind: get_todos_to_remind(user)
        GetTodosToRemind-->>SendReminders: overdue todos
        SendReminders->>User: reminder email
    end
    User->>User: mark todo as done, or change due date

```
"""

The pseudo-code in run_scenario refers to the code units of the application (e.g. c.Reminders.Actions.SendReminders), so that the scenario also serves as a map of the code-base. But remember that you can create your own scenario format if you don't like mine.

Once the scenarios are generated, we can delete the design doc (which should be empty) and test plan.

Updating the code-base using fast-tracking

If the requirements change, then we repeat the entire process. We ask the AI to write and/or update workflow-tests, to update the scenarios, and finally to update the code so that all tests are green again. When an update is easy because it fits perfectly in the existing structure then you can ask the agent to fast-track the changes, which means that you review all the work (the design, the tests and the code) afterwards. This speeds up the process.