# Record And Effects

Use this reference when deciding what should be recorded, injected, exported, or left as runtime-only state.

## Mental model

- `ExperimentEffects` controls run-level side effects.
- `RecordConfig` controls trial record behavior.
- `ctx.set(...)` writes local record state.
- `simple_inject` is a runtime bridge, not the primary mental model.

## Recommended defaults

```python
ExperimentEffects(
    capture_stdout=True,
    record_env=True,
    record=RecordConfig(
        inject_namespaces=('default', 'train'),
        export_rule=('default', 'result', 'env'),
        auto_record=True,
    ),
)
```

## Choose the right storage target

| Data | Place |
|------|-------|
| Final metrics | `TrialResult.metrics` |
| Trial summary | `TrialResult.summary` |
| Output artifact paths | `TrialResult.artifacts` |
| Serializable data metadata | `ExperimentData.info` (consumed by auto_record) |
| Runtime-only data objects | `ExperimentData.extras` (ignored by framework) |
| Shared split plan / cache / index | `ctx.shared` |
| Small report metadata | `ctx.set(..., namespace=...)` |
| Runtime optimizer / scheduler object | `ctx.set(..., namespace='train')` only if injection/export is intentional |

## `export_rule`

Use a tuple/list when namespace allowlist is enough:

```python
RecordConfig(export_rule=('default', 'result', 'env'))
```

Use a predicate when the export decision depends on key/value:

```python
RecordConfig(
    export_rule=lambda namespace, key, value: namespace != 'train' and key != 'trial_mode'
)
```

Effects of the rule:

- It controls final `TrialReport.records` export.
- It also controls the default view of `ctx.snapshot_states()`.
- It does not change `ctx.recorded_states()`, which remains the raw local record store.

## `auto_record`

`auto_record=True` allows framework-managed convenience records.

Default auto-record targets:

- `ExperimentData.info`
- `ModelSetup.hparams`
- optimizer
- lr_scheduler
- `trial_name` / `trial_mode` / `trial_seed`

Disable it when the experiment needs a strict or hand-authored record surface:

```python
RecordConfig(auto_record=False)
```

Or tune it per field:

```python
RecordConfig(
    auto_record=AutoRecordConfig(
        optimizer=False,
        lr_scheduler=False,
    )
)
```

## Common mistakes

### Exporting too much

If exported YAML contains runtime-only objects, tighten `export_rule` or stop recording them.

### Putting runtime objects in `ExperimentData.info`

`info` is consumed by auto_record and serialized into YAML. Non-serializable or large runtime objects belong in `ExperimentData.extras`.

### Using `ctx.shared` as report storage

`ctx.shared` is for runtime reuse. It is not exported automatically.

### Treating injection and export as unrelated systems

They are both parts of the record system. Configure them together with `RecordConfig`.
