# v0.90.0 — Freshness Controller & Self-Tuning > **Status:** Planned > **Scope:** Large > **User promise:** *"Tell me whether my freshness target is feasible and how pg_trickle would meet it."* > **Blocked by:** [v0.89.0](v0.89.0.md) > **Renumbered:** previously v0.85.0. The user-facing `target_freshness` > control moved forward to [v0.86.0](v0.86.0.md). This release makes the > measurement authoritative and introduces the controller in advisory mode. ## Theme Keep `target_freshness` as the primary product control, but make automation earn authority with benchmark and soak evidence. The first controller reports what it would do and why. It does not need to own every scheduling and execution choice before v1.0. The operating objective is explicit: > Meet feasible p95 freshness targets while minimizing pg_trickle resource use > and preserving configured OLTP headroom. When all targets cannot be met, > minimize weighted SLA breach instead of increasing resource use without a > bound. ## Items ### SLA-1: Authoritative freshness measurement `target_freshness` keeps the interval, `on_commit`, and `manual` forms accepted in v0.86.0. For an interval target, pg_trickle reports the p95 age of visible data from source commit to refresh commit. Missing provenance is reported as missing evidence, not replaced with refresh duration. `pgtrickle.freshness()`, `pg_stat_pgtrickle`, `health_check()`, Prometheus, and OpenTelemetry expose the target, p50, p95, p99, breach duration, evidence age, and feasibility status. ### SLA-2: Reproducible advisory decisions For each stream table, the controller recommends: - refresh timing - DIFFERENTIAL or FULL - pipeline batch size - queue priority - worker demand - overload deferral `explain()` and internal telemetry show the recommendation, the input evidence, and the reason. The same input snapshot must produce the same recommendation. An advisory decision cannot mutate configuration or override an explicit user setting. ### SLA-3: Layered controller The design has three layers with separate responsibilities. | Layer | Responsibility | |-------|----------------| | Global resource controller | Determines the CPU, memory, worker, and connection capacity pg_trickle may use without violating the configured OLTP headroom. | | SLA scheduler | Allocates available capacity by target, current freshness, breach risk, priority, dependency order, and fairness. | | Per-stream execution controller | Recommends refresh mode, batch size, and other execution choices within the resource allocation. | One layer cannot compensate for another by exceeding its bound. Infeasible targets cannot monopolize workers or force the global controller into a resource race. ### SLA-4: Authority rollout Automation advances in this order: 1. advisory decisions 2. automatic refresh timing 3. automatic priority 4. automatic batch sizing 5. adaptive worker allocation 6. automatic FULL or DIFFERENTIAL selection Advisory mode is mandatory for v0.90.0. A later stage may become authoritative in the same release only when burst, steady-state, restart, and mixed-SLA tests show stable behavior with no unsafe regression. Each decision class has its own enablement gate. A failed gate leaves that class advisory and does not block the v1.0 lifecycle critical path. ### SLA-5: Feasibility, overload, and oscillation The controller reports an infeasible target when measured work cannot meet it within the configured resource policy. Under overload, foreground PostgreSQL work wins. pg_trickle defers lower-risk refreshes, reports the expected breach, and keeps fairness and durability constraints intact. Hysteresis or an equivalent bounded policy prevents repeated switching. Tests cover burst traffic, steady inflow, workload shifts, restart, and an infeasible mix of targets. ### SLA-6: Configuration audit Classify each scheduler and execution setting as a primary control, an advanced override, or internal state. Do not remove an override until the replacement decision class has earned authority. `explain()` reports both the recommendation and any override that prevents it. ## Exit criteria - [ ] Freshness measurement is authoritative and preserves exact source commit provenance through stream-table chains - [ ] Every controller recommendation is visible, reproducible, and backed by current evidence - [ ] The three controller layers have independent bounds and tests - [ ] Burst, steady-state, restart, and mixed-SLA tests show no oscillation or unbounded worker demand - [ ] OLTP headroom wins under overload. Infeasible targets are reported and do not monopolize refresh capacity - [ ] Any automated decision class has its own benchmark, soak, rollback, and inspection gate. Unvalidated classes remain advisory - [ ] `pgtrickle.freshness()` and `sla_status` are documented and exported to Prometheus and OpenTelemetry - [ ] Configuration is classified without removing a control whose automated replacement remains advisory