github robintra/perf-sentinel v0.8.3

latest release: chart-v0.2.48
5 hours ago

What's new in v0.8.3

v0.8.3 adds a temporal coverage continuity signal to the periodic public disclosure, so a reader can tell a continuously measured period from one where the daemon ran only a handful of days. It also adds an in-band provenance marker on the scope manifest and reserves a hook for a future inter-period transparency log. The disclosure report schema gains an additive v1.2 revision, so v1.1 and v1.0 readers and existing reports stay valid. There is no breaking change to the daemon wire protocol, the CLI surface, or the configuration format, and the minimum supported Rust version stays 1.96.0. The release-gate lab validation passed end to end.

Disclosure: temporal coverage continuity signal

The periodic disclosure now reports aggregate.temporal_coverage, how much of the declared period actually carried measurements. It carries the ratio observed_days / days_in_period, the count of distinct UTC days that held at least one archived window, the declared days_in_period, and largest_gap_days, the longest run of consecutive in-period days with no window. It closes a visibility gap that days_covered (pure calendar arithmetic) and period_coverage (calibration quality) left open. A daemon that ran only three days out of a declared ninety could previously publish a fully valid official report with no sign of the gap.

Daemon archiving is traffic-gated, a window with no traffic writes nothing, so this figure measures days with observed traffic. It is a lower bound on activity, not a daemon uptime guarantee, and legitimately quiet days lower it. For that reason it is never a hard official gate. The value is published for transparency, the disclose CLI prints a warning and appends an in-band disclaimer below an informational threshold, and the validator only range-checks the ratio. This is the in-binary signal closest to an operator who simply stops measuring for part of a period. Total non-participation and a dishonest portfolio denominator remain beyond any in-binary check, the reserved hook below is the future answer to the former.

Disclosure: scope provenance and a reserved cross-period hook

scope_manifest.coverage_basis records, in band, which scope fields rest on operator assertion (the unaudited denominators total_applications_declared and total_requests_in_period, plus the exclusion lists) versus which are machine-derived from the archives (applications_measured, requests_measured, coverage_percentage). A reader of coverage_percentage can now see that its denominator is operator-asserted without consulting the schema reference.

integrity.cross_period_log is reserved for a future external append-only or Rekor-style log that chains successive report hashes across periods, the mechanism that would let a third party detect an operator who stops publishing. It is always absent in v1.2 and will be populated only under a future audited intent, so it is excluded from the post-sign field set and current report hashes are unaffected.

Validator: consistency checks

For intent = official, the validator gains three forgery-detection rules that a disclose-produced report satisfies by construction. days_covered must equal (to_date - from_date) + 1. requests_measured must not exceed an operator-declared total_requests_in_period. A populated temporal_coverage block must be internally consistent, with observed_days within days_in_period and days_in_period equal to the period. Omitting total_requests_in_period for an official report now emits a warning rather than silently dropping coverage_percentage.

Hash stability

Every new field is additive and omitted from the wire when absent, temporal_coverage via a default-is-omitted rule, coverage_basis and cross_period_log via the optional-is-omitted rule. A pre-v1.2 report re-hashed on a v1.2 binary keeps the same content_hash. A regression test pins both directions, an absent block leaves the hash unchanged and a populated temporal_coverage changes it, so the figure is bound by the hash and cannot be swapped silently.

Documentation

The schema reference, the reporting guide, and the periodic-disclosure design notes document the temporal coverage signal, the traffic-gated caveat, the self-disclosure limit on the operator-declared denominators, and the reserved cross-period hook, in English and the French mirrors. The JSON Schema and the two example reports are updated to v1.2.

Tests

The temporal coverage computation ships with focused coverage. Aggregator tests drive distinct-day counting, same-day dedup, and sub-second bucketing at the UTC day boundary. Validator tests pin the no-gate rule for a low ratio, the rejection of an inconsistent block, and the acceptance of a default block. A hasher regression test proves the content_hash is unchanged for an absent block and changes for a populated one. A schema test locks the coverage_basis field lists against the actual scope manifest fields so a future rename cannot leave a stale provenance label.

Helm chart

charts/perf-sentinel 0.2.47 to 0.2.48, appVersion 0.8.2 to 0.8.3. Template surface unchanged, additive metadata only.

Operator-visible behavior change

Disclosure consumers see three new fields, aggregate.temporal_coverage, scope_manifest.coverage_basis, and the reserved integrity.cross_period_log (absent in v1.2). Operators running disclose see a new stderr warning and an in-band disclaimer when temporal coverage is low, or when an official report omits total_requests_in_period. No detection verdict, daemon route, OTLP wire shape, or Prometheus metric changes.

Why this is a patch and not a minor

The release is additive and backward compatible. The feature extends the existing disclose subcommand and the report JSON with the v1.2 fields. The new fields default and are omitted when absent, so v1.1 and v1.0 consumers ignore them and older reports stay valid. There is no new CLI flag, no configuration change, and no change to the daemon HTTP routes, the OTLP wire protocol, the co2 model enum, or the Prometheus metric names and label sets. Output outside the disclosure is unchanged. The minimum supported Rust version stays 1.96.0.

Verifying this release

# Binary integrity via SLSA Build L3 attestation
gh attestation verify perf-sentinel-linux-amd64 \
  --owner robintra --repo perf-sentinel

# A periodic disclosure produced by this binary
perf-sentinel verify-hash --report perf-sentinel-report.json \
  --expected-identity "https://github.com/robintra/perf-sentinel/.github/workflows/release.yml@refs/tags/v0.8.3" \
  --expected-issuer "https://token.actions.githubusercontent.com"

gh CLI 2.49 or newer required for gh attestation verify (unchanged from v0.7.2).

Full Changelog: v0.8.2...v0.8.3

Don't miss a new perf-sentinel release

NewReleases is sending notifications on new releases.