Turn Repository Policy into Review Scope

OpenCodeReview has already established which Git change it is examining; the next question is which parts of that change deserve model attention. This chapter follows the deterministic selection and rule layers that answer it. The practical value is diagnostic: when a file is silent, a reader should be able to distinguish “not selected,” “selected but too large,” and “selected under a rule that produced no finding,” rather than treating all three as a clean review.

The distinction is central to OCR’s hybrid design. A model can decide whether a selected change is risky, but it should not quietly decide the scope of the review by skipping files or inventing a policy from the prompt. Scope is established first. Rules then tell the agent what kind of reasoning matters for the files that remain.

Selection is a chain of non-equivalent gates

The review provider can remove paths before the per-file selection logic runs. It blocks noisy or operational directories and applies repository ignore behavior so that common dependency, build, and metadata trees do not flood a review. These are provider-level boundaries. They are not just user preferences, and a later include pattern cannot necessarily bring such a path back into the review.

The remaining diffs pass through a fixed sequence. First, binary files are excluded. A binary artifact may be part of the Git change, but it is not meaningful input for the text-oriented review agent. Next, OCR applies the user’s exclude patterns. Exclusion has priority because a repository or team may know that a generated, vendored, or sensitive path should not be sent to the model even if its extension looks reviewable.

Then comes the subtle gate: user inclusion. If a path matches an explicit include pattern, OCR keeps it immediately and bypasses the later unsupported-extension and default-path checks. This is useful when a team deliberately wants to review a test or an unusual file type. It does not turn include into a universal whitelist. Paths that do not match an include pattern still proceed through the normal checks, and provider-level directory exclusions happened before this per-file decision.

The next gate is the supported-extension allowlist. OCR is designed for source and configuration formats it knows how to route to appropriate review guidance. A file with an unknown extension is not automatically evidence that it is unimportant; it is evidence that the default review policy does not know how to handle it safely. The correct response is an explicit rule or a different tool, not an assumption that the model should inspect every byte in the repository.

Finally, default-path exclusions remove common test-file patterns unless the user include rule has already bypassed that gate. This default reflects a noise and workload choice, not a claim that tests never contain defects. A team reviewing a test-heavy change may reasonably override the default, but that override should be visible. The difference between “tests were not selected by default” and “tests were selected and produced no comments” affects how much confidence a clean result deserves.

Selection has two additional outcomes. A deleted file is retained in the wider change context but is not dispatched as a normal review item because there is no new file content to inspect. A diff whose raw content alone exceeds 80% of the configured prompt limit is marked too large before grouping. OCR does not squeeze it into a request and hope the model copes. It records the exclusion so the omission can be explained.

The same deterministic selection pass powers preview and the real run. That design closes a common operational gap: a preview should not promise to review one set while execution silently derives another. It also gives the user a low-cost way to inspect the boundary before spending model tokens. In practice, the most useful question before a large review is often not “which model is best?” but “which files will actually reach it?”

flowchart TD A["Changed path"] --> B["Provider directory and ignore boundary"] B --> C{"Binary?"} C -->|Yes| X["Excluded"] C -->|No| D{"User excluded?"} D -->|Yes| X D -->|No| E{"User included?"} E -->|Yes| G["Keep for review"] E -->|No| F{"Supported extension?"} F -->|No| X F -->|Yes| H{"Default path excluded?"} H -->|Yes| X H -->|No| I{"Deleted or too large?"} I -->|Deleted| J["Context only"] I -->|Too large| X I -->|No| G G --> K["Resolve review rules"]

The gates therefore define an honest review denominator. They do not guarantee that every file a human considers relevant will be selected, and they do not judge the quality of a selected file’s code. They establish what the agent was asked to inspect. That is a narrower responsibility, but it is one that must be stable if later coverage records are to mean anything.

Rules turn scope into model guidance

Selection answers “should this file enter the review?” Rule resolution answers “what should the agent pay attention to once it enters?” OCR resolves review text through ordered layers. A per-run custom rule has the highest priority, followed by a project rule, a global user rule, and embedded system defaults. Within a layer, the first matching path pattern wins. Ordering is therefore behavior: moving two otherwise identical entries can change the instruction the model receives.

The embedded system layer gives OCR a fallback even when a repository has no custom configuration. It contains language- and format-specific guidance, and its matching supports recursive patterns, brace expansion, and case-insensitive path matching. Some extensions need more than a path pattern. A file ending in .m, for example, can represent different languages; the resolver can inspect its content to choose the more appropriate system guidance. The point is not the particular extension. It is that routing is a controlled decision rather than an unexplained model guess.

Filtering and rule text are related but not identical. The higher-priority user layer can define include and exclude patterns, while rule-text resolution can continue through the ordered layers to find guidance for a path. A repository can therefore inherit the system’s general language checklist while adding a project-specific instruction for one sensitive area. When a project rule replaces the system rule, it takes responsibility for the resulting text; when it explicitly merges the system rule, both obligations remain visible.

This matters when one semantic review group contains files with different rule sets. OCR does not simply concatenate unrelated instructions and hope the model knows which paragraph applies to which file. It can tag distinct rule blocks with the paths they govern. A shared conversation can still reason across related files, but the policy attached to each file remains identifiable. That is another example of engineering around model interpretation: the agent receives richer context without losing the ownership of an instruction.

The project’s own rule configuration makes the policy layer concrete. One rule targets the built-in provider registry and adds requirements about field style, protocol constants, documentation synchronization across languages, and regression tests. It also retains the system-specific guidance rather than discarding it. This is not a generic list of “best practices”; it is a repository decision about what a change to that particular registry must preserve. The review tool becomes part of the project’s governance because the rule is committed alongside the code and can evolve with it.

That example also shows why rules should not be mistaken for executable proof. A rule can tell the model to check that every new provider has matching documentation and tests, but the model still has to inspect the change, identify the relevant evidence, and decide whether a violation exists. Conversely, a file can satisfy every written checklist item while containing a problem the rule did not anticipate. Rules narrow attention and make expectations explicit; they do not replace judgment or tests.

The distinction between selection and guidance gives teams a useful way to troubleshoot. If a file never appears in preview, inspect the provider boundary and the selection gates. If it appears but the review emphasizes the wrong concern, inspect which rule layer and pattern won. If the rule is correct but the finding is weak, the remaining problem belongs to the agent’s reasoning, its available context, or the later comment pipeline. Keeping those causes separate prevents teams from responding to every disappointing review by adding more words to one global prompt.

There is a second benefit: policy changes become reviewable changes themselves. A project can decide to include a class of tests, exclude generated artifacts, or strengthen a provider rule, then observe how that affects selection and model guidance. Because the policy is explicit, the team can discuss its trade-offs: broader coverage may increase noise and cost; a narrower rule may reduce distractions while missing a concern outside its scope. The system does not hide those choices behind an opaque prompt.

Consider a change that contains a source file, its test, a generated output, and an image. The selection result is not a single yes-or-no opinion about the pull request. The source file may pass every gate, the test may be excluded by a default path pattern, the generated output may be removed by an explicit project exclusion, and the image may be rejected as binary. The result can still be a valid review, but only for the selected subset. A good operator reads the exclusions as part of the result and decides whether the policy matches the risk of the change.

The include gate is especially easy to misunderstand in that scenario. If the team includes the test path, the test can bypass the later default-path check. That does not automatically admit the generated output or image, and it does not override a provider-level directory boundary. The difference is a useful example of why “include” is not a synonym for “review only these files.” It is an exception within a larger decision chain, not a replacement for the chain.

The size gate creates a similar distinction. An oversized file is not the same as an unsupported file. The first is known input that exceeds the configured review-unit budget; the second is input the default policy does not know how to route. Those cases call for different operational responses. A team might split or narrow a large change, while an unsupported format might need a custom rule or a different analyzer. Treating both as a generic omission hides the decision that caused it.

Rules also have a lifecycle of their own. A project rule is loaded, matched against a path, and rendered into the prompt that governs the group. If the project changes the rule file in the same pull request as the code it governs, the review is evaluating both the policy and the implementation under a particular version of that policy. Reusing an earlier finding under changed guidance would make the old finding difficult to interpret, because the model was answering a different policy question.

The checked-in provider rule illustrates a second-order effect. It does not merely ask the model to inspect a provider entry. It connects the entry to documentation in several languages and to a regression test that protects protocol and model routing. The rule turns a local-looking code edit into a cross-file maintenance obligation. OCR still relies on the agent to notice whether the obligation was met, but the repository has made the obligation explicit and discoverable rather than leaving it to tribal knowledge.

This is the practical meaning of policy as an interface. The selection layer tells the agent what work it owns. The rule layer tells it what “good” means for that work. A failure in either layer can distort the review before any reasoning quality is measured, so both need to remain inspectable by humans.

The important conclusion is that repository policy is not incidental configuration around OpenCodeReview. It is the deterministic layer that defines the model’s assignment. It says which files count, which omissions are intentional, and which questions the agent should ask. Once that boundary is fixed, OCR can give related files shared context without handing the model an unbounded repository-wide conversation. The next step is to examine how those bounded review units are formed and how the agent works inside them.

References