The semantic review

The semantic review reads a change structurally. It compares two refs through semdiff, reasons over syntax-aware hunks, and reports findings a person can act on. It never reads whole files when the structural diff will do.

/s:review runs it. On a pull request, the semantic-review check carries its verdict.

What it reads

semdiff performs the mechanical work and emits compact JSON. Six subcommands serve the review:

subcommandwhat it returns
fileschanged paths, grouped into architectural cohorts
diffsyntax-aware hunks, with formatting noise stripped
contextthe references to a changed symbol
changea planned change's deltas, tasks, and lint findings
lintfindings from the repository's own linters
doctorthe tools available on this machine

The engine supplies the facts. The reviewer supplies the judgement.

What it looks for

The review works cohort by cohort, foundational layers first. Three of its passes look past the changed lines themselves:

  • Downstream impact. A changed signature, limit, or timeout breaks a contract, so the review chases every consumer. A consumer the diff never touched is the most valuable finding it produces.
  • Call-site values. The review follows the argument each caller passes. A guard the real call never reaches is dead code.
  • Risk lenses. Five triggers run over every diff: secret or credential exposure, authorization boundary, unbounded work, resource release, and migration reversibility.

A linter finding is corroboration the reviewer weighs. It never becomes a review finding on its own.

Severity and the blocking rule

Every finding carries one of three severities, and the blocking rule is mechanical:

severitymeaningblocks
higha correctness bug, a broken contract, an unmet criterionyes
mediuman unhandled edge case, a caller at genuine riskyes
lowstyle, naming, minor redundancyno

Two findings always rate high, whatever the reviewer's confidence: an exposed secret, and an authorization boundary reached without a scope check. A leaked credential does not wait for confirmation.

Where it runs

The review takes one of two paths. A local run ends at the report. A run that posts to a pull request enters a loop that survives later pushes.

no

yes

a later push

semdiff reads the diff

the review judges it

posting requested

report, then stop

read prior dispositions

post findings, set the check

implement or answer each finding

Before it posts, the review reads back the findings this pull request already carries. It omits a finding a reviewer answered with a reasoned reply, and it states how many it omitted. It keeps a finding that only a commit cleared, because a recurrence after a fix is a regression.

Each posted finding carries a hidden identity, hashed from its path and its text. Line numbers stay out of that hash, so a finding whose line moved still matches.

When a tool is missing

The review degrades rather than stops. Without difft it falls back to a structural-text engine and says so in the report. It records that loss of accuracy under what it could not verify. A linter that crashes or times out reports as failed, and the review still completes.

See also