Skip to content

fix(cloud-connection): move install-local outside the cloud ternary in README example - #8419

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-8355-cloud-connection-readme-wiring
Aug 13, 2026
Merged

fix(cloud-connection): move install-local outside the cloud ternary in README example#8419
os-zhuang merged 2 commits into
mainfrom
claude/issue-8355-cloud-connection-readme-wiring

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#8355

packages/cloud-connection/README.md stated the air-gapped contract correctly in prose
— "OS_CLOUD_URL=off disables every remote call; air-gapped installs keep working via
inline manifests handed to install-local" — while the code example a few lines above
did the opposite: MarketplaceInstallLocalPlugin sat inside the cloudUrl ? ternary,
so OS_CLOUD_URL=off unmounted the very surface the prose promised keeps working.
cloud's apps/objectos-ee/objectstack.config.ts was a faithful copy of this recipe —
the measured propagation vector for the #8343 P1 (a self-hosted deployment that could
not install a package by any route).

What changed

  • MarketplaceInstallLocalPlugin moves outside the cloudUrl ? ternary and is
    constructed with cloudUrl || 'off' instead of the bare cloudUrl/''. The plugin
    re-resolves whatever it is handed through resolveCloudUrl(), which treats '' as
    unset and substitutes the public DEFAULT_CLOUD_URL — so passing the empty string
    through would have pointed an air-gapped runtime's catalog branch at the public cloud
    instead of disabling it. 'off' is one of the documented disable sentinels
    (packages/cloud-connection/src/cloud-url.ts) and is the value that actually resolves
    to no cloud. This trap is a property of config resolution, untouched by fix(cloud-connection): derive features.marketplace from what is actually mounted (#8356) #8387.
  • RuntimeConfigPlugin now mounts unconditionally too (it already sat outside the
    ternary). This was previously a second trap on its own — the plugin used to hardcode
    features.marketplace: true, so mounting it on a cloud-less runtime would have
    advertised catalog browse it could not serve. fix(cloud-connection): derive features.marketplace from what is actually mounted (#8356) #8387 (merged) derives
    features.marketplace from what is actually mounted on the kernel serving the
    response, so a cloud-less runtime now reports marketplace: false on its own with
    nothing for a host config to keep in sync. That trap is retired; the corrected example
    reflects it.
  • The ternary now keeps only the genuinely cloud-gated halves —
    MarketplaceProxyPlugin and CloudConnectionPlugin, which are the control-plane
    client and need a resolved URL as their precondition.

Each line carries an inline comment explaining why it is (or isn't) inside the ternary,
so the recipe doesn't get silently miscopied again.

Verification

Read (not modified) to confirm the corrected shape:

  • packages/cli/src/commands/serve.ts (Serve.planMarketplaceWiring,
    Serve.OFFLINE_CONTROL_PLANE) — the OS_CLOUD_URL=off unmounts the air-gapped install-local endpoint — the offline install path is gated on the cloud URL it is designed not to need #8343 reference implementation. It confirmed the
    'off'-sentinel trap and the disable-sentinel spelling; note serve.ts's own
    offlineInstallLocal arm does not yet mount RuntimeConfigPlugin (a separate,
    already-filed and already-dispatched gap — a worktree for it exists alongside this
    one), so this PR's example is the documented recipe the Suggested Shape asked for,
    not a byte-for-byte mirror of serve.ts's current CLI wiring branches.
  • packages/cloud-connection/src/cloud-url.tsresolveCloudUrl()'s disable sentinels
    (off/none/local/disabled) and the ''-means-unset behavior.
  • packages/cloud-connection/src/runtime-config-plugin.ts — confirmed
    features.marketplace is derived via hasMarketplaceBrowseMount(rawApp) (fix(cloud-connection): derive features.marketplace from what is actually mounted (#8356) #8387,
    merged 631ddbf36), and that RuntimeConfigPluginConfig.controlPlaneUrl: '' is
    handled as an intentional "stay on this origin" case in this plugin specifically
    (different from the two Marketplace plugins' resolveCloudUrl re-resolution) — so the
    existing controlPlaneUrl: '' on RuntimeConfigPlugin was already correct and is
    unchanged.
  • The four plugins' config interfaces (MarketplaceProxyPluginConfig,
    MarketplaceInstallLocalPluginConfig, CloudConnectionPluginConfig,
    RuntimeConfigPluginConfig) — confirmed controlPlaneUrl/singleEnvironment/
    installLocal are the real prop names the example uses.
  • Typechecked the corrected snippet against the package's real source (copied into
    packages/cloud-connection/src/ as an untracked scratch file importing from
    ./index.js, deleted before this diff was committed) with
    npx tsc --noEmit -p tsconfig.json — 0 errors. So the example is verified runnable
    against the real constructors, not merely illustrative.

Docs-only. skip-changeset applied (docs change, nothing to release).

Out of scope (named in the dispatch brief, not touched here)

Generated by Claude Code


Generated by Claude Code

…n README example
The README's air-gapped contract prose ("OS_CLOUD_URL=off disables every
remote call; air-gapped installs keep working via inline manifests handed
to install-local") was contradicted by its own code example a few lines
above: MarketplaceInstallLocalPlugin sat inside the cloudUrl ? ternary, so
OS_CLOUD_URL=off unmounted the very surface the prose promised keeps
working. cloud's apps/objectos-ee/objectstack.config.ts was a faithful
copy of this recipe -- the measured propagation vector for #8343's P1.
- MarketplaceInstallLocalPlugin moves outside the ternary, constructed
with `cloudUrl || 'off'` rather than the bare cloudUrl/''. The
constructor re-resolves whatever it is given through resolveCloudUrl(),
which reads '' as unset and substitutes the public DEFAULT_CLOUD_URL --
'off' is a real disable sentinel and is the value that actually
resolves to no cloud.
- RuntimeConfigPlugin now mounts unconditionally without a caveat: #8387
(merged) derives features.marketplace from what is actually mounted, so
a cloud-less runtime reports marketplace: false on its own.
- The ternary keeps only the genuinely cloud-gated halves
(MarketplaceProxyPlugin, CloudConnectionPlugin).
Fixes#8355
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P7vaLs7bhBPi9m3JyzkhDj
@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 13, 2026 12:29pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/cloud-connection.

1 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/protocol/kernel/metadata-service.mdx(via @objectstack/cloud-connection)

1 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx(via @objectstack/cloud-connection)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@github-actionsgithub-actionsBot added the documentation Improvements or additions to documentation label Aug 13, 2026
@os-zhuangos-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 13, 2026 — with Claude
…ke its neighbor
The corrected example now has two spellings of "no cloud" two lines apart
with no stated reason: MarketplaceInstallLocalPlugin needs the explicit
'off' sentinel, RuntimeConfigPlugin keeps ''. Unexplained, a reader could
"normalise" either direction -- including changing install-local back to
'', which reproduces the exact defect this card exists to remove.
Add a one-line comment: RuntimeConfigPlugin does not re-resolve
controlPlaneUrl through resolveCloudUrl(), so '' means "stay on this
origin" here rather than "unset" -- the asymmetry is deliberate, not a
leftover copy-trap.
Part of #8355
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P7vaLs7bhBPi9m3JyzkhDj
@os-zhuang
os-zhuang marked this pull request as ready for review August 13, 2026 12:47
@os-zhuang
os-zhuang added this pull request to the merge queueAug 13, 2026
Merged via the queue into main with commit 3db3795Aug 13, 2026
26 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-8355-cloud-connection-readme-wiring branch August 13, 2026 13:04
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cloud-connection README's wiring example gates install-local on the cloud URL — the recipe that propagated #8343 into the EE image

2 participants

@os-zhuang@claude