fix(bench): RFC 0031 — generalize the pair picker (v8 has no ERROR logs) - #475
Conversation
Run #1 of the indicative comparative (29160983634) failed fast (12 s, before any container) in exactly the designed way: the corpus scan found ZERO severity>=17 rows in the whole 4.9 M-record otel-demo v8 capture — the calibration manifest confirms the corpus's complete severity distribution is INFO x2.19M, "Information" x2.76M, WARN x4 (the demo's adFailure/paymentFailure flags surface in traces/metrics, not logs) — and the picker refused to fabricate a pair. pick_error_pair → pick_selective_pair: instead of a hardcoded ERROR band, scan per-service (severity_number, severity_text) row counts and pick any (service, threshold T, text t) where EVERY row with number>=T carries the single text t and the count is 1..=4000. The consistency requirement still makes DSL `severity >= T` and LogQL `severity_text="t"` the same question. On v8 this selects the WARN band (>=13, 4 rows — an extremely selective honest L2); on error-bearing corpora it selects ERROR exactly as before, which the fixture unit test now pins (threshold 17, text ERROR). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 52 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe RFC0031 comparative test now dynamically selects a consistent severity-text band, derives its severity threshold, and applies the selected values to both Ourios DSL and Loki LogQL comparisons. Picker tests cover ERROR and WARN bands. ChangesRFC0031 selective-pair calibration
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant RFC0031 comparative run
participant pick_selective_pair
participant Ourios DSL
participant Loki LogQL
RFC0031 comparative run->>pick_selective_pair: select service, threshold, and text
pick_selective_pair-->>RFC0031 comparative run: return rows and time window
RFC0031 comparative run->>Ourios DSL: query severity >= threshold
RFC0031 comparative run->>Loki LogQL: query severity_text = text
Ourios DSL-->>RFC0031 comparative run: return matching rows
Loki LogQL-->>RFC0031 comparative run: return matching rows
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates the RFC0031 comparative benchmark “pair picker” to handle real-world corpora that may have no ERROR logs (e.g., otel-demo v8), by dynamically selecting a highly selective (service, severity threshold, severity text) pair that should produce a small, exactly-equivalent result set across Ourios (DSL) and Loki (LogQL).
Changes:
- Replace
pick_error_pairwithpick_selective_pair, scanning per-service severity bands to choose the smallest consistent band under the 5000-line cap. - Update the indicative comparative run to parameterize both the DSL threshold and LogQL
severity_textbased on the picked pair. - Update/rename the unit test to assert the fixture still selects the ERROR band (
threshold == 17,text == "ERROR").
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Copilot review, all three: - REVERSE consistency (real equivalence hole): the check guaranteed all num>=T rows share text t, but not that no LOWER-severity rows carry t — LogQL's text filter would return those too and break equivalence at container time. A candidate now also requires the service's total count for text t to equal the selected rows. - Nested map (service -> number -> text -> count): thresholds are the deduped number keys (no recomputation per (num,text) pair). - Severity texts clone only on FIRST occurrence per (service, number) via get_mut-then-insert — not one clone per record across millions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pick_selective_pair hit 106/100 after the reverse-consistency addition; extract select_pair_candidates. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot review: - pair.service / pair.text are interpolated into quoted DSL and LogQL string literals; a `"` or `\` (legal in OTLP attributes) would break or change either query. Rather than implement escaping for two query languages, a candidate whose names fall outside a conservative charset is simply skipped. - Doc: candidate thresholds are the OBSERVED severity numbers, which is complete — a gap threshold selects exactly the same rows as the next observed number above it, adding no new candidates. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A v8-shaped miniature fixture (INFO-dominated + one WARN, zero ERROR) pins that the picker selects the WARN band — the exact path run #1 surfaced. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot review: a zero-ts record can't be returned by either side's time-windowed query, so counting it into a band would fail the pair's expected-count check at run time. Skip it for bands (still counted in the total-records report figure). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot review: the effective-timestamp fallback means BOTH systems can return a time=0/observed-set record (Ourios windows the RFC 0005 §3.2 effective column; Loki's OTLP ingest falls back to observed) — but with DIFFERENT answer timestamps (Ourios keeps time_unix_nano=0, Loki stamps observed), so their LineKeys can never match. Exclusion is required for key identity, not window reachability; the comment now says so. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What
Run #1 of the indicative comparative (29160983634) failed fast and honestly (12 s, before any container): the scan found zero ERROR-severity rows in the entire 4.9 M-record v8 capture. The calibration manifest confirms the corpus's complete severity distribution:
INFO ×2,192,261,"Information" ×2,756,331,WARN ×4— the demo'sadFailure/paymentFailureflags surface in traces/metrics, not logs. The picker refused to fabricate a pair rather than compare nonsense — exactly its job.Fix
pick_error_pair→pick_selective_pair: instead of a hardcoded ERROR band, scan per-service(severity_number, severity_text)row counts and pick any(service, threshold T, text t)where every row withnumber ≥ Tcarries the single textt, count1..=4000. The consistency requirement still makes DSLseverity >= T↔ LogQLseverity_text="t"the same question; fewest rows wins (ties → lowest threshold → smallest service).≥ 13, 4 rows) — an extremely selective, fully honest L2 pair.threshold 17,text "ERROR").After merge
Re-dispatch
comparative-bench.yml→ run #2 proceeds past the picker into the store build, the 4.9 M-record Loki replay, equivalence at scale, and the first number.🤖 Generated with Claude Code
Summary by CodeRabbit