The Plugin Registry Serves Each Line
Policy major-lines-run-separately (the design page Major Lines Run Separately, §4b) runs the v3
and v4 platform lines side by side: core and every plugin repository keep main3 for v3 and main
for v4. The plugin registry has to follow: an instance whose record says updatePattern: "3.*" must be
listed and served each repository at its v3 ref, and an instance on "4.*" at main. A v3 instance
must never be offered a v4-only package version or v4 source.
This page records how the ref was chosen before lines existed, and the declaration that now chooses it.
How the ref was chosen before lines
- The record names ONE ref per git source. A registry record lists its git sources as
pluginRepos[]withisRegistrySource: trueand aref(PluginRepoMount.Ref, blank meansmain,PluginRepoMount.EffectiveRef). It renders asPluginCatalog:Sources:N:Ref(DeploymentPortalConfig.ConfigurationEntrieson the boot and Aspire routes; the chart'sPluginCatalog__Sources__N__Refon the Helm route, MeshWeaver.Deploytemplates/memex-portal/config.yaml). - The registry serves that ref to every caller.
PackageSources.FromConfigurationis the one reader of the sources (the registry endpoints, the default install, discovery and the update watcher all call it), and the/api/pluginslisting and/api/plugins/filesroutes (MeshWeaver.PluginsPluginRegistryEndpoints) readConfiguredPackageSource.GitRef. The consumer's own ref (PluginCatalog:Registries:N:Ref, defaultHEAD, sent as?ref=) is ADVISORY and ignored, except a full commit sha reachable from the configured ref (the snapshot token,ReadRef). - A consumer mount carries no ref.
PluginRepoMount.Refis documented "ignored by a consumer mount", and the chart renders the consumer'sRegistries:N:RefasHEAD. - The bundles are already per line. Prebuilt assemblies are fetched per framework identity
(
PluginBundleClientsends?identity=the running platform's live identity), and adoption accepts only a bundle of the running major (PrebuiltAdoptionPolicy,VersionStrictness.Family). The registry's bundle store is keyed by identity, not by git ref, so a v3 instance already receives only bundles built for its own compatibility key — the ref question is about the SOURCE files and the package LISTING alone.
So once MeshWeaver.Plugins main carries v4, every instance — v3 included — would be listed and served
v4 source.
The declaration: lineRefs on a registry source
A registry source declares the ref it is served at per line, on the record:
{
"name": "Plugins",
"url": "https://github.com/Systemorph/MeshWeaver.Plugins",
"ref": "main",
"lineRefs": { "3": "main3" },
"isRegistrySource": true
}
refstays the ref for every linelineRefsdoes not name (PluginRepoMount.RefForLine).- It is declared per repository, never derived from a branch-naming convention: a repository that has
no
main3yet is simply not given one, and keeps being served atref. - It renders NAME-keyed —
PluginCatalog:LineRefs:{source}:{major}={ref}— on the boot and Aspire routes (ConfigurationEntries) and through the Helm portal config's pass-through (DeploymentPortalConfig.PortalConfig), so neither route depends on the index the chart gives a source. A record that declares none renders exactly what it rendered before. Validaterefuses it on a consumer mount, for a line that is not a number, for a blank ref, and for two sources whose names key alike.
Who states which line
- A consumer states its line on every request.
RegistryPackageSource.Lineis read once from the instance's configuration (PlatformLine.Of): the explicitPluginCatalog:Linewhen set, else the major of the record'supdatePattern(SelfUpdate:DefaultPattern,3.*→ 3), else the major of the running platform version. It rides as&line=3on the listing and"line":"3"in the files body. When no line is known the request is byte-identical to the one sent before lines existed. - The registry serves each source at the caller's line.
ConfiguredPackageSource.ForLinemovesGitRefto the declared ref for that line, or back to the configured ref for a line nobody declared. The listing and the files route apply the SAME line, so a caller is never listed one line's package and served another line's files for it. - A caller that states no line runs an image older than the line-stating client. It is served
PluginCatalog:UnstatedCallerLinewhen the registry declares one, else the registry's OWN line. - In-process readers use the instance's own line.
FromConfigurationapplies the instance's own line, so on the registry itself the default install, module discovery and the update watcher read the repository at the ref of the line the registry runs.
Landing order
- Core: the record field, its rendering and the
PlatformLine/ForLinereader. Changes nothing for a record withoutlineRefs. - MeshWeaver.Plugins: the registry endpoints serve per line. It needs a platform floor at the first
sealed core set carrying step 1 (policy
request-min-version-wait-until-deployed). - The Memex records declare
lineRefs, once the control instance runs a build that reads the field and the registry runs step 2. Only repositories that already have theirmain3get an entry.
Until step 3 nothing in the fleet behaves differently.
What this does not cover
- Which commit a sealed bake publishes for a source is decided by the seal machinery
(The Sync-Ref Contract). Once
main3andmaindiverge, the v3 bundles must come from the v3 line's own build, as the design page's §4 says. This page does not change that path. - A consumer reads each registry through one mount, so the line is per INSTANCE, not per repository. A v3 instance that wants one v4 package is not a supported shape.