feat(objectql): ADR-0048 Phase 1+2 — namespace install gate + prefer-local resolution#1810
Merged
Merged
Conversation
feat(ADR-0046): package documentation portal + nav entry (#1686) objectui@893e5302174c7cbf75a7bed9e8e6dcb935273363
…local resolution Phase 1 — install-time namespace gate. `SchemaRegistry.installPackage` refuses a package whose `manifest.namespace` is already owned by a DIFFERENT installed package (new `NamespaceConflictError`), making explicit and early the constraint the object/table layer already enforces implicitly (a duplicate `CREATE TABLE <ns>_<obj>` fails at the DB). Same-package reinstall and shareable platform namespaces (base/system/sys) are exempt; OS_METADATA_COLLISION=warn downgrades to a warning. Phase 2 — prefer-local (container-scoped) resolution. `getItem(type, name, ns?)` resolves a bare name to the item owned by `ns`'s package before any cross-package fallback, preserving ADR-0005 overlay precedence and remaining backward compatible (param optional). `getApp` resolves prefer-local against its own name (app.name ≡ namespace in v1). The per-item collision guard now narrows to the cases prefer-local CANNOT disambiguate (shared/missing namespace), so two DIFFERENT-namespace packages legitimately coexist on the same bare name — the marketplace coexistence the revised ADR-0048 targets. Every existing collision test still passes (namespace-less fixtures remain a hard error). Tests: registry-namespace-install-gate.test.ts (7), registry-prefer-local- resolution.test.ts (7). Full objectql suite green (600). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…solution
Per the sharpened ADR-0048 decision: the URL/route key is the package id (A),
not the namespace. Migration cost is symmetric between A and B (both change one
thing), so A wins on the dimensions that matter for an open marketplace —
coordination-free global uniqueness, a single identity coordinate, no
land-grab, and a self-describing URL.
Backend:
- getItem(type, name, currentPackageId?) prefers `${currentPackageId}:${name}`
directly (was namespace→owner indirection). ADR-0005 overlay precedence and
backward compatibility unchanged.
- getApp(name, currentPackageId?) resolves prefer-local by package id.
- Retire the per-item CROSS-package throw: package ids are globally unique, so
package-scoped resolution always disambiguates two distinct packages — what
the old guard flagged is now the supported coexistence case. Remove the now-
dead MetadataCollisionError, findOtherPackageOwner, isPreferLocalDisambiguable,
isRealPackage, SYS_METADATA_OWNER. collisionPolicy now governs only the Phase
1 namespace gate.
Tests: rewrite *-cross-package-collision.test.ts from "throws" to "coexists +
package-scoped resolves"; prefer-local test keys on package id. Full objectql
suite green (598).
ADR: §3.3 package-scoped (package-id) resolution; §3.4 cross-package throw
retired; §3.6 transparent package-id URL + optional per-tenant namespace alias;
phasing marks Phase 1 + Phase 2 backend/frontend done, package-id routing as the
remaining frontend step.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…2-backend # Conflicts: # packages/objectql/src/registry-prefer-local-resolution.test.ts # packages/objectql/src/registry.ts
This was referenced Jun 13, 2026
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements Phase 1 and Phase 2 (backend) of the revised ADR-0048. Frontend (objectui) prefer-local ships in a companion PR.
Phase 1 — install-time namespace gate
SchemaRegistry.installPackagerefuses a package whosemanifest.namespaceis already owned by a different installed package (new exportedNamespaceConflictError). This makes explicit and early the constraint the object/table layer already enforces implicitly — a duplicateCREATE TABLE <ns>_<obj>fails loudly at the DB mid-install. Same-package reinstall is excluded; shareable platform namespaces (base/system/sys) are exempt;OS_METADATA_COLLISION=warndowngrades to a warning.Phase 2 — prefer-local (container-scoped) resolution
getItem(type, name, currentNamespace?)resolves a bare name to the item owned by that namespace's package before any cross-package fallback. Precedence: (1) bare-key runtime/DB overlay (ADR-0005, unchanged) → (2) the namespace owner's composite entry → (3) legacy first-match. OmittingcurrentNamespacepreserves the old behaviour exactly (backward compatible).getAppuses it (in v1app.name ≡ namespace).The per-item collision guard narrows: it now fires only where prefer-local cannot disambiguate — the two packages share a namespace (possible only for shareable
sys) or lack one (legacy). Two packages with distinct namespaces now legitimately coexist on the same bare name (page/homeincrmandhr) — the marketplace coexistence the revision targets.Tests
registry-namespace-install-gate.test.ts— conflict, same-package reload, distinct namespaces, shareable-namespace exemption, warn downgrade, uninstall-releases.registry-prefer-local-resolution.test.ts— coexistence, prefer-local pick, context-free fallback, overlay precedence, owner-misses fallback, shared-namespace still-fails.@objectstack/objectqlsuite green (600). Every pre-existing ADR-0048 collision test still passes unchanged.No public signature breaks — the new
getItemparam is optional.🤖 Generated with Claude Code