MR Risk Classification & Tiered Review Routing for Duo Code Review
## Problem Today, GitLab's code review workflows treat all MRs with the same level of scrutiny by default. Teams that want to differentiate — routing high-risk changes to more senior reviewers and letting low-risk changes merge quickly — must configure this manually through CODEOWNERS and branch protection rules. These approaches share a critical flaw: **they match on file paths, not on semantic risk**. A safe refactor touching 50 files gets the same review requirements as a 3-line change to an authentication critical path. This creates two compounding problems: - **Low-risk MRs sit in queues**, blocking engineers who need to ship while reviewers are occupied - **High-risk MRs don't get enough attention**, because the same queue pressure means reviewers can't give them the depth they deserve As AI-assisted development accelerates code production, this problem gets worse. Teams are creating more MRs than humans can reliably review, and the inability to triage by actual risk is a significant bottleneck to both velocity and quality. Existing AI code review tools address pieces of this problem, but none closes the loop into tiered AI-driven review routing. ## Proposal Introduce **MR risk classification** to Duo Code Review: an agent-driven system that evaluates each MR when it is opened and assigns it a risk tier. Classification runs **once**, in **parallel with base Duo Code Review**, at MR open or ready-for-review time. It does not re-run on re-review requests and does not use the Duo Code Review output as input. The tier then drives an automated recommendation for what level of review is appropriate. Proposed tiers: | Tier | Risk Level | Recommended Action | |------|------------|--------------------| | 1 | Very Low / Low | Auto-approve or fast-track merge | | 2 | Medium | Standard Duo Code Review | | 3 | High | Recommend Advanced Code Review | The tier assignment should be **explainable** — every classification surfaces a plain-language rationale (e.g., _"This MR is Tier 3 because it modifies `/ee/lib/auth/session_token.rb` and affects 4 downstream API consumers"_) so reviewers can immediately act on or challenge it. ## Risk Classification Signals The classifier should weight signals including but not limited to: **Semantic signals (highest weight)** - Changes to authentication, authorization, session, or encryption logic - API contract or schema modifications (breaking change detection) - Blast radius: number of services/consumers affected by the change, using Orbit's CALLS/DEFINES graph when available and path-pattern heuristics as a fallback - Behavioral vs. cosmetic change detection (code that alters runtime behavior vs. formatting/docs) - Change dispersion — whether changed files are logically related or scattered across unrelated subsystems **Structural signals** - Files changed are in security-sensitive directories (e.g., `ee/`, `config/`, `.gitlab-ci.yml`) - Cross-repo or cross-service impact detected - Changes to shared libraries or platform-level code **History-based signals (GitLab-native advantage)** - SAST/DAST findings in the affected code paths - Pipeline failure rate on the affected files - Deployment frequency and incident history for the affected area - Prior review patterns: how similar MRs have been reviewed in the past - Author commit history on changed files (author familiarity with the code paths being modified) - Existing test coverage on changed lines, not only whether test files were modified alongside the change **Code generation signals** - MR was authored primarily by an AI coding assistant, detected via service account author patterns (industry research shows AI-generated code has significantly higher defect rates than human-written code) - Future: per-source track record — weight by the incident/revert history of the specific AI tool or workflow that produced the MR, rather than treating all AI-generated code identically ## Domain Gates Certain domains carry enough inherent risk that they should establish a **minimum tier floor regardless of rubric score**. Domain gates are a pre-scoring categorical override layer — they are not inputs to the weighted rubric, they override it. When a domain gate fires, it emits a `domain_tag` and a `minimum_tier_floor`. The final tier is `max(rubric_tier, domain_floor)`. Multiple gates can fire on a single MR. **Platform default gates:** | Domain | Detection | Minimum Tier | |--------|-----------|-------------| | Auth / session / authorization | Semantic + path patterns | HIGH | | Database migration | `db/migrate/`, `.sql`, migration class patterns | HIGH | | Cryptography / secrets | `cipher`, `encrypt`, `kms`, `vault`, secret management patterns | CRITICAL | | Payment processing | Semantic patterns (`stripe`, `billing`, `charge`, PCI-scope) | CRITICAL | | Compliance / audit / PII | `audit_event`, data retention, PII handling patterns | HIGH | | Infrastructure / deployment | `Dockerfile`, `*.tf`, `k8s`, `.gitlab-ci.yml` | HIGH | **Configuration:** GitLab ships platform defaults. Groups can override thresholds or add domains at group level. Projects can register custom domain gates using CODEOWNERS-style rules — path patterns plus semantic keywords, with a declared minimum tier. **Routing output:** `domain_tags` produced by this step flow downstream to [Advanced Duo Code Review / Specialized Agents (21524)](https://gitlab.com/groups/gitlab-org/-/work_items/21524), where they determine which specialized agents (security, database, etc.) are recommended for the MR. ## Key Behaviors - **Runs once**: Classification fires at MR open or ready-for-review time, in parallel with base Duo Code Review. It does not re-run on re-review requests, new commits, or draft state changes. - **Staleness indicator**: When new commits are pushed after classification, the existing classification note shows which diff version was assessed and how many commits have been added since (e.g., _"Risk classified against diff v3 — 2 commits added since"_). Re-evaluation on update is explicitly out of scope. - **Break-glass override**: Teams can override a tier classification with a required written justification. Overrides are logged for audit and used to calibrate the model over time. - **Confidence surfacing**: The tier assignment includes a confidence level. A borderline Tier 2/3 classification is surfaced differently from a clear-cut one, giving reviewers useful signal about uncertainty. - **Configurable thresholds**: Teams can tune what constitutes High risk for their codebase — a fintech team may want to flag currency logic as Tier 3; a docs team may never trigger Tier 3 at all. Custom domain gates (see above) are the primary mechanism for this. ## Why This Is a GitLab Differentiator External AI code review tools are largely constrained to working from the diff and repository graph alone. Duo has access to signals no standalone tool can replicate: - **GitLab CI/CD history** on affected code paths (pipeline failure rates, flaky tests) - **SAST/DAST findings** surfaced during prior MRs to the same files - **Deployment frequency and incident data** for the affected service areas - **Issue and milestone context** — what was the intent behind this change? - **Review history** — who has approved similar changes before, and did those changes cause incidents? - **Orbit knowledge graph** — cross-file call and dependency relationships for accurate blast radius scoring Leading context engines in this space achieve around 80% classification accuracy using codebase context alone. Adding GitLab's platform signals to that foundation should significantly exceed what any standalone tool can achieve, and creates a durable competitive moat. ## Open Questions - What is the right default tier threshold for auto-approve behavior, and should it be opt-in at the group/project level? - How do we handle the cold-start problem for new projects with no review history? - Should the break-glass override be a GitLab UI action (button on the MR), a slash command, or both? - How do we expose tier calibration data to platform admins so they can see where the model is wrong? - Should the risk tier be visible to the MR author, or only to reviewers? - Should domain tags be surfaced in the MR UI (similar to labels), or only through the internal classification note and 21524 routing? - At what point does Orbit indexing become a prerequisite rather than optional enrichment for blast radius scoring, and what is the accuracy difference when falling back to path-pattern heuristics?
epic