Description
Found independently by SKT-0010.04 while triaging coverage gaps.
internal/inventory/synth.go:99 and e2e/inventory/inventory.go:88 both fold a classic histogram raw _bucket/_count/_sum series into its family base. internal/inventory/gcx_readback.go does not — it records the three components as three separate metric entries.
The immediate consequence: 15 false extra_metric coverage gaps, the entire k8s/eks extra_metric population, all five kubeproxy_*_duration_seconds families that synthkit does emit correctly as classic histograms. But the false gaps are the mild half. The producer asymmetry will also generate false instrument_mismatch and unexpected_label_key findings for every real histogram family the read-back covers, and those land in the Contradictions section — which SKT-0010.05 is about to make fail CI.
Fix in the producer so the two sides agree on what a family is, rather than teaching the comparator to tolerate two shapes.
Acceptance Criteria
- #1 The gcx read-back folds classic-histogram component suffixes the same way the synth and e2e inventories do
- #2 The fold is shared rather than reimplemented, so a future third producer cannot diverge again
- #3 The 15 false extra_metric findings for the kubeproxy families disappear
- #4 No real coverage gap is masked by the fold, proven by a test
Definition of Done
- #1 make gate (build vet test race rw-proto-check spdx-check forbidden-words)
- #2 make blueprint-schema (only if a blueprint field or construct/workload config struct changed)
- #3 DRY_RUN=true go run ./cmd/synthkit -once -dump — inventory diffed against signals/
Implementation Notes
2026-09-06 criterion reconciliation: AC3 remains unchecked. Current grouped report still contains all 15 raw kubeproxy duration histogram component findings from eks-live-readback.json. The original final summary deliberately deferred re-shaping the committed capture; this is case (b), recorded remaining work, so the task stays Done with AC3 open. No capture was rewritten in this wave.
Final Summary
The fold is now shared rather than reimplemented a third time, and it is gated on POSITIVE PROOF rather than on the name suffix — which is what makes it safe.
A family folds only when an actual <family>_bucket series carrying an le label was observed. Nothing else counts. That gate is not defensive coding: CloudWatch five-stat expansion emits a genuine _sum GAUGE and a _sample_count, so a blind suffix fold would hide real families nobody emits behind families that do not exist. Proven two ways — mutation tests that fail with aws_ec2_cpu_utilization_sum folded away when the gate is removed, and an end-to-end run leaving the entire CloudWatch corpus document BYTE-IDENTICAL.
Two non-obvious things were needed beyond the producer fix. The MERGE path had to fold the written document too, because CanonicalMerge never removes evidence — without it a refreshed read-back keeps the stale component entries forever and the producer fix can never take effect. And histogram.bucket_bounds had to be gated on both sides being non-empty, because a folded stored family proves the classic representation while the corpus elides its le values; ungated, that manufactured five FRESH bucket_bound_mismatch contradictions, precisely the class SKT-0010.05 is about to make fail CI.
AC #3 is unchecked and the reason is mechanical, not a shortfall: the 15 false findings live in the COMMITTED corpus document, which the lane does not own and which a producer fix cannot alter without being run. Measured against a re-shaped copy on the same tree: exactly 15 extra_metric gaps removed, replaced by 11 findings that are all pre-existing populations simply no longer hidden — 5 instrument_types coverage gaps of the unknown-sentinel class SKT-0010.02 owns, and 6 label findings matching what every already-paired kubeproxy family reports. Zero bucket_bound_mismatch and zero histogram.representations findings, so both gates hold.
FLAG FOR SKT-0010.05: re-shaping moves contradictions 68 to 73. The number goes UP because folded families stop hiding real contradictions. That is the report becoming more truthful, not a regression, and the gate should be flipped against the re-shaped document rather than the flattering one.