RunTrace
RunTrace is a lightweight CLI for capturing and comparing the code, configuration, environment, and metadata behind machine-learning experiments. It stores transparent YAML snapshots in the current Git repository, without a server or account.
Version: This source tree and distribution metadata target v0.2.0. Published files and release status are listed on PyPI and GitHub Releases. RunTrace supports Windows and Linux with Python 3.10–3.12.
Why RunTrace?
Experiment folders named final, final-2, and final-really do not explain
which commit, config, Python environment, or command produced a result.
RunTrace records that reproducibility context at the moment you choose, then
lets you inspect and compare it later.
RunTrace deliberately has a smaller job than MLflow or Weights & Biases. It is useful when you want:
- a local-first workflow with no service, database, or account;
- human-readable snapshot files that remain under your control;
- Git-aware records of committed and uncommitted code state;
- configuration and dependency comparisons from the terminal;
- an incremental reproducibility layer rather than a full tracking platform.
It does not track metrics, host dashboards, schedule experiments, upload artifacts, or replace a full experiment-tracking platform.
Quick Start
1. Install from PyPI
Create and activate an isolated environment using the command for your shell:
python -m venv .venv
Then install RunTrace and verify both supported entry points:
python -m pip install ml-runtrace
ml-runtrace --version
python -m ml_runtrace --version
The PyPI distribution is ml-runtrace, its Python import is ml_runtrace,
and its only console command is ml-runtrace. No runtrace import or command
alias is provided because an unrelated PyPI project owns those names.
Contributors should use the locked uv environment described in
Development.
2. Initialize an existing Git repository
RunTrace requires a Git repository with at least one commit:
cd your-project
ml-runtrace init
This creates runtrace.toml and .runtrace/runs/ at the Git root. Commit
runtrace.toml if it is part of the project configuration. Add .runtrace/ to
your .gitignore when recorded runs should remain local and untracked.
3. Record an experiment
Create a repository-local YAML config such as configs/train.yaml:
model: resnet18
optimizer:
learning_rate: 0.001
weight_decay: 0.01
batch_size: 32
seed: 42
Commit the code and config you want to identify, then record the experiment:
git add runtrace.toml configs/train.yaml
git commit -m "add training baseline"
ml-runtrace snapshot --name baseline --config configs/train.yaml --command "python train.py --config configs/train.yaml"
snapshot records the supplied command; it does not execute that command. The
result prints a 12-character run ID and writes one YAML file beneath
.runtrace/runs/.
4. Snapshot and run atomically
RunTrace v0.2.0 adds an opt-in wrapper for commands that should always have a snapshot captured immediately before execution:
ml-runtrace run --name baseline --config configs/train.yaml -- python train.py --config configs/train.yaml
run writes the snapshot before starting the command after --, preserving
the exact argument vector as well as a readable command. If snapshot capture
fails, the experiment is not started. If the experiment fails, its snapshot is
kept and its exit code is returned.
The child process is started directly, without an implicit shell. Pipes, redirection, shell variables, and other shell syntax are therefore not interpreted unless you explicitly run a shell as the child command.
5. Inspect and compare runs
After recording another run, use either a full ID or a unique abbreviated ID:
ml-runtrace list
ml-runtrace show <run-id>
ml-runtrace diff <baseline-id> <candidate-id>
A representative diff looks like this (IDs and values will differ):
Comparing a31f82000001 -> b91de3000002
Configuration ────────────────────────────────────────────────────────────────
changed config.values.optimizer.learning_rate
before 0.001
after 0.0005
Git ──────────────────────────────────────────────────────────────────────────
changed commit
before 83ab2c1000000000000000000000000000000000
after 92dc113000000000000000000000000000000000
Environment ──────────────────────────────────────────────────────────────────
changed torch
before 2.4.0
after 2.5.0
The detailed Getting Started guide walks through the entire init → snapshot → list → show → diff workflow and explains each result.
What a snapshot contains
- run ID, optional name, and UTC timestamp;
- Git commit, branch or detached-HEAD state, and dirty state;
- Python version, implementation, operating system, and architecture;
- installed Python distribution names and versions;
- optional NVIDIA GPU, driver, and CUDA metadata when detectable;
- an explicitly supplied command and YAML config path, SHA-256 hash, and parsed values.
Snapshots created by v0.2.0 also include the exact argument vector used by
ml-runtrace run and sanitized PEP 610
origins for direct VCS, archive, and local-directory package installations.
VCS and archive origins retain a safe relative package subdirectory when one
is declared.
CLI reference
| Command | Purpose |
|---|---|
ml-runtrace init |
Initialize local RunTrace state at the containing Git root. |
ml-runtrace snapshot |
Capture the current reproducibility context. |
ml-runtrace run -- COMMAND... |
Snapshot first and then execute an exact argument vector. |
ml-runtrace list |
List recorded runs newest first. |
ml-runtrace show <run-id> |
Display one complete stored snapshot. |
ml-runtrace diff <run-a> <run-b> |
Compare reproducibility-relevant values. |
Run ml-runtrace <command> --help for command-specific arguments and options.
Privacy and storage
RunTrace is local-only by default. It does not upload experiment data, source code, credentials, environment variables, or artifacts. Snapshot capture does not read those implicit secret sources.
When --config, --command, or the run wrapper is used, RunTrace
intentionally stores the parsed config values, readable command, and exact
command arguments in local YAML. Do not put secrets in those explicit inputs.
For packages installed from a direct source, v0.2.0 reads standardized
direct_url.json metadata. URL usernames/passwords, queries, fragments, and
local absolute directory paths are omitted. A remote URL's host and repository
path, requested revision, and safe relative subdirectory can still reveal
private project names; review .runtrace/runs/*.yaml before sharing or
committing it, just as you would review any experiment record.
Development
RunTrace requires Python 3.10 or newer and uses uv for its reproducible development environment:
git clone https://github.com/Corvus-226/RunTrace.git
cd RunTrace
uv sync --all-groups --locked
uv run ml-runtrace --help
uv run pytest
uv run ruff check .
uv run ruff format --check .
CI runs the same quality gates on Linux with Python 3.10, 3.11, and 3.12.
Contributing and security
Focused bug reports, design feedback, and contributions are welcome. Read CONTRIBUTING.md before opening a pull request. Report vulnerabilities privately using the instructions in SECURITY.md, not a public issue.
License
RunTrace is released under the MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ml_runtrace-0.2.0.tar.gz.
File metadata
- Download URL: ml_runtrace-0.2.0.tar.gz
- Upload date:
- Size: 132.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
633e52245f466d57fed0c9cd96eaf81f5e5eef04a1b6a40d0834caf253b0426d
|
|
| MD5 |
68aadca14dec9da25c0684fa230c3e6b
|
|
| BLAKE2b-256 |
25ba48faa9b55dc2a85075f36d2fd1e31baecfa5031f43ec2a5fd77b83f15c25
|
Provenance
The following attestation bundles were made for ml_runtrace-0.2.0.tar.gz:
Publisher:
publish.yml on Corvus-226/RunTrace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ml_runtrace-0.2.0.tar.gz -
Subject digest:
633e52245f466d57fed0c9cd96eaf81f5e5eef04a1b6a40d0834caf253b0426d - Sigstore transparency entry: 2498407323
- Sigstore integration time:
-
Permalink:
Corvus-226/RunTrace@aca08ecefb5d630cba1779438d54f818ad719a18 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Corvus-226
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aca08ecefb5d630cba1779438d54f818ad719a18 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ml_runtrace-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ml_runtrace-0.2.0-py3-none-any.whl
- Upload date:
- Size: 27.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0415a8954edacb446cc847781d01db36c06ee8b2f50288ed255d906d919fd0e
|
|
| MD5 |
59170fa84d2b60a4893f8684e94d9718
|
|
| BLAKE2b-256 |
589489c1edc28c7e6c413f32c26a6859d11399083f7ea84b8deffa31a3ef777b
|
Provenance
The following attestation bundles were made for ml_runtrace-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on Corvus-226/RunTrace
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ml_runtrace-0.2.0-py3-none-any.whl -
Subject digest:
b0415a8954edacb446cc847781d01db36c06ee8b2f50288ed255d906d919fd0e - Sigstore transparency entry: 2498407329
- Sigstore integration time:
-
Permalink:
Corvus-226/RunTrace@aca08ecefb5d630cba1779438d54f818ad719a18 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/Corvus-226
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aca08ecefb5d630cba1779438d54f818ad719a18 -
Trigger Event:
push
-
Statement type: