Skip to content

os migrate plan exits 0 when the host config exists but could not be loaded — the one remaining UNMEASURED shape after #12938 #12953

Description

@hotlong

Split out of #12938, which restored the composition but deliberately did not touch exit semantics (the dispatch bounded it to "only what is composed/visible", and the artifact-less run is byte-pinned to today's output, exit 0 included).

The remaining sliver

After #12938, os migrate plan can still compute a plan over a metadata set that is a fraction of the target's tables, in exactly one way: a host objectstack.config.{ts,js,mjs}exists but cannot be loaded. A missing environment variable is the ordinary cause — ObjectStack Cloud's own control-plane config throws without AUTH_SECRET, and that shape is representative rather than exotic.

Today that path:

  • warns loudly on stderr, naming the config, the underlying error and the consequence ("an empty plan here is UNMEASURED, not 'in sync'");
  • carries composition.hostConfigLoaded: false in os migrate plan --json;
  • and exits 0, printing "Physical schema is in sync with metadata — nothing to migrate" when the reduced set happens to be clean.

Composing the platform floor still happens on that path, so managedTables rises to 9 — above the five-table artifact-less baseline that consumer-side coverage gates are calibrated against (objectstack-ai/cloud#1705's workflow uses managedTables <= 5). A count alone therefore cannot distinguish "the config blew up" from "this deployment is genuinely small"; only hostConfigLoaded can.

#12938's own body raised this class in its non-normative "Suggested direction" section: "a plan computed over a metadata set that is a fraction of the target's tables is UNMEASURED, and today it is indistinguishable from 'in sync'".

The decision, stated so it can be ruled on rather than guessed

Should os migrate plan (and apply) exit non-zero when a host config is present and could not be loaded?

No recommendation is offered here; #12938's dispatch ruled the axis out of scope rather than deciding it, so this is a fresh call.

Where to look

Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions