Description
Surfaced by SKT-0010.16’s corpus refresh and explicitly deferred by it: “go_gc_duration_seconds is recorded as gauge on the synth side despite captured summary/quantile evidence, requiring a focused Kind-propagation investigation outside this task.”
It is the single instrument_mismatch contradiction in the report – a class that had zero entries before the refresh, so it is not noise from a widened corpus.
The capture is unambiguous. go_gc_duration_seconds is a Prometheus summary: it carries quantile series plus _sum and _count, and SKT-0013.06 deliberately kept those three separate rather than folding them, because folding a summary’s components and stamping it classic: true was exactly the defect that task fixed. The corpus records the summary evidence. The synth side records gauge.
So the question is where the Kind is lost between what synthkit emits and what the inventory reports. Establish that before changing anything: it is either the emitter genuinely emitting a gauge where a summary is correct, or the inventory projection flattening a summary to a gauge. Those have opposite fixes and the finding does not distinguish them.
Do not resolve this by widening the comparator to accept gauge-for-summary. A summary and a gauge are different instruments and a dashboard written against one does not work against the other.
Acceptance Criteria
- #1 Whether the Kind is lost in the emitter or in the inventory projection is established with evidence before any change
- #2 The synth side reports the instrument the emitter actually produces
- #3 The instrument_mismatch contradiction count returns to zero
- #4 The comparator is not widened to accept a gauge where reality observed a summary
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 Plan
- Preserve the investigation verdict before changing code: the Karpenter emitter builds the correct summary-shaped family, state.Set classifies its quantiles as gauges, the sink preserves that Kind, and inventory faithfully projects it. 2. Add failing focused tests for a first-class summary Kind through state collection, RW2 metadata, synth inventory, and the go_gc_duration_seconds emitter; keep _sum/_count on their existing counter path. 3. Implement the smallest explicit summary-quantile state seam and use it only for go_gc_duration_seconds; do not infer type from names and do not widen the comparator. 4. Measure the exact signal-fidelity finding delta, run focused tests and CodeRabbit, then the task gates and exact-SHA CI before finalization.
Implementation Notes
Read-only delegated investigation established the loss point before any change. Karpenter emits go_gc_duration_seconds quantiles plus _sum/_count, but quantiles call state.Set and state.Collect stamps KindGauge; promrw capture preserves that Kind and inventory maps it directly to gauge. A full-catalog one-shot inventory reported base=gauge and components=counter, while the captured corpus reports base=summary and components=unknown. The comparator therefore reports exactly one instrument_mismatch contradiction: synth=[gauge], reality=[summary]. The comparator is not the loss point and must remain unchanged. The delegated lane made no edits.
Implementation completed with focused TDD: the summary-kind tests failed before KindSummary and SetSummaryQuantile existed, then passed after the state, RW2 metadata, inventory and Karpenter seams were wired. Focused packages now pass: internal/state, internal/sink/promrw, internal/inventory, internal/construct/karpenter and internal/dashgen. The dashboard classifier explicitly maps summary quantiles to raw gauge-style queries.
Measured full-catalog comparator result after the implementation: go_gc_duration_seconds reports summary; _count and _sum remain counters; the Contradictions section has no instrument_mismatch subsection. The only remaining instrument_mismatch entries are coverage gaps for _count/_sum where reality is unknown, so they were not changed. The comparator implementation is untouched. DRY_RUN=true BLUEPRINT_NAMES=k8s-full-stack go run ./cmd/synthkit -once -dump completed and included the three expected families. make blueprint-schema is not applicable because no blueprint field or construct/workload config struct changed.
CodeRabbit review used the rknightion plan and raised two minor issues, with no Critical or Warning issues. The valid missing-series assertion in the Karpenter test was fixed. The Markdown-emphasis issue was dismissed because the cited tracker line contains no emphasis delimiters and tracker Markdown may only be changed through Backlog CLI.
Exact-SHA CI run 33214959014 for commit 35d11c4 passed docker, hygiene, secret-scan, UI, Go, Helm, signal-fidelity, e2e and ci-success.
Final Summary
Added first-class Prometheus summary Kind propagation from state through RW2 metadata and synth inventory, and used it for go_gc_duration_seconds quantiles while preserving _sum/_count counters and raw dashboard queries. Verified by focused tests, full-catalog inventory/comparator evidence with zero instrument_mismatch contradictions, the required dry-run dump, make gate, CodeRabbit review, and green exact-SHA CI run 33214959014 including e2e.