<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Engineering Practice on James Sawle</title><link>https://jamessawle.dev/categories/engineering-practice/</link><description>Recent content in Engineering Practice on James Sawle</description><generator>Hugo</generator><language>en-GB</language><atom:link href="https://jamessawle.dev/categories/engineering-practice/index.xml" rel="self" type="application/rss+xml"/><item><title>The agent writes the code. The team still pairs</title><link>https://jamessawle.dev/writing/the-agent-writes-the-code-the-team-still-pairs/</link><guid isPermaLink="true">https://jamessawle.dev/writing/the-agent-writes-the-code-the-team-still-pairs/</guid><pubDate>Thu, 27 Aug 2026 00:00:00 +0000</pubDate><description>&lt;p&gt;Pair programming appears to have a terminal problem with coding agents: a
programmer need not be present while the code is written.&lt;/p&gt;
&lt;p&gt;A person can describe a change, send an agent into the repository and return
later to a completed branch or pull request. The delegator may be a developer,
but they are not sharing the implementation—and while the agent works, there is
no pair at all. GitHub documents this background-delegation model directly,
contrasting it with a synchronous session between a developer and an
assistant.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; Early evidence from 25,264 agentic pull requests
finds the corresponding social pattern across open-source projects:
single-human oversight dominated and multi-human collaboration was
uncommon.&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;If producing code was the reason to pair, the practice has become obsolete.
Before defending it, we need to ask what disappears when the entire human pair
leaves.&lt;/p&gt;
&lt;h2 id="what-disappears-with-the-pair"&gt;What disappears with the pair?&lt;/h2&gt;
&lt;p&gt;XP does not oblige us to preserve pairing&amp;rsquo;s old mechanics. Beck&amp;rsquo;s
values–principles–practices framework instead asks what the practice made
concrete, and whether those needs still have an adequate expression under new
constraints.&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Four parts are especially relevant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Communication and feedback&lt;/strong&gt; ask that knowledge move between people and meet
evidence while it can still change the work. Pairing made that exchange
continuous; solitary delegation may defer the next human response until the
agent asks for clarification or returns an implementation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Diversity&lt;/strong&gt; recognises that teams need differences in perspective, skill and
experience, even though those differences also create conflict.&lt;sup id="fnref1:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;
Pairing applied two perspectives as the premise and design formed. With one
delegator, the same human perspective frames the request and judges the result.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Reflection&lt;/strong&gt; asks teams to examine how and why they work. Pairing externalised
that reasoning: assumptions had to be explained and could be challenged
immediately. Solitary agent work can leave the framing and judgement inside one
person&amp;rsquo;s private reasoning.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mutual benefit&lt;/strong&gt; favours work that helps now without borrowing against the
team&amp;rsquo;s future. Implementation pairing could advance a change and distribute
knowledge; industrial research has observed teacher and student roles when
partners hold different knowledge.&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt; An agent may complete
the task without increasing the team&amp;rsquo;s shared ability to understand the next
one.&lt;/p&gt;
&lt;p&gt;These values and principles do not, by themselves, require pairing to survive.
A team might express them through some combination of discovery workshops,
asynchronous challenge, shared decision records, review, rotation and deliberate
learning practices. They give us criteria for judging whatever comes next.&lt;/p&gt;
&lt;p&gt;The question is whether a modified form of pairing can supply these qualities
together, or whether they are better distributed across several new practices.&lt;/p&gt;
&lt;h2 id="pair-in-discovery"&gt;Pair in discovery&lt;/h2&gt;
&lt;p&gt;The task breakdown appears ready when the agent challenges one word in the
working decision record: &lt;em&gt;replacement&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Replacement is underspecified. If an administrator selects Resend twice,
which link remains usable?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A product manager and engineer have been exploring a constructed change: let an
administrator resend an expired invitation without recreating the recipient&amp;rsquo;s
access. They have agreed to issue a replacement with the same access while
keeping the expired link invalid. The agent has investigated the system,
recorded their decisions and proposed reusing its existing path for issuing an
invitation.&lt;/p&gt;
&lt;p&gt;The agent&amp;rsquo;s challenge exposes a behaviour they have not decided. The product
manager says that only the latest invitation should be usable: if both links
work, &lt;em&gt;resend&lt;/em&gt; has multiplied access rather than replaced it. The agent checks
the token model and confirms that its proposed task would leave both replacement
links valid. The engineer revises the design from &lt;em&gt;issue another invitation&lt;/em&gt; to
&lt;em&gt;rotate the invitation&lt;/em&gt;. The agent updates the behavioural example, design
constraint and affected tasks—all before implementation begins.&lt;/p&gt;
&lt;p&gt;This is what I mean by discovery pairing. Two people continuously navigate one
change, challenge each other&amp;rsquo;s reasoning and share authority over its decisions.
The agent investigates, answers questions and keeps a working decision record
coherent while the people judge and revise it.&lt;/p&gt;
&lt;p&gt;The agent is not a passive scribe. It tests whether an answer has enough depth
to carry into the next decision, challenges vague or unsupported responses and
keeps the question open until the people address it. It does not own the
decision. The pair can explicitly choose a direction the agent questions, but
they must make that choice rather than hide it inside an ambiguous word.&lt;/p&gt;
&lt;p&gt;It is not pair programming if the term is defined exclusively as two
programmers producing code at one computer; those mechanics have ended. I retain
&lt;em&gt;pairing&lt;/em&gt; because shared attention, immediate mutual challenge and joint
navigation survive. The agent becomes the driver of the record, not the second
human perspective.&lt;/p&gt;
&lt;p&gt;BDD discovery workshops provide established prior art. Cucumber&amp;rsquo;s guidance
brings product, development and testing perspectives together shortly before
implementation, keeps the conversation brief, and uses examples to expose
rules, questions and smaller slices.&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt; The proposal here
borrows that attention to examples and pairing&amp;rsquo;s continuous co-navigation. A
repository-aware agent connects the conversation to the current system and
propagates each accepted decision through the record; it does not make the
decision.&lt;/p&gt;
&lt;p&gt;The process supplies the earlier criteria together. Communication and feedback
happen while decisions remain revisable. Product defines what &lt;em&gt;replacement&lt;/em&gt;
promises; engineering exposes its consequence for system state. Their exchange
forces reflection on an unstated assumption, and the agent tests it against the
repository. Both people leave with a better model of the product and system.&lt;/p&gt;
&lt;p&gt;Some teams may keep the record in a work item, divide it among examples and
design notes, or preserve accepted behaviour in a durable specification. I use
OpenSpec because its proposal, behavioural delta, design and task artefacts make
the decisions inspectable, and its workflow allows implementation discoveries
to reopen them.&lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt; The process depends on connected, revisable
decisions rather than that particular structure.&lt;/p&gt;
&lt;h2 id="who-should-be-present"&gt;Who should be present?&lt;/h2&gt;
&lt;p&gt;Choose the participants before the session by predicting which perspectives the
slice is likely to need. That prediction is a starting point, not a fixed
attendance list.&lt;/p&gt;
&lt;p&gt;Two engineers bring different system knowledge, design instincts and
implementation experience. A product-and-engineering pair connects intended
behaviour with technical consequences. A designer contributes interaction,
accessibility and journey-level judgement; a tester contributes examples,
boundaries and failure modes. Either may pair with product or engineering when
those concerns dominate the uncertainty.&lt;/p&gt;
&lt;p&gt;The conversation will sometimes prove the prediction wrong. A person or the
agent may expose a question the group cannot answer with enough depth. Pause and
bring in the missing perspective rather than handing the question off. Keep that
person while their knowledge is likely to matter again; let them leave when it
no longer justifies their attention. The aim is not constant reshuffling but a
pragmatic correction as the change reveals what it needs.&lt;/p&gt;
&lt;p&gt;Sometimes those likely needs justify gathering the whole squad from the outset.
At other times an ongoing pair widens because the slice crosses several kinds of
judgement, omitting one would be expensive to unwind, and calling people in only
after the session would lose the context in which the issue formed.&lt;/p&gt;
&lt;p&gt;That wider form is a mob. Woody Zuill&amp;rsquo;s foundational experience report described
the whole team working on the same thing, at the same time, through one
computer.&lt;sup id="fnref:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt; In the agentic version, the agent reads the system,
drafts, asks, answers, revises and challenges responses that lack sufficient
depth. The squad navigates and retains authority: the agent proposes that a
decision or task breakdown is ready; the mob decides whether to agree.&lt;/p&gt;
&lt;p&gt;The literature does not establish that larger groups generally make better
decisions. A study of mob-programming practice found substantial variation,
stressed its social and organisational conditions, and noted that much of the
field&amp;rsquo;s literature consisted of experience reports.&lt;sup id="fnref:8"&gt;&lt;a href="#fn:8" class="footnote-ref" role="doc-noteref"&gt;8&lt;/a&gt;&lt;/sup&gt;
The case for mobbing is narrower: use the squad when the likely cost of a missed
perspective exceeds the cost of concentrating its attention. A mob cannot
guarantee that the relevant knowledge is present—it may sit outside the
squad—but it can reduce the need to predict which of the squad&amp;rsquo;s perspectives
will matter.&lt;/p&gt;
&lt;p&gt;This is a proposed operating rule, not an outcome established by the studies.
It should be tested against the total attention, rework and learning it creates
in a team&amp;rsquo;s own context.&lt;/p&gt;
&lt;p&gt;&lt;img class="article-figure" src="mob-boundary.svg" alt="A discovery pair and agent revise a shared decision record, widening into a mob when the discussion exposes a missing perspective. A clear handoff sends the agent into implementation alone, with discoveries reopening the decisions they invalidate." loading="lazy" decoding="async" title="Predict the discovery participants, correct the group as questions emerge, then end the collaboration before implementation."&gt;
&lt;/p&gt;
&lt;h2 id="end-the-collaboration-before-implementation"&gt;End the collaboration before implementation&lt;/h2&gt;
&lt;p&gt;Human attention remains expensive even when agent implementation is cheap.
Pair-programming research found trade-offs among quality, duration and effort
rather than a universal advantage,&lt;sup id="fnref:9"&gt;&lt;a href="#fn:9" class="footnote-ref" role="doc-noteref"&gt;9&lt;/a&gt;&lt;/sup&gt; with controlled
evidence showing effects that vary by system complexity and developer
experience.&lt;sup id="fnref:10"&gt;&lt;a href="#fn:10" class="footnote-ref" role="doc-noteref"&gt;10&lt;/a&gt;&lt;/sup&gt; A mob raises the cost further.&lt;/p&gt;
&lt;p&gt;Use one person and an agent for local, reversible and well-understood changes.
Use a pair when a second perspective earns its cost. Begin as a mob when the
likely decisions justify the squad&amp;rsquo;s attention, or widen into one when the
discussion exposes missing knowledge whose potential cost justifies it. Correct
the group in either direction as the work becomes better understood.&lt;/p&gt;
&lt;p&gt;Once the people agree on the decisions and implementation breakdown, they
leave. The agent writes the code alone. If implementation reveals that the
system cannot preserve an agreed constraint, it reopens the decision that no
longer holds and calls back the people whose judgement is needed.&lt;/p&gt;
&lt;p&gt;This is not upfront design followed by a one-way implementation phase. The task
breakdown in the invitation example changes the agreed behaviour and design
before code exists; implementation evidence can revise them again. The work
stays inside one thin vertical slice, no record section is mandatory, and the
participants leave as soon as shared judgement is no longer needed.&lt;/p&gt;
&lt;p&gt;The economic test is substitution. Teams already spend attention in refinement,
planning, discovery workshops, clarifications, handoffs and late design
discussions. Discovery pairing or mobbing must replace enough of that fragmented
work to justify its cost. If the existing interactions remain unchanged, the
session is another ceremony and should be removed.&lt;/p&gt;
&lt;p&gt;Across matched event studies, Demirer, Musolff and Yang estimated a much larger
increase in code written than in releases after teams adopted AI coding
tools.&lt;sup id="fnref:11"&gt;&lt;a href="#fn:11" class="footnote-ref" role="doc-noteref"&gt;11&lt;/a&gt;&lt;/sup&gt; The measures are not directly comparable and do
not isolate pairing, but they make the mechanism worth testing: one disagreement
about what &lt;em&gt;resend&lt;/em&gt; means can prevent an entire attempt at the wrong change.&lt;/p&gt;
&lt;h2 id="do-not-move-pairing-to-review"&gt;Do not move pairing to review&lt;/h2&gt;
&lt;p&gt;A pull request is a useful integration boundary, not a substitute for pairing.
Tests, contracts, static analysis and architectural rules should challenge an
implementation without waiting for another engineer. Human review has a
narrower purpose: use it when unresolved judgement remains or when someone
deliberately needs to learn the implementation.&lt;/p&gt;
&lt;p&gt;Research into modern code review identifies knowledge transfer, team awareness
and alternative solutions among its expected outcomes, and finds that
understanding a change&amp;rsquo;s reason and context is central to reviewing it
effectively.&lt;sup id="fnref:12"&gt;&lt;a href="#fn:12" class="footnote-ref" role="doc-noteref"&gt;12&lt;/a&gt;&lt;/sup&gt; Fowler also distinguishes pull requests from the
continuous review pairing can provide.&lt;sup id="fnref:13"&gt;&lt;a href="#fn:13" class="footnote-ref" role="doc-noteref"&gt;13&lt;/a&gt;&lt;/sup&gt; Those benefits can
justify selective human review, but they do not make it a new pairing surface.&lt;/p&gt;
&lt;p&gt;A reviewer encountering the second-resend ambiguity must reconstruct why the
change exists, reopen what &lt;em&gt;replacement&lt;/em&gt; means and discard code built from the
earlier answer. Discovery pairing encounters it while the decision is still
forming. Pair there, automate routine verification of the implementation, and
involve a human reviewer when the remaining judgement or learning warrants the
cost.&lt;/p&gt;
&lt;h2 id="what-discovery-pairing-still-loses"&gt;What discovery pairing still loses&lt;/h2&gt;
&lt;p&gt;Discovery pairing does not preserve every benefit of implementation pairing.
Agreeing intent and design does not teach another engineer how the generated
code works, ensure several people can debug it later, or recreate the teacher
and student roles observed in industrial pairs.&lt;sup id="fnref1:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Human review may sometimes earn its cost as an implementation-learning practice,
but it cannot be assumed as the answer. Teams may need rotation, deliberate code
exploration, teaching sessions or another practice not yet established. AI
review, linting and tests do not automatically express everything they value
about architecture, operability or maintainability either.&lt;/p&gt;
&lt;p&gt;A team could distribute the original criteria across several practices: a
workshop for diversity, a decision record for communication, asynchronous
challenge for reflection, automated and human review for feedback, and rotation
for learning. That is credible, but it introduces handoffs between the people,
context and moments at which a decision can change.&lt;/p&gt;
&lt;p&gt;Discovery pairing combines communication, feedback, diversity and reflection
while the decision is forming; the record preserves the result instead of
replacing the conversation. That integrated timing is why I would maintain
pairing in a changed form. Mobbing extends it when the relevant perspectives are
known to be broad or prove broader than expected. A deliberate ending keeps its
cost bounded.&lt;/p&gt;
&lt;p&gt;Pairing can survive agent implementation, but not as two people sharing the
production of code. Move it into discovery when a second perspective earns its
cost, choose the people for the expected uncertainty, correct that group as the
change reveals missing knowledge, and end the session when the agent has an
agreed implementation breakdown.&lt;/p&gt;
&lt;p&gt;The agent implements the bounded slice alone. The team has already paired while
its meaning was cheap to change.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;GitHub, &amp;ldquo;About GitHub Copilot coding agent,&amp;rdquo; checked at commit
&lt;code&gt;0dddeeb8cce75425f9ca0cdffd6a1cbd94926c07&lt;/code&gt;.
&lt;a href="https://github.com/github/docs/blob/0dddeeb8cce75425f9ca0cdffd6a1cbd94926c07/content/copilot/concepts/agents/cloud-agent/about-cloud-agent.md"&gt;https://github.com/github/docs/blob/0dddeeb8cce75425f9ca0cdffd6a1cbd94926c07/content/copilot/concepts/agents/cloud-agent/about-cloud-agent.md&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Maliha Noushin Raida and Daqing Hou, &amp;ldquo;Early Adoption of Agentic Coding
Tools by GitHub Projects,&amp;rdquo; arXiv:2607.14037v2, 2026.
&lt;a href="https://arxiv.org/abs/2607.14037v2"&gt;https://arxiv.org/abs/2607.14037v2&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Kent Beck with Cynthia Andres, &lt;em&gt;Extreme Programming Explained: Embrace
Change&lt;/em&gt;, second edition, Addison-Wesley Professional, 2004, chapters 3–5.
&lt;a href="https://www.pearson.com/en-us/subject-catalog/p/extreme-programming-explained-embrace-change/P200000000118/9780321278654"&gt;https://www.pearson.com/en-us/subject-catalog/p/extreme-programming-explained-embrace-change/P200000000118/9780321278654&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Linus Ververs, Trang Linh Lam and Lutz Prechelt, &amp;ldquo;Qualitative Analysis of
the Teacher and Student Roles in Pair Programming,&amp;rdquo; arXiv:2507.10305v2, 2025. &lt;a href="https://arxiv.org/abs/2507.10305v2"&gt;https://arxiv.org/abs/2507.10305v2&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Cucumber, &amp;ldquo;Discovery workshop,&amp;rdquo; &amp;ldquo;Example Mapping&amp;rdquo; and &amp;ldquo;Who does what?,&amp;rdquo;
checked at commit &lt;code&gt;48680f20869cf5409f5372293fdd1f50d771ed26&lt;/code&gt;.
&lt;a href="https://github.com/cucumber/website/blob/48680f20869cf5409f5372293fdd1f50d771ed26/docs/bdd/discovery-workshop.md"&gt;https://github.com/cucumber/website/blob/48680f20869cf5409f5372293fdd1f50d771ed26/docs/bdd/discovery-workshop.md&lt;/a&gt;,
&lt;a href="https://github.com/cucumber/website/blob/48680f20869cf5409f5372293fdd1f50d771ed26/docs/bdd/example-mapping.md"&gt;https://github.com/cucumber/website/blob/48680f20869cf5409f5372293fdd1f50d771ed26/docs/bdd/example-mapping.md&lt;/a&gt;
and
&lt;a href="https://github.com/cucumber/website/blob/48680f20869cf5409f5372293fdd1f50d771ed26/docs/bdd/who-does-what.md"&gt;https://github.com/cucumber/website/blob/48680f20869cf5409f5372293fdd1f50d771ed26/docs/bdd/who-does-what.md&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;Fission-AI, OpenSpec, &lt;code&gt;docs/workflows.md&lt;/code&gt; and &lt;code&gt;docs/concepts.md&lt;/code&gt;, checked at
commit &lt;code&gt;6926ccb18afa4ff621112813e9968334576ee11a&lt;/code&gt;.
&lt;a href="https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/docs/workflows.md"&gt;https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/docs/workflows.md&lt;/a&gt;
and
&lt;a href="https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/docs/concepts.md"&gt;https://github.com/Fission-AI/OpenSpec/blob/6926ccb18afa4ff621112813e9968334576ee11a/docs/concepts.md&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;Woody Zuill, &amp;ldquo;Mob Programming — A Whole Team Approach,&amp;rdquo; Agile Alliance
Experience Report, 2014.
&lt;a href="https://www.agilealliance.org/resources/experience-reports/mob-programming-agile2014/"&gt;https://www.agilealliance.org/resources/experience-reports/mob-programming-agile2014/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:7" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;Daniel Ståhl and Torvald Mårtensson, &amp;ldquo;Mob programming: From avant-garde
experimentation to established practice,&amp;rdquo; &lt;em&gt;Journal of Systems and
Software&lt;/em&gt; 180, 2021. &lt;a href="https://doi.org/10.1016/j.jss.2021.111017"&gt;https://doi.org/10.1016/j.jss.2021.111017&lt;/a&gt;&amp;#160;&lt;a href="#fnref:8" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;Jo E. Hannay, Tore Dybå, Erik Arisholm and Dag I. K. Sjøberg, &amp;ldquo;The
effectiveness of pair programming: A meta-analysis,&amp;rdquo; &lt;em&gt;Information and
Software Technology&lt;/em&gt; 51(7), 2009.
&lt;a href="https://doi.org/10.1016/j.infsof.2009.02.001"&gt;https://doi.org/10.1016/j.infsof.2009.02.001&lt;/a&gt;&amp;#160;&lt;a href="#fnref:9" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:10"&gt;
&lt;p&gt;Erik Arisholm, Hans Gallis, Tore Dybå and Dag I. K. Sjøberg, &amp;ldquo;Evaluating
pair programming with respect to system complexity and programmer
expertise,&amp;rdquo; &lt;em&gt;IEEE Transactions on Software Engineering&lt;/em&gt; 33(2), 2007.
&lt;a href="https://doi.org/10.1109/TSE.2007.17"&gt;https://doi.org/10.1109/TSE.2007.17&lt;/a&gt;&amp;#160;&lt;a href="#fnref:10" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:11"&gt;
&lt;p&gt;Mert Demirer, Leon Musolff and Liyuan Yang, &amp;ldquo;Writing Code vs. Shipping Code:
Productivity Effects Across Generations of AI Coding Tools,&amp;rdquo; &lt;em&gt;NBER Working
Paper No. 35275&lt;/em&gt;, 2026. &lt;a href="https://doi.org/10.3386/w35275"&gt;https://doi.org/10.3386/w35275&lt;/a&gt;&amp;#160;&lt;a href="#fnref:11" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:12"&gt;
&lt;p&gt;Alberto Bacchelli and Christian Bird, &amp;ldquo;Expectations, Outcomes, and
Challenges of Modern Code Review,&amp;rdquo; &lt;em&gt;Proceedings of ICSE&lt;/em&gt;, 2013.
&lt;a href="https://doi.org/10.1109/ICSE.2013.6606617"&gt;https://doi.org/10.1109/ICSE.2013.6606617&lt;/a&gt;&amp;#160;&lt;a href="#fnref:12" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:13"&gt;
&lt;p&gt;Martin Fowler, &amp;ldquo;Pull Request,&amp;rdquo; &lt;em&gt;martinfowler.com&lt;/em&gt;, 2021.
&lt;a href="https://martinfowler.com/bliki/PullRequest.html"&gt;https://martinfowler.com/bliki/PullRequest.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:13" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>The specification that outlives the task</title><link>https://jamessawle.dev/writing/the-specification-that-outlives-the-task/</link><guid isPermaLink="true">https://jamessawle.dev/writing/the-specification-that-outlives-the-task/</guid><pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate><description>&lt;p&gt;Ask a team why a piece of software behaves the way it does, and watch where they go to find out. They read the code. They read the tests, if the tests describe intent rather than implementation. They search the ticket tracker for the change that introduced the behaviour, then the discussion behind the change, then the person who remembers the discussion. Often the answer is only reassembled in a meeting, held for as long as the meeting lasts, and reconstructed again the next time someone asks.&lt;/p&gt;
&lt;p&gt;This reconstruction is a recurring tax. Code can be correct, readable and well-tested and still be a poor representation of the business behaviour distributed across it. A pricing rule lives in one service, its exception in another, its deliberate omission nowhere at all — a decision not to do something rarely leaves a trace in code. The system executes the accepted behaviour faithfully without ever stating it, so every change that touches the area pays to rediscover it.&lt;/p&gt;
&lt;p&gt;Coding agents change the economics of that tax in both directions. They can make reconstruction faster — an agent can scan more of a system in the time I would spend orienting myself — but they also make it possible to re-enter the same area more often as attempted changes get cheaper. Each attempt still has to re-derive the same intent. And an agent reading behaviour out of code is inferring what the system does, not consulting what the team decided it should do. Where those differ — an old compromise, or a bug customers now depend on — it cannot tell an intended rule from an accidental one.&lt;/p&gt;
&lt;p&gt;This is the gap a specification is meant to close: a place where the accepted behaviour of the system is stated, kept current, and consulted before it is changed. Most of what the industry now calls a specification cannot close it, because it does not last long enough to be consulted twice. A specification only earns the name if later work has to answer to it; the rest is a plan wearing the word. And the reason the distinction is worth an argument is not that a durable specification makes software more correct — I do not think it does — but that it lets a team do a few old things markedly better.&lt;/p&gt;
&lt;h2 id="a-specification-that-disappears-with-the-task-is-a-plan"&gt;A specification that disappears with the task is a plan&lt;/h2&gt;
&lt;p&gt;Here is the boundary stated plainly. A specification is a persistent, structured model of the system&amp;rsquo;s accepted behaviour, which later work deliberately changes. An artefact scoped to a single task is a plan — however detailed, however carefully reviewed, and even when it is committed to the repository.&lt;/p&gt;
&lt;p&gt;The test is lifecycle, not detail or storage. A plan is created for a task, consumed as the task is done, and then spent. It may be consulted later as a historical record, but later work is not expected to update it as the account of current behaviour. A specification is not read once and set aside; work proposes a change &lt;em&gt;to it&lt;/em&gt;, and the accepted change becomes part of it. A plan is written against your understanding of the system; a specification &lt;em&gt;is&lt;/em&gt; the recorded understanding, and the next plan is written against that.&lt;/p&gt;
&lt;p&gt;Two workflows readers already know sit cleanly on the plan side of that line. Vibe coding keeps the running code and discards everything else — the prompt was scaffolding, the code is what survives. An agent&amp;rsquo;s plan mode goes one better and writes the plan down, sometimes commits it, but it is still scoped to the task in front of it; once the change lands, the team does not maintain it as current behaviour. Neither is a lesser practice — a good plan is valuable, a committed one a useful record. But saving a plan does not make it a model of the system; it makes it an artefact of one change.&lt;/p&gt;
&lt;p&gt;&lt;img class="article-figure" src="plan-vs-specification.svg" alt="Two lifecycles compared. A plan is created for a task and may persist as history, but is not maintained after it produces code. A specification receives a reviewed delta that merges into a canonical model, which persists and is read against by the next change." loading="lazy" decoding="async" title="A plan becomes history once the code exists; a specification&amp;#39;s change merges into a model that persists."&gt;
&lt;/p&gt;
&lt;p&gt;You might suspect I am inventing a distinction the field already respects. It does not. The tools flying the specification-driven banner produce a specification-like file before code and then agree on almost nothing else, least of all how long that file is meant to live. At one extreme the file is an input to a delivery cycle rather than a maintained model of the system. GSD Core persists a great deal of &lt;em&gt;state&lt;/em&gt; across sessions and commits a &lt;code&gt;SPEC.md&lt;/code&gt; for a phase, but completing a milestone archives its requirements and removes the current requirements file before the next milestone creates a new one. Harper Reed&amp;rsquo;s much-copied workflow likewise commits a &lt;code&gt;spec.md&lt;/code&gt; and then uses it as scaffolding, not as a standing account of the system.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; At the other extreme the file is the source — the human edits the spec and the code is regenerated output, marked not to be touched by hand — which is the doctrine GitHub&amp;rsquo;s Spec Kit states without hedging: &amp;ldquo;code serves specifications,&amp;rdquo; implementation as &amp;ldquo;the continuously regenerated output.&amp;rdquo;&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt; In between sit the durable-but-partial living documents, held per feature in Kiro or merged into a single canonical tree in OpenSpec.&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt; Every one produces a file before code; what separates them is exactly the test above — whether later work must maintain it as the account of current behaviour.&lt;/p&gt;
&lt;p&gt;Birgitta Böckeler has mapped this range more carefully than a paragraph can, naming its rungs &lt;em&gt;spec-first&lt;/em&gt;, &lt;em&gt;spec-anchored&lt;/em&gt; and &lt;em&gt;spec-as-source&lt;/em&gt;.&lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt; I lean on her map but part company with it in one deliberate way: she describes the territory and declines to crown a winner, treating even throwaway spec-first as legitimate. I am privileging a single rung — the persistent one — as holding real and under-appreciated power. That is a narrowing she chose not to make, so I am filling a gap she left open rather than overturning a consensus.&lt;/p&gt;
&lt;p&gt;&lt;img class="article-figure" src="specification-spectrum.svg" alt="Four specification approaches ordered by lifetime and authority — spec as prompt, per-feature spec, canonical model, and spec as source — with a divider separating a task plan from a specification and the canonical model marked as the rung this article defends." loading="lazy" decoding="async" title="The disagreement is about how long the artefact lives and how much authority it holds."&gt;
&lt;/p&gt;
&lt;p&gt;One qualification keeps this from overreaching. The rung I am defending is not spec-as-source. The code still lives, is still read, and is still edited by hand; the specification is the account of accepted behaviour, not the sole editable origin of the software. That changes the failure surface rather than removing it. The cautions about ceding software design to a model that generates the code land most directly at the top of the ladder. The drift objection does not: keeping two editable artefacts makes it central to the rung I am defending, and I return to it below. The recent case for still designing code for humans supports keeping code in human hands; it cannot tell us whether maintaining the parallel behavioural model will pay for itself.&lt;sup id="fnref:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id="the-power-is-not-correctness-it-is-doing-xp-better"&gt;The power is not correctness. It is doing XP better&lt;/h2&gt;
&lt;p&gt;It would be easy to read all this as a bet on correctness — that a durable specification makes the software more likely to be right. I do not think the evidence supports that, and I am not going to argue it. Nothing here forces the running system to match the specification over time; keeping software honest to its specification is a hard problem, and a separate one, for another article.&lt;/p&gt;
&lt;p&gt;The opportunity in the persistent model is less obvious: it can strengthen two Extreme Programming practices, precisely because it persists.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Persistence can enable &lt;em&gt;less&lt;/em&gt; upfront specification.&lt;/strong&gt; This sounds backwards. Without a canonical model, a change may have to re-establish the accepted behaviour around it from code, tests and memory. A standing model creates a different possibility: when a small request is interpreted against behaviour that is already stated, only the delta has to be elaborated; the rest is already on the page.&lt;/p&gt;
&lt;p&gt;The obvious objection is that the standing model is itself a large specification, so the cost has only moved. Once upkeep is counted, it may have. The narrower point is about when the detail is created: the model accretes one delta at a time, each the just-in-time elaboration of a small slice, so its eventual density was paid for as real work demanded it — never as a batch written ahead of the code. That is the difference from an upfront requirements document: not that the model is smaller or cheaper in total, but that no one had to write it whole before implementation began.&lt;/p&gt;
&lt;p&gt;This is Ron Jeffries&amp;rsquo; &lt;em&gt;Card, Conversation, Confirmation&lt;/em&gt; read forward twenty-five years.&lt;sup id="fnref:8"&gt;&lt;a href="#fn:8" class="footnote-ref" role="doc-noteref"&gt;8&lt;/a&gt;&lt;/sup&gt; The card was a placeholder; the requirement was elaborated just-in-time, in conversation; the confirmation was the acceptance criteria. The specification is the modern analogue of Confirmation — a durable record of what &amp;ldquo;done&amp;rdquo; was agreed to mean — not a return to a heavyweight requirements document written before the work begins. It is the just-in-time, small-slice branch of the family tree, not the upfront-batch branch.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It evolves pairing past engineer-to-engineer to engineer-and-product.&lt;/strong&gt; I have argued before that pairing may be moving earlier — towards premises, examples and specifications — because, in my experience, the costliest mistake is usually not a poor implementation but a plausible implementation of a mistaken premise. The specification delta is where that becomes concrete: proposing a reviewed change to accepted behaviour is a repeatable surface where product understanding flows in and wrong assumptions surface &lt;em&gt;before&lt;/em&gt; cheap code generation turns them into expensive rework. This one is an observation, not a measurement: I have started to see product managers pair, and mob, with engineers while an agent drafts a specification change — not to review code but to interrogate intent while it is still cheap to change. The product manager leaves with a sharper grip on their own technical product, taken from a stated model rather than reconstructed from code.&lt;/p&gt;
&lt;p&gt;Neither is a correctness claim; both are claims about intent and collaboration, and together they are the whole case for the persistent model. Its value does not depend on being the sole editable source from which code is generated, or on covering all behaviour. It does depend on being authoritative within the behaviour it describes.&lt;/p&gt;
&lt;h2 id="walking-the-loop-with-a-concrete-change"&gt;Walking the loop with a concrete change&lt;/h2&gt;
&lt;p&gt;&lt;img class="article-figure" src="specification-loop.svg" alt="A small request is interpreted by an agent against the current specification and code. Product, engineering, and the agent review the proposed delta — the point of highest leverage — before more autonomous implementation merges the accepted change into the canonical model, which informs the next request." loading="lazy" decoding="async" title="Human judgement concentrates where the delta is reviewed; implementation and merge are more autonomous."&gt;
&lt;/p&gt;
&lt;p&gt;The two gains rest on a single mechanism, and it is easiest to watch it turn on something small. A product manager asks for one thing: &lt;em&gt;let a first-order welcome discount be combined with account credit.&lt;/em&gt; One line. The agent interprets it against the current specification, and the request lands in a dense corner of it — a welcome discount applies once per customer, to the subtotal, before delivery; account credit applies afterwards, to the remaining balance and is earned only on cash paid; and, stated flatly, &lt;em&gt;at most one promotional discount applies to an order.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;That last rule is where the code cannot settle the question. Code and tests may reveal how the terms are represented and show that the two have never combined; they cannot decide whether someone intended that separation. Is account credit a promotional discount, caught by the rule, or a payment instrument the rule never meant to cover? The specification is silent, and silence reads the same whether it was a decision or an oversight. So the agent does not guess. It surfaces the questions a human has to answer: is the single-discount rule policy or omission; does the welcome discount still compute against the full subtotal once credit is in play; can the pair drive the balance below zero, and who absorbs the remainder; and, since credit can be earned repeatedly while the welcome discount is once-per-customer, whether combining them opens a farming loop.&lt;/p&gt;
&lt;p&gt;A person settles them, and the decisions are about intent, not implementation. Account credit is a payment instrument; the single-discount rule was silent on it, not opposed — the omission was accidental. The welcome discount keeps computing against the subtotal, and credit still applies to what remains, capped at the balance. An existing rule earns credit only on cash paid, so the combination creates no new farming loop. Refunds and partial cancellation are named as unchanged and deliberately left alone.&lt;/p&gt;
&lt;p&gt;What merges back is not that reasoning, held in someone&amp;rsquo;s memory until the next argument, but a single typed change to the model — the modification and the addition side by side, ready to review. OpenSpec writes it as a delta against the current specification:&lt;sup id="fnref1:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#79c0ff"&gt;## MODIFIED Requirements
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#79c0ff"&gt;### Requirement: One promotional discount per order
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The system SHALL apply at most one promotional discount to an order. This
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;limit governs promotions only; payment instruments such as account credit
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;are exempt and do not count against it.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#79c0ff"&gt;#### Scenario: Welcome discount combined with account credit
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;-&lt;/span&gt; WHEN a first-order customer holds both a welcome discount and account credit
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;-&lt;/span&gt; THEN the welcome discount applies to the subtotal
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ff7b72"&gt;-&lt;/span&gt; AND account credit applies to the remaining balance, capped at that balance
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#79c0ff"&gt;## ADDED Requirements
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#79c0ff"&gt;### Requirement: Account credit stacks after a promotional discount
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The system SHALL deduct account credit from the balance that remains after any
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;promotional discount, and SHALL NOT allow the combined reduction to exceed the
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;order total.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The delta stays atomic — one rule clarified, one interaction recorded; the moment it began rewriting refunds and cancellation too would be the signal the request had left its small slice.&lt;/p&gt;
&lt;p&gt;Now hold the two lifecycles side by side. A plan would have said &lt;em&gt;add credit to the allowed-stacking check and ship&lt;/em&gt;. The rationale might survive in a ticket, test name or historical plan, but it would have no maintained home as current policy; the next person to touch promotions would have to find and interpret it before deciding whether to &amp;ldquo;fix&amp;rdquo; the apparent stacking bug. The delta records that decision &lt;em&gt;as&lt;/em&gt; the accepted rule. The request stayed small, the existing specification carried the density around it, and the artefact is a &lt;em&gt;change to the model&lt;/em&gt;, not a document about the task. That difference in lifecycle is what turns the two gains above from hopeful description into something a team can run.&lt;/p&gt;
&lt;h2 id="i-have-watched-this-fail-before"&gt;I have watched this fail before&lt;/h2&gt;
&lt;p&gt;The objection I take most seriously is not one I have to borrow from a critic. I share it. I have maintained a long-lived requirements document that was quietly false within a quarter — everyone had stopped reading it, and no one had told it — and nothing about my calling this new artefact a specification makes it immune.&lt;/p&gt;
&lt;p&gt;That failure has two distinct shapes, and they are worth separating, because the practice can mitigate one and not answer the other.&lt;/p&gt;
&lt;p&gt;The first is &lt;em&gt;rigidity&lt;/em&gt;. A specification agreed before the code is a blueprint written at the moment of least knowledge, and implementation is where its mistaken assumptions surface. Held too firmly, it forces the system to honour decisions that turned out to be wrong.&lt;/p&gt;
&lt;p&gt;The second is &lt;em&gt;decay&lt;/em&gt;. Documents drift against the system they describe unless someone pays, continually and deliberately, to keep them current — and requirements written this way turn out to be inappropriate almost as soon as they are written.&lt;sup id="fnref:9"&gt;&lt;a href="#fn:9" class="footnote-ref" role="doc-noteref"&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;sup id="fnref:10"&gt;&lt;a href="#fn:10" class="footnote-ref" role="doc-noteref"&gt;10&lt;/a&gt;&lt;/sup&gt; A persisted natural-language model is a standing invitation to do it again: to maintain a second, incomplete representation of the software that quietly stops being true.&lt;/p&gt;
&lt;p&gt;There is a sharper edge to the second worry, aimed at natural language itself. Prose is a lossy medium for behaviour. It skips the intermediate abstractions that make large-scale engineering possible, and machine-recovered traceability from it is good enough to assist a human, not to trust unattended.&lt;sup id="fnref:11"&gt;&lt;a href="#fn:11" class="footnote-ref" role="doc-noteref"&gt;11&lt;/a&gt;&lt;/sup&gt; Push a specification precise enough to pin an agent down and it stops being prose in any useful sense — it becomes, in one recent phrasing, &amp;ldquo;programming in a worse, more ambiguous programming language,&amp;rdquo; echoing Dijkstra&amp;rsquo;s 1978 objection to natural-language programming.&lt;sup id="fnref1:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt; Model-driven development encountered the same problems — round-tripping, drift, the cost of formalism — which is why even its advocates keep a catalogue of why it fails.&lt;sup id="fnref:12"&gt;&lt;a href="#fn:12" class="footnote-ref" role="doc-noteref"&gt;12&lt;/a&gt;&lt;/sup&gt; The warning that spec-as-source courts &amp;ldquo;the downsides of both MDD and LLMs: inflexibility and non-determinism&amp;rdquo; restates a very old worry.&lt;sup id="fnref1:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;And underneath both shapes the pragmatists have a pointed question. If specifications are prompts, and the code is what survives, why maintain a second artefact at all? Its upkeep may simply cost more than it returns, especially while nothing forces the running system to conform to it.&lt;/p&gt;
&lt;p&gt;I can mitigate the first shape and not answer the second. Each delta is created just-in-time for a small vertical slice and stays cheap to revise as the team learns. A specification agreed before code is not a finished blueprint but, in Unmesh Joshi&amp;rsquo;s phrase, &amp;ldquo;a hypothesis to be revised.&amp;rdquo;&lt;sup id="fnref:13"&gt;&lt;a href="#fn:13" class="footnote-ref" role="doc-noteref"&gt;13&lt;/a&gt;&lt;/sup&gt; The loop works because each round is a small, reviewable change, not a standing document defended against reality. That reduces rigidity; it does not prevent a team from turning the model into a gate that resists new knowledge.&lt;/p&gt;
&lt;p&gt;Decay I cannot answer, and I will not pretend to. Nothing in the workflows examined forces a persisted prose model to remain faithful to the running system over time, and a model that accretes cheap deltas while no one re-validates the whole is exactly how a large, quietly-false document forms. That is the real weight of the pragmatists&amp;rsquo; question, and it stays open here. Kent Beck&amp;rsquo;s instinct is worth sitting with: in &lt;em&gt;augmented coding&lt;/em&gt; his durable, trusted artefact is the test suite — an executable specification — alongside a task-scoped plan, not a persistent prose model.&lt;sup id="fnref:14"&gt;&lt;a href="#fn:14" class="footnote-ref" role="doc-noteref"&gt;14&lt;/a&gt;&lt;/sup&gt; Whether the durable artefact should be prose or executable, and whether something like BDD is the layer that makes it so, is the tension the next article takes up — not one I am claiming to have solved here.&lt;/p&gt;
&lt;h2 id="adopting-it-on-software-that-already-exists"&gt;Adopting it on software that already exists&lt;/h2&gt;
&lt;p&gt;Most teams are not starting from an empty repository, and neither route into an existing system is free. You can reverse-engineer a baseline — have an agent infer the accepted behaviour from the code and tests, then validate it with people who can distinguish intent from accident. The inferred baseline describes what the system &lt;em&gt;does&lt;/em&gt;, bugs and dead compromises included. A baseline nobody has validated is not a specification; it is the reconstruction tax paid once and then trusted, which is worse than paying it each time.&lt;/p&gt;
&lt;p&gt;Or you can grow coverage incrementally, letting the specification accrete around the areas you actually change. This spreads the cost and keeps it attached to real work, but a request that looks like a new requirement over existing code may in fact contradict accepted behaviour the specification does not yet describe. Treat those as higher-risk and route them to human judgement, because the model cannot yet warn you that you are changing something rather than adding it. Neither route removes the reconstruction tax; both convert it into an explicit, reviewable cost.&lt;/p&gt;
&lt;h2 id="where-this-is-still-moving"&gt;Where this is still moving&lt;/h2&gt;
&lt;p&gt;The claim is narrow: a persistent model can let a small change elaborate only its delta and can give product and engineering a shared surface for reviewing intent. That does not establish that the software will be more correct or that the model will cost less than it returns.&lt;/p&gt;
&lt;p&gt;The right granularity is unknown — how much behaviour one specification should hold before it becomes the requirements document the drift literature warns about. Repository and ownership boundaries are unknown; OpenSpec&amp;rsquo;s early cross-repository work shows the boundary being pushed, not that broad, shared specifications work.&lt;sup id="fnref2:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt; The context economics are unknown — a specification dense enough to be useful is also expensive to keep in an agent&amp;rsquo;s working context. And conformance over time — whether the running system still matches what the model says — is the largest open problem of all, the one this article has deliberately left standing.&lt;/p&gt;
&lt;p&gt;The persistent model earns its keep only while it stays cheap to change and tethered to reality. That is the tension this whole lineage has circled, from XP&amp;rsquo;s Confirmation through living documentation to agentic specifications — not one the tools have newly solved, but the one worth watching.&lt;/p&gt;
&lt;p&gt;So the next time a tool says it has written a specification, do not judge it by the filename or the detail inside. Ask what happens after the code lands. Will the artefact become a historical record, or will the next change have to consult and revise it as the account of accepted behaviour?&lt;/p&gt;
&lt;p&gt;If it becomes history, it may still be an excellent plan. If it persists, the team has made the harder bargain: in return for a place where product and engineering can examine intent before implementation, it accepts an obligation to keep that place authoritative where it speaks and honest as the system changes.&lt;/p&gt;
&lt;p&gt;The file does not make it a specification. The obligation carried into the next change does.&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Open GSD, GSD Core, &lt;code&gt;spec-phase.md&lt;/code&gt; and &lt;code&gt;complete-milestone.md&lt;/code&gt;, checked
6 August 2026.
&lt;a href="https://github.com/open-gsd/gsd-core/blob/fee72d55604461b86176ee970357f358e8b05cc9/commands/gsd/spec-phase.md"&gt;https://github.com/open-gsd/gsd-core/blob/fee72d55604461b86176ee970357f358e8b05cc9/commands/gsd/spec-phase.md&lt;/a&gt;
and
&lt;a href="https://github.com/open-gsd/gsd-core/blob/fee72d55604461b86176ee970357f358e8b05cc9/commands/gsd/complete-milestone.md"&gt;https://github.com/open-gsd/gsd-core/blob/fee72d55604461b86176ee970357f358e8b05cc9/commands/gsd/complete-milestone.md&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Harper Reed, &amp;ldquo;My LLM codegen workflow atm,&amp;rdquo; 2025.
&lt;a href="https://harper.blog/2025/02/16/my-llm-codegen-workflow-atm/"&gt;https://harper.blog/2025/02/16/my-llm-codegen-workflow-atm/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;GitHub, Spec Kit, &lt;code&gt;spec-driven.md&lt;/code&gt;.
&lt;a href="https://github.com/github/spec-kit/blob/main/spec-driven.md"&gt;https://github.com/github/spec-kit/blob/main/spec-driven.md&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Amazon Web Services, Kiro documentation, &amp;ldquo;Feature specs.&amp;rdquo;
&lt;a href="https://kiro.dev/docs/specs/feature-specs/"&gt;https://kiro.dev/docs/specs/feature-specs/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Fission-AI, OpenSpec, &lt;code&gt;docs/concepts.md&lt;/code&gt; and the Stores beta user guide,
checked 6 August 2026.
&lt;a href="https://github.com/Fission-AI/OpenSpec/blob/d57889664cab4f2f061d236ec3ff82a5578701bb/docs/concepts.md"&gt;https://github.com/Fission-AI/OpenSpec/blob/d57889664cab4f2f061d236ec3ff82a5578701bb/docs/concepts.md&lt;/a&gt;
and
&lt;a href="https://github.com/Fission-AI/OpenSpec/blob/d57889664cab4f2f061d236ec3ff82a5578701bb/docs/stores-beta/user-guide.md"&gt;https://github.com/Fission-AI/OpenSpec/blob/d57889664cab4f2f061d236ec3ff82a5578701bb/docs/stores-beta/user-guide.md&lt;/a&gt;.&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref2:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;Birgitta Böckeler, &amp;ldquo;Understanding Spec-Driven Development: Kiro, spec-kit,
and Tessl,&amp;rdquo; &lt;em&gt;martinfowler.com&lt;/em&gt;, 15 October 2025.
&lt;a href="https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html"&gt;https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;Valentina Servile, &amp;ldquo;Should we still design code for humans?&amp;rdquo; &lt;em&gt;Thoughtworks&lt;/em&gt;,
23 July 2026, citing Edsger W. Dijkstra, &amp;ldquo;On the foolishness of &amp;rsquo;natural
language programming&amp;rsquo;&amp;rdquo; (EWD667), 1978.
&lt;a href="https://www.thoughtworks.com/insights/blog/programming-languages/should-still-design-code-humans"&gt;https://www.thoughtworks.com/insights/blog/programming-languages/should-still-design-code-humans&lt;/a&gt;&amp;#160;&lt;a href="#fnref:7" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:7" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;Ron Jeffries, &amp;ldquo;Essential XP: Card, Conversation, Confirmation,&amp;rdquo; 2001.
&lt;a href="https://ronjeffries.com/xprog/articles/expcardconversationconfirmation/"&gt;https://ronjeffries.com/xprog/articles/expcardconversationconfirmation/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:8" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;David L. Parnas, &amp;ldquo;Software Aging,&amp;rdquo; &lt;em&gt;Proceedings of the 16th International
Conference on Software Engineering&lt;/em&gt;, 1994.
&lt;a href="https://doi.org/10.1109/ICSE.1994.296790"&gt;https://doi.org/10.1109/ICSE.1994.296790&lt;/a&gt;&amp;#160;&lt;a href="#fnref:9" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:10"&gt;
&lt;p&gt;Krzysztof Wnuk, Tony Gorschek and Showayb Zahda, &amp;ldquo;Obsolete software
requirements,&amp;rdquo; &lt;em&gt;Information and Software Technology&lt;/em&gt; 55(6), 2013,
pp. 921–940. &lt;a href="https://doi.org/10.1016/j.infsof.2012.12.001"&gt;https://doi.org/10.1016/j.infsof.2012.12.001&lt;/a&gt;&amp;#160;&lt;a href="#fnref:10" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:11"&gt;
&lt;p&gt;Jan-Philipp Steghöfer and Markus Borg, &amp;ldquo;An Abstraction Is Worth a Thousand
Vibes,&amp;rdquo; &lt;em&gt;IEEE Software&lt;/em&gt; 43(1), 2026, pp. 13–16.
&lt;a href="https://doi.org/10.1109/MS.2025.3621786"&gt;https://doi.org/10.1109/MS.2025.3621786&lt;/a&gt;&amp;#160;&lt;a href="#fnref:11" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:12"&gt;
&lt;p&gt;Johan den Haan, &amp;ldquo;8 Reasons Why Model-Driven Approaches (will) Fail,&amp;rdquo; &lt;em&gt;InfoQ&lt;/em&gt;, 2008. &lt;a href="https://www.infoq.com/articles/8-reasons-why-MDE-fails/"&gt;https://www.infoq.com/articles/8-reasons-why-MDE-fails/&lt;/a&gt;&amp;#160;&lt;a href="#fnref:12" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:13"&gt;
&lt;p&gt;Martin Fowler and Unmesh Joshi, &amp;ldquo;Conversation: LLMs and Building
Abstractions,&amp;rdquo; &lt;em&gt;martinfowler.com&lt;/em&gt;, 26 August 2025 — the &amp;ldquo;Upfront
Specification Impossibility&amp;rdquo; concept appears within.
&lt;a href="https://martinfowler.com/articles/convo-llm-abstractions.html"&gt;https://martinfowler.com/articles/convo-llm-abstractions.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:13" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:14"&gt;
&lt;p&gt;Kent Beck, &amp;ldquo;Augmented Coding: Beyond the Vibes,&amp;rdquo; &lt;em&gt;Tidy First?&lt;/em&gt; Substack, 2025. &lt;a href="https://newsletter.kentbeck.com/p/augmented-coding-beyond-the-vibes"&gt;https://newsletter.kentbeck.com/p/augmented-coding-beyond-the-vibes&lt;/a&gt;&amp;#160;&lt;a href="#fnref:14" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item><item><title>Agents write code faster. XP makes change safer</title><link>https://jamessawle.dev/writing/agents-write-code-faster-xp-makes-change-safer/</link><guid isPermaLink="true">https://jamessawle.dev/writing/agents-write-code-faster-xp-makes-change-safer/</guid><pubDate>Tue, 28 Jul 2026 00:00:00 +0000</pubDate><description>&lt;p&gt;Most conversations about coding agents begin with throughput. How do we deliver twice as much? Which maintenance tasks can we hand over? How do we complete the same backlog in half the time?&lt;/p&gt;
&lt;p&gt;These are sensible questions. Agents can make bounded tasks dramatically cheaper: a dependency upgrade that once consumed much of a day can be attempted in minutes, while an unfamiliar part of a system can be explored before I would previously have finished orienting myself. These are real wins, but they are not necessarily compounding wins. The next dependency upgrade still needs to be understood, tested and integrated, and producing twice as many changes does not make the system twice as capable of absorbing them.&lt;/p&gt;
&lt;p&gt;The data shows this gap directly. Across separate matched event studies, researchers estimated that AI coding tools raised weekly commits by a cumulative 179% — with well over twice as much code written each week. But the amount that reached users moved far less: their estimate for releases was a cumulative increase of about 31%. The two figures are not strictly comparable; the release estimate covered only autocomplete and synchronous agents and came from a smaller sample. Even so, the direction is hard to miss: far more code was written than was shipped.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;A study of one unusually AI-forward company shows the same pressure further along the pipeline. The company had set itself a twelve-month target to double output per engineer, and it got there early: by April 2026, authored pull requests per active developer had reached 2.09 times their January–April 2025 baseline.&lt;/p&gt;
&lt;p&gt;That volume landed on the same reviewers. Pull requests per active reviewer roughly doubled too, and the review process shifted to absorb them: automated review coverage rose to about 84%, while the share of pull requests reaching a human reviewer fell to 68%.&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Producing more code required the verification system to change as well.&lt;/p&gt;
&lt;p&gt;This is not an argument that agents have failed. Thirty per cent more releases would be an extraordinary result for many organisations. It is an argument that writing code and changing software are not the same thing. A plausible implementation still has to express the right intent, preserve behaviour we care about, integrate with everything else that has changed and remain understandable to the people who will operate and modify it later.&lt;/p&gt;
&lt;p&gt;Agents change the economics of producing code. They do not change the need for confidence in changing software.&lt;/p&gt;
&lt;p&gt;&lt;img class="article-figure" src="change-system.svg" alt="Small code changes pass from production through verification and integration to release, with feedback paths returning from each stage." loading="lazy" decoding="async" title="Agents accelerate code production; confidence is built across the entire path."&gt;
&lt;/p&gt;
&lt;h2 id="this-brought-me-back-to-xp"&gt;This brought me back to XP&lt;/h2&gt;
&lt;p&gt;The Thoughtworks &lt;em&gt;Future of Software Engineering&lt;/em&gt; retreat report was one of the things that pushed me towards this argument. Across its sessions, the repeated concern was not whether agents could produce more code, but whether teams could establish confidence in what they produced. Its recommendations centre on stronger testing, verification and feedback loops rather than generation alone.&lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;That landed with me because it felt familiar. In the XP teams I have worked in, the goal was never to maximise the amount of code we could produce. It was to make change manageable: make the change small, make it testable, make the evidence visible, integrate it before it drifts too far from the rest of the system and keep the design simple enough to change again.&lt;/p&gt;
&lt;p&gt;XP gave the team both a mindset and a coherent set of practices. That combination removed a great deal of recurring process invention. Without it, teams can react to every difficult week by introducing another local optimisation: cycle time is slow, so we add a ceremony; review is taking too long, so we add another rule; quality has slipped, so we place another gate at the end. Each response can make sense in isolation, but together they rarely form a coherent way of working.&lt;/p&gt;
&lt;p&gt;XP gave us somewhere more useful to return when delivery became difficult. We made the work smaller, shortened the feedback loop, improved the tests, integrated sooner and simplified what had become difficult to understand. It was not always the fastest-looking response to the immediate problem, but it made the system of work smoother and more dependable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Slow is smooth, and smooth is fast.”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;— US military maxim&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That does not mean preserving every XP practice unchanged. Beck described the practices as expressions of XP’s values, with principles translating those values into practice and helping teams act when no ready-made practice fits the problem. He was equally clear that “there is no freeze-dried software process” and that every team applies XP differently.&lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;XP cannot be reduced to its practices, but neither are the practices incidental. They make the values concrete and reinforce one another. Most may continue to hold as they are. Some may need to move, and others may need to change completely.&lt;/p&gt;
&lt;p&gt;The test is not whether a practice looks like XP as we remember it. The test is whether it still helps us make small, testable and verifiable changes, obtain rapid feedback, preserve simple designs and change software with confidence.&lt;/p&gt;
&lt;h2 id="faster-production-raises-the-value-of-restraint"&gt;Faster production raises the value of restraint&lt;/h2&gt;
&lt;p&gt;Agents make it tempting to expand the unit of work. A task that once felt too large to hand to another engineer can now be described to an agent and returned as an apparently complete implementation. Once that works, the natural response is to ask for more: another component, another migration, another feature.&lt;/p&gt;
&lt;p&gt;The ability to produce a large change does not make a large change desirable. Among commits detectable as agent-assisted, the median number of added lines was 31, compared with 11 for residual human-authored commits. Commits adding more than 1,000 lines were 90.1% more frequent in relative terms, although the paper does not report their absolute frequencies. Both groups touched a median of two files, but the agent-assisted distribution was larger above the median.&lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;In my experience, bounded changes are easier to direct and far easier to verify. But the case for small changes is not limited to the context windows or reliability of today’s agents. If we can attempt more changes, reducing the uncertainty introduced by each one becomes more valuable.&lt;/p&gt;
&lt;p&gt;A small failure is easier to diagnose and reverse. Its interaction with other work is easier to understand, and the feedback it produces is less ambiguous. The natural unit of agentic development should not be the largest task an agent can complete. It should be the smallest change for which the team can obtain meaningful feedback.&lt;/p&gt;
&lt;p&gt;&lt;img class="article-figure" src="feedback-batch-size.svg" alt="A large batch produces one delayed and ambiguous feedback signal, while a sequence of small changes produces specific feedback after each change." loading="lazy" decoding="async" title="Small changes keep evidence close to the decision that produced them."&gt;
&lt;/p&gt;
&lt;p&gt;The same reasoning applies to testing and integration. As the cost of producing another attempted change falls, the ability to evaluate that change cheaply and quickly becomes more valuable. An agent can state confidently that its implementation is correct, but confidence has to come from outside the agent: tests, compilation, static analysis, contracts, operational signals and other forms of verification capable of disagreeing with it.&lt;/p&gt;
&lt;p&gt;This does not settle every argument about test-driven development. It does not mean every team must follow one exact testing ritual, or that a large test suite automatically provides useful evidence. It means faster production increases the value of fast, independent feedback.&lt;/p&gt;
&lt;p&gt;The original description of XP already connected short cycles, automated tests, evolving design and close collaboration. Those were not isolated techniques; together they kept evidence close to the moment of change.&lt;sup id="fnref1:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Continuous integration matters for the same reason. It is easy to claim CI because every branch passes an automated pipeline, but running checks on isolated branches is not the same as frequently integrating the work. CI requires each team member to merge changes into the shared codebase at least daily, with every integration checked by an automated build including tests.&lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Agents can produce several substantial changes in parallel. That makes it more important to discover what those changes mean together before they have had time to diverge. The important question is not how much code an agent can finish before we interrupt it. It is how long we are prepared to wait before learning what that code means when combined with everything else.&lt;/p&gt;
&lt;p&gt;Simple design completes the loop. If a system is unnecessarily complex, neither a human nor an agent can easily see where the consequences of a change end. A modification that appears local may affect behaviour elsewhere, and the evidence needed to trust it becomes harder to assemble and interpret.&lt;/p&gt;
&lt;p&gt;Simple design is sometimes presented as an aesthetic preference. In this context, it is an economic one: it reduces the amount that must be understood and verified every time the system changes.&lt;/p&gt;
&lt;p&gt;Confidence should not come from believing that the agent is usually right. It should come from keeping the system understandable and making mistakes cheap to expose.&lt;/p&gt;
&lt;h2 id="some-practices-will-need-new-answers"&gt;Some practices will need new answers&lt;/h2&gt;
&lt;p&gt;The aims of XP may be more relevant than ever, while the right practices become less obvious. Pairing and pull requests expose that tension in different ways.&lt;/p&gt;
&lt;h3 id="pairing-may-move-earlier"&gt;Pairing may move earlier&lt;/h3&gt;
&lt;p&gt;An agent can provide implementation ideas, explore alternatives and maintain momentum, so two engineers working through every line together may no longer be the best use of their attention.&lt;/p&gt;
&lt;p&gt;But pairing was never only about producing code. A recent study returns to Beck’s description of trying to “program (and analyze and design and test)” while learning together how to work better.&lt;sup id="fnref:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;A second human challenges assumptions, contributes knowledge of the system and provides genuine resistance when an agent too readily accepts the direction it has been given. In my experience, this matters before any code is written: the costliest mistake is often not a poor implementation, but a plausible implementation of a mistaken premise.&lt;/p&gt;
&lt;p&gt;An agent can challenge an implementation. A human pair is better placed to challenge the premise.&lt;/p&gt;
&lt;p&gt;&lt;img class="article-figure" src="pairing-at-the-premise.svg" alt="Two engineers challenge the premise and shape examples before an agent implements the change, which is then evaluated by independent evidence." loading="lazy" decoding="async" title="Human judgement has the greatest leverage while the premise is still cheap to change."&gt;
&lt;/p&gt;
&lt;p&gt;In the squads I work with, some of the highest-value pairing—and increasingly mobbing—now happens earlier, around specifications, examples and the boundaries of a change. Pairing may not be disappearing so much as moving to where human judgement has greater leverage.&lt;/p&gt;
&lt;p&gt;This is also where the retreat report landed: deliberately preserve pairing around specifications and design intent, even if implementation pairing declines.&lt;sup id="fnref1:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;We should be equally careful not to remove the learning opportunities pairing provided simply because their value does not appear in today’s throughput figures. In a qualitative study of industrial pairing, knowledge asymmetry frequently produced explicit teacher and student roles, each requiring distinct pair-programming skills.&lt;sup id="fnref1:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Engineers develop judgement by watching other engineers frame problems, navigate uncertainty and revise their thinking. If experienced engineers increasingly pair only with agents, the cost may appear not in the speed of today’s change but in the capability of tomorrow’s team.&lt;/p&gt;
&lt;p&gt;That does not mean preserving traditional pairing on every task. It means understanding what else is being removed when we decide the practice is no longer efficient.&lt;/p&gt;
&lt;h3 id="pull-requests-are-less-clear"&gt;Pull requests are less clear&lt;/h3&gt;
&lt;p&gt;Agentic development makes it natural to let an agent complete a bounded change and then review the result, but that raises uncomfortable questions. Am I the author because I framed and supervised the work, or its first reviewer because I did not write the code? Does a second human review add confidence, or would that attention be better invested in stronger automated verification?&lt;/p&gt;
&lt;p&gt;The Thoughtworks retreat’s challenge is deliberately blunt: “Stop treating manual code review as a de facto quality guarantee; measure it.”&lt;sup id="fnref2:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;That is a valuable provocation, but it is not evidence that review has no value. Modern code review supports outcomes beyond defect detection, including knowledge transfer, team awareness and the development of alternative solutions. The same research found that understanding the reason and context for a change is central to reviewing it effectively.&lt;sup id="fnref:8"&gt;&lt;a href="#fn:8" class="footnote-ref" role="doc-noteref"&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Its relationship with post-release defects is less clear. A replication across Qt and Chrome found the estimated influence of code-review measures highly sensitive to variable selection. Explanatory models without those measures fitted as well as or better than models that included them, although review measures could still have indirect relationships with defects.&lt;sup id="fnref:9"&gt;&lt;a href="#fn:9" class="footnote-ref" role="doc-noteref"&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Pull requests also create a tension with continuous integration. They can provide a useful point for discussion before integration, but the value depends on keeping them small and responsive enough that work still reaches the mainline at least daily. Fowler also notes that pull requests are only one form of review; pairing can provide continuous review without making review a pre-integration gate.&lt;sup id="fnref:10"&gt;&lt;a href="#fn:10" class="footnote-ref" role="doc-noteref"&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;I do not yet know whether agents make pull requests more important or less valuable. That uncertainty reinforces the wider point: we should judge practices by the feedback, shared understanding and confidence they create, not preserve them simply because they are familiar.&lt;/p&gt;
&lt;p&gt;Pairing and pull requests deserve fuller treatment, but not here. For this argument, they serve as reminders that doubling down on XP does not mean refusing to change it.&lt;/p&gt;
&lt;h2 id="do-not-start-again-from-nothing"&gt;Do not start again from nothing&lt;/h2&gt;
&lt;p&gt;The software industry is in danger of treating agentic development as a wholly new discipline with wholly new problems. The tools are new, their capabilities are changing quickly and some of our practices will have to change with them. But we already know a great deal about changing software safely.&lt;/p&gt;
&lt;p&gt;We know why large batches are difficult to understand, why delayed feedback makes mistakes expensive and why unnecessary complexity makes consequences harder to predict. We know why isolated work becomes harder to integrate, and that shared understanding matters even when it does not appear in a throughput measure.&lt;/p&gt;
&lt;p&gt;These are not arguments against coding agents. They are the conditions under which coding agents become more useful.&lt;/p&gt;
&lt;p&gt;The Thoughtworks retreat’s clearest strategic warning was that agents amplify the disciplines and habits an organisation already has. Weak testing, unclear ownership and poor documentation do not disappear when implementation accelerates; they “get worse, faster, not better.”&lt;sup id="fnref3:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Before inventing an entirely new agentic development methodology, look at the XP practices your team already has. Ask how your tests could give an agent clearer and faster feedback. Ask how you could reduce the size of each change rather than using agent capacity to increase it. Look for complexity that makes generated code difficult to verify. Consider where human collaboration could improve the assumptions and specifications shaping the agent’s work.&lt;/p&gt;
&lt;p&gt;Then double down on what works.&lt;/p&gt;
&lt;p&gt;The answer is not to preserve every existing practice unchanged. Most may continue to hold, some will need to move and others may need to be replaced. But replacing a practice is not the same as abandoning the purpose it served.&lt;/p&gt;
&lt;p&gt;Agents have changed the economics of producing code. They have not removed uncertainty, integration risk or the need to learn from real use. In making implementation cheaper, they have made the ability to change software confidently more valuable.&lt;/p&gt;
&lt;p&gt;The old practices may not survive intact. The aims behind them have never been more relevant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;XP is dead. Long live XP.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="references"&gt;References&lt;/h2&gt;
&lt;div class="footnotes" role="doc-endnotes"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;Mert Demirer, Leon Musolff and Liyuan Yang, “Writing
Code vs. Shipping Code: Productivity Effects Across Generations of AI
Coding Tools,” &lt;em&gt;NBER Working Paper No. 35275&lt;/em&gt;, 2026.
&lt;a href="https://doi.org/10.3386/w35275"&gt;https://doi.org/10.3386/w35275&lt;/a&gt;&amp;#160;&lt;a href="#fnref:1" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Hao He, Shyam Agarwal, Yegor Denisov-Blanch, Pavel
Azaletskiy, Sanmi Koyejo and Bogdan Vasilescu, “AI Writes Faster Than Humans
Can Review: A Longitudinal Study of an Enterprise ‘2×’ Mandate,” &lt;em&gt;arXiv
preprint&lt;/em&gt;, 2026. The reported measure is authored pull requests per active
developer, rather than the target’s stated merged pull requests per engineer.
&lt;a href="https://arxiv.org/abs/2607.01904v1"&gt;https://arxiv.org/abs/2607.01904v1&lt;/a&gt;&amp;#160;&lt;a href="#fnref:2" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:3"&gt;
&lt;p&gt;Thoughtworks, &lt;em&gt;The Future of Software
Engineering: Insights and Findings from an Unconference on AI, Agentic
Engineering and the Future of the Discipline&lt;/em&gt;, 2026.
&lt;a href="https://www.thoughtworks.com/content/dam/thoughtworks/documents/report/tw_future_of_software_engineering_europe_2026.pdf"&gt;https://www.thoughtworks.com/content/dam/thoughtworks/documents/report/tw_future_of_software_engineering_europe_2026.pdf&lt;/a&gt;&amp;#160;&lt;a href="#fnref:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref2:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref3:3" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:4"&gt;
&lt;p&gt;Kent Beck with Cynthia Andres, &lt;em&gt;Extreme Programming
Explained: Embrace Change&lt;/em&gt;, second edition, Addison-Wesley Professional,
2004, pp. 2–3.
&lt;a href="https://www.pearson.com/en-us/subject-catalog/p/extreme-programming-explained-embrace-change/P200000000118/9780321278654"&gt;https://www.pearson.com/en-us/subject-catalog/p/extreme-programming-explained-embrace-change/P200000000118/9780321278654&lt;/a&gt;&amp;#160;&lt;a href="#fnref:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:4" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:5"&gt;
&lt;p&gt;Romain Robbes, Théo Matricon, Thomas Degueule, Andre
Hora and Stefano Zacchiroli, “Agentic Much? Adoption of Coding Agents on
GitHub,” &lt;em&gt;arXiv preprint&lt;/em&gt;, 2026.
&lt;a href="https://arxiv.org/abs/2601.18341v2"&gt;https://arxiv.org/abs/2601.18341v2&lt;/a&gt;&amp;#160;&lt;a href="#fnref:5" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:6"&gt;
&lt;p&gt;Martin Fowler, “Continuous Integration,”
&lt;em&gt;martinfowler.com&lt;/em&gt;, 2024.
&lt;a href="https://martinfowler.com/articles/continuousIntegration.html"&gt;https://martinfowler.com/articles/continuousIntegration.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:6" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:7"&gt;
&lt;p&gt;Linus Ververs, Trang Linh Lam and Lutz Prechelt,
“Qualitative Analysis of the Teacher and Student Roles in Pair Programming,”
&lt;em&gt;arXiv preprint&lt;/em&gt;, 2025.
&lt;a href="https://arxiv.org/abs/2507.10305v2"&gt;https://arxiv.org/abs/2507.10305v2&lt;/a&gt;&amp;#160;&lt;a href="#fnref:7" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href="#fnref1:7" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:8"&gt;
&lt;p&gt;Alberto Bacchelli and Christian Bird,
“Expectations, Outcomes, and Challenges of Modern Code Review,” &lt;em&gt;Proceedings
of the 35th International Conference on Software Engineering&lt;/em&gt;, 2013.
&lt;a href="https://doi.org/10.1109/ICSE.2013.6606617"&gt;https://doi.org/10.1109/ICSE.2013.6606617&lt;/a&gt;&amp;#160;&lt;a href="#fnref:8" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:9"&gt;
&lt;p&gt;Andrey Krutauz, Tapajit Dey, Peter C. Rigby and
Audris Mockus, “Do Code Review Measures Explain the Incidence of
Post-Release Defects? Case Study Replications and Bayesian Networks,”
&lt;em&gt;Empirical Software Engineering&lt;/em&gt;, 2020.
&lt;a href="https://doi.org/10.1007/s10664-020-09837-4"&gt;https://doi.org/10.1007/s10664-020-09837-4&lt;/a&gt;&amp;#160;&lt;a href="#fnref:9" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:10"&gt;
&lt;p&gt;Martin Fowler, “Pull Request,” &lt;em&gt;martinfowler.com&lt;/em&gt;, 2021.
&lt;a href="https://martinfowler.com/bliki/PullRequest.html"&gt;https://martinfowler.com/bliki/PullRequest.html&lt;/a&gt;&amp;#160;&lt;a href="#fnref:10" class="footnote-backref" role="doc-backlink"&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description></item></channel></rss>