Description
Audit dimension 3 confirmed a preventive tracking-key collision at the v2.0.0 release tree. src/meraki_dashboard_exporter/core/metric_expiration.py:174-187 builds the tracking and gauge-removal key from _freeze_labels, while lines 216-230 serialize sorted labels as key=value pairs joined by a pipe. Distinct mappings whose label values contain those delimiters can serialize identically; a later update then overwrites timestamp and gauge metadata for the first series, leaving its Prometheus child untracked for TTL and cardinality handling. Current tests use ordinary values only, and no current producer was shown to supply a colliding pair, so this is preventive hardening rather than an observed live collision.
Acceptance Criteria
- #1 Distinct label mappings cannot collide because of label-value delimiters in the expiration manager internal key
- #2 Two deliberately colliding legacy encodings remain independently tracked, expired and removed
- #3 Existing TTL cleanup and cardinality-shedding behavior remains unchanged
Definition of Done
- #1 just check (ruff format –check, ruff check, mypy, generated-doc drift, offline API conformance, and the marker-filtered pytest run with the 80% coverage floor — this is exactly what the CI
testjob runs) - #2 just gen, when metrics, config, endpoints, collectors, the settings schema or the chart config changed —
just checkincludes the drift gate and CI fails the build on it - #3 Grafana queries in grafana/dashboards/*.json and grafana/alerts/ updated, if a metric or label name changed
Implementation Plan
Write a failing legacy-delimiter collision regression through tracking, expiry and Gauge removal; replace the serialized label key with a sorted immutable tuple while preserving TTL and shedding behavior.
Final Summary
Replaced delimiter-concatenated expiration keys with collision-free tuple keys. The failing collision regression was observed before the fix; just check and just ci passed at 5e8d9c23b76a2f2edd531c15c776cbfbcc9134fa; exact-head CI 33843833956 and publication 33843966820 succeeded.