feat(deploy): make the plugin catalog configurable from the chart, and skill the deployment ramp-up - #829
Merged
Merged
Conversation
…ill the deployment ramp-up Ramping up a new deployment "including plugins" was not actually executable from config: deploy/helm/templates/memex-portal/config.yaml templated exactly ONE plugin key (PluginCatalog__AutoUpdateByDefault), and per the chart's own documented trap anything it does not template is silently dropped. So the live registry config on memex-cloud is a hand-applied `kubectl set env` that no redeploy reproduces — and the token list, never applied, leaves https://memex.meshweaver.cloud/api/plugins answering ANY anonymous caller with 28 packages from the private Plugins + education repos AND their file content. Chart (root-cause fix, not a patch): - values.yaml gains `pluginCatalog` — registryUrl / registryRef (consumer), registries[] (multi-registry consumer), sources[] (registry: the git repos it serves) — and secrets.memex_portal gains PluginCatalog__RegistryToken + __RegistryTokens. - config.yaml + secrets.yaml template them, so a values overlay now reproduces exactly the env vars memex-cloud carries by hand. Verified with `helm template` empty and populated, and `helm lint`. Skills: - .claude/skills/new-deployment — stand up a new deployment: the two orderings that fail SILENTLY (federated-credential subject before deploy, DNS before TLS), the silent-failure traps, cold-compile verification, and registering the deployment on the PRIVATE Systemorph/Memex repo. - .claude/skills/plugins — registry vs consumer wiring, token issuance, the anonymous-registry audit, and troubleshooting rooted in the un-templated-key cause above. Docs: OnboardingNewEnvironment.md gains the plugins step it never had. .gitignore: anchor `plugins/` -> `/plugins/`. Unanchored it matches at every depth, and on macOS's case-insensitive filesystem it also matched `Plugins/` — silently dropping every NEW file under src/MeshWeaver.AI/Plugins/ (its 12 existing files predate the rule, which is why nobody noticed) and blocking .claude/skills/plugins/ entirely. No What's New entry: operator/agent-facing only, no portal-user-visible change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01398UXRgmg2E3xS7xkTHdAo
Contributor
There was a problem hiding this comment.
Pull request overview
Enables MeshWeaver portal deployments to configure the Plugin Catalog purely via Helm chart values/templates (instead of hand-applied kubectl set env), and adds operator/agent runbooks (“skills”) plus onboarding documentation covering plugin wiring and new-environment ramp-up.
Changes:
- Adds a
pluginCatalogvalues block and templates plugin catalog settings/tokens into the portal ConfigMap/Secret. - Adds new
/new-deploymentand/pluginsskills and updates onboarding documentation with a plugins wiring step. - Fixes
.gitignoreto only ignore the repo-root/plugins/directory (not nestedplugins//Plugins/paths).
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/MeshWeaver.Documentation/Data/Architecture/OnboardingNewEnvironment.md | Adds a “Plugins” onboarding step with example Helm values/secrets. |
| deploy/helm/values.yaml | Introduces pluginCatalog configuration and plugin catalog secret placeholders in chart values. |
| deploy/helm/templates/memex-portal/secrets.yaml | Templates plugin catalog token secrets into the rendered Kubernetes Secret. |
| deploy/helm/templates/memex-portal/config.yaml | Templates plugin catalog registry/source configuration into the rendered ConfigMap. |
| .gitignore | Anchors /plugins/ ignore rule to avoid unintended ignores at other depths/casing. |
| .claude/skills/plugins/SKILL.md | Adds an operator skill describing consumer vs registry setup and troubleshooting. |
| .claude/skills/new-deployment/SKILL.md | Adds a deployment ramp-up skill (ordering, traps, verification, registration). |
Suppressed comments (1)
.claude/skills/plugins/SKILL.md:61
- The skill’s “several registries” example omits how to provide instance tokens per registry. For token-gated registries, consumers must set
PluginCatalog:Registries:N:Token(or they’ll get 401s); PluginRegistry.md calls this out explicitly.
pluginCatalog:
registries:
- {name: Plugins, url: "https://memex.meshweaver.cloud"}
- {name: Education, url: "https://<other-registry>"}
</details>
---
💡 <a href="/Systemorph/MeshWeaver/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
Comment on lines
+236
to
+239
| PluginCatalog__Sources__{{ $i }}__Name: "{{ $s.name }}" | ||
| PluginCatalog__Sources__{{ $i }}__RepoPath: "{{ $s.repoPath }}" | ||
| PluginCatalog__Sources__{{ $i }}__Ref: "{{ $s.ref | default "main" }}" | ||
| PluginCatalog__Sources__{{ $i }}__Format: "{{ $s.format | default "node-repo" }}" |
Comment on lines
+63
to
+65
| {{- range $i, $t := .Values.secrets.memex_portal.PluginCatalog__RegistryTokens }} | ||
| PluginCatalog__RegistryTokens__{{ $i }}: "{{ $t }}" | ||
| {{- end }} |
Comment on lines
+31
to
+34
| | Holds git credential | ✅ | ❌ never | | ||
| | Helm values | `pluginCatalog.sources` | `pluginCatalog.registryUrl` (or `.registries`) | | ||
| | Secret | `PluginCatalog__RegistryTokens` (the list it **accepts**) | `PluginCatalog__RegistryToken` (the one it **sends**) | | ||
| | Today | `memex-cloud` | every other deployment | |
Comment on lines
+239
to
+242
| # Plugin catalog. Consumer: the instance token issued to this install. Registry: the list of | ||
| # tokens it accepts (empty list = serves ANY anonymous caller — dev/e2e only). | ||
| PluginCatalog__RegistryToken: "" | ||
| PluginCatalog__RegistryTokens: [] |
Comment on lines
+110
to
+112
| NEW=$(kubectl -n <env> get pods -l app.kubernetes.io/component=memex-portal \ | ||
| --sort-by=.metadata.creationTimestamp -o jsonpath='{.items[-1:].metadata.name}') | ||
| kubectl -n <env> logs "$NEW" | grep "DynamicTypePreWarmer: warm-up complete" |
This was referenced Aug 6, 2026
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.
Follow-on from removing the GitHub Deployment records from this public repo (they named
atioz/memex/memex-cloudand were leftovers from the central deploy job deleted 2026-06-29). The deployment inventory + ramp-up runbook now live in the privateSystemorph/Memexrepo (PR #19, merged). This PR is the mechanism half that belongs here.The defect this fixes
Ramping up a deployment "including plugins" was not executable from config.
deploy/helm/templates/memex-portal/config.yamltemplated exactly one plugin key —PluginCatalog__AutoUpdateByDefault— and per the chart's own documented trap, anything it does not template is silently dropped.Consequences, verified live:
memex-cloud's registry config exists only as hand-appliedkubectl set envvars on the Deployment. No redeploy reproduces them; ahelm upgradewould drop them.memexandatiozhave no plugin config at all.https://memex.meshweaver.cloud/api/pluginsreturns HTTP 200 with 28 packages to an unauthenticated caller, andPOST /api/plugins/filesreturns full file content — from the privateMeshWeaver.Pluginsandeducationrepos, including paid course content.PluginRegistry.mdcalls an emptyRegistryTokenslist the local-dev/e2e stub mode; a production registry must always configure tokens.This PR makes the fix possible; it does not apply it. Rolling tokens is a live prod change and needs consumer-token-first ordering, or every consumer loses its catalog in the gap.
Changes
Chart —
values.yamlgains apluginCatalogblock (registryUrl,registryRef,registries[]for consumers;sources[]for a registry) andsecrets.memex_portalgainsPluginCatalog__RegistryToken/__RegistryTokens.config.yamlandsecrets.yamltemplate them. A values overlay now reproduces exactly the env varsmemex-cloudcarries by hand.Verified with
helm lintandhelm templateboth empty (3 keys, no stray indices) and populated (renders the full indexedSources__N__*/Registries__N__*/RegistryTokens__Nsets), plus the AKS overlay unchanged.Skills —
.claude/skills/new-deployment/(the two orderings that fail silently: federated-credential subject before deploy, DNS before TLS; the silent-failure traps; cold-compile verification; registering the deployment on the private repo) and.claude/skills/plugins/(registry vs consumer wiring, token issuance, the anonymous-registry audit, troubleshooting rooted in the un-templated-key cause).Docs —
OnboardingNewEnvironment.mdgains the plugins step it never had..gitignore— anchorplugins/→/plugins/. Unanchored it matches at every depth, and on macOS's case-insensitive filesystem it also matchedPlugins/: a new file undersrc/MeshWeaver.AI/Plugins/is silently untracked today (its 12 existing files predate the rule, which is why this went unnoticed), and.claude/skills/plugins/was blocked entirely.Verification
helm lintclean ·helm templatecorrect empty + populated + with the AKS overlayDocumentationLinkIntegrityTest— passeddotnet build src/MeshWeaver.Documentation -c Release -warnaserror— 0 warnings, 0 errorsNo What's New entry — operator/agent-facing only, no portal-user-visible change.
🤖 Generated with Claude Code
https://claude.ai/code/session_01398UXRgmg2E3xS7xkTHdAo