Repository navigation
fix(operator): hosting-deploy refuses a vault values half that carries structure (Memex#295) - #5700
Merged
Merged
Conversation
…rries structure (Memex#295) The operator layers helm-values-<release> FIRST and the record's render LAST. helm replaces a list the later file names and leaves one it omits, and HelmValues omits an empty list, so a legacy extraVolumes/extraVolumeMounts/extraEnvFrom left in the half deployed beside the record's own keyVaultSecretClasses wiring: the memex V58 Reconcile failed at helm upgrade with "Job memex-migration-62 invalid: duplicate volume kv-secrets". A structural map merges instead and silently supplies every leaf the render does not name. hosting-deploy now reads only the half's top-level key NAMES and refuses, before helm and naming them, any key outside secrets/parameters/pgbackrest (the allow-list the config repo's capture and lane guard share), an unreadable half, and a half holding none of the families. The remedy it names is a governed HelmRelease capture. Checked against both real halves (key names only): memex passes (pgbackrest, secrets); memex-cloud is refused until it is re-captured. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Three moderate validation edge cases remain unresolved in hosting-deploy.
Review effort: Lite
Findings: None
What changed in this PR
Adds pre-Helm validation for Key Vault values halves, restricting them to approved secret families and documenting the recapture workflow.
Changes:
- Added YAML/JSON structure and family validation.
- Added regression tests for accepted and rejected formats.
- Documented the values-half contract.
| File | Summary |
|---|---|
src/MeshWeaver.Documentation/Data/Architecture/DeploymentEnvLayers.md |
Documents the values-half contract. |
deploy/aks/operator/test/run-tests.sh |
Tests validation behavior and edge cases. |
deploy/aks/operator/bin/hosting-deploy |
Validates vault values before Helm execution. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Contributor
Contributor
Contributor
Contributor
Contributor
Contributor
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
hosting-deploy(the operator's Provision/Reconcile path) layers the Key Vault values halfhelm-values-<release>FIRST and the record's render LAST. It now reads the half's top-level key names (never a value) and refuses, before helm and naming them:secrets,parameters,pgbackrest(the same allow-list the Memex lane'scapturestores and its guard reads,scripts/vault-values.pyVAULT_FAMILIES);The refusal names the remedy: a governed
HelmReleaseaction withhelmAction: capture.Why
On 2026-09-25 the V58 Reconcile of
memexfailed athelm upgrade:Job memex-migration-62 invalid: duplicate volume "kv-secrets". The half still carried legacyextraVolumes/extraVolumeMounts/extraEnvFrom. helm replaces a list the later file names and leaves one it omits.HelmValues.Renderomits an empty list (the memex overlay writesextraVolumes: [], but the render writes no key), so the vault's list deployed beside the record'skeyVaultSecretClasseswiring. A structural map merges instead, and silently supplies every leaf the render omits. This is C4 of Memex#295 on the operator path. The lane already has its own switch.I did not change the render to emit
[]. With structure refused at the only earlier layer, an omitted list falls to the chart default, so there is nothing left to override.HelmValuesTestsalso asserts the no-legacy-lists shape on purpose.Verified
deploy/aks/operator/test/run-tests.sh: 601 passed, 0 failed. The new cases cover: a structural list refused before helm and named, with no value echoed; a structural map; families-only accepted (quoted keys, comments); JSON accepted and refused; a top-level list refused as unreadable; a family-less half refused.helm-values-memexgivespgbackrest secrets(passes, post-capture).helm-values-memexcloudgives 14 keys includingconfig image ingress …(refused), which matches a PyYAML read of the same files. PyYAML's indentless sequences (- name:at column 0 under a key) are handled.Rollout consequence
This takes effect when an operator image carrying it runs. From then on, memex-cloud's Reconcile refuses until its half is re-captured. The capture is safe: I measured it against a local
HelmValues.Renderof the live record, and every vault-only leaf is inert (image.*andingress.tls.*are not read by the chart, andportal.image/migration.imageare--setby this script). Doc:Architecture/DeploymentEnvLayers→ "The half carries secret families only".Pairs-with: none — no public C# surface is touched (bash operator script, its test, one doc page).
🤖 Generated with Claude Code