Task · SKT-0015.02

Make series churn a declarable rate on the constructs that already model identity lifecycle

Description

High DPM per series is one detector input; series CHURN is the other, and it drives a different set of tools — ‘new series per minute’ alerting, active-series accounting, and the Adaptive Metrics recommendations that follow from a set that will not settle.

synthkit already models real churn in places: the k8s constructs turn pods over through their lifecycle, and network_topology drives change_total from a real edge-visibility predicate with state.DeleteGauge behind it. What it does not have is a way for a blueprint to say ‘turn the active series set over at this rate’ so the churn becomes a test knob rather than whatever the model happens to produce.

Scope this by finding the existing seam, not by inventing one. Start from internal/state (which owns cumulative series lifetime and already has DeleteGauge) and from the constructs that genuinely have an identity lifecycle to churn — pods, nodes, topology edges — and decide there whether the knob belongs in shared state, in the fixture/identity layer, or as a per-construct declaration. Constructs must stay isolated from each other and from blueprint names; whatever seam is chosen has to respect that.

Two things not to do:

Deliverable is a rate a blueprint can declare, honoured by whichever constructs can honour it truthfully, and a plain statement of which constructs cannot and why.

Acceptance Criteria

Definition of Done

Implementation Plan

After SKT-0015.01 lands, find the existing identity-lifecycle seam, TDD a declarable churn rate that retires old series without reseeding stable cluster identity, document unsupported constructs, and preserve import isolation.

Implementation Notes

Implementation decision: series_churn_per_minute belongs on the network_topology integration because its reconciled edge inventory already has truthful visibility transitions and DeleteGauge retirement. It rotates only stable declared edge identities and rejects rates larger than half the declared edge pool. Kubernetes pods, nodes and storage do not honour this field: their cluster-scoped names, UIDs, seeds and PV/PVC/EBS joins are deterministic contracts and are not reseeded or silently churned.

Implemented network_topology.series_churn_per_minute as a bounded rotating window over declared edge identities. Retired gauges use DeleteGauge; skipped ticks walk every elapsed churn-minute boundary so change_total does not lose a complete rotation. Focused validation: go test ./internal/construct/nettopo ./internal/construct/k8scluster ./internal/archtest -count=1 passed; make blueprint-schema regenerated both artifacts; git diff –check passed. CodeRabbit final review completed with zero findings after fixing delayed-tick transition accounting and clarifying baseline-visibility semantics.

Final evidence: tests prove two stable edge identities are removed and two returned per minute without accumulation at a 10s tick cadence, complete skipped rotations are counted, half-pool validation is pinned, Kubernetes determinism and TestCatalogImportIsolation pass, schema generation passed, and the integrated make gate passed.

Final Summary

Added truthful declarable churn to network_topology by rotating existing edge identities and deleting retired gauges. Preserved deterministic Kubernetes identity, documented unsupported constructs, and verified transition accounting plus isolation.

View the source file on GitHub