Run and artifact store¶
Runs and artifacts are referenced by id, not by path. A store is a directory tree on one machine in which every run and every sealed artifact has a global id; configs name ids, and each machine resolves them to its own paths (RFC-0005, part 2). The store also refuses to delete anything that something else still refers to, and copies runs and artifacts between machines.
Ids name content; the index records what each artifact was built from and what each campaign refers to; push and pull copy entries between machines.
Set up the store¶
uv run hylo store init bench/runs # this machine's store, recorded in the profile
uv run hylo store where
uv run hylo store ls # every run and artifact, by id
uv run hylo store ls --kind artifact --json
The store root is, in order: --root on the command line, $HYLO_STORE, store: in this machine's
execution profile, and otherwise ./runs relative to the working directory.
Ids¶
| Id | Names |
|---|---|
run:<run_id> |
a run (a directory with evallog.json); run ids already end in a random suffix |
artifact:<name>@<digest> |
a sealed artifact (a directory with artifact.json): its manifest name and content digest |
artifact:<name>@<prefix> |
the same, with a digest prefix of at least 8 hex characters |
artifact:<name> |
allowed only while exactly one artifact has that name |
uv run hylo store ref bench/runs/judges/l10-trace-v2 # -> artifact:l10-trace-v2@54a1efadf00d34d8
uv run hylo store show artifact:l10-trace-v2 # entry, path on this machine, what it was built from, referrers
An id that is not found lists the ids with the same name; an ambiguous one lists the candidates; an id that was removed says when and why.
Reference artifacts in configs¶
agent:
type: remote
params:
ref: lerobot.noise_steered
runtime: lerobot
params:
repo_id: lerobot/smolvla_libero
memory: {type: action_bank, params: {path: "artifact:l10-noise-search-v1@2687768fc5102b06", frozen: true}}
- The experiment digest is taken over the id, so it pins the artifact's content, not where it is.
- The registry replaces ids with this machine's paths when it builds a component, after the digest was taken. A plugin still receives a path; nothing in a plugin changes.
- The run's
manifest.jsonrecords every id the config used, with the full id and the path it resolved to (artifacts:), so a name-only id is pinned after the fact. - Learner job inputs accept run ids (
"inputs": ["run:<run_id>"]). - The gate resolves ids in candidate patches, checks that the content still has the referenced digest, and refuses
behaviour artifacts whose provenance is unknown. Generators that seal artifacts (
learn,critic.chunk_value) put ids, not paths, into candidates.
The index and what refers to what¶
<root>/.hylo-store/index.json is a cache, rebuilt by walking the tree whenever an id is not found (hylo store index
rebuilds it explicitly). Besides ids and paths it records references:
- an artifact refers to what it was built from (its provenance: runs and other artifacts);
- a campaign (
campaign:<path>) refers to every run and artifact its archive or promotion ledger names: by id, by a path inside an entry, or by a run id appearing in a path recorded on another machine.
Delete safely¶
uv run hylo store rm run:<run_id>
uv run hylo store rm artifact:old-critic@1a2b3c4d --force --reason "superseded by l10-v2"
hylo store rm refuses while anything refers to the entry, and lists what does. --force deletes anyway. Either way a
tombstone in <root>/.hylo-store/tombstones.jsonl records what was removed, when, why and what referred to it, so a
later lookup of that id says it was removed instead of "not found".
Warning
Do not delete run directories by hand: an artifact's provenance or a campaign's archive may still name them.
Move runs and artifacts between machines¶
uv run hylo store pull robot-host:/home/lab/runs # runs recorded on the robot computer
uv run hylo store push gpu-box:/data/runs artifact:l10-trace-v2@54a1efad --with-sources
uv run hylo store push /mnt/backup/runs --dry-run # what would be copied
| Option | Meaning |
|---|---|
LOCATION |
PATH or HOST:PATH (ssh and rsync) |
IDS ... |
what to copy (default: everything) |
--with-sources |
also what the selected artifacts were built from |
--dry-run |
print the plan |
--remote-wc |
the hylo command on the other machine (default hylo) |
The other side is listed with its own hylo store ls --json, so hylo must be installed there. Sealed artifacts are
never re-copied or overwritten. The same path holding a different entry on the other side is a conflict, and then
nothing is copied. Runs and mutable artifacts (such as lesson books) are brought up to date.
Not yet
Sync has been tested between two local stores only, not yet over ssh. Studio shows ids but still walks
directories for its listings, and workcell output_dir and campaign out_dir are still relative to the working
directory: register the directory they write to as the store.
Adopt older directories¶
Artifacts built before manifests existed can be sealed in place, with the runs they were built from:
uv run hylo store adopt bench/runs/memory/l10-search-v1 --kind action_memory --role behaviour \
--source run:rsi-l10-parent-search-10507bae9c9e95b3-31f1e5
Without any --source, the provenance is recorded as unknown. Such an artifact can still be used in experiments,
but the gate refuses it as a behaviour artifact in a candidate, because a leak of gate or held-out data cannot be
ruled out.