Rhys Brett-Bowen Coding in the age of AI

How a Team's AI Coding Flow Should Be Wired

updated

Every check needs something to compare against. Which loop asks it, and what answers, is decided by how that thing behaves — and for both of the checks that matter, the right place isn’t the PR.

“Creators need an immediate connection to what they’re creating.” — Bret Victor, Inventing on Principle (CUSEC, January 2012)

Three linked paper loops form a calm sequence while a clay return arc carries the middle loop's output back to the first.

A change lands in review with everything green. The rules pass, the types check, the tests are close to the ones I’d have asked for. I read the diff anyway, and the thing I’m looking for isn’t in it. I’m trying to work out whether this was the change to make — whether it collides with the other work in flight, whether it’s still what we agreed to build, whether the shape it took is the shape the problem wanted. Nothing upstream of me asked any of that. Nothing upstream of me can, because the only place the answer is written down is a plan that stopped being true a week ago, and nobody updated it.

That’s the state of the art, and we’re pouring engineering into the other half.

BLUF: Bottom line up front

  • There are two checks on a change, and they compare it against different things. Call the thing a check compares against its referent. Is the code done right holds the diff against the codebase and the house’s rules. Is it solving the right problem, in the right way holds the work against the plan and against everything else in flight.
  • The two referents behave differently, and that’s what makes this a placement problem. Question 1’s referent sits still, but the thing it judges — the finished change — doesn’t exist until the end, so that check is pinned late by construction. Question 2’s referent is live and moves while you build, and the thing it judges exists from the first prompt, so that check can be asked at every stage and gives a different answer each time.
  • “Shift left” picked the check that can’t move. Most write-time instruments we reach for — linters, hooks, pre-commit, stop burning tokens on LLM review and write custom rules instead — are trying to move the one check that has nothing to run on until the change is finished. Shift the other one.
  • The write-time argument doesn’t survive the change of author. Write-time checks are shaped for a human write loop: a human types character by character, so firing between keystrokes is genuinely earlier and costs nothing. An agent emits in batches. The agent doesn’t consume autocomplete, it is the autocomplete.
  • The flow is three loops with six stations in it, and the second question is askable at five of them. A station is any point in the flow where a check can sit. Plan, generation, review — and review alone is three stations, not one. Each station has a different thing to compare against, which is what decides both whether a check can live there and which instrument can run it. The sixth station is question 1’s only home. Two of the five that take question 2 exist only for a team: nobody’s solo work collides with what the rest of the org is building.
  • A human has a re-entry point in every loop, not an approval click on every iteration. They settle consequential plan choices, return when generation proposes a material change, and check the final claim. Whether a re-entry blocks is team policy, set by reversibility and risk, not by anyone’s preferred workflow.
  • Count the hole honestly. Five of the six stations can take the second question. By instrument I mean something built, that runs on its own, and that belongs to the team — not a habit, not a prompt somebody remembers to use. Three of the five have no instrument at all, one can’t have one, and the fifth is a human doing it last and from memory.
  • The lever nobody’s pulled is shifting the first check right. Let changes land, sweep the codebase instead of the diff, and the check gets what it always wanted: the whole referent, and time. It only works if its output is a fix, not a finding.
  • Build the org reviewer first. It pays at two stations off one build, and its referent is the only one with no human substitute — a reviewer can hold the plan in their head; nobody holds what every other in-flight change is doing.

Two checks, and only one of them can move

Strip a code review down and there are two questions in it. Is the code done right. And is it solving the right problem, in the right way.

They feel like the same activity because they arrive on the same screen at the same time. They aren’t, and the thing that separates them isn’t difficulty or importance. It’s what each one compares against, and when the thing it judges shows up.

Question 1 — done right Question 2 — right problem, right way
Referent — what it compares against the codebase + the house’s rules the plan + everything else in flight
Does the referent hold still? yes — it’s there the whole time no — it moves while you build
The thing being judged arrives only when the change is finished with the first prompt
So the check runs once, late — by construction at every stage, with a different answer each time
Instrument today built a human at the end, reading a diff

Naming the first referent as “the house’s rules” invites the obvious objection: whose house? Different projects here do it differently, so which one is the rule? The answer is that the divergence was never load-bearing. Local idiom exists because whoever wrote the code first set the style and every owner since dragged it a little further toward their own preferences, and the justification for tolerating that was always human — a maintainer had preferences, and making them work in a foreign style cost them real effort. An agent has no preferences to accommodate and conforming costs it nothing. So local idiom is now pure cost with no offsetting benefit, and the referent should be one house, not one per directory. The Other Intent argues the one-person-wrote-it version of this at length; I’m taking it as settled and noting only that it makes question 1 more mechanizable, not less.

Three classes of referent turn up once you start looking for them, and each one dictates where its check can go. A referent that’s fixed and outside the work lets the check run the moment the thing it judges exists — which for question 1 means late, because that thing is the finished change, and no cleverness is available. A referent that’s live and moves while you work wants the check run twice, at both ends, because the two readings answer different questions. A referent that lives only in someone’s head can’t be mechanized at all, so the only lever is putting it where judgment is cheapest to act on.

That third class is where “taste” usually gets invoked, and taste is doing two jobs there. Taste about how code should look shouldn’t exist. If two shapes are both acceptable, that isn’t taste, it’s a missing rule — again, argued at length next door — and once it’s written down it’s a question-1 rule like any other: rule-shaped conformance, checked against an artifact that exists. What’s left when you delete that half is taste about how to solve the problem: is this the right decomposition, does this belong in this service, is the simpler thing available. That half never converts into a rule you can hold a diff against, because it isn’t asking whether the artifact conforms. It’s asking whether this was the right change. That’s question 2.

Which gives the tightening that made me want to write this post: the check that can’t be mechanized and the check we’ve built nothing for are the same check.

So here’s the turn. “Shift left” isn’t wrong because earlier is bad. Larry Smith’s original 2001 argument for it was sound and it’s still sound. It’s wrong because of what we pointed it at. We aimed a decade of tooling at the check that has nothing to run on until the work is done, and left the movable one to a person at the end.

Why “lint it earlier” doesn’t transfer

There’s a live position that you should stop burning tokens on LLM code review and write custom linters instead: deterministic, fast, cheap, and it fires while you write. The economics are unarguable for a human. They don’t transfer, and the reason is the loop, not the model.

A human types character by character. A check that fires between keystrokes is genuinely earlier than one that fires on the finished file, and the loop is close to free — the editor is already open, the eyes are already on the screen, and the response-time budget that tooling is built against came from human perception in the first place. Miller measured it in 1968 and Nielsen restated the thresholds in 1993: a tenth of a second to feel instant, one second to keep your train of thought, ten seconds and you’ve gone to make coffee. Those are numbers about a nervous system. An agent doesn’t have one.

An agent emits in batches. Its smallest output unit is already a chunk of finished work, and its smallest feedback loop costs a tool call and context. It doesn’t consume autocomplete — it is the autocomplete, and that’s a literal mechanism rather than a slogan: fill-in-the-middle training is what turned a next-token model into a completion engine, and the same capability scaled up is the thing now writing whole files.

The strong version is wrong. Agents do get per-edit feedback — fill-in-the-middle completion, tsc --watch, a hook on every edit. The claim is about grain and cost, not about the absence of a loop. And it isn’t that write-time and review are the same station; a post-edit hook genuinely fires before the change is finished. It’s that the gap between after each agent edit and on the finished diff is far smaller than the gap between per keystroke and on the finished diff. So the win from shifting is much smaller than the human intuition predicts, and the human intuition is where the whole argument came from.

Two mechanisms, one conclusion, and they’re independent. The referent argument says the check has nothing to run on until the change is finished. This one says the loop the tool was built for doesn’t exist either.

It also answers the sharpest objection to the referent argument: a linter fires on my half-written file mid-keystroke constantly, so your claim that this check can’t run early must be too strong. Correct — inside a loop that exists only because a human types one character at a time. Tree-sitter says the quiet part out loud in its own documentation: “In applications like text editors, you often need to re-parse a file after its source code has changed.” Write-time tooling is editor tooling. The editor was the point.

What we built, and the measurement that made it necessary

We built the instrument for question 1: an automated reviewer that runs before human review and decides whether the change is fit to merge into the rest of the code. It’s real, it runs, and it’s half of what’s needed.

It exists in the shape it does because of one measurement. Before building it we took our review rules — question-1 rules, every one of them, conformance checks against an artifact — and asked, one at a time, which of them a linter could express. Most of them can’t. Not a minority, not the exotic ones — most. They’re conditional on shape, riddled with exceptions, and they turn on what the code is for. A Big Rule Set Is an Attention Problem reports the same shape from the other side: about a third of the rules leave the model’s context entirely, and the rest still need a judge even after the noticing is mechanised — which is the split Noticing Is Cheap, Judgment Is Scarce owns. That result is the load-bearing counter to write custom linters instead: the deterministic subset is worth mechanizing and we did mechanize it, but if you stop there you’ve built a check for the part that was never the problem. I’m giving you the direction and not the count, deliberately; the denominator is our catalog.

Which also means the reviewer buys back exactly one thing. It removes the obligation to read the diff for correctness. It doesn’t remove the ability, and fluent senior developers will keep reading anyway, which is fine and good. The difference between a check and a backstop is what happens when they disagree: when someone finds a defect the automated review passed, that’s a gap in the instrument, and the fix is a rule. The human’s code read is the check’s test set. That’s how the catalog grows — the loop Teaching the Reviewer argues, and the reason this station can stay a precondition instead of drifting into an opinion.

The map — three loops, not a pipeline

Three feedback loops show plan, generation, and review. Generation produces code and a first-class update back to the RFC. Six stations carry badges: 1a, 1b, 2, 3a, 3b, and 3c. The five clay badges — 1a, 1b, 2, 3b, and 3c — mark where the right-problem, right-way question can be asked; slate 3a is question one's only station.
The plan is current operational state, regenerated as work changes. When generation changes the underlying intent or rationale, it appends a non-destructive RFC amendment with the earlier plan, what changed, and why; review needs both the current plan and that path.

Three loops, and the reason to draw them as loops rather than stages is that every one of them can send you backwards.

Humans are present in all three loops, but not as an approval click on every iteration. The system owes them a visible re-entry point: consequential plan choices in loop 1, a material change to the plan or RFC in loop 2, and the claim review in loop 3. Whether that point blocks is policy — decided by reversibility and risk, not by who happens to prefer a tighter workflow.

A designer is often in this flow too, and where they sit isn’t fixed. Some hand off: they settle what the thing should be and the RFC carries it from there. Some stay in loop 1 and iterate on the plan as it firms up. Some skip the middle and check the end product, beside 3c. That’s a team’s choice, not a property of the flow, so the designer isn’t a station — a station asserts one placement and this actor has three. The modes aren’t equivalent, though. A designer who hands off is supplying part of question 2’s referent, helping decide what right means. A designer who iterates in loop 1, or who checks the end product, is asking question 2 — and has no more instrument for it than the stations around them. The hole is one participant wider than the count.

Loop 1 — the plan. A prompt becomes an RFC, and the RFC gets refined in a loop rather than written once. Two different checks want to live here. The first is the thinking-partner shape: surface the fork, name the tradeoff, catch the assumption nobody stated. Its referent is only in a head, which is the class that can’t be mechanized, so it’s a prompt for judgment, not a check with a referent an instrument can read. Status: exists, as a personal skill and a prompt, not as a team instrument. The second is the org read — does this collide with the other work in flight, does it serve the objectives we’ve actually stated. Its referent is live, and this is its first of two readings. The instrument that would run it is the one I’ll call the org reviewer, and it’s the same instrument 3b needs; it’s what this post ends up arguing to build first. Status: not built.

Loop 2 — the code. Generation, with guardrails on architecture rather than on syntax. The instrument here reads the trajectory, not the diff — where the work is heading, not what the text currently says — and that’s exactly why it can live inside generation while a rules check can’t. Inside generation the checkable thing is the direction, not the text. Evals Aren’t the Moat makes the case for watching the trajectory rather than the snapshot; what this adds is where that watch has to sit — inside the generation loop, because that’s the only place the direction is still cheap to change. Status: not built.

The part of this loop that matters most is its second output. The plan is current operational state — the execution projection of the RFC — so generation updates or regenerates it as sequencing, dependencies, and remaining work change. It is not the expensive first artifact, preserved forever.

An RFC amendment is different. When generation changes the underlying intent, constraint, or rationale rather than merely the execution steps, it appends a non-destructive revision: the earlier RFC and plan stay visible, along with what changed and why. Otherwise “the updated plan” is only the latest state, and no downstream check can tell whether a divergence was justified or merely forgotten. This makes the history a byproduct of drawing the loop correctly, not a discipline bolted on and then skipped. The current plan and the amendment history have two consumers: the automated check at 3b, and the human who needs to drop to the raw at 3c. Status: not built.

Loop 3 — the review, three stations in order.

3a — automated code quality. Question 1, at the only place it can be asked, as a precondition rather than an opinion: it passes or the change doesn’t go on to be argued about. That it gets to block at all rests on the check being mechanized, and Nobody Broke It narrows even that: deterministic is necessary and not sufficient, because a check that imposes a consequence also owes an answer to whose obligation is this? On a PR the diff answers that for free — which is the one advantage this station holds over the sweep I’ll argue for later. The failure mode to watch here is silent rather than loud: when a gate breaks it errs toward letting the change through instead of blocking it, so a station that has quietly stopped flagging looks exactly like a station with nothing to flag. Status: built.

3b — against the updated plan and the current org state. Question 2’s second reading, and the word updated is carrying the weight. This station only works because loop 2 wrote back; against the original plan it’s comparing the change to a fiction. The two readings ask different questions, too. At plan time: don’t start something that collides. Here: the world moved while you were building — does this still fit? Status: not built.

3c — the human. And their referent is the claim, not the code, which has a consequence people won’t like: the PR description becomes a load-bearing instrument rather than a courtesy. A description that restates the diff hands the reviewer nothing to check. It has to make a claim — what I set out to do, what changed on the way, what I left — and then the human can check the claim against the plan, and drop to the raw when the claim looks thin. That matters because a claim is not a substitute for reading: A Description Can’t Replace the Code argues no description stands in for the raw, and a recorded intent is a description too. The claim’s job is to be a pointer — it tells the reviewer where to drop, and what’s checkable before they get there.

The other consequence is that the human is inside loop 3, not after it. A comment re-enters the loop: back through the automated review, back through the org re-read. They aren’t a terminal gate that bypasses the machinery, and they’re most valuable precisely where the computable checks have already cleared, because their referent is the one that can’t be computed. That’s the routing Augmented Reading reaches from the other direction — run the machine pass first and put each reader where its own decay costs least; here the same order falls out of the referent rather than out of fatigue. Status: happening today — but as a person doing it last, from memory, against a plan that moved. That’s the thing to fix, not the thing to preserve.

The hole

Six stations across the three loops, and five of them can take question 2: the fork-and-tradeoff read at plan time, the collision read at plan time, the trajectory check during generation, the re-read against the updated plan at review, and the human’s read of the claim. The sixth is 3a, and it’s question 1’s only home — the one station on the map that isn’t a place to ask this.

The tempting sentence is four of the five have nothing. It’s cleaner and it’s wrong. The honest count: three of the five have no instrument, one can’t have one by construction, and the fifth is a human doing it last and from memory.

The middle clause is the one to sit with, because it isn’t a gap a better model closes. A Pool of Models Narrows the Overlap — It Doesn’t Erase It settles that: every model verifies what you specified, so the part you never wrote down is invisible to all of them at once, by construction. Question 2’s referent is exactly that part. Which is why the answer here is instruments that have to be built, not a model pool that has to be sampled.

That’s still the whole movable half of code review, unserved. And one level above the diff has a measured gradient behind it. Zhu, Tsantalis and Rigby measured it inside a single pipeline: as generated volume goes up, architectural problems track it at ρ = 0.94 against 0.53 for code-level ones, and file count at 0.72 against 0.33, which wasn’t significant. Be precise about what that buys. Architectural smells are what the loop-2 guardrail watches for — its referent is the trajectory, not the plan — so that’s a different unbuilt instrument from question 2’s. What the gradient says is that the further above the line you go, the faster the problem scales with the amount of code an agent writes, and everything above the line is unserved. It isn’t evidence about question 2; nobody has measured that. Their bounds are real and worth carrying — twenty projects from one multi-agent framework, one detector, generated code rather than a maintained repo — so take it as the direction, not the coefficient.

The same paper kills the obvious cheap fix. Four escalating levels of prompt detail produced no significant effect on any smell category, all p > 0.8. You cannot front-load your way out of this by writing a better plan up front, which is what makes the loop, and the checks inside it, the only place the work can happen. The Brief §2 owns that argument; I’m citing it, not re-deriving it.

The most expensive defect is a well-built change that shouldn’t have been built, and every instrument we have is pointed at the other thing.

The lever we haven’t pulled — shift question 1 right

Question 1’s check can only run late. But late has no upper bound, and that’s a lever nobody pulls.

Let changes land without the heavy analysis. Then sweep new code across the whole codebase on a schedule instead of per-PR. The upside is exactly what question 1’s check always wanted from its referent and the PR could never hand it: the agent gets the whole codebase instead of a diff, and it gets time to use it. Reviews get fast because the slow check left the critical path. Structurally that’s Buy Back the Coverage applied to the review itself: reviewing a diff is a method that narrows the view, the codebase outside the diff is the bill, and a sweep is a compensating check aimed at exactly what the method cut out.

The downside isn’t the one people name first. Yes, a sweep finds the problem after it’s load-bearing — other code already depends on it, the author has moved on, the check is better and the fix is more expensive. But the real cost is this: a sweep has no author. A PR check lands on someone who owns the change and is still holding the context in their head. A sweep finding lands on whoever is nearest. The problem with “less oversight” is attribution, not detection, and it’s the bill for the free answer 3a was quietly collecting.

The whole lever depends on one condition, and I’ll mark it as a prediction rather than a result because nobody has run the experiment: a sweep is only viable if its output is a fix, not a finding. A finding reports that something is wrong and asks somebody to deal with it. A fix is a patch you can read, argue with, and merge. The difference is who is left holding work at the end of the check. An ownerless backlog of findings is a documented failure mode, not a guess. The Google static-analysis team reports that their bug dashboard “saw little use because a bug dashboard was outside the developers’ usual workflow”, and that the answer was to stop shipping dashboards: “Instead of providing bug dashboards, projects like Error Prone extend the compiler with additional checks, and surface analysis results in code review.” The warnings accumulate, nobody is on the hook for any single one, and the list stops being read. A sweep that opens the fix has somewhere to land. That’s newly possible now, which is the reason the lever is worth pulling now rather than in 2015 — and The Nit Was Never Optional is the repricing underneath it. Once generating the fix is cheap and instant, the effort a finding used to protect all but disappears; here that repricing runs one level up, where it’s what turns an ownerless finding into a reviewable patch.

You can already watch both halves of this play out. CodeVibes is an open-source reviewer built on DeepSeek that does the sweep exactly as the referent argument says you should: point it at a repository, and it walks the file tree in priority order — secrets and auth first, then core logic, then everything else — analysing whole files. No diffs, no commits, no PR webhook anywhere in it. That’s the right referent, arrived at independently, and it’s the strongest evidence I have that the lever is real rather than merely tidy. Then it hands back a list of issues and a score out of a hundred. It has the sweep shape right — whole files, no diff, no webhook. The patch is the part that decides whether anyone acts on it.

Two of the best-documented static-analysis programs we have both pulled the other way, back before a patch was cheap to generate. Tricorder states its placement plainly: “Given that all developers at Google use code review tools before submitting changes, TRICORDER’s primary use is to provide analysis results at code review time.” The FindBugs production evaluation records the same drift, moving warnings “more directly into the developer workflow” as confidence grew. Both of those teams moved findings toward the author. The sweep only beats them if it arrives carrying a patch.

Then there’s the boundary, and it’s the part that convinced me this isn’t a tangent. The sweep works for question 1, and it fails for question 2 — a question-2 finding discovered post-merge isn’t a fix, it’s a migration. The sweep works for exactly the check that can’t shift left, and fails for exactly the one that can.

So question 1 shifts right, question 2 shifts left, and both of them move away from the PR. The thesis is sharper than where it started: the PR is the wrong place for both checks, in opposite directions.

The knowledge graph rides on the sweep

Here’s what closes the loop, and it’s structural rather than decorative. By the graph I mean the org’s work and its code held as linked entities an agent can query — what’s in flight, what it touches, what objective it serves, what depends on what — rather than as prose a person has to read. The org read asks does this collide with what else is being built, and that’s a question about edges, not records. The sweep already walks the whole codebase with the whole codebase in context. That is the same pass you need in order to build that graph — and the graph is the precondition for the org reviewer, which is question 2 shifting left.

The right-shift is what funds the left-shift. The two moves aren’t independent.

Per-commit patches keep the graph current between sweeps: build in batch, patch on change. It’s the same shape as incremental parsing — one full parse, then re-parse only what the edit touched — and I’m pointing at that as a structural echo, not as a claim about a system that exists.

What to build next, and why that one first

The org reviewer, ahead of the architecture guardrail. Three reasons, in order of how much they moved me.

It pays at two stations off one build. Same referent, and both stations ask it the same kind of question: loop 1’s collision read and 3b’s re-read against current state. Nothing else on the list has that property.

Its referent has no human substitute. A reviewer can hold the plan in their head — badly, from memory, but they can do it. Nobody can hold what every other in-flight change is doing. Without an instrument the plan check degrades to slow-and-partial; the org check degrades to absent.

The architecture guardrail is more deferrable. Its referent is the trajectory, which is at least partly visible to whoever’s in the loop, so a human in the loop gets some of it for free. They get none of the org state. That’s a statement about build order, not about importance — the ρ = 0.94 gradient says the architecture level is where the volume hurts, and it should be built. Second.

What has to exist for it to work

Four preconditions, and naming them is the actionable part of this post, because each one is a thing you can start on Monday without waiting for the reviewer.

Queryable org state. In-flight changes and stated objectives in a form an agent can ask questions of. A wiki is not that. This is the graph, and it’s the one the sweep can bootstrap.

A plan that’s live and carries its revisions. Which is the two-output arrow from loop 2. Without it, 3b compares the change against a fiction and reports that everything is fine.

A PR description that makes a claim. Otherwise the human at 3c has nothing to check and falls back to reading the diff — which is the state we’re trying to leave.

An RFC that carries approach, not just need. If the RFC only says what the business wants, everything downstream reconstructs the how from scratch — and that reconstruction is the gap other flows fill by building a prototype to look at. If it carries the technical approach too, the plan has something to project from and the check at 3b has something to compare against. This one is a writing habit, not a tool, which makes it the cheapest of the four and the easiest to skip.

None of those four is a model problem. They’re all artifact problems, which is the good news: they’re buildable now, and the reviewer that needs them can arrive later.


How sure I am

  • My model, argued from practice: the two-question split, the referent asymmetry, and the placement conclusions that fall out of it. That the movable check is the one we’ve built nothing for is my inference from our own tooling, not a survey of anyone else’s. The three referent classes are a description that earns its place by predicting placement; I’m not claiming it’s exhaustive.
  • Lived and real: that we built the instrument for question 1, that it runs as a precondition to human review, and that most of our review rules can’t be expressed as a linter. The rule-mechanizability result is a real measurement over our own catalog, reported as a direction and not a count, on purpose — the denominator is a proprietary artifact. That the human review today happens from memory against a plan that moved is my own experience of doing it. That designers sit in this flow in three different modes — hand off, stay in, check the end — is observed across teams, not surveyed.
  • Our take, mechanism-backed, not measured: the loop-granularity argument. Miller and Nielsen establish that the response-time budget write-time tooling targets is a human-perception budget; that agents therefore gain less from shifting a check left is my inference from the batch-emission mechanism, and I have not measured the cost difference between per-edit and per-diff feedback for an agent. I deliberately did not press the prompt-detail null into service here — that null is about prompt detail, not feedback grain, and stretching it would be exactly the overclaim I’d flag in someone else.
  • Backed, with bounds stated: the architecture-versus-code-level asymmetry. Zhu, Tsantalis and Rigby report ρ = 0.94 for architectural smells against generated volume versus 0.53 for code-level, and 0.72 versus 0.33 (not significant) for file count, plus no significant effect of prompt specificity on any category (all p > 0.8). Bounds, which the authors state themselves: twenty projects generated by one multi-agent framework, scored by one detector. It measures what agents build from scratch, not what they do to your repo — so I’m using the direction and not the coefficient.
  • Prior art for the counter-argument, bounded to what I read: Tricorder and the FindBugs production evaluation both record analysis moving toward the review station, and the same team’s CACM retrospective records the dashboard nobody read. Three spans, all three read; I’m quoting nothing beyond them. The CACM spans come from a university PDF mirror of the published article, because both ACM copies refused to open.
  • Argued, not measured: the post-merge sweep, in full. Nobody here has run it. The pros follow from the referent argument, the attribution problem follows from how ownerless findings have historically been treated, and “only viable if its output is a fix” is a prediction. CodeVibes shows the sweep half is being built independently, which is corroboration that the referent argument is right about placement — it is not evidence that the sweep catches more defects than a PR check, because nobody has run that comparison.
  • Declined on purpose: I’m not leaning on cost-to-fix escalation. It’s the obvious rhetorical crutch for a post about check placement, and the largest study on it found no evidence for the effect. My argument doesn’t need it: it’s about which check can move, not about how much cheaper early fixes are.
  • Not built, and marked as such throughout: the org reviewer, the architecture guardrail, station 3b, and the knowledge graph. Three of the six stations in this post are proposals. That’s the genre — the post is about where the hole is — but no status mark in here should be read as a shipped thing.

Sources

  • Bret Victor, Inventing on Principle (CUSEC, 20 January 2012) — “Creators need an immediate connection to what they’re creating.” Used by subversion: immediacy is a property of the human write loop, and the thing writing the code no longer has a nervous system to connect.
  • R. B. Miller, Response time in man-computer conversational transactions (AFIPS Fall Joint Computer Conference, Vol. 33, pp. 267–277, 1968), and Jakob Nielsen, Response Time Limits (Nielsen Norman Group, 1 January 1993) — the 0.1s / 1s / 10s thresholds, derived from human perception. The strongest prior art in this post: the budget write-time tooling is designed against was never a budget about code.
  • Mohammad Bavarian et al., Efficient Training of Language Models to Fill in the Middle (arXiv:2207.14255, 28 July 2022) — the mechanism behind “the agent is the autocomplete.” Cited so the inversion reads as a technical observation, not a slogan.
  • Tree-sitter documentation — “In applications like text editors, you often need to re-parse a file after its source code has changed.” Doing two jobs here: write-time tooling is editor tooling by design, and batch-build-then-incremental-patch is the shape a knowledge graph wants. The second use is a structural echo, not a claim about our system.
  • Larry Smith, Shift-Left Testing (Dr. Dobb’s Journal, Vol. 26 Issue 9, 1 September 2001) — the origin of the term. Named, not quoted; I verified the venue and date but not a span.
  • Yue Cai Zhu, Nikolaos Tsantalis, Peter C. Rigby, AI-Generated Smells: An Analysis of Code and Architecture in LLM- and Agent-Driven Development (arXiv:2605.02741, 4 May 2026) — the measured gradient (ρ = 0.94 vs 0.53; 0.72 vs 0.33, n.s.) and the prompt-specificity null (all p > 0.8). Bounds carried in text.
  • Caitlin Sadowski et al., Tricorder: Building a Program Analysis Ecosystem (ICSE 2015) — “Given that all developers at Google use code review tools before submitting changes, TRICORDER’s primary use is to provide analysis results at code review time.” The best evidence against the sweep, and the reason the sweep needs to output a patch.
  • Caitlin Sadowski et al., Lessons from Building Static Analysis Tools at Google (Communications of the ACM 61(4), pp. 58–66, 26 March 2018; 10.1145/3188720) — the bug dashboard that “saw little use because a bug dashboard was outside the developers’ usual workflow,” and the correction: “Instead of providing bug dashboards, projects like Error Prone extend the compiler with additional checks, and surface analysis results in code review.” Same team as the Tricorder paper, three years later, and the reason “a sweep is only viable if its output is a fix” is a prediction with a precedent behind it, not a hunch. Read from a university PDF mirror; both ACM copies refused to open.
  • Nathaniel Ayewah et al., Evaluating Static Analysis Defect Warnings On Production Software — “As experience and confidence with FindBugs grows, Google is working to incorporate FindBugs warnings more directly into the developer workflow.” Same drift, earlier.
  • CodeVibes (github.com/danish296/codevibes, MIT) — an open-source AI reviewer on DeepSeek that scans a whole repository by priority-ordered file tree instead of reviewing diffs, and returns a scored issue list. Cited as independent corroboration that the sweep placement is right, and as a live instance of the findings-not-fixes shape the post argues against. I read the repository documentation, not the code, and I haven’t run it.
  • Tim Menzies, Ye Yang, George Mathew, Barry Boehm, Jairus Hihn et al., Are Delayed Issues Harder to Resolve? Revisiting Cost-to-Fix of Defects throughout the Lifecycle (arXiv:1609.04886, 16 September 2016; EMSE 22(4)) — “We found no evidence for the delayed issue effect,” in what the authors call the largest study yet published on it. Cited to explain why this post doesn’t use cost-to-fix escalation.
  • The Other Intent — that a change carries two intents and one artifact can serve both, that code-level taste is a missing rule, and the one-person-wrote-it case for homogenization. This post takes all of that as settled and asks a different question: where the checks go.
  • Give Away the Writing — “The taste that used to go in as you typed goes here now.” The write-time shift, already argued; cited, not re-derived.
  • The Brief, §2 — iterate rather than front-load: start loose, see where it breaks, tighten a round at a time. One clause of this post rests on it; the argument is there, not here.
  • Ten earlier posts carry the arguments the stations rest on, each linked inline at the point it’s invoked: A Big Rule Set Is an Attention Problem and Noticing Is Cheap, Judgment Is Scarce on what mechanization actually moves; Teaching the Reviewer on the catalog growing out of the human’s read; Evals Aren’t the Moat on watching the trajectory, not the snapshot; Nobody Broke It on what a check owes before it gets to block; A Description Can’t Replace the Code and Augmented Reading on the claim and where the human belongs; A Pool of Models Narrows the Overlap — It Doesn’t Erase It on the ceiling at question 2; Buy Back the Coverage and The Nit Was Never Optional on why the sweep is a compensating check and why it has to output a patch. This post is the wiring. Every claim it stands on is argued in one of those.