Metadata-Version: 2.4
Name: runprint
Version: 0.1.11
Summary: Run anything. Capture everything needed to reproduce it.
Author: Runprint Contributors
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/minhquang0407/Runprint
Project-URL: Repository, https://github.com/minhquang0407/Runprint
Project-URL: Issues, https://github.com/minhquang0407/Runprint/issues
Keywords: reproducibility,research,ml,experiment-tracking,provenance
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0.0
Requires-Dist: rich>=12.0.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Dynamic: license-file

# Runprint (`qr`)

**Production-Grade, Local-First Experiment & Reproducibility Platform for AI & Scientific Research**

> *"Run anything. Capture everything needed to reproduce it."*

[![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![PyPI version](https://img.shields.io/pypi/v/runprint.svg)](https://pypi.org/project/runprint/)
[![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey.svg)](https://pypi.org/project/runprint/)

Runprint (`qr`) is a lightweight, framework-agnostic execution wrapper and reproducibility tracker for machine learning, deep learning, and computational science. It operates seamlessly both **outside your code** (as an invisible process supervisor via `qr run -- ...`) and **inside your code** (via an intuitive, IDE-friendly Python SDK).

<img width="1190" height="827" alt="image" src="https://github.com/user-attachments/assets/bf395319-4e7c-46ca-badf-f47ad6a1633a" />



All manifests, code diffs, logs, metrics, and environment locks are preserved in a clean `.qr/` directory inside your project. **Zero cloud accounts, zero telemetry, zero external database servers.**

```text
                       qr run -- <command>
                               │
                               ▼
                   ┌───────────────────────┐
                   │     Runprint (qr)     │
                   └───────────┬───────────┘
                               │
            ┌──────────────────┼──────────────────┐
            ▼                  ▼                  ▼
     Git State & Diff     Dependencies        Hardware & OS
       (uncommitted)      (AST + Lock)        (CPU, GPU, RAM)
            │                  │                  │
            └──────────────────┼──────────────────┘
                               ▼
                      .qr/runs/<run_id>/
                               │
          ┌────────────────────┼────────────────────┐
          ▼                    ▼                    ▼
     manifest.json       metrics.jsonl        stdout / stderr
     config.json         artifacts.json       git.diff patch
                               │
                               ▼
                    Local SQLite & Lineage
                               │
            ┌──────────────────┼──────────────────┐
            ▼                  ▼                  ▼
          qr ui             qr diff            qr rerun
      (Live Web Hub)    (Side-by-Side)   (--restore-env / worktree)
```

---

## 📑 Table of Contents

- [Key Capabilities](#-key-capabilities)
- [Installation](#-installation)
- [Quickstart in 60 Seconds](#-quickstart-in-60-seconds)
- [Interactive Web UI Hub (`qr ui`)](#-interactive-web-ui-hub-qr-ui)
- [Complete Python SDK Reference](#-complete-python-sdk-reference)
  - [Three Execution Paradigms](#three-execution-paradigms)
  - [1. Universal & Semantic Logging (`qr.log`, `qr.log_*`)](#1-universal--semantic-logging-qrlog-qrlog_)
  - [2. Hyperparameter Tracking (`qr.log_config`, `qr.params`)](#2-hyperparameter-tracking-qrlog_config-qrparams)
  - [3. Streaming Metrics & Block Timing (`qr.metric`, `qr.log_metric`, `qr.timer`)](#3-streaming-metrics--block-timing-qrmetric-qrlog_metric-qrtimer)
  - [4. Dataset Declarations & Checksumming (`qr.dataset`, `qr.log_dataset`)](#4-dataset-declarations--checksumming-qrdataset-qrlog_dataset)
  - [5. Artifact Registration (`qr.log_artifact`)](#5-artifact-registration-qrlog_artifact)
  - [6. In-Code Activation for IDEs (`qr.init()`, `qr.activate()`, `qr.finish()`)](#6-in-code-activation-for-ides-qrinit-qractivate-qrfinish)
  - [7. Hyperparameter Sweeps & GridSearch (`with qr.run()`)](#7-hyperparameter-sweeps--gridsearch-with-qrrun)
  - [8. Reproducibility & Determinism Helper (`qr.seed`)](#8-reproducibility--determinism-helper-qrseed)
  - [9. Distributed Training & Multi-GPU (`qr.is_main_process`, PyTorch DDP)](#9-distributed-training--multi-gpu-qris_main_process-pytorch-ddp)
  - [Complete SDK Method & Alias Cheatsheet](#complete-sdk-method--alias-cheatsheet)
- [Exhaustive CLI Command Guide](#-exhaustive-cli-command-guide)
  - [`qr run` — Execute & Snapshot](#1-qr-run--execute--snapshot)
  - [`qr ui` — Local Web Hub](#2-qr-ui--local-web-hub)
  - [`qr list` — Search & Filter History](#3-qr-list--search--filter-history)
  - [`qr show` — Inspect Provenance & Score](#4-qr-show--inspect-provenance--score)
  - [`qr rerun` — 1-Click Reproduction Engine](#5-qr-rerun--1-click-reproduction-engine)
  - [`qr diff` — Side-by-Side Run Comparison](#6-qr-diff--side-by-side-run-comparison)
  - [`qr env` — Package Drift & Cache Management](#7-qr-env--package-drift--cache-management)
  - [`qr doctor` — Integrity Diagnostics & Auto-Repair](#8-qr-doctor--integrity-diagnostics--auto-repair)
  - [`qr sync` — Cache Synchronization & Multi-Machine Merging](#9-qr-sync--cache-synchronization--multi-machine-merging)
- [Core Architectural Concepts](#-core-architectural-concepts)
  - [Multi-Dimensional Execution Fingerprint & Provenance Audit](#1-multi-dimensional-execution-fingerprint--provenance-audit)
  - [Experiment Lineage DAG & Sister Runs](#2-experiment-lineage-dag--sister-runs)
  - [AST Core Dependencies vs. Full Lockfile](#3-ast-core-dependencies-vs-full-lockfile)
  - [Deep Hardware & OS Diagnostics](#4-deep-hardware--os-diagnostics)
  - [Restorability Scoring Rubric (0 – 100)](#5-restorability-scoring-rubric-0--100)
- [Storage Layout & Manifest Schema](#-storage-layout--manifest-schema)
- [Quality Assurance & Security](#-quality-assurance--security)
  - [Test Suite Audit (TESTING.md)](TESTING.md)
  - [Air-Gapped Security Policy (SECURITY.md)](SECURITY.md)
- [License](#-license)

---

## ⚡ Key Capabilities

- **Zero-Instrumentation Wrapper**: Wrap any command (`qr run -- python train.py`, Bash scripts, C++ binaries) without modifying a single line of training code.
- **100% Local-First & Self-Contained**: Stored directly in `.qr/` within your workspace. No third-party cloud, no SaaS subscriptions, no data exfiltration.
- **Complete Git & Untracked File Snapshotting**: Preserves exact Git commit SHA, branch name, uncommitted working tree diffs (`git.diff`), and new untracked source files without touching your Git index.
- **Multi-Dimensional Provenance Audit**: Computes deterministic SHA-256 execution fingerprints and audits across **Code**, **Parameters**, **Datasets**, and **Runtime Environment**. Automatically detects **Identical Runs** (with linear versioning `v2`), **Sister Runs** (parameter sweeps with delta diffs), and **Code Drift**.
- **AST Core Dependency Isolator**: Analyzes script imports via Python's Abstract Syntax Tree, filters out standard library packages, and isolates direct application dependencies (`direct-packages.txt`) while preserving the full environment freeze (`pip-freeze.txt`) for high-fidelity environment reconstruction.
- **Deep Hardware & OS Diagnostics**: Captures CPU driver version, physical cores & logical threads, max clock, L3 cache, RAM bus speed (MHz/MTs), per-slot RAM module topology, GPU compute capabilities, GPU driver, and dedicated VRAM.
- **Interactive Web UI Hub (`qr ui`)**: Zero-dependency local server with real-time log streaming via Server-Sent Events (SSE), Tree View by Script & Commit DAG, interactive parameter auto-forms, and side-by-side run comparisons.
- **1-Click Automated Reproduction (`qr rerun --reproduce`)**: Recreates past experiments in an isolated temporary Git worktree with an isolated reconstructed virtual environment.
- **0–100 Restorability Scoring**: Granular 3-pillar audit scoring (Source Code 35 pts, Environment 35 pts, Data & Inputs 30 pts) with actionable checklists in `qr show`.

---

## 📦 Installation

### From PyPI (Recommended)
```bash
pip install runprint
```
*(Both `qr` and `runprint` commands are registered globally. You can also run `python -m qr` or `python -m runprint`).*

### From GitHub
```bash
pip install git+https://github.com/minhquang0407/Runprint.git
```

### Local Development
```bash
git clone https://github.com/minhquang0407/Runprint.git
cd Runprint
pip install -e ".[dev]"
```

---

## 🚀 Quickstart in 60 Seconds

### 1. Initialize Runprint in your Repository
```bash
qr init
```
*Run `qr init` once per repository to create the `.qr/` workspace, `project.json`, and local SQLite index. (Note: `qr run` will also auto-initialize the workspace if omitted, but running `qr init` explicitly prepares the repository).*

### 2. Run your First Experiment
```bash
qr run --tag baseline -- python train.py --epochs 10 --batch-size 32 --lr 0.001
```

If your code has uncommitted modifications, `qr` automatically captures the patch into `git.diff`:
```text
[!] Working tree contains uncommitted changes. Snapshotting diff:
  - train.py
  - configs/model.yaml

Run QR-20260918-E90F-v1 [baseline] started (13:30:15)
... live stdout & stderr logged in real-time ...
Run completed: exit=0, duration=12.4s (QR-20260918-E90F-v1)
```

### 3. Launch the Web UI Hub
```bash
qr ui
```
Open **`http://127.0.0.1:8765`** to explore your experiment DAG, view live logs, inspect hardware diagnostics, and compare runs.

---

## 🌐 Interactive Web UI Hub (`qr ui`)

Launch the built-in local dashboard anytime:
```bash
# Default (port 8765, opens browser automatically)
qr ui

# Custom port or headless mode
qr ui --port 9000 --no-browser
```

### Key UI Features:
1. **Master Column Navigation**:
   - **`[ ≡ Flat View ]`**: Chronological run list with status badges, tags, and instantaneous search.
   - **`[ 🌳 Tree View by Script & Commit ]`**: Hierarchical DAG grouping:
     1. **Script Entrypoint** (e.g. `📄 train.py (12 runs)`)
     2. **Git Commit & Dirty state** (e.g. `🌱 Commit #b02ad01 (dirty)`)
     3. **Run Cards** with nested version lineage (`v1` ➔ `v2`).
2. **8 Dedicated Detail Tabs**:
   - **Overview**: Metadata, Git commit, restorability score gauge, execution command, duration, and exit code.
   - **Output Logs**: Real-time streaming terminal output (`stdout` & `stderr`) via Server-Sent Events (SSE) with search filter and download.
   - **Metrics**: Extrema summary cards (Min, Max, Latest) and interactive SVG line plots with metric selection.
   - **Artifacts**: Registered models, weights, evaluation plots with file size and SHA-256 checksums.
   - **Parameters**: Structured table of command-line arguments and in-code hyperparameters.
   - **Packages & Environment**: Dual-view toggle:
     - `[ ⭐ Direct Packages ]`: Core packages directly imported by the script.
     - `[ 🔗 Full Lockfile ]`: Complete 190+ package freeze of the virtual environment.
   - **Notes & Tags**: Live editable markdown notes and experiment tags.
   - **Lineage & Sister Runs**: Visual DAG provenance chain and Sister Runs comparison table with 1-click `[ Compare ]` action.
3. **Launch New Run Modal (`+ New Run`)**:
   - Auto-discovers runnable scripts in your project.
   - **AST Auto-Form**: Automatically parses script arguments and generates input fields that merge into the command line.
   - **Multi-Dimensional Provenance Warnings**: Instantly displays alert cards for 100% duplicate runs (with options to View Existing or Rerun as v2), Sister Runs with hyperparameter deltas, or Code Drift.
4. **Deep Hardware & OS Diagnostics Modal (`(i)`)**:
   - Displays real CPU driver version, physical cores, logical threads, L3 cache, RAM bus speed (MHz/MTs), per-slot memory modules, GPU driver, and VRAM.
   - **1-Click Markdown Specs Exporter**: Formats full hardware specifications for research paper supplementary materials.
5. **Side-by-Side Run Diff Modal**:
   - Compares parameters, Git diffs, and metric extrema between any two runs.
6. **Rerun Preflight Modal**:
   - Pre-flight audit checklist with toggles to reconstruct virtual environments or bypass mismatches.

---

## 🐍 Complete Python SDK Reference

The `runprint` Python SDK (`import qr`) provides rich, framework-agnostic utilities for deep experiment tracking.

### Three Execution Paradigms

1. **CLI Wrapper (`qr run -- python train.py`)**: Zero code changes required. If `import qr` is used in the script, calls to `qr.log()`, `qr.log_metric()`, etc. automatically attach to the active CLI run via environment variables.
2. **In-Code Activation (`qr.activate()` / `qr.init()`)**: Ideal for IDE users who execute scripts by clicking **Run** or **Debug** in VS Code or PyCharm.
3. **Context Managers (`with qr.run() as run:`)**: Designed for multi-run loops (GridSearch, Optuna, K-Fold cross-validation) where each iteration produces an independent, linked run in the lineage DAG.

---

### 1. Universal & Semantic Logging (`qr.log`, `qr.log_*`)

The SDK provides both explicit `log_*` functions (for strict typing and IDE autocomplete) and a universal `qr.log()` dispatcher with an **optional `type` parameter** (`"metric"` | `"config"` | `"dataset"` | `"artifact"` | `"note"`):

```python
import qr

# 1. Automatic Type Inference (type parameter is optional):
# If type is omitted: dict is logged as "metric", str is logged as "note"
qr.log({"loss": 0.24, "val_acc": 0.942}, step=100, epoch=5)  # Auto-infers type="metric"
qr.log("Model convergence achieved at epoch 5")              # Auto-infers type="note"

# 2. Explicit Type Dispatching (pass type="..."):
qr.log({"learning_rate": 0.001, "batch_size": 32}, type="config")
qr.log({"val_loss": 0.18, "f1_score": 0.92}, type="metric", epoch=10)
qr.log("checkpoints/best_model.pt", type="artifact", kind="model")
qr.log("cifar10", type="dataset", uri="data/cifar10")
qr.log("Learning rate decayed by factor of 0.1", type="note")
```

---

### 2. Hyperparameter Tracking (`qr.log_config`, `qr.params`)

Records training configuration into `manifest.json` and writes `config.json`:

```python
import qr

qr.log_config({
    "learning_rate": 0.001,
    "batch_size": 32,
    "optimizer": "AdamW",
    "weight_decay": 1e-4,
    "backbone": "resnet50",
})

# Or using the shorthand alias:
qr.params({"dropout": 0.2, "seed": 42})
```

---

### 3. Streaming Metrics & Block Timing (`qr.metric`, `qr.log_metric`, `qr.timer`)

Appends numerical metric records to `metrics.jsonl` with real-time Web UI streaming and **adaptive fsync rate-limiting** (eliminates NVMe write stalls during fast batch training loops):

```python
import qr

for epoch in range(1, 11):
    # Measure duration of a specific training phase
    with qr.timer("epoch_duration_seconds"):
        train_loss = train_one_epoch()
        val_loss, val_acc = evaluate()

    # Log metrics with step/epoch tracking (via qr.metric or qr.log_metric)
    qr.metric(
        {"train_loss": train_loss, "val_loss": val_loss, "val_accuracy": val_acc},
        epoch=epoch,
        step=epoch * 100,
    )
```

> **Performance Note**: `qr.metric()` immediately flushes data to the OS stream for live Web UI rendering, while intelligently rate-limiting physical disk `os.fsync()` calls (executed on epoch milestones, explicit `sync=True`, or maximum once per second).

---

### 4. Dataset Declarations & Checksumming (`qr.dataset`, `qr.log_dataset`)

Declares dataset references. For local files or directories, `qr` automatically calculates a streaming SHA-256 fingerprint:

```python
import qr

# Primary shorthand alias:
qr.dataset("processed_features", "data/features.parquet")

# Or declare with explicit checksum:
qr.dataset(
    name="imagenet_val",
    uri="s3://my-bucket/imagenet/val.tar",
    fingerprint="sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
)
```

---

### 5. Artifact Registration (`qr.log_artifact`)

Registers model checkpoints, evaluation charts, or exported weights. Runprint tracks the file size and SHA-256 hash without duplicating heavy files on disk:

```python
import qr

# Register model checkpoint
qr.log_artifact(
    path="checkpoints/best_model.pt",
    kind="weights",
    metadata={"val_accuracy": 0.952, "epoch": 8},
)

# Shorthand alias:
qr.artifact("reports/confusion_matrix.png", kind="plot")
```

---

### 6. In-Code Activation for IDEs (`qr.init()`, `qr.activate()`, `qr.finish()`)

When running experiments directly via your IDE's **Run / Debug** buttons (VS Code, PyCharm, Jupyter) without opening a terminal, **place `qr.init()` at the very start of your training script**:

> **API Note**: Use `qr.init()` for standard explicit run initialization at the start of your training script. `qr.activate()` is an equivalent alias provided for IDE workflow familiarity; `qr.init()` is the recommended primary spelling.

```python
import qr

def main():
    # 🚀 1. Initialize at the VERY START:
    # Immediately creates the run in .qr/runs/, records hardware and git state,
    # marks status as 'running', and begins real-time stdout/stderr streaming to the Web UI!
    qr.init(tag=["baseline", "cifar10"], params={"lr": 0.001, "batch_size": 32})

    # 2. Declare datasets and hyperparameters
    qr.input_dataset("cifar10", "data/cifar10")
    
    # 3. Real-time metric tracking during training (fsynced immediately)
    for epoch in range(10):
        # ... training loop ...
        qr.log({"loss": 0.25, "accuracy": 0.942}, epoch=epoch)

    # 4. Register outputs
    qr.artifact("checkpoints/model.pt", kind="model")

    # 5. Automatic finalization: Python atexit automatically finalizes upon script exit!
    # (or call qr.finish() if you wish to conclude the run early)

if __name__ == "__main__":
    main()
```

#### Why `qr.init()` / `qr.activate()` Must Be Placed at the Start:

- **Instant Web UI Visibility**: The run appears immediately on the Web UI dashboard with a live green `running` indicator from second 0.
- **Live Terminal Log Streaming**: Stdout and stderr are teed and streamed in real-time over Server-Sent Events (SSE) to the Web UI as log lines are printed.
- **Zero Data Loss on Crash or OOM**: Every call to `qr.log()` flushes and `fsync`s metrics directly to disk. If training crashes or is terminated midway (e.g. CUDA OOM or `Ctrl+C`), all preceding epochs and stack traces are safely preserved.
- **Accurate Environmental Snapshots**: Captures the exact Git working tree state, hardware metrics, and environment packages at the moment training begins.
- **Automatic Lifecycle Management**: Runprint automatically registers `atexit` and `sys.excepthook` handlers. When the script exits cleanly, the run is finalized as `completed`; if an unhandled exception occurs, it is recorded as `failed` with exit code `1`.
- **CLI Compatibility**: If executed later via `qr run -- python train.py`, `qr.init()` / `qr.activate()` automatically recognizes the active CLI wrapper session and transparently integrates without creating duplicate runs.

---

### 7. Hyperparameter Sweeps & GridSearch (`with qr.run()`)

For hyperparameter search (GridSearch, Optuna, K-Fold cross-validation), isolate each trial into its own linked run in the lineage DAG:

```python
import qr
from sklearn.ensemble import RandomForestClassifier

param_grid = [
    {"n_estimators": 50, "max_depth": 3},
    {"n_estimators": 100, "max_depth": 3},
    {"n_estimators": 50, "max_depth": 6},
    {"n_estimators": 100, "max_depth": 6},
]

# Parent Session: Represents the overarching sweep
with qr.run(tag="rf_gridsearch", params={"total_trials": len(param_grid)}) as session:
    qr.input_dataset("cancer_data", "data/cancer.csv")

    for i, p in enumerate(param_grid, start=1):
        # Child Run: Automatically linked as a child of `session`
        with qr.run(tag="trial", params=p) as trial:
            model = RandomForestClassifier(**p)
            model.fit(X_train, y_train)
            acc = model.score(X_test, y_test)
            
            trial.log({"trial": i, "accuracy": acc})
            trial.artifact(f"models/rf_{i}.pkl", kind="model")
        # Exiting trial context automatically finalizes that trial run!
```

---

### 8. Reproducibility & Determinism Helper (`qr.seed`)

Achieve maximum deterministic execution across random number generators and GPU hardware kernels:

```python
import qr

# Sets seeds for Python random, NumPy, and PyTorch (including CUDA)
# Automatically configures torch.backends.cudnn.deterministic = True
# and persists seed metadata to manifest.json and config.json
qr.seed(42, deterministic=True)
```

---

### 9. Distributed Training & Multi-GPU (`qr.is_main_process`, PyTorch DDP)

Runprint natively supports distributed training (PyTorch `torchrun` / DDP, SLURM, Horovod, DeepSpeed, Accelerate):

```python
import qr

def main():
    # Only Rank 0 creates the run directory and writes logs.
    # Non-zero worker ranks act as transparent no-ops without file collisions!
    qr.init(tag="ddp_training")

    # Inspect rank explicitly if needed:
    if qr.is_main_process():
        print("Running on primary GPU rank 0")
```

---

### Complete SDK Method & Alias Cheatsheet

| Primary Method | Shorthand Aliases | Description |
| :--- | :--- | :--- |
| `qr.log(data, type=...)` | — | Universal smart logging dispatcher |
| `qr.log_metric(dict, step, epoch, sync)` | `qr.metric`, `qr.metric_log` | Appends metrics with adaptive fsync rate-limiting |
| `qr.log_config(dict)` | `qr.config_log`, `qr.params` | Logs hyperparameters to manifest and `config.json` |
| `qr.log_dataset(name, uri, ...)` | `qr.dataset`, `qr.input_dataset`, `qr.dataset_log`, `qr.data_log` | Declares dataset inputs with streaming SHA-256 |
| `qr.log_artifact(path, kind, ...)` | `qr.artifact`, `qr.artifact_log` | Registers outputs with checksum and size tracking |
| `qr.log_note(text)` | `qr.note` | Appends timestamped annotations to `notes.jsonl` |
| `qr.seed(seed, deterministic=True)` | — | Seeds random, numpy, PyTorch and enables cuDNN determinism |
| `qr.is_main_process()` | — | Returns True on primary rank (Rank 0) in distributed training |
| `qr.timer(name)` | — | Context manager measuring execution duration |
| `qr.activate(tag, params, ...)` | — | In-code runner for IDE Run/Debug executions |
| `qr.init(tag, params, ...)` | — | Explicit run initializer at script start |
| `qr.finish(status, exit_code)` | — | Explicit run finalizer |
| `qr.run(tag, params, parent)` | — | Context manager for multi-run sweeps / trials |

---

## 🛠️ Exhaustive CLI Command Guide

### 1. `qr run` — Execute & Snapshot

Wraps any arbitrary command, logs `stdout`/`stderr`, snapshots code, and records environment:

```bash
# Basic usage
qr run -- python train.py

# With tags and research notes
qr run --tag baseline --tag vision --notes "Batch size 32 with CosineAnnealing" -- python train.py

# Force new run (bypasses duplicate detection and linear versioning)
qr run --force -- python train.py

# Explicit parent linkage for manual lineage chaining
qr run --parent QR-20260918-E90F-v1 -- python train.py

# Override run ID
qr run --run-id MY-CUSTOM-EXPERIMENT-01 -- python train.py
```

---

### 2. `qr ui` — Local Web Hub

Starts the local dashboard server:

```bash
# Start on default port 8765
qr ui

# Specify custom port
qr ui --port 9000

# Headless mode (do not auto-open browser)
qr ui --no-browser
```

---

### 3. `qr list` — Search & Filter History

Lists historical experiment runs:

```bash
# List recent runs
qr list

# Filter by tag
qr list --tag baseline

# Limit output count
qr list --limit 15
```

---

### 4. `qr show` — Inspect Provenance & Score

Prints complete run provenance, code state, hardware, logs, and restorability audit:

```bash
qr show QR-20260918-E90F-v1
```

Includes the **Restorability Audit Checklist**:
- `[✓] Git Commit Recorded (+10 pts)`
- `[✓] Working Tree Clean or Complete Diff Stored (+15 pts)`
- `[✓] All Untracked Source Files Archived (+10 pts)`
- `[✓] Pinned Python Environment (+10 pts)`
- `[✓] Package Lockfile Recorded (+15 pts)`
- `[✓] Verified Dataset Fingerprints (+30 pts)`

---

### 5. `qr rerun` — 1-Click Reproduction Engine

Rerun any historical experiment with preflight reproducibility audits:

```bash
# 1-Click full reproduction (isolated git worktree + isolated virtualenv)
qr rerun QR-20260918-E90F-v1 --reproduce

# Restore exact virtualenv from recorded lockfile into .qr/envs/
qr rerun QR-20260918-E90F-v1 --restore-env

# Execute in an isolated temporary Git worktree
qr rerun QR-20260918-E90F-v1 --isolated

# Bypass dataset fingerprint validation if data was updated intentionally
qr rerun QR-20260918-E90F-v1 --allow-dataset-mismatch

# Bypass environment package drift check
qr rerun QR-20260918-E90F-v1 --allow-env-mismatch
```

Reruns create a linear version child linked in the experiment lineage DAG (`QR-...-v1` ➔ `QR-...-v2`).

---

### 6. `qr diff` — Side-by-Side Run Comparison

Compare code, parameters, duration, and numerical metrics between any two runs:

```bash
qr diff QR-20260918-E90F-v1 QR-20260918-1A96-v2
```

Outputs side-by-side comparison tables highlighting parameter deltas and numerical metric changes (e.g. `accuracy: 0.9250` vs `0.9480 (+0.0230)`).

---

### 7. `qr env` — Package Drift & Cache Management

Inspect environment drift and manage reconstructed virtualenvs:

```bash
# Compare recorded run packages against current active Python environment
qr env diff QR-20260918-E90F-v1

# List all reconstructed virtual environments in .qr/envs/
qr env list

# Clean virtual environments to reclaim disk space
qr env clean --run-id QR-20260918-E90F-v1
qr env clean --all
```

---

### 8. `qr doctor` — Integrity Diagnostics & Auto-Repair

Scans repository health, reconciles interrupted runs, backfills restorability scores, and rebuilds the SQLite index:

```bash
# Scan repository health
qr doctor

# Automatically repair orphaned runs and rebuild index
qr doctor --fix
```

---

### 9. `qr sync` — Cache Synchronization & Multi-Machine Merging

Synchronize SQLite index cache with experiment runs on disk, import runs from external machines or backups, and prune dangling records:

```bash
# Incrementally sync unindexed runs from .qr/runs into SQLite
qr sync

# Copy and merge runs from an external directory (USB drive, another machine, or backup)
qr sync --from /path/to/other/project/.qr/runs

# Sync without pruning deleted runs
qr sync --no-prune
```

*Note: Runprint also applies **Zero-Friction Auto-Sync** automatically whenever `qr list` is invoked or the Web UI Hub is refreshed if filesystem runs differ from the SQLite index.*

---

## 🔬 Core Architectural Concepts

### 1. Multi-Dimensional Execution Fingerprint & Provenance Audit

To balance fast deduplication with granular change detection, Runprint separates **Execution Fingerprinting** from **Multi-Dimensional Provenance Auditing**:

#### Controllable Execution Fingerprint
Computed across primary controllable execution inputs:
$$\text{Fingerprint} = \text{SHA256}(\text{Command} \parallel \text{Git Commit} \parallel \text{Git Dirty} \parallel \text{Parameters} \parallel \text{Datasets})$$

#### Multi-Dimensional Provenance Audit
During run initialization (`qr run` or Web UI `+ New Run`), Runprint audits four distinct dimensions (**Code**, **Parameters**, **Datasets**, and **Runtime Environment**), categorizing the execution into:

- **Identical Run (100% Match)**: Identical execution fingerprint and matching environment. Warns in UI and CLI; provides 1-click options to view existing results or re-run as a new version `v2`.
- **Sister Run (Parameter Sweep)**: *A sister run shares the exact same code entrypoint and Git commit, but differs in hyperparameters or input configurations (e.g. learning rate or batch size sweeps).* Runprint computes exact parameter deltas (`changed`, `added`, `removed`) and links the run as a sibling in the lineage DAG.
- **Code Drift**: Same script entrypoint, but the code has changed since the last execution. Runprint archives a fresh code snapshot and uncommitted diff.
- **Environment Drift**: Same code and parameters, but executed on a different package lockfile or Python version.

### 2. Experiment Lineage DAG & Sister Runs

Experiments are organized as a Directed Acyclic Graph (DAG):
- **Linear Versions**: Re-running an experiment creates `v2`, `v3`, etc. linked directly to its parent run.
- **Tree View by Script & Commit**: Groups runs hierarchically: `Script Entrypoint` ➔ `Git Commit` ➔ `Sister Runs & Versions`.
- **Sister Runs**: Distinct trials sharing the same base code that can be compared side-by-side with 1 click.

### 3. AST Core Dependencies vs. Full Lockfile

Modern Python environments often contain 150–300 packages. When reviewing an experiment, you want to know what the script *actually* imports.
- **AST Direct Package Detection**: Parses script source code using `ast.parse`, discards standard library modules (`sys.stdlib_module_names`), and maps top-level imports to PyPI distribution names (`direct-packages.txt`).
- **Complete Lockfile**: Stores `pip-freeze.txt` alongside direct packages for deterministic environment restoration.

### 4. Deep Hardware & OS Diagnostics

Captures bare-metal hardware configuration using zero-dependency platform queries:
- **CPU**: Model, driver version (`Win32_PnPSignedDriver`), physical cores, logical threads, max clock, L3 cache, socket designation.
- **RAM**: Total capacity, configured bus speed (MHz/MTs), module count, and per-slot topology (capacity, speed, manufacturer, part number).
- **GPU**: Device names, driver version, dedicated VRAM (MB), CUDA compute capability, VBIOS version.

### 5. Restorability Scoring Rubric (0 – 100)

| Pillar | Max Pts | Criteria |
| :--- | :--- | :--- |
| **Source Code** | **35 pts** | Valid Git commit (+10), clean tree or complete `git.diff` (+15), untracked source files captured (+10) |
| **Environment** | **35 pts** | Pinned Python version (+10), package lockfile recorded (+15), zero non-standard local dependencies (+10) |
| **Data & Inputs** | **30 pts** | Pure compute with no external data (+30), OR all datasets declared (+10) with verified SHA-256 fingerprints (+20) |

- `90 - 100`: **HIGHLY_RESTORABLE** (Green)
- `70 - 89`: **PARTIALLY_RESTORABLE** (Yellow)
- `< 70`: **LOW_RESTORABILITY** (Red)

> **Audit Heuristic Note**: The Restorability Score (0 – 100) is a **metadata completeness heuristic** (evaluating how thoroughly code, environment, and dataset provenance were captured), not a mathematical guarantee or probability of successful execution.

---

## 📂 Storage Layout & Manifest Schema

All data is self-contained inside your repository under `.qr/`:

```text
my-project/
├── train.py
├── configs/
├── .git/
└── .qr/
    ├── project.json                 # Project configuration
    ├── index.sqlite                 # Fast local index cache (auto-rebuildable)
    ├── envs/                        # Cached virtual environments for reproduction
    ├── worktrees/                   # Temporary checkouts for isolated reruns
    └── runs/
        └── QR-20260918-E90F-v1/
            ├── manifest.json        # Machine-readable provenance manifest (Schema v0.1)
            ├── config.json          # Parsed hyperparameters & config
            ├── git.diff             # Uncommitted diff patch (binary & untracked files)
            ├── stdout.log           # Full captured stdout stream
            ├── stderr.log           # Full captured stderr stream
            ├── metrics.jsonl        # Streaming metric records with timestamps
            ├── artifacts.json       # Registered artifact references & checksums
            ├── notes.jsonl          # Timestamped experiment notes
            └── environment/
                ├── direct-packages.txt   # Core packages imported by script
                ├── direct-packages.json  # AST-resolved distribution mapping
                └── pip-freeze.txt        # Full environment freeze
```

---

## 🛡️ Quality Assurance & Security

- **Automated Test Audit**: Runprint is validated with an exhaustive **68-test automated suite** covering subprocess isolation, Git dirty diffing, AST import detection, SQLite auto-reconciliation, and virtualenv reproduction. See [TESTING.md](TESTING.md).
- **Air-Gapped & Local-First Security**: **100% offline operation** with zero telemetry and zero external network calls. Built and published via cryptographic PyPI Trusted Publishing (OIDC). See [SECURITY.md](SECURITY.md).

---

## 📄 License

Licensed under the [Apache License, Version 2.0](LICENSE).
