Skip to content

rollout/judge: per-seed error isolation with batch-level error-rate threshold - #44

Closed
jakepresent wants to merge 5 commits into
mainfrom
jakepresent/fix-rollout-input-error-isolation
Closed

rollout/judge: per-seed error isolation with batch-level error-rate threshold#44
jakepresent wants to merge 5 commits into
mainfrom
jakepresent/fix-rollout-input-error-isolation

Conversation

@jakepresent

@jakepresent jakepresent commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Problem

A single content-filter / input-refusal hit was killing entire scale runs. The May 11 overnight scale-500 was the first one: seed 501 of 502 was rejected by Azure CF, and 500 already-completed transcripts were thrown away. As subsequent runs ran further, three more independent places surfaced the same failure mode:

  • callable-target raw litellm exceptions - LangGraph (and any framework wrapper) makes provider calls inside the user callable, so litellm.BadRequestError etc. bypass generate()/_with_retries entirely and the rollout's isinstance(_, LLMInputError) checks miss them.
  • auditor-side input refusals - the adversarial prompt the auditor sends to the target trips Azure Prompt Shields' jailbreak detector. Surfaced live at seed 853/1000 on the May 12 mix run.
  • judge-side input refusals - the same adversarial content the auditor produced trips the content filter on the judge call itself. Surfaced at scored-seed 539/1000 on the May 12 rerun.
  • non-classified runtime errors inside the agent under test - openai.BadRequestError raised inside a LangGraph internal task ('research') escaped past both _run_prompt_seed and CallableSession's wrapper because it was raised in a different asyncio task than the one being awaited, so it never reached the classification layer at all.

This is the wrong failure mode for an adversarial-eval pipeline. Generating prompts the target / auditor / judge refuses is exactly what we're supposed to do, and the refusal itself is data we want to keep, not a global pipeline error.

Fix

Treat per-seed failures as data, not as global pipeline errors, at four layers, plus a generic catch-all with a batch-level error-rate threshold.

Per-layer isolation

Layer What's caught Recorded as
Target side (rollout._run_prompt_seed, _run_auditor_target_loop) LLMInputError from the target call [TARGET INPUT REFUSED: ...] event, stop_reason='target_input_refused'
Callable target classification (session.CallableSession.run_turn) Raw provider exceptions raised inside user callables Wrapped via _classify_llm_error so they flow through the same target-side isolation; unclassified errors propagate unchanged
Auditor side (rollout._run_auditor_target_loop) LLMInputError from the auditor call [AUDITOR INPUT REFUSED: ...] event, stop_reason='auditor_input_refused'
Judge side (stages.judge) LLMInputError on the judge call Synthetic score row with judge_status='filter_skipped', judge_error='judge_input_refused: ...'; flows through the existing infer_judge_status() contract as a non-ok seed

Generic catch-all (final commit)

Any non-global exception that escapes the targeted handlers now synthesizes a transcript with stop_reason='runtime_error' carrying a single system event with the error type and message. The transcript is written like a normal one; the seed isn't lost. The exception is still attached to the result so the gather loop can count it.

Batch-level error-ratio threshold

Replaced if errors: raise errors[0] in the rollout gather loop with a configurable threshold:

  • Default 10% (1 in 10 seeds erroring is the tipping point)
  • Tunable via P2M_ROLLOUT_ERROR_FAIL_RATIO for ops scenarios
  • Below threshold: log a single warning summary with the ratio, stage completes normally
  • Above threshold: log an error and raise the first exception so the runner surfaces a clean message

Systemic failures (auth misconfigured, every seed errors) still fail fast.

What still fails fast (intentionally)

  • LLMAuthError - global config problem; retry won't help
  • LLMRateLimitError - global throttling
  • LLMProviderError - provider 5xx; conservative choice
  • Any pre-rollout stage failure (policy/design/seeds) - those have no per-seed semantics

Validation

End-to-end 1k mix run on 15332c8 (travel-planner-langgraph-pr44-mix1k-e2e/baseline, 700 prompts + 300 scenarios, C=5):

Stage Wall Per case
policy 16.2s -
design 3.1s -
seeds 72.9s -
rollout 1796.7s (29.9 min) 1.80s
judge 1925.8s (32.1 min) 1.93s
total 3814.7s (1h 3m 36s)

1000/1000 transcripts, 1000/1000 scored, all judge_status='ok', zero recorded runtime errors. Earlier runs on the same branch did exercise the isolation paths live (auditor refusal at 853, judge filter at 539, LangGraph escape ~994); the final run was clean.

Tests

7 new tests:

  • test_run_turn_reclassifies_litellm_bad_request_as_input_error (session)
  • test_run_turn_passes_through_unclassified_exceptions (session)
  • test_run_prompt_seed_records_target_input_refusal (rollout)
  • test_run_rollout_isolates_target_input_refusal_to_one_seed (rollout)
  • test_run_rollout_isolates_auditor_input_refusal_to_one_seed (rollout)
  • test_run_rollout_still_fails_fast_on_provider_5xx (rollout)
  • test_run_rollout_tolerates_below_threshold_errors (rollout)

1 existing test updated (test_run_rollout_keeps_partial_successful_transcripts_when_later_worker_fails) to reflect the new contract: failing seeds now have synthesized stop_reason='runtime_error' transcripts, and the 50% error rate still aborts.

All 52 rollout + exception-handling tests pass locally.

Files

p2m/core/session.py              |  37 +++-
p2m/stages/judge.py              |  36 +++-
p2m/stages/rollout.py            | 194 ++++++++++++++++---
tests/test_exception_handling.py |  69 +++++++
tests/test_rollout_stage.py      | 401 +++++++++++++++++++++++++++++++++++-
5 files changed, 702 insertions(+), 35 deletions(-)

Commits (read in order)

Each commit closed a real gap surfaced by the previous commit's validation, so the sequence is also the discovery log:

  1. 82cf339 - target-side LLMInputError isolation (the original May 11 fix).
  2. 0184d8d - classify raw litellm exceptions raised inside user callables, so callable-target frameworks (LangGraph, etc.) flow through the same target-side isolation.
  3. f265154 - auditor-side LLMInputError isolation.
  4. dcaa91f - judge-side LLMInputError isolation.
  5. 15332c8 - generic per-seed error isolation with batch-level error-ratio threshold.

Known follow-ups not in this PR

  • Seeds-stage content-filter refusals are not isolated. Generation is pre-rollout, so the per-seed semantics here don't apply directly. Separate work.
  • 10% default error-ratio threshold is a starting value, not a calibrated one. For 10-seed runs it's 1-error sensitive; for 1k+ runs it allows up to 100 silent errors. Worth revisiting once we have multi-run error-rate data.
  • P2M_ROLLOUT_ERROR_FAIL_RATIO env var is a temporary control surface. If it stays useful it should graduate to a real config field; if not, it can be dropped.
  • Overlaps with Aaron's PR Load testing #45 benchmark shim (_install_content_filter_tolerance in scripts/benchmark.py, using stop_reason="content_filter_blocked"). That patch monkey-patches the rollout to drop content-filter-blocked seeds at benchmark time; this PR lands per-seed isolation in product code so the shim can be retired once Load testing #45 merges (or revisited to align stop_reason naming).

…ing batch

A single target-side LLMInputError (e.g. Azure content filter rejecting
an adversarial prompt) was killing the entire rollout stage. The overnight
scale-500 run on May 11 hit this exactly: seed 501 of 502 was refused
by Azure CF, and 500 already-completed transcripts were discarded
because the worker re-raised LLMInputError and the gather loop fails
the stage on the first exception.

This is the wrong failure mode for an adversarial-evaluation pipeline:
generating prompts the target refuses is exactly what we're supposed to
do, and the refusal itself is data we want to keep, not a global error.

Fix:

- _run_prompt_seed: when the target's run_turn raises LLMInputError,
  record a [TARGET INPUT REFUSED] event in the transcript and return
  with stop_reason='target_input_refused' instead of propagating. Other
  classified errors (LLMAuthError, LLMRateLimitError, LLMProviderError)
  and arbitrary runtime exceptions still propagate, since those are
  global pipeline problems rather than seed-specific.
- _run_auditor_target_loop: same treatment for target-call refusals
  mid-conversation. Auditor-side LLMInputError still propagates because
  the auditor is our own generator, not seed data.

The judge stage already passes stop_reason through opaquely, so the
new target_input_refused value flows downstream without any judge-side
changes.

Tests:

- test_run_prompt_seed_records_target_input_refusal: unit test that
  mocks the runtime to raise LLMInputError and verifies the transcript
  carries stop_reason='target_input_refused' plus the refusal event.
- test_run_rollout_isolates_target_input_refusal_to_one_seed: end-to-end
  reproduction of the May 11 scenario at 5-seed scale. One seed gets
  refused; the other 4 complete cleanly; the batch returns successfully.
- test_run_rollout_still_fails_fast_on_provider_5xx: regression guard
  that auth/rate-limit/5xx errors still abort the stage.
The rollout isolation in the previous commit converts target-side
LLMInputError into a recorded transcript event with
stop_reason="target_input_refused". It only fires when the exception
reaches the rollout helpers as an already-classified LLM error class.

For callable: targets (LangGraph agents, framework wrappers, raw
litellm callers, etc.) the user's own code makes the provider calls
and bypasses generate()/_with_retries entirely, so provider errors
bubble up as raw litellm exceptions (BadRequestError,
ContentPolicyViolationError, RateLimitError, ...). The rollout's
isinstance(_, LLMInputError) checks miss them and the stage aborts on
the first content-filter rejection \u2014 the same failure pattern the
isolation was supposed to fix.

Fix CallableSession.run_turn so any exception escaping invoke_callable
is passed through _classify_llm_error before propagating. Classified
errors are re-raised with __cause__ preserved; unclassified errors
(user agent crashes, ValueError from misconfigured tools, etc.) pass
through unchanged so they don't get smuggled into one of the four LLM
error classes.

Tests:

- test_run_turn_reclassifies_litellm_bad_request_as_input_error: a
  fake litellm BadRequestError raised from inside the user callable
  emerges as LLMInputError with cause preserved.
- test_run_turn_passes_through_unclassified_exceptions: a custom
  RuntimeError from inside the user callable propagates as itself,
  not as any LLM*Error class.

All 50 rollout + exception-handling tests pass. Local smoke against
azure/gpt-5.4-mini with the LangGraph travel-planner callable
(30 prompts + 10 scenarios, C=4) completed end-to-end in 176.9s.
@jakepresent

Copy link
Copy Markdown
Collaborator Author

Pushed 0184d8d: CallableSession.run_turn now classifies exceptions escaping invoke_callable through _classify_llm_error before they propagate.

Why the second commit: the rollout isolation in the first commit only fires when the exception reaches the helpers as an already-classified LLMInputError. For callable: targets (LangGraph agents, framework wrappers, raw litellm callers), the user's own code makes the provider call and bypasses generate()/_with_retries entirely, so provider errors bubble up as raw litellm.BadRequestError and the isinstance(_, LLMInputError) checks miss them. Same failure pattern the isolation was meant to fix. Caught this locally when smoke-testing the PR against the LangGraph travel-planner callable.

Classified errors are re-raised with __cause__ preserved; unclassified exceptions (user agent crashes, etc.) pass through unchanged so they don't get smuggled into one of the four LLM error classes.

Two new tests in tests/test_exception_handling.py:

  • test_run_turn_reclassifies_litellm_bad_request_as_input_error
  • test_run_turn_passes_through_unclassified_exceptions

50/50 rollout + exception-handling tests pass.

The previous commits isolate target-side LLMInputError. Auditor-side
LLMInputError (where the auditor's adversarial prompt itself trips the
provider's content filter / Prompt Shields jailbreak detector) was
still re-raised by _run_auditor_target_loop's auditor catch block,
which aborted the whole rollout stage on the first occurrence.

This was hit live on the May 12 PR #44 mix-1k validation run: at
scenario 853 of 1000, the auditor's adversarial prompt for one seed
was refused by Azure Prompt Shields with the same Bad request /
'flagged as potentially violating our usage policy' signature. Aaron
flagged this auditor-side refusal pattern in the May 12 standup and
worked around it in PR #45 with a tame auditor system prompt for
benchmarking; the right fix in product code is the same per-seed
isolation as the target-side case.

Fix: catch LLMInputError separately from the other classified errors
in _run_auditor_target_loop's auditor block. Record an
'[AUDITOR INPUT REFUSED: ...]' system event in the transcript, set
stop_reason='auditor_input_refused', and end the conversation cleanly
so the worker moves on to the next seed. Auth/rate-limit/5xx errors
still propagate (they're global pipeline problems, not seed-specific).

Tests:

- test_run_rollout_isolates_auditor_input_refusal_to_one_seed: 5-seed
  scenario batch where one seed's auditor call raises LLMInputError;
  all 5 transcripts are written, the refused seed carries
  stop_reason='auditor_input_refused', the batch returns successfully.

All 51 rollout + exception-handling tests pass.
@jakepresent

Copy link
Copy Markdown
Collaborator Author

Pushed f265154: auditor-side LLMInputError now gets the same per-seed isolation as the target-side case.

Hit this live on the mix-1k validation run: at scenario 853/1000 the auditor's adversarial prompt for one seed tripped Azure Prompt Shields' jailbreak detector. Same Bad request / 'flagged as potentially violating our usage policy' signature, just on the auditor side instead of the target side. This is the same pattern Aaron flagged in standup today and worked around in PR #45 with a tame auditor prompt.

The previous two commits handled the target side and the callable-target classification gap. This one closes the loop: _run_auditor_target_loop now catches LLMInputError separately from the other classified errors, records an [AUDITOR INPUT REFUSED: ...] system event in the transcript with stop_reason='auditor_input_refused', and ends the conversation cleanly. Auth/rate-limit/5xx errors still propagate.

One new test, test_run_rollout_isolates_auditor_input_refusal_to_one_seed, reproduces the May 12 scenario at 5-seed scale: one seed's auditor call raises LLMInputError, the other four complete cleanly, the batch returns successfully. 51/51 rollout + exception-handling tests pass.

Relaunching the 1k mix overnight on this commit.

The previous commits isolate target-side LLMInputError and auditor-side
LLMInputError in rollout. The judge stage had the same fail-fast catch
for LLMInputError: a single content-filter rejection on a transcript
the judge LLM can't process would kill the whole stage and discard the
hundreds of seeds already scored.

This was hit live on the May 12 PR #44 mix-1k validation rerun (after
the auditor-side fix from f265154 unblocked rollout): the judge stage
scored 539 of 1000 transcripts at the lowered concurrency, then died
when one transcript's adversarial content tripped Azure's content
filter on the judge call itself. Same Bad request / 'flagged as
potentially violating our usage policy' signature, just on the judge
side. This is the third logically-independent place the same
adversarial-eval-as-attacker dynamic can fire.

Fix: catch LLMInputError separately in the judge worker. Record a
synthesized score row with judge_status='filter_skipped' and
judge_error='judge_input_refused: ...' so the seed isn't lost and
infer_judge_status downstream correctly counts it as a non-ok seed.
Auth/rate-limit/provider-5xx errors still propagate (global pipeline
problems, not seed-specific).

The filter_skipped status flows cleanly through the existing
infer_judge_status() contract in p2m/core/judge.py: it's a non-'ok'
status, so it's treated as judge_failed by downstream consumers
(results.py, viewer_read_model.py). This matches Aaron's PR #45
_install_judge_skip_blocked shim, but lands the behavior in product
code instead of as a benchmark monkey-patch.
@jakepresent

Copy link
Copy Markdown
Collaborator Author

Pushed dcaa91f: judge-side LLMInputError now gets the same per-seed isolation as the rollout-side cases.

Hit this live on the mix-1k rerun. After the auditor-side fix from f265154 unblocked rollout, the judge stage made it through 539 of 1000 transcripts (at C=3 to avoid the rate-limit cliff at C=10) before one transcript's adversarial content tripped Azure's content filter on the judge call itself. Same Bad request / 'flagged as potentially violating our usage policy' signature, just on the judge side instead of target or auditor.

This is the third logically-independent place the same adversarial-eval-as-attacker dynamic fires, so PR #44 has grown into a coherent 'isolate LLMInputError per-seed across all three stages' shape:

  • target-side (82cf339): rollout records stop_reason=target_input_refused
  • callable target classification gap (0184d8d): CallableSession.run_turn classifies raw litellm exceptions so the rollout fix actually fires on callable: targets
  • auditor-side (f265154): rollout records stop_reason=auditor_input_refused
  • judge-side (dcaa91f): judge synthesizes a judge_status=filter_skipped score row with judge_error=judge_input_refused: ...

The filter_skipped status flows cleanly through infer_judge_status() in p2m/core/judge.py as a non-ok status, so results.py and viewer_read_model.py correctly count these as non-scored seeds without any further changes. Matches Aaron's PR #45 _install_judge_skip_blocked shim behavior, but lands it in product code instead of as a benchmark monkey-patch.

Re-running the mix-1k now on the new HEAD.

…o threshold

Previous commits handled three specific per-seed failure cases by
classification (target LLMInputError, callable target unclassified
litellm exceptions, auditor LLMInputError). Each surfaced through live
validation. The mix-1k run on 2026-05-12 then surfaced a fourth gap
that none of those targeted fixes covered: an openai.BadRequestError
raised inside a LangGraph internal task (named 'research') escaped
past _run_prompt_seed and CallableSession's wrapper. PR #44's other
fixes work on classified errors; this one was raised in a different
asyncio task than the one being awaited, so it never reached the
classification layer at all.

Rather than chase the next specific failure mode, this commit adopts a
generic guarantee: one bad conversation can't kill the whole run.

Worker change:
- Removed the (ValueError, KeyError) and bare-Exception handlers that
  returned {'error': exc} and were stop-the-stage on any error.
- Any non-global exception (i.e. not LLMAuthError, LLMRateLimitError,
  LLMProviderError) now synthesizes a transcript with
  stop_reason='runtime_error' carrying a single system event with the
  error type and message. The transcript is written like a normal one;
  the seed isn't lost. The exception is still attached to the result
  so the outer loop can count it toward the error-ratio threshold.

Gather-loop change:
- Replaced 'if errors: raise errors[0]' with an error-ratio threshold.
- Default 10% (1 in 10 seeds erroring is the tipping point), tunable
  via the P2M_ROLLOUT_ERROR_FAIL_RATIO env var for ops scenarios.
- Below threshold: log a single warning summary with the ratio and
  threshold and let the stage complete normally.
- Above threshold: log an error and raise the first exception so the
  runner surfaces a clean message. Systemic problems (deployment
  misconfigured, every seed errors) still fail fast.

Tests:
- Updated test_run_rollout_keeps_partial_successful_transcripts_when_later_worker_fails
  to reflect the new contract: both seeds now have transcripts (the
  failing one with stop_reason='runtime_error'), and the stage still
  aborts at 50%>10% ratio.
- New test_run_rollout_tolerates_below_threshold_errors: 20 seeds, 1
  fails -> 5% below threshold -> batch completes with synthesized
  runtime_error transcript for the failing seed and 19 clean ones.

All 52 rollout + exception-handling tests pass.
@jakepresent

Copy link
Copy Markdown
Collaborator Author

Pushed 15332c8: generic per-seed error isolation with a batch-level error-ratio threshold (default 10%).

The mix-1k validation tonight surfaced a fourth specific failure mode that the targeted classification fixes don't catch: an openai.BadRequestError raised inside a LangGraph internal task escaped past _run_prompt_seed because it was raised in a different asyncio task than the one being awaited. Classification only catches errors that reach the classifier.

Rather than chase the next specific gap, this commit adopts a generic guarantee: one bad conversation can't kill the whole run.

  • The worker now catches all non-global exceptions and synthesizes a transcript with stop_reason='runtime_error' carrying the error message. The seed is preserved as data, not lost.
  • The gather loop replaces if errors: raise errors[0] with an error-ratio threshold (default 10%, tunable via P2M_ROLLOUT_ERROR_FAIL_RATIO). Below threshold: warn and continue. Above threshold: abort the stage. Systemic problems (deployment misconfigured, every seed errors) still fail fast.
  • Auth/rate-limit/provider-5xx still propagate as before (these are global, not seed-specific).

PR #44's shape has now stabilized into 'isolate per-seed failures, fail the stage only on systemic problems.' Five commits total:

  • 82cf339 target-side LLMInputError
  • 0184d8d callable target classification gap
  • f265154 auditor-side LLMInputError
  • dcaa91f judge-side LLMInputError
  • 15332c8 generic per-seed error isolation + ratio threshold

52/52 rollout + exception-handling tests pass.

@jakepresent jakepresent changed the title fix(rollout): isolate target-side input refusals per-seed instead of aborting batch rollout/judge: per-seed error isolation with batch-level error-rate threshold May 13, 2026
AaronAspinwall123 added a commit that referenced this pull request May 14, 2026
Lifts the four product-code changes from PR #44 into our branch and
removes the corresponding benchmark monkey-patches that were doing the
same job out-of-tree.

Changes:

* CallableSession.run_turn now reclassifies user-callable provider
  errors via `_classify_llm_error` so litellm BadRequestError /
  ContentPolicyViolationError emerge as typed `LLMInputError` (with
  `__cause__` preserved) instead of bypassing the typed-exception layer
  the rollout/judge stages key off. Unclassified exceptions propagate
  untouched. (PR #44 commit 0184d8d)

* `_run_prompt_seed` records a `[TARGET INPUT REFUSED: ...]` event in
  the transcript and sets `stop_reason='target_input_refused'` when the
  target's run_turn raises `LLMInputError`. Other classified errors
  still propagate. (PR #44 commit 82cf339)

* `_run_auditor_target_loop` splits the combined classified-error catch
  into a typed `LLMInputError` branch that records
  `[TARGET INPUT REFUSED: ...]` / `[AUDITOR INPUT REFUSED: ...]` events
  and sets `stop_reason='target_input_refused'` /
  `'auditor_input_refused'` respectively. Auth / rate-limit / 5xx
  errors still propagate. (PR #44 commits 82cf339 + f265154)

* judge `_worker` splits the combined catch so `LLMInputError` becomes
  a synthesized `score_row` with `judge_status='filter_skipped'` and
  `judge_error='judge_input_refused: ...'`. Rate-limit / provider 5xx
  still go to the per-row error path. Auth still fails fast. (PR #44
  commit dcaa91f)

* New `P2M_ROLLOUT_ERROR_FAIL_RATIO` env var (default 0.10) caps the
  rollout stage's tolerance for *untyped* worker errors. Below the
  threshold: warn and continue (existing soft-fail). Above: raise the
  first error. Typed refusals (target_input_refused,
  auditor_input_refused, target_error) are NOT counted toward the ratio
  — they're recorded data, not real failures. Inspired by PR #44
  commit 15332c8 but scoped to untyped errors only instead of #44's
  blanket runtime_error catch-all (which would have hidden real bugs
  behind the same threshold).

* scripts/benchmark.py: drops `_install_content_filter_tolerance`,
  `_install_judge_skip_blocked`, and `_is_content_policy_violation`
  helpers (~210 lines). The product-code typed handlers above replace
  them. The benchmark now scans `transcripts.jsonl` and `scores.jsonl`
  after the run completes and counts typed stop_reasons /
  judge_status values. CSV columns updated to typed names:
  `target_input_refused_count`, `auditor_input_refused_count`,
  `target_error_count`, `judge_filter_skipped_count` (replaces the
  legacy `content_filter_blocked` / `target_error_tolerated`
  aggregates). `--no-tolerate-content-filter` flag preserved as a
  no-op for back-compat.

Tests:

* test_run_turn_reclassifies_litellm_bad_request_as_input_error
* test_run_turn_passes_through_unclassified_exceptions
* test_run_prompt_seed_records_target_input_refusal
* test_run_rollout_isolates_target_input_refusal_to_one_seed
* test_run_rollout_isolates_auditor_input_refusal_to_one_seed
* test_run_rollout_still_fails_fast_on_provider_5xx
* test_run_rollout_fails_when_untyped_error_ratio_exceeds_threshold
  (new — covers the threshold introduced in this commit)
* test_run_judge_isolates_input_refusal_to_one_seed
* test_run_rollout_keeps_partial_successful_transcripts_when_later_worker_fails
  (updated — sets P2M_ROLLOUT_ERROR_FAIL_RATIO=0.6 since the original
  2-seed/1-failure setup now exceeds the production 10% default)

654 passed, 14 skipped, 13 subtests, 2 deselected (pre-existing
Windows tempdir flakes in test_logging_config.py from main's PR #22).
0 new test failures. viewer check: 0 errors / 0 warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jakepresent

Copy link
Copy Markdown
Collaborator Author

Closing as superseded by #45. Aaron's PR absorbed the per-row/per-batch error-isolation pieces from this branch and now has the cache-finalization and benchmark-summary fixes on top.

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.

1 participant