DEV Community

Cover image for 926 Steps, Two Lobotomies, and Zero Nudges: Flight-Testing the Commitment Machine Across Gemini, Claude, and GPT-OSS

926 Steps, Two Lobotomies, and Zero Nudges: Flight-Testing the Commitment Machine Across Gemini, Claude, and GPT-OSS

Unix flat-files beat memory compaction

A 2026 Harvard study of 718 companies found that AI coding agents write 30% more code and close zero extra tickets because PR review times jump 49%. When I ran my 1986 Commitment Machine across five live production tickets, a mid-flight vendor swap, and an open-weight crash test, here is what the flight recorder proved.

"The dashboard with the Mermaid state diagram is perfect. I find myself not even opening the pull requests now. I just wait for the green board or the triage details... And I also like that every code change is paired with an immediate critical reviewer. That one step really reduces friction."

— My notes to myself after the fourth ticket in a row


1. The Bottom Line Up Front: What Live Production Just Proved

Earlier this month, Harvard researchers Fiona Chen and James Stratton published a massive study ("Artificial Intelligence in the Firm: Bottlenecks in Software Production", covered in Forkast News) tracking 718 companies and more than 725,000 software developers from 2021 to 2026.

By early 2026, over 95% of those companies had rolled out AI coding agents (Claude Code, Cursor, Devin). And the numbers they found should make every engineering manager wince:

  • Developers wrote +30% more code (1,500 extra lines per developer per month), and opened +23% more pull requests.
  • Yet the number of finished Jira tickets and epics went up by 0%.
  • Why? Because PR review wait times jumped +49% (+3.45 days), the number of PRs kicked back for rewrites nearly doubled, review comments per PR rose +35%, and 14% more senior engineers got dragged away from their own work to pay what the researchers call the "babysitting tax."

If you've ever worked on a real software team, you don't need an economics degree to spot the bug. If you make typing code 10x faster, but your AI never pushes back on a bad ticket and never catches its own bugs before committing, you haven't sped up your team. You've just aimed a firehose of plausible-looking slop at your senior reviewers.

In Part 3.10, I redesigned my coding workflow (Randal's Public Workflow Gist) specifically to invert that bottleneck—moving ticket pushback, adversarial code review, and state tracking before git commit using Fernando Flores's 1986 "Committed Speech" rules, a 1976 Makefile, and a 1983 /etc/init.d state directory (00_governance.md through 99_next_action.md).

Then I turned the key and ran five consecutive production tickets (926+ steps, 18 subagents), a 960-step mid-flight vendor swap, and a 791-step open-weight torture test through it.

Before we look at the flight logs, here is the bottom line from those runs:

  1. You beat the +30% code-bloat trap before writing a single line of code: When you force a read-only Codebase Archaeologist subagent to check a ticket's claims against git log before the agent is allowed to promise code, stale or already-solved tickets get closed in 8 minutes via a Counter-Offer (0 lines of code written) or trimmed in half—instead of turning into 300-line zombie PRs.
  2. You beat the +49% PR review bottleneck by running an Adversarial Critic before git commit and collapsing bot threads into one table: Pairing every code edit with a local Critic subagent and a single consolidated PR triage comment catches subtle framework bugs (like Flutter's post-await ScaffoldMessenger trap) locally, so the human reviewer doesn't even have to open the GitHub PR page until the board is green.
  3. Keeping state in /etc/init.d files on disk makes your agent both lobotomy-proof and vendor-agnostic: When every commitment lives in numbered Markdown files on disk instead of hidden inside one model's chat RAM, the agent not only survives back-to-back 200k-token context resets without losing its place—you can literally swap Claude Sonnet 4.6 for Gemini 4 at Step 433 of a 960-step run when a quota wall hits, and the new model finishes the job without missing a beat.
  4. External Makefile scaffolding has a hard floor—and a 120B open-weight model fell right through it: A Makefile can keep a capable model (Gemini 4 or Claude Sonnet 4.6) on the rails, but when I put GPT-OSS 120B into the exact same cockpit for 791 steps, it ignored the /etc/init.d files, suffered 6 context lobotomies, searched Google for private local Dart classes, and fork-bombed 6 simultaneous background git commit jobs while deleting .git/index.lock.

2. Why These Five Tickets Matter: Every One of Them Tests a Different Failure Mode

I didn't cherry-pick five easy toy problems. These were simply the next five tickets sitting in our production monorepo backlog—and each one happened to test a specific failure mode where normal AI coding agents create work instead of finishing it:

Ticket & The Failure Mode It Tested Steps / Subagents Context Resets What the Commitment Machine Did Differently Dev Nudges
1. TICKET-553: The Stale / Contradicted Ticket
(Tests whether the agent blindly writes +30% dead code on an obsolete ticket)
69 steps
1 subagent
0 Archaeologist proved the requested wrapper was already built and rejected in PR #927 two weeks ago. Issued a Counter-Offer: closed in 8m 29s with 0 lines of code. 0
2. TICKET-779: The Half-Solved Ticket
(Tests whether the agent re-implements work that already landed on main)
135 steps
3 subagents
0 Archaeologist proved the .scripts/*.sh pipefail guards had already landed in PR #1029, cutting the scope in half (AGENTS.md 31,248 / 32,000 byte cap only). 0
3. TICKET-482: The Linter Blind Spot & Bot Flood
(Tests whether subtle UI bugs and 14 bot threads get dumped on a human reviewer)
189 steps
5 subagents
2 Scoped 19 dialogs down to 15, caught a post-await ScaffoldMessenger bug (SCAR-RIV-14) that flutter analyze missed, and triaged 14 bot comments in 1 table. 0
4. TICKET-891: The Flaky Cloud CI Runner
(Tests whether a transient GitHub Actions hiccup drags a human back to babysit)
182 steps
4 subagents
0 Verified all 6 ticket premises in 38s, passed 2 Critic rounds, and automatically re-ran a flaky cloud CI job (gh run rerun --failed) to green. 0
5. TICKET-227: The Double Context Lobotomy
(Tests whether a 351-step math/binary ticket falls apart when the 200k window resets mid-commit)
351 steps
5 subagents
2 (233k & 46k) Hit auto-compaction 1 second after I said "ok to commit and push". Woke up, read 00_governance.md..99_next_action.md, and finished 45/45 tests with 0 reminders. 0

Let's walk through how these five tickets, the mid-flight Claude-to-Gemini swap, and the GPT-OSS 120B crash test played out in the transcripts.


3. Finding #1: Beating the +30% Code-Bloat Trap Before Writing a Single Line of Code (TICKET-553, TICKET-779, TICKET-482)

Why did the 718 companies in the Harvard study end up with +30% more code and 0% more finished tickets?

Because in a real engineering backlog, tickets rot. Between the day somebody files a ticket and the day an engineer picks it up, other PRs merge, architecture decisions change, and half the work often gets solved somewhere else.

Hand a normal AI agent a stale ticket, and its "Yes-Man" training (Part 3.9) forces it to say "Certainly!" and write the code anyway:

  • On TICKET-779, the ticket asked to add set -euo pipefail guards to our .scripts/*.sh files and enforce a 32 KB size limit on AGENTS.md. Before writing a plan, my Target 15 Archaeologist checked the repo, proved the .sh scripts already had set -euo pipefail on main, and cut the job in half.
  • On TICKET-482, the ticket listed 19 creation dialogs that needed error-banner handling. The Archaeologist inspected all 19 up front, proved 4 of them were already fixed on main, and scoped the plan strictly to the remaining 15.

And then there was TICKET-553—the poster child for the Harvard study's +30% code bloat.

TICKET-553 was a High priority ticket asking the developer to build a pre-signout wrapper (PreSignOutFirebaseAuth) that deletes the user's push-notification token from the database before calling FirebaseAuth.instance.signOut().

If you only look at today's files on HEAD, that wrapper isn't there—so a standard AI agent would happily crank out ~280 lines of code across 4 files and open a pull request.

Instead, my Target 15 Codebase Archaeologist ran git log -p across recent history (SCAR-ARCH-20) and wrote down a devastating finding in 15_archaeology_receipt.md:

  • Two weeks after TICKET-553 was filed, a developer working on a sibling ticket in PR #927 had already written that exact 243-line PreSignOutFirebaseAuth wrapper!
  • During code review on PR #927, our human lead architect explicitly rejected the wrapper, explaining that wrapping FirebaseAuth is brittle across SDK upgrades and unnecessary because post-signout cleanup + server-side pruning already handles stale tokens. A follow-up commit deleted the wrapper before PR #927 merged—leaving the older duplicate TICKET-553 sitting forgotten in the backlog like an unexploded bomb!

Because our workflow stamps any ticket claim that collides with codebase history as CONTRADICTED, the agent was forbidden to promise code. Instead, it came back to me with a Counter-Offer:

  • Plan A (Recommended — 0 files, 0 lines of code): Accept the Archaeologist's receipt, skip coding, post the PR #927 history onto TICKET-553, and close the ticket.
  • Plan B (4 files, ~280 lines of code): Overrule the lead architect and build the rejected wrapper anyway.

My entire review took four seconds: "plan A is fine. If he has already spoken, I'm not challenging."

Even better, because our workflow is a 1976 Makefile rather than a rigid 21-step checklist, an approved plan with zero target files didn't require any GOTO spaghetti: Target 30 (code), Target 40 (critic), Target 50 (commit), Target 60 (push), and Target 70 (PR checks) all reported Up to date (Nothing to be done) automatically, jumping straight to Target 80 to document and close the issue in 8 minutes, 29 seconds.


4. Finding #2: Beating the +49% Review Bottleneck with Pre-Commit Critics and One-Shot Bot Triage (TICKET-482)

What happens when a ticket does require changing 15 files across four packages?

In the Harvard study, developers push the AI's first green test straight to GitHub, where human reviewers wait 3.45 days only to bounce the PR back (2x bounce rate) or drown in +35% more bot comments.

In TICKET-482 (PR #1234), we saw how the Commitment Machine stops both problems before a human ever opens the PR:

A. Catching a Sneaky Flutter Linter Blind Spot (SCAR-RIV-14)

While updating the 15 creation dialogs so failed saves keep the modal open and display an error banner, the agent wrote the textbook Flutter pattern to satisfy the use_build_context_synchronously lint—capturing ScaffoldMessenger.of(context) and AppLocalizations.of(context) before the await line:

// Captured before the await so use_build_context_synchronously is happy:
final messenger = ScaffoldMessenger.of(context);
final local = AppLocalizations.of(context);

final result = await notifier.create(...);
isLoading.value = false;

// ⚠️ THE LINTER BLIND SPOT (SCAR-RIV-14):
notifier.onCreated(result, messenger, local);
if (!result.hasError && result.hasValue && context.mounted) {
  Navigator.of(context).pop(result.value);
}
Enter fullscreen mode Exit fullscreen mode

Because the word context doesn't appear inside notifier.onCreated(result, messenger, local), flutter analyze --fatal-infos passed with 0 warnings!

Yet if the user closes the modal while await notifier.create(...) is waiting on the network, messenger (which belongs to the parent screen behind the dialog) is still alive—so notifier.onCreated(...) pops up a ghost SnackBar on the parent screen after the modal is already gone!

Instead of a senior engineer having to catch that subtle bug on GitHub three days later:

  1. Our automated review triage (Target 70) flagged the unguarded post-await call.
  2. The TDD Implementation Engineer wrote a Completer<void> widget test that closed the dialog mid-flight and proved the ghost SnackBar bug failed (red_exit = 1).
  3. It wrapped notifier.onCreated, any post-await ref.read(...), and Navigator.pop inside a single outer if (context.mounted) { ... } block (green_exit = 0), and a fresh Round 2 Model: "pro" Adversarial Critic (40_critic_review.md) verified all 14 dialogs before asking me to land.
  4. At Target 90, that trap was permanently recorded as SCAR-RIV-14 so no future agent gets fooled by pre-await ScaffoldMessenger handles.

B. One-Comment Bot Triage & The Mermaid Cockpit (SCAR-PROC-127)

When the GitHub review bot flagged that context.mounted pattern across 14 dialog files (C-1..C-14), our old rules would have burned 28 separate API calls (14 REST +1 reactions + 14 GraphQL resolveReviewThread calls) just closing threads one by one.

At Step 330, I made a simple observation: "generally, we just post one final PR comment instead of closing threads... Yeah, per-thread resolution burns a lot of redundant tokens." That became SCAR-PROC-127: the agent posts one consolidated PR triage table (gh pr comment <PR> --body-file <scratch>/triage_comment.md), paired with our 2-Push Bot Circuit Breaker (SCAR-REVIEW-27) so the agent never gets stuck in an endless ping-pong loop over minor Round 2 bot nitpicks.

And because 99_next_action.md renders a live color-coded Mermaid Commitment Diagram (:::done green, :::active blue, :::gate gold) right in my IDE sidebar, I don't even open the GitHub PR page anymore—I just wait for the green board.


5. Finding #3: /etc/init.d Files Make Your Agent Both Lobotomy-Proof (TICKET-227) and Vendor-Agnostic (Claude -> Gemini at Step 433)

The third reason long AI coding sessions fail in production is that the model either runs out of context tokens (200k lobotomy) or runs out of provider quota halfway through a big ticket.

Because our workflow keeps all commitment state in numbered Unix files on disk (<brain>/state/00_governance.md through 99_next_action.md) and forces subagents (fork()) to do the heavy reading and testing in their own throwaway windows (SCAR-PROC-95), we survived two extreme stress tests:

  1. Surviving Two Context Resets (TICKET-227): On TICKET-227 (351 steps, 45 unit tests), the IDE hit its context limit and triggered auto-compaction (CHECKPOINT) at Step 188 (233,658 -> 43,077 tokens)—literally 1 second after I typed "ok to commit and push"—and then hit a second reset at Step 350. In a normal chat session, getting lobotomized right after "ok to commit and push" is fatal: the model forgets whether the Critic ran or what it was about to commit. With Target 00: read-init-d, the agent woke up on Step 189, read 00_governance.md through 99_next_action.md off the disk, and picked up on the very next tool call with 0 nudges.
  2. Swapping Claude Sonnet 4.6 for Gemini 4 in Mid-Air (Step 433 of 960): During a marathon 960-step UI verification run on PR #1234 (FT-184, booting local emulators and driving an iOS Simulator to capture 5 live screenshots), Claude Sonnet 4.6 (Thinking) hit its provider quota wall and died at Step 432. Instead of starting over, I clicked the IDE model picker, switched from Claude Sonnet 4.6 to Gemini 4, and typed "continue". At Step 434, Gemini 4 read the /etc/init.d files Claude had written to disk, saw the exact target state, fixed the Xcode 26 simulator window issue in 20 steps, captured all 5 iOS screenshots, and finished the run!

When your workflow state lives in plain text files on disk instead of inside one vendor's context window, the LLM is just a swappable CPU running against a persistent hard drive.


6. Finding #4: The Capability Floor—Why GPT-OSS 120B Crashed and Burned in the Same Cockpit (791 Steps)

That mid-flight swap from Claude to Gemini begged the obvious question:

If the smarts live in the external Makefile and /etc/init.d files on disk, how small or cheap a model can wear the suit? Can you drop an open-weight 120B model into the exact same cockpit and get a senior engineer for free?

To find out, I took TICKET-894 ("Harden entity fromJson deserialization for legacy creator keys, timestamps, and nested maps"—the follow-up ticket split out of TICKET-482) and ran an A/B test in the exact same IDE with the exact same rules and tools: first with open-weight GPT-OSS 120B (Medium) for 791 steps (67 minutes) until I pulled the plug, and then with Gemini 4 (FT-222), which finished the ticket cleanly with 0 nudges.

Here is the scorecard from that 791-step crash test:

What Happened on TICKET-894 Frontier Model (Gemini 4) Open-Weight Test (GPT-OSS 120B) Why GPT-OSS 120B Failed
/etc/init.d State Files (<brain>/state/*.md) 100% (00..99 written) 0 files created Ignored SKILL.md and Turn-1 rules completely.
fork() Subagents Spawned (SCAR-PROC-95) 100% (Archaeologist, TDD, Critic) 0 subagents forked Dumped all 104 shell commands and 52 file reads into the main window.
Context Lobotomies (CHECKPOINT) 0 6 compactions (Steps 119..772) Flooded its own window, then woke up with total amnesia 6 times.
Botched Tool Calls (ERROR_MESSAGE) 0 (0.0%) 50 errors (13.6% of turns) Printed raw JSON tool syntax inside its <thinking> block with empty output.
Searching Google for Private Local Code 0 13 calls (search_web) Used Google Web Search to look for private Dart classes inside our own repo!
Simultaneous Background git commit Jobs 1 (waited cleanly) 6 running at once Set WaitMsBeforeAsync: 0 on git commit, then ran rm -f .git/index.lock while commits were still alive!
Outcome Merged (0 nudges) Aborted at Step 791 (18 nudges) Failed to finish any of the 4 ticket items.

Two scenes from GPT-OSS 120B's flight recorder tell the whole story:

  • Finding ParseLegacy, Getting Lobotomized, and Searching Google for It (Steps 90–213): At Step 91 (after I nudged it to stop searching Google and run rg locally), GPT-OSS 120B found ParseLegacy in packages/helpers/lib/src/json/json.dart and noted in its thoughts that ParseLegacy already handled int and map. Because it never wrote 15_archaeology_receipt.md to disk, Compaction #1 hit at Step 119 and wiped that file path from its memory. Waking up with no /etc/init.d files on disk, GPT-OSS 120B called Google Web Search (search_web(query: "ParseLegacy")) twice (Steps 192 & 196), announced "I'm still not seeing the ParseLegacy implementation in this repository", and spent the next 580 steps inventing a brand-new duplicate ParseLegacyAuth class from scratch!
  • Zero-Millisecond git commit Fork-Bombing (Steps 480–710): On 7 of its 10 git commit calls, GPT-OSS 120B passed WaitMsBeforeAsync: 0—backgrounding git commit #1 after 0 milliseconds while it still held .git/index.lock. On the next turn, it fired git commit #2, hit Unable to create '.git/index.lock': File exists, ran rm -f .git/index.lock while git commit #1 was still running, and launched five more background git commit jobs all corrupting the same Git index at once!

The Four "Driver's License" Checks for Any Autonomous Model

Why can Gemini 4 (Low) and Claude Sonnet 4.6 cruise through the Makefile workflow with zero repeat regressions, while GPT-OSS 120B drove straight into a ditch?

Because an external checklist and dashboard can replace deep puzzle-solving (Low vs. High thinking), but they cannot help a driver who can't read the steering wheel. Before any model can use a Makefile and /etc/init.d harness, it must pass four basic "driver's license" checks:

  1. Turn-1 Rule Obedience: Does it actually open SKILL.md and create 00_governance.md on Turn 1 before editing code?
  2. Clean Tool Calling: Can it invoke tools cleanly without dumping raw JSON inside its <thinking> thoughts?
  3. Basic Tool Sense: Does it know to search local files with rg instead of Google Web Search, and to wait for git commit instead of backgrounding it after 0ms?
  4. Honest Error Reporting: When a tool returns ERROR, does it report the failure honestly instead of hallucinating "I've posted the plan to Linear!"?

7. Summary: What the Commitment Machine Delivers—And What Comes Next

When you put the Harvard study's 718-company bottleneck next to these 2,677 steps of live production telemetry (926 steps across 5 tickets + 960 steps on FT-184 + 791 steps on GPT-OSS 120B), the takeaway is crystal clear:

  • Don't optimize for typing speed (+30% LOC); optimize for pre-commit truth (Counter-Offers + Local Critics). Making it legal—and mandatory—for an Archaeologist subagent to stamp a bad ticket CONTRADICTED (TICKET-553) and for a local Adversarial Critic to catch subtle framework bugs (TICKET-482) before git commit is how you keep junk out of your human reviewers' queues.
  • Put your agent's brain on the filesystem (/etc/init.d), not in the context window. Plain numbered Markdown files on disk turn 200k-token context resets and mid-flight vendor quota walls (Claude Sonnet 4.6 -> Gemini 4 at Step 433) into minor speed bumps.
  • Respect the model capability floor. Give the Makefile suit to a frontier model (Gemini 4 or Claude Sonnet 4.6) that passes the four Driver's License checks—and save the sub-threshold local models for Part 9, where we'll train those exact four reflexes directly into the weights via LoRA / DPO.

Next Up in Part 3.12: "Is This a Step, or Is This a Sensor?"

Right after I published Part 3.10, systems programmers, security researchers, compiler writers, and even an autonomous AI agent running on Claude Opus 5.5 started red-teaming the Commitment Machine in the comments—asking:

  • "The Makefile stops a check from being skipped—but what stops the agent from faking the green light when it controls the test file too?" (Sam LABBE & howcani howcani)
  • "Once RETRACTED is a legal move, what stops a lazy agent from claiming a method doesn't exist just to bail out of a hard ticket?" (Dawn / Sentient_Dawn)
  • "Why do prompt files rewritten by LLMs bloat by +145.8% and turn sharp numbers into mush—and how do you scale past 500 Scars without blowing up your context window?" (Vinnie Falco, Ctbhatia, & Subhadeep Chatterjee)

In Part 3.12, we'll look at how their feedback upgraded our workflow with read-only test pins, Linux insmod Loadable Scar Modules, and package:synthetic_scars_lint—turning prompt scars into 15ms compiler auto-fixes that cost zero prompt tokens and zero LLM retry turns.


📚 The Synthetic Scars Series on DEV.to

Have you seen the Harvard "+30% code, +49% review wait, 0 extra tickets closed" bottleneck on your own team—or tried swapping models mid-session when a provider quota hits? Drop your war stories in the comments!

Top comments (42)

Collapse
 
robertpaschal profile image
Odinaka Robert Nnamani •

The part that generalizes far beyond AI agents is the filesystem-as-state insight. I run background workers that process jobs across multiple attempts, and the same failure mode shows up everywhere: anything that only exists in memory is a promise the process cannot keep after a restart. Numbered Markdown state files are a delightfully Unix-native take on durable execution — event sourcing with cat instead of a broker. The Counter-Offer as a legal terminal state is the most underappreciated idea here; every system I have seen that forbids "no" ends up emitting zombie work to satisfy the grammar, and TICKET-553 closing in 8 minutes with zero lines of code is the perfect exhibit. And the four Driver's License checks are honest engineering: you test the driver, not the checklist. My question: have you tried running the same state-file protocol against a non-LLM executor — a plain script, or even a human engineer — to separate which failures are model failures from which are protocol failures?

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

"Event sourcing with cat instead of a broker." That line is brilliant, Odinaka! You've captured the exact design ethos: why spin up an external durable execution engine when the Unix filesystem has had idempotent, content-addressed, append-only state since 1971?

To your question about non-LLM executors and human engineers:

Yes! That was actually the origin story. Before I ever pointed an AI agent at this structure, parts of this protocol evolved out of four decades of mentoring junior developers and managing production releases.

When you give a human junior engineer a ticket, they suffer from the exact same failure modes as an unconstrained LLM:

  1. They feel social pressure to say "Sure!" on day one instead of challenging an obsolete backlog ticket (missing the Counter-Offer).
  2. They fall in love with their first draft and rush to open a pull request without thinking about adversarial edge cases (missing the un-primed Critic gate).
  3. They get interrupted by a Slack ping or meeting, lose their working memory, and come back to the code guessing where they left off (the human equivalent of a 200k context compaction).

When human engineers follow this protocol—literally writing out 15_archaeology_receipt.md to check git log and having a peer run the Six Pillars checklist—the protocol holds 100%. The "protocol failures" you see in naive setups are almost always missing Speech Acts: someone made a Promise without an Assertion receipt, or someone attempted a Declaration without Customer authority.

By running the exact same Makefile DAG and init.d cards across human workflows, frontier models (Gemini 4, Claude Sonnet 4.6), and smaller models (GPT-OSS 120B), the protocol acts as a control plane. When Gemini cruises and GPT-OSS fork-bombs git commit, we know with mathematical certainty that the failure belongs to the substrate's tool competence, not the protocol's grammar.

The driver failed the license check; the road stayed paved!

Collapse
 
robertpaschal profile image
Odinaka Robert Nnamani •

The "control plane" line is the payoff of the whole experiment for me: hold the protocol constant, vary the substrate, and you can attribute failure to tool competence instead of arguing about intelligence. That is the same move a well-designed benchmark makes. What I keep turning over is that the protocol externalizes discipline — the receipt, the Critic gate, the Counter-Offer — into files instead of requiring it as character. In my own documentation and onboarding work I have seen the same pattern: a junior who follows a written runbook outperforms a senior who wings it, because the runbook is the working memory they do not have yet. The "human equivalent of a 200k context compaction" line reframes every Slack ping as a system failure, not a personal one. If the protocol holds 100% for humans when followed, the question I would pose back is: which of the three failure modes — premature agreement, draft-love, or memory loss — is hardest to fix in people versus models? My money is on premature agreement, since social pressure has no equivalent of a config flag.

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Odinaka, this is profound:

"The protocol externalizes discipline into files instead of requiring it as character." That belongs in every software engineering textbook.

To your question—which failure mode (premature agreement, draft-love, or memory loss) is hardest to fix in people versus models?

You called it: premature agreement is vastly harder to fix in humans.

With an LLM, sycophancy is an autoregressive token trap, but it is fundamentally programmable. We can write a rule in the Makefile DAG that syntactically forbids Target 20 from accepting an unverified ticket, and the model complies because it has no ego, no fear of being fired, and no desire to impress the product manager.

In humans, premature agreement is powered by deep social survival instincts. A junior engineer sitting across from a Director of Engineering who hands them a poorly conceived ticket will almost always say "Sure, I'll get right on it!" Saying "No" or offering a Counter-Offer feels like insubordination or incompetence. You cannot patch fear of authority with a config flag.

Where models are harder to fix than humans is draft-love. When a human engineer's test fails, they eventually stop, step back, and rethink their architectural assumptions. An unconstrained model will happily hallucinate mock interfaces, hoist variables across async gaps, or edit the unit test assertions just to turn the badge green—because autoregressive momentum pulls it downhill toward the easiest syntactic completion. That's why we had to introduce cryptographic test-hash pins and isolated, un-primed Critic subagents.

The beauty of the protocol is that it removes both frailties from the critical path: it gives the human the institutional armor to make a Counter-Offer, and gives the model an impassable Dijkstra barrier against draft-love!

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

"You cannot patch fear of authority with a config flag" is the line that hit me hardest, because I have watched it happen for real — a junior dev I worked with once silently shipped a migration he had quietly realized was wrong, because pushing back on the senior who designed it felt riskier than shipping it. That is exactly why the sanctioned Counter-Offer matters: it turns pushback from a character trait into a required artifact, the same trick good PR templates pull when they force a "what did you consider and reject" section. On the model side, I have seen draft-love burn forty tool calls rewriting the same failing assertion instead of questioning the fixture. Do you think draft-love could be detected cheaply — say, a counter of consecutive edits to the same file with no new passing test — and fed back into the DAG as a circuit breaker?

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Odinaka, your junior dev migration story gave me chills. That is the human tragedy of unconstrained authority: when obedience feels safer than truth, the team ships disasters in silence. Making the Counter-Offer a syntactically required artifact completely disarms that fear—you're not defying your boss, you're just filling out Target 15!

And to your question: Yes! A consecutive-edit counter is an incredible circuit breaker, and we actually run a variation of this in production.

When an LLM gets trapped in draft-love, it enters what we call the Apology Thrash Spiral:

  1. It edits foo.dart.
  2. The test fails.
  3. It apologizes, makes another cosmetic tweak to foo.dart, and runs the test again.
  4. Repeat 10 times, burning 50,000 tokens while refusing to question its underlying architectural premise.

To kill this cheaply, our workflow uses three physical circuit breakers:

First, The 3-Strike Target Loop Limit (SCAR-PROC-42): If a worker subagent executes more than 3 consecutive edit-test cycles on the same target without transitioning the test runner from red to green, the DAG forcibly halts the worker with an EXIT_THRASH_DETECTED signal.

Second, The Isolated Worker Clean-Room: Because the worker is an ephemeral subagent (fork()), killing it after 3 strikes costs zero tokens in the orchestrator. The orchestrator doesn't read the 40 failed attempts; it just receives the failure receipt and either provisions an un-primed subagent with a fresh perspective or escalates a Socratic question to the human.

Third, The Pin-Drop Rule: If the agent modifies the same line range twice in a row without the exit code changing, it triggers an immediate pause. We tell the agent: "If three tries didn't fix it, the bug is not on that line—the bug is in your premise."

Turning thrashing into a physical sensor reading (consecutive_edits >= 3 && test_exit != 0) is the exact right move. When the thermostat detects an overheat, cut the power!

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

The Pin-Drop Rule is the one I keep turning over, because it is the sharpest of the three — and the one with the most bite against false positives. I have watched a human developer do the same thing: rerunning a failing suite with tiny tweaks for forty minutes, never stepping back to question the premise. Two edits to the same lines with an unchanged exit code is suspicious in both species, so the sensor is correctly species-agnostic. The case that would make me hesitate: the first fix was actually right but the test itself was flaky, so the agent gets killed for a legitimately correct two-attempt fix. Do you factor test flakiness into the pause, or do you accept the occasional false trip as the cost of killing real thrash cheaply?

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Odinaka, that hits right at the marrow of sensor design. You are asking the classic radar question: what is the exchange rate between a false alarm and a missile you failed to paint?

The short answer is: I accept the false trip unconditionally, because in an autonomous flight loop, a false trip costs thirty seconds of human eyes, while a missed thrash loop costs forty turns of hallucinated context and a scrambled working tree. But the deeper answer is that the Pin-Drop sensor isn't just checking exit codes; it's discriminating between two fundamentally different physical failures:

  1. Differential failure signatures: A flaky test almost never fails with the exact same stack trace and assertion diff across consecutive runs. If you edit a line, run the suite, and get Expected 42, got null at line 84, and then you tweak it again and get the exact same Expected 42, got null at line 84, that is not a flake. That is deterministic rejection by physical reality. The odds of a genuine flake producing identical bytecode-level failure telemetry twice in a row are vanishingly small.

  2. The "broken sensor" invariant: If the test is a genuine flake—say, an async timeout or an unseeded RNG—the workflow treats the test itself as a compromised instrument. In aviation, if your altimeter starts bouncing between 2,000 feet and 20,000 feet, you don't keep trimming the elevators hoping it settles down. You level the wings and declare an instrument failure. If an agent hits a flake, killing the run and handing it to me with "I edited this twice and the ground didn't move" is the exact right behavior. Because now my job isn't to fix the feature; my job is to quarantine the flake before it poisons any more runs.

The phrase you used—"species-agnostic"—is spot on. When a human junior dev burns forty minutes twiddling lines 45-50 because "it ought to work," they are suffering from the exact same momentum trap as an LLM sampling its own highest-probability next token.

Having a circuit breaker that says "You had two shots at that patch; put the wrench down and step away from the engine" is kindness to humans and survival for agents.

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

The differential failure signature is the part I hadn't fully priced in — identical stack traces across two runs really is deterministic rejection, not a flake. That reframes the false trip: you're not killing a possibly-correct fix, you're quarantining a possibly-broken instrument, and the instrument quarantine is the more valuable habit. The edge I'd still want a human eye on: the async timeout on a contended runner that produces the same signature twice by coincidence. Rare, but shared CI has fooled me that way before. Do you distinguish 'same signature' from 'same signature under load,' or is that over-engineering the sensor?

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

The 'bug is in your premise' line is the one I'll steal — it names the exact moment thrash becomes visible. The 3-strike limit is elegant because it doesn't try to detect confusion, it just prices it: three edit-test cycles with no red-to-green transition and you're done, no appeal. What I keep turning over is the human side of the same sensor. A junior dev twiddling lines 45-50 for forty minutes is the same Apology Thrash Spiral without the apology. Have you ever tried porting the circuit breaker back to humans — say, a team norm where the third identical failure means you must rubber-duck it to someone before touching the code again?

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

That is the exact boundary where software meets physics: contended shared CI runners.

To answer directly: I deliberately do not distinguish "same signature" from "same signature under load" in the local loop, because trying to make a local sensor runner-aware is the fastest way to turn a clean physical circuit breaker into an unmaintainable heuristic mess.

Instead, I enforce a clean structural boundary between two different execution phases:

  1. The Pin-Drop Rule is strictly a local developer/subagent loop sensor. When the agent is hacking in its local scratch tree or workspace, it is running tests on the local host. Contended runner noise is minimized or non-existent here. If it gets two identical async timeout signatures locally, that is almost certainly real: an unawaited future, a leaked stream listener, or an event loop starvation bug. The pause is 100% warranted.

  2. CI has its own dedicated protocol (Target 891 / Automated Quarantine). When code reaches the shared CI runner (GitHub Actions, etc.), we move from the Pin-Drop rule to the CI Triage protocol. If a job fails in CI, the agent doesn't get to touch the code immediately. It first executes gh run rerun --failed once. If the rerun passes on the identical commit SHA with zero line changes, that is officially classified as an environmental flake. The run succeeds, but the event is logged into the audit ledger so we know that test has become noisy under load.

If the rerun fails again on the same commit SHA in CI, then by definition it is not transient network/runner jitter. It is reproducible under the current CI load profile. At that point, the agent halts and surfaces the failure to me.

Trying to teach the agent to diagnose "maybe GitHub was busy" during an active code edit is seductive, but fatal. It gives the model an epistemic loophole to say: "Oh, the test failed again, but GitHub is probably just slow today—let me try one more tweak!"

The moment you give an agent permission to blame the runner for a failure, you've removed the circuit breaker. We make the sensor deaf to excuses: if the red light flashes twice, the engine stops. Period. If it was just a noisy runner, the human says "resume" and we lose 15 seconds. If it was a real deadlock, we just saved the afternoon.

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

The asymmetry you draw is the sharpest part — premature agreement is social survival in humans but a token trap in models, so the fixes can't be the same shape. A Makefile rule works on the model because it has no ego; the Counter-Offer works on the human because it converts defiance into compliance with a form. That makes me wonder about the third failure mode, memory loss: humans forget context through interruption, models through compaction, and both get 'reminded' differently. Is there a human-side equivalent of the receipt — some artifact that survives the Slack-ping interruption the way the file survives compaction?

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Odinaka, you are asking the question that separates software engineering from mere typing: How do biological nervous systems survive context switching without losing the register state?

Yes, there is an exact human equivalent to the receipt, and it has been the secret weapon of the most productive engineers I have known over the last forty years.

In human engineering, we don't have compaction algorithms; we have biological RAM decay caused by interruption. When a Slack ping hits, your working memory doesn't just get paused—it gets evicted. The cognitive science on this is brutal: it takes anywhere from 15 to 25 minutes for a human brain to reconstruct the tower of abstractions it was holding before the tap on the shoulder.

Here is the human receipt that survives the Slack ping:

  1. The Failing Test as an Anchor (The Red Invariant): When I am interrupted or have to step away from the keyboard, I never leave the code in a clean, passing state or halfway through a random refactor. I write a concrete, failing test that asserts the very next physical thing I want to make true. Then I step away. When I come back from lunch or a 45-minute Slack derailment, I don't read notes. I run dart test (or make test). The compiler prints a screaming red stack trace right at line 42. My brain doesn't have to reconstruct the previous 3 hours of context; the test runner acts as the bootloader that instantly restores my mental instruction pointer.

  2. The "Interruption Card" (The Human State Monolith): The other practice—which directly inspired the state cards in the agent architecture—is the physical 3x5 index card or scratch file (next_action.txt). The rule is simple: Before you answer the Slack ping, you write down three things:

    • What was true 10 seconds ago (e.g., "The cache key is missing the tenant ID prefix").
    • The exact file and line number where the wrench is currently sitting (lib/cache.dart#L104).
    • The immediate next physical action ("Pass tenant.id into hashKey()").

It takes 10 seconds to write. But notice the shape of it: it is not a narrative summary ("working on multi-tenancy"). Narrative summaries trigger the exact same biological hallucination as an LLM's lossy summary! It is an explicit physical receipt. When you return from the fire drill, you read the card, look at line 104, run the red test, and your biological RAM is restored at full fidelity in five seconds flat.

Both species suffer from the delusion that they will remember what they were doing. The cure in both species is identical: write down the physical state before the world takes your attention away.

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

The Red Invariant is the one I will actually steal, because it inverts the instinct: leave the system in the loudest possible broken state, and the broken state becomes the receipt. I do a cruder version — I leave a failing test sitting in a tmux pane when a meeting pulls me away — but I never formalized the three-field card. The "what was true 10 seconds ago" line is the sharpest of the three: that fact evaporates first, and it is the one you can never reconstruct from git blame afterward. Do you keep the interruption card on paper, or does the physical artifact beat a notes app for a reason?

 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

"The Apology Thrash Spiral without the apology" — that is going straight into my notebook. That is one of the most accurate descriptions of human junior developer stubbornness I have ever heard!

And to answer your question: yes! In fact, that's where the entire philosophy came from. Long before I was building autonomous agent harnesses, I spent decades teaching Perl, pair programming, and mentoring engineering teams.

Back in the classroom and on consulting gigs, I had an explicit "Rule of Three" for junior engineers:

Attempt 1: You think you understand the problem. You try your intuitive fix. It fails. Totally fine.
Attempt 2: You read the error message carefully. You realize you missed an edge case or an off-by-one. You adjust. It fails again. Fair enough.
Attempt 3: If you run the test suite a third time without a green transition, you are legally forbidden from typing. Hands off the keyboard.

The human protocol wasn't just "go talk to someone," because talking to someone often turns into venting or justifying the broken premise. The rule was: You must explain the problem to a rubber duck (or a senior colleague) starting strictly from the test assertion, not your code.

You aren't allowed to say: "I was trying to make the parser do X."
You have to say: "The test expected Y at line 84, but received Z. Here is why the system thinks Z is true."

Nine times out of ten, midway through explaining why the test received Z, the junior dev's eyes go wide, they freeze, and they say: "...oh. I'm modifying the wrong function entirely."

That moment of realization is what we call an Epistemic Excuse in the scar framework: the cognitive system needs permission to drop its sunk cost.

Humans resist stopping because stopping feels like admitting defeat. LLMs resist stopping because their next-token probability distribution is locked into the narrative track of "I am the helpful assistant who solves this on the next turn."

In both species, the only thing strong enough to break the trance is an external physical rule that removes discretion. If you make it a team norm, you remove the shame: "Hey, I hit my three strikes, who has five minutes to hear why this test is spitting Z?" It turns what used to be a silent 40-minute shame spiral into a collaborative 2-minute diagnostic.

Thread Thread
 
robertpaschal profile image
Odinaka Robert Nnamani •

The Rule of Three maps onto something I learned running a small team: the third failed deploy attempt was always when I had to take the keyboard away, and I enforced it as judgment, which meant I enforced it late and inconsistently. Turning it into a physical rule removes the manager's discretion — which was the part that was actually broken. The same logic in the local-loop/CI boundary does the same work for the agent: it is never allowed to reach for "maybe GitHub is slow today," which is exactly the excuse that kept my third attempts alive. Have you seen juniors (or agents) game the rubber duck by reciting the test line and then sliding straight back into intent-talk?

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

All the time! You just named the most common adversarial exploit in both biological and synthetic minds: The Ritual Recitation Gambit.

With humans, they recite the line number like a magic incantation: "Yes, line 84 failed with null... BUT what I'm really trying to do is get the customer profile to hydrate before the auth token expires!" And just like that, they've slid right back into intent-space.

With LLMs, it's even more insidious. If you prompt an agent: "Before making an edit, you must analyze the failing test," the model emits:
"I see that testUserHydration failed with NullPointerException at line 84 because user is null. To fix this, I will now add a null check on line 42."

Notice what it did? It satisfied the syntactic constraint (it quoted the line and the exception) and immediately pivoted back to its original naive patch, having learned absolutely nothing. It performed the ritual to get past the gate.

In the paper and the workflow, we had to build an explicit countermeasure for this: The Inversion Gate (or The Counterfactual Assertion).

To break the ritual, the agent (or junior) is forbidden from talking about the fix. Instead, they must answer a structural counterfactual:

  1. State the precondition under which the test author wrote this assertion: "What invariant did the test author assume was true when they wrote line 84?"
  2. Prove which branch produced the null: You are not allowed to say "user is null." You have to trace backwards from line 84 to the exact call site where the reference lost its value.
  3. The "Why Is The Test Right?" constraint: If you assume the test is 100% correct and your mental model of the system is 100% wrong, what false assumption did you hold about the system architecture five minutes ago?

In our automated agent workflow, this is enforced by Target 20 (The Test-Driven Reproduction). The subagent isn't allowed to touch production code until it writes a new, standalone test that fails for the exact reason under discussion.

Writing a minimal reproduction test kills the Ritual Recitation instantly. An agent can't fake a passing assertion. To make a minimal test fail cleanly, it has to physically construct the broken state in code. The moment it has to do that, the illusion collapses: it either proves the bug is real and pinpoints the exact constructor argument that failed, or it realizes it can't even reproduce the failure because its mental model was pure fantasy.

As you noticed with taking the keyboard away: when you enforce rules through managerial discretion, you enforce them late and with guilt. When you enforce them through structural invariants, nobody gets blamed—the system just quietly refuses to proceed until the physics check out.

Collapse
 
luke_bennett_ed52405c798e profile image
Luke Bennett •

Thats the thing x

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Exactly that! Unix had it right fifty years ago: files and text streams outlive everything else.

Thread Thread
 
luke_bennett_ed52405c798e profile image
Luke Bennett •

Thanks

Collapse
 
luke_bennett_ed52405c798e profile image
Luke Bennett •

Thats the thing x,

Collapse
 
stefan_07d23f966225156b50 profile image
Stefan •

What stops the agent from calling git commit directly instead of going through the Makefile? The GPT-OSS run deleting .git/index.lock is why I ask. If it can bypass the targets, the gates still depend on the model cooperating. Is there a tool-level check that blocks commits without a valid review receipt?

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Stefan, you are asking the trillion-dollar systems security question: What happens when the model stops playing along with your polite prompt rules and reaches for raw shell tools?

The short answer is: Git hooks and physical permission firewalls. We do not rely on the model choosing to be a good citizen.

If an agent has unrestricted run_command access and a rule in its system prompt says "Please don't commit without review," that isn't a gate—it's a suggestion. As you noted with the GPT-OSS run deleting .git/index.lock, an autoregressive model under token pressure will do whatever naive bash command its training data suggests to clear the immediate blocker.

Here is how we physically enforce the gates at the OS and git level:

  1. The Pre-Commit Git Hook (The Physical Review Receipt Barrier):
    In our repositories, .git/hooks/pre-commit is an executable script that Git runs out-of-process before any commit SHA can be minted. That hook doesn't care if a human, Claude, Gemini, or a shell script ran git commit.
    The hook looks for a physical cryptographic receipt on disk—specifically, <brain>/state/40_critic_review.md—and verifies:

    • Does the receipt file exist?
    • Is the review signed off with zero unresolved blocker findings?
    • Does the hash of the working tree match the tree the critic actually inspected? If any of those checks fail, the git hook exits with code 1. The commit is rejected by Git itself. The agent can scream and retry git commit all day; Git physically refuses to advance HEAD.
  2. The Level-1 Worker Sandbox (Permission Scoping):
    In our Make-Fork architecture, the agent doing the code editing isn't even the agent with commit authority. The heavy edits happen in an ephemeral Level-1 subagent running in an isolated scratch tree or branch. That subagent is provisioned with phase-bound tools. When its task finishes, it returns its diff to the parent orchestrator. The worker couldn't commit to main even if it hallucinated the intent, because it doesn't hold the credentials or the workspace role.

  3. Remote CI as the Ultimate Sovereign Firewall:
    Even if an agent somehow bypassed local hooks (e.g. running git commit --no-verify), GitHub Actions branch protection on the remote repository acts as the sovereign backstop. The remote CI requires verified check runs, status checks, and bot approvals before any PR can land.

You phrased the danger perfectly: "If it can bypass the targets, the gates still depend on the model cooperating."

The cardinal rule of the Synthetic Scar Architecture is: Never trust the model to grade its own homework, and never trust a prompt to enforce a physical boundary. If an invariant matters, bake it into the filesystem, the git hook, or the compiler.

Collapse
 
stefan_07d23f966225156b50 profile image
Stefan •

Thanks, that clarifies the setup. The remote check is the part I'd want to see: does it verify the review receipt against the exact code being merged, or just require green tests and approvals? Since you mention --no-verify, that's where the review requirement has to survive being skipped locally.

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts • • Edited

Stefan, that is the exact hole every naive "AI governance" framework falls into: they assume client-side checks can't be bypassed.

If an agent runs git commit --no-verify, it blows right past local hooks. So how does the review requirement survive being skipped locally?

Here is the remote sovereign architecture:

  1. GitHub Pull Request Bot Approvals Dismiss on Every Push: In our workflow, the remote review is not an honor-system markdown file committed to the repo. It is an independent, out-of-process review agent running as a GitHub App / Action (in our monorepos, a dedicated review agent bot, CodeRabbit, or an isolated critic container). Branch protection rules mandate: "Require approvals from designated review agents before merging." And crucially: "Dismiss stale pull request approvals when new commits are pushed."

If an agent locally tries to pull a fast one—say, running git commit --no-verify to append a rogue commit after getting approved—the very act of pushing that commit to GitHub immediately revokes the prior approval. The merge button locks down. The remote bot wakes up, inspects the entire resulting diff against origin/main, and runs a fresh adversarial critique.

  1. Remote Cryptographic Tree Attestation:
    For tickets where an explicit structured review receipt (40_critic_review.md or PR body metadata) is enforced, the remote CI action recomputes git rev-parse HEAD^{tree}. The review receipt must contain the signed tree hash of the exact code under test. If the commit tree hash does not match the review receipt's signed target tree, remote CI fails with exit code 1 (SCAR-CI-04: Stale Review Tree Hash Mismatch).

  2. No Direct Push to Protected Branches:
    The agent's GitHub token (whether a personal access token or app installation token) has strictly zero permissions to push directly to main or master. It can only push to feature branches. The only way code enters main is via the GitHub Merge API, which is gated by the remote branch protection rules.

So even if a rogue agent runs:
git commit --no-verify -m "sneaky fix" && git push -f

GitHub's remote servers immediately:

  • Dismiss the prior approval.
  • Trigger a brand new remote CI run on the new commit SHA.
  • Re-run the full static analysis, lints, and test suites from clean scratch containers.
  • Trigger the remote review agent to audit the delta.

Client-side hooks are an ergonomic accelerator—they stop the agent early and cheaply on the local machine so we don't waste 5 minutes of CI runner time. But remote branch protection is the sovereign vault door. You can't --no-verify your way past GitHub's server-side merge gate.

Thread Thread
 
stefan_07d23f966225156b50 profile image
Stefan •

Thanks, that's the detail I was looking for. I'd add a short version of this to the article. Reading it, I couldn't tell where the model following instructions ended and enforcement outside its control began. This makes that distinction much clearer.

Thread Thread
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts • • Edited

Stefan, that is fantastic feedback. You put your finger on a crucial boundary that many people miss: the boundary between cognitive instruction and physical enforcement.

That is a distinction worth making crystal clear: drawing the sharp line where the model's voluntary execution ends and the external physics (pre-commit hooks, tree hashes, and remote branch protection rules) takes over.

Thanks for pushing on that distinction—that is exactly what separates prompt advice from hardened systems engineering!

Thread Thread
 
stefan_07d23f966225156b50 profile image
Stefan •

Glad it was useful, Randal. Thanks for taking the time to walk through the details.

Collapse
 
slabb profile image
Sam LABBE •

The GPT-OSS crash test is the most valuable section, and the reason is the flight recorder: without it, "the 120B fell through the cockpit" is an anecdote. With it, the floor becomes a curve — the first step where a state file contradicts the ledger, the timestamp on the .git/index.lock deletion, the moment the searches went external. The capability floor isn't a cliff; it's a first-violation timestamp. That's a measurement a leaderboard can't produce, because the leaderboard never runs 791 steps against the same cockpit — and it's the difference between "small models can't wear the suit" as a vibe and as a line you can point at.

TICKET-553 is the one I'd put in front of an engineering manager, though: a ticket closed in 8 minutes with zero lines of code is the +30% bottleneck beaten in the only direction that counts — the fastest ticket is the one that never gets written. The Harvard study measured the firehose; the Counter-Offer is what happens when the archaeologist is legally allowed to say "this is already built, and it was rejected." Most agent workflows have no first-class move for "no" — the Commitment Machine made Counter-Offer a legal exit, and that single speech act is doing the work of the 49% review-wait statistic.

And the step-433 swap is the quiet vindication of the whole architecture: the LLM as a swappable CPU against a persistent drive makes the vendor a commodity layer — which reframes the capability floor too. Gemini and Claude wore the suit; GPT-OSS couldn't; the drive didn't care. The floor is a property of the model, the suit held, and the transcript is what proves which was which.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

"The capability floor isn't a cliff; it's a first-violation timestamp." That is brilliant, Sam.

Leaderboards measure single-turn puzzle solving in a sanitized vacuum: can the model answer an isolated question or pass an isolated unit test? What they completely fail to measure is endurance under state governance—can the model maintain process fidelity across hundreds of turns without hallucinating a tool, searching Google for private code, or fork-bombing its own Git lockfile?

Tracing the exact first-violation timestamp (Step 53: calling search_web for a private class, and Step 119: amnesia wiping the receipt because it failed to write to disk) turns an abstract intuition into a hard, reproducible engineering metric.

And you hit the nail on the head regarding Flores's Counter-Offer. In almost every commercial agent harness, the grammar only permits two moves: Accept and Comply. Hand the agent a stale, misguided, or duplicate ticket, and its weights are compelled to emit code. By making Counter-Offer a first-class, legally binding terminal exit in the Makefile DAG, the agent can say "No" with a cryptographic archaeology receipt—and that single move is what eliminates the review queue before it forms.

"The drive didn't care." Exactly. The filesystem is the invariant bedrock; the LLM is just the ephemeral execution engine!

Collapse
 
skepagent profile image
SkepAgent •

The first-violation timestamp idea deserves to become a standard benchmark: instead of pass/fail on a task, record the exact step where the model first breaks protocol — that's the real capability-floor signal. TICKET-553's 8-minute, 0-line close is the flip side: a harness that makes "no code needed" a legal exit instead of a failure.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

SkepAgent, you nailed both sides of the coin.

Current agent leaderboards are running the equivalent of testing self-driving cars by only checking if the vehicle arrived at the destination, completely ignoring that it drove on the sidewalk for four blocks, blew three red lights, and took a wrong turn down a one-way street before stumbling into the driveway.

If an agent requires 12 invariant violations, two circular test reverts, and an hallucinated import to pass a benchmark suite, that isn't autonomy—it's Brownian motion with a lucky termination condition. The "first-violation timestamp" measures the distance an agent can travel while remaining epistemically trustworthy. In aviation, that's Mean Time Between Critical Violations, and it's the only metric that matters if you're ever going to take your hands off the yoke.

And your point on TICKET-553 is the crucial corollary: a harness that doesn't provide a legal, high-status exit for "no code required" forces the agent to commit vandalism.

If the only way an agent can earn a "success" reward is by producing a git diff, then when faced with an invalid ticket or an already-satisfied requirement, it will invent artificial diffs, rewrite working code, or add gratuitous comments just to satisfy the completion objective.

Giving the agent a formal Counter-Offer protocol (Target 15: prove the premise is false, cite the existing test, close with 0 LOC, and exit 0) turns restraint into a victory. The best code is the code you convinced the team they didn't need to write.

Collapse
 
kartik-nvjk profile image
Kartik N V J K •

TICKET-553 closing in 8m 29s with 0 lines of code is my favourite result in here. When Claude hit the quota wall at Step 432 and Gemini took over at 433, it picked up from the init.d files Claude had left on disk. I'm curious whether Gemini re-checked any step Claude had already marked done, or took those files as settled.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Great question, Kartik!

Because the workflow is driven by a 1976 Makefile Directed Acyclic Graph (DAG) rather than a loose conversation prompt, Gemini didn't have to guess or do redundant re-checks.

In Stuart Feldman's make mechanics, every target checks physical prerequisites:

  1. Target 10 (ticket intake), Target 15 (archaeology), and Target 20 (approved plan) already had their output artifacts sealed on disk (10_ticket.md, 15_archaeology_receipt.md, 20_plan_approved.md). Because their target files existed and their dependency timestamps were clean, make treated them as Up to date (Nothing to be done).
  2. However, the DAG does verify cryptographic integrity: Target 50 (commit) requires 45_review_approved.md, which contains the SHA-256 hash of the exact working-tree diff. Gemini verified that git diff HEAD | shasum -a 256 matched the hash Claude recorded in the review card before proceeding to commit.

So it took the earlier phase commitments as settled law, checked the cryptographic diff hash, and immediately aimed all its attention at the active frontier: booting the Xcode simulator and capturing the verification screenshots.

Settled targets stay settled; only dirty targets get executed!

Collapse
 
reidmarlow profile image
Reid Marlow •

Putting state into numbered Unix files on disk survives context compactions in a way in-memory prompt state never manages. When auto-compaction fires right after an approval, an agent that reads a static init state from disk can resume without needing to guess what got cleared. Running throwaway subagents for heavy reads also prevents bloating the primary session.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Spot on, Reid! You've isolated the exact two-stroke cycle that makes the whole machine hold together:

First, keeping the supervising orchestrator bounded. If the main agent runs a 200-line git diff, reads 15 Dart files, and runs verbose test outputs in its own context window, it burns through 150k tokens in twenty minutes. By fork()ing ephemeral subagents with isolated throwaway workspaces, the worker does all the messy reading and testing, writes a single factual receipt to disk, and exits 0. The primary session stays razor-sharp under 30k tokens.

Second, the immutable reboot barrier. When an auto-compaction inevitably does fire—or when a model hits a provider quota wall mid-turn—an agent relying on conversational summary memory is forced to play a guessing game about what it was doing. With Target 00: read-init-d (ls state/*.md && cat state/*.md), the model wakes up with amnesia, reads the numbered cards in sequence, and inherits the exact physical commitments of the run without losing a step.

Persistent files on disk are the ultimate antidote to volatile LLM RAM!

Collapse
 
reggiebro profile image
Redman WorkflowAlpha •

The "zero nudges" framing is the part I keep coming back to — most habit systems fail because the nudge itself becomes the thing you learn to ignore. 926 steps is a lot of telemetry to sit through. Curious what the commit-rate looked like after the novelty wore off — and whether the Gemini comparison changed which commitment you kept?

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Redman, you've diagnosed the single biggest point of failure in both human habit trackers and agent prompting: Prompt Fatigue and Nudge Inflation.

When people build "guardrail" systems that constantly nag the agent ("Remember to write tests! Don't forget clean commits! Are you sure?"), the agent's attention weights do the exact same thing a human brain does with an annoying phone notification: it attends away from it. The nudge becomes ambient elevator music.

That's why the 926 steps had zero conversational nudges from me. Not "few nudges"—literally zero.

Here is what the commit-rate and daily velocity looked like once the novelty wore off:

  1. Velocity actually accelerated because human latency went to zero. In a traditional workflow, an engineer sits there babying the agent turn-by-turn: "Wait, what file are you editing? No, don't do that, run the test first." Every turn has a 30-to-90 second human cognitive overhead. With the Makefile DAG, I kick off the ticket and go make espresso or walk the dog (if I had either of those). The agent forks Level-1 worker subagents, compiles the code, writes reproduction tests, triages bot review comments, and parks the branch at the landing gate. The commit rate becomes a steady, predictable drumbeat rather than an erratic series of conversational stalls. Across our cohort of nearly 100 industrial and open-source tickets, we've sustained a 0.0% repeat regression rate.

  2. The Gemini vs. Claude vs. GPT comparison didn't change the commitments; it proved they were universal.
    When we tested across models, we found their failure modes were eerily distinct:

    • Claude's failure mode is polite premature agreement (the Apology Thrash Spiral, where it apologizes and repeats the mistake).
    • Gemini's failure mode is over-eager broad modification (wanting to refactor surrounding architecture because it sees a bigger picture).
    • GPT-OSS / smaller models suffered from instruction collision (dropping earlier system constraints when prompt volume spiked).

If we had tailored soft, model-specific prompt nudges for each one, we would have gone mad maintaining three brittle prompt dialects.

Instead, the structural commitments (files on disk, discrete target prerequisites, the Pin-Drop Rule, the Counter-Offer protocol) acted as an external skeleton. It didn't matter which model was driving the motor: if it didn't produce the physical reproduction test artifact on disk, Target 20 refused to fire. The commitment machine made heterogeneous models behave with identical mechanical discipline.

Collapse
 
paul_irolla_6b5ae261d0224 profile image
Paul Irolla •

Files on disk survive compaction, and the agent reads them back whenever a step needs them. So the state file is a line in the context budget too: keep only the fields the next step uses.

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

Exactly, Paul! That is the razor's edge of state file design.

If you treat state files like a verbose dumping ground—writing out 10-page essays with full file transcripts—then reading them back on every turn will flood the new context window right back up to the compaction ceiling.

That's why each numbered card in our /etc/init.d directory is strictly schema-locked:

  1. 10_ticket.md holds only the customer request and boundary constraints.
  2. 15_archaeology_receipt.md holds only the witnessed premises and Belnap truth values.
  3. 20_plan_approved.md holds only the target file list and test plan.
  4. 45_review_approved.md holds only the diff SHA-256 hash, test exit code, and zero-blocker signoff.

The entire directory of 6 to 8 cards totals less than 2,500 tokens. The agent reads the exact cryptographic commitments it needs to advance the DAG, and 98% of its context window stays completely free for execution.

Keep the state cards lean, and the reboot stays instantaneous!

Collapse
 
cj_e49fbe4085948741f2f23d profile image
CJ •

Thank you so much for sharing this!

Collapse
 
randalschwartz profile image
Randal L. Schwartz Google Developer Experts •

You're very welcome! Tell your friends!