Skip to content

Report

diffcone plan prints a JSON report (--format text prints a readable summary of the same information). The report's format is versioned by schema_version, currently 3.

Top-level fields

Field Contents
schema_version The report format version, 3.
status complete, or degraded when an analysis error made diffcone select every target.
discovery_incomplete true when the runner may collect tests diffcone couldn't see; the plan then exits with code 3.
analysis What was compared: both snapshots, the source roots, whether uncommitted files were analysed, counts, and the recording used, if any.
changed_symbols Every symbol that differs between the snapshots.
selected_targets The targets to run, and why.
unselected_targets The targets not affected, and why.
dependency_explanations For each selected target, the path from the target to the change.
unresolved_relationships References diffcone couldn't resolve, and which changes they might reach.
fallback_decisions Where diffcone selected more because it couldn't tell what a change reaches.
analysis_errors Errors such as a file that doesn't parse. Any error selects every target.
declarations The dependencies declared in diffcone.toml.
discovery For each runner: how many targets were found, the configuration read, and any notes.

Snapshots

analysis.base and analysis.head describe the two snapshots:

Field Contents
revision What you asked for: main, HEAD~1, WORKTREE.
commit The commit it resolved to (for INDEX and WORKTREE, the commit they sit on).
kind commit, index or worktree.
uncommitted true for INDEX and WORKTREE.

Changed symbols

{
  "id": "calc.ops.mul",
  "kind": "function",
  "changes": ["body_changed"],
  "base_path": "src/calc/ops.py",
  "head_path": "src/calc/ops.py"
}

changes lists one or more of added, deleted, body_changed, definition_changed and dependencies_changed (what they mean).

Selected targets

{
  "runner": "pytest",
  "runner_id": "tests/test_calc.py::test_square",
  "entry_symbol": "tests.test_calc.test_square",
  "lifecycle_dependencies": ["tests.test_calc"],
  "rules": ["dependency"],
  "conservative": false,
  "affected_dependencies": ["tests.test_calc.test_square"]
}

rules says how the target was selected. conservative is true when any of them is a fallback: something diffcone couldn't bound, so it selected the target to be safe.

Rule Fallback Meaning
dependency A chain of calls, references or imports connects the target to a change (the target's own code included), shown in dependency_explanations.
new_target The target is new.
entry_docstring_changed The target's docstring changed; for a doctest, the docstring is the test.
declared_dependency A dependency declared in diffcone.toml connects it to a change.
dynamic_reference yes It reaches code that looks names up dynamically (getattr, importlib), and a change could be among them.
unresolved_name_match yes It reaches a call diffcone couldn't resolve, whose name matches a changed function or method.
entry_symbol_unresolved yes Its own code wasn't found in either snapshot.
lifecycle_dependency_unresolved yes Something it depends on wasn't found: a fixture diffcone couldn't find, a conftest.py outside the source roots, a benchmark's code it couldn't read.
analysis_error yes A file couldn't be analysed, so every target is selected.
runner_dependency yes Code the test runner itself imports changed.
unanalysed_file_changed yes A file diffcone doesn't read changed under the source roots (data, compiled sources, configuration), or your runner configuration or build script changed outside them.

With execution evidence, the rules name what the recorded run observed:

Rule Fallback Meaning
executed_changed The test ran a changed function.
executed_reader The test ran code that reads a changed value or definition.
touched_file The test read a file that changed.
changed_target The test's own code, or its class or module, changed.
test_scope Test code it shares a scope with changed (a mark, fixture or parameter).
escalated The change can't be judged from a recording (code that runs on import, for example), so it was planned from the code.
cython_caller The test ran Cython code that calls a changed function the recording can't see.
lookup_site yes The test looked a name up dynamically where a name was added or removed.
no_evidence yes The test has no recording (a new test, for example).
unstable yes The test's recordings differed between runs.
subprocess yes The test started a subprocess, which the recording can't follow.
pytest_hook_changed yes A pytest hook or what decides what pytest loads changed.
unobserved_file_changed yes A change the recording can't attribute to tests: code that ran outside every test (a hook, collection), a conftest.py outside the source roots, Cython outside functions or without a profiled build.
unindexed_import yes Changed code ran while a file outside the source roots was being imported.

Exit codes

Code Meaning
0 Plan produced; the analysis is complete.
1 Plan produced, but an analysis error made diffcone select every target.
2 No plan: a bad argument, an unreadable manifest, or an unknown revision.
3 Plan produced, but the runner may collect tests diffcone couldn't see.

When both 1 and 3 apply, the plan exits with 3.