Docs /features/scope

Scope analysis & configuration

The izri/scope signal compares a PR's changed files against a declarative scope config — the team vocabulary of what counts as a module, a category of work, and a sensitive area. The analyzer turns the file diff plus the intent (PR title + body) into an alignment score, a bucketed view of changed files, and per-rule findings.

Two sources of scope config

Scope config can live in two places:

  1. Dashboardproject_scope_configs rows seeded by the LLM /derive-scope job on project connect, edited later from /organizations/<slug>/projects/<id>/scope. Versioned.
  2. In repo.izri/scope.yml at the PR head, checked into the customer's repository and code-review-able.

In-repo wins when valid. The file at the PR head SHA reflects what the team is intentionally shipping with this delta; the dashboard config can lag (someone forgot to update it) but the checked-in file can't. If the in-repo file is missing or fails validation we fall back to the dashboard config, and if neither is available the analyzer uses baked-in defaults.

The active source for a given delta is surfaced as a small badge on the scope card of the delta report — Using .izri/scope.yml when the in-repo file took precedence.

File location

<repo-root>/.izri/scope.yml

Place exactly at .izri/scope.yml. Other paths and other extensions (.yaml, .json) are not recognized.

Schema

The file is validated against the same Zod schema that gates dashboard configs (packages/trpc/src/types/scopeCheck.ts :: ScopeConfigSchema). All three top-level arrays are required, even when empty.

# Logical modules in your codebase. The analyzer uses these to group
# changed files into "what part of the system did this PR touch?".
# `paths` are globs — minimatch syntax.
modules:
  - name: auth
    paths:
      - "packages/auth/**"
  - name: web
    paths:
      - "apps/web/**"

# Categories of work the PR intent should resolve to (parsed from the
# PR title + body). Each category can optionally require a stated
# intent or a test change. `expects` and `forbids` are advisory hints
# the analyzer surfaces in its rationale.
categories:
  - label: feature
    requires_intent_statement: true
  - label: bugfix
    requires_test_change: true
  - label: docs

# Paths whose modification produces a soft `sensitive_path` finding.
# Use for areas where review attention matters more than usual —
# auth, billing, migrations. Sensitive findings are informational by
# default (they don't block the umbrella).
sensitive:
  - name: env_files
    paths:
      - ".env*"
  - name: db_migrations
    paths:
      - "packages/database/migrations/**"

Override semantics

Situation Source recorded Behaviour
.izri/scope.yml parses + passes schema validation in_repo The in-repo config is used. Dashboard config is ignored for this delta.
.izri/scope.yml missing dashboard Dashboard config used. Falls through to defaults if no dashboard config exists.
.izri/scope.yml malformed YAML or schema mismatch dashboard Dashboard config used (or defaults). One info-severity scope finding is emitted naming the file and the failure.
Neither in-repo nor dashboard config defaults Analyzer falls back to baked-in defaults — useful findings on day one for first-time projects.

A malformed in-repo file is never fatal. The analyzer always produces a verdict; the misconfiguration shows up as an info finding on the scope card so a reviewer can see what happened without the PR being blocked.

Where the source is recorded

The resolved source is persisted in two places:

  • scope_checks.scope_config_source — source of truth, per analysis.
  • delta_reports.scope_config_source — denormalized cache of the latest scope_check's source, so dashboard / API reads don't need a join.

Both columns take one of 'dashboard', 'in_repo', 'defaults'. Rows written before the column was added are nullable.

Why in-repo wins

The reverse default ("dashboard wins, in-repo file is a hint") would mean a customer who checks in a config file might see the analyzer disagree with what's actually in their repo, with no clear signal which one ran. Inverting later (in-repo wins → dashboard wins) would silently change behaviour for every project that already relies on it. In-repo as the override is the safer default to ship first: the file someone reviewed with the PR is the one that drives the analysis.

See issue #234.

Reading this with an agent? /docs/features/scope.md serves the raw markdown.

All docs