Runner
runner
Subprocess runner that targets the audited project's venv.
When auditing an external project, tools (ruff, mypy, pytest, etc.) must execute in that project's virtual environment, not axm-audit's own.
ProcessVerdict
Bases: Enum
Centralized interpretation of a subprocess exit.
One source of truth for what a returncode means to a scored rule, so individual rules no longer re-derive returncode semantics (which is how an env-failure could silently score a green 100).
Members
CLEAN: the tool ran and found nothing (rc == 0).
ISSUES: the tool ran and reported findings via an expected
non-zero exit (e.g. ruff rc=1 with JSON findings).
ENV_FAILURE: the tool did not actually complete the check
(rc in :data:_ENV_FAILURE_RETURNCODES, or a timeout).
A scored rule MUST fail loud on this verdict, never green.
Source code in packages/axm-audit/src/axm_audit/core/runner.py
find_venv(project_path)
Locate the nearest .venv directory for a project.
Checks project_path first, then walks up the directory tree to
support uv monorepo workspaces where the shared .venv lives
at the workspace root rather than inside the individual package.
The search is bounded to :data:_MAX_VENV_SEARCH_DEPTH levels to
avoid accidentally picking up an unrelated .venv higher in the
file system.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
project_path
|
Path
|
Root of the project being audited. |
required |
Returns:
| Type | Description |
|---|---|
Path | None
|
The |
Path | None
|
environment exists in the project or any of its ancestors |
Path | None
|
(within the bounded depth). |
Source code in packages/axm-audit/src/axm_audit/core/runner.py
interpret_process(result)
Classify a finished subprocess into a :class:ProcessVerdict.
This is the single home of the env-failure returncode set
(:data:_ENV_FAILURE_RETURNCODES). Both the lint and type rules
route their env-failure decision through here, removing the
historical mypy-vs-lint asymmetry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
result
|
CompletedProcess[str]
|
The completed (or synthetic-on-timeout) subprocess. |
required |
Returns:
| Type | Description |
|---|---|
ProcessVerdict
|
|
ProcessVerdict
|
returncode is in the env-failure set; otherwise |
ProcessVerdict
|
(an expected non-zero exit carrying findings). |
Source code in packages/axm-audit/src/axm_audit/core/runner.py
run_in_project(cmd, project_path, *, timeout=_DEFAULT_TIMEOUT, with_packages=None, capture_output=False, text=False, check=False)
Run a command in the target project's environment.
Locates the nearest .venv/ — either in project_path itself
or in an ancestor directory (for uv monorepo workspace members).
Uses uv run --directory to execute the command within the
correct environment. Falls back to running the command directly
with cwd set when no virtual environment is found.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cmd
|
list[str]
|
Command and arguments to run. |
required |
project_path
|
Path
|
Root of the project being audited. |
required |
timeout
|
int
|
Maximum seconds to wait before killing the subprocess. Defaults to 300 (5 minutes). |
_DEFAULT_TIMEOUT
|
with_packages
|
list[str] | None
|
Optional packages to inject at runtime via
|
None
|
capture_output
|
bool
|
Capture stdout/stderr (piped). Preserves the prior
|
False
|
text
|
bool
|
Decode output as text. Preserves the prior contract. |
False
|
check
|
bool
|
Raise |
False
|
Returns:
| Type | Description |
|---|---|
CompletedProcess[str]
|
CompletedProcess result. On timeout, returns a synthetic result |
CompletedProcess[str]
|
with |
Note
The child is launched in its own process group / session
(start_new_session on POSIX, CREATE_NEW_PROCESS_GROUP on
Windows). On timeout the whole group is killed, so a wrapper
such as uv and every process it forked (the inner python,
worker threads, …) are reaped together instead of being orphaned.
Source code in packages/axm-audit/src/axm_audit/core/runner.py
| Python | |
|---|---|
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | |