Repository navigation
fix(cloud-connection): report the release discovery reports as runtime_version when OS_RUNTIME_VERSION is unset - #24231
Conversation
…e_version when OS_RUNTIME_VERSION is unset bind/start's approval links and bind/poll's registration claim sent the plugin's own version field (0.3.0) when OS_RUNTIME_VERSION was unset. Both now read the version from the discovery document through the protocol service at handler time; a set OS_RUNTIME_VERSION still wins verbatim, and a missing or failing discovery read sends no version instead of a wrong one. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVm1pAXVXQ3PjC42j1kPFf
📓 Docs Drift CheckThis PR changes 1 package(s): 7 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 4 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 26d288179ee318c482e68c152fd3eb6b26008d24 && git checkout 26d288179ee318c482e68c152fd3eb6b26008d24
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 6e43b7bc3f8cec05e65e200f28c9e6074c585228 a217f4bc6ca7f32a49d55069e0488a112c6ee906 && git checkout -B drift-repro 6e43b7bc3f8cec05e65e200f28c9e6074c585228 && git merge --no-ff a217f4bc6ca7f32a49d55069e0488a112c6ee906
node scripts/docs-audit/affected-docs.mjs --json 6e43b7bc3f8cec05e65e200f28c9e6074c585228
|
席位核对 — ACCEPT ·
|
Fixes #24150
Clause-②: no
What changed
CloudConnectionPluginsends the server's version to the cloud at two sites:runtime_versionon the approval linksPOST /api/v1/cloud-connection/bind/startreturns (the page the approver reads), andruntime_versionin the registration claimPOST /api/v1/cloud-connection/bind/pollsends to the control plane's/bind. WithOS_RUNTIME_VERSIONunset, both sent the plugin's ownversionfield,'0.3.0'.Both sites now call one closure,
reportedRuntimeVersion(), defined inside thekernel:readyhook besidecredential():OS_RUNTIME_VERSION: sent verbatim, with the same??set-ness as before (a set but empty value still sends nothing).ctx.getService('protocol').getDiscovery()when the handler runs and sends that document'sversion, the fieldGET /api/v1/discoveryserves. The value is read per call and not cached atinit.protocolservice, orgetDiscovery()throws): nothing is sent. The approval links get noruntime_versionparameter and the bind body gets noruntime_versionkey.The plugin's own
readonly version = '0.3.0'stays, because it is the plugin's version. No dependency was added and no export either. Nopackages/metadata-protocolpath is touched, andresolveDiscoveryVersionis neither imported nor copied. The#renameparagraph ofcontent/docs/deployment/cloud-connection.mdxnow says the version is the release discovery reports, and thatOS_RUNTIME_VERSIONis an override.Mechanism assumptions, measured
GET /api/v1/discovery, and do the two agree? Measured on a realpnpm dev -- --fresh -p PORTboot ofexamples/app-showcaseatc90a9776d(mainb9ac35cbfplus this diff).OS_RUNTIME_VERSIONwas unset andOS_CLOUD_URLpointed at a stand-in control plane on loopback.GET /api/v1/discoveryanswered unenveloped and carriedapiName. That is@objectstack/rest's discovery route overprotocol.getDiscovery(): the dispatcher cedes/api/v1/discoverywhencom.objectstack.rest.apiis mounted.version=18.0.0-next.3.GET /.well-known/objectstack, which is dispatcher-owned (HttpDispatcher.getDiscoveryInfo()), answered enveloped with noapiName.version=18.0.0-next.3.OS_RUNTIME_VERSIONfirst and then their own package version, and@objectstack/metadata-protocoland@objectstack/runtimeare in one changesetfixedgroup.ctx.getService('protocol')andgetDiscovery(), read at handler time. No copy of the resolver is made.Same boot, with this diff:
bind/start:verification_uriandverification_uri_completeboth carryruntime_version=18.0.0-next.3.bind/poll: the stand-in control plane received one/bindrequest, carrying"runtime_version": "18.0.0-next.3".The before reading is the card's own, taken by the dev of #24066 on main
9ffe8af09:runtime_version=0.3.0at both sites while discovery reported18.0.0-next.2.What to send when the discovery read fails
Options: A, send nothing; B, send
'unknown'; C, send0.3.0(the old behaviour); D, send the plugin's own package version, which needs a third copy of the resolver.'unknown'in the cloud's bind record. A shows nothing, and both sites already handle an empty value: a set but emptyOS_RUNTIME_VERSIONalready sent nothing.Chosen: A. Discovery's own resolver still answers
'unknown'when itspackage.jsoncannot be read. The plugin forwards whatever discovery reports.Tests
packages/cloud-connection/src/cloud-connection-runtime-version.pin.test.ts, 12 cases, both resolution modes. It drives the mountedbind/startandbind/pollroutes against a stand-in control plane. Each expected value is read from a realObjectStackProtocolImplementation.getDiscovery()on the same harness, never written as a literal, and the pin also asserts that value is not the plugin's ownversion.OS_RUNTIME_VERSIONis sent verbatim at both sites, with and without a discovery producer on the kernel.protocolservice is missing or its read throws.connection-credential-store.test.ts: its shared harness gains aprotocolservice. Two of its bind cases assert that a version is present, and on a harness with no discovery producer only the old constant satisfied that.a217f4bc6(this branch withorigin/maind3d064447merged):pnpm --filter @objectstack/cloud-connection exec vitest run --maxWorkers=2: 52 files, 613 tests passed, exit 0.pnpm --filter @objectstack/cloud-connection run typecheck: exit 0.--listFilesshows the new pin in both tsc programs.test:repo: core 86 passed, types 11, objectql 5, rest 262 passed and 14 skipped, runtime 808. Every exit was 0.c90a9776d, before the merge: spectest:repopassed 1115 tests in 67 files, exit 0. The merge did not touch the changed files.Ablation (one pass, on the committed fix)
The mutation went through
scripts/ablation-replace.mjsin WRAP mode, with a trap that restores the file. It replacedif (stamped !== undefined) return stamped || undefined;withreturn (stamped ?? this.version) || undefined;, which is the old(process.env.OS_RUNTIME_VERSION ?? this.version) || undefinedfallback, restored.vitest run src/cloud-connection-runtime-version.pin.test.tsexited 1, with 8 failed and 4 passed. The four controls stayed green. Two of the failures:expected [ '0.3.0', '0.3.0' ] to deeply equal [ '18.0.0-next.3', '18.0.0-next.3' ]andexpected '0.3.0' to be '18.0.0-next.3'.1b75c89c5andgit diff HEADis empty.Gates (final head
a217f4bc6)node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 93 commands. All 93 ran and exited 0.--ranreconciliation:93 derived, 93 run, 0 NOT-MEASURED, 0 UNRUN.pnpm exec eslint --no-inline-configon the three changed TypeScript files: exit 0. The.mdxand.mdfiles have no matching eslint configuration.Acceptance notes
connection-credential-store.test.ts, in the same directory, also changed: test-only, aprotocolservice added to its shared harness (see Tests).OS_RUNTIME_VERSIONset to an empty string. The plugin sends nothing, as before, which keeps the ruling that a set value wins exactly as it does now. Discovery's resolver treats an empty value as unset and reports the package version. The two disagree only on that config. Carrier: none.protocolservice, while REST's discovery resolves the environment's kernel per request. Both call the sameresolveDiscoveryVersion()of the one installed module, so the value is the same within one process. On a host with noprotocolservice, nothing is sent. Not measured on a multi-tenant host, whose composition lives in the cloud repository. Carrier: none.content/docs/deployment/cloud-connection.mdx, which this card does not touch, says the flow's settings,OS_RUNTIME_VERSIONamong them, are listed on that page. The page's cloud-control-plane table has noOS_RUNTIME_VERSIONrow. Docs only. Carrier: none.Generated by Claude Code