Origin: triage split from objectstack-ai/cloud#1502 (EE 4.1.0 published-image acceptance, measured on ghcr.io/objectstack-ai/objectos-ee@sha256:20fc4ab5…). Filed by the triage seat; the cloud-side legs (deploy README, CI leg, ADR-0010 direction) stay on the source card.
Symptom (measured on the published image)
With OS_CLUSTER_DRIVER=redis set (the deploy README's recommended production multi-node path), boot dies:
✗ Cannot find package '@objectstack/service-cluster' imported from
/repo/objectstack/packages/cli/dist/commands/serve.js
migrate exits 1, and compose's service_completed_successfully condition takes the whole stack down with it. Triggered by requesting the redis driver at all — replicas declared or not.
Root cause
Module-resolution asymmetry measured inside the image:
/repo/objectstack/packages/cli/node_modules/@objectstack/ holds 48 packages — noservice-cluster / service-cluster-redis;- both are installed only under the app (
apps/objectos-ee/package.json declares them).
serve.ts reaches the driver via dynamic imports (packages/cli/src/commands/serve.ts:1425'@objectstack/service-cluster', :1456`@objectstack/service-cluster-${driver}`) that resolve from the CLI's own location and cannot cross the link: boundary. App-side code CAN load the same packages (the ClusterServicePlugin multi-node guard runs fine), so only the CLI-side hop is broken. Same class as the earlier AI-Studio-plugin CLI auto-discovery resolution defect.
PM 建议的路线(可选,实测优先)
Either declare service-cluster (+ shipped drivers) as CLI dependencies, or resolve the dynamic import with createRequire anchored at the app's config directory — the general fix should cover any app-declared optional package the CLI advertises it will load, not just this driver.
Notes
- Direction-independent of the ADR-0010 question held on cloud#1502 (
needs-user-decision: whether EE recommends redis at all). Whatever that ruling says, a CLI that names @objectstack/service-cluster-redis in its own refusal guidance must be able to load it when the app declares it. - Downstream: cloud#1502 (
priority:p0) is blocked on this card. - File surface:
packages/cli/src/commands/serve.ts (+ possibly packages/cli/package.json). Mind serve-multi-node-cap-advisory.pin.test.ts, which pins the current dynamic-import shape.
Origin: triage split from objectstack-ai/cloud#1502 (EE 4.1.0 published-image acceptance, measured on
ghcr.io/objectstack-ai/objectos-ee@sha256:20fc4ab5…). Filed by the triage seat; the cloud-side legs (deploy README, CI leg, ADR-0010 direction) stay on the source card.Symptom (measured on the published image)
With
OS_CLUSTER_DRIVER=redisset (the deploy README's recommended production multi-node path), boot dies:migrateexits 1, and compose'sservice_completed_successfullycondition takes the whole stack down with it. Triggered by requesting the redis driver at all — replicas declared or not.Root cause
Module-resolution asymmetry measured inside the image:
/repo/objectstack/packages/cli/node_modules/@objectstack/holds 48 packages — noservice-cluster/service-cluster-redis;apps/objectos-ee/package.jsondeclares them).serve.tsreaches the driver via dynamic imports (packages/cli/src/commands/serve.ts:1425'@objectstack/service-cluster',:1456`@objectstack/service-cluster-${driver}`) that resolve from the CLI's own location and cannot cross thelink:boundary. App-side code CAN load the same packages (theClusterServicePluginmulti-node guard runs fine), so only the CLI-side hop is broken. Same class as the earlier AI-Studio-plugin CLI auto-discovery resolution defect.PM 建议的路线(可选,实测优先)
Either declare
service-cluster(+ shipped drivers) as CLI dependencies, or resolve the dynamic import withcreateRequireanchored at the app's config directory — the general fix should cover any app-declared optional package the CLI advertises it will load, not just this driver.Notes
needs-user-decision: whether EE recommends redis at all). Whatever that ruling says, a CLI that names@objectstack/service-cluster-redisin its own refusal guidance must be able to load it when the app declares it.priority:p0) is blocked on this card.packages/cli/src/commands/serve.ts(+ possiblypackages/cli/package.json). Mindserve-multi-node-cap-advisory.pin.test.ts, which pins the current dynamic-import shape.