Skip to content

Preserve structured failure diagnostics in canonical results.jsonl #1037

Description

@yangziao56

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

  1. 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
  2. Pass the existing categories and diagnostic collector through _build_rollout_result(); do not reclassify human-readable strings in the exporter.
  3. Preserve the current error, stop_condition, training_ready, and Prime-SFT fields unchanged.
  4. Reuse the existing JSON redaction/non-finite sanitization path so diagnostic text cannot bypass artifact redaction.
  5. 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?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions