Skip to content

Build1 publisher3 min readPublished

The hexagonal version needed 38% more time to clear a coding agent's acceptance gates

A principal engineer built the same EV-charging invoice service twice and timed a coding agent through nine cumulative features on each. The two setups differed in more than layering, and he says so.

The Engineer · Build desk

Illustration accompanying The hexagonal version needed 38% more time to clear a coding agent's acceptance gates

What happened

  • Across nine cumulative features, the hexagonal implementation of the same EV-charging invoice service took 38% longer than the flat one for a coding agent to reach acceptance.
  • Every measured task ran in a fresh session against a frozen public contract and counted as accepted only after project tests and a separate public-interface evaluator both passed.
  • The two compared setups differed in three ways at once: their starting code, their architecture guidance and their test suites.
  • The nine cumulative tasks began with CSV export and an offline invoice CLI and ended with effective-dated tariffs, partial refunds with concurrent balance protection, and tenant routing.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • constraint The number prices an entire hexagonal setup, so it cannot settle whether ports and adapters specifically slow an agent down. Answering that needs a rerun with one variable moved and the rest held.
  • exposure A repository that enforces boundaries in CI gives an agent a second way to fail: the change satisfies the behavioural contract and breaks a structure test anyway.
  • cost Repair cycles sit inside the measured clock, so every gate failure is paid in wall time by whoever is running the agent and waiting on acceptance.
  • decision Teams that keep architecture tests have to decide whether those tests belong in the agent's acceptance gate at all, or in a slower review that does not block the loop.

The 38% is a measure of time to acceptance: agent work, project tests, external checks and any repair, with the clock stopped only after validation passed [14]. Retries are inside the number.

That definition is where the hexagonal arm's extra work shows up. It was asked to carry architecture tests alongside the isolated domain, use cases, ports and adapters [5]. Architecture tests gate structure, not behaviour, so a change that satisfies the frozen contract can still fail them and burn the bounded repair attempt. The flat arm got an architecture-neutral prompt for the same functionality, and it came out as a direct application with shared pricing, persistence, transactions, HTTP and CLI behaviour [6].

The author is clear about what all this costs the inference. The hexagonal baseline was prepared with both a local model and OpenAI assistance, while the flat baseline came from the local model alone; preparation time was excluded from the measured clock [10]. The write-up says the results cannot show that hexagonal architecture alone caused anything, or whether either approach has a better total lifecycle cost [11]. He also notes the experiment did not compare agents with humans [20].

The workload is worth reading before borrowing the number. ChargeLedger is a Java service for an EV charging network that turns a completed session into an invoice: energy used, time spent plugged in after charging completes, tax, and a total that must remain stable once stored [4]. Three guarantees shaped it. A tariff change must not rewrite an old invoice, a retry must not refund twice, and a failed audit write must roll the issuance back with it [8]. Both arms shared the same business contract, Java 21, Javalin, SQLite, Gradle and dependency pins [7].

For the 38% to say anything about your repository, your agent has to work the way this one did: a fresh session per task, a frozen public contract, an automated behavioural gate plus an external interface check, and one repair attempt inside the clock [13]. If your gate is a human reviewer, or your sessions carry context between features, the measurement describes someone else's loop.

Nine tasks in two conditions is 18 runs. The study reports 30 measured runs passing their project and external acceptance checks [16]. That leaves 12 runs outside the nine-by-two pairing [21]. The baseline suite the work started from had 14 original tests [15]. Only one participant job ran at a time, so the two projects were not competing for the model [12], a control most benchmark posts skip.

The post gives the percentage without per-task times, so the size of the difference in minutes is unstated. Its author, who describes himself as a principal engineer [1], wrote: "Every layer has a cost for the person and the agent that must read it. I now think that cost needs a concrete justification." [18] He also wrote: "I still care about clean code. But this experiment made me much less willing to prescribe an architecture before I can explain what it buys us." [3]

What to watch

  • A rerun in which both arms start from the same generated baseline and the same test suite, isolating layering from preparation.
  • Per-task wall-clock times, which would show whether the 38% is worth seconds or hours per feature.
  • Any measure of maintenance cost beyond time to acceptance, which the author says this design cannot compare.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories