Skip to main content

stooge

Stooge is a small CLI and Python framework for reproducible local research projects. It discovers dependencies between numbered scripts and runs only the tasks whose declared outputs are missing or stale.

Stooge requires Python 3.12 or newer. Supported execution backends are uv and the current Python interpreter.

Project structure

Task scripts use canonical IDs such as a010_clean.py and a020_calculate.py. Paths are declared in local.py. A path is an output when its variable name or filename starts with the current script's task ID; other referenced paths are inputs.

my_project/
├── inputs/raw.csv
├── local.py
├── a010_clean.py
└── a020_calculate.py

Stooge reads local.py statically and never executes it. Its deliberately narrow contract supports top-level path assignments built from:

  • Path("literal") or Path(__file__).parent, including .parent chains;
  • an earlier path variable joined to string literals with /; and
  • a simple alias of an earlier path variable.

Keep local.py free of side effects and project-module imports. Output parent directories are created immediately before their producing task runs.

Parsing produces a deterministic .stooge.toml containing the backend, source hashes, artifact paths, and direct task dependencies. Generated projects also include a short AGENTS.md with these conventions.

Initialize, parse, and inspect

The uv backend is the default and includes a minimal pyproject.toml.

stooge init my_project --backend uv
stooge parse my_project
stooge parse my_project --dry-run
stooge info my_project
stooge info my_project --json

Use --backend python to run tasks with the interpreter that launched Stooge. info is read-only and can inspect a project before its manifest exists.

Parsing rejects dynamic path expressions, duplicate task IDs, duplicate output producers, dependency cycles, tasks without outputs, and outputs outside the project root.

Plan and run

Commands accept an optional project path, so changing directories is not required:

stooge run a030 my_project --dry-run
stooge run a030 my_project
stooge run a030 my_project --json

A task is stale when an output is missing, its script content hash changed, or its newest input is newer than its oldest output. Script mtimes alone do not trigger work. A local.py edit only rebuilds tasks whose parsed definitions change. When an upstream task runs, affected downstream tasks are rebuilt.

  • --dry-run reports the ordered plan and a reason for each task without writing the manifest or outputs.
  • --force always reruns the target in addition to stale dependencies.
  • --force-all reruns the target's entire upstream closure.
  • --debug executes selected scripts under the standard-library debugger.

Override local paths for one run

For debugging, run can temporarily swap local.py path values without editing any project file:

stooge run a030 my_project --set output_path=/tmp/stooge_debug --dry-run --json
stooge run a030 my_project --set output_path=/tmp/stooge_debug --set input_path=alt_inputs
stooge run a030 my_project --local-file debug_local.py
  • --set name=path is repeatable. Relative paths resolve against the project root. Unknown names fail with the list of available variables.
  • --local-file points at a python file following the same static contract as local.py. Variables matching names in local.py become overrides; other variables are helpers and are ignored. --set wins on conflicts.
  • Derived variables are recomputed: overriding output_path also moves every path defined from it (e.g. a030_result = output_path / "result.png"), both when planning and inside the executing script.
  • Overridden runs are ephemeral: the manifest is never written, no execution fingerprints are recorded, and fingerprint-based staleness is skipped (plans rest on missing outputs and mtimes at the overridden locations). A later plain stooge run behaves as if the overridden run never happened.
  • Overridden outputs may resolve outside the project root (e.g. /tmp).
  • Works with --dry-run, --json, and --debug.

Remove outputs

Remove or preview only the outputs declared by one task:

stooge remove a020 my_project --dry-run
stooge remove a020 my_project
stooge remove a020 my_project --json

Downstream results are retained and rebuilt when required by a later run. Files, symlinks, and output directories are supported. Stooge refuses to remove the project root or paths outside it.

JSON output

Every command except version accepts --json. The envelopes are a stable contract for scripts and agents:

  • Success: {"command": "<name>", "ok": true, ...} with command-specific fields.
  • Failure: {"command": "<name>", "ok": false, "kind": "<kind>", "error": "<message>"} written to stdout with exit status 1. kind is one of parse_error, task_not_found, run_error, init_error, or error, so callers can branch without parsing the message.
  • When run fails partway through a plan, the failure envelope also includes executed: the task IDs that completed (and were recorded in the manifest) before the failure.
  • run --dry-run never fails on a missing raw input; the plan reports it as a missing_input reason so a build can always be previewed.
  • When --set/--local-file overrides are active, run envelopes include "overrides": {name: path} and "ephemeral": true.

Development

pip install -e '.[test]'
pytest
ruff check .
ruff format --check .

Stooge is optional by design: scripts remain directly executable in task-ID order. The supported Python API is listed in stooge.__all__.

Metadata

Release files for stooge 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for stooge 0.1.1
File Size Uploaded Provenance Actions
stooge-0.1.1.tar.gz 57.3 kB With provenance Details for stooge-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for stooge 0.1.1
File Interpreter ABI Platform Actions
stooge-0.1.1-py3-none-any.whl Python 3 none any Details for stooge-0.1.1-py3-none-any.whl

Total release size: 88.0 kB

Release files / stooge-0.1.1.tar.gz

Download URL stooge-0.1.1.tar.gz
Size 57.3 kB
Tags Source
SHA-256 checksum
How to use checksums
66cdc3d6f18dff2fb90d0736401dd584d8a9a5cad9c464709a3bc4d7c8474de4
BLAKE2b-256 checksum
How to use checksums
9042cb98f65a1c900cef467c310c415e53b0aee31cdbe0f424814973ee5eaa37
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / stooge-0.1.1-py3-none-any.whl

Download URL stooge-0.1.1-py3-none-any.whl
Size 30.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
242d69db2964c2cded0b81592705fc723e8b407f2945996331221c6ef72f1290
BLAKE2b-256 checksum
How to use checksums
aaef3a9c0cc0a72c8fac176d865c491f66dcfc4fe982e0a3bf5562f9d079c9b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Security for stooge 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for stooge-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page