Skip to content

refactor(bench): RFC 0031 — split the comparative harness + dispatch class filter - #542

Merged
jensholdgaard merged 3 commits into
mainfrom
bench-harness-split
Jul 18, 2026
Merged

jensholdgaard merged 3 commits into
mainfrom
bench-harness-split

Conversation

@jensholdgaard

@jensholdgaard jensholdgaard commented Jul 18, 2026

Copy link
Copy Markdown
Owner

What

Two long-deferred items in one structural PR: the #499 harness split and #538's last item (the dispatch class filter), sequenced together because the filter touches exactly the dispatch plumbing the split reorganizes.

The split (#499)

rfc0031_comparative.rs (6,031 lines) becomes a directory target — same single binary (RFC 0028 consolidation preserved: tests/rfc0031_comparative/main.rs), same nextest group — cut along the seams #499 proposed:

file lines contents
main.rs 1,182 module doc, §5 scenario tests, the dispatch run + reports
pickers.rs 1,403 corpus scanners, five pair pickers, shared fixtures
picker_tests.rs 1,090 the pickers' unit tests
harness.rs ~1,100 specs, gate math, latency channel, template-map probe, results record
loki.rs 976 container plumbing, LOKI_DISPATCH_FLAGS, HTTP, measurement polls, diagnostics
interop.rs 409 the two PR-gated Docker tests

Item bodies are byte-identical moves; visibility is pub(crate). Test names are unchanged except the two Docker tests, which become interop::-qualified — and that renaming exposed a trap worth naming: the loki-interop job filters by --exact, and a stale bare name would have matched nothing and still exited 0, silently hollowing out a required check. The job now greps 2 passed from the tee'd log (with pipefail), so an empty filter is a hard failure forever.

The class filter (#538 item 4)

OURIOS_COMPARATIVE_CLASSES (workflow input classes, default all): a targeted re-run — say, re-verifying one flaky pair after an L3 flicker — measures only the requested classes, skipping the other classes' measurement polls and latency reps (~2 h → substantially less; ingest still dominates the floor). Skipping L4 also skips pick_frequency_pair (the one expensive picker pass) and downgrades the L4-missing must-win failure to a requested skip.

Discipline boundaries, explicitly:

  • The filter selects what is measured, never what a measured pair asserts — equivalence and the frozen §7 gates apply unchanged to everything that runs.
  • The results artifact records the filter (additive class_filter field, null for a full run) so the completeness trend series distinguishes partial runs from full ones.
  • Unknown class names panic loudly (a typo that silently measured nothing would read as a mysteriously thin run).
  • Unit tests: the parser grammar, subset/full behavior, loud-rejection, and an exhaustiveness anchor tying PairClass::ALL to the enum so a future variant can't silently become unfilterable.

Hazards / invariants

No production code. The §7 gate semantics, equivalence rules, and measurement paths are untouched (byte-identical moves + a measurement-selection layer). The one behavioral edge — L4-missing no longer failing a run that excluded L4 — is the filter's documented purpose, and full runs (the default) behave exactly as before.

Checks run

cargo fmt --all --check; workspace cargo clippy --all-targets --all-features -- -D warnings; ourios-bench lib (134) + rfc0031_comparative integration tests (45 = 42 + 3 filter tests; 7 ignored Docker/dispatch). This PR's own loki interop job exercises the renamed Docker tests + the empty-filter guard live.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WQY9wfrfRggqSpMLH8Xj3Y

Summary by CodeRabbit

  • New Features

    • Added configurable comparative benchmark runs, including filtering by selected taxonomy classes.
    • Added machine-readable benchmark results with byte counts, completeness details, latency measurements, and gate outcomes.
    • Added end-to-end comparisons against Loki for log queries, trace lookups, template searches, and frequency aggregations.
  • Bug Fixes

    • Improved handling and reporting of incomplete benchmark results, ingestion issues, and template-map acquisition failures.
  • Tests

    • Expanded validation for query equivalence, backdated data, aggregation accuracy, latency thresholds, and benchmark fixture selection.
    • CI now verifies expected interop test outcomes and preserves test output for troubleshooting.

Issue #499 + issue #538 item 4.

The split: rfc0031_comparative.rs (6,031 lines) becomes a directory
target — same single binary, same nextest group, same test names except
the two Docker tests (now interop::-qualified) — cut along the seams
#499 proposed: main.rs (module doc, §5 scenario tests, the dispatch run
+ its reports), loki.rs (container plumbing, the shared
LOKI_DISPATCH_FLAGS, HTTP + measurement polls, diagnostics), interop.rs
(the two PR-gated Docker tests), pickers.rs (corpus scanners + pair
pickers + shared fixtures), picker_tests.rs, harness.rs (specs, gate
math, latency channel, template-map probe, results record). Largest
file is now 1,403 lines. Every moved item is pub(crate); item bodies
are byte-identical moves.

The loki-interop CI job's --exact filters are updated to the qualified
names, WITH a guard: a bare name would have matched nothing and still
exited 0, silently hollowing out a required check — the job now greps
"2 passed" from the tee'd log (pipefail keeps real failures fatal).

The class filter: OURIOS_COMPARATIVE_CLASSES (workflow input `classes`,
default "all") selects which taxonomy classes a dispatch measures, so a
targeted re-run — re-verifying one flaky pair — skips the other
classes' measurement polls and latency reps instead of paying the full
~2h. Skipping L4 also skips pick_frequency_pair (the one expensive
picker pass) and downgrades the L4-missing must-win failure to a
requested skip. The filter never touches what a measured pair asserts —
equivalence and the frozen gates apply to everything that runs — and
the results artifact records the filter (additive `class_filter` field,
null for a full run) so the trend series can tell partial runs apart.
Unknown class names panic loudly. Unit tests cover the parser, the
subset/full behaviors, and an exhaustiveness anchor tying
PairClass::ALL to the enum.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQY9wfrfRggqSpMLH8Xj3Y
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jensholdgaard, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 649dab5c-671c-42e1-8cba-25a025c237d7

📥 Commits

Reviewing files that changed from the base of the PR and between b9a00f3 and 0af2ab0.

📒 Files selected for processing (3)
  • crates/ourios-bench/tests/rfc0031_comparative/harness.rs
  • crates/ourios-bench/tests/rfc0031_comparative/loki.rs
  • crates/ourios-bench/tests/rfc0031_comparative/main.rs
📝 Walkthrough

Walkthrough

Adds the RFC0031 comparative benchmark stack: deterministic pair pickers, Ourios/Loki measurements, byte and latency gates, JSON artifacts, Docker interop tests, and workflow controls for selecting benchmark classes.

Changes

RFC0031 comparative evaluation

Layer / File(s) Summary
Pair discovery and fixture validation
crates/ourios-bench/tests/rfc0031_comparative/pickers.rs, crates/ourios-bench/tests/rfc0031_comparative/picker_tests.rs
Adds deterministic selective, trace, template, window, frequency, and diagnostic pair selection with corpus and fixture validation tests.
Comparative specifications and gates
crates/ourios-bench/tests/rfc0031_comparative/harness.rs, crates/ourios-bench/tests/rfc0031_comparative/main.rs, .github/workflows/comparative-bench.yml
Adds pair specs, class filtering, latency and byte gates, template-map checks, result artifacts, RFC scenario tests, and dispatch wiring.
Loki container and measurement backend
crates/ourios-bench/tests/rfc0031_comparative/loki.rs
Adds Loki startup, OTLP ingestion, range and matrix queries, latency polling, completeness handling, and diagnostics.
Docker interop validation
crates/ourios-bench/tests/rfc0031_comparative/interop.rs, .github/workflows/ci.yml
Adds current and backdated Ourios/Loki equivalence tests and validates the interop test count in CI.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

  • jensholdgaard/ourios issue 499 — Directly describes splitting the RFC0031 comparative harness into picker, Loki, harness, interop, and main modules.

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant Workflow
  participant ComparativeTest
  participant OuriosStore
  participant LokiContainer
  Workflow->>ComparativeTest: set selected benchmark classes
  ComparativeTest->>OuriosStore: build store and measure pair specs
  ComparativeTest->>LokiContainer: start container and push OTLP corpus
  ComparativeTest->>LokiContainer: poll range and matrix queries
  ComparativeTest->>ComparativeTest: evaluate gates and produce JSON results
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: splitting the RFC 0031 comparative harness and adding a dispatch class filter.
Description check ✅ Passed The description covers the summary, related issue context, implementation details, hazards, and checks run, though it doesn't use the template headings exactly.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bench-harness-split

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restructures the RFC 0031 comparative benchmark harness in ourios-bench by splitting the previously monolithic rfc0031_comparative integration test into multiple modules while preserving the single test binary entrypoint, and adds a dispatch-time “taxonomy class” filter to allow targeted comparative re-runs (e.g., only L3 or only L4) without changing any equivalence/gate semantics for the pairs that do run.

Changes:

  • Split the RFC 0031 comparative integration test into a directory of modules (main.rs + harness.rs + pickers.rs + picker_tests.rs + loki.rs + interop.rs), keeping the consolidated test binary.
  • Add OURIOS_COMPARATIVE_CLASSES / workflow input classes to measure only selected PairClass categories and record that filter in the results artifact.
  • Harden CI’s loki-interop job against silent no-op --exact filters by using module-qualified test names and grepping for “2 passed”.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
crates/ourios-bench/tests/rfc0031_comparative/main.rs New module entrypoint + scenario tests + dispatch-only comparative run; applies class filtering to measured pairs.
crates/ourios-bench/tests/rfc0031_comparative/harness.rs PairSpec/gate machinery, latency channel, results artifact schema, and new ClassFilter parsing/serialization.
crates/ourios-bench/tests/rfc0031_comparative/pickers.rs Corpus scanning + picker logic (selective/trace/template/frequency/window) and shared fixtures.
crates/ourios-bench/tests/rfc0031_comparative/picker_tests.rs Unit tests for pickers and fixtures (moved out of the monolith).
crates/ourios-bench/tests/rfc0031_comparative/loki.rs Loki container plumbing, OTLP push, query/poll loops, and diagnostics; shared dispatch flags.
crates/ourios-bench/tests/rfc0031_comparative/interop.rs Docker-gated interop tests (equivalence + backdated wide-range) used by CI.
.github/workflows/comparative-bench.yml Adds classes workflow input and wires it to OURIOS_COMPARATIVE_CLASSES.
.github/workflows/ci.yml Updates loki-interop to use module-qualified test names and adds a grep guard to fail on empty filters.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/ourios-bench/tests/rfc0031_comparative/harness.rs Outdated
Comment thread crates/ourios-bench/tests/rfc0031_comparative/main.rs Outdated
Both Copilot findings on the split PR were genuine:

ClassFilter::parse now de-duplicates tokens first-seen — "L1,L1" is one
class, and a list naming every class with repeats is a FULL run
(artifact_value keys off the count, so duplicates previously made a
full run read as partial in the results artifact).

The filter moves inside build_pair_specs/class_pair_specs instead of a
post-hoc retain: an excluded class must impose no preconditions —
concretely, a classes=L1 dispatch previously still died on the L6
window loop's no-clean-window panic for a class it never asked to
measure. Skip messages now say "SKIPPED by OURIOS_COMPARATIVE_CLASSES"
rather than the misleading no-eligible-candidate text. A new regression
test pins both directions: excluded classes skip their preconditions,
and a REQUESTED window class still enforces its clean-window
requirement (the filter selects classes; it never softens a requested
class's rules).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQY9wfrfRggqSpMLH8Xj3Y

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/ourios-bench/tests/rfc0031_comparative/harness.rs`:
- Around line 289-311: Update the class parsing logic in the relevant parser
constructor and its artifact_value path to canonicalize duplicate class names or
reject repeated tokens before full-set detection; ensure repeated selections
cannot be treated as PairClass::ALL. Add parser unit coverage for repeated input
such as L1,L1,L1,L1,L1,L1, preserving existing validation for unknown and empty
selections.
- Around line 51-76: Update the L4 grid and decoding flow around start, end, and
parse_loki_matrix to handle timestamps exactly equal to a bucket boundary. Add a
boundary-timestamp fixture covering a row at start, then align the evaluation
grid and decoder so count_over_time’s first window maps to Ourios’s [start,
start + width) bucket; alternatively reject such timestamps explicitly. Ensure
the existing non-boundary bucket mapping remains unchanged.

In `@crates/ourios-bench/tests/rfc0031_comparative/loki.rs`:
- Around line 260-286: Update loki_query_with_stats to return
Result<(Vec<LineKey>, u64, LokiFetchedBytes), String> instead of panicking on
transport, HTTP status, body, or parsing failures. Replace the expect/assert
paths with descriptive String errors, then update its callers in
loki_measure_pair to propagate errors into the existing deadline retry loop,
matching loki_query_matrix while preserving previously collected measurements.

In `@crates/ourios-bench/tests/rfc0031_comparative/main.rs`:
- Around line 553-565: Apply the requested class filter before invoking pickers
or constructing specs: conditionally skip excluded L1/L4 picker flows, including
template-map publication and related measurements, and make build_pair_specs
omit excluded classes before requiring their candidate windows rather than
retaining afterward. Add a unit test for a targeted run where an excluded window
has no valid candidate, verifying the run succeeds without selecting that class.

In `@crates/ourios-bench/tests/rfc0031_comparative/pickers.rs`:
- Around line 925-929: The latest-version wildcard mapping in the grouped
comparison must not be applied indiscriminately across template versions. Update
the logic around the `latest` map and its regex-derived candidate selection to
use only wildcard ordinals stable across every version, or validate each derived
group against `answer.groups` before comparison. Add a multi-version regression
unit test covering earlier rows where the latest `param(n)` is absent or maps to
a different position.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b20ee6e2-8e90-403e-b8c9-8b440349d42e

📥 Commits

Reviewing files that changed from the base of the PR and between f9b6afe and b9a00f3.

📒 Files selected for processing (9)
  • .github/workflows/ci.yml
  • .github/workflows/comparative-bench.yml
  • crates/ourios-bench/tests/rfc0031_comparative.rs
  • crates/ourios-bench/tests/rfc0031_comparative/harness.rs
  • crates/ourios-bench/tests/rfc0031_comparative/interop.rs
  • crates/ourios-bench/tests/rfc0031_comparative/loki.rs
  • crates/ourios-bench/tests/rfc0031_comparative/main.rs
  • crates/ourios-bench/tests/rfc0031_comparative/picker_tests.rs
  • crates/ourios-bench/tests/rfc0031_comparative/pickers.rs

Comment thread crates/ourios-bench/tests/rfc0031_comparative/harness.rs
Comment thread crates/ourios-bench/tests/rfc0031_comparative/harness.rs Outdated
Comment thread crates/ourios-bench/tests/rfc0031_comparative/loki.rs Outdated
Comment thread crates/ourios-bench/tests/rfc0031_comparative/main.rs
Comment thread crates/ourios-bench/tests/rfc0031_comparative/pickers.rs
CodeRabbit caught that loki_query_with_stats — the one remaining
Loki-query helper on a measurement poll path — still used expect/assert
for transport, HTTP, body, and parse errors, so a single transient blip
inside loki_measure_pair's poll would unwind the async block holding
every pair's already-collected measurements. Converted to
Result<_, String> with retry-until-deadline in the poll loop — the
identical salvage pattern loki_query_matrix and
loki_query_range_uncapped received in #536; this closes the set (every
Loki query helper on a measurement or diagnostic path is now
panic-free).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WQY9wfrfRggqSpMLH8Xj3Y

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.

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