Repository navigation
Description
🤖 Generated by the Agentic Engineer
Summary
Stage the reference platform's hardened cluster dead-man heartbeat in the explicit Coroot profiles before retiring kube-prometheus-stack.
Motivation
The Coroot profiles now replace Loki, Alloy, OpenCost, UI access, and incident delivery, but they still inherit kube-prometheus-stack because its Watchdog alert is the only cluster-down heartbeat. Removing that stack now would silently lose cluster-death detection. The reference platform instead runs a dedicated cluster-heartbeat CronJob from the dependent Coroot apps payload, after the infrastructure policy exclusion reports ready.
This slice separates that direct cluster-liveness signal from the Prometheus-to-Alertmanager Watchdog check without changing either default provider profile. Local and unconfigured Coroot renders remain inert through an invalid fallback.
Design correction (2026-07-22)
Exact-head review disproved the original proposal to reuse alertmanager_heartbeat_url. If Watchdog and the CronJob reset one monitor, the CronJob hides a broken alert pipeline; if Watchdog is disabled, the pipeline loses its only end-to-end dead-man check. Review also exposed an upgrade-order gap when the CronJob reconciled before the infrastructure layer's policy exclusion. The safe design uses two distinct external checks, keeps Watchdog on the existing Alertmanager URL, and stages the CronJob from the dependent apps layer only after infrastructure reports ready.
Hypothesis and success signal
If both opt-in Coroot apps profiles render one hardened heartbeat on a distinct external check after their infrastructure dependency is ready, a later metrics-stack retirement can remove kube-prometheus-stack without losing the direct cluster dead-man signal or prematurely weakening alert-pipeline coverage.
Success is a structural and rendered contract: default Docker/Hetzner payloads remain unchanged; local-coroot and prod-coroot controller payloads contain no heartbeat; their dependent apps payloads each render exactly one; the only new egress is exact hc-ping.com:443; the two monitor check identities remain distinct; and every existing incident-delivery assertion remains green.
Proposed solution
- Add the portable
cluster-heartbeatCronJob to a shared apps base consumed only by the Coroot apps profiles. - Require the apps Flux Kustomization to wait for infrastructure, which owns the generated-policy exclusion.
- Keep Watchdog enabled on
alertmanager_heartbeat_url; use a separate optionalcluster_heartbeat_urlfor the CronJob. - Require canonical lowercase-UUID
hc-ping.comURLs and reject reused check identities during bootstrap, matching the fail-closed network and signal-separation policies. - Substitute the heartbeat URL into a Kubernetes Secret, expose it through a Secret-backed environment variable, and feed curl through stdin configuration rather than runtime arguments.
- Extend the observability validator with rendered, ordering, hardening, signal-separation, and negative-boundary assertions.
- Document that kube-prometheus-stack stays transitional until Flux-native reconciliation alerts are staged in a later child.
Acceptance criteria
- Default Docker and Hetzner renders contain no cluster heartbeat and keep the current kube-prometheus-stack payload unchanged.
- Both explicit Coroot controller payloads contain no heartbeat; both dependent apps payloads render exactly one five-minute
cluster-heartbeatusing the separatecluster_heartbeat_urlsubstitution and inert fallback. - Both Coroot apps Flux Kustomizations depend exactly on infrastructure with readiness waiting enabled.
- Watchdog stays enabled on the existing
alertmanager_heartbeat_urlin every profile; the CronJob never reuses that monitor. - Bootstrap accepts an unset CronJob URL, otherwise requires canonical lowercase-UUID
hc-ping.comURLs, rejects reused check identities and URL aliases, and encrypts the optional value into the production cluster variables Secret. - The rendered bearer URL is held in a Kubernetes Secret and reaches curl through stdin configuration, not the PodSpec or curl's runtime argument vector.
- The CronJob is non-overlapping, deadline/history bounded, digest-pinned, non-root, read-only, token-free, and drops all capabilities.
- Coroot egress permits exactly
hc-ping.com:443for the heartbeat; no second policy, wildcard, or world selector may match the workload. - Production incident delivery remains exactly once and local profiles remain free of real integrations.
- Mutation controls reject controller-layer staging, a missing apps dependency, a shared monitor identity, URL aliases, disabled Watchdog, broadened bootstrap hosts, PodSpec credential exposure, missing heartbeat, schedule/substitution/hardening drift, an additive matching policy, missing or broadened egress, and heartbeat leakage into defaults.
- Naming, observability, policy, local KSail, and production KSail validation pass.
- Operator docs explain the distinct checks, optional Coroot input, reconciliation order, and temporary kube-prometheus-stack retention.
Rough size
S
Part of #65
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Start date
Target date
Effort
Projects
- StatusShow more project fields✅ Done
Activity
coderabbitai commentedon Jul 21, 2026
🔗 Related PRs
#62 - feat(coredns): migrate docker-provider CoreDNS from Deployment to HelmRelease [merged]
#86 - feat(cluster-policies): consume shared helm remediation policy [merged]
#99 - feat(observability): preserve Coroot incident notifications [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!