Triage a gerenuk report
gerenuk run said one line on stderr before handing over to pytest, or
gerenuk impacted-tests printed a report. Read the verdict before the list.
Three outcomes.
selected: the walk completed and the listed tests are the whole answer. Each entry carries an arrow chain from the test back to the changed symbol; read it right to left. A surprise in the list is a real edge, not a guess. Animpacted conftestsentry is not a test:runexpands it to every test file in its subtree.run_all: gerenuk could not bound the impact, so the full suite runs (or thefallback-commanddoes). The reason line says why; work the ladder below.impacted-testsstill exits0: “run everything” is an answer.- nothing:
selectedwith an empty list.runspawns nothing and exits0, indistinguishable from a green suite, which for a hook it is.
The run_all ladder. Take the first reason that matches.
non-Python files changed: the diff touched a file gerenuk cannot reason about - config, a template, data - and any test may depend on it. Files no test reads, like docs, go inignore-paths; otherwise accept the full run, or setfallback-commandwhere the full suite is too slow.a changed file did not parse: fix the syntax error, then rerun.tyf is not available:uv add --dev ty-find, thengerenuk doctor.tyf failed during the walkorthe working tree could not be read:gerenuk -v impacted-testsprints the error; usually the daemon (tyf daemon status,tyf daemon stop) or a permissions problem.the depth limit was reached,the symbol limit was reachedorthe time budget ran out: a hub symbol. Raise the budget for this one run,gerenuk impacted-tests --max-depth 20, and read what it finds; make it policy only viagerenuk guide tune.a changed symbol is dispatched by an unresolvable decorator: a registrar gerenuk cannot see. Add the decorator toignore-decoratorsonly if the tests reach the symbol some other way; otherwise the full run is right.the full suite is faster than a selection:suite-msinpyproject.tomlsays so andruntook it at its word. Remove the key if the suite grew.
JSON. --format json prints one object: verdict, reason (null when
selected), base, merge_base, impacted_tests as {file, symbol, via, origin} (symbol null for a whole file), test_files_changed,
ignored_symbols, ignored_paths, stats and errors.
Replay. Save one walk and map it more than once:
gerenuk impacted-tests --format json > impact.json
gerenuk run --impact impact.json -- -q
The saved report is parsed strictly, and a stale one selects the wrong tests,
so regenerate it after every diff. gerenuk run --dry-run prints the decision
and the exact argv without spawning anything, and says when per-test node ids
were folded into a file selected wholesale.
Do not: bypass the hook or drop the step to get past run_all - the full
suite is the safe answer - or raise a budget in pyproject.toml for one commit.
next: run gerenuk run -- -q