Agent-Assisted Code Review · ~7 min
The same review comment, written for the third time, is not a comment — it's an unencoded rule asking to be promoted into the harness.
A recurring review comment is evidence of an invariant that lives in one reviewer's head. This lesson turns that head-knowledge into a deterministic check — and, just as importantly, teaches you to retire the check before your rule library rots.
One comment is noise. Two is coincidence. The promotion threshold is load-bearing: the same comment across three or more PRs in a window is the signal that an unencoded invariant is costing you on every review.
So the loop is simple: a comment recurs → categorize it → encode the smallest enforceable check → ship it with remediation text → track its hit count → retire it when the count trends to zero.
Match the rule's placement to the comment's category. Promoting a semantic check into a regex linter is a category error: it fires on every legitimate exception and erodes trust in the whole lint stack — the rule becomes the new recurring noise source.
| Comment category | Encoding layer |
|---|---|
| Style or formatting | Linter rule (ESLint, Ruff, …) |
| Architectural boundary | AST / import check, dependency-graph rule |
| Safety or correctness invariant | Pre-completion checklist entry, type or runtime check |
| Spec or contract violation | Evaluator rubric line, integration test |
Then pick the cheapest mechanism that fires deterministically. A one-line ESLint rule beats a multi-file AST plugin when both would work — over-engineering adds maintenance cost the retirement step can't recover.
Anthropic draws the line explicitly: "Unlike CLAUDE.md instructions which are advisory, hooks are deterministic and guarantee the action happens." A reviewer's eye is probabilistic; a mechanical check fires every time. Promotion converts an advisory comment into an enforced invariant.
A rule that says no fs in renderer without saying what to do instead doesn't remove the bottleneck — it
relocates it from review to comprehension. The shape that works states what's wrong, what to do
instead, and where the rationale lives:
A semantic invariant — "this handler swallows the database error" — lands as a checklist line, not an AST check, because whether the catch block "swallows" depends on what it does with the error:
Refactors obviate boundaries, model upgrades eliminate failure modes, conventions solidify until no one would write the violation. Annotate each rule with its obsolescence condition — the observable signal it has done its job — and delete it when the hit count has stayed at zero.
The learned-rules pattern (Cursor Bugbot) tunes the reviewer's defaults from accept/reject signals. This loop promotes the invariant out of the reviewer entirely — into the lint stack, checklist, or rubric. They compose: Bugbot sharpens what review catches; this loop drains high-frequency comments before they ever reach review.
Retrieval practice — recall, don't peek
Question 1You should promote a recurring review comment into a harness rule once it has fired across…
Question 2Forcing a semantic, correctness-style comment into a regex linter mainly causes…
Question 3A rule shipped without remediation text mostly…
Question 4Letting promoted rules accumulate without retirement leads to…
Question 5 · spaced recall from an earlier lessonTo make an AI-authored PR reviewable, the author should…