Every feature, and whether it is on¶
One page that says what this tool does. Each row names the thing, whether it ships on or off, and where the detail is. Nothing here is a summary of a summary: if a row interests you, the link is the page that argues it.
Two conventions run through the whole list.
- Off means off. A feature that ships off changes nothing about a run until you write the key. That is not caution for its own sake: a rule whose first run on a real repository is mostly false positives should be opted into rather than opted out of, and every "off" below has a measurement behind it.
- A feature the installed Understand cannot do is refused before the run starts. Not read,
ignored and quietly measured as something else.
scitools-hook doctorrecords what your build offers; a check reads that record. See Understand 8.0.
What it measures¶
| Ships | Where | |
|---|---|---|
| Per-routine, per-class, per-file and per-project thresholds — complexity, nesting, length, parameters, cohesion, comment ratio | on, with defaults | Rules |
Statistical thresholds over a whole scope, AVG:, MAX:, P90: and friends |
on where configured | Rules |
Two metrics the gate computes itself, because Understand has no usable value for them: CountParams and CountDeclMethodNonStub |
on | Rules |
The Understand 8.0 plugin metrics: CountGlobalsModified/Set/Used, CountClassCoupledModified, CorePercentage, BidirectionalDepsPercent, the CBRI* family |
off — none is a shipped threshold | Understand 8.0 |
| How much of the analysis Understand actually resolved, per side | reported on, judged off | Configuration |
What it compares¶
| Ships | Where | |
|---|---|---|
| The ratchet: every affected entity's before and after value, inside one commit | on | The ratchet |
| Dependency cycles between files and between architecture nodes, reported only when the change creates one | on | Rules |
| Layer rules and coupling limits you declare, over Understand architecture nodes | on where declared | Configuration |
| Fan-in and fan-out, per file and per class | on, as warnings | Rules |
| New dependencies per file | on | Rules |
| Call cycles and reachable complexity | off | Rules |
| A module-level name bound to the same value in many files | off | Rules |
| Routines nothing in the project calls or uses | off | Configuration |
| Findings from an Understand CodeCheck configuration | off until you name one | Rules |
| An adaptive baseline that only ever narrows | off | Configuration |
What it leaves behind¶
The lean-code family: whether code should exist at all rather than whether it is too complex.
Every rule ships off and is enabled by naming a severity on its [lean] switch; the two
floors and the two shrink metrics ship on. One entry per rule, with what it does not report
and the measurement behind its default, is on Rules; how to
read a finding is on Lean code.
| Ships | Where | |
|---|---|---|
A parameter nothing reads, a class nothing references, a module-level binding nothing reads: structure.unused_parameter, structure.unused_class, structure.unused_variable |
off | Rules |
Two floors in front of those and pass_through: resolution_floor and accuracy_floor, below which the rules judge nothing and say so; both measured repositories are below them |
on, at 0.75 each | Configuration |
A routine with one caller that only forwards to one callee: structure.pass_through |
off | Rules |
A base class with exactly one implementation and no other user: structure.single_implementation |
off | Rules |
A file defining one name for one importer: structure.over_export |
off | Rules |
Twelve or more code lines the project holds somewhere else, whitespace and comments absent: structure.duplicate_block |
off | Rules |
A family of routines that are one routine written many times, one finding per family: structure.similar_routine |
off | Rules |
Lines per statement and comment lines per routine, the two shrink signals: routine.LinesPerStatement, routine.CountLineComment |
on, as warnings | Rules |
The net line, net: +12 lloc (+30 lines) over 7 routines, on every check with a before side |
on | CLI |
A ceiling on that figure: structure.net_growth at max_net_growth |
off | Rules |
Understand's duplicate-lines plugin metric as a threshold, DuplicateLinesOfCode and DuplicateLinesOfCodePercent |
off | CLI |
A delete:, yagni: or shrink: tag opening every lean hint, and a worked before-and-after example beneath it under scitools-hook --verbose check and always in JSON |
on | Lean code |
Three doctor rows for what the family reads: lean references, lean tokens, duplicate metric |
on | CLI |
A lean section in the agent-rules block: the ladder, the rules in force with their tags, and which rungs are the agent's alone |
on | Agents |
What it produces¶
| Ships | Where | |
|---|---|---|
| A human report with a remediation hint on every finding | on | CLI |
--format json, one document, schema-versioned |
on request | Agents |
SARIF 2.1.0, to standard output or to --sarif PATH |
on request | CLI |
| Understand's own SARIF beside the gate's, re-rooted on the repository, for one code-scanning upload | off | CLI |
| Dependency and butterfly graphs as SVG, plus an impact set, for reviewing a large change by shape | on request | Review |
| The effective limits written into your agent instructions file | on request | CLI |
| A recommendation: which limits fit this repository, and what each candidate would cost | on request | CLI |
How it runs¶
| Ships | Where | |
|---|---|---|
A native .git/hooks pre-commit shim, chaining to whatever hook was there |
on install | Hooks and CI |
| A pre-push shim that checks each pushed range | on install | Hooks and CI |
A pre-commit framework hook definition |
on install | Hooks and CI |
--staged, --worktree, --all, --files and --range A..B |
on | CLI |
| Nothing written into the working tree: shadows, databases and state live in a cache | on | Operations |
| Per-directory limits, so tests and generated code can be judged differently | on where configured | Configuration |
doctor, which reports the installation, the licence, the features and the cache and always exits 0 |
on | CLI |
What it costs¶
The warm one-line check on this repository is 13.0 s, down from 27.7 s in 0.1.0a8. Four
snapshot extractions became one, and the before side is served from a cache.
| Ships | Where | |
|---|---|---|
| One extraction per side, recording two dependency rings in a single walk | on | Understand 8.0 |
| A snapshot cache for the before side, keyed on everything that could change the document | on | Configuration |
| A before database built from the base commit instead of an exported tree | off | Configuration |
| Git-derived architectures, generated from the after side's commit | off | Understand 8.0 |
A check with nothing selected analyses nothing, extracts nothing and stores nothing: measured at 1.0 s, which is the process starting and the configuration being read.
What it does not do¶
Worth saying plainly, because each is a thing people reasonably expect.
- It does not judge correctness, types, security or style. Those are your test suite, mypy, CodeQL or Semgrep, and ruff. See Against the alternatives.
- It does not fix anything. Every finding carries a hint saying what to change; nothing changes it for you.
- It does not report the debt you already have. A commit is judged against its own before
side, so existing violations in code you touched are reported as pre-existing and do not
block.
check --allis the inventory, and it has no before side at all. - It is not on PyPI, and will not be. See Install.