> This page is for version 0.2.1.
> For other versions, use one of these documentation indexes:
> - Main (default): https://docs.nvidia.com/nemo/gym/main/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo/gym/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo/gym/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo/gym/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo/gym/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo/gym/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo/gym/v0.3.0/llms.txt
> - 0.2.1: https://docs.nvidia.com/nemo/gym/v0.2.1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/gym/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/gym/_mcp/server.

# nemo_gym.rollouts.rollout_health

Deterministic post-run rollout quality verification workflow.

Checks operate only on persisted rollout records and their canonical
`ng_trajectory` evidence. They return evidence; this module derives verdicts
and writes reports.

## Module Contents

### Classes

| Name                                                                           | Description                                                                                                   |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| [`CheckInput`](#nemo_gym-rollouts-health-types-CheckInput)                     | Persisted or derived evidence required to evaluate a check.                                                   |
| [`CheckScope`](#nemo_gym-rollouts-health-types-CheckScope)                     | -                                                                                                             |
| [`CheckSpec`](#nemo_gym-rollouts-health-types-CheckSpec)                       | Stable, self-describing health-check contract.                                                                |
| [`CheckSubject`](#nemo_gym-rollouts-health-types-CheckSubject)                 | -                                                                                                             |
| [`Finding`](#nemo_gym-rollouts-health-types-Finding)                           | Evidence emitted by a check. Checks never emit verdicts.                                                      |
| [`HealthCheckResult`](#nemo_gym-rollouts-health-types-HealthCheckResult)       | -                                                                                                             |
| [`RolloutDigest`](#nemo_gym-rollouts-health-types-RolloutDigest)               | -                                                                                                             |
| [`_AggregationSources`](#nemo_gym-rollouts-rollout_health-_AggregationSources) | The shards `gym eval aggregate` merged into a rollout file, in its order, each as its path, size and SHA-256, |
| [`_Failures`](#nemo_gym-rollouts-rollout_health-_Failures)                     | The rollouts that failed and never landed, and the rollouts the run owed.                                     |

### Functions

| Name                                                                                                     | Description                                                                                                  |
| -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| [`_aggregated_shards`](#nemo_gym-rollouts-rollout_health-_aggregated_shards)                             | The shards `gym eval aggregate` merged into `run_dir/rollout_name`, in its order; None if it merged none.    |
| [`_context_window_exceeded`](#nemo_gym-rollouts-rollout_health-_context_window_exceeded)                 | From the row's own `step_usage` (written by scicode_agent): a sub-step recorded as context_window_exceeded.  |
| [`_flag`](#nemo_gym-rollouts-rollout_health-_flag)                                                       | A config flag as written: a bool is known, anything else (absent, interpolated, malformed) is unknown.       |
| [`_health_artifact_digests`](#nemo_gym-rollouts-rollout_health-_health_artifact_digests)                 | Bind gate facts to saved rollout inputs, not to external captures or observation completeness.               |
| [`_health_check_collected_rollouts`](#nemo_gym-rollouts-rollout_health-_health_check_collected_rollouts) | Write the quality summary for whatever a run collected; a run that never started collection has none.        |
| [`_index_jsonl`](#nemo_gym-rollouts-rollout_health-_index_jsonl)                                         | -                                                                                                            |
| [`_jsonl_rows`](#nemo_gym-rollouts-rollout_health-_jsonl_rows)                                           | Stream a JSONL file's objects; an inventory can be hundreds of MB.                                           |
| [`_judge_run`](#nemo_gym-rollouts-rollout_health-_judge_run)                                             | Add the run-level check to the accounting: its coverage, and a reason and an unhealthy verdict per finding.  |
| [`_landed_in`](#nemo_gym-rollouts-rollout_health-_landed_in)                                             | `landed` keys of one input, keyed as `_read_failures` keys that input read alone.                            |
| [`_last_failed_attempts`](#nemo_gym-rollouts-rollout_health-_last_failed_attempts)                       | The selected failed attempt of every rollout that never landed.                                              |
| [`_limit_text`](#nemo_gym-rollouts-rollout_health-_limit_text)                                           | -                                                                                                            |
| [`_mark_duplicate_identities`](#nemo_gym-rollouts-rollout_health-_mark_duplicate_identities)             | Flag physical records of one input that claim the same logical rollout identity.                             |
| [`_mlflow_configured`](#nemo_gym-rollouts-rollout_health-_mlflow_configured)                             | A names-only fact about the saved config snapshot: whether its three MLflow name fields are concrete.        |
| [`_observed_upstream_recovery`](#nemo_gym-rollouts-rollout_health-_observed_upstream_recovery)           | Count only observed failed attempts and explicitly completed operations; never certify completeness.         |
| [`_persisted_limits`](#nemo_gym-rollouts-rollout_health-_persisted_limits)                               | The limits the run's earlier summary was judged by; none (no limit) when it has no readable summary.         |
| [`_process_pool_chunksize`](#nemo_gym-rollouts-rollout_health-_process_pool_chunksize)                   | Keep several schedulable chunks per worker without unbounded IPC batches.                                    |
| [`_read_failures`](#nemo_gym-rollouts-rollout_health-_read_failures)                                     | Read every input's failures sidecar and inventory.                                                           |
| [`_read_record`](#nemo_gym-rollouts-rollout_health-_read_record)                                         | -                                                                                                            |
| [`_reduce`](#nemo_gym-rollouts-rollout_health-_reduce)                                                   | -                                                                                                            |
| [`_remove_health_reports`](#nemo_gym-rollouts-rollout_health-_remove_health_reports)                     | -                                                                                                            |
| [`_report_sources`](#nemo_gym-rollouts-rollout_health-_report_sources)                                   | The rollouts files a report was computed from, relative to the folder it is written in                       |
| [`_resolve_rollout_path`](#nemo_gym-rollouts-rollout_health-_resolve_rollout_path)                       | -                                                                                                            |
| [`_response_population`](#nemo_gym-rollouts-rollout_health-_response_population)                         | The call ids of the rollout's verified successful raw model responses selected for evaluation, and of the    |
| [`_rollout_accounting`](#nemo_gym-rollouts-rollout_health-_rollout_accounting)                           | Project managed runs from selected history; preserve raw accounting for legacy runs.                         |
| [`_run_excessive_failures`](#nemo_gym-rollouts-rollout_health-_run_excessive_failures)                   | The `run_excessive_failures` check: one finding per group of failed rollouts that reaches its limit.         |
| [`_run_health_line`](#nemo_gym-rollouts-rollout_health-_run_health_line)                                 | Run health: failed rollouts against the configured limits, and the coverage reasons.                         |
| [`_sha256`](#nemo_gym-rollouts-rollout_health-_sha256)                                                   | -                                                                                                            |
| [`_sort_key`](#nemo_gym-rollouts-rollout_health-_sort_key)                                               | -                                                                                                            |
| [`_task_findings`](#nemo_gym-rollouts-rollout_health-_task_findings)                                     | -                                                                                                            |
| [`_unique_task_repeats`](#nemo_gym-rollouts-rollout_health-_unique_task_repeats)                         | Collapse duplicate persisted records for task-level repeat semantics.                                        |
| [`_with_captured_calls`](#nemo_gym-rollouts-rollout_health-_with_captured_calls)                         | Failed rollouts' rows, each with the model calls captured under its rollout id, read with the collector's    |
| [`_worker`](#nemo_gym-rollouts-rollout_health-_worker)                                                   | -                                                                                                            |
| [`_write_reports`](#nemo_gym-rollouts-rollout_health-_write_reports)                                     | -                                                                                                            |
| [`capture_dirs_for_health`](#nemo_gym-rollouts-rollout_health-capture_dirs_for_health)                   | The run's model-call capture directories for `run_health_checks`; none when capture is off or misconfigured, |
| [`evaluate_record`](#nemo_gym-rollouts-rollout_health-evaluate_record)                                   | Evaluate every rollout-level check on one rollout record.                                                    |
| [`format_health_report`](#nemo_gym-rollouts-rollout_health-format_health_report)                         | -                                                                                                            |
| [`health_check_run_dir`](#nemo_gym-rollouts-rollout_health-health_check_run_dir)                         | Recheck a run directory. The run's own persisted limits judge it, so the verdict of the same artifacts       |
| [`normalize_ignored_checks`](#nemo_gym-rollouts-health-checks-normalize_ignored_checks)                  | Normalize and validate check IDs supplied by library, CLI, or Hydra config.                                  |
| [`run_health_checks`](#nemo_gym-rollouts-rollout_health-run_health_checks)                               | Check selected completed attempts while retaining run-wide failure and timeout evidence.                     |
| [`run_provenance`](#nemo_gym-rollouts-rollout_health-run_provenance)                                     | Facts about how the run was configured, read from the resolved config saved beside the rollouts.             |
| [`write_aggregation_sources`](#nemo_gym-rollouts-rollout_health-write_aggregation_sources)               | Record the shards `merged_fpath` is merged from, for a recheck of its directory to read.                     |
| [`write_disabled_summary`](#nemo_gym-rollouts-rollout_health-write_disabled_summary)                     | Write the quality summary of a run with `disable_health_check` set, so a disabled check is recorded as       |
| [`write_provisional_summary`](#nemo_gym-rollouts-rollout_health-write_provisional_summary)               | Write the run accounting of a stopped run fast: `rollouts.jsonl` is not read, and the per-record checks      |

### Data

[`CHECK_REGISTRY`](#nemo_gym-rollouts-health-checks-CHECK_REGISTRY)

[`MLFLOW_TRACKING_REQUIRED_KEY`](#nemo_gym-rollouts-rollout_health-MLFLOW_TRACKING_REQUIRED_KEY)

[`Verdict`](#nemo_gym-rollouts-health-types-Verdict)

[`_MLFLOW_REQUIRED_NAMES`](#nemo_gym-rollouts-rollout_health-_MLFLOW_REQUIRED_NAMES)

[`_PROCESS_POOL_CHUNKS_PER_WORKER`](#nemo_gym-rollouts-rollout_health-_PROCESS_POOL_CHUNKS_PER_WORKER)

[`_PROCESS_POOL_MAX_CHUNKSIZE`](#nemo_gym-rollouts-rollout_health-_PROCESS_POOL_MAX_CHUNKSIZE)

[`_RUN_FAILURES_CHECK`](#nemo_gym-rollouts-rollout_health-_RUN_FAILURES_CHECK)

[`logger`](#nemo_gym-rollouts-rollout_health-logger)

### API

```python
class nemo_gym.rollouts.rollout_health.CheckInput
```

**Bases:** `enum.Enum`

Persisted or derived evidence required to evaluate a check.

**`AGENT_TURNS`** `= 'agent_turns'`

---

**`BOUND_CALLS`** `= 'bound_calls'`

---

**`OBSERVED_MODEL_CALLS`** `= 'observed_model_calls'`

---

**`OWNED_MODEL_CALLS`** `= 'owned_model_calls'`

---

**`RECORD`** `= 'record'`

---

**`REPEAT_DIGESTS`** `= 'repeat_digests'`

---

**`REPEAT_VERDICTS`** `= 'repeat_verdicts'`

---

**`RUN_ACCOUNTING`** `= 'run_accounting'`

---

**`TRAJECTORY`** `= 'trajectory'`

---

```python
class nemo_gym.rollouts.rollout_health.CheckScope
```

**Bases:** `enum.Enum`

**`ROLLOUT`** `= 'rollout'`

---

**`RUN`** `= 'run'`

---

**`TASK`** `= 'task'`

---

```python
class nemo_gym.rollouts.rollout_health.CheckSpec()
```

**Bases:** `BaseModel`

Stable, self-describing health-check contract.

**`evaluation_scope`** `CheckScope`

---

**`id`** `str`

---

**`model_config`** `= ConfigDict(frozen=True)`

---

**`reads`** `frozenset[CheckInput]`

---

**`subject`** `CheckSubject`

---

```python
nemo_gym.rollouts.rollout_health.CheckSpec._require_one_call_binding_view(
    reads: frozenset[nemo_gym.rollouts.health.types.CheckInput]
) -> frozenset[nemo_gym.rollouts.health.types.CheckInput]
```

classmethod

```python
class nemo_gym.rollouts.rollout_health.CheckSubject
```

**Bases:** `enum.Enum`

**`AGENT_TURN`** `= 'agent_turn'`

---

**`CHECK_EXECUTION`** `= 'check_execution'`

---

**`MODEL_CALL`** `= 'model_call'`

---

**`RECORD`** `= 'record'`

---

**`ROLLOUT`** `= 'rollout'`

---

**`RUN`** `= 'run'`

---

**`TASK`** `= 'task'`

---

**`TRAJECTORY_CAPTURE`** `= 'trajectory_capture'`

---

```python
class nemo_gym.rollouts.rollout_health.Finding()
```

**Bases:** `BaseModel`

Evidence emitted by a check. Checks never emit verdicts.

**`check`** `str`

---

**`detail`** `dict[str, Any] = Field(default_factory=dict)`

---

**`locator`** `dict[str, int | str] | None = None`

---

**`subject`** `dict[str, int | str]`

---

```python
class nemo_gym.rollouts.rollout_health.HealthCheckResult()
```

**Bases:** `BaseModel`

**`rollouts`** `list[RolloutDigest]`

---

**`summary`** `dict[str, Any]`

---

**`summary_path`** `Path`

---

**`verdicts_path`** `Path`

---

```python
class nemo_gym.rollouts.rollout_health.RolloutDigest()
```

**Bases:** `BaseModel`

**`capture_completion_tokens`** `int = 0`

---

**`capture_observed`** `bool`

---

**`capture_prompt_tokens`** `int = 0`

---

**`context_window_exceeded`** `bool | None = None`

---

**`duplicated_calls`** `int = 0`

---

**`ended_on_error`** `bool = False`

---

**`errors_by_status`** `dict[str, int] = Field(default_factory=dict)`

---

**`findings`** `list[Finding]`

---

**`model_call_errors`** `int = 0`

---

**`model_call_errors_usage_unknown`** `int = 0`

---

**`model_calls`** `int = 0`

---

**`policy_calls_observed`** `bool = False`

---

**`responses`** `dict[str, list[str]] | None = None`

---

**`rollout_id`** `str`

---

**`rollout_index`** `int | str`

---

**`scored`** `bool = False`

---

**`stage_index`** `int | str | None = None`

---

**`successful_model_calls`** `int = 0`

---

**`task_index`** `int | str`

---

**`timing`** `RolloutTiming | None = None`

---

**`transcript_completion_tokens`** `int = 0`

---

**`transcript_prompt_tokens`** `int = 0`

---

**`unobserved`** `list[str]`

---

**`upstream_recovery_observations`** `dict[str, int] | None = None`

---

**`verdict`** `Verdict`

---

**`verification_skipped`** `bool | None = None`

---

```python
class nemo_gym.rollouts.rollout_health._AggregationSources()
```

**Bases:** `BaseModel`

The shards `gym eval aggregate` merged into a rollout file, in its order, each as its path, size and SHA-256,
and that file's size and SHA-256.

**`merged_bytes`** `int`

---

**`merged_sha256`** `str`

---

**`shards`** `list[tuple[str, int, str]]`

---

```python
class nemo_gym.rollouts.rollout_health._Failures(
    rows: dict[tuple[typing.Any, ...], dict[str, typing.Any]],
    owed: set[tuple[typing.Any, ...]] | None,
    any_sidecar: bool
)
```

Dataclass

The rollouts that failed and never landed, and the rollouts the run owed.

**`any_sidecar`** `bool`

---

**`owed`** `set[tuple[Any, ...]] | None`

---

**`rows`** `dict[tuple[Any, ...], dict[str, Any]]`

---

```python
nemo_gym.rollouts.rollout_health._aggregated_shards(
    run_dir: pathlib.Path,
    rollout_name: str = 'rollouts.jsonl'
) -> list[pathlib.Path] | None
```

The shards `gym eval aggregate` merged into `run_dir/rollout_name`, in its order; None if it merged none.

The merged rows have none of the shards' failures or inventories, so a recheck reads the shards, as the
aggregation did. A merged file that is gone, or not byte for byte the one the list was written for, is not
theirs; a shard that is gone cannot be read, and one not byte for byte the one merged holds other rows. Each
raises rather than check rows other than the merged ones, or without their failures.

```python
nemo_gym.rollouts.rollout_health._context_window_exceeded(
    record: collections.abc.Mapping[str, typing.Any]
) -> bool | None
```

From the row's own `step_usage` (written by scicode_agent): a sub-step recorded as context_window_exceeded.

scicode_agent sets that status from a best-effort error-text match or model metadata, so it is a signal of a
context-window failure, not proof that the input was clipped.

```python
nemo_gym.rollouts.rollout_health._flag(
    value: typing.Any
) -> bool | None
```

A config flag as written: a bool is known, anything else (absent, interpolated, malformed) is unknown.

```python
nemo_gym.rollouts.rollout_health._health_artifact_digests(
    paths: collections.abc.Sequence[pathlib.Path]
) -> list[dict[str, str | None]]
```

Bind gate facts to saved rollout inputs, not to external captures or observation completeness.

```python
nemo_gym.rollouts.rollout_health._health_check_collected_rollouts(
    output_fpath: pathlib.Path,
    config: typing.Any,
    landed_keys: set | None = None,
    coverage: dict | None = None,
    terminated: bool = False,
    model_call_capture_dirs: collections.abc.Sequence[pathlib.Path] = (),
    disabled: bool = False
) -> None
```

Write the quality summary for whatever a run collected; a run that never started collection has none.

After SIGTERM, Slurm kills the job once KillWait (120 s on some clusters) is over, and the full check can take
minutes on a large run. So a stopped run with `landed_keys` gets the provisional summary: the run
accounting only, without reading the rollouts. With `disabled`, the summary only records that
(`write_disabled_summary`). A check that cannot run writes nothing, so saved evidence stays as it is.

```python
nemo_gym.rollouts.rollout_health._index_jsonl(
    paths: collections.abc.Sequence[pathlib.Path],
    histories: collections.abc.Mapping[pathlib.Path, nemo_gym.rollouts.rollout_store.RolloutStore | None] | None = None
) -> list[nemo_gym.rollouts.health.types._LineSlice]
```

```python
nemo_gym.rollouts.rollout_health._jsonl_rows(
    path: pathlib.Path
) -> collections.abc.Iterator[dict[str, typing.Any]]
```

Stream a JSONL file's objects; an inventory can be hundreds of MB.

```python
nemo_gym.rollouts.rollout_health._judge_run(
    artifacts: dict[str, typing.Any],
    findings: list[nemo_gym.rollouts.health.types.Finding],
    coverage: dict[str, int]
) -> None
```

Add the run-level check to the accounting: its coverage, and a reason and an unhealthy verdict per finding.

```python
nemo_gym.rollouts.rollout_health._landed_in(
    landed: set[tuple[typing.Any, ...]],
    source_index: int
) -> set[tuple[typing.Any, ...]]
```

`landed` keys of one input, keyed as `_read_failures` keys that input read alone.

```python
nemo_gym.rollouts.rollout_health._last_failed_attempts(
    landed: set[tuple[typing.Any, ...]],
    paths: collections.abc.Sequence[pathlib.Path],
    histories: collections.abc.Mapping[pathlib.Path, nemo_gym.rollouts.rollout_store.RolloutStore | None] | None = None
) -> list[dict[str, typing.Any]]
```

The selected failed attempt of every rollout that never landed.

A run with a manifest selects it from its run history, as its accounting does; a legacy output's sidecar row
that stands last is it.

```python
nemo_gym.rollouts.rollout_health._limit_text(
    value: float | None
) -> str
```

```python
nemo_gym.rollouts.rollout_health._mark_duplicate_identities(
    digests: list[nemo_gym.rollouts.health.types.RolloutDigest],
    lines: list[nemo_gym.rollouts.health.types._LineSlice],
    ignored_checks: frozenset[str]
) -> None
```

Flag physical records of one input that claim the same logical rollout identity.

Each input numbers its rollouts on its own, as the run accounting counts them: runs merged from different
environment servers can reuse task indices.

```python
nemo_gym.rollouts.rollout_health._mlflow_configured(
    config: collections.abc.Mapping[str, typing.Any]
) -> bool | None
```

A names-only fact about the saved config snapshot: whether its three MLflow name fields are concrete.

True when all three are concrete strings, False when any is absent, null or empty, None when a value is
interpolated or not a string. It is not `MLFlowConfig.is_available` (the token, which the snapshot may mask, is
not judged) and says nothing about whether an exporter was activated, whether tracking was required or
disabled, or whether anything was delivered: overrides, resumes and post-run exports can differ from the
snapshot. No value is copied.

```python
nemo_gym.rollouts.rollout_health._observed_upstream_recovery(
    calls: list[dict[str, typing.Any]]
) -> dict[str, int] | None
```

Count only observed failed attempts and explicitly completed operations; never certify completeness.

```python
nemo_gym.rollouts.rollout_health._persisted_limits(
    run_dir: pathlib.Path
) -> nemo_gym.rollouts.health.types.RunHealthLimits
```

The limits the run's earlier summary was judged by; none (no limit) when it has no readable summary.

```python
nemo_gym.rollouts.rollout_health._process_pool_chunksize(
    item_count: int,
    workers: int
) -> int
```

Keep several schedulable chunks per worker without unbounded IPC batches.

```python
nemo_gym.rollouts.rollout_health._read_failures(
    landed: set[tuple[typing.Any, ...]],
    paths: collections.abc.Sequence[pathlib.Path]
) -> nemo_gym.rollouts.rollout_health._Failures
```

Read every input's failures sidecar and inventory.

The last attempt of a rollout stands, and a rollout that later landed is not failed. With an inventory, only
owed rollouts count: an unreadable record or a sidecar row outside the inventory is not one.

```python
nemo_gym.rollouts.rollout_health._read_record(
    line: nemo_gym.rollouts.health.types._LineSlice
) -> tuple[dict[str, typing.Any], str | None]
```

```python
nemo_gym.rollouts.rollout_health._reduce(
    digests: list[nemo_gym.rollouts.health.types.RolloutDigest],
    ignored_checks: frozenset[str]
) -> dict[str, typing.Any]
```

```python
nemo_gym.rollouts.rollout_health._remove_health_reports(
    output_fpath: pathlib.Path
) -> None
```

```python
nemo_gym.rollouts.rollout_health._report_sources(
    paths: collections.abc.Sequence[pathlib.Path],
    report_dir: pathlib.Path
) -> list[str]
```

The rollouts files a report was computed from, relative to the folder it is written in
(`run.<QUALITY_SUMMARY_SOURCES_KEY>`): the reports keep one name per folder whatever the rollouts file is
called, so a reader with several runs' rollouts in one folder can tell whose they are. Only the directories are
resolved, as `_aggregated_shards` does, so a shard keeps its own name.

```python
nemo_gym.rollouts.rollout_health._resolve_rollout_path(
    run_dir: pathlib.Path,
    rollout_file: str | pathlib.Path | None
) -> pathlib.Path
```

```python
nemo_gym.rollouts.rollout_health._response_population(
    scope_complete: bool,
    bindings: typing.Any
) -> dict[str, list[str]] | None
```

The call ids of the rollout's verified successful raw model responses selected for evaluation, and of the
faulted ones among them. IDs only: no response text is kept.

Selected means bound to an agent turn of a complete call scope. A bound call that failed is a trial matter and
is left out. Every other bound call must carry an explicit 2xx/3xx status, a raw response and a call id, or the
population is unknown. A fault is judged from the raw output itself: a length-limited finish that is not a
length refusal (truncated), or an output with nothing usable (`_response_has_usable_output`: empty, reasoning
only or malformed). Token counts alone are never a fault.

```python
nemo_gym.rollouts.rollout_health._rollout_accounting(
    landed: set[tuple[typing.Any, ...]],
    paths: collections.abc.Sequence[pathlib.Path],
    limits: nemo_gym.rollouts.health.types.RunHealthLimits,
    limits_source: nemo_gym.rollouts.health.types.LimitsSource | collections.abc.Mapping[str, nemo_gym.rollouts.health.types.LimitsSource],
    duplicated: int,
    run_coverage: collections.abc.Sequence[collections.abc.Mapping[str, typing.Any] | None] | None = None,
    scored: set[tuple[typing.Any, ...]] | None = None
) -> dict[str, typing.Any]
```

Project managed runs from selected history; preserve raw accounting for legacy runs.

Managed `missing` means reserved attempts with no outcome. Never-dispatched
work and intentional omissions have their own categories. Final failures include
exhausted budgets as well as terminal outcomes. A stopped collector supplies its
in-memory coverage so this path never reloads large rollout records on SIGTERM.
In a legacy sidecar, a `record_omitted_rollouts` row records no result: an interrupted attempt is the
rollout's latest execution and leaves it missing, and a row never started is skipped.
`scored` holds the `landed` keys whose records are all scored. It is `None` when the records were not
read, which leaves a legacy input's `scored` count unknown.

```python
nemo_gym.rollouts.rollout_health._run_excessive_failures(
    artifacts: dict[str, typing.Any],
    limits: nemo_gym.rollouts.health.types.RunHealthLimits,
    ignored_checks: frozenset[str]
) -> tuple[list[nemo_gym.rollouts.health.types.Finding], dict[str, int]]
```

The `run_excessive_failures` check: one finding per group of failed rollouts that reaches its limit.

It reads only the run accounting, so a stopped run can evaluate it without the rollouts. With no limit
configured, or no inventory to count expected rollouts against, it is unobserved.

```python
nemo_gym.rollouts.rollout_health._run_health_line(
    artifacts: dict[str, typing.Any]
) -> str
```

Run health: failed rollouts against the configured limits, and the coverage reasons.

```python
nemo_gym.rollouts.rollout_health._sha256(
    fpath: pathlib.Path
) -> str
```

```python
nemo_gym.rollouts.rollout_health._sort_key(
    digest: nemo_gym.rollouts.health.types.RolloutDigest
) -> tuple[tuple[int, typing.Any], ...]
```

```python
nemo_gym.rollouts.rollout_health._task_findings(
    grouped: dict[int | str, list[nemo_gym.rollouts.health.types._TaskRepeat]],
    ignored_checks: frozenset[str]
) -> tuple[dict[int | str, list[nemo_gym.rollouts.health.types.Finding]], dict[str, dict[str, int]]]
```

```python
nemo_gym.rollouts.rollout_health._unique_task_repeats(
    digests: list[nemo_gym.rollouts.health.types.RolloutDigest]
) -> list[nemo_gym.rollouts.health.types._TaskRepeat]
```

Collapse duplicate persisted records for task-level repeat semantics.

```python
nemo_gym.rollouts.rollout_health._with_captured_calls(
    rows: collections.abc.Iterable[dict[str, typing.Any]],
    capture_dirs: collections.abc.Sequence[pathlib.Path]
) -> collections.abc.Iterator[dict[str, typing.Any]]
```

Failed rollouts' rows, each with the model calls captured under its rollout id, read with the collector's
key and reader.

Collection joins captures only into a rollout that produced a result, so a row that failed without one (an
episode cut by its deadline, say) has none, although the model server captured its calls. Each capture dir is
listed once, never created. A row comes back as it is, its time unmeasured, when it carries its own capture
(so no call counts twice), when its capture is missing or partial (a write still claimed, a failed write, an
unreadable record), or when its identity or its capture cannot be read.

```python
nemo_gym.rollouts.rollout_health._worker(
    payload: nemo_gym.rollouts.health.types._WorkerInput
) -> nemo_gym.rollouts.health.types.RolloutDigest
```

```python
nemo_gym.rollouts.rollout_health._write_reports(
    summary: dict[str, typing.Any],
    digests: list[nemo_gym.rollouts.health.types.RolloutDigest],
    output_dir: pathlib.Path
) -> tuple[pathlib.Path, pathlib.Path]
```

```python
nemo_gym.rollouts.rollout_health.capture_dirs_for_health(
    global_config_dict: typing.Any
) -> list[pathlib.Path]
```

The run's model-call capture directories for `run_health_checks`; none when capture is off or misconfigured,
so a capture setting never stops the health check.

```python
nemo_gym.rollouts.rollout_health.evaluate_record(
    record: dict[str, typing.Any],
    ignored_checks: frozenset[str],
    line: nemo_gym.rollouts.health.types._LineSlice | None = None,
    parse_error: str | None = None
) -> nemo_gym.rollouts.health.types.RolloutDigest
```

Evaluate every rollout-level check on one rollout record.

The one code path behind both the post-run report (which reads `record` from a JSONL `line`)
and live emission (which passes the in-memory result, so `line` is `None`).

```python
nemo_gym.rollouts.rollout_health.format_health_report(
    result: nemo_gym.rollouts.health.types.HealthCheckResult
) -> str
```

```python
nemo_gym.rollouts.rollout_health.health_check_run_dir(
    run_dir: str | pathlib.Path,
    rollout_file: str | pathlib.Path | None = None,
    workers: int | None = None,
    ignored_checks: collections.abc.Sequence[str] = (),
    limits: nemo_gym.rollouts.health.types.RunHealthLimits | None = None,
    json_output: bool = False,
    model_call_capture_dir: str | pathlib.Path | None = None
) -> nemo_gym.rollouts.health.types.HealthCheckResult
```

Recheck a run directory. The run's own persisted limits judge it, so the verdict of the same artifacts
does not change. Each limit set explicitly on `limits` overrides only that persisted limit and is recorded
as an override; set to `None` it removes the limit. A limit not set keeps its persisted value.

A directory `gym eval aggregate` merged shards into is rechecked from those shards, with the failures and
inventories beside them, as the aggregation checked them. An explicit `rollout_file` is checked alone.

`model_call_capture_dir` is the run's `model_call_capture_dir`; with it, failed rollouts' captured calls
count in the timeouts section's time split.

```python
nemo_gym.rollouts.rollout_health.normalize_ignored_checks(
    checks: collections.abc.Sequence[str] | str | None
) -> tuple[str, ...]
```

Normalize and validate check IDs supplied by library, CLI, or Hydra config.

```python
nemo_gym.rollouts.rollout_health.run_health_checks(
    rollout_paths: pathlib.Path | collections.abc.Sequence[pathlib.Path],
    output_dir: pathlib.Path | None = None,
    workers: int | None = None,
    ignored_checks: collections.abc.Sequence[str] = (),
    limits: nemo_gym.rollouts.health.types.RunHealthLimits = RunHealthLimits(),
    limits_source: nemo_gym.rollouts.health.types.LimitsSource | collections.abc.Mapping[str, nemo_gym.rollouts.health.types.LimitsSource] = 'config',
    run_coverage: collections.abc.Sequence[collections.abc.Mapping[str, typing.Any] | None] | None = None,
    source_histories: collections.abc.Mapping[pathlib.Path, nemo_gym.rollouts.rollout_store.RolloutStore | None] | None = None,
    model_call_capture_dirs: collections.abc.Sequence[pathlib.Path] = ()
) -> nemo_gym.rollouts.health.types.HealthCheckResult
```

Check selected completed attempts while retaining run-wide failure and timeout evidence.

Workers read selected byte ranges from the original histories, which own selection and identity.
Aggregation supplies its scoring snapshots so health cannot select a later attempt while retaining older
coverage counts. Standalone calls load the current histories; explicit None entries denote loose inputs.
History-map keys accept the same relative paths and aliases as rollout_paths.
Loose JSONL and explicit failure sidecars retain their line-by-line behavior.

```python
nemo_gym.rollouts.rollout_health.run_provenance(
    rollout_path: pathlib.Path
) -> dict[str, typing.Any]
```

Facts about how the run was configured, read from the resolved config saved beside the rollouts.

Only values the config states are reported: `route_failures_to_sidecar` and each agent's `skip_verification`
are booleans when written as booleans and `None` otherwise, never a default. Each top-level server entry
reports its kind (`responses_api_agents`, `resources_servers` or `environment_servers`), its implementation
key and, for an agent, the resources server it names. No values beyond these names and flags are copied.

```python
nemo_gym.rollouts.rollout_health.write_aggregation_sources(
    merged_fpath: pathlib.Path,
    shards: collections.abc.Sequence[tuple[pathlib.Path, int, str]],
    merged_contents_fpath: pathlib.Path
) -> None
```

Record the shards `merged_fpath` is merged from, for a recheck of its directory to read.

The merged file holds only the shards' rows: their failure sidecars and inventories stay next to them.
`shards` holds each shard's path with the size and SHA-256 of what the merge read from it, and
`merged_contents_fpath` the rows about to take `merged_fpath`'s place; the record names both by size and
SHA-256, so it never vouches for other contents. Each shard is recorded relative to the record's directory,
so the shards and the merged file can move together, and under its own file name: a shard reached through a
file link keeps the sidecars beside the link, as the aggregation read them.

```python
nemo_gym.rollouts.rollout_health.write_disabled_summary(
    rollout_paths: collections.abc.Sequence[pathlib.Path],
    output_dir: pathlib.Path
) -> pathlib.Path | None
```

Write the quality summary of a run with `disable_health_check` set, so a disabled check is recorded as
`state: disabled` rather than by an absent summary. It counts and judges nothing: the counts and `healthy`
are null.

A report written at the end of a run must not stop it, so a write error is logged and returns `None`.

```python
nemo_gym.rollouts.rollout_health.write_provisional_summary(
    rollout_path: pathlib.Path,
    landed: set[tuple[typing.Any, typing.Any]],
    limits: nemo_gym.rollouts.health.types.RunHealthLimits = RunHealthLimits(),
    ignored_checks: collections.abc.Sequence[str] = (),
    run_coverage: collections.abc.Mapping[str, typing.Any] | None = None
) -> pathlib.Path
```

Write the run accounting of a stopped run fast: `rollouts.jsonl` is not read, and the per-record checks
are skipped.

`landed` is the `(task index, rollout index)` of every persisted record, as rollout collection holds it.
Duplicates come from the per-record pass, so `healthy` is false when the accounting already has a reason
and null otherwise. `gym eval health-check` on the run dir writes the full summary.

```python
nemo_gym.rollouts.health.checks.CHECK_REGISTRY: tuple[CheckSpec, ...] = (CheckSpec(id='check_execution_error', evaluation_scope=(CheckScope.ROLLOUT), su...
```

```python
nemo_gym.rollouts.rollout_health.MLFLOW_TRACKING_REQUIRED_KEY = 'mlflow_tracking_required'
```

```python
nemo_gym.rollouts.health.types.Verdict = Literal['healthy', 'unhealthy', 'unobserved']
```

```python
nemo_gym.rollouts.rollout_health._MLFLOW_REQUIRED_NAMES = ('mlflow_tracking_uri', 'mlflow_experiment_name', 'mlflow_run_name')
```

```python
nemo_gym.rollouts.rollout_health._PROCESS_POOL_CHUNKS_PER_WORKER = 4
```

```python
nemo_gym.rollouts.rollout_health._PROCESS_POOL_MAX_CHUNKSIZE = 128
```

```python
nemo_gym.rollouts.rollout_health._RUN_FAILURES_CHECK = 'run_excessive_failures'
```

```python
nemo_gym.rollouts.rollout_health.logger = logging.getLogger(__name__)
```