Skip to content

fix(kagent): the kagent release detects and corrects drift — a deleted platform Harness comes back on the next reconcile (#409) - #410

Merged
teemow merged 2 commits into
mainfrom
harness-drift-detection-409
Sep 12, 2026
Merged

teemow merged 2 commits into
mainfrom
harness-drift-detection-409

Conversation

@teemow

@teemow teemow commented Sep 12, 2026

Copy link
Copy Markdown
Member

Closes #409. Follow-up of #406 (the skip-path statement of that design was wrong).

Problem

Since 4.8.0 the platform Harness kagent is rendered by the kagent chart (harness.create: true), owned by the kagent HelmRelease. A consumer whose exactly pinned connectivity chart skipped 4.7.19's keep loses the object on the 4.8.0 upgrade, and the kagent release never recreates it: with no spec.driftDetection helm-controller logs "release in-sync with desired state" on every reconcile and runs no upgrade — 600 s observed in the lab with the Harness absent and every AgentTemplate unadmitted. Only reconcile.fluxcd.io/forceAt brought it back.

Solution

spec.driftDetection.mode: enabled on the kagent HelmRelease. On every reconcile (gitops.interval, 10 min by default) helm-controller compares the manifest in the Helm storage with the cluster and re-applies what differs or is missing, as a server-side apply — no Helm revision, no forced reconcile.

  • components.<name>.driftDetection is a passthrough for every component entry (HelmRelease v2 spec.driftDetection: mode, ignore), documented in the template header and the values; set for kagent only. The kagent chart (0.11.0-gs.6) renders no hook, no webhook, no HPA-scaled Deployment and nothing of the platform edits its objects in place, so no ignore rule is needed. The Harness it renders carries helm.sh/resource-policy: keep itself; it is the release's own object, not drift.
  • tests/verify-kagent-wiring.py::check_drift_detection asserts the kagent release carries it and no other release does by default (runs inside make verify-meta).
  • The ATS smoke (test_deleted_platform_harness_comes_back_on_the_next_reconcile) deletes the Harness, requests a plain reconcile (requestedAt, standing in for the 10-minute interval; no forceAt), and asserts it is back with a new uid, owned by the kagent release with keep, spec unchanged, both templates Ready again, the Helm revision unchanged.
  • UPGRADE.md: the new <current> → <next> section; the 4.8.0 skip-path bullet now states the truth for an installation on 4.8.0 exactly and names the forced-reconcile recovery.
  • examples/customer-bom.yaml pins the connectivity chart to the release it is published with (4.8.0); a pin behind 4.7.19 renders a second owner of the Harness next to the kagent release.

Verification

  • All 26 make verify-* targets of the CI job green locally (helm-controller v1.6.4 / Flux 2.9.5 in the lab; HelmRelease v2 driftDetection is GA on helm-controller 1.x).
  • Lab (agentlab, released 4.8.0 with kagent 0.11.0-gs.6, Substrate 0.0.27-gs.7; this chart installed via platform.chartPath): the kagent HelmRelease's first reconcile with drift detection reported Drifted=False NoDriftDetected (no spurious drift on the chart's objects, the previously force-recreated Harness included). Deletion proof: see the comment below.

…d platform Harness comes back on the next reconcile (#409)

The kagent HelmRelease carries spec.driftDetection.mode: enabled. On every
reconcile (gitops.interval) helm-controller compares the manifest in the Helm
storage with the cluster and re-applies what differs or is missing, as a
server-side apply without a Helm revision. Without it a plain reconcile of the
unchanged release reported "release in-sync with desired state", so the
platform Harness a consumer skipping 4.7.19 loses on the 4.8.0 upgrade stayed
deleted — every template unadmitted, 600 s observed — until a forced reconcile.

- components.<name>.driftDetection is a passthrough for every component entry
  (HelmRelease v2 spec.driftDetection: mode, ignore), set for kagent only; the
  values, the schema and the template header document it.
- tests/verify-kagent-wiring.py asserts the kagent release carries it and no
  other release does by default (a decision per release).
- The ATS smoke deletes the Harness and sees it back on a requested (not
  forced) reconcile with both templates Ready again and no Helm revision.
- UPGRADE.md: the new section; the 4.8.0 skip-path note now states the truth
  for an installation on 4.8.0 exactly and names the forced-reconcile recovery.
- examples/customer-bom.yaml pins the connectivity chart to the release it is
  published with (a pin behind 4.7.19 renders a second owner of the Harness).
@teemow
teemow requested a review from a team as a code owner September 12, 2026 18:30
@teemow

teemow commented Sep 12, 2026

Copy link
Copy Markdown
Member Author

Lab proof (agentlab, 2026-09-12)

Lab on the released 4.8.0 (kagent 0.11.0-gs.6, Substrate 0.0.27-gs.7, helm-controller v1.6.4 / Flux 2.9.5 from the bundled engine); this branch's chart installed via platform.chartPath. The kagent HelmRelease got spec.driftDetection.mode: enabled, Helm revision stayed 11 (no upgrade: chart and values unchanged); its first reconcile with drift detection at 18:28:54Z reported Drifted=False NoDriftDetected — no spurious drift on any of the kagent chart's objects, the previously force-recreated Harness included.

Deletion, no annotation of any kind:

Event UTC Δ
last reconcile before the delete 18:28:54
kubectl -n kagent delete harness kagent (uid 4ddf228c…) 18:29:55 0 s
both AgentTemplates unadmitted (status.harnesses: []) 18:30:05 +10 s
next interval reconcile: DriftDetected "Harness/kagent/kagent removed" → DriftCorrected "Harness/kagent/kagent created" 18:38:58 +543 s
Harness back, new uid f7951051…, meta.helm.sh/release-name: kagent, helm.sh/resource-policy: keep 18:39:00 +545 s
both AgentTemplates Ready on it again 18:39:22 +567 s (22 s after the Harness)

Afterwards: Ready=True, Drifted=False NoDriftDetected, status.history[0].version still 11 — the correction was a server-side apply, not a Helm upgrade. (One benign helm-controller log line during the correction: "error patching conditions: The condition Drifted was modified by a different process" — two reconciles of the same second raced on the status patch; the next reconcile a second later wrote it.)

The lab was then restored to the released chart (chartPath removed) with the recreated Harness in place.

…he key admits ignore rules (schema additionalProperties: true)
@circleci-architect

circleci-architect Bot commented Sep 12, 2026 •

Copy link
Copy Markdown

Published Helm chart agent-platform

4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd
Chart agent-platform
Version 4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd
OCI reference oci://gsoci.azurecr.io/charts/giantswarm/agent-platform:4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd
Digest sha256:08deae36319b056b6c7bdaefff5300ca71932a0a924e701180dc56a84de389aa
Registry public — gsoci.azurecr.io
Git catalog giantswarm-test-catalog (index)
Pull this chart
helm pull oci://gsoci.azurecr.io/charts/giantswarm/agent-platform --version 4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd

Posted by architect-orb · build 6695 · commit 1e630dd · updated in place on every push

@circleci-architect

circleci-architect Bot commented Sep 12, 2026 •

Copy link
Copy Markdown

Published Helm chart agent-platform-connectivity

4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd
Chart agent-platform-connectivity
Version 4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd
OCI reference oci://gsoci.azurecr.io/charts/giantswarm/agent-platform-connectivity:4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd
Digest sha256:771e212483ee9b8c5c66a4dee176d87de10ea389ed445303065e314f0aa152af
Registry public — gsoci.azurecr.io
Git catalog giantswarm-test-catalog (index)
Pull this chart
helm pull oci://gsoci.azurecr.io/charts/giantswarm/agent-platform-connectivity --version 4.8.1-dev.harness-dri--tection-409.2026-09-12.18-42-09.h1e630dd

Posted by architect-orb · build 6696 · commit 1e630dd · updated in place on every push

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A deleted kagent Harness is not recreated by the kagent HelmRelease without driftDetection or a forced reconcile (4.8.0 skip path)

1 participant