Browse docs
Docs /signals/scope
The four signals

izri/scope

Scope answers: does this diff do what the PR claims, and only that?

It is the signal that catches the change nobody asked for — the refactor smuggled into a bugfix, the config edit that rode along with a feature, the migration that appeared in a docs PR. Agent-written PRs drift this way constantly, because an agent asked to fix one thing will happily fix four.

What it compares

Two things:

  • Declared intent — the PR title, labels, and body. Conventional-commit prefixes are parsed for the declared type.
  • Actual diff — which files changed, which categories and modules they belong to, and how much changed.

The comparison runs in two layers.

The rule layer (always on)

Deterministic, fast, free on every plan, no LLM. It produces:

  • Path categorization — mapping changed files onto your project's module and category vocabulary.
  • Type-vs-files alignment — does a fix: PR look like a fix?
  • Sensitive-path detection — did this touch something you flagged?
  • Scale anomalies — is this far bigger or smaller than the stated intent implies?

The semantic layer (opt-in)

An LLM comparison of stated intent against intent derived from the diff. It catches drift the rule layer can't see — a PR that says "update copy" and rewrites an auth flow, where both are "small changes to two files."

It costs AI tokens and is gated by plan. Enable per-invocation:

izri check-scope --semantic

The rule layer runs either way, so scope never depends on an LLM being available.

The alignment score

0–100, how well the diff matches its declared intent. It feeds the umbrella composite at weight 0.24.

The score is a soft signal. A low alignment score alone doesn't block a merge — it drags the composite, and the merge blocks only if the composite lands under 70.

Findings

Category Severity Meaning
pr_type_forbidden_category error The diff changed a category the declared PR type forbids. Hard rule — fails the umbrella outright.
pr_type_mismatch warn The diff doesn't look like what the PR type claims.
test_removal warn Tests were deleted. Sometimes correct, always worth seeing.
scale_anomaly warn / info The change is much larger or smaller than the stated intent implies.
structural_drift info Module boundaries moved.
sensitive_path info A path marked sensitive in your config was touched.

Only pr_type_forbidden_category blocks on its own. In particular sensitive_path is info by design: a hint that a human should look, not an assertion that something is wrong. If your team wants a sensitive path to be a hard gate, express that as a forbidden category for the PR type rather than expecting the hint to block.

Configuration

Scope reads .izri/scope.yml from your PR head — checked in, code-reviewable, and versioned with the code it governs. Resolution precedence and the full schema are in the scope.yml reference.

Running it locally

izri check-scope
izri check-scope --base origin/develop
izri check-scope --json

Deterministic and fast, so it's cheap to run before pushing. See the CLI reference.

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

Edit this page on GitHub →All docs