ci: chart-invariant gate — render tracebloc/client @ pinned ref, assert the 8 CLI-assumed invariants#311
Conversation
The CLI hardcodes 8 invariants about the tracebloc/client chart — discovery labels + jobs-manager Deployment name forms, the jobs-manager Service on 8080, the client-pvc mount at /data/shared, the ingestion-authz ConfigMap + "ingestor" SA fallback, the INGESTOR_IMAGE_DIGEST env, the requests-proxy Deployment, and the POST /internal/submit-ingestion-run port. A chart rename ships green in both repos and breaks discovery/doctor/ingest in the field. New scripts/.client-ref pins the client commit the gate renders (the scripts/.data-ingestors-ref pattern, backend#1009): chart-drift.yml checks out tracebloc/client at that ref, helm-templates it with the same CI values the client repo's own drift job uses, and scripts/chart-invariants asserts every invariant with a mapping back to the CLI constant it protects. Triggers: PRs touching internal/cluster/** or internal/doctor/** (or the gate's own files, weekly cron, manual dispatch. The client-side half extends that repo's scripts/tests/check-drift.sh so renaming chart PRs fail at the source. Refs #290 (WS-D.1, backend#1106) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> EOF )
|
@BugBot run |
|
👋 Heads-up — Code review queue is at 52 / 30 Above the WIP limit. The team convention is to review existing PRs before opening new work. Open PRs currently in Code review (oldest first):
Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.) |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 470441b. Configure here.
saadqbal
left a comment
There was a problem hiding this comment.
👍 Excellent gate — the 8 invariants trace to real CLI assumptions (the label-selector + -jobs-manager suffix match DiscoverParentRelease exactly), it's pinned to .client-ref (ref-shape validated), least-privilege, and the whole render→assert flow ran green here plus the 266-line unit test. The drift message pointing at the CLI-side constants to bump is a nice touch.
|
Status: approved, but 1 open Cursor Bugbot finding blocks merge: Service check ignores probe order (chart-invariants/main.go:277). Resolve/fix and it's ready. |
Invariant 3 passed if any jobs-manager/<release>-jobs-manager Service exposed 8080, but pickJobsManagerService (internal/cluster/discover.go) selects the unprefixed "jobs-manager" first by existence, ignoring ports. With both Services rendered and only the non-selected one on 8080, the gate passed while the CLI would port-forward to the wrong target. Now the gate mirrors that precedence and checks the selected Service. Adds a regression case covering the both-Services-only-sibling-has-8080 scenario. Fixes a Cursor Bugbot finding on #311. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
saadqbal
left a comment
There was a problem hiding this comment.
Re-approving — Bugbot fix verified: the gate now mirrors pickJobsManagerService's precedence (unprefixed 'jobs-manager' first) and asserts the selected Service exposes 8080, not merely 'some' Service — with a test for the selected-lacks-8080-but-sibling-has-it case. Correct. 👍

Fixes #290 (WS-D.1 of tracebloc/backend#1106 — cli side; the client-side half is a separate PR extending tracebloc/client's
scripts/tests/check-drift.sh).Summary
The CLI hardcodes 8 invariants about the tracebloc/client chart. Today 3 are guarded at the source (the two Deployment names + the helm-standard labels ride on the client repo's own drift check); 5 are unguarded — a chart rename ships green in both repos and breaks discovery/doctor/ingest in the field. This adds a cli-side render gate that asserts all 8 against the chart at a pinned ref.
What changed
scripts/.client-ref(new) — pins the tracebloc/client commit the gate renders, same format + rationale asscripts/.data-ingestors-ref(pin, don't float, so an unrelated chart commit can't red every open CLI PR; adopting upstream is a deliberate SHA bump). Pinned to clientdevelopHEAD at gate introduction:ca9a3352f3b1a1a9135c196dcbb694ce239be1fe.scripts/chart-invariants/(new, Go, no new deps —gopkg.in/yaml.v3is already direct) — reads ahelm templaterender, asserts the 8 invariants, each mapped to the CLI constant it protects:app.kubernetes.io/name=client+managed-by=Helm, instance/chart/version reads) —internal/cluster/discover.go DiscoverParentRelease<release>-jobs-manager/jobs-manager)pickJobsManagerService+jobsManagerPortpvc.go SharedPVCClaimName/SharedPVCMountPath<release>-ingestion-authzConfigMap, keyingestion-authz.yaml,allowed[]{service_account, namespace}shape, unambiguous for the release namespace, and the default SA stayingingestorwith the SA object rendered —discoverIngestorSAName+ theIngestorSANamefallbackINGESTOR_IMAGE_DIGESTenv on the first container (the exact read the CLI does)findDeploymentaccepts —checkRequestsProxyPOST /internal/submit-ingestion-run—internal/submit SubmitPath. (The path is comment-carried in the render — a weak but deliberate tripwire; a client-runtime endpoint move updates those comments and must then confront the CLI constant.).github/workflows/chart-drift.yml(new, dedicated file — nothing appended to build.yml) — checks out the pin (ref shape validated first),helm templatewithclient/ci/bm-values.yaml, runs the checker. Triggers: PRs touchinginternal/cluster/**/internal/doctor/**/ the gate's own files, weekly cron (Mon 05:00 UTC, offset from e2e + path-persist),workflow_dispatch.Deviations from the ticket (verified against reality)
secrets.*). No goldens workflow with a secret exists yet either (sync-validator-goldens.sh's CI job is still pending). So there is nothing to guard-skip on; the workflow notes inline that a read token becomes necessary only if the client repo ever goes private. @LukasWodka flagging this per the ticket — if you'd rather pre-provision an org read token now, say the word and a guarded fallback goes in.values.schema.jsonrequires non-emptyclientId/clientPassword), so the gate renders withclient/ci/bm-values.yaml— the same values file the client repo's owncheck-drift.shCI half picks, dummy creds + platform bits only; every invariant object is unaffected.Verified locally (green)
scripts/.client-ref→ matches client develop HEAD →helm template(local helm v4.1.1; CI pins v3.15.4, same as the client repo's drift job) → checker passes 8/8 against the real render.go build ./...,go vet ./..., fullgo test ./...suite,go test -race ./scripts/...,gofmt -s,errcheck@v1.20.0,ineffassign@v0.2.0,misspell@v0.3.4— all clean.actionlintonchart-drift.yml— clean.Needs CI
.github/workflows/chart-drift.yml+scripts/chart-invariants/**, which are in its own path filter, so it exercises itself here.🤖 Generated with Claude Code
Note
Low Risk
Adds CI and a validation script only; no runtime CLI behavior changes. Failures surface contract drift before release rather than altering production paths.
Overview
Adds a cross-repo chart drift gate so CLI assumptions about the
tracebloc/clientHelm chart cannot silently diverge from what ships in the field.scripts/.client-refpins the client commit CI renders (same pin-don’t-float model asscripts/.data-ingestors-ref).scripts/chart-invariantsis a small Go tool that parseshelm templateoutput and fails if any of 8 invariants break—discovery labels, jobs-manager Deployment/Service (8080, unprefixed Service precedence),client-pvcat/data/shared, ingestion-authz +ingestorSA,INGESTOR_IMAGE_DIGESTon the first container, requests-proxy naming, and submit path/port markers tied tointernal/cluster,internal/doctor, andinternal/submit..github/workflows/chart-drift.ymlchecks out the pin, renders withclient/ci/bm-values.yamland Helm v3.15.4, runs the checker, and triggers on relevant PR paths, weekly schedule, andworkflow_dispatch. Unit tests cover each invariant via fixture mutations.Reviewed by Cursor Bugbot for commit cb15ff0. Bugbot is set up for automated code reviews on this repo. Configure here.