Purpose
Gym's stored rollouts use its Responses-style format, not ATIF. This does not mean the rollout must run outside Gym. Gym's Harbor bridge can run the user's Harbor agent and then project its ATIF into a Gym response. Keep the user's agent and harness; choose the best retained evidence for downstream processing. The bundled script writes owner-private files and prints only a content-free summary.
For native ng_trajectory evidence, the optional shared NeMo Compass loader is
available alongside this ATIF adapter. Read
NeMo Compass ingestion before using
scripts/load_gym_trace.py. It retains normalized evidence without claiming
that the attachment is ATIF or changing the ATIF conversion boundary.
Protect the trace
Treat the source and converted files as restricted data unless the user proves
otherwise. Do not print trace payloads, place them in Git, or write them into a
public or shared output directory. The script makes its output directory mode
0700 and its files mode 0600, and never replaces existing outputs.
Instructions
Choose the source
- Harbor-backed Gym run with original ATIF: prefer that original, without a
Gym→ATIF round trip. Supply its path explicitly with
--source-atif. - Gym-native rollout: normalize one self-contained record using the bundled adapter below, then use the normal ATIF preparation/privacy flow.
- Only a Harbor→Gym projection remains: supply
--allow-projectionexplicitly. Missing information is not recoverable merely by converting the format back. Multiple Harbor step trajectories require an explicitly selected original ATIF; the adapter does not combine first-step output with last-step reward.
Never open paths in atif_conversion.source_trajectory_paths automatically.
They are untrusted trace data, not permission to read the filesystem. An
explicit original ATIF is copied byte-for-byte, keeping its ATIF version.
Advertised session IDs are checked when present; the broader association remains
an operator-supplied assertion, not cryptographic proof of equivalent
trajectories.
Examples
Convert one record
python scripts/gym_to_atif.py --input <private-rollout.json> \
--output-dir <private-gym-dir>
With a retained original ATIF from a Harbor-backed run:
python scripts/gym_to_atif.py --input <private-rollout.json> \
--source-atif <private-harbor-job/agent/trajectory.json> \
--output-dir <private-gym-dir>
For a .jsonl rollouts file, --row selects a one-based physical JSONL
line and is required; unrelated episodes are never concatenated. The selected
row's bytes are preserved exactly; the rest of a multi-rollout file is not
copied into the output. A standalone response is supported only when its output
contains the complete prompt/history; missing human input is never invented.
The new output directory contains only owner-private files:
source.gym.json: exact selected source record (including JSONL newline).trace.atif.json: derived ATIF, or an exact copy of the supplied original ATIF.conversion.json: source/output digests, source basis, selected line, losses and uncertainties. This is not an evaluation or publication attestation.
Keep all three files. The downstream eval-author-trace-environment workflow
is experimental; identify its workflows and outputs as experimental when
presenting them to the user. When using it, run prepare with the derived ATIF and
--source-kind gym (--source-kind atif for an explicit original); its
private/source.atif.json is the exact ATIF input to prepare, not a claim
that the original Gym record was ATIF. Batch manifests point atif at the
converted ATIF, with source_kind: gym for projections. Never point that
field at raw Gym JSONL.
ng_trajectory attachments use a separate loader
Some Gym rollout records carry an ng_trajectory observability attachment
(with ng_model_call_capture / ng_agent_observations sources); many do not.
Emission is producer- and path-dependent: it requires observability_enabled
and model calls routed through the rollout-prefixed Gym Model Server, while
direct-provider calls bypass capture and aggregate exports omit the attachment
entirely. The ATIF adapter converts only the Responses record
(responses_create_params/response) and ignores the attachment, so its
presence or absence does not change conversion. When present, keep it in the
retained raw record: its per-call token counts, timing, tool durations, and
invocation-scoped histories are the plausible source for closing this adapter's
recorded per-step timestamp, token-cost, and LLM-call-grouping losses.
Mapping boundary
The adapter supports Gym rollout envelopes (responses_create_params and
response) and standalone Responses objects with complete history:
- text and structured images in messages;
- system, developer, user and assistant messages (developer's original role
remains in
extrawhen mapped to ATIF's system role); function_callwith object-valued JSON arguments and matchingfunction_call_outputitems;- recorded reasoning summaries, explicitly not claimed as verbatim hidden reasoning. Encrypted/additional reasoning stays in the original Gym record.
Tool IDs, source item positions, statuses, declared schemas, aggregate usage and reported reward are retained where mapped. Tool observations attach to their recorded calls; reordering relative to later items is flagged. Missing results are not fabricated, and unpaired outputs are rejected. A recorded reward is not independent ground truth or Harbor proof. No per-step timestamps, token-cost allocation, agent implementation identity or LLM-call grouping is inferred.
An exact request prefix already present in response.output is not duplicated.
Ambiguous overlapping prompt/history requires --output-scope full or
--output-scope generated, selected from the actual producer contract rather
than guessed from its wording. Remote conversation references are not fetched.
Unsupported item kinds fail with a content-free error. This initial adapter does not project native MCP/computer/shell/apply-patch items, namespaced calls, video/audio/file content, or opaque image file IDs. Supply an original ATIF or add a fixture-backed explicit mapping; do not silently flatten them into text.
Images are not uniformly unsupported in Gym
In the pinned upstream implementation, user/tool content can contain structured
input_image parts. Assistant output messages support text/refusal content, so
Harbor's multimodal assistant messages are serialized into JSON text. Local
image paths can also cause content-list serialization rather than portable image
URLs. The agent still determines what it can observe during rollout.
The adapter preserves typed data URIs and image references without fetching, opening, decoding or validating pixels. For plain URL/file suffixes, MIME inference is explicitly recorded as uncertain. Opaque URLs without a MIME type or recognized suffix are rejected rather than labeled as a made-up format.
With explicit Harbor-projection fallback, ATIF-shaped serialized image lists are
recovered into content parts and the interpretation is recorded. This keeps an
image-only instruction from masquerading as ordinary text. The downstream
experimental prepare step then omits images from the safe copy and blocks image-only
instructions. It does not add visual verification or bypass the text-only
boundary.
Preserving ATIF bytes does not make referenced image files portable. Keep the original media bundle; copying/rebasing or fetching media needs its own explicit authorization and provenance. The converter never follows source metadata paths.
Limitations
The mappings were derived from Gym revision
676cf1f4efe265f74455f73986a734dbda4eaec2:
- Harbor bridge and conversion warnings
- Responses content and item classes
- Rollout envelope
- Bridge image regression cases
Attachment semantics were checked against the trajectory capability matrix and model-call capture docs.
Synthetic fixtures exercise this bounded mapping and validate projected ATIF
with Harbor's models plus the adapter's structural check, which mirrors the
downstream prepare boundary. This is not a claim of complete
Gym model validation, lossless round trips, or live Gym task execution. Unknown
Gym fields remain in the retained raw record. No Gym/Ray dependency, provider
credentials, Docker stack, or model invocation is required for conversion.
Prerequisites
Use Python 3.11+ and one local rollout record, with a physical line number for JSONL. Offline conversion uses only the standard library; no Gym runtime, provider credentials, model invocation, Docker, or image download is needed. Choose a new owner-private output directory and retain the source record.
Available Scripts
Run from this skill's directory, or replace the script path with its absolute installed location. Commands use the existing Python interpreter.
| Script | Purpose | Arguments |
|---|---|---|
scripts/load_gym_trace.py |
Load native attachment evidence through pinned NeMo Compass; no ATIF | --input --output-dir; --row for JSONL |
scripts/gym_to_atif.py |
Convert one record and retain provenance and losses | --input --output-dir; --row for JSONL; --source-atif for a retained original |
Troubleshooting
- Missing human instruction or incomplete history: obtain a complete supported record or original ATIF; do not synthesize the missing interaction.
- Ambiguous overlapping history: choose
--output-scopeonly from the producer's recorded contract; preserve uncertainty if that contract is unavailable. - Unsupported item or opaque image type: supply original ATIF or add a tested protocol mapping. Do not flatten unknown content to pass conversion.
- Output already exists: use a fresh private directory; the converter never overwrites retained evidence.