Scrubby
System

The Learning Loop

Most static-analysis tools are frozen at config time. The rules someone wrote in 2023 are the rules you're still being graded against in 2026 — whether or not your codebase still works that way. Scrubby is built differently. Every review is also a learning event. The connections that produce useful signal get reinforced. The ones that don't get weakened. After a few weeks of normal development, the system has converged on the relationships that actually matter for your codebase.

Why static rules decay

A linter rule is a contract: "this pattern is forbidden, that pattern is required." It's written once and applied everywhere. That works for things that are universally true (don't use var in modern JavaScript, don't catch exceptions you can't handle). It breaks for everything else.

Most of what makes a codebase maintainable isn't universal. It's local. Your auth domain has its own error-handling style for reasons that go back to a 2024 incident no one wrote down. Your billing domain has a strict facade pattern that exists because the team decoupled it from user-management two years ago. None of this is in a linter. None of it can be, because the rules don't generalize.

The traditional alternative is human review — senior engineers carrying the rules in their heads and enforcing them in PR comments. That works until those engineers are saturated, or leave, or get tired of writing the same comment for the third month in a row.

The Hebbian principle, in plain English

Scrubby's learning loop borrows an idea from neuroscience: neurons that fire together wire together. Translated to a codebase: connections between domains that produce useful signal get stronger; connections that don't get weaker.

Concretely: when a Scrubby review on a file in your "Billing" domain produces a useful finding that's attributed to the "Email & Notifications" domain, the connection between Billing and Email gets reinforced (weight goes up by 0.05). When the Email domain runs a check on a file and produces nothing, the connection weakens (weight goes down by 0.02).

The asymmetry is intentional. Useful signal counts more than its absence. A connection that's frequently silent decays slowly; a connection that's frequently productive strengthens quickly. Both bounded between 0 and 1, with a small temporal-decay factor so very old connections fade if they stop being relevant.

What gets reinforced

Three places in the system feed the loop:

  1. Findings reported from your AI editor. When the agent reviews a file and reports its findings via scrubby_report_findings, weights update.
  2. GitHub App PR reviews. Every PR Scrubby reviews produces a set of findings, which feed the loop automatically.
  3. PR feedback signals. Dismissing a finding on a PR signals that the connection that produced it was wrong; that flows back as a small negative update.

The compounding effect

Two effects compound over time:

Cross-domain noise fades. Domain pairs that started with weak coupling but never produce useful findings drift toward zero. Scrubby stops asking the questions that don't pay off.

The connections that matter get sharper. Domain pairs that consistently produce useful findings strengthen. Reviews become tuned to your codebase, not a generic abstraction.

Global vs repo-scoped learning

Repo-scoped weights move on every review against your repo. Global-domain weights (Ruby, React, Testing, Security) move on a slower clock so a single repo's signal doesn't dominate them. The aggregate across many repos is what trains the global layer — which means a fresh React app you connect tomorrow inherits the wisdom of every other React repo Scrubby has seen.

Why this beats config-driven review

A team that uses Scrubby for six months has a network of connection weights that reflects how their codebase actually behaves — with the same hot-spots, the same caution flags, the same strong dependencies their senior engineers carry around mentally. That network was never written by anyone. It emerged from the reviews.

Replicating that with static rules would mean an engineering manager sitting down and writing hundreds of bespoke rules per codebase, then maintaining them as the codebase changes. Nobody does this in practice. So static-rule code review either stays generic and misses most of what matters, or it stays specific but rots within a quarter.

The phrase "Scrubby gets smarter over time" describes the literal behavior of the connection graph — not a marketing claim. After a few weeks of consistent use, the network has stabilized around what's actually load-bearing in your codebase.

Quiet reviews matter too

You don't only feed the loop when there's a finding. Reporting an empty findings array on a file that was reviewed weakens the cross-domain checks that ran without firing — which is just as useful for sharpening the network as the positive case. Encourage your AI agent to report quiet reviews; the system gets cleaner faster.

See the network shift over a few weeks of normal use.

Join the Scrubby beta Read the docs →