You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(install): the default install lands every module first, and a declared set installs only itself - #6737
The platform bootstrap: a FRESH instance whose image does not ship the store-delivered modules (a control image, Mesh:ClosedTypeSet=true) can now install the store from the registry.
1. Phase 1 — modules; phase 2 — nodes.InstanceAutoRegistrationService.LandModulesFirst lands the compiled module of every selected package that has no install record yet, BEFORE any package's nodes are written. Phase 2 (the node install, in dependency order) is subscribed only after every module of the selection has been decided.
Same gates the install funnel applies before a file travels: entitlement (with the deployment-config principal), the licence-acceptance gate, and declared parameters; the platform floor is the adoption's own floorHold. Each adoption is bounded by PerPackageAdoptBudget; the module set is proposed after every wave that decided a fresh carrier.
Fresh installs only: an installed package keeps its module on the funnel (after content, inside the floor and update-policy holds), so this never lands drift those holds gate. An unreadable install record is not treated as fresh.
Never fails the pass: the adoption absorbs its failures; a fault of the phase is logged at Error and the content phase runs as before.
The landing raises the pending-restart marker (restart-as-activation — a brand-new module is NotHeld); the pass after that restart finds Skill/Agent registered and installs Store first, then everything rooted on Store/Plugin. The "NodeType must be registered" validation is untouched — the first pass's content failures are FAILED with their cause and retried by the next pass.
DefaultInstallSummary.ModulesLanded + a MODULES LANDED ahead of content (load at the next restart): […] clause on the summary line.
2. A declared set installs only itself.PluginCatalogOptions.InstallPreInstalledPackages keeps its bool surface (reads true while unset); the new InstallPreInstalledPackagesConfigured (bool?) tells unset from true. Unset, the preInstalled baseline applies unless InstallByDefault declares an EXPLICIT set (every entry Source/Package, none Source/*); then exactly the named packages and their declared requires are selected. An explicit true/false still wins. A whole-source pattern (the chart default Plugins/*) or no patterns keeps the baseline exactly as before.
3. Docs:PluginAuthoring, the chart's installPreInstalledPackages comments, Doc/Architecture/PluginRegistry — new section The bootstrap: modules first, then nodes, and the InstallPreInstalledPackages bullet; EnvironmentComposition lane table; DeploymentContent.PreInstall summary.
Why (measured on a fresh control instance, 2026-10-13)
[DefaultInstall] installing package Store failed … NodeType(s) not registered: Skill
[DefaultInstall] installing package AI failed … NodeType 'Store/Plugin' is not registered
[DefaultInstall] reconciled with FAILURES: 0 installed, 0 up to date, 48 failed [Store, AI, Acp, …]
/data/modules empty. Store's nodes need Skill (the MeshWeaver.AI module, delivered by AI); AI's root and every other root are Store/Plugin (declared by Store); a module landed only after its own package's content validated (CatalogLayoutAreas.InstallOrUpdateCore → WithModule runs on the content's success). No entry point. The instance named five packages and the pass selected 48: every preInstalled package of the registry plus Store.
Tests
test/Memex.Portal.Shared.Test/StoreBootstrapLandsModulesFirstTest.cs, against an in-process registry serving the REAL wire shapes (listing, /files, bundle index, a module bundle with real assembly bytes) to the real RegistryPackageSource / PluginBundleClient:
StoreBootstrapLandsModulesFirstTest.AFreshImage_LandsEveryModuleFirst_AndSelectsOnlyTheDeclaredSet — reproduces the production errors verbatim (Install of 'AI' failed: NodeType 'Store/Plugin' is not registered, Store on Skill), and asserts all three modules landed with the pending-restart marker, and the selection is {Store, AI, EntityViews, Chat} without the unnamed preInstalledGames.
StoreBootstrapCompletesAfterTheRestartTest.OnceTheModulesLoad_OnePassInstallsTheStoreThenEverythingRootedOnIt — with Skill registered (the loaded module's stand-in), one pass delivers all four, Store before AI before Chat.
PreInstalledBaselineSelectionTest — the selection rule's truth table.
Negative controls (run locally, each reverted alone):
Module phase removed → Expected collection {} to equal {"Bootstrap.Test.AI", "Bootstrap.Test.Chat", "Bootstrap.Test.EntityViews"} (the sidecar stays empty — the production state).
Selection reverted to ?? true → Expected collection {"AI", "Chat", "EntityViews", "Games", "Store"} to equal {"AI", "Chat", "EntityViews", "Store"}.
Restored: 231/231 across every default-install / module-landing / floor-hold / install-record class in Memex.Portal.Shared.Test (48 classes); 830/830 MeshWeaver.Documentation.Test. Built -c Release -warnaserror: MeshWeaver.PluginCatalog, Memex.Portal.Shared.Test, MeshWeaver.Documentation.Test, MeshWeaver.Deployment.Contract.Test — 0 Error(s), 0 Warning(s).
Deploy notes
Behaviour change on the next boot of any instance whose InstallByDefault names packages exactly and does not set InstallPreInstalledPackages: the preInstalled baseline is no longer selected there. Nothing installed is removed; installed packages keep updating through the registry reconciler. Instances with a whole-source pattern (the chart default Plugins/*) are unchanged.
A fresh instance needs ONE restart after its first boot for the landed modules to load (the self-updater takes the pending-restart marker; where it cannot roll, any restart does).
…lared set installs only itself
A fresh instance whose image ships none of the store-delivered modules could not install the store:
Store's nodes need Skill (registered by the MeshWeaver.AI module that AI delivers), AI's root is typed
Store/Plugin (declared by Store), and a mixed package's module landed only after its own content had
validated. Every install failed validation, no module ever reached the volume, and no restart could
register the types (measured on a fresh control instance: 0 installed, 48 failed, /data/modules empty).
Phase 1 of the default install now lands the module of every selected, not-yet-installed package
BEFORE any package's nodes are written (entitlement and parameter gates applied first; the floor is
the adoption's own hold). The landing raises the pending-restart marker; the pass after that restart
finds Skill/Agent registered and installs Store first, then everything rooted on Store/Plugin, in the
order the declared requires already derive. The "NodeType must be registered" validation is unchanged.
Selection: PluginCatalog:InstallPreInstalledPackages is now nullable. Unset, the preInstalled
baseline applies unless InstallByDefault declares an explicit set (Source/Package entries only) — a
deployment that names its packages gets those and their requires, not every preInstalled package of
the registry on top. An explicit true/false still wins.
Pinned by StoreBootstrapLandsModulesFirstTest / StoreBootstrapCompletesAfterTheRestartTest /
PreInstalledBaselineSelectionTest against an in-process registry serving the real wire shapes.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 3e0f65f: PluginAuthoring.md, the chart's config.yaml comment and values.yaml comment now describe the unset rule (applies unless installByDefault names an explicit Source/Package set; true/false always wins).
…fault entry keeps the baseline; assert modules download before any content; decisions cited by policy id (default-install-modules-first, declared-package-set-is-exact)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The adoption timeout does not cover this preceding install-record read. If storage never emits, the sequential Concat cannot advance and phase 2 is never subscribed, so one wedged record read blocks every module and all package content instead of being isolated as an unreadable record. Apply the established install-record read budget before the catch so the pass can continue.
Clarify baseline suppression when InstallPreInstalledPackages is false
The final sentence is unconditional, but an explicit PluginCatalog:InstallPreInstalledPackages=false suppresses the baseline even when PreInstall is empty or contains a whole-source pattern. Qualify this as the unset-key behavior so the public contract does not contradict the explicit override.
Document InstallByDefault relationship for unset behavior
The introduction at line 90 still says these two keys are independent, but the new unset behavior here explicitly derives the baseline from InstallByDefault. That contradiction can make operators assume an explicit package set still retains the baseline; update the introduction to acknowledge the relationship.
Modules are adopted before Install() evaluates the partition-ownership holds. An unproven registry ref or a proven source targeting another repository can therefore land and propose its module here even though lines 2451-2478 later return HoldForThePartitionsOwnWriter without fetching content; that hold's existing contract explicitly says “no module is adopted” (line 2529). Apply the ownership verdict before admitting a carrier so code cannot load without its matching held content.
…tInstallSummary.ModuleSetVerdict), not a store the reconciler's own wave close also writes
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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
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
The platform bootstrap: a FRESH instance whose image does not ship the store-delivered modules (a control image,
Mesh:ClosedTypeSet=true) can now install the store from the registry.1. Phase 1 — modules; phase 2 — nodes.
InstanceAutoRegistrationService.LandModulesFirstlands the compiled module of every selected package that has no install record yet, BEFORE any package's nodes are written. Phase 2 (the node install, in dependency order) is subscribed only after every module of the selection has been decided.floorHold. Each adoption is bounded byPerPackageAdoptBudget; the module set is proposed after every wave that decided a fresh carrier.NotHeld); the pass after that restart findsSkill/Agentregistered and installsStorefirst, then everything rooted onStore/Plugin. The "NodeType must be registered" validation is untouched — the first pass's content failures are FAILED with their cause and retried by the next pass.DefaultInstallSummary.ModulesLanded+ aMODULES LANDED ahead of content (load at the next restart): […]clause on the summary line.2. A declared set installs only itself.
PluginCatalogOptions.InstallPreInstalledPackageskeeps itsboolsurface (reads true while unset); the newInstallPreInstalledPackagesConfigured(bool?) tells unset from true. Unset, thepreInstalledbaseline applies unlessInstallByDefaultdeclares an EXPLICIT set (every entrySource/Package, noneSource/*); then exactly the named packages and their declaredrequiresare selected. An explicittrue/falsestill wins. A whole-source pattern (the chart defaultPlugins/*) or no patterns keeps the baseline exactly as before.3. Docs:
PluginAuthoring, the chart'sinstallPreInstalledPackagescomments,Doc/Architecture/PluginRegistry— new section The bootstrap: modules first, then nodes, and theInstallPreInstalledPackagesbullet;EnvironmentCompositionlane table;DeploymentContent.PreInstallsummary.Why (measured on a fresh control instance, 2026-10-13)
/data/modulesempty.Store's nodes needSkill(theMeshWeaver.AImodule, delivered byAI);AI's root and every other root areStore/Plugin(declared byStore); a module landed only after its own package's content validated (CatalogLayoutAreas.InstallOrUpdateCore→WithModuleruns on the content's success). No entry point. The instance named five packages and the pass selected 48: everypreInstalledpackage of the registry plusStore.Tests
test/Memex.Portal.Shared.Test/StoreBootstrapLandsModulesFirstTest.cs, against an in-process registry serving the REAL wire shapes (listing,/files, bundle index, a module bundle with real assembly bytes) to the realRegistryPackageSource/PluginBundleClient:StoreBootstrapLandsModulesFirstTest.AFreshImage_LandsEveryModuleFirst_AndSelectsOnlyTheDeclaredSet— reproduces the production errors verbatim (Install of 'AI' failed: NodeType 'Store/Plugin' is not registered, Store onSkill), and asserts all three modules landed with the pending-restart marker, and the selection is{Store, AI, EntityViews, Chat}without the unnamedpreInstalledGames.StoreBootstrapCompletesAfterTheRestartTest.OnceTheModulesLoad_OnePassInstallsTheStoreThenEverythingRootedOnIt— withSkillregistered (the loaded module's stand-in), one pass delivers all four,StorebeforeAIbeforeChat.PreInstalledBaselineSelectionTest— the selection rule's truth table.Negative controls (run locally, each reverted alone):
Expected collection {} to equal {"Bootstrap.Test.AI", "Bootstrap.Test.Chat", "Bootstrap.Test.EntityViews"}(the sidecar stays empty — the production state).?? true→Expected collection {"AI", "Chat", "EntityViews", "Games", "Store"} to equal {"AI", "Chat", "EntityViews", "Store"}.Restored: 231/231 across every default-install / module-landing / floor-hold / install-record class in
Memex.Portal.Shared.Test(48 classes); 830/830MeshWeaver.Documentation.Test. Built-c Release -warnaserror:MeshWeaver.PluginCatalog,Memex.Portal.Shared.Test,MeshWeaver.Documentation.Test,MeshWeaver.Deployment.Contract.Test—0 Error(s),0 Warning(s).Deploy notes
InstallByDefaultnames packages exactly and does not setInstallPreInstalledPackages: thepreInstalledbaseline is no longer selected there. Nothing installed is removed; installed packages keep updating through the registry reconciler. Instances with a whole-source pattern (the chart defaultPlugins/*) are unchanged.Store/Plugin) on a closed type set once installer-side NodeType rows are withheld (Closed type set: package installer holds no NodeType rows; #6349 retry skips the closed-set refusal (#6627) #6670, open) — phase 1 lands the modules either way, which is what/healthrequired_modulesreads.Implementers: none — no interface member added.
Pairs-with: none — additive only:
PluginCatalogOptions.InstallPreInstalledPackagesConfigured,DefaultInstallSummary.ModulesLanded(init);CatalogLayoutAreas.ProposeMeshModuleSetprivate → internal.🤖 Generated with Claude Code