Environment variables¶
Audience: operators, CI authors, contributors driving capa from a script or a doc-tooling harness. Scope: every environment variable capa reads, grouped by who sets it and why.
The runtime list is grepped from src/capa/; contributor-only test variables come from tests/hardware/. If a variable is named with the CAPA_ prefix but does not appear here or on Hardware tests, capa does not read it — silently ignoring an unfamiliar env var is intentional, and setting a misspelled name has no effect.
For configuration that lives in files (experiment YAML, hardware TOML, method TOML) see Configuration overview. For runtime flags that are CLI options rather than env vars, see the per-command CLI pages.
Path overrides¶
| Variable | Effect | Default | Source |
|---|---|---|---|
CAPA_RUNS_ROOT |
Directory that holds every sealed bundle and the runs.sqlite catalog. Honoured by every CLI command that needs a bundle parent (run, gui, finalize, catalog list, catalog verify, catalog rebuild). An explicit --runs-root flag overrides this. |
./runs (resolved against the CWD) |
cli/_helpers.py |
XDG_CONFIG_HOME |
Used as the parent of the user-global plugins.lock fallback ($XDG_CONFIG_HOME/capa/plugins.lock). Standard XDG variable; not capa-specific. |
OS-default; on Linux/macOS falls back to $HOME/.config |
cli/_helpers.py |
HOME |
Used to derive $HOME/.config/capa/plugins.lock and ~/.capa/logs/ (the pre-run log directory). Standard POSIX variable; not capa-specific. On Windows the same lookup uses pathlib.Path.home() via the USERPROFILE/HOMEPATH machinery. |
OS-default | cli/_helpers.py, core/logging.py |
Resolution order for --runs-root-style paths is explicit flag > env var > built-in default. The same rule applies everywhere a path can come from more than one source.
Plugin trust¶
| Variable | Accepted values | Effect | Default | Source |
|---|---|---|---|---|
CAPA_PLUGIN_MODE |
dev / production (case-insensitive; anything else is treated as dev) |
dev loads every procedure plugin that passes the contract check, ignoring plugins.lock. production refuses any procedure plugin missing from plugins.lock or whose distribution hash drifts. capa run / capa gui read this variable; capa plugins list --plugin-mode can override it for inspection. |
dev |
core/plugins_runtime.py |
A production run that finds no usable plugins.lock fails fast — pass --plugins-lock explicitly or place one at ./plugins.lock or $XDG_CONFIG_HOME/capa/plugins.lock. See Plugin lockfile for the lockfile schema.
Contributor testing¶
| Variable | Effect | Default | Source |
|---|---|---|---|
CAPA_HARDWARE_TESTS |
Set to 1 to opt into the hardware-marked pytest tier. Default behaviour is to skip every test marked @pytest.mark.hardware, which is every test that opens a real device. Per-vendor connection parameters are read by the individual modules under tests/hardware/. |
unset (skip) | pyproject.toml, tests/hardware/ |
See Hardware tests for the full opt-in workflow.
FLIR IR camera SDK¶
| Variable | Effect | Default | Source |
|---|---|---|---|
CAPA_FLIR_ATLAS_ROOT |
Filesystem root of the FLIR Atlas C SDK install (Atlas 2.19.0). The capa-flir plugin's _loader.py dlopens libatlas_c_sdk.so (Linux) or atlas_c_sdk.dll (Windows) from $CAPA_FLIR_ATLAS_ROOT. Without this variable set, the plugin's adapters refuse to open and capa hardware discover --adapter camera_ir returns no devices. |
unset | capa-flir plugin (see capa-plan.md → FLIR Atlas SDK install) |
On Linux you also need $CAPA_FLIR_ATLAS_ROOT/lib prepended to LD_LIBRARY_PATH. On Windows you need $CAPA_FLIR_ATLAS_ROOT/bin on PATH so dependent DLLs resolve. See FLIR IR cameras for the per-platform install steps.
Diagnostic logging¶
| Variable | Effect | Default | Source |
|---|---|---|---|
CAPA_WEBCAM_FRAME_DIAG |
Set to 1 to log the first 150 webcam input frames at INFO with their format name, width, height, and pts. Useful when chasing format-negotiation regressions; verbose, so leave unset in normal operation. |
unset | devices/camera/webcam/adapter.py |
For general log-reading guidance see Reading event logs.
Doc-tooling and screenshot harness¶
Warning
Do not set these on a real rig. They exist so the screenshot-harness and the make-docs tooling can hold transient runtime states (CONNECTING, DRAINING) long enough to capture a screenshot, and to force sim adapters into failure modes that don't occur naturally. None of them produce useful behaviour during real experiments.
| Variable | Accepted values | Effect | Default | Source |
|---|---|---|---|---|
CAPA_SCREENSHOT_PROBE |
1 (or any non-empty string) |
Enables a read-only HTTP probe on 127.0.0.1:9876 when the GUI launches. Exposes GET /widgets, GET /actions, GET /property. The probe runs in a daemon thread; cost is zero when the variable is unset (module not imported). |
unset | ui/app.py, ui/_screenshot_probe.py |
CAPA_SCREENSHOT_PROBE_INTERACTIVE |
1 (or any non-empty string) |
Requires CAPA_SCREENSHOT_PROBE set as well. Promotes the probe to write-capable: POST /screenshot, POST /click, POST /type, POST /key, POST /trigger, POST /set_tab, POST /set_property, POST /dismiss, POST /wait_for, POST /resize, POST /hover. These endpoints can fire real UI actions — never enable this on a rig connected to live hardware. |
unset | ui/_screenshot_probe.py |
CAPA_DRAINING_DELAY_S |
float seconds | Holds the conductor in the DRAINING state for the configured number of seconds before disarming workers. Lets doc tooling screenshot the status badge in DRAINING; under a clean sim shutdown the state lasts milliseconds. |
0 (no delay) |
runtime/conductor.py |
CAPA_SIM_OPEN_DELAY_MS |
int milliseconds | Stretches the simulated Watlow adapter's open() so the connection-strip badge sits in CONNECTING long enough to screenshot. |
0 (no delay) |
devices/sim/watlow_sim.py |
CAPA_SIM_OPEN_FAIL |
any non-empty string | Forces the simulated Watlow adapter's open() to raise AdapterError. Drives the connection strip into FAILED so the error-state UI can be captured. |
unset | devices/sim/watlow_sim.py |
Not currently env-configurable¶
For completeness, things that look like they should be env vars but aren't:
- Configs root. There is no
CAPA_CONFIGSlookup today. Hardware / experiment / method files are passed by explicit path argument to every CLI command; the GUI reads its last-opened paths from its own settings store. SettingCAPA_CONFIGShas no effect. - Log level / format. Log behaviour is controlled by
configure_logging()arguments, not env vars.CAPA_LOG_LEVELandCAPA_LOG_JSONare not read anywhere. Pre-run logs go to~/.capa/logs/capa-YYYYMMDD.log(human-friendly console renderer); in-bundle logs go torun.log(JSON lines). To change levels for a debugging session, edit the call site incli/run.pyor run the engine from a Python harness that passes the levels you want.
If you want one of these, file an issue — these are deliberate gaps, not oversights, but the absence is worth surfacing.
See also¶
- Exit codes — how outcomes map to process exit codes.
- File formats — every on-disk format capa reads or writes.
- Configuration overview — how the file-based configuration layers compose.
- Hardware tests — full
CAPA_HARDWARE_TESTS=1workflow. - FLIR IR cameras — Atlas SDK install and
CAPA_FLIR_ATLAS_ROOTwalkthrough.