github robintra/perf-sentinel v0.6.0

latest releases: chart-v0.2.63, v0.8.14, chart-v0.2.62...
one month ago

What's new in v0.6.0

v0.6.0 is the first SemVer-incompatible release of the 0.x line. Three things break together. The public Config API splits into sectioned sub-structs (thresholds, detection, green, daemon), the eight legacy top-level keys deprecated since 0.5.26 are removed so a 0.5.x .perf-sentinel.toml that still uses any of them now fails at load with an explicit migration error, and the OTLP ingest path no longer reaches into report::metrics::MetricsState directly. A new MetricsSink trait owned by ingest closes a long-standing layering leak. The audit pass also lands its first wave of user-facing alignments: the CLI says "Found N finding(s)" instead of "issue(s)", fan-out becomes fanout to match the ExcessiveFanout enum and the excessive_fanout label, eight tautological template_carries_* HTML drift guards are dropped in favor of a typed API_KEY_HEADER lockstep check, and a Grafana Pyroscope row joins the README comparison table to position the two tools as complementary.

Breaking: Config sectioned API

Config splits into four sub-structs reachable as config.thresholds, config.detection, config.green, config.daemon. Library consumers that read config.green_default_region, config.tls_cert_path, config.n_plus_one_threshold etc. need to migrate to the nested form. The RawConfig to Config adapter still accepts the section + flat-keys mix on disk for keys that have a section equivalent, the eight legacy top-level keys listed below are the only ones that now hard-fail.

Breaking: 8 legacy top-level config keys removed

The keys deprecated with a WARN since 0.5.26 are gone. Loading a .perf-sentinel.toml that still uses any of them returns a ConfigError::Validation whose message names both the removed key and its replacement, so the error stream tells you exactly what to edit.

Removed (top-level) Use instead Section
n_plus_one_threshold n_plus_one_min_occurrences [detection]
window_duration_ms window_duration_ms [detection]
n_plus_one_sql_critical_max n_plus_one_sql_critical_max [thresholds]
n_plus_one_http_warning_max n_plus_one_http_warning_max [thresholds]
io_waste_ratio_max io_waste_ratio_max [thresholds]
listen_port listen_port_http [daemon]
max_events_per_trace max_events_per_trace [daemon]
max_payload_size max_payload_size [daemon]

Breaking: MetricsSink trait closes the ingest -> report leak

Before 0.6.0 the OTLP ingest path imported report::metrics::MetricsState directly to record per-protocol rejection counters. That meant ingest could only be enabled when report::metrics was compiled in, and MetricsState was part of every public OTLP handler signature. v0.6.0 introduces pub trait MetricsSink: Send + Sync in crates/sentinel-core/src/ingest/otlp.rs, with one method record_otlp_reject(&self, reason: OtlpRejectReason). MetricsState implements the trait in crates/sentinel-core/src/report/metrics.rs. The OTLP HTTP and gRPC handlers and the daemon listener layer now accept Option<Arc<dyn MetricsSink>> instead of Option<Arc<MetricsState>>. The dependency direction is inverted: ingest no longer depends on report, report provides an implementation of the trait ingest defines. CLI consumers see no behavior change, the /metrics exemplars are byte-identical for already-clean inputs.

Lexicon alignment from the audit

The user-facing vocabulary was drifting across CLI output, docs, the data model, and the SARIF / JSON / API surfaces. v0.6.0 lands the first wave of alignments.

  • CLI: Found N finding(s) instead of Found N issue(s). The CLI integration test asserts the new wording.
  • Spelling: a single Acknowledgement (UK) drift in docs/SUPPLY-CHAIN.md was aligned to the 386 Acknowledgment (US) occurrences elsewhere.
  • Detector naming: fan-out becomes fanout across docs (EN + FR mirrors), aligning prose with the ExcessiveFanout enum and the snake_case excessive_fanout finding label.
  • Glossary: docs/ARCHITECTURE.md and the FR mirror gain a Glossary section that pins down event vs finding vs pattern vs detection, plus the four operating modes (batch, CI, daemon, watch) and the Confidence axis.
  • Edge cases: docs/ACK-WORKFLOW.md adds a "Service renames invalidate acks" section covering signature breakage on service.name change, http.route refactors, and SQL/HTTP template changes. docs/LIMITATIONS.md adds a "Long-running traces and TTL eviction" section explaining why sparse-burst traces undercount in streaming mode and how to mitigate.
  • Comparison table: README.md and README-FR.md add a Grafana Pyroscope column to the capability table and a "Not a continuous profiler" entry. The framing is complementary, not competitive: Pyroscope tells you where compute time goes, perf-sentinel tells you which I/O patterns drive that time.

Tests: drop 8 tautological template_carries_*

Eight template_carries_* HTML drift guards in crates/sentinel-core/src/report/html.rs were tautologies, each asserting that a literal HTML id, class, or function name appeared in the static template with no semantic check (template_carries_daemon_status_badge_id, template_carries_refresh_button_id, template_carries_acknowledgments_panel_id, template_carries_include_acked_toggle_id, template_carries_auth_modal, template_carries_ack_modal, template_carries_session_api_key_storage_constant, template_carries_boot_live_mode_function). v0.6.0 removes them and consolidates the X-API-Key header value into a single source of truth, pub const API_KEY_HEADER: &str = "X-API-Key"; in crates/sentinel-core/src/http_client.rs. The new template_propagates_api_key_header_constant test asserts the live-mode JS propagates the same constant, replacing eight literal-string drift guards with one typed lockstep check. fetch_with_body and the daemon check_ack_auth both consume the constant through crate::http_client::API_KEY_HEADER. Net: -8 tests, +1 test, behavior unchanged.

Kept as-is for real semantic value:

  • template_carries_scoring_config_bandeau_and_helpers (drift guard for the 0.5.12 scoring bandeau JS)
  • template_carries_estimated_column_and_helper (drift guard for the 0.5.10 estimated-energy JS)
  • template_carries_csp_placeholder (CSP placeholder ordering invariant required by the replacen substitution)
  • live_mode_acks_cap_matches_daemon_constant now parses DAEMON_ACKS_CAP out of the template and asserts equality against daemon::query_api::MAX_ACKS_RESPONSE. The 0.5.x version asserted a literal 1000 on one side only.

Added

  • MetricsSink trait in crates/sentinel-core/src/ingest/otlp.rs, decoupling the OTLP ingest from MetricsState. MetricsState is the only built-in implementation today, the OTLP handlers now accept any Arc<dyn MetricsSink>.
  • pub const API_KEY_HEADER: &str = "X-API-Key"; in crates/sentinel-core/src/http_client.rs. The daemon check_ack_auth and the outbound fetch_with_body both consume it through this single constant.
  • Glossary section in docs/ARCHITECTURE.md (and FR mirror) covering event / finding / pattern / detection plus the four operating modes (batch, CI, daemon, watch) and the Confidence axis.
  • docs/ACK-WORKFLOW.md "Service renames invalidate acks" section (and FR mirror), documenting how service.name renames, http.route refactors, and SQL/HTTP template churn invalidate existing acknowledgments.
  • docs/LIMITATIONS.md "Long-running traces and TTL eviction" section (and FR mirror), explaining sparse-burst undercounting in streaming mode and the mitigation knobs.
  • Grafana Pyroscope column in the README comparison table and a "Not a continuous profiler" entry positioning the two tools as complementary.

Changed

  • CLI: Found N issue(s) becomes Found N finding(s). The CLI integration test asserts the new wording so it stays in lockstep with the data model and the JSON / SARIF / API surfaces.
  • fan-out becomes fanout across EN and FR docs, aligning prose with the ExcessiveFanout enum and the excessive_fanout label.
  • docs/SUPPLY-CHAIN.md Acknowledgement aligned to Acknowledgment to match the 386 US-spelling occurrences elsewhere.
  • live_mode_acks_cap_matches_daemon_constant parses DAEMON_ACKS_CAP from the template and asserts equality against daemon::query_api::MAX_ACKS_RESPONSE instead of a one-sided literal 1000.
  • OTLP HTTP and gRPC handlers and the daemon listener layer accept Option<Arc<dyn MetricsSink>> instead of Option<Arc<MetricsState>>.

Removed

  • 8 legacy top-level config keys (n_plus_one_threshold, window_duration_ms, n_plus_one_sql_critical_max, n_plus_one_http_warning_max, io_waste_ratio_max, listen_port, max_events_per_trace, max_payload_size). Loading hard-fails with ConfigError::Validation instead of falling back to the section default with a WARN.
  • 8 tautological template_carries_* tests in crates/sentinel-core/src/report/html.rs.
  • tracing-test = "0.2.6" dev-dependency on perf-sentinel-core. It was only used by the legacy-flat deprecation tests, which the legacy keys removal made redundant.

Internal

  • Config is four sub-structs (thresholds, detection, green, daemon). The RawConfig to Config adapter still accepts the section + remaining flat-keys mix on disk. Per-section validate_* functions centralize range and consistency checks.
  • CI fix: live_mode_acks_cap_matches_daemon_constant, the fresh_metrics_sink test helper, and the MetricsState test import in ingest/otlp.rs are now gated by #[cfg(feature = "daemon")]. cargo check -p perf-sentinel-core --no-default-features --all-targets is warning-clean.

Notes

  • Migration steps: edit .perf-sentinel.toml to move the eight removed keys into their respective sections before upgrading. The error message names the replacement, so a single pass on the load error tells you exactly what to edit. Library consumers also need to swap config.green_*, config.tls_*, config.n_plus_one_* for the config.<section>.* form.
  • Wire format unchanged: JSON, SARIF, HTML, TOML ack store, and Prometheus /metrics outputs are byte-identical to v0.5.28 for already-clean inputs. No data on disk needs migration, only the configuration file and library imports.
  • Helm chart: charts/perf-sentinel/Chart.yaml is still pinned at version: 0.2.31 / appVersion: 0.5.28. A chart bump pinning 0.6.0 will follow.

Install

Pre-built static binaries are attached to this release for linux-amd64, linux-arm64, macos-arm64, and windows-amd64. Verify the SHA256 from SHA256SUMS.txt before extracting. Crate consumers can cargo install perf-sentinel --version 0.6.0 once the workflow finishes propagating to crates.io.

Full Changelog: v0.5.28...v0.6.0

Don't miss a new perf-sentinel release

NewReleases is sending notifications on new releases.