The more rules I added for the coding bots, the less they followed them, so I stopped adding rules

日本語

Contents of this article

Summary

Over roughly four months, I had five kinds of autonomous coding bots, split by role, put out change proposals (PRs) for a service I develop at my own company, and what became clear was that the more prohibitions I added to the rules I wanted them to keep, the less the bots kept the rules. This article retraces, from that failure, the design question of how to enforce compliance: whether to bind the bots’ violations with a rules document, or stop them with a machine check. The division of labor is that the human side builds mechanisms that detect violations and quality regressions through monitoring and automated checks, and the bots only take the role of putting out PRs that fix the detected problems.

The approach of adding a prohibition to the rules document each time a violation appeared did not stop the recurrence. I could identify two structural reasons the additions had little effect. First, even when I closed a violating PR, the reason it was closed did not reach the bot that next created a PR. Second, in the official specification of the bots I use, the only thing read automatically before a PR is filed is the single rules file at the repository root, and the finely divided per-role notes are not guaranteed to be loaded.

But even after I acted on these two points, writing the prohibitions directly into the place that is always read and raising the declaration of having read the rules to required, the recurrence continued. Within a few months the rules grew past twenty prohibitions, and the self-checks I asked of the bots before filing also swelled past twenty items. The more I added, the longer the document grew, yet the violations did not decrease.

So in the end I moved only the violations that can be judged uniquely without reading context, at the moment of filing, into a gate that a machine detects. The machine flags only four kinds: that the declaration of having read the rules is missing from the PR description, that a change to the rules file itself is mixed into the PR’s diff, that an existing line of the rules file is deleted, and that a heading consisting of only a date is appended to a document in the repository.

Context-dependent violations, such as straying outside the delegated scope, duplicate PRs, or declaring the severity of a security fix heavier than it really is, I did not mechanize but left to human review. The gate does not close a PR automatically; it goes only as far as attaching a comment flagging the issue and a classification mark, and the decision to close stays with a human. The same set of bots also kept putting out PRs that were merged and proved useful.

The body, readable by subscription, is built to follow the failures in the order they happened. First I lay out a synopsis of the roughly four months of operation and the shape of the division of labor, where the human side builds the detection mechanisms and the bots only put out fixing PRs. Next I trace the first accident, where I made a request without defining scope and the quality checks failed across the board, and how from there I divided the delegable scope into three.

Then I trace how the same violations kept recurring even as I added prohibitions, the two structural reasons the document did not reach the bots, and how the recurrence continued even after I wrote the rules directly into the read location. On that basis I describe the design of the machine gate that flags at the moment of filing, the split between violations left to the machine and those left to humans, and the way I built the implementation using actually-closed cases as test inputs. I close by leaving the settled operation after months of running alongside the bots, and the branch I have not yet been able to settle: whether to widen the range the machine guards, or to cut the rules themselves shorter.

Who this is for and what you can take away

This article is for developers who are continuously having multiple autonomous coding bots write PRs, or who are about to delegate that to them.

There are three takeaways. The first is a measured account of where the approach of enforcing compliance through a written rules document reaches its limit. The second is the structural cause that produces that limit. The third is a way of splitting: having a machine flag, at the moment of filing, only the violations that can be judged without reading context, and leaving context-dependent judgment to humans.

What became clearest in this operation was that the more rules I piled on to enforce, the harder they became to keep. So in the end I stopped piling on rules and shifted the design toward reliably surfacing the places that are not being kept. What I write here is not a general theory but a consideration based on the primary record of running a service I develop at my own company for about four months.