The hillclimb dir
One folder per project, and the run specs that describe its searches.
All hillclimb data lives in one hillclimb/ folder inside your project, so it never mingles with
the rest of the repo. hillclimb init creates it:
my-project/
└── hillclimb/
├── config.yaml # defaults, and the marker that makes this the hillclimb dir
├── problems/ # problem definitions
├── specs/ # committed run specs (versioned run parameters)
└── runs/ # search artifacts (gitignored by init)Commands work from any subdirectory — the hillclimb dir is found by upward search for
hillclimb/config.yaml (like git). Without one, commands error and point you at hillclimb init;
HILLCLIMB_DIR pins it explicitly.
Config precedence, highest first: CLI flags → the hillclimb dir's config.yaml → user
~/.config/hillclimb/config.yaml → built-in defaults.
Machine-scoped state is shared across hillclimb dirs under ~/.cache/hillclimb/ (honors
XDG_CACHE_HOME; HILLCLIMB_CACHE_DIR overrides): solution-runtime venvs keyed by a hash of
their requirements (rebuilt automatically when requirements change), the emflow problem cache, and
the cross-search agent semaphore. Checkouts predating this layout left .runtime-venv*/ and
cache/ in the project dir — safe to delete.
Run specs: versioned run parameters
The canonical way to run is a committed spec file, so the repo fully describes its searches
(git log explains every run). Entries carry per-search parameters; CLI flags override them for
ad-hoc experiments:
problems:
- target: emflow://gefcom2014:solar
model: opus
budget: 2h
parallel_agents: 3
- target: emflow://gefcom2014:wind
budget: 1huv run hillclimb run hillclimb/specs/gefcom.yaml # exactly as committed
uv run hillclimb run hillclimb/specs/gefcom.yaml --model sonnet # ad-hoc overrideA spec with a single top-level target: (plus the same parameter keys) runs one search. run.yaml
records which spec launched the run.