Skip to content

fix: make canonical metrics terminal-info resolution safe - #116

Merged
ashishsinghbora merged 15 commits into
ashishsinghbora:mainfrom
AryanXCode646:main
Sep 20, 2026
Merged

ashishsinghbora merged 15 commits into
ashishsinghbora:mainfrom
AryanXCode646:main

Conversation

@AryanXCode646

Copy link
Copy Markdown
Contributor

Summary

This follow-up hardens the canonical episode metrics pipeline against arbitrary environment telemetry in terminal info mappings.

The previous implementation used dictionary equality to determine whether the terminal info had already been recorded. That is unsafe when telemetry contains non-scalar values such as NumPy arrays, because equality comparisons can raise ambiguous truth-value errors.

Changes
Removed unsafe equality-based comparison of arbitrary telemetry mappings in _resolve_episode_step_infos().
Switched terminal-step deduplication to an explicit, safe representation/identity contract.
Preserved existing episode ordering and terminal-step semantics.
Added regression coverage for terminal info containing NumPy arrays and nested non-scalar telemetry.
Added coverage ensuring an already-recorded terminal mapping is not duplicated.
Verified that existing canonical metrics semantics remain unchanged.
Regression case

The metrics pipeline now safely handles telemetry such as:

{
"success": True,
"queue_lengths": np.array([2, 1, 0]),
}

without attempting to use arbitrary telemetry equality as a boolean predicate.

Validation
Focused canonical metrics tests pass.
Broader test suite passes.
Lint/type checks pass where configured.
No unrelated public API behavior was intentionally changed.
Motivation

This closes the correctness issue identified during review and ensures the canonical metrics layer remains robust when environments provide complex telemetry payloads.

… downstream consumers

- Enforce invariant in extract_episode_metrics where collision=True overrides any conflicting positive success flag to False
- Align Evaluator and GeneralizationEvaluator success rate aggregation directly on canonical EpisodeMetrics
- Fix Dict type hint in CurriculumTrainer for backward typing compatibility
- Add regression tests verifying conflicting info resolution and cross-consumer consistency
…, and canonical public API

- Introduce EpisodeMetricsAccumulator for multi-step collision and success tracking across evaluation routines
- Preserve traffic-specific evaluation contract requiring controlled queues and no overflow/premature termination
- Document canonical rate denominator semantics over evaluation episodes
- Update callback fallback extraction to respect truncation/termination flags
- Consolidate canonical EpisodeMetrics public API under adaptive_rl.metrics
- Add regression tests for multi-step outcomes, traffic overflow, and mixed outcome rates
…tcome policies

- Preserve nullable tri-state metrics (None/False/True) end-to-end across models, trainers, and callbacks
- Ensure outcome rates compute over defined episodes with valid denominators (returning None when undefined)
- Extract traffic domain-specific logic into TrafficOutcomePolicy via composition
- Wrap extract_episode_metrics cleanly around EpisodeMetricsAccumulator
- Establish adaptive_rl.metrics as single canonical public owner with backward-compatible re-exports
- Update benchmark reports, metadata serialization, and experiment records to handle nullable metrics
- Add full lifecycle regression tests for None preservation, explicit False, multi-step precedence, and rates
…bility roundtrip

- Prevent intermediate success flags from latching into traffic episode outcomes
- Add load_episodes_csv to ensure full lossless round-trip for tri-state outcome fields
- Document precise PPO/SAC data flow through SB3CallbackAdapter to EpisodeMetricsAccumulator
- Safely handle nullable success rates in curriculum rolling metrics and stage advancement
- Add explicit regression tests for traffic terminal success rules and CSV serialization roundtrip
…nterpretation and enforce single outcome source of truth
…olation

Fix/pr 114 metrics policy isolation
Replace unsafe dict equality comparison in _resolve_episode_step_infos
with object identity (is). Environments can include NumPy arrays or
other non-scalar values in info dicts, and comparing them with == raises
ValueError. Identity is the correct contract here — we only need to skip
appending when the caller passes the exact same object.
…olation

fix: use identity check for terminal-info deduplication
@ashishsinghbora

ashishsinghbora commented Sep 20, 2026

Copy link
Copy Markdown
Owner

@AryanXCode646
One thing I’d like to clarify before merging: the new deduplication relies on object identity ("is") rather than structural equality. This correctly avoids NumPy's ambiguous truth-value problem, but it also means two separately-created dictionaries containing exactly the same terminal telemetry will intentionally be treated as different entries.

Can we add an explicit test/documentation for this contract and confirm that callers are expected to preserve the same "info" object when it is already present in "step_infos"? Otherwise, a caller that reconstructs the terminal mapping could still produce a duplicate terminal step without any indication that it is semantically equivalent.

@ashishsinghbora
ashishsinghbora merged commit ed0e803 into ashishsinghbora:main Sep 20, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants