Problem
BenchFlow persists typed rollout diagnostics in result.json, but the canonical trainer-facing results.jsonl currently drops them.
For example, an idle-timeout rollout can contain this in result.json:
{
"error_category": "idle_timeout",
"idle_timeout_info": {
"reason": "idle_timeout",
"idle_timeout_sec": 120,
"idle_duration_sec": 121
}
}
The corresponding results.jsonl row only exposes the generic error.error = "agent_error" and/or stop_condition = "partial_trajectory". Downstream evaluation and training-data QA therefore cannot distinguish idle timeout, wall-clock timeout, sandbox startup, transport closure, verifier timeout, provider API failure, and suspected API failure without reopening per-rollout result.json files.
The loss happens because _build_rollout_result() already computes error_category, verifier_error_category, and owns a RolloutDiagnostics collector, but its call to _write_results_jsonl() passes only the human-readable error and verifier_error strings.
Proposed bounded scope
- Add an optional, versioned structured-diagnostics block to
results.jsonl under info, preserving:
error_category
verifier_error_category
- only present typed diagnostic events from
DIAGNOSTIC_REGISTRY
- Pass the existing categories and diagnostic collector through
_build_rollout_result(); do not reclassify human-readable strings in the exporter.
- Preserve the current
error, stop_condition, training_ready, and Prime-SFT fields unchanged.
- Reuse the existing JSON redaction/non-finite sanitization path so diagnostic text cannot bypass artifact redaction.
- Preserve backward compatibility: callers that omit the new optional arguments produce the same row shape as today.
Acceptance tests
- Each registered diagnostic class round-trips into the per-rollout row with the correct channel/category.
- Agent and verifier categories remain separate and precedence matches
RolloutDiagnostics.category_for_channel().
- Absent diagnostics do not add a block, preserving existing consumers.
- Secrets in raw diagnostic fields are redacted in the written JSONL.
- Non-finite values remain valid JSON.
- Job-level aggregation preserves the block.
- Existing training-readiness and Prime-SFT tests remain green.
Non-overlap
This proposal only closes the exporter parity gap for already-produced structured diagnostics.
Before opening an implementation PR, could a maintainer confirm that this scope is useful and unowned, the preferred schema location/name, the acceptance path, and whether/at what value this work is eligible for Ziao Yang's FrontierPhysics infrastructure contribution credit?
Problem
BenchFlow persists typed rollout diagnostics in
result.json, but the canonical trainer-facingresults.jsonlcurrently drops them.For example, an idle-timeout rollout can contain this in
result.json:{ "error_category": "idle_timeout", "idle_timeout_info": { "reason": "idle_timeout", "idle_timeout_sec": 120, "idle_duration_sec": 121 } }The corresponding
results.jsonlrow only exposes the genericerror.error = "agent_error"and/orstop_condition = "partial_trajectory". Downstream evaluation and training-data QA therefore cannot distinguish idle timeout, wall-clock timeout, sandbox startup, transport closure, verifier timeout, provider API failure, and suspected API failure without reopening per-rolloutresult.jsonfiles.The loss happens because
_build_rollout_result()already computeserror_category,verifier_error_category, and owns aRolloutDiagnosticscollector, but its call to_write_results_jsonl()passes only the human-readableerrorandverifier_errorstrings.Proposed bounded scope
results.jsonlunderinfo, preserving:error_categoryverifier_error_categoryDIAGNOSTIC_REGISTRY_build_rollout_result(); do not reclassify human-readable strings in the exporter.error,stop_condition,training_ready, and Prime-SFT fields unchanged.Acceptance tests
RolloutDiagnostics.category_for_channel().Non-overlap
This proposal only closes the exporter parity gap for already-produced structured diagnostics.
Before opening an implementation PR, could a maintainer confirm that this scope is useful and unowned, the preferred schema location/name, the acceptance path, and whether/at what value this work is eligible for Ziao Yang's FrontierPhysics infrastructure contribution credit?