Step 6 Build: Small Slices with an Assistant Under a Mandate

Building is the step at which the assistant is most useful and most dangerous, because it is the step at which code appears faster than anyone can read it. This chapter teaches a working rhythm that keeps the builder in charge of the pace: ask for a plan before any code, take one small slice at a time, run the tests, read what changed, commit, write down what the assistant did, and know when to throw a conversation away and start again. It concerns Step 6 Build and the developer function D3 Build, producing software and directing the assistant that helps to produce it, within a mandate.

It builds on AI Developer, Chapter 7, which describes the craft of building with assistants and what the studies of them measured, on AI Developer, Chapter 8, which treats delegated coding under a mandate in a sandbox with a run record written by the host, and on AI Threat, Chapter 14, on the ironies of automation, in which a person asked to supervise a process they no longer perform is badly placed to catch its failures (86, Nordqvist, 2026); (78, Nordqvist, 2026). It assumes the three steps before it: the specification of Step 4 says what correct means, the design of Step 5 fixes the stack, the data and the access, and the workshop of Step 3 supplies the repository, the rules file AGENTS.md and the mandate MND-*-BLD-*.

The slice loop: plan, build, test, read, commit, with a stop path that discards the branch and restarts with a fresh conversation

Figure 10.1: The slice loop and its stop path.

The figure shows one turn of the loop. The builder asks for a plan without code and accepts it or sends it back. The assistant builds one slice on a branch. The tests run. The builder reads the diff, the set of changes the assistant made. A commit and a run record close the turn, and the next slice starts from a clean state. Two conditions send the work to the stop path instead: tests that fail twice in a row, and a diff the builder cannot explain. The stop path discards the branch and starts again with a fresh conversation, a decision made by the builder and by nothing inside the conversation.

What a developer does while building

A developer building a feature works in steps small enough to hold in the head. The code runs at the end of every step. When something breaks, the thing that broke is the thing that changed a few minutes ago, because only a few minutes of change exist. A developer commits often, which means saving a named snapshot of the repository with a message, so that history shows how the software came to be and any snapshot can be returned to. This is not a matter of taste. The DevOps Research and Assessment (DORA) programme's description of trunk-based development, a practice that the programme documents on its capability page, is built on small batches: changes merged into the main line at least daily, few active branches, branches that last no more than a few hours (132, Google Cloud, n.d.). The page is programme documentation, not a controlled study of builders, and a citizen build has no team to merge with. The part that carries over is the size of the unit: a change small enough that its author can say, in a sentence, what it was for and how to undo it.

The same developer reads. Reviewing a change, one's own or another's, is the default activity of professional work, and the reading is done against something, usually the task the change was meant to accomplish. The developer asks whether the change does what the task said, whether it does anything the task did not say, and whether a test would fail if it were wrong.

What vibe coding does instead

Vibe coding works in the opposite proportions. One conversation runs for hours. Each message asks for more, the assistant changes many files at once, and the builder tests by trying the application. When something breaks, the builder describes the symptom and the assistant changes more files. No snapshot is saved, because saving seemed unnecessary while it worked, so there is nothing to go back to when it stops. The conversation itself becomes the only record of why the code is the way it is, and the conversation will not be available to the colleague who inherits it.

The gap between the two ways of working is not skill at writing code. It is the unit of work. A developer's unit is small, tested, read and recorded. The vibe coder's unit is the whole application and its record is a transcript. The slice rhythm of this chapter replaces the second with the first and needs no knowledge of how to write code, only the discipline to stop between turns.

How AI helps and where it misleads

It is worth being exact about what has been measured, because both enthusiasm and dismissal in this field have outrun the evidence. The studies were of developers, not of builders who are not developers, and no controlled study of the latter is cited in this book.

In a controlled experiment on one task, writing an HTTP server in JavaScript, developers given GitHub Copilot finished 55.8 per cent faster than a control group (87, Peng et al., 2023). Three randomised field experiments at Microsoft, Accenture and a Fortune 100 company, covering 4,867 developers, reported a pooled 26.08 per cent increase in completed tasks, with results that varied across the experiments (88, Cui et al., 2024). A randomised controlled trial of 96 full-time Google software engineers on one enterprise-grade task found a best estimate of about a 21 per cent speedup, with a wide confidence interval (93, Paradis et al., 2024). A randomised trial of 16 experienced open-source developers on 246 tasks in mature projects they had worked on for about five years found that allowing early-2025 AI tools increased completion time by 19 per cent. The developers had expected a 24 per cent reduction beforehand and believed afterwards that they had achieved a 20 per cent reduction (36, Becker et al., 2025). In February 2026 the same group reported that a follow-up with 57 developers, 143 repositories and more than 800 tasks gave an unreliable signal, because developers declined to work without AI or withheld tasks, and said it was changing the design of the experiment (94, METR, 2026).

Taken together these results are observable and mixed. They differ in task, in the experience of the participants and in the codebase, and the direction differs with them: gains on a defined task in some studies, a loss for experienced developers in a familiar codebase in another. A survey-based study on a different question, the DORA programme's 2024 report, estimated associations between AI adoption and delivery of a 1.5 per cent reduction in throughput and a 7.2 per cent reduction in stability for each 25 per cent increase in adoption, from self-reported data; its 2025 report again found a negative relationship with delivery stability (126, Google Cloud, 2024); (28, Harvey & DeBellis, 2025). A study of what happens to the code afterwards ran in two phases with 151 participants, 95 per cent of them professional developers. Its randomised phase found no significant difference in how easily new developers could evolve code written with or without an assistant, and the authors did not detect systematic maintainability advantages or disadvantages (102, Borg et al., 2025). A study of 21 programmers who labelled their own sessions with a taxonomy of activities reported inefficiencies and time costs in the interaction (110, Mozannar et al., 2024).

The lesson for a builder is not that assistants are fast or slow. It is that the perception of speed is not evidence of speed, that experts and novices differ, that a measured gain in finishing a task says nothing about whether the result can be relied on, and that the gains reported were for people who could read what the assistant produced. The claim that the slice rhythm suits non-developers better than a long conversation is the book's own conclusion, drawn from the structure of the work and from the studies above, and it is not a measured result.

Where the assistant misleads in practice is easier to describe than to measure. It reports success it has not verified, so a message saying that all tests pass is a claim to be checked by running them. It changes more than was asked, because a request to fix one function is also a chance to tidy three others. It follows the pattern of the surrounding code even when the pattern is the bug. And it is fluent in the same way when it is right and when it is wrong, which is the property that makes reading its output hard. AI Threat, Chapter 14, calls the underlying difficulty an irony of automation: the more of the work is done by the system, the less practice the supervisor has at the thing being supervised.

The slice rhythm

A slice is the smallest change that can be tested and that does something a person can name. It is not a layer of the application, such as "the database part" or "the screen". It is a behaviour: "report a mismatch when portal and phone script disagree on a weekday's opening hours". A slice has a specification line it satisfies, a test that shows it satisfied, and a diff small enough to read in one sitting, which in practice means a handful of files and a few dozen lines at a time.

The rhythm has five beats, and the order matters.

  1. Plan. Ask the assistant for a plan with no code. The plan says which files will change, which tests will be added and what will not be touched. The builder accepts it, narrows it or sends it back.
  2. Build. The assistant implements the slice on a new branch, a separate line of the repository's history that leaves the main line untouched until the work is accepted. The test is written first or together with the code, from an example in the specification.
  3. Test. Run the whole test suite, not only the new test, and read the result yourself. A message from the assistant that the tests pass does not replace running them.
  4. Read. Read the diff, as the next section explains.
  5. Commit and record. Commit with a message in the convention below and write the run record. Then start the next slice from the state the commit left.

In commands, a turn looks like this. They are ordinary git commands and nothing in them is specific to the assistant.

git switch -c slice-1-opening-hours      # a new branch for this slice only
# ... the assistant works; then, as the builder:
python -m pytest -q                      # run every test yourself
git diff main --stat                     # which files changed, how much
git diff main                            # read the changes
git add src tests docs/runs
git commit -m "slice 1 - compare opening hours (R1)"
git switch main && git merge --ff-only slice-1-opening-hours

The commit message convention is one line, in the form slice N - what it does (rule). The rule in brackets points to the line in the specification that the slice satisfies, so that git log --oneline reads as a list of the specification being met, in order. A commit that cannot be described that way is either too large or not tied to anything the builder asked for.

The commit habit is the cheapest control in the chapter. It makes the stop path possible, since discarding a branch costs nothing when the main line is unchanged. It makes review possible, because a colleague can read slice by slice. And it protects against the failure most specific to assistants: a change that quietly undoes earlier work. If every slice is a commit, git diff between two commits shows exactly what changed.

Directing the assistant

The assistant does what its context says. The context is what it can see: the conversation so far, the files it has read, the rules file AGENTS.md and the instruction in the current message. Directing it means controlling that context.

Three controls matter for a builder. The first is the rules file. AGENTS.md, set up in Step 3, tells the assistant the project's conventions: the language and libraries to use, where tests live, the commands that run them, what it must never touch. The rules file is read at the start of each session, which makes it the most reliable place to put an instruction that must survive a restart. It belongs to the builder and is outside the assistant's mandate to change.

The second control is to ask for a plan first and to say no. A plan is cheap to correct and code is not. The builder is allowed, and expected, to reject a plan that touches files outside the slice, introduces a library not in the design, or does something the specification lists as a never-do. A request that works well is ordinary and specific:

Slice 1 of docs/specification.yaml: rule R1, opening hours for each weekday
are equal in the portal and in the phone script. Plan only, no code yet.
Say which files you will change, which tests you will add and what you will
not touch. Use only the standard library and PyYAML. Do not change
AGENTS.md, pipeline.yml or anything under tests/oracle/. Do not write to
any source system.

The third control is the size of the context. A conversation is a limited window, and a model uses what is in a long window unevenly: in the 2023 study that gave the problem its name, models tested were best at using information at the beginning or end of a long input and worse at information in the middle (95, Liu et al., 2023). The finding was about the models tested then, and models change, so no builder should rely on a particular number. A vendor's own engineering guidance reaches the practical conclusion that the context should be curated, not simply enlarged (56, Anthropic, 2025). That guidance is vendor guidance and not a controlled study. What both support is a habit that costs nothing: one slice per conversation, or at most a few, with the rules file and the specification as the standing context, instead of one long conversation that accumulates every earlier misunderstanding.

Cost belongs here too. A long conversation costs more per turn than a short one because the whole context is processed each time, and an assistant that runs tests and edits files in a loop consumes more than one that answers questions. The mandate may set limits, such as a number of tool calls, a maximum duration and a ceiling on spend per session, and a builder who has such limits should treat reaching them as information: the slice was too large or the conversation too long.

Reading what you cannot write

Reading a diff is possible without writing code, in the way that reading a contract is possible without being a lawyer: not every clause, but the things that matter. A diff shows lines removed in one colour and lines added in another, grouped by file. The builder reads it against the plan, with five questions.

  • Which files changed? Any file outside the plan is a reason to stop and ask. A change to AGENTS.md, pipeline.yml, anything under tests/oracle/ or the mandate itself is outside the mandate and is a stop in all cases.
  • How large is it? A slice that touched 25 files was not a slice.
  • What was removed? Deleted lines and deleted tests deserve more attention than added ones, since an assistant that cannot make a test pass sometimes weakens the test.
  • What does it reach? New network calls, new file writes, new libraries, new places where a path or a credential appears. A design that said the tool only reads should not acquire a write.
  • Is there something here that belongs to the domain? Rules, thresholds, wording and the meaning of a field are matters of the builder's own knowledge, and that knowledge is exactly what a builder who is not a developer brings.

Asking the assistant to explain the diff is useful and has a limit. An explanation is a second piece of generated text, and it is produced by the same system that produced the change. It is good for learning what a construct is, and for finding a part the builder has not understood. It is weak as evidence that the change is right, since it describes what the code is meant to do. The independent oracle of Chapter 11 exists for that reason. Reading catches what the reader knows to look for; the oracle catches the rest.

The limit has a worked case in this book. In the Hansa Mutual build, the assistant wrote the document-type rules in slice 1 and, for motor_glass, copied the motor_collision entry, so that glass-damage claims were asked for an accident report. Katarzyna read the diff of rules.yaml, a file of nine near-identical lines, and did not see it. The assistant's own tests agreed with the file, since it had written both. The error was found at Step 7 by an oracle case written by Marek Zieliński, who had not seen the assistant's work, and the account of it belongs to Chapter 11. The lesson drawn here is not that Katarzyna should have read harder. It is that reading is one control among several, and that a design which relied on it alone would have shipped the error.

Debugging with an assistant

Debugging with an assistant follows the order a developer uses: reproduce, isolate, fix, test. The builder's part is to keep that order against the assistant's tendency to propose a fix at once.

Reproduce means finding the smallest input that shows the failure and writing it down as a test that fails. A bug described as "the report looks wrong" cannot be fixed or verified. A bug described as a test that expects SP-07 to be reported on Tuesday and does not get it can be. Isolate means finding the smallest part of the code responsible, and the assistant is good at helping with this when asked to explain what a function does with that input, step by step. Fix means one change, in one place, that makes the failing test pass. Test means running the whole suite again, since a fix in one place breaks another often enough to be worth checking each time.

The loop to recognise is the one in which the assistant makes a change, the test still fails, the assistant makes another change on top, and the code grows while the failure stays. The rule used in this book is a count: after two failed attempts at the same failure, stop. Discard the branch, write down in two sentences what the failure is and what was already tried, and start a new conversation with the specification, the rules file, the failing test and those two sentences. A fresh conversation does not carry the accumulated wrong turns. The builder pays the cost of retyping a few lines and saves the cost of a conversation that has stopped being useful. The two-attempt threshold is the book's own and is a place to start; a team that finds its own number should record it in AGENTS.md.

Run records

The commit says what changed. It does not say how the change came about. The run record does. For each session in which the assistant changed the repository, the builder writes, or the platform generates, a short record: what was asked, what the assistant changed, what the tests showed, who read the diff and what was refused. AI Developer, Chapter 8, specified a RUN-* record written by the host and not by the agent, so that the agent cannot describe its own work as it likes. In a builder workspace the host may or may not provide that; where it does not, the builder writes it by hand and says so in the record.

The run record serves three readers. The builder next month, who will not remember why a change was made. The receiving developer, who reads the run records to see how the assistant was used and where the builder overruled it. And the auditor, if one asks, who needs evidence that the mandate was kept. The record for slice 1 of the Nordvik build follows.

id: RUN-NR-2031-0004
build: BLD-NR-2031-0001
slice: 1
mandate: MND-NR-BLD-2031-01
mode: 3
level: 2
date: 2031-10-22
task: Compare opening hours between portal and phone script (rule R1)
asked: Plan first, then tests, then code; touch only compare.py and its test.
files_changed: [src/spcheck/compare.py, tests/test_compare_hours.py]
tests: {passed: 4, failed: 0}
read_by: Hanna Wikström
diff_notes: Normalisation of 9:00 to 09:00 was added by the assistant after the second test; Hanna asked why and kept it.
refused: The assistant proposed writing corrections back to the portal; declined (never-do).
commit: slice 1 - compare opening hours (R1)

A short test in the repository keeps the records honest. It does not judge their content. It checks that each record has the fields a reader needs, that the tests were green when the slice was committed, and that no changed file lies inside the places the mandate forbids.

from datetime import date
from pathlib import Path

import yaml

RUNS = Path(__file__).resolve().parent.parent / "docs" / "runs"
REQUIRED = {"id", "build", "slice", "mandate", "mode", "level", "date", "task", "asked",
            "files_changed", "tests", "read_by", "commit"}
FORBIDDEN = ("tests/oracle", "AGENTS.md", "pipeline.yml")


def test_every_run_record_is_complete_and_within_the_mandate():
    records = sorted(RUNS.glob("RUN-*.yaml"))
    assert records, "no run records yet"
    for path in records:
        record = yaml.safe_load(path.read_text(encoding="utf-8"))
        assert REQUIRED <= record.keys(), f"{path.name} lacks {REQUIRED - record.keys()}"
        assert isinstance(record["date"], date)
        assert record["tests"]["failed"] == 0, f"{path.name}: commit only on green tests"
        for changed in record["files_changed"]:
            assert not any(changed.startswith(f) for f in FORBIDDEN), f"outside mandate: {changed}"

Proportion by tier

The rhythm is the same at every tier. What changes is how much of it is written down and who checks it. Tier D is not a citizen build, and a builder who finds that the tool would rank or decide about a named person, feed a high-risk AI system, sit in a security-critical path or act irreversibly on production data stops and calls a developer.

Tier Slices and commits Run records Who reads the diff
A personal Commit when it works; slices as convenient Optional; a line in the commit message is enough The builder
B team One slice per branch, tests with each slice One per session, kept in the repository The builder; a colleague samples
C business One slice per branch, tests written from the specification, the oracle from Step 7 in place One per session, complete, checked by the test above The builder, and a developer on every slice that touches data, access or the pipeline
D project Not a citizen build Not applicable A developer team owns it

Across the degrees of delegation

At this step the assistant does real work, and the degree of delegation is where it is easiest to go wrong. The builder's assistant normally operates at Mode 2 in the editor and Mode 3 for a delegated task inside the sandbox, and does not run as an autonomous production agent, since Mode 5 is not for builders.

Action Degree of delegation Mode Control
Propose a plan Level 0 Advisory Mode 1 Builder accepts, narrows or rejects
Write code and tests for one slice on a branch Level 2 Supervised Mode 2 or 3 Builder runs the tests and reads the diff before merge
Run the test suite and linters in the sandbox Level 3 Bounded Mode 3 Within the mandate; result written to the run record
Explain a diff or an error message Level 1 Assisted Mode 1 or 2 Not evidence that the change is right
Merge to the main line Level 0 Advisory none Builder merges, never the assistant
Read secrets, production data or production configuration Not permitted none The mandate closes the route
Change AGENTS.md, pipeline.yml, tests/oracle/ or the mandate Not permitted none Outside the mandate in every case
Push to the main line or trigger the pipeline Not permitted none The pipeline identity ships, not the assistant

Level 4 Autonomous is never used for a change to production without a gate that the change itself cannot alter, for security-critical code without a named developer's review, for a change to the assistant's own mandate, permissions, credentials, test oracles or pipeline gates, for an irreversible action on production data, or for a decision about a named person's employment, pay, performance rating or access to work. Several rows above go further than the prohibition and use no autonomy at all, since in a builder workspace the assistant has no reason to hold those rights. The stewardship principle applies to every slice: the builder names who owns the change, understands it well enough to explain what it does and can revert it, which the branch and the commit make possible.

Practical guide: One slice end to end

Purpose. To take one behaviour from the specification to a committed, tested, read and recorded change, in a way a colleague could repeat.

Roles. Builder; the assistant under the builder mandate; deputy (reads one run record per week); receiving developer (reads the log and the run records before the takeover test).

Inputs. The specification record SPC-* with the rule for the slice, the design record from Step 5, AGENTS.md, the mandate, synthetic data in data/synthetic/.

Steps.

  1. Pick one rule or behaviour from the specification. Write its name in the branch name.
  2. Start a fresh conversation. Give the assistant the specification, AGENTS.md and the slice. Ask for a plan, as in the request above. Accept, narrow or reject it.
  3. Ask for the test first, from an example in the specification, and run it to see it fail. A test that has never failed has not shown that it can.
  4. Ask for the code that makes it pass. Run the whole suite yourself.
  5. Read the diff with the five questions. Ask about anything outside the plan. Discard the branch if tests failed twice or you cannot explain the diff.
  6. Commit with the convention. Merge to the main line with a fast-forward only.
  7. Write the run record, naming what the assistant proposed and you refused.
  8. Run the record check. Stop; do not start the next slice in the same conversation.

The slice that the Nordvik build produced for rule R1 is src/spcheck/compare.py. It is short enough to read whole.

import re
from dataclasses import dataclass

WEEKDAYS = ("mon", "tue", "wed", "thu", "fri")


@dataclass(frozen=True)
class Mismatch:
    kind: str
    service_point: str
    field: str
    values: dict


def _normalise(hours: str) -> str:
    """Make '9:00 - 16:00' and '09:00–16:00' compare equal; keep 'closed' as 'closed'."""
    text = hours.strip().lower().replace("–", "-").replace(" ", "")
    if text in ("", "closed", "stängt"):
        return "closed"
    return re.sub(r"\b(\d):", r"0\1:", text)


def compare_hours(portal: dict, phone: dict) -> list[Mismatch]:
    found = []
    for sp in sorted(portal.keys() & phone.keys()):
        for day in WEEKDAYS:
            in_portal = portal[sp]["hours"].get(day, "")
            in_phone = phone[sp].get(day, "")
            if _normalise(in_portal) != _normalise(in_phone):
                found.append(Mismatch("hours", sp, day, {"portal": in_portal, "phone": in_phone}))
    return found

Its tests are written from the specification's examples and name the behaviour, not the function. The last of them records a decision: a service point that is missing from one source is not an opening-hours mismatch, because rule R3 handles it, and the slice must not do R3's work.

from spcheck.compare import Mismatch, compare_hours

PORTAL = {"SP-07": {"hours": {"mon": "09:00-16:00", "tue": "09:00-16:00"}}}


def test_equal_hours_give_no_mismatch():
    phone = {"SP-07": {"mon": "09:00-16:00", "tue": "09:00-16:00"}}
    assert compare_hours(PORTAL, phone) == []


def test_different_hours_are_reported_with_both_values():
    phone = {"SP-07": {"mon": "09:00-16:00", "tue": "10:00-16:00"}}
    assert compare_hours(PORTAL, phone) == [
        Mismatch("hours", "SP-07", "tue", {"portal": "09:00-16:00", "phone": "10:00-16:00"})
    ]


def test_formatting_differences_are_not_mismatches():
    phone = {"SP-07": {"mon": "9:00 – 16:00", "tue": "09:00-16:00"}}
    assert compare_hours(PORTAL, phone) == []


def test_a_service_point_missing_from_one_source_is_left_to_rule_r3():
    assert compare_hours(PORTAL, {}) == []

Exit gate. Step 6 Build is finished for a slice when the slice is on the main line as one commit with a message that names its rule, the whole suite passes when the builder runs it, the builder has read the diff and can say in a sentence what each changed file is for, and the run record exists and passes the check. The step is finished for the build when every rule of the specification that is in the release has such a commit. A slice for which the builder cannot answer "what is this file for?" has not met the gate.

Artefact. The commits on the main line, the run records RUN-* in docs/runs/, the updated tests and the build record BLD-*, which lists the slices.

Evidence age. A run record is evidence that a slice was built and read on a date. It does not say the code still works. The test suite is re-run on every change, and the rule from Chapter 11 on how long evidence about a running tool is valid, 90 days in this book's illustration, applies from the last green run.

When to call a developer

Slicing is within a builder's reach. A builder calls a developer when the assistant proposes something the builder cannot judge: a new library or service, a change to how the tool authenticates, a change that touches the pipeline or the secrets, anything the assistant says it needs permission to do beyond the mandate. A builder also calls when two attempts at a failure have gone nowhere and the cause is not in the builder's own domain, when a diff is too large to read and cannot be made smaller, when the tool starts to do more than the specification says, and when the assistant's explanation of a diff is the only reason the builder believes it. In each case the question for the developer is specific and short, and the run record is what the developer reads first.

Nordvik Region and Hansa Mutual

Nordvik Region. Hanna Wikström built service-point-check in three slices on the Region's builder workspace, under the mandate MND-NR-BLD-2031-01, which was adopted on 2031-10-13 (AIDR-1201). Slice 1 compared opening hours between the portal export and the phone-service script (rule R1) and was committed on 2031-10-22 with the run record RUN-NR-2031-0004. Slice 2 was the notice check, rule R2, which tests whether a notice whose dates cover today appears in both the portal and the phone script. Slice 3 was the weekly report in Markdown. The assistant ran at Mode 2 in the editor and Mode 3 for delegated tasks in a sandbox that cannot read production configuration. At the first release, version 0.1.0 on 2031-11-12, the repository held 14 tests, about 600 lines of Python including tests, and a run record per session. In slice 1 the assistant proposed writing corrections back to the portal. Hanna refused and recorded the refusal, since the specification lists it as a never-do.

Hansa Mutual. Katarzyna Nowak built claims-doc-check in three slices in the builder lane that Group Application Development provides inside the claims analytics workspace, under MND-HM-BLD-2031-01, adopted on 2031-10-27 (AIDR-1252). Slice 1 was the document-type rules in rules.yaml, slice 2 the list of missing documents per claim, and slice 3 the draft request text in Polish, German and English from templates. It was in slice 1 that the assistant copied the collision rule for glass claims, as described above, and in slice 3 that Katarzyna's own knowledge did the most work: she rewrote the wording of two request texts because they would have read to a claimant as an accusation. Release 0.1.0 followed on 2031-11-17 to the pilot team with 18 tests and about 450 lines. The builder and the assistant never read production exports; the pipeline's identity does.

Summary

Step 6 Build puts the builder in charge of the pace of work with an assistant. It concerns Step 6 Build and the developer function D3 Build. The method is a rhythm, plan, build, test, read, commit and record, applied to slices small enough to hold in the head, with a stop path that discards the branch and starts again when tests fail twice or a diff cannot be explained. The assistant plans, drafts, writes and explains. The builder accepts, reads, merges and records. Reading a diff is within reach of someone who does not write code, if it is done against five questions and with the knowledge of one's own domain, and it is one control among several, not the only one.

The controlled evidence on assistants, from Peng, Cui, Paradis and Becker, and the survey evidence of the DORA programme, is mixed, and it concerns developers, not builders. The book's own conclusion, labelled as such, is that the slice rhythm is a better fit for a builder than the long conversation, because it keeps the unit of work inside what a person can check. How much is written down depends on the tier. Level 4 Autonomous is never used for a change to production without an unalterable gate, for security-critical code without a named developer's review, for a change to the assistant's own mandate, permissions, credentials, test oracles or pipeline gates, for an irreversible action on production data, or for a decision about a named person's employment, pay, performance rating or access to work, and a builder workspace uses no autonomy at all for the merge and the pipeline. The gate for each slice is a commit, a green suite, a diff the builder can explain and a run record. Chapter 11 turns to Step 7 Prove, and to the independent oracle that finds what reading does not.

Observable, expected, speculation. It is observable that controlled studies of coding assistants, on developers, give results that differ in direction and size with the task, the experience of the people and the codebase, and that a follow-up by METR in 2026 could not measure the effect cleanly. It is expected that the length of tasks an assistant completes without help will keep growing, since the METR time-horizon study reported a doubling time of about seven months for frontier models, a trend its authors present as conditional on generalising to real work (41, Kwa et al., 2025); how far that extends to a builder's small tools has not been measured. That small slices will remain the right unit as assistants grow more capable is speculation. That the slice rhythm is better for non-developers is the book's own conclusion, not a measured result.

Sources

  1. Peng, S., Kalliamvakou, E., Cihon, P. & Demirer, M. (2023). The Impact of AI on Developer Productivity: Evidence from GitHub Copilot. arXiv:2302.06590. (87, Peng et al., 2023)
  2. Cui, Z. (K.), Demirer, M., Jaffe, S., Musolff, L., Peng, S. & Salz, T. (2024). The Effects of Generative AI on High-Skilled Work: Evidence from Three Field Experiments with Software Developers. SSRN 4945566. (88, Cui et al., 2024)
  3. Paradis, E. et al. (2024). How much does AI impact development speed? An enterprise-based randomized controlled trial. arXiv:2410.12944. (93, Paradis et al., 2024)
  4. Becker, J., Rush, N., Barnes, E. & Rein, D. (2025). Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity. arXiv:2507.09089. (36, Becker et al., 2025)
  5. METR (Becker, J., Rush, N., Cunningham, T., Rein, D. & Mahamud, K.) (2026). We are Changing our Developer Productivity Experiment Design. METR blog, 24 February 2026. (94, METR, 2026)
  6. Google Cloud, DORA (2024). Accelerate State of DevOps Report 2024. (126, Google Cloud, 2024)
  7. Harvey, N. & DeBellis, D. (2025). Announcing the 2025 DORA Report: State of AI-Assisted Software Development. Google Cloud Blog. (28, Harvey & DeBellis, 2025)
  8. Borg, M. et al. (2025). Echoes of AI: Investigating the Downstream Effects of AI Assistants on Software Maintainability. arXiv:2507.00788. (102, Borg et al., 2025)
  9. Mozannar, H., Bansal, G., Fourney, A. & Horvitz, E. (2024). Reading Between the Lines: Modeling User Behavior and Costs in AI-Assisted Programming. CHI 2024. (110, Mozannar et al., 2024)
  10. Google Cloud, DORA. Trunk-based development. DORA capability page. (132, Google Cloud, n.d.)
  11. Liu, N. F. et al. (2023). Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172. (95, Liu et al., 2023)
  12. Anthropic (2025). Effective context engineering for AI agents. Anthropic Engineering, 29 September 2025. (56, Anthropic, 2025)
  13. Kwa, T. et al. (2025). Measuring AI Ability to Complete Long Tasks. METR; arXiv:2503.14499. (41, Kwa et al., 2025)
  14. Nordqvist, G. (2026). AI Threat: Are the Dystopias Coming True? Evidence, Risk and Response for European Enterprises and Public Authorities. The Transformed Architecture, Book 5. (78, Nordqvist, 2026)
  15. Nordqvist, G. (2026). AI Developer: How the Developer Role Changes When AI Is Used Broadly in European Enterprises and Public Authorities. The Transformed Architecture, Book 12. (86, Nordqvist, 2026)