Skip to content

reader program 3/4 — @objectstack/cli: the four config-load boundaries and the gates that key off config.objects #15006

Description

@hotlong

Part of #14122 · blocks #14512 · Blocked-by: #15004 (the acceptance probe).

Reader half of the program ruled on #14512 (comment 5528589044, maintainer 2026-09-03, batch #23). The artifact stays additive through this card.

The sites

From the boundary measurement in 5523741937. Note this package holds four independent config-load boundaries, not one — a fold at any single point reaches none of the others.

Boundary / reader file:line Note
B2 os serve / os dev config-module load packages/cli/src/commands/serve.ts:2170 (bundleRequire) → :2172 (let config = mod.default || mod;) The from-source entry. The compiled artifact never passes through it
configHasMetadata + new AppPlugin(config) serve.ts:2802, :2923 Everything AppPlugin then reads — see card 2/4
i18n auto-registration serve.ts:2976-2995
ObjectQL engine auto-registration serve.ts:2632if (config.objects && !hasObjectQL) ⚠️ Silent: with no top-level objects this reads undefined and the engine is simply not registered
Storage-driver auto-registration serve.ts:2669if (!hasDriver && config.objects) ⚠️ Same mechanism, same silence
appSecurityPluginOptions(config) serve.ts:3710 Feeds the ADR-0056 D7 permission surface from the from-source side — the same surface card 2/4 feeds from the artifact side
B3 os build config-module load packages/cli/src/commands/compile.ts:211 (loadConfig) Then normalizeStackInput :231, safeParse :318, authoring rules :344, per-package run :401
B4 os migrate — its own second, independent loadConfig packages/cli/src/utils/schema-migration-plugins.ts:1083configHasMetadata :1094, new AppPlugin(config, …) :1100 Not behind B2; missed by both earlier enumerations
dev.ts readArtifactObjects() packages/cli/src/commands/dev.ts:653-666 Opens the artifact with its own JSON.parse(readFileSync(...)) at :655 and its own envelope unwrap at :656, reading top-level meta.objects at :657 to diff the inventory across recompiles. Non-fatal — it just goes permanently empty — but it is a sixth place the artifact is opened
resolveDevDatabase / os start / os db clean dev.ts:56, start.ts:557, db/clean.ts:46 These call into resolve-project-database (card 2/4) before any stack exists

The trap in this card

The two auto-registration gates at serve.ts:2632 and :2669 are the sharpest silent failures in the whole program, and they interact with a runtime-side detail: standalone-stack.ts:785 omits the objects key entirely when the array is absent rather than setting [], and mergeBootConfig (packages/cli/src/utils/merge-boot-config.ts:42) is a plain spread. So an option-B artifact reaches these gates with config.objects === undefined and the app boots with no query engine and no storage driver, having thrown nothing. Verify this pair against card 2/4's behaviour on the probe before calling either done.

Acceptance

Sibling cards: #15004 (probe, blocks this), #15005 @objectstack/runtime, 4/4 @objectstack/plugin-security. Emitter half: #14512.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions