Uh oh!
There was an error while loading. Please reload this page.
fix(cli): mount RuntimeConfigPlugin on the offline marketplace arm so an air-gapped runtime's install-local route is discoverable (#8389) - #8431
Conversation
…8389) An `OS_CLOUD_URL=off` runtime had a working `/api/v1/marketplace/install-local` route and served no `/api/v1/runtime/config` at all, so the Console could not learn the route existed and rendered no install affordance for a capability that works. #8343 could not mount RuntimeConfigPlugin here because the plugin hardcoded `features.marketplace: true` — reporting install-local truthfully would have asserted a browse capability definitively absent on a proxy-less runtime. #8356 derived that flag from the serving app's route table, which removes the constraint. The mount is guarded like its neighbour: `kernel.use` keys by name, so an unguarded mount would REPLACE a host's own instance and drop its branding and `resolveFeatures` policy. The two offline guards are independent, so a host providing only one surface still gets the other. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P7vaLs7bhBPi9m3JyzkhDj
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 17 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 3 release-owned page(s) also reference the affected code. These are read-only:
|
Uh oh!
There was an error while loading. Please reload this page.
Fixes#8389
An
OS_CLOUD_URL=offruntime had a working/api/v1/marketplace/install-localroute and served no
/api/v1/runtime/configat all. From the Console's sidethat is indistinguishable from "the feature does not exist": it cannot learn the
route is there, and renders no install affordance for a capability that works.
#8343 mounted install-local alone on purpose, not carelessly.
RuntimeConfigPluginhardcoded
features.marketplace: true, so reporting install-local truthfully wouldhave asserted a browse capability definitively absent on a proxy-less runtime —
trading the reported bug for its mirror image. #8356 (PR #8387) removed that
constraint by deriving
features.marketplacefrom the route table of the appserving the response. That is what unblocks this mount, and it is why this is
completion of #8343's ruled outcome rather than a new decision.
What changed
packages/cli/src/commands/serve.tsonly.planMarketplaceWiringgains a third flag,offlineRuntimeConfig, and theoffline arm mounts
RuntimeConfigPluginunder it. The decision stays in the purestatic for the reason that function's own doc gives: the call site sits deep
inside
run()behind a dynamic import, where observing a mounting rule meansbooting a kernel.
gate. A host that wires its own install-local (so the existing rule leaves it
alone) may still have no runtime-config at all — that box has this defect in
full, and one shared gate would silently exclude it.
Kernel.use()doesthis.plugins.set(name, meta), so an unguarded mount does not double-mount, itreplaces — and
RuntimeConfigPlugincarries the host's branding and theopen-core
resolveFeaturesseam, so the replacement would answer with frameworkdefaults and no distribution policy. New
RUNTIME_CONFIG_IDENTITIES+ a driftcheck, mirroring
INSTALL_LOCAL_IDENTITIES.RUNTIME_CONFIG_OPTIONS. The difference between the arms must come from what ismounted (the derived
marketplaceflag), never from a second copy of theoptions drifting away from the first.
Note the two neighbouring mounts in this arm deliberately spell "no cloud"
differently:
RuntimeConfigPluginspecial-casescontrolPlaneUrl: ''as "stay onthis origin", while
MarketplaceInstallLocalPluginre-resolves what it is handedand would substitute the public default cloud, hence
OFFLINE_CONTROL_PLANE.Harmonising them in either direction breaks one of them; both are commented and one
is pinned.
The pin is written against the served payload
packages/cli/test/serve-marketplace-offline-runtime-config.test.tsreads the bodyout of the really-mounted handler and asserts
installLocal: trueandmarketplace: false. It deliberately does not assert "the constructor was handedinstallLocal: true": #8388 makesfeatures.installLocalderived the same waymarketplacenow is, keeping the constructor option only as an explicit override,so a pin on the mechanism would break when it lands and a pin on the payload will
not. #8388 is not addressed here.
marketplace: falseis the assertion most at risk of being vacuous — a runtimeserving nothing would also "report" false. Three guards:
/api/v1/runtime/configwas never registered, so"nothing served" can never read as a passing
false;installLocal: true, which an unservedpayload cannot do;
MarketplaceProxyPluginon the same appand requires
marketplace: true, proving the flag is observed and not pinnedfalse by the fixture.
Ablation, run from the committed state: reverting
serve.tstoorigin/mainturns11 of 11 cases red, and the acceptance case dies on
THE #8389 DEFECT: nothing mounted GET /api/v1/runtime/config, not on afalse-looking
false. Restored from the commit, all 20 cases across both offlinefiles pass again.
Verification
packages/clifull suite: 117 files, 1276 tests, all passed.pnpm --filter @objectstack/cli typecheckclean.scripts/pm/dispatch-gates.mjs(the dispatch prompt named none):
check:changeset-gate-self-tests,check:cross-package-test-inputs,check:objectui-changeset,check:startup-registry-verdict,check:query-options-erasure,check:type-check-coverage,check:type-check-debt,check-changeset-no-major.mjs,check:nul-bytes— all green.check:objectui-pin-freshreports a stale.objectui-sha. Pre-existing repostate, not from this branch:
.objectui-shais not in this diff, so the gate'sinputs are identical to
origin/main.Scope
packages/cloud-connectionis untouched — that is #8388's file surface. The cloudarm's own unguarded mounts are out of scope: already filed as #8357, which names
RuntimeConfigPluginexplicitly, and making the host win there is a real behaviourchange for connected runtimes.
Generated by Claude Code