Skip to content

Exports

An export is what a rig’s harness writes when something new happened: the new attempts, champions, events and notes since the last export, and a copy of its ledger. The rig’s supervisor sends each export off the rig. This page says where it goes, what control keeps of it, how the supervisor reports it, and how control tells that a rig’s results have left it. Get a rig’s results from control gives the steps.

Terminal window
curl -fsS -H "Authorization: Bearer $(cat .dev/secrets/control-admin-token)" \
http://127.0.0.1:8800/v1/rigs/rig-1/results-left
{"left":true,"why":"every export has left the rig: they are on control","to":"control","waiting":0,"champions_waiting":0,"reported_at":"2026-10-20T12:01:00.000Z"}
The rig’s supervisor hasIts exports go toThe rig’s Results row says
A results repository (THERMITE_RESULTS_REMOTE)The results repository, pushed with git. See Set up the results repositoryN exports · pushed … ago
No results repository, and a controlControl, sent over control’s API with the rig’s tokenN exports · sent to control … ago, or sent to control: none yet
NeitherNowhere: they stay in the supervisor’s own repository, in its volumeno results repository

The rigs that control sets up on machines and clusters, and the rigs you join yourself, have no results repository, so their exports go to control. The local compose stack has one. Champion patches go to control in every case, so you can download a run’s champion.

An export leaves the harness’s outbox only once it is safe: pushed to the results repository, or kept in full on control. Until then the supervisor tries again every round (THERMITE_POLL_SECONDS, 60 seconds by default).

Every file the export’s manifest lists, each with the SHA-256 the manifest gives it. The copy of the ledger (ledger.sqlite) goes with the first export, then at most once a day, and with every full export: the same rule as the results repository’s ledger branch. A ledger copy never holds held-out results.

  1. The supervisor starts the export on control with its manifest and the size of each file it sends. Control refuses a list that leaves out a file of the manifest (the ledger copy aside), or names one the manifest does not list.
  2. It sends each file in pieces of up to 8 MiB, each at the place control says it has. When a send breaks, the next round goes on from there.
  3. When a file’s last byte arrives, control checks its SHA-256 against the manifest. It keeps the file only if they match; otherwise it deletes it, and the supervisor sends it again.
  4. The export is complete when every file it promised is kept. Then the supervisor tells the harness, and the export leaves the outbox.

The routes are in the REST API reference. A rig whose control reaches it through a proxy (a RunPod pod) sends the same requests through its tunnel.

PlaceWhat
THERMITE_CONTROL_DIR, under exports/<rig>/<export>/manifest.jsonThe export’s manifest, as the harness wrote it
THERMITE_CONTROL_DIR, under exports/<rig>/<export>/files/Each file, at its path in the export. A file still arriving ends in .part
Control’s databaseEach export: its manifest, the files it promised with their sizes and SHA-256, which arrived, and when the last one did

Control never deletes an export. They take room in control’s state volume until you remove them yourself.

The supervisor reports these every round, unsigned. They are supervisor.export in GET /v1/rigs/<rig>/view.

FieldMeaning
remoteWhether it has a results repository
toWhere its exports go: repository, control or none
exportsExports it has taken from the outbox
pushed, pushed_commit, last_push_atThe newest 50 exports in the results repository, the commit the last push left there, and when
uploaded, last_upload_atThe newest 50 exports control holds in full, and when the last one was complete
waitingExports still on the rig: not yet taken from the outbox, or taken and not yet pushed or kept on control
champions_waitingChampion patches not yet on control
last_errorThe last push’s or send’s error, or an export that failed its check

Control answers this from the rig’s latest supervisor report and, for exports on control, from its own copy. A RunPod pod’s terminate waits for it, and so does its stop, for 15 minutes at most (Stop, start, restart and terminate). GET /v1/rigs/<rig>/results-left asks it, with the owner’s token; ?export=<name> also asks about that export.

The answer is yes only when all of these hold:

  • the supervisor has reported, and its report says where its exports go and how many wait;
  • no export waits on the rig (waiting is 0);
  • for a rig that sends to control, no champion patch waits either;
  • with export: for a results repository, the supervisor reports that export pushed; for control, control holds every file of it.

Results recorded after the rig’s last export are in no export yet. To include them, export first (Export now, or the export_now command) and ask about that export by name.

FieldMeaning
leftThe answer
whyWhy not, or where they are, in plain words
torepository, control, or null when the report does not say
waiting, champions_waitingThe report’s counts, or null
reported_atWhen control received the report it read
whyMeaning
the rig's supervisor has not reported yetNo report
the rig has no results repository, and its supervisor does not send exports to control (an older version)A supervisor from before exports went to control
the rig's supervisor does not say what waits to leave (an older version)The report has no waiting
<n> exports wait on the rig to go to controlNot yet sent. Also for the results repository
<n> champion patches wait on the rig to go to controlNot yet uploaded
export <name> is not in the results repository yetNot yet pushed
export <name> has not reached control yetNot started on control
export <name> is on its way to control: <k> of <n> files arrivedPartly sent
every export has left the rig: they are on controlYes. Or in the results repository

A full reset waits at verifying until its full export has left the rig in the same way: reported pushed to the results repository, or held in full on control. For a rig without either, the reset fails with the rig has no results repository, and its supervisor does not send exports to control (an older version): its export cannot be verified.

The supervisor’s last_error, in red on the rig’s Results row:

ErrorMeaning
upload failed: …A send to control failed: control could not be reached, or answered with an error. The export waits and goes again next round
upload failed: export <name>: control answered 503: control keeps no exports: it has no folder for themA control started without its exports folder. The export waits
export <name> refused: …The export does not match its own manifest. It is never sent, and stays in the outbox
export <name>: control has another export named <name> from this rigControl already holds a different export by that name. It is not sent again, and stays in the outbox
export <name> is no longer in the outboxThe export went before it was sent, for example in a wipe. It is not sent

The Results row also says · N waiting to leave the rig while exports wait.