Skip to content

feat(ingestor): resolve the spawned tag per environment (:dev / :stg) - #494

Merged
LukasWodka merged 5 commits into
developfrom
feat/ingestor-channel-tags
Jul 31, 2026
Merged

feat(ingestor): resolve the spawned tag per environment (:dev / :stg)#494
LukasWodka merged 5 commits into
developfrom
feat/ingestor-channel-tags

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Part 2 of tracebloc/backend#1360. Draft on purpose — see the sequencing gate below.

Part 1 (tracebloc/data-ingestors#422) publishes :dev / :stg. This is the half that makes them consumable: today images.ingestor.tag is a single value ("0.7") shared by dev and staging, so the two cannot sit on different channels. Only prodDigest is env-aware.

What changes

key before after
images.ingestor.tag "0.7" (the only float) explicit override, empty by default
images.ingestor.channelTags {dev: dev, stg: stg, prod: "0.7"}, keyed on resolved CLIENT_ENV

New tracebloc.ingestorTag helper, mirroring tracebloc.ingestorDigest's precedence: explicit tag > channel for CLIENT_ENV > literal 0.7. That last fallback matters — a release predating these keys still renders under a plain --reuse-values replay.

prod deliberately stays a semver float, not a :prod channel — no such tag is published for the ingestor, and prod normally spawns prodDigest anyway (the tag is only the fallback when pinning is disabled).

Rendered result (verified, not asserted)

CLIENT_ENV=dev       INGESTOR_IMAGE_TAG="dev"   DIGEST=""
CLIENT_ENV=stg       INGESTOR_IMAGE_TAG="stg"   DIGEST=""
CLIENT_ENV=prod      INGESTOR_IMAGE_TAG="0.7"   DIGEST="sha256:9098b3c9…"
CLIENT_ENV=<unset>   INGESTOR_IMAGE_TAG="0.7"   DIGEST="sha256:9098b3c9…"

The CI guard had to move with it

ingestor-multiarch in helm-ci.yaml hard-failed on an empty tag, so this change could not land without it. It now validates the explicit override when set plus every channelTags entry — an edge resolves exactly one of them, so a single-arch value in any would break ingestion on arm64 for whichever environment lands on it (client#186 / #160). Part 1's merge job already refuses to publish a single-arch index, so the channels satisfy it by construction.

⚠️ Sequencing gate — why this is a draft

:dev and :stg do not exist yet. Merging this before Part 1 has published both would point dev/staging edges at a nonexistent tag → ImagePullBackOff on the next ingestion. Also, the ingestor-multiarch job on this PR will legitimately fail until then, because it inspects those tags.

Order: merge #422 → let a develop and a staging push publish :dev and :stg (confirm both carry amd64+arm64) → mark this ready → merge.

Behavioural change to be deliberate about

Chart defaults propagate through the fleet auto-upgrade (--reset-then-reuse-values re-applies user-supplied values but reads new chart defaults), and the installer does not pin the tag — so existing dev/staging edges move onto their channel on the next upgrade. That is the intent (a staging edge should run staging code, as jobs-manager and the engine already do), but it is a real change in what those edges run. An operator who set images.ingestor.tag explicitly keeps it. Prod is untouched.

These channels are unsigned internal images (Part 1 keeps one signed trust root at the prod tags) — hence prod is never pointed at them.

Verification

  • 307/307 helm unittest across 27 suites, including 9 new cases: each environment, the explicit override winning over a channel, an unknown CLIENT_ENV falling back rather than rendering empty, and a channelTags: null replay.
  • One existing test legitimately changed: keeps the ingestor floating on dev asserted tag 0.7 for CLIENT_ENV=dev; that is precisely the behaviour this PR changes, so it now asserts dev with the rationale inline. The other two tag assertions were checked and remain correct (no-CLIENT_ENV → prod float; the explicit 0.4 override case).
  • helm lint --strict clean on all four platform values files (aks/bm/eks/oc).
  • Schema: still rejects latest in channelTags, now accepts the empty override.
  • scripts/gen-manifest.sh run — no change (no installer script touched).

Note

Medium Risk
Upgraded dev/staging edges will switch ingestor images on the next chart upgrade (intended but operationally significant), and merging before :dev/:stg exist causes ImagePullBackOff; prod pinning logic was touched but alias handling is tightened.

Overview
Spawns ingestion jobs with environment-specific ingestor tags instead of one shared images.ingestor.tag (0.7). tag is now an optional override (empty by default); defaults live in new images.ingestor.channelTags (dev:dev, stg:stg, prod0.7). jobs-manager’s INGESTOR_IMAGE_TAG comes from tracebloc.ingestorTag (override → channel for resolved env → 0.7 fallback).

Shared tracebloc.clientEnv normalizes CLIENT_ENV aliases (staging/production/etc.) so tag selection and the prod prodDigest pin stay aligned—fixing the case where production got the prod float tag but lost the digest pin.

CI and tooling follow the new model: ingestor-multiarch validates every tag an edge might spawn (explicit override plus each channelTags entry); resolve-ingestor-digest.sh defaults to channelTags.prod when tag is empty. Chart 1.9.9; helm unittest coverage for channels, overrides, aliases, and legacy --reuse-values without channelTags.

Reviewed by Cursor Bugbot for commit fa74943. Bugbot is set up for automated code reviews on this repo. Configure here.

dev and staging edges now spawn ingestion Jobs from the internal channels
published by the matching data-ingestors branch (:dev / :stg) instead of
the 0.7 release float, so an ingestor change can be validated on a real
edge without a production release. Before this, the ingestor image
existed only as a byproduct of a prod release -- on 2026-07-30 testing
one change cost a prod PyPI publish plus an FR-gate override.

- images.ingestor.tag becomes an explicit override, EMPTY by default.
- images.ingestor.channelTags carries the per-environment floats
  (dev/stg/prod), keyed on the resolved CLIENT_ENV.
- New tracebloc.ingestorTag helper mirrors tracebloc.ingestorDigest's
  precedence: explicit tag > channel for CLIENT_ENV > literal 0.7 (so a
  release predating these keys still renders under --reuse-values).
- prod deliberately stays a semver float, NOT a :prod channel -- no such
  tag is published, and prod normally runs prodDigest anyway.
- The ingestor-multiarch CI guard previously hard-failed on an empty tag;
  it now validates the explicit override when set plus every channelTags
  entry, since an edge resolves exactly one of them.

Chart defaults propagate through the fleet auto-upgrade
(--reset-then-reuse-values), and the installer does not pin the tag, so
existing dev/staging edges pick up their channel on the next upgrade.
An operator who set images.ingestor.tag explicitly keeps it.

Verified: 307/307 helm unittest across 27 suites (9 new cases covering
each environment, the override, an unknown CLIENT_ENV, and a
channelTags-less replay); helm lint --strict clean on all four platform
values files; rendered INGESTOR_IMAGE_TAG confirmed as dev/stg/0.7/0.7
for dev/stg/prod/unset; schema still rejects 'latest' in channelTags and
now accepts the empty override.
@LukasWodka

Copy link
Copy Markdown
Contributor Author

👋 Heads-up — Code review queue is at 37 / 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.)

@saadqbal saadqbal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid PR — verified the render myself (checked out the branch, helm template per env, 307/307 unittest, lint --strict clean on all four platform files). Prod is safe: digest pin still wins and its tag fallback is unchanged 0.7, so the behaviour change only touches dev/staging edges as intended. The tag never renders empty on any path I could build — including a --reuse-values replay predating the keys (channelTags: null0.7) and prodPin: false (→ 0.7), so no empty-repo: ImagePullBackOff hiding anywhere.

Keep it a draft until the ingestor-multiarch job goes green — merging before #422 publishes :dev/:stg multi-arch is the only real breakage here, and it's correctly gated.

Two nits, neither blocking:

  • The env.CLIENT_ENV schema description still says (dev, staging, prod), but resolution keys on stg — worth fixing now that the exact string is load-bearing for channel selection.
  • The values.schema.json reformat (single-line → multi-line + unicode escapes) buries the ~30 real lines in a 576-line diff. Functionally inert, just harder to review.

Asad's first note landed on a real defect, not just a stale description.
The schema documents CLIENT_ENV as (dev, staging, prod) while the channel
keys are dev|stg|prod, so CLIENT_ENV=staging -- the documented value --
missed channelTags entirely and fell back to the prod float. Meanwhile
client-runtime normalizes staging->stg at runtime, so that edge would
have talked to the stg backend while spawning the 0.7 release ingestor:
exactly the split-brain client-runtime#227 was filed for, reintroduced
one layer up.

tracebloc.ingestorTag now normalizes development/staging/production
before the lookup, mirroring proxy_config.ENV_ALIASES, and the schema
description states which values are canonical and that it is load-bearing
for channel selection.

Also addresses the second note: values.schema.json is edited surgically
in the file's own style instead of being reformatted by a json round-trip
(576-line diff -> 29).

Verified: 310/310 helm unittest (3 new alias cases); lint --strict clean
on all four platform files; rendered tag is dev/dev/stg/stg/0.7/0.7 for
dev/development/stg/staging/prod/production, and an unknown value still
falls back to the float rather than rendering empty.
@LukasWodka

Copy link
Copy Markdown
Contributor Author

@saadqbal thanks for checking out the branch and re-deriving the render — and your first note was not just a doc nit. It exposed a real defect, fixed in 6c207d6.

The (dev, staging, prod) description was describing a bug

You were right that the exact string is load-bearing, and following the documented value broke it:

CLIENT_ENV=staging  ->  INGESTOR_IMAGE_TAG="0.7"   # before: missed channelTags entirely
CLIENT_ENV=staging  ->  INGESTOR_IMAGE_TAG="stg"   # after

The keys are dev|stg|prod, so staging found no channelTags entry and fell through to the prod float. And because client-runtime normalizes stagingstg at runtime, that edge would have talked to the stg backend while spawning the 0.7 release ingestor — precisely the split-brain client-runtime#227 was filed for, reintroduced one layer up in the chart. A doc-only fix would have left the trap in place for anyone who used the documented value.

So tracebloc.ingestorTag now normalizes development/staging/production before the lookup, mirroring proxy_config.ENV_ALIASES, and the description says which values are canonical and that it selects the channel:

CLIENT_ENV tag
dev / development dev
stg / staging stg
prod / production 0.7
anything else (produktion) 0.7 — still falls back rather than rendering empty

Second note: fixed, 576 → 29 lines

Fair complaint — I'd round-tripped the file through json.dumps(indent=2), which reformatted everything and buried the real change. Reverted to the original and edited it surgically in the file's own style (inline "not": { "const": "latest" }, 12-space indent). git diff --stat is now 26 insertions, 3 deletions.

Verification after the fix

  • 310/310 helm unittest across 27 suites — 3 new cases pinning each alias, including the one that would have caught this.
  • helm lint --strict clean on all four platform values files.
  • Render re-derived for all seven inputs in the table above.

On your gating advice — agreed, and it has now cleared

Both channels are published and multi-arch:

:dev -> sha256:87fccee44d9695e9…   linux/amd64 + linux/arm64
:stg -> sha256:ff92490567f368f7…   linux/amd64 + linux/arm64

ingestor-multiarch was red only because it ran at 12:06, before the first publish at 12:19; re-run after :stg landed and it passes. So the gate you asked for is satisfied — this can come out of draft once you're happy with the alias fix.

@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

Comment thread client/values.yaml
Comment thread client/templates/_helpers.tpl
Both from Bugbot on #494, and both caused by my own half-applied alias fix.

1. The alias normalization went into tracebloc.ingestorTag only, while
   tracebloc.ingestorDigest still compared the RAW CLIENT_ENV to "prod".
   So CLIENT_ENV=production got the prod float tag but an EMPTY digest --
   silently dropping the reproducibility pin (backend#1028/#1245) on an
   edge that looked correctly configured, which is worse than the bug the
   alias fix was for. Extracted tracebloc.clientEnv as the single
   normalizer and pointed both helpers at it, so they cannot drift again
   (the reason ENV_ALIASES lives once in client-runtime proxy_config).

2. scripts/resolve-ingestor-digest.sh read images.ingestor.tag, now empty
   by default, so the documented no-arg / --write path exited on an empty
   tag -- the exact command the chart comments and the ingestor-multiarch
   CI error tell operators to run. It now falls back to
   images.ingestor.channelTags.prod on both the yq and the yq-free path,
   with a matching sibling awk reader scoped the same way.

Verified: 311/311 helm unittest (a new case pins the production-alias
digest); lint --strict clean on all four platform files; rendered
tag+digest correct for prod/production/stg/staging/dev/development; the
script's no-arg path resolves 0.7 -> the multi-arch digest again, and the
portable reader returns 0.7 with tag empty.
@LukasWodka

Copy link
Copy Markdown
Contributor Author

Both new findings were valid, and both were caused by my own half-applied alias fix — fixed in b87a4d4.

Prod alias skips digest pin (Medium) — the serious one

I added normalization to tracebloc.ingestorTag but not tracebloc.ingestorDigest, which still compared the raw CLIENT_ENV to "prod". Measured before the fix:

CLIENT_ENV=prod        tag=0.7  digest=sha256:9098b3c9…
CLIENT_ENV=production  tag=0.7  digest=""            <-- pin silently gone

So a production edge got the right tag and lost the reproducibility pin (backend#1028/#1245) while looking correctly configured — worse than the bug the alias fix was for, and my schema description had already started claiming both were normalized.

Fixed structurally rather than by patching the second call site: there is now one tracebloc.clientEnv helper and both consumers go through it, so they cannot drift again. That is the same reasoning as keeping ENV_ALIASES in one place in client-runtime/proxy_config.py — the split-brain in client-runtime#227 came from exactly this shape of duplication, and I had just reproduced it in the chart.

After:

CLIENT_ENV tag digest
prod / production 0.7 sha256:9098b3c9…
stg / staging stg (empty — floats, intended)
dev / development dev (empty — floats, intended)

Empty tag breaks digest resolver (Medium) — also valid

scripts/resolve-ingestor-digest.sh read images.ingestor.tag, which this PR makes empty by default, so the documented no-arg / --write path exited with an empty-tag error. That is the exact command the chart comments and the ingestor-multiarch CI failure message tell operators to run to refresh prodDigest — so I had broken the prescribed remediation path.

It now falls back to images.ingestor.channelTags.prod, on both readers: the yq path and the portable yq-free awk parser, with a sibling reader scoped the same disciplined way (only the 6-space prod: leaf inside images: → ingestor: → channelTags: can match). Verified end to end:

$ scripts/resolve-ingestor-digest.sh
ghcr.io/tracebloc/ingestor@sha256:53b998893eba9c4c…  (tag 0.7; platforms: linux/amd64 linux/arm64)

and the portable reader in isolation returns 0.7 with tag empty.

Verification

  • 311/311 helm unittest across 27 suites — a new case pins the production-alias digest specifically, so this regression can't come back silently.
  • helm lint --strict clean on all four platform values files.
  • bash -n clean on the script. shellcheck flags one SC2295 at line 135 — confirmed pre-existing on develop (4 occurrences there), not introduced here; left alone rather than mixed into this change.

Two review rounds, four real findings, three of them my own regressions — the helper duplication in particular was worth catching before it shipped to edges.

bugbot run

@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit b87a4d4. Configure here.

@LukasWodka
LukasWodka marked this pull request as ready for review July 30, 2026 16:19
@LukasWodka
LukasWodka requested a review from saadqbal July 30, 2026 16:19
@LukasWodka

Copy link
Copy Markdown
Contributor Author

👋 Heads-up — Code review queue is at 32 / 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.)

@LukasWodka

Copy link
Copy Markdown
Contributor Author

@saadqbal ready for review — the gate you asked for has cleared, and the diff has changed materially since you looked, so it's worth a fresh pass rather than a rubber stamp.

Your gate is satisfied

Both channels are published and multi-arch, and ingestor-multiarch passes (it was only red because it ran at 12:06, before the first publish at 12:19):

:dev -> sha256:87fccee44d9695e9…   linux/amd64 + linux/arm64
:stg -> sha256:ff92490567f368f7…   linux/amd64 + linux/arm64

What changed since your review — three regressions, all mine

Your first "nit" wasn't a doc issue. Following the documented CLIENT_ENV=staging resolved to 0.7 rather than :stg, and since client-runtime normalizes stagingstg at runtime, that edge would have talked to the stg backend while spawning the release ingestor — the split-brain of client-runtime#227, one layer up.

Then Bugbot found my fix for that was half-applied, which was worse: I normalized in ingestorTag but not ingestorDigest, so CLIENT_ENV=production got the prod tag with an empty digest — silently dropping the reproducibility pin (backend#1028/#1245) on an edge that looked fine. This is the part most worth your eyes, since it touches the prod pin path you specifically verified. Fixed structurally: one tracebloc.clientEnv normalizer, both helpers consume it, so they can't drift again.

Third: I'd broken scripts/resolve-ingestor-digest.sh — it reads images.ingestor.tag, which this PR empties, so the no-arg/--write path (the command the chart comments and the ingestor-multiarch error tell operators to run) exited on an empty tag. Now falls back to channelTags.prod on both the yq and yq-free readers.

Your second nit is fixed too: the schema is edited surgically in its own style now — 576-line diff → 29.

Current state

CLIENT_ENV tag digest
prod / production 0.7 sha256:9098b3c9…
stg / staging stg empty (floats)
dev / development dev empty (floats)
unknown (produktion) 0.7 empty

311/311 unittest (new cases pin both the stagingstg resolution and the production digest), lint --strict clean on all four platform files, Bugbot clean, zero unresolved threads.

One deployment note, not a code note

Merging to develop moves no edge — the chart has to be released and edges upgraded. But when it does land, dev/staging switch from the 0.7 float to :dev/:stg, and :dev tracks develop by design. Divya is mid-D16-validation on a staging edge, so the sensible sequence is: approve and merge now, hold the chart release until she's finished — a channel switch under her feet would muddy her results. Flagging it so the release timing is a decision rather than a side effect.

saadqbal
saadqbal previously approved these changes Jul 31, 2026

@saadqbal saadqbal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Careful, well-scoped PR — the helper precedence, the single tracebloc.clientEnv normalizer shared by both ingestorTag and ingestorDigest, the CI multi-arch guard extension, and the resolver's channelTags.prod fallback all line up, and the unittest coverage is thorough (incl. the alias + reproducibility-pin cases). LGTM on the code.

Approving the code only — merge still waits on the sequencing gate you flagged: #422 has to publish :dev/:stg (both multi-arch) first, and ingestor-multiarch will legitimately stay red until then. One trivial comment inline.

Comment thread scripts/resolve-ingestor-digest.sh
The new read_ingestor_prod_channel landed between read_ingestor_tag's
header comment and read_ingestor_tag itself, so that header described the
wrong function and read_ingestor_tag sat comment-less ~30 lines below.
Moved the new function below the original; each header is now directly
above the function it documents. No behaviour change -- both readers
verified still returning 0.7 / empty, and the no-arg resolver path still
resolves the multi-arch digest.
@LukasWodka

Copy link
Copy Markdown
Contributor Author

Thanks for the approval — and the nit was a fair catch, fixed in 8a5b82d.

You were exactly right: inserting read_ingestor_prod_channel there orphaned the original header, so # Portable, yq-free reader for images.ingestor.tag … sat above my function while read_ingestor_tag was comment-less ~30 lines down. Moved the new function below the original, so each header is directly above the function it documents:

L41  # Portable, yq-free reader for images.ingestor.tag …
L45  read_ingestor_tag() {
L75  # Portable, yq-free reader for images.ingestor.channelTags.prod …
L79  read_ingestor_prod_channel() {

No behaviour change — both readers re-verified (prod_channel='0.7', tag=''), the no-arg resolver still returns the multi-arch digest, and the chart suite is untouched at 311/311. Thread resolved.

One correction on the merge gate — it has already cleared

Your review says ingestor-multiarch "will legitimately stay red until" #422 publishes the channels. That happened while this was in draft:

:dev -> sha256:87fccee44d9695e9…   linux/amd64 + linux/arm64
:stg -> sha256:ff92490567f368f7…   linux/amd64 + linux/arm64

#422 is merged, both channels published (a staging hop carried the workflow onto staging, which fired the :stg build), and Spawned ingestor image is multi-arch: success on the current head — I just re-confirmed it. The earlier red was purely timing: the job ran at 12:06 and the first publish was 12:19.

So the sequencing gate you set is satisfied and this is mergeable on the code you approved.

The remaining call is deployment timing, not code

Merging to develop moves no edge — the chart has to be released and edges upgraded. When that release lands, dev/staging switch from the 0.7 float to :dev/:stg. Divya is mid-D16 validation on a staging edge, so the sensible order is: merge now, hold the chart release until she's finished. A channel switch under her feet would muddy her results. Flagging so the release timing is a decision rather than a side effect of merging.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8a5b82d. Configure here.

Comment thread scripts/resolve-ingestor-digest.sh
… channel parser

Two things, both caught by CI/review rather than by me:

- The 'chart content ⇒ Chart.yaml version bump' guard was red: this PR
  edits client/templates and client/values.yaml, and a Helm repo publishes
  only on a version change, so without a bump the whole change would reach
  no install -- exactly how the perIngestionTables block shipped dark in
  #472. Chart 1.9.8 -> 1.9.9.

- read_ingestor_prod_channel stripped quotes BEFORE removing an inline
  comment, the reverse of read_ingestor_tag. A channelTags.prod line with a
  trailing comment therefore parsed as 0.7" -- a stray quote -- and the
  no-arg/--write resolver would look up a nonexistent ref. Reordered to
  match: key, comment, trim, quotes. Verified across all four forms
  (double/single quoted with and without a trailing comment, and bare).
@LukasWodka

Copy link
Copy Markdown
Contributor Author

Two more, both fixed in fa74943 — and one of them would have made this whole PR a no-op.

The chart-version guard was right to block it

chart content ⇒ Chart.yaml version bump was red because this PR edits client/templates/** and client/values.yaml without bumping the chart. Its error message says it best: a Helm repo publishes only on a version change, so an unbumped edit reaches no install"this is how the perIngestionTables flag block shipped dark — PR #472". Without the bump, the per-environment channel resolution would have merged, looked correct, and changed nothing on any edge. Bumped 1.9.8 → 1.9.9 (version + appVersion).

That guard earned its keep here — it caught the exact failure mode it was written for.

Bugbot: Channel parser quote order (Low) — valid, and reproduced

My read_ingestor_prod_channel stripped quotes before removing an inline comment, the reverse of read_ingestor_tag. Reproduced with the real awk:

prod: "0.7"  # tracks the current line   ->  '0.7"'    <-- stray quote

The trailing " was no longer at end-of-line once the comment followed it, so the unwrap missed and the resolver would have looked up ingestor:0.7" — a nonexistent ref. It fails closed, but on a values file that hasn't got a comment on that line yet, which is a latent trap rather than a visible one. Reordered to match the sibling exactly (key → comment → trim → quotes) and verified all four forms:

line parsed
prod: "0.7" # tracks the current line 0.7
prod: '0.7' # single quoted 0.7
prod: 0.7 0.7
prod: "0.7" 0.7

Worth noting the shape of this one: I wrote a sibling parser and diverged from the sibling's ordering — the same class of "second copy drifts from the first" as the ingestorTag/ingestorDigest split you and Bugbot caught earlier. Third time that pattern showed up in this PR.

State

311/311 unittest, lint --strict clean on all four platform files, resolver's no-arg path still returning the multi-arch digest, gen-manifest no-op (no installer script changed). Thread resolved.

@saadqbal your approval predates these two commits — the chart bump and the parser reorder. Neither touches the logic you reviewed (the helper precedence, the shared normalizer, the guard extension, the channelTags.prod fallback), but flagging it so you can re-confirm rather than have your approval carried onto a diff you hadn't seen.

@LukasWodka
LukasWodka merged commit 8e2bca0 into develop Jul 31, 2026
44 checks passed
LukasWodka added a commit that referenced this pull request Jul 31, 2026
…path (#417 unblocked)

Rebuilt against develop: #494 (backend#1360) landed the per-environment channel
scheme while this PR sat on HOLD, which made the original one-line change WRONG,
not merely conflicting. `images.ingestor.tag` is now an explicit force-override
that is EMPTY by default; the effective tag comes from `channelTags[CLIENT_ENV]`.
Setting `tag: "0.8"` as this PR originally did would have pinned 0.8 on EVERY
edge and silently defeated the new :dev / :stg channel routing.

The correct change on today's develop:

- `channelTags.prod` 0.7 -> 0.8. dev/stg already track the internal :dev / :stg
  channels, so prod is the only entry that was still on a pre-D16 line.
- `prodDigest` refreshed to the 0.8 multi-arch index, resolved with
  `scripts/resolve-ingestor-digest.sh --write` (never hand-typed, per the
  chart's own instruction) and independently cross-checked against
  registry-1/ghcr's `docker-content-digest`:
  sha256:d4af33420520d0fb01df3af4cf5259f664c89e95c7dff0681e8aa335a0c6e614
- `_helpers.tpl`'s last-resort literal 0.7 -> 0.8. It only fires for a release
  predating these keys under `--reuse-values`, but leaving it on 0.7 would spawn
  a pre-D16 ingestor on exactly those replays.
- Chart.yaml 1.9.9 -> 1.9.10, version AND appVersion. develop had already
  published 1.9.9 (via #494), so the original bump to 1.9.9 would have collided.

HOLD condition is now satisfied — this was the only thing blocking the PR:
  data-ingestors#419 merged 2026-07-30 10:52Z; v0.8.0 released 11:45Z.
The CI multi-arch gate failed on this PR at 10:55Z, 50 minutes BEFORE the image
was published, which is the whole of that red X. All four refs the gate now
inspects verify multi-arch (linux/amd64 + linux/arm64) against ghcr.io today:
:dev, :stg, :0.8, and the prodDigest index.

Verification: helm unittest 320/320 across 27 suites; helm lint --strict clean
for all four platform value files (aks/bm/eks/oc); gen-manifest --check and
check-drift clean.

Left as a DRAFT deliberately — flipping it ready is Lukas's call, and moving the
prod pin reaches every prod edge on the next fleet auto-upgrade.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
Contributor Author

/fr-pass

LukasWodka added a commit that referenced this pull request Aug 4, 2026
…path (#417 unblocked)

Rebuilt against develop: #494 (backend#1360) landed the per-environment channel
scheme while this PR sat on HOLD, which made the original one-line change WRONG,
not merely conflicting. `images.ingestor.tag` is now an explicit force-override
that is EMPTY by default; the effective tag comes from `channelTags[CLIENT_ENV]`.
Setting `tag: "0.8"` as this PR originally did would have pinned 0.8 on EVERY
edge and silently defeated the new :dev / :stg channel routing.

The correct change on today's develop:

- `channelTags.prod` 0.7 -> 0.8. dev/stg already track the internal :dev / :stg
  channels, so prod is the only entry that was still on a pre-D16 line.
- `prodDigest` refreshed to the 0.8 multi-arch index, resolved with
  `scripts/resolve-ingestor-digest.sh --write` (never hand-typed, per the
  chart's own instruction) and independently cross-checked against
  registry-1/ghcr's `docker-content-digest`:
  sha256:d4af33420520d0fb01df3af4cf5259f664c89e95c7dff0681e8aa335a0c6e614
- `_helpers.tpl`'s last-resort literal 0.7 -> 0.8. It only fires for a release
  predating these keys under `--reuse-values`, but leaving it on 0.7 would spawn
  a pre-D16 ingestor on exactly those replays.
- Chart.yaml 1.9.9 -> 1.9.10, version AND appVersion. develop had already
  published 1.9.9 (via #494), so the original bump to 1.9.9 would have collided.

HOLD condition is now satisfied — this was the only thing blocking the PR:
  data-ingestors#419 merged 2026-07-30 10:52Z; v0.8.0 released 11:45Z.
The CI multi-arch gate failed on this PR at 10:55Z, 50 minutes BEFORE the image
was published, which is the whole of that red X. All four refs the gate now
inspects verify multi-arch (linux/amd64 + linux/arm64) against ghcr.io today:
:dev, :stg, :0.8, and the prodDigest index.

Verification: helm unittest 320/320 across 27 suites; helm lint --strict clean
for all four platform value files (aks/bm/eks/oc); gen-manifest --check and
check-drift clean.

Left as a DRAFT deliberately — flipping it ready is Lukas's call, and moving the
prod pin reaches every prod edge on the next fleet auto-upgrade.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
LukasWodka added a commit that referenced this pull request Aug 5, 2026
…path (#417 unblocked)

Rebuilt against develop: #494 (backend#1360) landed the per-environment channel
scheme while this PR sat on HOLD, which made the original one-line change WRONG,
not merely conflicting. `images.ingestor.tag` is now an explicit force-override
that is EMPTY by default; the effective tag comes from `channelTags[CLIENT_ENV]`.
Setting `tag: "0.8"` as this PR originally did would have pinned 0.8 on EVERY
edge and silently defeated the new :dev / :stg channel routing.

The correct change on today's develop:

- `channelTags.prod` 0.7 -> 0.8. dev/stg already track the internal :dev / :stg
  channels, so prod is the only entry that was still on a pre-D16 line.
- `prodDigest` refreshed to the 0.8 multi-arch index, resolved with
  `scripts/resolve-ingestor-digest.sh --write` (never hand-typed, per the
  chart's own instruction) and independently cross-checked against
  registry-1/ghcr's `docker-content-digest`:
  sha256:d4af33420520d0fb01df3af4cf5259f664c89e95c7dff0681e8aa335a0c6e614
- `_helpers.tpl`'s last-resort literal 0.7 -> 0.8. It only fires for a release
  predating these keys under `--reuse-values`, but leaving it on 0.7 would spawn
  a pre-D16 ingestor on exactly those replays.
- Chart.yaml 1.9.9 -> 1.9.10, version AND appVersion. develop had already
  published 1.9.9 (via #494), so the original bump to 1.9.9 would have collided.

HOLD condition is now satisfied — this was the only thing blocking the PR:
  data-ingestors#419 merged 2026-07-30 10:52Z; v0.8.0 released 11:45Z.
The CI multi-arch gate failed on this PR at 10:55Z, 50 minutes BEFORE the image
was published, which is the whole of that red X. All four refs the gate now
inspects verify multi-arch (linux/amd64 + linux/arm64) against ghcr.io today:
:dev, :stg, :0.8, and the prodDigest index.

Verification: helm unittest 320/320 across 27 suites; helm lint --strict clean
for all four platform value files (aks/bm/eks/oc); gen-manifest --check and
check-drift clean.

Left as a DRAFT deliberately — flipping it ready is Lukas's call, and moving the
prod pin reaches every prod edge on the next fleet auto-upgrade.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

2 participants