Skip to main content

Local-first experiment history CLI.

Project description

Trace CLI Agent Reference

This repository contains Trace, a cloud-hosted experiment history tool with local command capture.

Install The CLI

For normal cloud-hosted onboarding, install the published CLI:

pip install origami-trace

You can also run the published CLI without a persistent install:

uvx --from origami-trace otrace --help

Cloud onboarding

Trace uses Supabase Auth for browser sign-up and sign-in. The CLI syncs a local project workspace with a cloud project by using a project-scoped Trace API key created from the cloud-first React app.

For local app development, serve the static React app:

cd /Users/alansong/Documents/Projects/origami/trace
python3 -m trace_cli.cli ui

Open:

http://localhost:8000/account

Use the app to sign up or sign in with Google, create a project, then create a project API key. Copy the trc_... key when it appears; it is shown only once.

Initialize your local workspace with that key:

export TRACE_API_KEY="trc_your_key_here"
cd /path/to/research-project
otrace init
otrace whoami

otrace init validates the API key, initializes .trace/, and syncs the current workspace to the cloud project tied to the key. OTrace does not write .env; it prints the values to add if you want future shells to use workspace-local credentials. otrace whoami should print the account email, project, and API key prefix. otrace run prints the RunSpec filepath being used, validates the API key, and creates a hosted run before local command execution. If hosted run creation fails, the experiment command is not executed.

Create a hosted experiment:

otrace run \
  --intent "Smoke test Trace hosted experiment creation" \
  --setup "Fresh Trace project with a minimal shell command" \
  --expect-log outputs/smoke.log \
  -- sh -c 'mkdir -p outputs && echo ok | tee outputs/smoke.log'

For local development from this repository, use the repo-local wrapper from notebook/:

cd /Users/alansong/Documents/Projects/origami/trace/notebook
export TRACE_API_KEY="trc_your_key_here"
otrace init
otrace whoami
otrace run \
  --intent "Smoke test Trace hosted experiment creation" \
  --setup "Fresh Trace project with a minimal shell command" \
  --expect-log outputs/smoke.log \
  -- sh -c 'mkdir -p outputs && echo ok | tee outputs/smoke.log'

For local development of this repository, use an editable install:

python3 -m pip install -e .

Or run the repo checkout directly with uvx:

uvx --from . otrace --help

After installation, run otrace from any research project directory:

cd /path/to/research-project
export TRACE_API_KEY="trc_your_key_here"
otrace init
otrace run \
  --intent "Train baseline" \
  --setup "Baseline training from the default config" \
  --config configs/base.yaml \
  --expect-artifact outputs/metrics.json \
  -- python train.py

Check that the installed command is available:

which otrace
otrace --help

If otrace is not found, put your Python environment's bin directory earlier on PATH or reinstall the CLI:

otrace init
otrace run \
  --intent "Train baseline" \
  --setup "Baseline training from the default config" \
  --config configs/base.yaml \
  --expect-artifact outputs/metrics.json \
  -- python train.py

Trace stores durable experiment state in Supabase. Runtime logs and snapshots are written under .trace/ while commands execute; that directory should not be committed. otrace init also writes TRACE_FOR_AGENTS.md into the project root so backend-agnostic coding agents can learn the Trace workflow.

The repo-local wrapper still works:

cd notebook
otrace <command>

Quick Command Index

Command Purpose
otrace init Validate a project API key, initialize local Trace state, and sync the workspace to its cloud project.
otrace run --intent "..." --setup "..." --expect-artifact PATH -- <command> Run a command and save it as a new experiment node.
otrace import --spec PATH [--dry-run] Replace the current hosted project's runs with a Trace-native historical run manifest.
otrace checkout EXP_ID [--path PATH] Create a reproducible checkout for an experiment.
otrace export [--format zip] [--output PATH] Zip the project working tree and runtime Trace files for moving between machines.
otrace ui [--port PORT] Start the cloud-first localhost app.
otrace notebook generate [--mode MODE] [--output PATH] Generate a markdown notebook from Trace data.

Working Directory Rule

Run otrace from the project whose experiments should be tracked:

cd /path/to/research-project

The CLI records paths, snapshots git state, uploads durable records to Supabase, and runs experiment commands relative to the current working directory.

For the bundled CIFAR-10 example, the project root remains:

cd /Users/alansong/Documents/Projects/origami/trace/notebook

Initialize Trace

otrace init

Creates:

.trace/
  checkouts/
  logs/
  notebook/
  snapshots/
.traceignore
TRACE_FOR_AGENTS.md

otrace init validates the project API key and syncs workspace metadata to the cloud project. OTrace does not create or update .env. If you want future shells to run OTrace without passing --api-key, add the printed TRACE_* values to your shell or workspace-local .env yourself.

OTrace does not edit .gitignore.

Options:

export TRACE_API_KEY="trc_your_key_here"
otrace init
otrace init --api-key "trc_your_key_here"
otrace init --api-url "$TRACE_API_URL" --api-key "trc_your_key_here"
otrace init --force --api-key "trc_your_key_here"

--api-key is useful for a one-time bind. Future otrace whoami and otrace run commands still need TRACE_API_KEY in the shell or a user-managed .env.

Notes for agents:

  • Do not commit .trace/; it contains runtime logs, snapshots, generated notebooks, and checkouts.
  • If the user stores Trace credentials in .env, do not commit it; it contains the project API key.

Run An Experiment

otrace run normalizes the requested run into a RunSpec. By default, each project uses otrace_<project-name>_runspec.yaml, where <project-name> is the sanitized project directory name. OTrace prints the RunSpec filepath it is using and does not ask for confirmation by default. If no default RunSpec exists, a flag-based run writes that YAML file after the run record exists.

Use --verify-runspec to render the RunSpec and require Y/N before OTrace resolves credentials, syncs workspace metadata, creates the hosted run, or executes the command.

otrace run \
  --intent "Describe why this run exists" \
  --setup "Describe the relevant setup and assumptions" \
  --config PATH \
  --expect-artifact PATH \
  -- <command> [args...]

Example:

otrace run \
  --intent "Smoke test Trace capture" \
  --setup "Fresh Trace project with a minimal Python command" \
  --expect-log outputs/smoke.log \
  -- sh -c 'mkdir -p outputs && echo ok | tee outputs/smoke.log'

Users or agents can generate a RunSpec YAML file and maintain it themselves. Agents can validate the equivalent RunSpec object with the side-effect-free trace_validate_run_spec MCP tool when useful:

version: 1
intent: "Train baseline"
setup: "Default config on the validation split"
command:
  - "python"
  - "train.py"
  - "--config"
  - "configs/base.yaml"
config_paths:
  - "configs/base.yaml"
expected_artifact_paths:
  - "outputs/metrics.json"
expected_log_paths:
  - "outputs/train.log"
title: "Baseline"
tags:
  - "baseline"
otrace run --spec otrace_my-project_runspec.yaml

Options:

otrace run --intent "..." --setup "..." --config PATH --expect-artifact PATH -- <command>
otrace run --intent "..." --setup "..." --expect-log PATH --title "Short display title" -- <command>
otrace run --intent "..." --setup "..." --expect-artifact PATH --tag baseline --tag ablation -- <command>
otrace run --spec otrace_my-project_runspec.yaml
otrace run --verify-runspec

Behavior:

  • Prints the RunSpec filepath used for the run.
  • Renders a RunSpec preview only when --verify-runspec is passed.
  • Validates hosted auth and creates the hosted run record before executing the wrapped command.
  • Does not execute the wrapped command if hosted run creation fails.
  • Captures declared --config paths as config artifacts.
  • Creates the next experiment ID, such as exp001.
  • Captures git commit, dirty diff, staged diff, dependency file copies, Python version, platform, stdout/stderr logs, exit code, duration, and a deterministic summary.
  • Captures files declared by --expect-artifact and --expect-log after the command exits and uploads them with the hosted run details.
  • Sets the new experiment as the active experiment after the run.
  • Returns the wrapped command's exit code.

Dependency files captured when present:

requirements.txt
pyproject.toml
environment.yml
environment.yaml
poetry.lock
uv.lock
Pipfile
Pipfile.lock

The command must appear after --. If omitted, Trace errors with:

No command provided. Use `otrace run --intent ... -- <command>`.

Import Historical Runs

Use otrace import --spec <spec> to import historical experiments into the current hosted Trace project without re-running them. The spec is a Trace-native JSON manifest authored by you or an agent. File paths are resolved relative to the manifest file unless they are absolute.

Import is project-replacing: if the current hosted project already has runs, OTrace asks for confirmation, deletes those project runs, then imports the manifest. Use --dry-run first to validate the manifest without checking credentials, deleting runs, or writing to the cloud.

Dry-run a manifest before writing to the cloud:

otrace import --spec trace-import.json --dry-run

Import after validation:

export TRACE_API_KEY="trc_your_key_here"
otrace import --spec trace-import.json

Manifest example:

{
  "version": 1,
  "runs": [
    {
      "title": "baseline linear regression",
      "intent": "Train a toy linear regression model",
      "setup": "Synthetic one-feature regression with gradient descent",
      "command": "python3 train.py",
      "status": "completed",
      "created_at": "2026-06-01T12:00:00Z",
      "started_at": "2026-06-01T12:00:01Z",
      "finished_at": "2026-06-01T12:00:04Z",
      "exit_code": 0,
      "duration_seconds": 3.0,
      "tags": ["historical", "baseline"],
      "artifacts": [
        { "path": "outputs/baseline/metrics.json", "type": "metrics" },
        { "path": "outputs/baseline/model.json", "type": "other" }
      ],
      "logs": [
        { "path": "logs/baseline.log", "stream": "stdout" }
      ],
      "result_files": [
        "outputs/baseline/metrics.json"
      ],
      "results": [
        { "kind": "scalar", "name": "manual_metric", "value": 42, "source_path": "notes.md" }
      ],
      "tables": [],
      "snapshot": {
        "git_commit": "abc123",
        "python_version": "3.12"
      }
    }
  ]
}

Required per run: intent, setup, command, and status. status must be one of created, running, completed, failed, or capture_failed. Use artifacts for files that should be stored with the run, logs for log text, and result_files for JSON/CSV/TSV/text files Trace should parse into scalar results and tables. Explicit results and tables are preserved as provided. For large checkpoints or model files, add "store_content": false to the artifact entry so Trace records the path, type, size, and hash without inlining the file contents into the database.

Attach Artifacts

Captured Outputs

Declare outputs before the run starts:

otrace run \
  --intent "Train baseline" \
  --setup "baseline config" \
  --expect-artifact outputs/results.csv \
  --expect-artifact outputs/grid.png \
  --expect-log outputs/train.log \
  -- python train.py

Behavior:

  • Globs are expanded after the wrapped command exits.
  • Each matched artifact path must be a file.
  • Files are copied into .trace/artifacts/<EXP_ID>/.
  • Missing expected paths are recorded on the run instead of failing the command.
  • Captured artifacts, parsed results, logs, and snapshot metadata are uploaded to the hosted run details endpoint.

Common artifact types are inferred from file suffix and expected path kind:

metrics
figure
log
other

Checkout An Experiment

otrace checkout EXP_ID

Default destination:

../<project-name>.trace-checkouts/<EXP_ID>/

Options:

otrace checkout EXP_ID --path /absolute/or/relative/path
otrace checkout EXP_ID --in-place

Important:

  • --in-place is declared but intentionally not automated in the MVP; it returns an error.
  • The destination must be empty or absent.
  • Prefer --path when an agent needs a predictable checkout location.

Behavior:

  • Creates a git worktree at the captured commit when possible.
  • Falls back to copying the repo without .trace, .git, or __pycache__ if worktree creation fails.
  • Applies the captured dirty diff when present.
  • Copies captured dependency files.
  • Copies captured artifacts into trace-artifacts/.
  • Writes reproduce.sh.
  • Writes trace-reproduction.md.

After checkout:

cd <checkout-path>
bash reproduce.sh

Export A Project Snapshot

otrace export --format zip

Options:

otrace export --output path/to/snapshot.zip
otrace export --output path/to/snapshot.zip --force
otrace export --exclude examples --exclude "*.pt"
otrace export --no-default-excludes

Behavior:

  • Zips the project working tree, including .git/ and the complete .trace/ directory.
  • Preserves runtime Trace files such as logs, snapshots, notebook files, and ledgers. Durable experiment history lives in Supabase.
  • Skips rebuildable/heavy paths by default, including .venv/, venv/, env/, node_modules/, Python caches, test caches, build/, and dist/.
  • Adds trace-export-manifest.json with export metadata.
  • Adds TRACE_EXPORT_README.txt with restore steps.
  • Skips the snapshot ZIP file itself while the archive is being written.
  • Use repeated --exclude flags for additional bulky paths, or --no-default-excludes if you really want every rebuildable dependency copied too.

Start The Web UI

otrace ui

Default URL:

http://localhost:8000

Option:

otrace ui --port 4321

Behavior:

The alpha app is cloud-first. Use it for account sign-in, project creation, project API keys, workspace sync metadata, and hosted run records.

  • Serves the installed Trace UI with the selected port.
  • Uses the current working directory as the traced project.
  • Serves the Trace React UI and JSON APIs.
  • This command is long-running.

Generate Notebook

otrace notebook generate

Options:

otrace notebook generate --mode chronological
otrace notebook generate --mode branch
otrace notebook generate --mode insights
otrace notebook generate --output path/to/notebook.md

Modes:

Mode Behavior
chronological Includes all experiments ordered by creation time. This is the default.
branch Includes the active experiment, its ancestors, and its descendants.
insights Includes experiments with at least one #insight note.

Default output:

.trace/notebook/generated.md
.trace/notebook/generated.json

The generated notebook is deterministic and based on structured Trace data. It explicitly says when no metrics file was captured or parsed.

Active Experiment Rules

Commands that maintain local active experiment state:

run

Resolution behavior:

  • Every successful run sets the new experiment as active.
  • Local post-run mutation commands have been removed; use a new hosted run to capture additional outputs.

Common Agent Workflows

Initialize and capture a smoke run:

cd notebook
export TRACE_API_KEY="trc_your_key_here"
otrace init
otrace whoami
otrace run \
  --intent "Smoke test Trace capture" \
  --setup "Fresh Trace project with a minimal Python command" \
  --expect-log outputs/smoke.log \
  -- sh -c 'mkdir -p outputs && echo ok | tee outputs/smoke.log'

Capture outputs in the run declaration:

otrace run \
  --intent "Capture baseline outputs" \
  --setup "Baseline training with expected metrics and logs" \
  --expect-artifact outputs/results.csv \
  --expect-log outputs/train.log \
  -- python3 train.py

Reproduce a prior experiment in a separate directory:

otrace checkout exp001 --path /tmp/trace-exp001
cd /tmp/trace-exp001
bash reproduce.sh

Error Handling Notes

Common errors and fixes:

Error Fix
Trace is not initialized. Run \otrace init` first.` Run otrace init from the project root.
Supabase schema error Apply docs/supabase/trace_cloud.sql in the Supabase SQL editor.
Unknown experiment: EXP_ID Query existing experiments via UI/API.
Artifact path is not a file Pass file paths or globs that resolve to files.
Checkout destination is not empty Choose an empty path with --path.

Machine-Readable Command Shapes

otrace init [--force] [--api-key KEY] [--api-url URL]
otrace login [--api-key KEY] [--api-url URL]
otrace whoami
otrace run --intent TEXT --setup TEXT (--expect-artifact PATH | --expect-log PATH) [--title TEXT] [--tag TAG ...] -- COMMAND [ARG ...]
otrace import --spec PATH [--dry-run] [--continue-on-error]
otrace checkout EXP_ID [--path PATH] [--in-place]
otrace export [--format zip] [--output PATH] [--force] [--exclude PATTERN ...] [--no-default-excludes]
otrace ui [--port PORT]
otrace notebook generate [--mode chronological|branch|insights] [--output PATH]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

origami_trace-0.1.0.tar.gz (120.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

origami_trace-0.1.0-py3-none-any.whl (130.6 kB view details)

Uploaded Python 3

File details

Details for the file origami_trace-0.1.0.tar.gz.

File metadata

  • Download URL: origami_trace-0.1.0.tar.gz
  • Upload date:
  • Size: 120.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for origami_trace-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d5c71156c549cdd9e15db3ac4635919137b241e19265d59f6ad3f10920792147
MD5 788f4eb6aa99660806c56167197e8110
BLAKE2b-256 c2c5b9c9e5307a8db6b61ff617eb57db7ee0bf9af2ba418b6458631c7a6cb4c5

See more details on using hashes here.

File details

Details for the file origami_trace-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: origami_trace-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 130.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for origami_trace-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c774931be8a0ecc8f02f71571cfe753943bdb4d97ed45bd60983a4e0419c4aa6
MD5 1c08c5f04065e8e48207f9fe9bc1fc44
BLAKE2b-256 4f5ea66b263283d3377cc77c5ffab139f5f7de0b2d21fe98e3259e699c9b0d55

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page