Back to blog
Aug 30
dogfooding
byok
anthropic
provider-reliability
engineering-log

Run #17: The Chain Finally Closed, and a New One Opened

Run #16 closed with Architecture's timeout fix fully confirmed and one finding turned into a real pattern: Builder had now failed the identical way twice, both times writing a commit message well past the configured limit. Before Run #17, that pattern got a fix — the smallest one this whole investigation has produced.

What we did to prepare

Two completed Builder attempts, two commit_message_too_long failures — 854 characters over a 500-character limit in Run #14, 1,094 in Run #16, both against the exact same call that otherwise succeeded cleanly. Before touching the limit itself, we checked what it actually protects: the commitMessage field is passed verbatim as a real Git commit message on a real GitHub commit — not a display string, not something with room to grow. The 500-character ceiling was never a technical constraint, just a reasoned default sized against ordinary commit-message conventions, and nothing in Builder's own instructions ever told it that commitMessage needed to stay short while a separate summary field already existed for the detailed explanation. Builder had no reason to know the two fields served different purposes — so both times, it wrote the same kind of thorough explanation into whichever field came naturally, and once was commitMessage, twice.

The fix was a clarification, not a rule change: nothing about maxCommitMessageChars, the retry policy, or any timeout was touched. Builder's prompt and JSON schema now say plainly that commitMessage is a short, conventional commit message and the detailed explanation belongs in summary — the same distinction the validation logic already enforced, just not one Builder had ever been told about.

What happened

Scope, Architecture, Security, and UX all completed cleanly — Architecture's call ran 75,655 milliseconds, a third consecutive clean success under the 120-second timeout since Run #16, no longer a single data point but a settled fact of how this workflow runs now. The routine approval gate opened after Security and was decided quickly, no confusion this time about which gate was which.

Then Builder succeeded — for the first time in this entire series. Its Anthropic call completed in 93,045 milliseconds, comfortably inside its own 120-second budget, and the resulting structured patch passed every safety and bounds check clean. No builder_patch_invalid, no rejection, no wasted retry. Two runs of the identical failure, understood and fixed on the first real attempt at a fix.

Review ran next, and also succeeded — new ground for this project, since no run had ever produced a patch for it to review before. 43,927 milliseconds, unremarkable, clean.

Then Test failed, instantly, for a reason nothing in the last nine runs of investigation had any way to find.

No real provider adapter is configured for preferred kind "openai".

No provider call was ever attempted — no execution record exists for this failure, by design; this is the same structural, safety-first refusal this project built early on for exactly this situation, not a new kind of error. The Tester role's own configuration lists openai as its first-preference provider, and this deployment only has a real adapter wired up for Anthropic. Every previous run in this entire seventeen-run series would have hit this identical wall — none of them ever got far enough to find out, because Architecture or Builder always failed first. This is not a regression from anything shipped recently. It's a gap that has existed since the Tester role was first defined, surfacing for the first time simply because nothing had ever survived long enough to reach it.

What the evidence actually supports

The commit-message fix worked, cleanly, on the first real test. Two occurrences were enough to diagnose the actual cause — a genuine gap in what Builder had been told, not a limit that needed loosening — and one small clarification resolved it without touching anything the validation logic itself enforces.

Reaching Test at all is new information, not a failure of anything built in this investigation. Every fix in this series — the retry deferral, the acquisition-latency batching, both provider timeouts, the Builder diagnostics, this commit-message clarification — was aimed at getting a real run further than the last one. Run #17 is the direct result of all of them working together: further than any prior run, by a wide margin, immediately turning up the next real thing to understand.

Where this leaves things

  • Builder's commit-message question is closed — a real success on the first attempt after the fix, not just an argument that it should work.
  • The full pipeline has now been proven capable of running Scope through Review without a single failure — the first time this project has had that evidence at all.
  • Test's provider-configuration gap is a genuinely new, different problem — not latency, not validation, not governance classification, but provider availability. Whether the right answer is a real OpenAI adapter, a reordered preference list favoring the provider that's actually configured, or something else is an open question this project hasn't had reason to ask until now.
  • No code change is proposed here without investigating that gap on its own terms first — the same discipline every fix in this series has followed from the start.