docs(rfc): draft RFC 0041 — dashboard datasource plugins (Grafana / Perses) - #640
Conversation
…erses) Ourios's query API is stable (RFC 0002 + 0016 green) and nothing consumes it but curl, MCP and the bench harness. The DSL was explicitly shaped for dashboard authors -- RFC 0002 §3.6 names Perses as the primary audience and RFC0002.10 property-tests YAML-embeddability -- but no dashboard tool can issue a query without a plugin. Drafted, not specified: §§1-4 and §§7-8 per the lifecycle, with §5/§6 left empty on purpose. The open question is whether this is worth doing and where, not how. §7 puts "is this worth doing now?" first and names the competing calls (RFC 0036 implementation, the D1/D2 soak cadence, agent-observability). Both hosts were spiked to a rendered dashboard against the live querier before drafting, so §3.1's numbers are measured: 1-2 days for Grafana, 3-5 for Perses. The Ourios-side mapping is identical across them and ported in ~20 minutes; effectively all cost is each host's plugin system. One finding is Ourios-side and wants deciding either way (§3.4): a natural `severity >= trace` query returns zero rows against real agent telemetry, because GenAI events carry severity_number 0 and every row group prunes. Faithful storage, but a dashboard makes it look like a broken datasource. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
|
Warning Review limit reached
Next review available in: 34 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)
📝 WalkthroughWalkthroughThis change adds RFC 0041 on Ourios datasource plugins for Grafana and Perses, covering spike findings, response mappings, time-range handling, repository placement, alternatives, and open questions. The RFC is also linked from the documentation summary. ChangesDashboard datasource plugins RFC
Estimated code review effort: 1 (Trivial) | ~5 minutes 🚥 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 |
Consulted the OTel spec on SeverityNumber=0 rather than leaving §3.4 as "this wants a decision". The spec addresses it directly and turns an open worry into three options with upstream precedent: - Logs Data Model, Comparing Severity: "Special handling MAY be given to SeverityNumber=0 when it is used to represent an unspecified severity" -- the spec anticipates exactly this case in >= comparisons. - Logs SDK LoggerConfig: records with unspecified severity "bypass minimum severity filtering". OTel's own filter INCLUDES them; ours excludes them, so today's behaviour is the inverse of the SDK's. - Logs Data Model, Severity Fields: a backend "may interpret" missing severity as INFO(9) -- explicitly permitted, but invents a value the source did not send, so it is defensible at query time and not at storage time. - The Collector's attributesprocessor exposes match_undefined, precedent for making the choice explicit rather than implicit. Also records that this is a pruning-correctness question, not only UX: whichever semantics win, row-group pruning must agree or a filter will skip files containing matching rows. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
§3.4 opened as "needs a decision either way" and presented three options. It has since been decided and merged on its own (#641): floors admit unspecified severity, ceilings exclude it, the rule is compiled into the predicate so pruning agrees, and an explicit 0 threshold keeps ordinary semantics. Rewritten as a record of what shipped rather than an open question, with the §7 checklist item closed and the status banner noting that one finding landed independently. The rest of the RFC -- whether to build a plugin at all, and for which host -- is unchanged and still open. Keeping the section rather than deleting it: the spike is what surfaced the defect, and it is the clearest example of a class of bug only a dashboard client exposes, which is itself an argument the RFC makes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@docs/rfcs/0041-dashboard-datasource-plugins.md`:
- Around line 90-93: Update the range-format documentation in the dashboard
datasource plugins RFC to explicitly define the injected dashboard range as the
half-open interval [from, to), consistent with RFC 0010. Document how plugins
preserve an existing handwritten range unchanged so Grafana/Perses boundary
semantics do not drift.
🪄 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: f0117bfb-4bd0-4606-9061-78337cd4013c
📒 Files selected for processing (2)
docs/SUMMARY.mddocs/rfcs/0041-dashboard-datasource-plugins.md
There was a problem hiding this comment.
Pull request overview
Drafts a new RFC (0041) discussing whether to build dashboard datasource plugins (Grafana / Perses) for Ourios’s existing query API, and wires the RFC into the mdBook navigation.
Changes:
- Add RFC 0041 (“Dashboard datasource plugins”) as a
draftedRFC describing measured spike findings, alternatives, and open questions. - Link RFC 0041 from
docs/SUMMARY.mdso it appears in the rendered documentation.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| docs/SUMMARY.md | Adds RFC 0041 to the RFC index for mdBook navigation. |
| docs/rfcs/0041-dashboard-datasource-plugins.md | Introduces the drafted RFC capturing motivation, measured spike results, and decision framing. |
Comments suppressed due to low confidence (1)
docs/rfcs/0041-dashboard-datasource-plugins.md:91
- The inline
range(...)example contains an ellipsis placeholder inside the code span and splits across lines, which makes it look like valid DSL syntax. Using a fully-formed example keeps the spec copy/pasteable and unambiguous.
- **Grafana's ISO range format parses as-is.** `range(2026-07-25T08:00:00.000Z,
…)` — milliseconds included — is accepted by the DSL. No translation layer.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
CodeRabbit asked for the `range(...)` boundary contract to be documented, on the premise that RFC 0002 leaves it unspecified. It does not -- §6.2 already fixes `range(from, to)` as `from <= effective < to`, matching RFC 0010's [from, to). But the useful half of the point stands: RFC 0041 never cited it, and both pickers hand over an inclusive-looking `to`, so a plugin author would otherwise have to infer that a row exactly on the upper bound is excluded. Now stated in §3.2 alongside the existing-range-wins rule, so the two plugins cannot drift apart on it. Copilot: the document spelled the schema language both "Cue" and "Cuelang". Normalised to CUE throughout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
Copilot on PR #640: the §3.1 table said Perses time series "needs a third plugin" one row above "Plugins to write: 2", which is internally inconsistent as written. Both figures were true at different scopes, which is exactly the confusion. Split the row: logs parity is 1 plugin on Grafana and 2 on Perses; logs AND time series is still 1 on Grafana and 3 on Perses. Added the underlying asymmetry in prose, since it is the sharpest structural difference between the hosts -- a Grafana datasource picks its frame from the response shape, while Perses splits LogQuery from TimeSeriesQuery. Also scoped the effort figures (§1 and the table row) to log parity, so 1-2 vs 3-5 days is not read as covering equal capability: Grafana's number already includes time series, Perses's does not. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qtny6z6cA74xPZa4qRhk4F Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
…0041 §3.4 cited a private note slug that exists nowhere in the repo, so the fidelity rationale was unresolvable for any reader; point at RFC 0018's faithful-witness wording instead. §7 listed RFC 0036's implementation as a competing call on time. RFC 0036 is accepted with its §5 criteria green — the claim was inherited from a stale roadmap entry (docs/roadmap.md, tracked separately). Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
* docs(roadmap): refresh §3 through RFC 0041 (closes #642) The RFC 0036 bullet under "What's actually open" described it as `specified` with design review gating `red`, months after #593 flipped it to `accepted` and #592/#594/#595 landed the implementation. The roadmap is what a contributor reads to pick up work, so the entry actively misdirected — it already did, on #640. Checking the neighbours for the same drift found the file had gone stale wholesale against its own §6 cadence rule (refresh whenever a merged PR materially changes §3): - ladder stopped at RFC 0036; adds 0037 (`green`), 0038/0039/0040 (`green`, the self-observability arc) and 0041 (`drafted`) - "all ten product crates" predates `-config`, `-df-otel` and `-testgen`; now twelve product crates plus one dev-only - the `-telemetry` bullet described a metrics-only export surface, which stopped being true at RFC 0038/0039 - §5's Perses row still read "prerequisite is clear, left for after RFC 0031" with no pointer to RFC 0041, which now works that question up for both hosts Also records the unreleased breaking change (#641) sitting on `main` behind v0.5.0, so whoever cuts the next tag doesn't call it a patch. Prior banner entries are left as written — they are point-in-time records; the 2026-07-21 entry gains a one-line note that its arc closed. Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org> * docs(roadmap): reconcile §5's telemetry row with the §3 refresh Review caught the exact failure this PR exists to fix: §3 now records RFC 0038/0039/0040 as green while §5's telemetry row still read "Traces deliberately deferred", leaving two contradictory statuses in one file. Also tightens the ourios-df-otel dependency claim — datafusion + opentelemetry are its *runtime* deps; it does carry dev-dependencies (opentelemetry_sdk, chrono, criterion). The load-bearing property is that no ourios-* crate is among them, so say that instead. Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org> --------- Signed-off-by: Jens Holdgaard Pedersen <Jens@holdgaard.org>
Summary
Drafts RFC 0041 and wires it into
SUMMARY.md. No implementation — the RFC exists to make a decision possible, not to pre-commit to one.§7's first open question is "Is this worth doing now?", and it names the competing calls explicitly (RFC 0036 implementation, the RFC 0009 D1/D2 soak cadence, agent-observability/FinOps). "Do nothing" is written up as a live option in §4, not a strawman — the MCP surface already gives an agent the same access a dashboard gives a human.
Status is
drafted: §§1–4 and §§7–8 filled per the lifecycle indocs/rfcs/README.md; §5 acceptance criteria and §6 testing strategy deliberately empty, since the open question is whether and where, not how.Why the numbers are trustworthy
Both hosts were spiked to a rendered dashboard against the live querier before this was written, so §3.1 is measured, not estimated:
count by bucket(w)Datasource+LogQuery)Neither host needs a Go backend — both proxy server-side and inject
x-ourios-tenantfrom datasource config. The Ourios-side mapping is identical across them and ported in ~20 minutes, so effectively all the cost is each host's plugin system, not Ourios.One finding already shipped
§3.4 began as "needs a decision either way" and has since been decided and merged independently as RFC0002.21 (#641): Ourios's
severity >= Xwas the inverse of the OTel Logs SDK, soseverity >= tracereturned zero rows against real agent telemetry. Floors now admit unspecified severity, ceilings exclude it, and the rule is compiled into the predicate so row-group pruning agrees.That section is kept as a record rather than deleted, because the spike is what surfaced it — and it's the clearest example of a defect class only a dashboard client exposes, which is itself one of the RFC's arguments.
Notes
scratch/and are not part of this PR.CLAUDE.md§7 layout change needing ameta:RFC.Checklist
mdbook buildclean; RFC linked fromSUMMARY.mddrafted(§§1–4, §§7–8 filled; §5/§6 intentionally empty)CHANGELOG.md— N/A, no user-facing changeSummary by CodeRabbit