Idea
A mode that runs checks only over the files that changed (optionally intersected with a per-check glob), rather than the whole tree — the fast local / pre-commit / pre-push case: "check what I touched."
e.g. verifyx --changed [<ref>] (or --staged): compute changed files vs a ref, and for each check run over changed ∩ check-scope. An empty intersection means the check is skipped.
This supersedes the coarse per-script diff filter that was ported from assist and then removed (off by default, unused, confusing --no-filter flag). If we do diff-scoping, do it properly as this mode.
The hard constraint: file-checks vs whole-program checks
Checks split into two kinds, and this is what shapes the whole feature:
Scopable — running over a file subset is correct:
lint (oxlint takes paths), format (oxfmt takes paths)
complexity, comment-block (native, per-file — already accept a [pattern])
block-comments is already changed-scoped (only looks at comments on changed lines)
NOT soundly scopable — need the whole program/graph (scoping makes them WRONG):
check-types — tsc is whole-program; a subset misses cross-file types
unused-code (knip) — "unused" is defined across the whole import graph
circular-deps (skott) — a cycle spans files
duplicate-code (jscpd) — borderline: needs the whole corpus to find clones, but could report only clones touching changed files
A naive "only run on changed files" would silently make types/unused/circular checks incorrect — the dangerous failure mode. The mode must know each check's scope.
Sketch of what it'd take
- Per-check scope metadata on
Check: scope: 'files' | 'project'.
- A changed-files mode (
--changed [<ref>] / --staged): for files checks run over changed ∩ check-glob; for project checks either run-full (correct, slower) or skip (deliberate choice, documented).
- A ref story: changed vs working tree/
HEAD (local) vs base branch (CI/PR).
- Command templating for externals: current external commands are fixed strings (
oxlint .); passing a file list means templating (oxlint <files>), which only some tools accept (oxlint/oxfmt yes; knip/skott/tsc no).
Cheaper alternative
Don't build scoping into verifyx at all — document pairing it with lint-staged / a pre-commit hook for the file-oriented checks, and keep verifyx "run the gate, whole-tree." Less power, near-zero surface.
Status
Parked. Captured from a design discussion; not scheduled.
Idea
A mode that runs checks only over the files that changed (optionally intersected with a per-check glob), rather than the whole tree — the fast local / pre-commit / pre-push case: "check what I touched."
e.g.
verifyx --changed [<ref>](or--staged): compute changed files vs a ref, and for each check run overchanged ∩ check-scope. An empty intersection means the check is skipped.This supersedes the coarse per-script diff filter that was ported from assist and then removed (off by default, unused, confusing
--no-filterflag). If we do diff-scoping, do it properly as this mode.The hard constraint: file-checks vs whole-program checks
Checks split into two kinds, and this is what shapes the whole feature:
Scopable — running over a file subset is correct:
lint(oxlint takes paths),format(oxfmt takes paths)complexity,comment-block(native, per-file — already accept a[pattern])block-commentsis already changed-scoped (only looks at comments on changed lines)NOT soundly scopable — need the whole program/graph (scoping makes them WRONG):
check-types—tscis whole-program; a subset misses cross-file typesunused-code(knip) — "unused" is defined across the whole import graphcircular-deps(skott) — a cycle spans filesduplicate-code(jscpd) — borderline: needs the whole corpus to find clones, but could report only clones touching changed filesA naive "only run on changed files" would silently make types/unused/circular checks incorrect — the dangerous failure mode. The mode must know each check's scope.
Sketch of what it'd take
Check:scope: 'files' | 'project'.--changed [<ref>]/--staged): forfileschecks run overchanged ∩ check-glob; forprojectchecks either run-full (correct, slower) or skip (deliberate choice, documented).HEAD(local) vs base branch (CI/PR).oxlint .); passing a file list means templating (oxlint <files>), which only some tools accept (oxlint/oxfmt yes; knip/skott/tsc no).Cheaper alternative
Don't build scoping into verifyx at all — document pairing it with
lint-staged/ a pre-commit hook for the file-oriented checks, and keep verifyx "run the gate, whole-tree." Less power, near-zero surface.Status
Parked. Captured from a design discussion; not scheduled.