# ADR-0001 — Python 3.11+, distributed for `uvx`

**Status:** accepted · **Date:** 2026-07-26

## Context

Constraint: usable in under five minutes, no signup. The tool shells out to agent CLIs, manages
git worktrees, does numerical statistics, and renders terminal reports.

## Decision

Python 3.11+, published to PyPI, with `uvx ablate` as the documented entrypoint. Dependencies
limited to `click`, `rich`, `pydantic`, `numpy`, `PyYAML`. No `scipy`, no `pandas`, no
`tree-sitter`.

## Rejected: Go (single static binary)

The strongest alternative, and the best answer on distribution: one binary, no runtime, instant
start, trivial GitHub Action packaging.

Rejected because the statistics are the product. BCa bootstrap, ridge with task fixed effects,
and design-matrix conditioning are ~150 lines of numpy and several hundred lines of hand-rolled
Go linear algebra that I would then have to test, for a solo maintainer, in the part of the
codebase where a bug is a silent wrong answer rather than a crash. Correctness of the statistics
outranks elegance of distribution. `uvx` closes most of the distribution gap.

## Rejected: TypeScript / npm

`npx ablate` is the best install story in this ecosystem (AgentLinter proves it) and both agent
CLIs are Node-adjacent. Rejected for the same reason as Go, more acutely: the numerical ecosystem
is weak, and I'd be writing bootstrap resampling and ridge regression by hand in a language with
no established, trustworthy implementations to check against.

**Revisit if** adoption stalls specifically on install friction. A thin `npx ablate` shim that
bootstraps `uv` is a cheap hedge and is worth doing at v1.1 regardless.

## Rejected: building inside inspect-ai

Tempting — it already has `--epochs`, bootstrap scoring, and a good log format
([01-prior-art.md](../01-prior-art.md)). Rejected because its `Sample`/`Solver`/`Scorer`
abstraction fits poorly over "clean git worktree per trial with a swapped config file," because
it drags in a large dependency tree that visibly hurts `uvx` cold start, and because the
statistical layer I need (paired cluster bootstrap with a four-verdict equivalence taxonomy) is
not what its metrics API is shaped for. Adapting it would cost more than writing it.

## Consequences

- Cold `uvx` start is ~2–4s. Acceptable; `ablate demo` must feel instant after that, so the demo
  fixture is bundled, not downloaded.
- The GitHub Action needs a `setup-uv` step rather than shipping a binary. Minor.
- Keeping the dependency list short is a **standing constraint**, not a one-time choice. Adding
  scipy or pandas later would silently regress the five-minute promise.
