Skip to content

TML-2916: un-namespaced PG models default to public namespace per ADR 223#838

Merged
wmadden merged 3 commits into
mainfrom
tml-2916-un-namespaced-pg-defaults-to-public
Jun 16, 2026
Merged

TML-2916: un-namespaced PG models default to public namespace per ADR 223#838
wmadden merged 3 commits into
mainfrom
tml-2916-un-namespaced-pg-defaults-to-public

Conversation

@wmadden-electric

@wmadden-electric wmadden-electric commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

At a glance

- "namespaces": {
-   "__unbound__": { ... empty ... },
-   "public": { "user": {...} }
- }
+ "namespaces": {
+   "public": { "user": {...} }
+ }

Postgres contracts were emitting an empty __unbound__ storage namespace slot alongside public on every contract — in violation of ADR 223 — Target-owned default namespace, which makes target.defaultNamespaceId (= "public" for Postgres) the static, target-owned default. Surfaced during the #825 (TML-2889) review.

The decision

Two sites in the authoring/emit pipeline injected the spurious slot. Both are now gated on defaultNamespaceId === UNBOUND_NAMESPACE_ID — descriptor-driven, no targetId === 'postgres' branch anywhere (per ADR 223). Only SQLite and Mongo (whose default IS unbound) keep the slot.

Site Where Fix
1 packages/2-sql/2-authoring/contract-ts/src/build-contract.ts:748 — end of buildSqlContractFromDefinition, the path both the PSL interpreter and the TS DSL converge on Guard the ensureUnboundNamespaceSlot call on defaultNamespaceId === UNBOUND_NAMESPACE_ID.
2 packages/2-sql/9-family/src/core/ir/sql-contract-serializer-base.tshydrateSqlStorage re-injected the slot on every deserialize round-trip, defeating site 1 during emit Added protected abstract get defaultNamespaceId(): string to SqlContractSerializerBase; implemented in PG, SQLite, and the SqlContractSerializer family-level fallback (which preserves legacy behaviour for callers without a target descriptor). Mongo uses its own base class and is unaffected.

Why two sites

D1 (diagnosis dispatch) identified site 1 only; the in-memory contract built via the TS DSL was already clean (only public). D2's emit traced through executeContractEmitfamilyInstance.deserializeContract(enrichedIR)hydrateSqlStorage, where the round-trip re-introduced the slot. Sites 1 and 2 are independent; both need the gate.

What's regenerated

  • Baked extension-pack contracts (pgvector, paradedb, postgis, supabase) — src/contract.json + .d.ts lose the __unbound__ slot; their migration head.json refs and migration.ts hashes are rewritten by migrations:regen.
  • multi-extension-monorepo sub-extensions (audit, feature-flags) — same shape; scripts/regen-extension-migrations.mjs was extended to walk these (they live under examples/multi-extension-monorepo/packages/*, outside the script's original packages/3-extensions/ walk).
  • apps/telemetry-backend, examples/{bundle-size, paradedb-demo, prisma-next-cloudflare-worker, multi-extension-monorepo/app, prisma-next-demo, prisma-next-postgis-demo} — emitted contracts + migration chains lose the slot; migration hashes update.
  • Test fixtures under packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/, packages/3-extensions/sql-orm-client/test/fixtures/generated/, test/e2e/framework/test/fixtures/generated/, test/integration/test/{fixtures,namespaced-accessors/fixtures/generated}/ — same.

What was NOT regenerated

The diamond + 6 sibling fixture chains under examples/prisma-next-demo/fixtures/*/migrations/app/. The regen script (regen-example-migrations.mjs) requires a per-step contract.prisma for each migration directory to recompute the end-state contract; these chains store only migration.ts per step plus a single root contract.prisma for the final state. A grep -rln "fixtures/diamond" (excluding node_modules, dist, .json, .d.ts) returns zero hits outside the slice's own docs — no test or script reads these fixtures. Left stale on this branch; follow-up to add a regen mechanism or rewrite them.

Tests

  • New IR-level invariant pin: packages/2-sql/2-authoring/contract-psl/test/interpreter.namespaces.test.ts — a bare model user { id String @id } interpreted against the PG target produces domain.namespaces.public.models.user + storage.namespaces.public, with no __unbound__ namespace. Goes red on main without the fix at site 1.
  • Updated bug-encoding tests: 6 cases in packages/2-sql/2-authoring/contract-ts/test/contract-builder.namespaces.test.ts that asserted __unbound__ was present in PG storage — flipped to assert post-fix shape with a // TML-2916 marker.
  • Collateral test update: packages/3-extensions/pgvector/test/descriptor.test.ts:100 asserted the install-vector pre/postcheck SQL contained literal extname = 'vector'. The regen produces parameterised SQL ("extname" = \$1 + params: ["vector"]), a downstream effect of TML-2889's typed-AST routing of verification queries. Test updated to assert both the parameter placeholder and the params array.

ADR-223 grep gate

git grep -nE "targetId === 'postgres'|=== \"postgres\"" packages/1-framework packages/2-sql

Returns the same 3 hits as before — all input validation guards rejecting reserved namespace names. No new namespace-defaulting branches.

Related

  • Surfaced by #825 (TML-2889) — the authoring-half fix (hand-authored Migration PG methods require explicit schema). This PR is the planner/interpreter half.
  • Part of the Marker/ledger via typed query AST project (pre-Phase-2 prerequisite cleanup).

Closes TML-2916.

Summary by CodeRabbit

Release Notes

  • Refactor

    • Generated contract schemas and typings now omit the previously included “unbound” storage namespace, leaving only the public namespace where applicable.
    • Regenerated contract artifacts reflect updated content hashes tied to the revised storage schema.
  • Chores

    • Updated contract serialization/namespace handling to align with target configuration.
    • Extension-migration regeneration now supports additional extension roots.
  • Tests

    • Added/updated assertions to confirm unbound namespaces are not produced.
  • Documentation

    • Updated upgrade guidance to note the regenerated contracts and hash changes.

@wmadden-electric wmadden-electric requested a review from a team as a code owner June 16, 2026 12:22
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 0af03a53-4bb1-4f50-9a43-8b995c0f1d4d

📥 Commits

Reviewing files that changed from the base of the PR and between 822289e and 99d8dc6.

⛔ Files ignored due to path filters (19)
  • examples/bundle-size/src/postgres/generated/contract.d.ts is excluded by !**/generated/**
  • examples/bundle-size/src/postgres/generated/contract.json is excluded by !**/generated/**
  • packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • packages/2-sql/4-lanes/sql-builder/test/fixtures/generated/contract.json is excluded by !**/generated/**
  • packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • packages/3-extensions/sql-orm-client/test/fixtures/generated/contract.json is excluded by !**/generated/**
  • projects/migrate-marker-ledger-to-typed-query-ast-commands/slices/un-namespaced-pg-defaults-to-public/diagnosis.md is excluded by !projects/**
  • projects/migrate-marker-ledger-to-typed-query-ast-commands/slices/un-namespaced-pg-defaults-to-public/plan.md is excluded by !projects/**
  • projects/migrate-marker-ledger-to-typed-query-ast-commands/slices/un-namespaced-pg-defaults-to-public/spec.md is excluded by !projects/**
  • test/e2e/framework/test/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • test/e2e/framework/test/fixtures/generated/contract.json is excluded by !**/generated/**
  • test/integration/test/namespaced-accessors/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • test/integration/test/namespaced-accessors/fixtures/generated/contract.json is excluded by !**/generated/**
  • test/integration/test/sql-builder/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • test/integration/test/sql-builder/fixtures/generated/contract.json is excluded by !**/generated/**
  • test/integration/test/sql-orm-client/fixtures/generated/contract.d.ts is excluded by !**/generated/**
  • test/integration/test/sql-orm-client/fixtures/generated/contract.json is excluded by !**/generated/**
  • test/integration/test/sql-orm-client/fixtures/polymorphism/generated/contract.d.ts is excluded by !**/generated/**
  • test/integration/test/sql-orm-client/fixtures/polymorphism/generated/contract.json is excluded by !**/generated/**
📒 Files selected for processing (125)
  • apps/telemetry-backend/src/prisma/contract.d.ts
  • apps/telemetry-backend/src/prisma/contract.json
  • examples/multi-extension-monorepo/app/src/contract.d.ts
  • examples/multi-extension-monorepo/app/src/contract.json
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.d.ts
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.json
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.json
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.ts
  • examples/multi-extension-monorepo/packages/audit/migrations/refs/head.json
  • examples/multi-extension-monorepo/packages/audit/src/contract.d.ts
  • examples/multi-extension-monorepo/packages/audit/src/contract.json
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.d.ts
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.json
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.json
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.ts
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/refs/head.json
  • examples/multi-extension-monorepo/packages/feature-flags/src/contract.d.ts
  • examples/multi-extension-monorepo/packages/feature-flags/src/contract.json
  • examples/paradedb-demo/src/prisma/contract.d.ts
  • examples/paradedb-demo/src/prisma/contract.json
  • examples/prisma-next-cloudflare-worker/src/prisma/contract.d.ts
  • examples/prisma-next-cloudflare-worker/src/prisma/contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/migration.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/migration.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/migration.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/migration.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/ops.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/migration.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/migration.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/migration.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/migration.ts
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/ops.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.ts
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/ops.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/migration.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/migration.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/start-contract.json
  • examples/prisma-next-demo/src/prisma/contract.d.ts
  • examples/prisma-next-demo/src/prisma/contract.json
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/end-contract.d.ts
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/end-contract.json
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/migration.json
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/migration.ts
  • examples/prisma-next-postgis-demo/src/prisma/contract.d.ts
  • examples/prisma-next-postgis-demo/src/prisma/contract.json
  • examples/react-router-demo/src/prisma/contract.d.ts
  • examples/react-router-demo/src/prisma/contract.json
  • examples/supabase/src/contract.d.ts
  • examples/supabase/src/contract.json
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.namespaces.test.ts
  • packages/2-sql/2-authoring/contract-ts/src/build-contract.ts
  • packages/2-sql/2-authoring/contract-ts/test/contract-builder.namespaces.test.ts
  • packages/2-sql/9-family/src/core/ir/sql-contract-serializer-base.ts
  • packages/2-sql/9-family/src/core/ir/sql-contract-serializer.ts
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.d.ts
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.json
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.json
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.ts
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/ops.json
  • packages/3-extensions/paradedb/migrations/refs/head.json
  • packages/3-extensions/paradedb/src/contract.d.ts
  • packages/3-extensions/paradedb/src/contract.json
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.d.ts
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.json
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.json
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.ts
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/ops.json
  • packages/3-extensions/pgvector/migrations/refs/head.json
  • packages/3-extensions/pgvector/src/contract.d.ts
  • packages/3-extensions/pgvector/src/contract.json
  • packages/3-extensions/pgvector/test/descriptor.test.ts
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.d.ts
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.json
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.json
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.ts
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/ops.json
  • packages/3-extensions/postgis/migrations/refs/head.json
  • packages/3-extensions/postgis/src/contract.d.ts
  • packages/3-extensions/postgis/src/contract.json
  • packages/3-extensions/supabase/src/contract/contract.d.ts
  • packages/3-extensions/supabase/src/contract/contract.json
  • packages/3-targets/3-targets/postgres/src/core/postgres-contract-serializer.ts
  • packages/3-targets/3-targets/postgres/test/postgres-contract-serializer.test.ts
  • packages/3-targets/3-targets/sqlite/src/core/sqlite-contract-serializer.ts
  • scripts/regen-extension-migrations.mjs
  • skills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14/instructions.md
  • skills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.md
  • test/integration/test/authoring/parity/callback-mode-scalars/expected.contract.json
  • test/integration/test/authoring/parity/core-surface/expected.contract.json
  • test/integration/test/authoring/parity/default-cuid-2/expected.contract.json
  • test/integration/test/authoring/parity/default-dbgenerated/expected.contract.json
  • test/integration/test/authoring/parity/default-nanoid-16/expected.contract.json
  • test/integration/test/authoring/parity/default-nanoid/expected.contract.json
  • test/integration/test/authoring/parity/default-pack-slugid/expected.contract.json
  • test/integration/test/authoring/parity/default-ulid/expected.contract.json
  • test/integration/test/authoring/parity/default-uuid-v4/expected.contract.json
  • test/integration/test/authoring/parity/default-uuid-v7/expected.contract.json
  • test/integration/test/authoring/parity/map-attributes/expected.contract.json
  • test/integration/test/authoring/parity/pgvector-named-type/expected.contract.json
  • test/integration/test/authoring/parity/relation-backrelation-list/expected.contract.json
  • test/integration/test/authoring/side-by-side/postgres/contract.json
  • test/integration/test/fixtures/contract.d.ts
  • test/integration/test/fixtures/contract.json
✅ Files skipped from review due to trivial changes (73)
  • packages/3-extensions/paradedb/migrations/refs/head.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/migration.ts
  • examples/multi-extension-monorepo/packages/audit/migrations/refs/head.json
  • packages/3-extensions/pgvector/migrations/refs/head.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/ops.json
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.ts
  • skills/extension-author/prisma-next-extension-upgrade/upgrades/0.13-to-0.14/instructions.md
  • skills/upgrade/prisma-next-upgrade/upgrades/0.13-to-0.14/instructions.md
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/migration.json
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.json
  • test/integration/test/authoring/parity/default-uuid-v4/expected.contract.json
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.json
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/refs/head.json
  • test/integration/test/fixtures/contract.json
  • packages/3-extensions/postgis/migrations/refs/head.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/end-contract.json
  • test/integration/test/authoring/parity/default-nanoid-16/expected.contract.json
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/migration.ts
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/migration.json
  • packages/3-targets/3-targets/sqlite/src/core/sqlite-contract-serializer.ts
  • test/integration/test/authoring/parity/default-cuid-2/expected.contract.json
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/migration.json
  • examples/prisma-next-postgis-demo/src/prisma/contract.json
  • test/integration/test/authoring/parity/default-nanoid/expected.contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/migration.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/migration.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/migration.ts
  • test/integration/test/authoring/parity/pgvector-named-type/expected.contract.json
  • examples/prisma-next-cloudflare-worker/src/prisma/contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/end-contract.json
  • test/integration/test/authoring/side-by-side/postgres/contract.json
  • test/integration/test/authoring/parity/default-uuid-v7/expected.contract.json
  • packages/3-extensions/postgis/src/contract.d.ts
  • packages/3-extensions/supabase/src/contract/contract.json
  • packages/3-extensions/pgvector/src/contract.json
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.json
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.d.ts
  • examples/prisma-next-demo/src/prisma/contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/end-contract.d.ts
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/ops.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/migration.json
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.json
  • examples/prisma-next-demo/migrations/app/20260422T0720_initial/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/end-contract.json
  • examples/supabase/src/contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/start-contract.json
  • test/integration/test/authoring/parity/callback-mode-scalars/expected.contract.json
  • test/integration/test/authoring/parity/default-ulid/expected.contract.json
  • test/integration/test/authoring/parity/default-pack-slugid/expected.contract.json
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.json
  • examples/multi-extension-monorepo/app/src/contract.json
  • packages/3-extensions/pgvector/src/contract.d.ts
  • test/integration/test/authoring/parity/relation-backrelation-list/expected.contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/end-contract.json
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/end-contract.d.ts
  • examples/react-router-demo/src/prisma/contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/end-contract.json
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/start-contract.json
  • examples/supabase/src/contract.json
  • test/integration/test/authoring/parity/core-surface/expected.contract.json
  • examples/prisma-next-demo/src/prisma/contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/start-contract.d.ts
  • examples/react-router-demo/src/prisma/contract.d.ts
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/end-contract.d.ts
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/end-contract.d.ts
🚧 Files skipped from review as they are similar to previous changes (44)
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/migration.ts
  • examples/multi-extension-monorepo/packages/audit/src/contract.json
  • examples/prisma-next-postgis-demo/migrations/app/20260512T1309_migration/migration.ts
  • examples/paradedb-demo/src/prisma/contract.json
  • packages/2-sql/2-authoring/contract-ts/src/build-contract.ts
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.ts
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/migration.json
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/migration.ts
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.namespaces.test.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/migration.ts
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/migration.ts
  • packages/3-extensions/postgis/migrations/20260601T0000_install_postgis_extension/ops.json
  • test/integration/test/authoring/parity/default-dbgenerated/expected.contract.json
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/ops.json
  • apps/telemetry-backend/src/prisma/contract.json
  • packages/3-extensions/pgvector/test/descriptor.test.ts
  • packages/3-extensions/postgis/src/contract.json
  • examples/prisma-next-demo/migrations/app/20260610T0000_add_priority_enum/migration.ts
  • apps/telemetry-backend/src/prisma/contract.d.ts
  • packages/3-extensions/paradedb/src/contract.json
  • examples/multi-extension-monorepo/packages/feature-flags/src/contract.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/start-contract.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/migration.json
  • examples/multi-extension-monorepo/packages/audit/migrations/20260601T0000_create_audit_event/migration.json
  • packages/2-sql/9-family/src/core/ir/sql-contract-serializer-base.ts
  • packages/3-extensions/supabase/src/contract/contract.d.ts
  • examples/prisma-next-cloudflare-worker/src/prisma/contract.d.ts
  • packages/2-sql/9-family/src/core/ir/sql-contract-serializer.ts
  • packages/3-extensions/paradedb/src/contract.d.ts
  • examples/prisma-next-postgis-demo/src/prisma/contract.d.ts
  • examples/multi-extension-monorepo/packages/feature-flags/migrations/20260601T0000_create_feature_flag/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0742_migration/start-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260422T0748_migration/start-contract.d.ts
  • examples/multi-extension-monorepo/packages/feature-flags/src/contract.d.ts
  • test/integration/test/authoring/parity/map-attributes/expected.contract.json
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/end-contract.json
  • examples/prisma-next-demo/migrations/app/20260605T1145_mti_variant_link_columns/end-contract.d.ts
  • test/integration/test/fixtures/contract.d.ts
  • examples/multi-extension-monorepo/app/src/contract.d.ts
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.json
  • packages/2-sql/2-authoring/contract-ts/test/contract-builder.namespaces.test.ts
  • packages/3-extensions/paradedb/migrations/20260601T0000_install_pg_search_extension/end-contract.d.ts
  • examples/prisma-next-demo/migrations/app/20260610T2216_set_priority_default/end-contract.d.ts
  • packages/3-extensions/pgvector/migrations/20260601T0000_install_vector_extension/end-contract.d.ts

📝 Walkthrough

Walkthrough

Un-namespaced models now resolve to public instead of creating __unbound__. Serializer defaults control when __unbound__ is injected, extension SQL checks are parameterized, and generated contract, migration, fixture, and documentation artifacts were refreshed.

Changes

Conditional namespace defaults and regenerated artifacts

Layer / File(s) Summary
Conditional unbound slot and serializer defaults
packages/2-sql/2-authoring/contract-ts/src/build-contract.ts, packages/2-sql/9-family/src/core/ir/sql-contract-serializer-base.ts, packages/2-sql/9-family/src/core/ir/sql-contract-serializer.ts, packages/3-targets/3-targets/postgres/src/core/postgres-contract-serializer.ts, packages/3-targets/3-targets/sqlite/src/core/sqlite-contract-serializer.ts
buildSqlContractFromDefinition now gates ensureUnboundNamespaceSlot on defaultNamespaceId. SqlContractSerializerBase adds conditional __unbound__ hydration plus an abstract defaultNamespaceId. SqlContractSerializer, PostgresContractSerializer, and SqliteContractSerializer provide concrete defaults.
Namespace expectations in tests
packages/2-sql/2-authoring/contract-ts/test/contract-builder.namespaces.test.ts, packages/2-sql/2-authoring/contract-psl/test/interpreter.namespaces.test.ts, packages/3-extensions/pgvector/test/descriptor.test.ts, packages/3-targets/3-targets/postgres/test/postgres-contract-serializer.test.ts
Namespace builder tests drop __unbound__ expectations and the SqlUnboundNamespace import. A new PSL test verifies public defaults for bare models. The postgres serializer test overrides defaultNamespaceId. The pgvector descriptor test expects parameterized extension checks.
Extension migration checks and metadata
packages/3-extensions/paradedb/migrations/..., packages/3-extensions/pgvector/migrations/..., packages/3-extensions/postgis/migrations/...
Extension install ops use extname = $1 with params. Migration descriptors, refs, and contract artifacts update hashes, drop __unbound__, and reshape FieldOutputTypes/FieldInputTypes under public where applicable.
Example app and demo artifacts
apps/telemetry-backend/src/prisma/..., examples/multi-extension-monorepo/..., examples/prisma-next-demo/..., examples/prisma-next-postgis-demo/..., examples/paradedb-demo/..., examples/prisma-next-cloudflare-worker/..., examples/react-router-demo/..., examples/supabase/...
Generated contract typings, JSON, migration metadata, head refs, and some operation ids are regenerated across example apps and demos. The outputs remove __unbound__ namespace entries and refresh SHA-256 hashes.
Integration fixtures and snapshots
test/integration/test/authoring/parity/*/expected.contract.json, test/integration/test/authoring/side-by-side/postgres/contract.json, test/integration/test/fixtures/contract.*
Integration snapshots and shared fixtures are updated to remove __unbound__ namespace entries and refresh storageHash values.
Regeneration script and upgrade notes
scripts/regen-extension-migrations.mjs, skills/extension-author/.../instructions.md, skills/upgrade/.../instructions.md
The regen script now processes extra extension roots. Upgrade notes describe the regenerated __unbound__-removal artifacts and updated hashes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • prisma/prisma-next#668: Updates telemetry contract artifacts by switching StorageHash and namespace typing from __unbound__ to public, matching the same generated-output pattern here.
  • prisma/prisma-next#630: Introduces the serializer-side namespace handling changes that remove the unconditional __unbound__ slot creation this PR builds on.
  • prisma/prisma-next#534: Regenerates contracts and storage metadata to drop the __unbound__ slot and update hashes, similar to the artifact refresh performed here.

Suggested reviewers

  • wmadden

Poem

🐇 Hop, hop—public lights the way,
__unbound__ fades out of the hay.
Hashes refresh with a tidy new gleam,
SQL checks stream with a $1 beam.
The rabbit nods: “All contracts are neat!”

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tml-2916-un-namespaced-pg-defaults-to-public

@pkg-pr-new

pkg-pr-new Bot commented Jun 16, 2026

Copy link
Copy Markdown

Open in StackBlitz

@prisma-next/extension-author-tools

npm i https://pkg.pr.new/@prisma-next/extension-author-tools@838

@prisma-next/mongo-runtime

npm i https://pkg.pr.new/@prisma-next/mongo-runtime@838

@prisma-next/family-mongo

npm i https://pkg.pr.new/@prisma-next/family-mongo@838

@prisma-next/sql-runtime

npm i https://pkg.pr.new/@prisma-next/sql-runtime@838

@prisma-next/family-sql

npm i https://pkg.pr.new/@prisma-next/family-sql@838

@prisma-next/extension-arktype-json

npm i https://pkg.pr.new/@prisma-next/extension-arktype-json@838

@prisma-next/middleware-cache

npm i https://pkg.pr.new/@prisma-next/middleware-cache@838

@prisma-next/mongo

npm i https://pkg.pr.new/@prisma-next/mongo@838

@prisma-next/extension-paradedb

npm i https://pkg.pr.new/@prisma-next/extension-paradedb@838

@prisma-next/extension-pgvector

npm i https://pkg.pr.new/@prisma-next/extension-pgvector@838

@prisma-next/extension-postgis

npm i https://pkg.pr.new/@prisma-next/extension-postgis@838

@prisma-next/postgres

npm i https://pkg.pr.new/@prisma-next/postgres@838

@prisma-next/sql-orm-client

npm i https://pkg.pr.new/@prisma-next/sql-orm-client@838

@prisma-next/sqlite

npm i https://pkg.pr.new/@prisma-next/sqlite@838

@prisma-next/extension-supabase

npm i https://pkg.pr.new/@prisma-next/extension-supabase@838

@prisma-next/target-mongo

npm i https://pkg.pr.new/@prisma-next/target-mongo@838

@prisma-next/adapter-mongo

npm i https://pkg.pr.new/@prisma-next/adapter-mongo@838

@prisma-next/driver-mongo

npm i https://pkg.pr.new/@prisma-next/driver-mongo@838

@prisma-next/contract

npm i https://pkg.pr.new/@prisma-next/contract@838

@prisma-next/utils

npm i https://pkg.pr.new/@prisma-next/utils@838

@prisma-next/config

npm i https://pkg.pr.new/@prisma-next/config@838

@prisma-next/errors

npm i https://pkg.pr.new/@prisma-next/errors@838

@prisma-next/framework-components

npm i https://pkg.pr.new/@prisma-next/framework-components@838

@prisma-next/operations

npm i https://pkg.pr.new/@prisma-next/operations@838

@prisma-next/ts-render

npm i https://pkg.pr.new/@prisma-next/ts-render@838

@prisma-next/contract-authoring

npm i https://pkg.pr.new/@prisma-next/contract-authoring@838

@prisma-next/ids

npm i https://pkg.pr.new/@prisma-next/ids@838

@prisma-next/psl-parser

npm i https://pkg.pr.new/@prisma-next/psl-parser@838

@prisma-next/psl-printer

npm i https://pkg.pr.new/@prisma-next/psl-printer@838

@prisma-next/cli

npm i https://pkg.pr.new/@prisma-next/cli@838

@prisma-next/cli-telemetry

npm i https://pkg.pr.new/@prisma-next/cli-telemetry@838

@prisma-next/emitter

npm i https://pkg.pr.new/@prisma-next/emitter@838

@prisma-next/migration-tools

npm i https://pkg.pr.new/@prisma-next/migration-tools@838

prisma-next

npm i https://pkg.pr.new/prisma-next@838

@prisma-next/vite-plugin-contract-emit

npm i https://pkg.pr.new/@prisma-next/vite-plugin-contract-emit@838

@prisma-next/mongo-codec

npm i https://pkg.pr.new/@prisma-next/mongo-codec@838

@prisma-next/mongo-contract

npm i https://pkg.pr.new/@prisma-next/mongo-contract@838

@prisma-next/mongo-value

npm i https://pkg.pr.new/@prisma-next/mongo-value@838

@prisma-next/mongo-contract-psl

npm i https://pkg.pr.new/@prisma-next/mongo-contract-psl@838

@prisma-next/mongo-contract-ts

npm i https://pkg.pr.new/@prisma-next/mongo-contract-ts@838

@prisma-next/mongo-emitter

npm i https://pkg.pr.new/@prisma-next/mongo-emitter@838

@prisma-next/mongo-schema-ir

npm i https://pkg.pr.new/@prisma-next/mongo-schema-ir@838

@prisma-next/mongo-query-ast

npm i https://pkg.pr.new/@prisma-next/mongo-query-ast@838

@prisma-next/mongo-orm

npm i https://pkg.pr.new/@prisma-next/mongo-orm@838

@prisma-next/mongo-query-builder

npm i https://pkg.pr.new/@prisma-next/mongo-query-builder@838

@prisma-next/mongo-lowering

npm i https://pkg.pr.new/@prisma-next/mongo-lowering@838

@prisma-next/mongo-wire

npm i https://pkg.pr.new/@prisma-next/mongo-wire@838

@prisma-next/sql-contract

npm i https://pkg.pr.new/@prisma-next/sql-contract@838

@prisma-next/sql-errors

npm i https://pkg.pr.new/@prisma-next/sql-errors@838

@prisma-next/sql-operations

npm i https://pkg.pr.new/@prisma-next/sql-operations@838

@prisma-next/sql-schema-ir

npm i https://pkg.pr.new/@prisma-next/sql-schema-ir@838

@prisma-next/sql-contract-psl

npm i https://pkg.pr.new/@prisma-next/sql-contract-psl@838

@prisma-next/sql-contract-ts

npm i https://pkg.pr.new/@prisma-next/sql-contract-ts@838

@prisma-next/sql-contract-emitter

npm i https://pkg.pr.new/@prisma-next/sql-contract-emitter@838

@prisma-next/sql-lane-query-builder

npm i https://pkg.pr.new/@prisma-next/sql-lane-query-builder@838

@prisma-next/sql-relational-core

npm i https://pkg.pr.new/@prisma-next/sql-relational-core@838

@prisma-next/sql-builder

npm i https://pkg.pr.new/@prisma-next/sql-builder@838

@prisma-next/target-postgres

npm i https://pkg.pr.new/@prisma-next/target-postgres@838

@prisma-next/target-sqlite

npm i https://pkg.pr.new/@prisma-next/target-sqlite@838

@prisma-next/adapter-postgres

npm i https://pkg.pr.new/@prisma-next/adapter-postgres@838

@prisma-next/adapter-sqlite

npm i https://pkg.pr.new/@prisma-next/adapter-sqlite@838

@prisma-next/driver-postgres

npm i https://pkg.pr.new/@prisma-next/driver-postgres@838

@prisma-next/driver-sqlite

npm i https://pkg.pr.new/@prisma-next/driver-sqlite@838

commit: 99d8dc6

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
postgres / no-emit 153.31 KB (+0.02% 🔺)
postgres / emit 140.92 KB (+15.94% 🔺)
mongo / no-emit 78 KB (0%)
mongo / emit 72.09 KB (0%)
cf-worker / no-emit 181.74 KB (+0.03% 🔺)
cf-worker / emit 167.76 KB (+14.33% 🔺)

wmadden-electric and others added 3 commits June 16, 2026 15:22
… 223

The contract authoring pipeline injected an empty `__unbound__` storage
namespace into every Postgres contract, in violation of ADR 223 — which
makes `target.defaultNamespaceId` ("public" for Postgres) the static,
target-owned default. Two sites are guarded on `defaultNamespaceId ===
UNBOUND_NAMESPACE_ID` so only SQLite and Mongo (whose default is the
unbound sentinel) keep the slot:

1. `build-contract.ts` — the `ensureUnboundNamespaceSlot` call site at
   the end of `buildSqlContractFromDefinition` (the build path both the
   PSL interpreter and the TS DSL converge on).
2. `sql-contract-serializer-base.ts` — `hydrateSqlStorage` previously
   re-injected the slot on every deserialize round-trip, defeating the
   build-time fix during emit. An `abstract get defaultNamespaceId():
   string` was added to the base class and implemented in the PG, SQLite,
   and Mongo (`SqlContractSerializer` fallback) subclasses.

Regenerates the affected fixtures and baked extension-pack contracts
(pgvector, paradedb, postgis, supabase, audit, feature-flags) to drop
the spurious `__unbound__` slot. Updates the contract-builder.namespaces
tests that encoded the bug as expected behavior. Adds an IR-level test
in interpreter.namespaces that pins the un-namespaced PG → public
invariant end-to-end.

The diamond fixture chain under examples/prisma-next-demo/fixtures/* is
not regenerated by this PR: it has no per-step contract.prisma source
so the regen script cannot rebuild it, and a `grep` of the codebase
shows zero consumers. Left stale; follow-up to add a regen mechanism.

Extends `regen-extension-migrations.mjs` to cover the
multi-extension-monorepo sub-extension packages (audit, feature-flags)
that also carry on-disk migrations + head refs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…struction declarations

- postgres-contract-serializer.test.ts: RegistryDispatchProbeSerializer
  needs to implement the new abstract defaultNamespaceId getter.
- skills/upgrade + skills/extension-author 0.13-to-0.14/instructions.md:
  add TML-2916 incidental-substrate-diff markers so per-pr-declaration
  CI gate sees the upgrade-instruction files were touched.

Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…-2918

Post-rebase regen: TML-2918 (#837) landed schema-qualified op ids
(`column.${schema}.${table}.${column}`) for the PG AddColumn op. The
prisma-next-demo migration ops.json files now carry `column.public.*`
ids; migrationHash updates accordingly.

Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@wmadden-electric wmadden-electric force-pushed the tml-2916-un-namespaced-pg-defaults-to-public branch from 85695a1 to 99d8dc6 Compare June 16, 2026 13:24
@wmadden wmadden enabled auto-merge June 16, 2026 13:25
@wmadden wmadden added this pull request to the merge queue Jun 16, 2026
Merged via the queue into main with commit 088813b Jun 16, 2026
21 checks passed
@wmadden wmadden deleted the tml-2916-un-namespaced-pg-defaults-to-public branch June 16, 2026 13:49
wmadden-electric added a commit that referenced this pull request Jun 18, 2026
Main shipped the 0.14.0 publish bump (#843) and several follow-ups
(TML-2916 #838, TML-2503 #839, TML-2787 #683, TML-2893 #849, ci-fix
#847) while slice 1 was in review. Merge to pick them up.

Resolution:
- `skills/extension-author/.../0.13-to-0.14/instructions.md` — union of
  the slice's TML-2919 entry and main's TML-2916 entry as two distinct
  HTML-comment blocks, matching the file's per-ticket convention.
  Per the skill spec's rebase scenario (lines 122-130): existing entries
  in the just-shipped 0.13-to-0.14 directory may stay in place; we do
  not relocate the TML-2919 entry to 0.14-to-0.15.
- Lockfile + example fixtures + apps + all other non-slice files —
  take main's side cleanly (the branch hadn't touched them; auto-merge
  resolved to main's content). `pnpm install` confirms the lockfile is
  consistent.
- No `src/` conflicts — only the one instructions.md conflict above.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants