Repository navigation
Chart Drift has never produced a verdict — 39 runs, 39 failures since 2026-08-15; it renders with one of the deploy’s three value sources #4640
Description
Chart Drift (.github/workflows/chart-drift.yml) has run 39 times and failed 39 times — 2026-08-15T06:22Z through 2026-09-17T06:39Z, zero successes, ever. It has never once produced the verdict it exists for.
gh api "repos/Systemorph/MeshWeaver/actions/workflows/334176566/runs?per_page=100" \
--jq '[.workflow_runs[]|.conclusion]|group_by(.)|map({c:.[0],n:length})'
[{"c":"failure","n":39}]
This is NOT #1709, and #1709 being closed is half the defect
#1709 tracked the first cause — MEMEX_DEPLOY_REPO_TOKEN authenticating as nothing — and was closed 2026-08-26. That cause was fixed: in today's run Assert the inputs exist and Read the environment list both pass. The next failure mode then took over silently, and with the ticket closed nothing was left pointing at it. Twelve more days of red went unread.
The workflow is not at fault: it fails RED exactly as designed. What failed is that a permanently-red check carries no information, and the one artefact that made the state visible was retired.
The current cause: it cannot render, because it only has two of the three value sources
Both environment jobs fail identically, at helm template:
##[error]helm template FAILED — cannot determine what the chart describes:
Error: execution error at (memex/templates/memex-portal/secrets.yaml:101:33):
memex.orleansConnectionString: 'memex_portal' runs AdoNet clustering on an EXTERNAL database
(postgres.enabled is false) but names no database for cluster membership: neither
secrets.memex_portal.ConnectionStrings__orleans nor secrets.memex_portal.ConnectionStrings__memex
is set. … Refusing to render.
That refusal is #3780's guard working correctly. The reason it fires is structural:
check-chart-drift.sh's own header: "Render with the SAME-flist the deploy uses, or you are diffing against a chart nobody deployed."- The deploy uses three sources —
-f <Key Vault values half> -f <overlay>plus chart defaults (Memex#295). - Chart Drift is given one: the committed
values.<release>.public.yaml, which is deliberately secret-free (chart-drift.yml's own item 3 — publishing it would leakpgbackrest.azure.accountKey).
So the check is rendering with a strict subset of the deploy's -f list, which its own header forbids. Before #3780 it would have rendered something — a chart nobody deployed — and diffed against it. Either way it has never answered its question.
Why this matters right now — measured
Ops/Status/memex, 2026-09-17T18:03:59Z (fleet watch, read-only):
| committed pin (record and overlay agree) | 3.0.0-ci.8692 |
2 pods memex-portal-deployment-6c967c7c4c-* |
3.0.0-ci.8710 |
1 pod memex-portal-deployment-d77fd7c88-x7nzm |
3.0.0-ci.8812, restarts 2, not ready |
generations: 2, converged: false |
Nothing that is committed is running, and two different uncommitted images are — for ~7 hours at the time of reading. No guard in the fleet reports this:
Memex/.github/workflows/deploy-drift.ymlcompares git against the deploy record; its header says plainly it cannot see the cluster, and delegates that to this workflow.check-chart-drift.shdoes not compare the container image at all — its compared set is the ConfigMap, the pod template's inline env / envFrom / preStop / grace / probes, and the availability shape (PDB, ScaledObject).grep -n imagefinds only prose.- The fleet watch defines
IssueKinds.ImageDriftand explicitly excludes it fromEvaluatedKinds("needs inputs this sweep does not read").
A render IS possible with no secret — but not yet truthfully
Measured locally, helm v4.2.4 (the version PR Memex#352 measured against), against deploy/helm + the committed values.memex.public.yaml:
A stub containing only fields already committed on the record — vaultValuesKeys for the key names, and databaseServer/database/databaseUsername/host for the connection-string shape — renders all 18 objects, exit 0. The placeholder value reaches exactly two objects, memex-portal-secrets and memex-migration-secrets, and neither is compared by the check:
PodDisruptionBudget memex-portal-pdb placeholder=False
ConfigMap memex-portal-config placeholder=False
Deployment memex-portal-deployment placeholder=False
Secret memex-portal-secrets placeholder=True ← not compared
Secret memex-migration-secrets placeholder=True ← not compared
Do not ship that yet. While Memex#295 is unfixed the vault half also carries STRUCTURE — for memex: extraVolumes, extraVolumeMounts, extraEnvFrom, ingress, resources, replicas, persistence, portal, migration, config — and the ConfigMap this check compares is rendered from config.*. A stub render would report every vault-only config leaf as CLUSTER-ONLY, i.e. confident nonsense in precisely the category that is supposed to mean hand-applied drift.
The order, therefore
- Memex#352 (draft, awaiting a maintainer decision) makes the vault half carry secrets only. Until it lands, this workflow cannot give a truthful verdict even if it renders.
- Then give Chart Drift the record-derived secret-free stub above as its third
-f. The workflow already checks the Memex repo out (deploy-repo), so the record is in hand — no new credential. - Separately: decide whether the container image belongs in the compared set. Today it is in nobody's.
And regardless of 1–3
A check that can be red for 34 days without anyone noticing needs the treatment deploy-drift.yml already gives the same class (Memex#95/#116): a tracking issue, updated in place, closed when it goes green. A red on the Actions tab is an event; "drift detection is not running" is a standing state, and standing states need an artefact that survives someone closing a ticket.
Measured with read-only calls: the Actions API, Ops/Status/memex via the control instance, and a local helm template. No InstanceAction was filed and nothing on any cluster was changed.
Activity
rbuergi commentedon Sep 18, 2026
Fixed by #4683 — the render, the two-render independence proof, the PR-gated negative controls, and a tracking issue so a standing state stops depending on somebody reading the Actions tab.
It produced its first verdict ever on 2026-09-18:
memex19 divergences across 209 compared fields,memex-cloud29 across 233.Two things about the plan in the description turned out differently, both measured:
vaultValuesKeysplus four connection-shape fields; the one that ships needs onlysecrets.<half>.ConnectionStrings__orleans, with its host read fromconfig.<half>.MEMEX_HOST— already committed, secret-free, and the same input the chart itself uses for the probe target. And the render is no longer trusted on the argument that the placeholder should be inert: it renders twice with two different placeholders and requires the compared objects to be identical, so the claim is re-established every run instead of asserted once. TheMemex#295concern is real and is carried forward as decision 3 on Chart Drift: three decisions its first working verdict left open — the image nobody compares, ConfigMap values in a public log, and the vault half's structure #4685, with the discriminator written down.memex-cloud(inlinefalseshadowing a ConfigMaptrue), armed with no reader onmemex(startup probe hand-moved to/ready). Filed as The NodeType bake readiness gate is not in force on EITHER production portal — off on the pod on memex-cloud, armed with no reader on memex #4684.Items 3 and 4 of the description are split out to #4685 (image coverage, the public-log disclosure, the vault half's structure) rather than left here — because this issue closes, and "the ticket was closed so nothing pointed at the next cause" is exactly what happened with #1709 and cost the twelve days this issue is about.
Written up as
Doc/Architecture/ChartDriftRenderWithoutSecrets;ChartDriftSemantics's claim that the gate "has been red every day since it first completed on 2026-08-26" is corrected in the same change — it had never completed.