Description
The first implementation wave and the one SKT-0007 AC#3 turns on: until this exists, no base blueprint can be emitted OTel-native end to end.
SKT-0007.01 verdicted k8s_cluster OTEL-NATIVE on evidence: the OTel Collector k8sclusterreceiver builds cluster-object metrics straight from the API server (k8s.pod.phase, k8s.deployment.available, k8s.container.cpu_limit, k8s.statefulset.ready_pods, …), and kubeletstatsreceiver supplies the container/pod/node CPU and memory groups.
The trap this task must not fall into. Those are a DIFFERENT metric namespace from the KSM/cAdvisor/kubelet names in signals/k8s.md. An OTEL-NATIVE verdict is not permission to re-emit the existing promrw families in an OTLP envelope — this task sources a second name catalogue with its own provenance. Re-spelling kube_pod_status_phase as an OTLP metric would fabricate a shape no collector produces.
Add the lane as an opt-in core.OTLPMetrics declaration following the web_service otel.metrics precedent: nil unless declared, gated by a blueprint switch, promrw output unchanged when off.
Resolve cantfind SK-85 before emitting any kubeletstats family — the k8sclusterreceiver names are confirmed from its metadata, but the kubeletstats DEFAULT-ENABLED set is not.
Depends on SKT-0007.02 for instrument shapes: k8sclusterreceiver uses non-monotonic cumulative Sums and int gauges the original two-family lane did not cover.
Acceptance Criteria
- #1 A blueprint switch gates OTel-native cluster metrics; absent it, k8s_cluster emits exactly what it emits today
- #2 Every emitted family and attribute is sourced from k8sclusterreceiver or kubeletstatsreceiver metadata with provenance and date
- #3 No family name is derived from the existing kube_* or container_* Prometheus names
- #4 SK-85 is resolved, or the kubeletstats families are not emitted
- #5 signals/otlp-metrics.md covers every added family with provenance
- #6 A blueprint modelled on k8s-minimal demonstrates the base surface emitting OTel-native end to end
- #7 The construct imports no OTel SDK, selfobs or profiling; TestCatalogImportIsolation passes
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
Lane A owns internal/construct/k8scluster/**: add a test-first, switch-gated OTel-native metric lane sourced only from the observed receiver namespace, return provenance rows and root wiring requests, and run focused construct plus import-isolation checks.
Implementation Notes
Dispatch preflight 2026-08-28: generic EXECUTION route gpt-5.6-luna/max and fork_turns=none confirmed before spawn. Post-spawn route metadata is unexposed by this Codex client; only lane name/status are observable, so absence is recorded as a limitation rather than treated as substitution.
Implemented the opt-in cluster otel.metrics switch and hand-encoded native OTLP lane. The k8s-otel-native proof blueprint exports exactly the 55 families observed in the 2026-08-27 receiver permutation; focused construct, loader and TestCatalogImportIsolation checks pass, and the scoped -inventory-json export confirms 55 OTLP metric families.
Final evidence: k8s-otel-native resolves and emits exactly 55 observed OTLP-native families; the switch-off path remains promrw-only, provenance is recorded in signals/k8s.md and signals/otlp-metrics.md, SK-85 is resolved, targeted inventory and TestCatalogImportIsolation passed, and the integrated make gate passed once via Lane G.
Final Summary
Added the first switch-gated OTel-native k8s_cluster base surface from observed k8sclusterreceiver and kubeletstatsreceiver metadata. Verified 55 native families with the reference blueprint, schema generation, focused inventory, architecture isolation, and the integrated make gate.