Skip to content

Five platform-side comments still name the multi-package artifact as the source of the scope-less served row — it never was: defineStack materialises scope: 'project' #14803

Description

@claude

Five platform-side comments still attribute the scope-less served row to examples/app-multi-package's module. Measured on main 8f9ef6f7c, that attribution is false: defineStack parses every packages[] entry through ManifestSchema (packages/spec/src/stack.zod.ts:233), whose scope is .default('project') (packages/spec/src/kernel/manifest.zod.ts:311), so no package of a compiled artifact is ever scope-less. dist/objectstack.json and both served rows carry scope: "project".

Found while fixing #14597, which corrected the same claim at its source (the fixture's own docblock, README and dogfood harness). Fencing that card to the fixture left these five copies standing; this card is the sweep.

What is true, and what is false

TRUE, and load-bearing everywhere it appears — keep it: a scope-less booted package is read-only while a scope-less database base is writable, and only engine.manifests tells them apart (isWritablePackage, packages/metadata-protocol/src/package-writability.ts:77, which reads the boot map before it reads any scope). That is why the server owns the verdict.

FALSE — the clause to correct: that the scope-less booted row is the module a multi-package artifact carries. It is not. A genuinely scope-less row arises only where a manifest reaches the registry without a ManifestSchema parse, because installPackage stores toRecordManifest(manifest) (packages/objectql/src/registry.ts:3956, :1229), a key-by-key copy that applies no defaults:

  • booted, read-only — a marketplace install / offline file import / ledger rehydrate: manifestService.register(rawBody) (packages/cloud-connection/src/marketplace-install-local-plugin.ts:291 and :827) routes to ql.registerApp (packages/objectql/src/plugin.ts:457);
  • database base, writablePOST /api/v1/packages: const manifest = body.manifest || body (packages/runtime/src/domains/packages.ts:383) reaches protocol.installPackage (packages/metadata-protocol/src/protocol.ts:21188, :21215), which defaults version and derives namespace by hand and parses nothing.

Measured directly: ManifestSchema.parse of the orders body turns has_scope: false into scope: "project"; SchemaRegistry.installPackage of the same unparsed body yields a record with no scope key.

The five sites

  1. packages/runtime/src/domains/packages.ts:286-289withWritableVerdict's docblock: "a scope-less module carried by a multi-package artifact (ADR-0130 D4/D5) lands there too".
  2. packages/runtime/src/domains/packages-writable-verdict.test.ts:15-16 and :39-44 — Pin 2's rationale, including "The raw body is what the load path registers (D7), so the row has no scope at all". The load path registers the PARSED body. The pin itself is sound (it hand-builds a scope-less manifest, which the marketplace path really does produce) — only the attribution is wrong.
  3. packages/metadata-protocol/src/protocol.ts:7233-7234 — same clause. NOTE: this file is held by open PR fix(metadata-protocol): apply the allowOrgOverride read gate inside getMetaItems, so multi-type sweeps are scoped per type #14767, so this site needs sequencing after it lands.
  4. packages/metadata-protocol/src/get-meta-items-package-writable.test.ts:13-14 — same clause.
  5. .changeset/packages-read-door-writable-verdict.md:17-18 — same clause, and this one is pending, so it ships the false attribution into the release notes unless corrected first.

Scope

Comment / prose only. No predicate, no assertion and no served shape changes — every pin listed stays green as written, because each builds its scope-less manifest by hand rather than from the artifact. Re-point the illustration at the marketplace-import and Studio-base paths named above.

Filed unassigned by the #14597 dev. Follows #14597; the objectui half is filed separately in that repo.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions