Roadmap¶
What's still open: planned features, known gaps, and operational follow-ups. What's already shipped lives in CHANGELOG.md and in each feature's own docs page, not repeated here.
Overview¶
This page tracks only what's not done yet: planned features, known robustness gaps, and operational follow-ups that aren't code changes. It is not a running history of delivered work — once an item here ships, it's removed from this page, not reworded as "done"; its details live in CHANGELOG.md (what shipped and when) and the relevant feature's own docs page (how it works today).
How to read this pageHide
This project does not commit features to specific version numbers — a version tag marks when something shipped, not a promise of what a future one will contain. What's below has no version committed yet:
See the Planned items below.
Quarters on each item are estimates of when we expect to pick it up, not commitments or release dates. Items marked Unscheduled have no target.
Open items from a code audit of internal/correlation, internal/collector, internal/planner, and internal/ingester — each is a gap in what the engine can currently claim, not a bug in what it already does. Ordered by how much they affect the trustworthiness of a reported regression, not by planned release.
Shipped operational work (publishing signed release artifacts, per-release docs versioning, per-PR release-notes fragments) is documented where it actually lives — CI/CD and Installation — and logged in CHANGELOG.md, rather than listed again here once it's done. What's below is genuinely still open:
See the Follow-up items below.
These are consciously not planned yet: without external users and an objective definition of "correct attribution" there is nothing to calibrate them against.
See the Deferred items below.
Security and robustness checklist¶
This repository's code/docs/workflow-addressable checklist has 6 of its 7 steps complete — security model and trust boundaries, secret-consent and policy controls, alert destination controls, Kubernetes hardening defaults, the tenant-safe remote cluster model, and supply-chain controls, in that order. Each is documented in full on its own page, not restated here: Security Model, Multi-Cluster (Fleet) Mode, Deployment Security, and Supply Chain cover how; CHANGELOG.md covers when.
Step 7 remains intentionally operational, and genuinely open:
See the External-user quickstart validation item below.
Key initiatives¶
Roadmap items¶
Stage 2 weighs a one-call interval like a ten-thousand-call one, while the reported window means are call-weighted.
Read moreShow less
The reported MeanLatencyBefore/MeanLatencyAfter are total time over total calls, but the t-test compares unweighted per-interval means. A ratio-estimator test (mean = total time / total calls, with a cluster-robust variance that treats each scrape interval as a cluster) is consistent with the reported numbers and, in simulation with bursty traffic and log-normal latency, kept the 5% size while raising power for a +30% regression from 41% to 73% at 3 calls per interval. It would also make --min-executions act directly on the precision of the test. Per-call variance from stddev_exec_time is a further input that is not used yet.
Both kind-based workflows were validated locally but have never run on a real GitHub Actions runner.
Read moreShow less
.github/workflows/e2e-kind.yml and .github/workflows/e2e-kind-multicluster.yml were both authored, actionlint/YAML-checked, and validated against real clusters in a local sandbox that lacks GitHub Actions' kernel support for kind/Docker-in-Docker (see Multi-Cluster: Operational considerations for the networking workaround that local validation needed) — but neither has actually executed as a real workflow_dispatch/labeled-PR run on an actual GitHub Actions runner. Treat each workflow's first real run as part of reviewing the change that introduces it, not as an already-passing check.
Required checks only have effect once main's ruleset requires each one by name.
Read moreShow less
See Branch Protection — the CI checks in CI/CD only have real effect once main's ruleset actually requires each one by name.
The issue template links to Discussions; whether it is enabled on the repo hasn't been confirmed.
Read moreShow less
.github/ISSUE_TEMPLATE/config.yml links to the repo's Discussions tab; whether Discussions is actually enabled on the repo hasn't been confirmed.
The significance test runs on a split the same data picked, so its p-value is optimistic. Calibrate it before reading it as a 5% rate.
Read moreShow less
Stage 1 searches every candidate split for the best E-divisive change point and stage 2 then tests that split as if it had been chosen independently, which makes the p-value optimistic (post-selection inference). The stage 0 pre-filter and the LatencyChangeThreshold mask most of the effect on typical series, but the p-value should not be read as a calibrated 5% false-positive rate: measured with the project's own E-divisive and Welch code on no-change series, 35-39% had p < 0.05 with independent noise and 60-99% with autocorrelated noise, and through the full engine up to 8% of no-change analyses were reported Detected with autocorrelated, heavy-tailed noise. Options, roughly in order of cost: a minimum effect-size floor alongside the p-value; empirical calibration against recorded no-regression series; a permutation test that repeats the full change-point search on each permuted series. Series with autocorrelated noise are the case most worth measuring first.
A shift before the deploy can still be blamed on it. Make the window asymmetric, depending on how the event was timestamped.
Read moreShow less
evaluateQuery rejects a change point only when its absolute distance from the deploy exceeds ChangePointTolerance, so a shift that happened before the event can still be attributed to it. That is sometimes right — the ArgoCD and Argo Rollouts parsers stamp DeployEvent.Timestamp with time.Now() when the webhook arrives (typically at sync completion), while the real effect can start when the first replicas roll — and sometimes wrong. Detection Algorithm currently justifies the tolerance only by effects lagging a deploy, which is the opposite case. Planned direction: an asymmetric window whose lead and lag depend on how the event's timestamp was obtained. The OTLP source already lets an operator choose the span's start or end; the webhook sources have no equivalent, so a lightweight first step is to record a timestamp-quality indicator (source-provided vs. receipt time) on the event rather than adding separate started/completed fields to the public DeployEvent type.
When several deploys could explain a change, say so with an Ambiguous result instead of presenting one as the cause.
Read moreShow less
Engine.Analyse evaluates one event at a time and every tracked query is a candidate for every event on the same watch — nothing links a queryid to an application, and pg_stat_statements does not record one. Two deploys inside one tolerance window therefore each produce their own regression for the same change point. A first step that needs no new data: when more than one event falls inside the window, mark the result Ambiguous and list the candidate events instead of presenting one as the cause. Further outcomes (Unattributed when no event is close enough, InsufficientEvidence) and candidate ranking by cluster, namespace, and workload can follow once that vocabulary exists.
Report how many other queries shifted at the same moment, to tell a deploy-local change from a saturated database.
Read moreShow less
Whether a regression is local to one query or shared by most tracked queries at the same moment is already computable from data the collector holds, and separates "this deploy changed this query" from "the database is saturated". Reporting the fraction of other tracked queries that shifted at the same change point is a cheap first control signal; richer workload context (CPU, connections, lock waits, I/O) is deliberately not planned until there is evidence the cheaper signal is not enough, since requiring it would raise the barrier to adoption.
pg_store_plans in the kind + CloudNativePG e2eThe CloudNativePG e2e posts a generic webhook instead of a real ArgoCD one, and runs without pg_store_plans.
Read moreShow less
The kind + CloudNativePG e2e workflow (.github/workflows/e2e-kind.yml) posts a sourceType: generic webhook directly to the DeploySource route rather than standing up ArgoCD's Application controller and Notifications engine (the part that actually emits a real on-sync-succeeded webhook — see Deploy Sources & Webhooks); that's a second, mostly-orthogonal integration surface, a natural follow-up once someone needs to validate ArgoCD's own webhook delivery specifically. Separately, it doesn't run with pg_store_plans on the CloudNativePG instance: that C extension isn't compiled into CloudNativePG's default operand images, and building/maintaining a custom operand image just for this smoke test hasn't been judged worth it yet (narrower than "is pg_store_plans validated against a real server at all" — see Testing for that validation, which runs outside of CloudNativePG specifically).
GitHub/GitLab PR comment on detected regression; Grafana annotation.
Step 7 of the checklist needs a real operator run in an external environment, which code alone can't prove.
Read moreShow less
The execution checklist exists in Quickstart Validation, but completion still depends on a real human/operator run in an external environment.
Up to 500 queries are tested per pass with no correction. Options: false-discovery-rate control, or ranking by impact.
Read moreShow less
One Analyse or AnalysePeriodic pass can evaluate up to the top 500 queries, each against PValueThreshold, and periodic analysis repeats that on every tick. A false-discovery-rate correction (Benjamini-Hochberg is the obvious first candidate) is one option; ranking and surfacing regressions by their share of total execution time is another that also helps operators triage. Whichever is chosen, the more conservative behaviour should be a separate mode, not a silent change to what PValueThreshold means.
planner.Diff compares only the root node type, total estimated cost, and snapshot sourceThe diff only compares the root node, total cost and source. Walking the whole plan tree would explain the “why”.
Read moreShow less
A root that stays an Index Scan while its row estimate moves by four orders of magnitude, or a join order change below an unchanged root, is invisible to it. Walking the whole plan tree — scan types, index names, join methods and order, estimated rows, and sorts — would make the hint far more useful for the "why". Actual rows and buffer counts are only worth adding for sources that record them; EXPLAIN (GENERIC_PLAN) never does.
SampleSource abstracts where samples come from, not what a sample meansMake explicit what each observation means, so new sources can't be mixed into the same statistical test by accident.
Read moreShow less
internal/telemetry/promsource already requires a per-interval mean, but nothing in the interface enforces it, and a future histogram- or percentile-based source would be indistinguishable from a mean-based one to the engine. Making the meaning of each observation explicit (interval mean, cumulative mean, histogram-derived, gauge) in the sample type — with a single normalisation step in front of the engine rather than per-source conventions — would keep the engine independent of the ingestion protocol. Percentile (p95/p99) detection needs its own statistical path and calibration; feeding percentiles through the mean-based Welch test is not an option.
An OLM bundle for OperatorHub.io.
auto_explain log ingestion is not yet builtA log-shipping pipeline for clusters that have neither pg_store_plans nor PostgreSQL 16.
Read moreShow less
internal/planner captures a query's execution plan from either pg_store_plans (the real, previously-executed plan — see Testing for how it's validated against a real install) or EXPLAIN (FORMAT JSON, GENERIC_PLAN) (an estimate, PostgreSQL 16+ only) and diffs two captures — see Detection Algorithm. A full auto_explain log-shipping pipeline remains a heavier, not-yet-started alternative for clusters that have neither pg_store_plans nor PostgreSQL 16 available — see the "Honest limitations" note on Detection Algorithm.
Better significance for autocorrelated series, and baselines that adapt over time.
Read moreShow less
Block-permutation or block-bootstrap significance for autocorrelated series, and adaptive baseline models.
Detect regressions in the tail of the distribution, not only in the mean.
Read moreShow less
Histogram and tail-latency change detection.
Traces add context and execution paths to an attribution; they don't prove one.
Read moreShow less
Using OpenTelemetry traces as extra attribution evidence (which service, endpoint, and application version was affected). Traces give context and execution paths, not a counterfactual, so they should inform an attribution result rather than prove one.
Compare against control queries and history to estimate calibrated attribution probabilities.
Read moreShow less
Control-group methods (difference-in-differences against comparable queries), counterfactual baselines from history, and empirically calibrated attribution probabilities.
See also¶
- CHANGELOG.md — what's already shipped, release by release; this page only tracks what's still open.
- CI/CD — the workflows referenced by the operational follow-ups above.
- Persistence and Collector Internals — the two pages with the most detail on the robustness gaps above.
- Support Matrix — officially supported PostgreSQL versions and distributions, including real
kind+ CloudNativePG validation coverage (single- and two-cluster) and the remainingpg_store_plans-on-CloudNativePG-operand-image follow-up referenced above.
Have an idea? Open a feature request: dates are not promised, but this page is where accepted ideas land.