Job Records
gym eval submit describes what to submit; the job record describes what was submitted. It exists so a run can be found again, by a person, a collection script, or a future status command, without re-reading the original config.
The record format is deliberately executor-neutral. Nothing in it is named after Slurm, and the executor field says how to interpret the executor-shaped parts.
Where records are written
The resolved config is the right thing to archive or diff: the config file may have changed since, and the overrides mean nothing without the file they were applied to. It is also what --resolve-only prints.
Secrets
In resolved-config.yaml, host:VAR values are written back as host:VAR, never as the value, so the file is safe to share with another account. The resolved values live only in the owner-only job.sh. The collector’s ingest token is not written to the job directory at all.
Write order and failures
The local index is written first, because it cannot fail the submit: a failure to write it is reported on stderr and ignored. The resolved config and manifest are then written to the run directory. By that point the jobs are already queued, so if either write fails the command raises an error that names every queued job (<benchmark>=<slurm job id>). Record those IDs by hand before collecting results.
Manifest fields
gym-job.json is a SubmissionRecord:
Each entry in benchmarks:
A submission with at least one entry whose job_id is null makes the command exit 1, but the record is still written for the benchmarks that were queued.
--json
gym eval submit --json prints the manifest, and only the manifest, so the output parses as JSON:
With --resolve-only, --json prints the resolved config instead. --dry-run produces no record, so there is nothing to print as JSON.
Compatibility
A record outlives the Gym that wrote it, so schema_version is read in one direction: a reader accepts any record at or below its own version and refuses only one that is newer. Upgrading Gym therefore never orphans records already on disk. To keep that safe, within one schema version a field may only be added with a default, or removed; its meaning never changes. A change in meaning requires a version bump and an explicit migration.
If you load records yourself, use SubmissionRecord.load(payload) from nemo_gym.orchestration.jobs. It raises a clear error for a missing schema_version or one written by a newer Gym.