Repository navigation
fix(#2235): a second WebhookInbox target slot, so the platform-release target stops being shadowed - #2352
Conversation
…t slot memex-cloud's overlay set WebhookInbox__Targets__0 to Hosting/PlatformBuilds (the new platform-release inbox target) and helm rendered it correctly into the ConfigMap — but the live Deployment already carried a hand-set `kubectl set env WebhookInbox__Targets__0=Store/Payments` from before this chart key existed (the pre-existing Stripe payments inbox). Kubernetes gives an explicit Deployment env: entry priority over the same-named var sourced via envFrom, so the ConfigMap's correct value was silently and permanently shadowed: helm reported success, the rendered ConfigMap held the right value, and the running pod kept answering 404 for Hosting/PlatformBuilds — which is exactly what CD's notify-platform-update hit on every promoted build since 08-22, with nothing visibly wrong anywhere. Confirmed live (memex-cloud, 2026-08-26): kubectl get configmap ... WebhookInbox__Targets__0 -> Hosting/PlatformBuilds (correct) kubectl exec ... printenv WebhookInbox__Targets__0 -> Store/Payments (shadowed) Root cause is that the chart only ever templated ONE indexed slot (WebhookInbox__Targets__0), so a deployment needing a second webhook target had nowhere to put it except colliding on the same index by hand. This adds WebhookInbox__Targets__1 as a real second slot, following the same index-by-index pattern already used for OpenRouter__Models__N / AzureFoundry__Models__N (EveryConfigKeySetInAValuesFile_IsBoundInTheConfigMap requires each key spelled out explicitly, never a range). Companion overlay change: Systemorph/Memex#121 (private repo) sets memex-cloud's __0 to match what is actually live (Store/Payments) and adds __1 = Hosting/PlatformBuilds on the fresh, never-shadowed slot. Landing both plus a helm-release deploy of memex-cloud is what actually restores delivery — this PR only adds the chart capability. Verified: helm template renders both slots correctly (`helm template memex ./deploy/helm -f ./deploy/helm/values.yaml -f ./deploy/aks/values.aks.yaml`); PlatformBakeLaneGuard (incl. EveryConfigKeySetInAValuesFile_IsBoundInTheConfigMap) 9/9 green. No What's New entry: chart/config-only, matching precedent (#2268, #1925, #1999) — no portal-user-visible change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a second Helm ConfigMap key for webhook inbox targets so a deployment can configure multiple WebhookInbox:Targets entries without colliding on __0 (which can be shadowed by an out-of-band env: override).
Changes:
- Add
WebhookInbox__Targets__1to the portal ConfigMap template to support a second allowlisted webhook target. - Document/configure the new target slot in AKS values (
WebhookInbox__Targets__1, default empty).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| deploy/helm/templates/memex-portal/config.yaml | Adds a second WebhookInbox__Targets__1 slot to the rendered ConfigMap. |
| deploy/aks/values.aks.yaml | Documents the second slot and defines it as empty by default for AKS deployments. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…llowlist "<no value>" Copilot review on #2352: a values file that omits WebhookInbox__Targets__1 (or __0) entirely made Helm render the literal string "<no value>" for that key — non-whitespace, so it would pass WebhookInboxEndpoints' IsNullOrWhiteSpace filter and silently allowlist a bogus target string. Same `| default ""` pattern already used two lines above for SelfUpdate__MinRollInterval. Verified: `helm template` with an overlay that sets neither key now renders "" for both (was previously the untested path); the two prior scenarios (values.aks.yaml's real values; the intended memex-cloud overlay) render unchanged. PlatformBakeLaneGuard 9/9 green, fresh .trx after a Release/-warnaserror rebuild. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
One caveat for whoever deploys this, which the review thread doesn't cover — the A So for Two things that make this PR's approach right, for the record:
|
Test Results (shard 3) 9 files 9 suites 5m 32s ⏱️ Results for commit 0f45aed. ♻️ This comment has been updated with latest results. |
Test Results (shard 0)593 tests 589 ✅ 12m 32s ⏱️ Results for commit 0f45aed. ♻️ This comment has been updated with latest results. |
Test Results (shard 5) 9 files 9 suites 7m 9s ⏱️ Results for commit 0f45aed. ♻️ This comment has been updated with latest results. |
Test Results (shard 2)2 831 tests 2 728 ✅ 9m 20s ⏱️ Results for commit 0f45aed. ♻️ This comment has been updated with latest results. |
Test Results (shard 4)2 064 tests 2 061 ✅ 14m 10s ⏱️ Results for commit 0f45aed. ♻️ This comment has been updated with latest results. |
Test Results (shard 1)2 046 tests 1 853 ✅ 8m 20s ⏱️ Results for commit 0f45aed. ♻️ This comment has been updated with latest results. |
Test Results 53 files 53 suites 57m 6s ⏱️ Results for commit 0f45aed. ♻️ This comment has been updated with latest results. |
|
Small correction so this doesn't propagate — the Tested directly on Helm v4.2.3, with a values file that defines data:
quoted: "{{ .Values.config.memex_portal.Missing }}"
bare: {{ .Values.config.memex_portal.Missing }}renders: data:
quoted: ""
bare:Empty in both forms — not the literal What the review thread verified was the post-fix render ( Two things that do NOT change:
The substantive finding in this PR is unaffected and remains correct: an inline |
|
CI red is #2008, not this PR — and this run was unusually useful. Shard 2 failed on This PR's diff is Why the run mattered anyway: #2008 is a ~1.3% flake whose diagnostics were being discarded — process B called Re-running the failed jobs. Cause named above rather than discovered by watching it go green. |
The hop where delivery actually stops
Not where #2268 (already merged) or the issue's own comments suspected. #2268 fixed the CD side —
notify-platform-updatenow fails loud on a non-2xx instead of::warning::-ing past it, and thatchange is what turned this from invisible into a reproducible 404 on the very next promote:
Tracing why, live on memex-cloud (the
memex.meshweaver.cloudcontrol instance — NOT thememexnamespace, which serves
memex.systemorph.com; a first wrong turn worth naming since it cost time):Hosting/PlatformBuildsnode exists (both MCP servers confirm it, version 1, unchanged — theexpected steady state, not evidence of nothing arriving, per the issue's own corrected
diagnosis).
Hosting__PlatformWebhookSecretis mounted and non-empty (memexcloud-portal-ai-secrets,wired via the
memexcloud-portal-ai-secretsSecretProviderClass) — the issue's suspicion that thesecret was never provisioned is now stale/incorrect.
WebhookInbox__Targets__0in the ConfigMap isHosting/PlatformBuilds— correct.WebhookInbox__Targets__0in the running pod's actual environment isStore/Payments:The Deployment carries an explicit
env:entryWebhookInbox__Targets__0=Store/Payments—hand-set via
kubectl set env, pre-dating this chart key, for the pre-existing Stripe paymentsinbox. Kubernetes gives an explicit
env:entry priority over the same-named var sourced viaenvFrom(the ConfigMap), so it permanently shadows whatever the chart renders for that name.Every reported signal was green: helm said "Upgrade complete", the ConfigMap held the right value,
WebhookInboxEndpoints.Deliver(memex/Memex.Portal.Shared/Api/WebhookInboxEndpoints.cs) iscorrectly wired and unconditionally mapped — and the live pod answered 404 anyway, because nothing
in the chain ever looks at the pod's resolved environment, only at what was intended to render
into it.
This is the same defect class as #2210 (the GitHub App identity blanking): a value that renders
correctly into the ConfigMap while the running container silently uses something else.
Why it looked like success
helm upgradegenuinely succeeds — it owns the ConfigMap, not the out-of-bandenv:entry.indistinguishable from a wrong URL, by design —
WebhookInboxEndpoints.cs's own doc comment).the config was right — and they were, in the ConfigMap. Nothing checks the pod's env against it.
Fix
The chart only ever templated one indexed slot (
WebhookInbox__Targets__0), so a deploymentneeding a second webhook target had nowhere to put it except colliding on the same index by hand.
This PR adds
WebhookInbox__Targets__1as a real second slot indeploy/helm/templates/memex-portal/config.yaml(same index-by-index pattern asOpenRouter__Models__N/AzureFoundry__Models__N—EveryConfigKeySetInAValuesFile_IsBoundInTheConfigMaprequires each key spelled out explicitly, never a range) and documents both slots in
deploy/aks/values.aks.yaml.Companion overlay PR (private repo): Systemorph/Memex#121 — sets memex-cloud's
__0to matchwhat is actually live (
Store/Payments, so the ConfigMap stops asserting a value the pod silentlydiscards) and adds
__1 = Hosting/PlatformBuildson the slot the straykubectl set envnevertouched. Once both land, a
helm-release.ymldeploy ofmemexcloud(a separate, deliberate step —prod deploy is its own decision, not a side effect of this merge) restores delivery without needing
to touch the stray
env:entry on index 0 at all.Not fixed here, and doesn't need to be
kubectl set envon index 0 — harmless now that the overlay's__0matches it.memex/Memex.Portal.Shared/(out of scope for this session; another thread has itopen) —
WebhookInboxEndpoints.Deliverwas read closely and has no bug: allowlist check, "targetnode must exist" check, and the HMAC-verification-is-the-consumer's-job design are all correct as
written.
Verification
helm template memex ./deploy/helm -f ./deploy/helm/values.yaml -f ./deploy/aks/values.aks.yamlrenders both
WebhookInbox__Targets__0and__1correctly.PlatformBakeLaneGuard(test/MeshWeaver.Documentation.Test), includingEveryConfigKeySetInAValuesFile_IsBoundInTheConfigMapwhich exists specifically to catch anun-templated values key: 9/9 green, fresh
.trxafter a-c Release -warnaserrorbuild (0 Warning(s),0 Error(s)).kubectl get configmapvskubectl exec ... printenv) is the actual proofof the defect, gathered against the real memex-cloud pod, not inferred from the issue text.
#2235 stays open — MeshWeaver#2235's own stated close condition is unchanged: one promoted
build producing (a) a
repository_dispatchrun on all four satellite repos and (b) theMW_IMAGE_DIGESTbump PRs, observed after Memex#121 merges and a deploy runs. Never a green CDtick alone — that's exactly what this repo has looked like since 08-22.
Coordination
Checked
src/MeshWeaver.GitSyncfor the concurrent restructuring mentioned in the task brief — thisPR does not touch that project at all (nor
memex/Memex.Portal.Shared/, nor any of the otherstay-out directories); the fix is entirely in
deploy/helm/anddeploy/aks/.🤖 Generated with Claude Code