@prisma/orm-mongo 8.0.0-rc.5 → 8.0.0-rc.5-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/package.json +11 -10
  2. package/skills/prisma-8/SKILL.md +84 -0
  3. package/skills/prisma-8/references/build.md +142 -0
  4. package/skills/prisma-8/references/contract.md +417 -0
  5. package/skills/prisma-8/references/debug.md +141 -0
  6. package/skills/prisma-8/references/feedback.md +251 -0
  7. package/skills/prisma-8/references/migration-review.md +224 -0
  8. package/skills/prisma-8/references/migrations.md +519 -0
  9. package/skills/prisma-8/references/queries-mongo.md +236 -0
  10. package/skills/prisma-8/references/queries-postgres.md +415 -0
  11. package/skills/prisma-8/references/queries.md +168 -0
  12. package/skills/prisma-8/references/quickstart.md +326 -0
  13. package/skills/prisma-8/references/runtime.md +344 -0
  14. package/skills/prisma-8/references/supabase.md +244 -0
  15. package/skills/prisma-8/references/upgrade-app.md +101 -0
  16. package/skills/prisma-8/references/upgrade-extension.md +105 -0
  17. package/skills/prisma-8/upgrading/app/upgrades/0.10-to-0.11/instructions.md +56 -0
  18. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/instructions.md +381 -0
  19. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-closed-mongo-contracts.ts +202 -0
  20. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-domain-namespaced-contracts.ts +201 -0
  21. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/re-emit-postgres-public-default.ts +198 -0
  22. package/skills/prisma-8/upgrading/app/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
  23. package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/instructions.md +339 -0
  24. package/skills/prisma-8/upgrading/app/upgrades/0.12-to-0.13/re-emit-mti-variant-link-columns.ts +229 -0
  25. package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/instructions.md +543 -0
  26. package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
  27. package/skills/prisma-8/upgrading/app/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
  28. package/skills/prisma-8/upgrading/app/upgrades/0.14-to-0.15/instructions.md +359 -0
  29. package/skills/prisma-8/upgrading/app/upgrades/0.15-to-0.16/instructions.md +173 -0
  30. package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/instructions.md +805 -0
  31. package/skills/prisma-8/upgrading/app/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
  32. package/skills/prisma-8/upgrading/app/upgrades/0.17-to-8.0.0-rc.1/instructions.md +72 -0
  33. package/skills/prisma-8/upgrading/app/upgrades/0.7-to-0.8/instructions.md +8 -0
  34. package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/instructions.md +36 -0
  35. package/skills/prisma-8/upgrading/app/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
  36. package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/instructions.md +86 -0
  37. package/skills/prisma-8/upgrading/app/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
  38. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +588 -0
  39. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
  40. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +158 -0
  41. package/skills/prisma-8/upgrading/app/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +42 -0
  42. package/skills/prisma-8/upgrading/extension/upgrades/0.10-to-0.11/instructions.md +276 -0
  43. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/instructions.md +738 -0
  44. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/migrate-contract-testing-imports.ts +97 -0
  45. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/regenerate-extension-public-baseline.ts +223 -0
  46. package/skills/prisma-8/upgrading/extension/upgrades/0.11-to-0.12/strip-migration-labels-hints.ts +340 -0
  47. package/skills/prisma-8/upgrading/extension/upgrades/0.12-to-0.13/instructions.md +266 -0
  48. package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/instructions.md +522 -0
  49. package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/migration-op-factories-to-methods.ts +290 -0
  50. package/skills/prisma-8/upgrading/extension/upgrades/0.13-to-0.14/uuid-preset-rename.ts +43 -0
  51. package/skills/prisma-8/upgrading/extension/upgrades/0.14-to-0.15/instructions.md +803 -0
  52. package/skills/prisma-8/upgrading/extension/upgrades/0.15-to-0.16/instructions.md +219 -0
  53. package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/instructions.md +731 -0
  54. package/skills/prisma-8/upgrading/extension/upgrades/0.16-to-0.17/strip-sha256-hash-prefixes.ts +382 -0
  55. package/skills/prisma-8/upgrading/extension/upgrades/0.17-to-8.0.0-rc.1/instructions.md +194 -0
  56. package/skills/prisma-8/upgrading/extension/upgrades/0.7-to-0.8/instructions.md +8 -0
  57. package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/instructions.md +57 -0
  58. package/skills/prisma-8/upgrading/extension/upgrades/0.8-to-0.9/strip-inline-contracts.ts +226 -0
  59. package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/instructions.md +150 -0
  60. package/skills/prisma-8/upgrading/extension/upgrades/0.9-to-0.10/stamp-storage-types-kind.ts +360 -0
  61. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.1-to-8.0.0-rc.2/instructions.md +746 -0
  62. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.2-to-8.0.0-rc.3/instructions.md +5 -0
  63. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.3-to-8.0.0-rc.4/instructions.md +137 -0
  64. package/skills/prisma-8/upgrading/extension/upgrades/8.0.0-rc.4-to-8.0.0-rc.5/instructions.md +129 -0
@@ -0,0 +1,803 @@
1
+ ---
2
+ from: "0.14"
3
+ to: "0.15"
4
+ changes:
5
+ - id: sql-contract-createnamespace-required
6
+ summary: |
7
+ The SQL family no longer materialises a placeholder namespace, so authoring a SQL contract now
8
+ requires a target namespace factory. If your extension builds a contract via `prismaContract(...)`
9
+ or `defineContract(...)` from `@internal/sql-contract-psl` / `@internal/sql-contract-ts`
10
+ (rather than through a target pack's own `defineContract` wrapper, which already supplies it),
11
+ pass the now-required `createNamespace` option: `postgresCreateNamespace` from
12
+ `@internal/target-postgres/types`, or `sqliteCreateNamespace` from `@internal/target-sqlite/control`.
13
+ Without it, `contract emit` / build fails at runtime with "createNamespace is not a function".
14
+ detection:
15
+ glob: "**/*.{ts,mts,cts}"
16
+ contains:
17
+ - "prismaContract("
18
+ - "defineContract("
19
+ anyMatch: true
20
+ - id: sql-namespace-types-renamed-and-removed
21
+ summary: |
22
+ `SqlNamespace` is now an abstract class and the family placeholder concretion is gone. Rename the
23
+ factory-input type `SqlNamespaceTablesInput` -> `SqlNamespaceInput` (it is the `createNamespace`
24
+ factory input, not a tables-only type). The removed symbols `buildSqlNamespace`,
25
+ `buildSqlNamespaceMap`, `SqlBoundNamespace`, and `SqlUnboundNamespace` have no drop-in replacement:
26
+ construct SQL namespaces only through a target `createNamespace` factory (`postgresCreateNamespace`
27
+ / `sqliteCreateNamespace`). Any hand-written SQL namespace type literal or fixture must carry the
28
+ target `kind` (e.g. `'postgres-schema'`) instead of the removed `'sql-namespace'` discriminator.
29
+ detection:
30
+ glob: "**/*.{ts,mts,cts,tsx}"
31
+ contains:
32
+ - "SqlNamespaceTablesInput"
33
+ - "buildSqlNamespace"
34
+ - "SqlBoundNamespace"
35
+ - "SqlUnboundNamespace"
36
+ - "'sql-namespace'"
37
+ anyMatch: true
38
+ - id: codec-render-value-literal-for-restricted-columns
39
+ summary: |
40
+ A field/column restricted to a value set (e.g. an enum) now derives its narrowed TS literal
41
+ union **through the codec**, not the framework's (now-deleted) domain-enum override. If your
42
+ extension authors a custom codec descriptor (`extends CodecDescriptorImpl`) used by a
43
+ restricted/enum column, implement `renderValueLiteral(value, side)` on it so the column narrows
44
+ to its value union; without it the column widens to the codec's output type
45
+ (`CodecTypes[id][side]`). If your extension builds a `CodecLookup` by hand and drives the
46
+ framework emitter (`generateContractDts`), expose `renderValueLiteralFor` so the emit path can
47
+ reach your descriptor's renderer. Framework-built lookups (via the CLI/build / control-stack)
48
+ already supply it — no action there. (`side`: `output` = the read/SELECT type, `input` = the
49
+ create/update type.)
50
+ detection:
51
+ glob: "**/*.{ts,mts,cts}"
52
+ contains:
53
+ - "CodecDescriptorImpl"
54
+ - "renderValueTypeFor"
55
+ - "renderOutputType"
56
+ anyMatch: true
57
+ - id: sql-codec-json-result-decoding
58
+ summary: |
59
+ SQL `encodeJson` / `decodeJson` now use the exact scalar shape produced by the corresponding
60
+ database inside JSON values. SQL include decoding calls `decodeJson`; ordinary column decoding
61
+ continues to call `decode`. Update custom SQL codecs whose database JSON representation differs
62
+ from their normal driver wire representation, then re-emit committed contracts and defaults.
63
+ Built-in representation changes are: `pg/bytea@1` base64 -> `\\x`-prefixed hex,
64
+ `pg/numeric@1` string -> JSON number, `pg/timestamp@1` UTC `Z` suffix -> no timezone suffix,
65
+ `pg/timestamptz@1` UTC `Z` suffix -> `+00:00`, `sqlite/bigint@1` string -> JSON number,
66
+ `pg/vector@1` JSON array -> Postgres vector text, and `pg/geometry@1` GeoJSON object -> HEXEWKB
67
+ text. SQLite cannot represent BLOB values inside its native JSON values; such queries still fail
68
+ at the database boundary rather than receiving a synthetic codec representation.
69
+ detection:
70
+ glob: "**/*.{ts,mts,cts}"
71
+ contains:
72
+ - "encodeJson"
73
+ - "decodeJson"
74
+ anyMatch: true
75
+ - id: mongo-derive-json-schema-value-sets-param
76
+ summary: |
77
+ `deriveJsonSchema` / `derivePolymorphicJsonSchema` (from `@internal/mongo-contract-psl`) now
78
+ source a value-set field's `$jsonSchema` `enum` keyword from a value-set map, not the domain
79
+ enum. Their fourth argument changed from a domain-enum map
80
+ (`Record<string, ContractEnum>`, read as `members.map(m => m.value)`) to a value-set map
81
+ (`FieldValueSets` = `Record<string, { values: readonly JsonValue[] }>`, keyed by the field's
82
+ `valueSet` `entityName`). If your extension calls either function directly, pass the storage
83
+ value sets (`contract.storage.namespaces[<ns>].entries.valueSet`) instead of `domain.enum`; the
84
+ values are identical for enums, so the rendered validator is unchanged. Most extensions author
85
+ Mongo contracts through `mongoContract(...)` / `defineContract(...)`, which call these
86
+ internally — those need no change.
87
+ detection:
88
+ glob: "**/*.{ts,mts,cts}"
89
+ contains:
90
+ - "deriveJsonSchema"
91
+ - "derivePolymorphicJsonSchema"
92
+ anyMatch: true
93
+ - id: sql-migration-planner-keep-diff-issue-to-ownership-oracle
94
+ summary: |
95
+ `MigrationPlanner.plan()` (and the SQL family's `SqlMigrationPlannerPlanOptions`) drops the
96
+ `keepDiffIssue` option — a caller-supplied `(issue: DiffIssue) => boolean` predicate the
97
+ planner applied to its schema diff for multi-space ownership scoping. It is replaced by
98
+ `ownership?: SchemaOwnership` — an ownership oracle (`{ declaresEntity(entityName): boolean }`,
99
+ exported from `@internal/framework-components/control`) that the `ContractSpaceAggregate`
100
+ satisfies. The planner asks it, per live extra node, whether any contract space declares that
101
+ entity: a node another space owns is left untouched, a node no space owns is a genuine extra it
102
+ may drop under a destructive policy. If your extension calls `planner.plan(...)` directly with
103
+ `keepDiffIssue` (rather than through the aggregate's `db init` / `db update` / `migrate`
104
+ orchestration, which passes the aggregate as the oracle for you), drop the predicate and pass
105
+ the aggregate (or any object implementing `SchemaOwnership`) as `ownership`. There is no
106
+ names-set and no filter function — ownership lives in the aggregate; the planner only asks.
107
+ detection:
108
+ glob: "**/*.{ts,mts,cts}"
109
+ contains:
110
+ - "keepDiffIssue"
111
+ anyMatch: true
112
+ - id: family-sql-collect-sql-schema-issues-removed
113
+ summary: |
114
+ `collectSqlSchemaIssues`, `collectSqlSchemaIssuesPerNamespace`, and their
115
+ `CollectSqlSchemaIssuesOptions` options type are removed from `@internal/family-sql/diff`.
116
+ They implemented the coordinate-based relational schema diff the migration planner used before
117
+ it moved onto the generic node differ (`plan(start, end)`). There is no drop-in replacement —
118
+ if your extension called either function directly to compare a contract against a live/derived
119
+ schema, use the generic node differ instead: `diffSchemas` (from
120
+ `@internal/framework-components/control`) over two schema-IR trees, or a target's own
121
+ `buildXPlanDiff` (e.g. `buildPostgresPlanDiff` from `@internal/target-postgres/diff-database-schema`,
122
+ `buildSqlitePlanDiff` from the sqlite target) for the same op-render-stamped comparison the
123
+ planner itself runs.
124
+ detection:
125
+ glob: "**/*.{ts,mts,cts}"
126
+ contains:
127
+ - "collectSqlSchemaIssues"
128
+ - "collectSqlSchemaIssuesPerNamespace"
129
+ - "CollectSqlSchemaIssuesOptions"
130
+ anyMatch: true
131
+ - id: sql-control-target-descriptor-diff-database-schema-removed
132
+ summary: |
133
+ `SqlControlTargetDescriptor` (from `@internal/family-sql/control`) drops the
134
+ `diffDatabaseSchema` field — the per-target `SchemaDiffer` hook that used to back the
135
+ coordinate-based relational diff. If your extension implements a custom SQL target descriptor
136
+ and supplied this field, remove it; the migration planner reaches the one differ directly via
137
+ the target's own diff-tree builder now (see the `family-sql-collect-sql-schema-issues-removed`
138
+ entry above). `diffSchemaForVerdict` (the full-tree node diff the verify verdict derives from)
139
+ is unaffected and still required.
140
+ detection:
141
+ glob: "**/*.{ts,mts,cts}"
142
+ contains:
143
+ - "diffDatabaseSchema"
144
+ anyMatch: true
145
+ - id: migration-tools-aggregate-strategy-rename
146
+ summary: |
147
+ `@internal/migration-tools/aggregate` renames its exported graph-walk strategy to say what
148
+ it does, not how it's implemented: `graphWalkStrategy` -> `resolveRecordedPath`,
149
+ `GraphWalkOutcome` -> `ResolveRecordedPathOutcome`, `GraphWalkStrategyInputs` ->
150
+ `ResolveRecordedPathInputs`. The function's behaviour, inputs, and outcome shape are
151
+ unchanged — only the names. If your extension imports any of these symbols directly (rather
152
+ than going through `planMigration`, which handles this internally), update the import names.
153
+ detection:
154
+ glob: "**/*.{ts,mts,cts}"
155
+ contains:
156
+ - "graphWalkStrategy"
157
+ - "GraphWalkOutcome"
158
+ - "GraphWalkStrategyInputs"
159
+ anyMatch: true
160
+ - id: target-postgres-diff-postgres-database-schema-removed
161
+ summary: |
162
+ `diffPostgresDatabaseSchema` is removed from `@internal/target-postgres/planner` — the
163
+ Postgres-specific coordinate-based `SchemaDiffer` implementation, retired alongside
164
+ `SqlControlTargetDescriptor.diffDatabaseSchema` (see the entry above). If your extension
165
+ imported it directly, use `buildPostgresPlanDiff` from
166
+ `@internal/target-postgres/diff-database-schema` instead — it runs the same one-differ
167
+ comparison the planner itself uses (relational + RLS-policy issues in one node-typed list,
168
+ filter to the subset you need) and additionally stamps the op-render payload the planner reads.
169
+ detection:
170
+ glob: "**/*.{ts,mts,cts}"
171
+ contains:
172
+ - "diffPostgresDatabaseSchema"
173
+ anyMatch: true
174
+ - id: schema-issue-vocabulary-retired
175
+ summary: |
176
+ The coordinate-based issue vocabulary is gone: `BaseSchemaIssue`, `SchemaIssue`,
177
+ `EnumValuesChangedIssue`, and the `DiffIssue` union are removed from
178
+ `@internal/framework-components/control`. `SchemaDiffIssue` (`{ path, reason, message,
179
+ expected?, actual? }`) is the only issue shape everywhere now — verify results, the codec
180
+ `verifyType` hook, and `SchemaVerifier.issues` all report it. Its `outcome` field is also
181
+ gone; use `reason` (`'not-found'` | `'not-expected'` | `'not-equal'`) instead — `outcome`'s
182
+ `'missing'` / `'extra'` / `'mismatch'` map onto those three respectively. If your extension
183
+ imports any of the removed types, constructs a `{ kind, table, message }`-shaped issue by
184
+ hand, or reads `.outcome` off a `SchemaDiffIssue`, switch to the node-typed shape and
185
+ `reason`.
186
+ detection:
187
+ glob: "**/*.{ts,mts,cts}"
188
+ contains:
189
+ - "BaseSchemaIssue"
190
+ - "EnumValuesChangedIssue"
191
+ - "SchemaDiffOutcome"
192
+ - ".outcome === 'missing'"
193
+ - ".outcome === 'extra'"
194
+ - ".outcome === 'mismatch'"
195
+ anyMatch: true
196
+ - id: schema-finding-lists-single-list
197
+ summary: |
198
+ `SchemaFindingLists` (and therefore `VerifyDatabaseSchemaResult.schema` /
199
+ `.schema.warnings`) collapses from two lists (`issues: SchemaIssue[]`, `schemaDiffIssues:
200
+ SchemaDiffIssue[]`) to one: `{ issues: SchemaDiffIssue[] }`. The framework `SchemaDiff`
201
+ class follows the same collapse — its constructor now takes one issue array instead of
202
+ two (`new SchemaDiff(issues)`, not `new SchemaDiff(issues, schemaDiffIssues)`), and
203
+ `.filter()` narrows the single list. If your extension reads
204
+ `result.schema.schemaDiffIssues` (or `.schema.warnings.schemaDiffIssues`) directly, or
205
+ constructs a `SchemaDiff` by hand, update both call sites to the single-list shape —
206
+ concatenate the old two lists into one, in the same order, if you need to reproduce prior
207
+ combined output.
208
+ detection:
209
+ glob: "**/*.{ts,mts,cts}"
210
+ contains:
211
+ - "schemaDiffIssues"
212
+ - "new SchemaDiff("
213
+ anyMatch: true
214
+ - id: codec-verify-type-hook-returns-schema-diff-issue
215
+ summary: |
216
+ `CodecControlHooks.verifyType` (the storage-type verification hook,
217
+ `@internal/family-sql/control`) now returns `readonly SchemaDiffIssue[]` instead of
218
+ `readonly SchemaIssue[]` — no more `kind` string; classify by `reason` instead. A storage
219
+ type (e.g. a native enum) only ever diverges in its value set, so every paired
220
+ `not-equal` finding grades as value drift (suppressed under an `external` control policy,
221
+ same as before); `not-found` is a missing type, `not-expected` an extra one. If your
222
+ extension implements a custom codec's `verifyType` hook, return `{ path, reason, message,
223
+ expected?, actual? }` issues instead of the old `{ kind, table, message }` shape.
224
+ detection:
225
+ glob: "**/*.{ts,mts,cts}"
226
+ contains:
227
+ - "verifyType:"
228
+ - "verifyType("
229
+ anyMatch: true
230
+ - id: policy-target-models-require-rls-attribute
231
+ summary: |
232
+ If your extension's contract space authors `policy_select` blocks (PSL), each block's
233
+ `target` model must now declare `@@rls`; `contract emit` / `build:contract-space` fails
234
+ with `PSL_EXTENSION_TARGET_MODEL_MISSING_ATTRIBUTE` otherwise. Add `@@rls` to the
235
+ policy-bearing models and re-emit; the contract gains an `rls` marker entity
236
+ (`entries.rls[tableName]`) and a new storage hash.
237
+ detection:
238
+ glob: "**/*.prisma"
239
+ contains:
240
+ - "policy_select"
241
+ anyMatch: true
242
+ - id: postgres-table-schema-node-rls-enabled-required
243
+ summary: |
244
+ `PostgresTableSchemaNodeInput.rlsEnabled` (from `@internal/target-postgres/types`) is
245
+ now a required boolean, and `isEqualTo` compares it alongside the table name. Every
246
+ `new PostgresTableSchemaNode({ ... })` construction in your extension (planner tests,
247
+ diff-tree fixtures, tooling) must supply it explicitly - `false` for a table that is not
248
+ RLS-controlled. The expected side derives the value from the contract's `entries.rls`
249
+ marker; the actual side from `pg_class.relrowsecurity` at introspection.
250
+ detection:
251
+ glob: "**/*.{ts,mts,cts}"
252
+ contains:
253
+ - "new PostgresTableSchemaNode("
254
+ anyMatch: true
255
+ - id: authoring-contributions-model-attributes-slot
256
+ summary: |
257
+ `AuthoringContributions` gains a `modelAttributes` slot and the assembled control-stack
258
+ shape (`AssembledAuthoringContributions`) is now five fields - code that constructs the
259
+ assembled shape literally (e.g. a stubbed `ContractSourceContext.authoringContributions`
260
+ in tests) must add `modelAttributes: {}`. New SPI for pack authors: a target/extension
261
+ pack can contribute declarative `@@` model attributes via
262
+ `AuthoringContributions.modelAttributes` (an `AuthoringModelAttributeDescriptor` carries
263
+ the bare attribute name, an ADR-231 `modelAttribute()` spec, and a lowering that files an
264
+ entity into the namespace's `entries[attribute][key]`), and a PSL block descriptor can
265
+ declare `requiresModelAttribute: { parameter, attribute }` to demand that the model
266
+ named by a ref parameter carries a bare `@@` attribute.
267
+ detection:
268
+ glob: "**/*.{ts,mts,cts}"
269
+ contains:
270
+ - "AssembledAuthoringContributions"
271
+ - "authoringContributions: {"
272
+ anyMatch: true
273
+ - id: native-enum-serialized-in-contract-json
274
+ summary: |
275
+ `native_enum` entities now serialize into an extension's emitted `contract.json` (previously they
276
+ were authoring-time-only — stripped on emit, leaving only the derived `valueSet`). If your
277
+ extension declares native Postgres enums — `native_enum` blocks in a `.prisma` contract, or
278
+ `pg.enum(...)` / `nativeEnum(...)` columns in the TypeScript DSL — re-emit your bundled contract
279
+ (`prisma-next contract emit`) and commit the result, so the `entries.native_enum` maps and the
280
+ recomputed `storageHash` land in your checked-in `contract.{json,d.ts}`. Re-emitting is what makes
281
+ your pack's enum type names visible in the published contract: a consumer running `contract infer`
282
+ with your pack in the stack subtracts your pack-owned enum types by matching those serialized type
283
+ names, so an un-re-emitted contract leaves the consumer re-declaring types your pack already owns.
284
+ The change is backward compatible (a pre-existing contract still hydrates), so re-emit at your
285
+ next release rather than urgently.
286
+ detection:
287
+ glob: "**/*.{prisma,ts,mts,cts}"
288
+ contains:
289
+ - "native_enum"
290
+ - "pg.enum("
291
+ - "nativeEnum("
292
+ anyMatch: true
293
+ - id: native-enum-entry-keyed-by-physical-type-name
294
+ summary: |
295
+ A serialized `native_enum` entry is now keyed by its physical Postgres type name — the `@@map`
296
+ value, or the declared type name when unmapped — not the TS-facing PascalCase name it previously
297
+ used (`entries.native_enum.aal_level`, not `entries.native_enum.AalLevel`). This aligns the
298
+ `native_enum` key with every other storage entry (a table keys by its physical name) per ADR 221.
299
+ If your extension declares native Postgres enums, re-emit your bundled contract
300
+ (`prisma-next contract emit`) and commit the result so the re-keyed `entries.native_enum` map and
301
+ the recomputed `storageHash` land in your checked-in `contract.{json,d.ts}`. If your extension code
302
+ addresses a `native_enum` entry by key
303
+ (`contract.storage.namespaces[<ns>].entries.native_enum[<name>]`), switch that key from the
304
+ PascalCase type name to the physical type name.
305
+ detection:
306
+ glob: "**/*.{prisma,ts,mts,cts}"
307
+ contains:
308
+ - "native_enum"
309
+ - "pg.enum("
310
+ - "nativeEnum("
311
+ anyMatch: true
312
+ - id: scalar-field-state-descriptor-generic
313
+ summary: |
314
+ `ScalarFieldState` (from `@internal/sql-contract-ts/contract-builder`) changes its first
315
+ type parameter from the codec-id string (`CodecId extends string = string`) to the full column
316
+ descriptor type (`Descriptor extends ColumnTypeDescriptor = ColumnTypeDescriptor`), so field
317
+ states preserve the whole descriptor type — including a native-enum entity's member literal
318
+ tuple — instead of only the codec id. If your extension names `ScalarFieldState<...>` with
319
+ positional generics, wrap the codec id in the descriptor type: `ScalarFieldState<'pg/text@1',
320
+ ...>` becomes `ScalarFieldState<ColumnTypeDescriptor<'pg/text@1'>, ...>` (import
321
+ `ColumnTypeDescriptor` from `@internal/framework-components/codec`); the remaining six
322
+ parameters are unchanged. Two narrowing ride-alongs can surface in exact-type test assertions:
323
+ built contract types now keep a descriptor's literal `nativeType`/`typeParams` (previously
324
+ widened to `string`), and `pg.enum(handle)` (from `@internal/postgres`) returns a descriptor
325
+ whose `entityRef` is non-optional and whose `entityRef.entity` is `PostgresNativeEnum<Members>`
326
+ instead of `unknown`. Both remain assignable everywhere the old types were accepted — update
327
+ `expectTypeOf`-style equality assertions to the narrowed types; do not re-widen production
328
+ types to satisfy them.
329
+ detection:
330
+ glob: "**/*.{ts,mts,cts}"
331
+ contains:
332
+ - "ScalarFieldState"
333
+ anyMatch: true
334
+ - id: schema-ir-fk-unbound-referenced-schema-absent
335
+ summary: |
336
+ The family's `contractToSchemaIR` (from `@internal/family-sql/control`) no longer stamps
337
+ `referencedSchema` on a derived `SqlForeignKeyIR` whose target is the unbound namespace — the
338
+ field is now absent for that case (it previously carried the `__unbound__` sentinel). Namespace
339
+ identity is answered by the namespace node's new `isUnbound` getter (on `NamespaceBase` /
340
+ `SqlNamespace`), never by comparing an id against the sentinel. If your extension rebuilds a
341
+ target schema-IR tree from a `contractToSchemaIR`-derived one and reconstructs each
342
+ `SqlForeignKeyIR` (as the Postgres target does in `contractToPostgresDatabaseSchemaNode`),
343
+ default the absent value back to the target's own coordinate for the unbound slot:
344
+ `referencedSchema: fk.referencedSchema ?? UNBOUND_NAMESPACE_ID`. Extensions that read
345
+ `referencedSchema` only for bound (named-schema) FK targets need no change — absence already
346
+ meant "unbound" downstream.
347
+ detection:
348
+ glob: "**/*.{ts,mts,cts}"
349
+ contains:
350
+ - "SqlForeignKeyIR"
351
+ - "referencedSchema"
352
+ anyMatch: true
353
+ - id: supabase-pack-contract-complete
354
+ summary: |
355
+ The `@internal/extension-supabase` shipped contract is now the complete, introspection-generated
356
+ description of everything Supabase owns — every `auth` (23) and `storage` (10) table of the
357
+ reference platform version (supabase/postgres:17.6.1.106), all 10 native enum types, and the three
358
+ roles — up from the previous 5-table minimum. All additive and still `external`: composing apps
359
+ re-emit and pick up the new pack storageHash; `db.asServiceRole().supabase.{sql,orm}` now exposes
360
+ the full owned table set; extension-aware `contract infer` omits correspondingly more. `db verify`
361
+ now requires the full owned set to exist in the live database — real Supabase projects have them;
362
+ a local or CI stand-in database should restore the pack's reference fixture: `bootstrapSupabaseShim`
363
+ from `@internal/extension-supabase/test/utils` now does exactly that (it restores the complete
364
+ reference schema — all Supabase schemas and roles — instead of a hand-authored 5-table subset), so
365
+ shim users need no change beyond re-running. The curated `/contract` model handles (AuthUser,
366
+ AuthIdentity, AuthSession, StorageBucket, StorageObject) are unchanged.
367
+ detection:
368
+ glob: "**/*.{ts,mts,cts,tsx,prisma,json}"
369
+ contains:
370
+ - "@internal/extension-supabase"
371
+ anyMatch: true
372
+ - id: psl-relation-index-argument
373
+ summary: |
374
+ PSL's `@relation(...)` gained an optional boolean `index` argument that lowers onto the foreign
375
+ key's existing IR `index` flag: `@relation(fields: [x], references: [y], index: false)` declares
376
+ the FK without the derived backing-index expectation, for databases whose FK columns genuinely
377
+ have no physical index (previously unexpressible in PSL — verify would report the synthesized
378
+ index `not-found`). `contract infer` now emits `index: false` automatically for FKs it introspects
379
+ without a live backing index, using the same column-key predicate verify uses (shared helper
380
+ `backingIndexColumnKeys`/`isBackedByColumnKeys` in `@internal/family-sql`). Purely additive —
381
+ omitted `index` keeps the default `true`; existing contracts re-emit byte-identically.
382
+ detection:
383
+ glob: "**/*.prisma"
384
+ contains:
385
+ - "@relation"
386
+ anyMatch: true
387
+ - id: contract-canonicalization-preserves-false
388
+ summary: |
389
+ The contract canonicalizer no longer strips `value: false` from resolved default-value objects
390
+ (bare `false` was treated as an omittable empty value, so a `@default(false)` column lost its
391
+ default in the emitted `contract.json` and never round-tripped against live introspection).
392
+ Re-emitting a contract that has boolean-`false` column defaults changes its emitted JSON (the
393
+ default is now present) and therefore its storageHash. No authoring-surface change; re-emit and
394
+ commit the refreshed artifacts.
395
+ detection:
396
+ glob: "**/*.prisma"
397
+ contains:
398
+ - "@default(false)"
399
+ anyMatch: true
400
+ - id: sql-array-columns-round-trip
401
+ summary: |
402
+ Fixes for scalar-list (array) columns and introspection fidelity that can change emitted/derived
403
+ artifacts for affected schemas: (1) the family's `contractToSchemaIR` now keeps an array column's
404
+ `nativeType` as the bare element type with `many: true` (previously it baked `"text[]"` into
405
+ `nativeType`, so every list column verified `not-equal` against live introspection); (2) Postgres
406
+ introspection now excludes expression-keyed indexes (e.g. on `lower(email)`) and no longer
407
+ collides a unique and non-unique index over identical columns; (3) `contract infer` carries a
408
+ non-default index access method through as `@@index(..., type: "<method>")` — note the type must
409
+ be registered in the stack's IndexTypeRegistry to emit. Extensions that snapshot introspection
410
+ output or assert on derived schema-IR for array/expression-indexed tables should re-run and
411
+ refresh expectations.
412
+ detection:
413
+ glob: "**/*.{ts,mts,cts}"
414
+ contains:
415
+ - "contractToSchemaIR"
416
+ - "introspect"
417
+ anyMatch: true
418
+ - id: postgres-inet-codec
419
+ summary: |
420
+ The postgres target gains a `pg/inet@1` codec (transparent string carrier, like `pg/uuid@1`):
421
+ `inet` columns are now authorable as `String @db.Inet` in PSL and representable in contracts,
422
+ and `contract infer` maps an introspected `inet` column to `String @db.Inet` instead of
423
+ `Unsupported("inet")`. Purely additive — no existing contract changes; re-running `contract
424
+ infer` against a database with inet columns now includes them in the output.
425
+ detection:
426
+ glob: "**/*.{prisma,ts,mts,cts}"
427
+ contains:
428
+ - "inet"
429
+ - "db.Inet"
430
+ anyMatch: true
431
+ - id: psl-role-block
432
+ summary: |
433
+ PSL gains a standalone `role` block on the postgres target, authored inside the explicit
434
+ unbound namespace: `namespace unbound { role anon {} }` (name-only, no parameters) lowers to a
435
+ first-class `PostgresRole` entity in the contract's `__unbound__` storage slot
436
+ (`control: 'external'` — roles are referenced, never owned; the planner emits no role DDL and
437
+ `db verify` checks existence via `pg_roles`). The unbound namespace's purpose is late binding
438
+ (search_path-resolved tables); roles are declared there because they are cluster-scoped and
439
+ belong to no schema. To make this authorable, the "no `namespace unbound { }` alongside named
440
+ namespaces" restriction is narrowed to models: a blocks-only unbound namespace is legal next
441
+ to named namespaces, while one containing models next to named namespaces stays rejected
442
+ (`PSL_RESERVED_NAMESPACE_NAME`). A `role` block anywhere else — a named namespace or the
443
+ document top level — is rejected with `PSL_ROLE_BLOCK_OUTSIDE_UNBOUND_NAMESPACE`. Purely
444
+ additive for existing contracts.
445
+ detection:
446
+ glob: "**/*.{prisma,ts,mts,cts}"
447
+ contains:
448
+ - "role "
449
+ - "AuthoringPslBlockDescriptor"
450
+ anyMatch: true
451
+ - id: supabase-pack-contract-declares-roles
452
+ summary: |
453
+ The `@internal/extension-supabase` shipped contract now declares Supabase's three standard
454
+ Postgres roles (`anon`, `authenticated`, `service_role`) as first-class `role` entities with
455
+ `control: 'external'`. `db verify` on a project composing the pack now fails with a `not-found`
456
+ schema issue naming each declared role the live database lacks. Real Supabase databases always
457
+ have these roles, so hosted projects need no change; a local or CI database that stands in for
458
+ Supabase must create them — `bootstrapSupabaseShim` from
459
+ `@internal/extension-supabase/test/utils` already does. The public
460
+ `SupabaseRoleBinding['role']` type is unchanged (`'anon' | 'authenticated' | 'service_role'`);
461
+ it is now derived from the `SupabaseRole` Prisma Next enum handle's values; the contract declares the roles via the
462
+ new PSL `role` blocks inside `namespace unbound { }` (see the `psl-role-block` entry).
463
+ detection:
464
+ glob: "**/*.{ts,mts,cts,tsx,prisma,json}"
465
+ contains:
466
+ - "@internal/extension-supabase"
467
+ anyMatch: true
468
+ ---
469
+ <!--
470
+ Release bump to 0.15.0 (PR #988): the version bump itself. Every
471
+ `packages/3-extensions/*/package.json` advances to 0.15.0 (version field +
472
+ `workspace:` specifier lockstep; one stray `workspace:*` in target-postgres
473
+ normalized to the pinned form). No SPI, contract shape, or emitted artefact
474
+ change beyond the pack version stamp. No extension-author action beyond the
475
+ normal dependency upgrade this recipe covers. Incidental substrate diff only.
476
+ -->
477
+
478
+ <!--
479
+ TML-2503 (extension-supabase Slice E — launch close-out, PR #985): docs only.
480
+ The `packages/3-extensions/` touch is `packages/3-extensions/supabase/README.md` —
481
+ the package README corrected to as-built (runtime usage, JWT validation modes, the
482
+ service_role admin root, unsupported scope). No SPI, contract shape, or emitted
483
+ artefact change. Incidental substrate diff only.
484
+ -->
485
+
486
+ <!--
487
+ TML-2787 (M:N slice 3): namespace-scoped execution-default refs land in
488
+ `@internal/sql-orm-client` (nested writes through a junction, the
489
+ required-payload gate, and the namespace-keyed `ExecutionMutationDefault.ref`).
490
+ The changes are internal to the ORM client and its emitted-contract consumption;
491
+ the extension-author surface is unchanged. No extension-author action — re-emit
492
+ picks up the new contract ref shape. Incidental substrate diff only.
493
+
494
+ TML-2929 (replace legacy PSL parser with CST symbol table): the SQL/Mongo PSL
495
+ interpreters now consume a symbol table built from the CST parser instead of the
496
+ legacy `parsePslDocument` AST. The only `packages/3-extensions/` touch is a
497
+ test-file call-shape rewire in `postgres/test/psl-namespace-qualifier-routing.test.ts`
498
+ (`{ document }` → the symbol-table interpreter input); no extension-author API
499
+ changed. No extension-author action. Incidental substrate diff only.
500
+
501
+ TML-2794 (M:N slice 5): wires the `mn-psl` integration fixture into the
502
+ `@internal/sql-orm-client` test `emit` script. Test-fixture infrastructure
503
+ only; no extension-author surface change. Incidental substrate diff only.
504
+
505
+ TML-2868 (Postgres RLS slice 1): adds the additive Postgres row-level-security
506
+ authoring feature. The only `packages/3-extensions/` touches are the re-emitted
507
+ `supabase/src/contract/contract.d.ts` (regeneration picks up the new RLS-capable
508
+ contract shape) and the `supabase/test/supabase-bootstrap.ts` test helper. No
509
+ extension-author API changed — the framework SPI is unchanged and re-emit
510
+ absorbs the contract shape. Incidental substrate diff only.
511
+
512
+ TML-2931 (entity-kind-migration-seam): implements the entity-kind seam for
513
+ schema diffing and provenance-symmetric RLS diff. The `packages/3-extensions/`
514
+ touches are test updates in `pgvector/test/migrations/` (planner fixtures
515
+ converted to `PostgresSchemaIR`) and `pgvector/test/descriptor.test.ts`
516
+ (contract shape updated to remove `__unbound__` namespace and adjust
517
+ `FieldOutputTypes`/`FieldInputTypes` to namespace-keyed form; precheck/postcheck
518
+ SQL assertions updated for parameterised queries). No extension-author API
519
+ changed. Incidental substrate diff only.
520
+
521
+ TML-2884 (Mongo enum end-to-end vertical): adds the Mongo domain-enum authoring
522
+ surface. The `packages/3-extensions/mongo/` touches are:
523
+ - New `mongo/src/contract/enum-type.ts` and exports in `mongo/src/exports/contract-builder.ts`
524
+ (`enumType`, `member`, `EnumTypeHandle`, `EnumMember`) — all net-new exports; nothing
525
+ existing was changed or removed.
526
+ - `mongo/src/runtime/mongo.ts` gains a `db.enums` facade property — an additive
527
+ field on `MongoClient`; existing fields are unchanged.
528
+ - `mongo/package.json` gains `@internal/emitter` and `@internal/mongo-emitter`
529
+ devDependencies for the new e2e test.
530
+ The `EnumTypeHandle` brand changed from a `Symbol()` to a string-key phantom (`__prismaNextEnumTypeHandle__`);
531
+ extension authors never construct or assert against the brand directly, so the structural surface
532
+ is unchanged. No extension-author action required — the enum surface is purely additive and
533
+ re-emit absorbs the new contract shape. Incidental substrate diff only.
534
+ -->
535
+
536
+ <!--
537
+ TML-2886 (redo, PR #841): type SQL enum columns via a baked storage column lookup.
538
+ The SQL emitter generates a new `StorageColumnTypes` map in `contract.d.ts`, keyed
539
+ `[namespace][table][column]`; `FieldOutputTypes`/`FieldInputTypes` are derived from it
540
+ at emit time. The extension-package `contract.d.ts` fixtures (paradedb, pgvector,
541
+ postgis, supabase, sql-orm-client test fixture) regenerate to add the `StorageColumnTypes`
542
+ block. `contract.json` and hashes are byte-identical; `FieldOutputTypes` is unchanged.
543
+ No extension-author API or surface change. Incidental substrate diff only.
544
+ -->
545
+
546
+ <!--
547
+ TML-2919: typed-DDL conversion of the not-null-with-temporary-default recipe (slice
548
+ 1 of the typed-DDL migration-ops project). The recipe's ADD COLUMN execute step
549
+ now lowers a typed `PostgresAlterTable` DDL node through the adapter, with the
550
+ temporary backfill value carried as a `FunctionColumnDefault` — so the emitted
551
+ DEFAULT clause parenthesizes its expression (e.g. `DEFAULT ('')` instead of the
552
+ previous `DEFAULT ''`). Semantically identical in PostgreSQL. The recipe's DROP
553
+ DEFAULT step also routes through a new typed `DropDefaultAction`. The pgvector
554
+ `planner.behavior.test.ts` assertion that pins the recipe's emitted ADD COLUMN
555
+ SQL was updated to the parenthesized form. Test-only assertion update — no
556
+ extension-author API change. Incidental substrate diff only. (The 0.13 → 0.14
557
+ counterpart entry already records the same change; this entry covers the same
558
+ substrate diff against the post-0.14.0 main.)
559
+ -->
560
+
561
+ <!--
562
+ TML-2911 (native scalar-array storage machinery): the emitted contracts now carry
563
+ the adapter-reported `scalarList` capability marker and the bumped envelope
564
+ version. The scalar-list machinery threaded through this release is internal — no
565
+ authoring path emits a list storage column yet, so extension contracts and runtime
566
+ behaviour are unchanged. No extension-author API or surface change. Incidental
567
+ substrate diff only.
568
+ -->
569
+
570
+ <!--
571
+ PR #894 (postgres-rls slice 2, schema-node-tree-restructure): restructures the
572
+ schema-diff node tree, splits `db verify` into per-space contract-satisfaction
573
+ plus one unclaimed-elements list, and moves plan/verify scoping into the
574
+ aggregate orchestration. The only `packages/3-extensions/` touches are test
575
+ files: `pgvector/test/migrations/planner.*.test.ts` (planner fixtures rebuilt
576
+ for the schema-node tree) and `supabase/test/classification.e2e.test.ts`
577
+ (comment wording). The renamed internals (`AggregateContractSpace`,
578
+ `combineVerifyResults`, the planner keep-predicate) are migration-tools/CLI
579
+ internals with no references in any extension source. No extension-author API
580
+ changed; no extension-author action. Incidental substrate diff only.
581
+ -->
582
+
583
+ <!--
584
+ Exercise Mongo enums in retail-store (this PR): the `MongoClient` facade gains two
585
+ additive members — `raw` (MongoRawClient) and `execute<Row>(plan)` (direct query
586
+ execution without going through `runtime()`). Both additive; existing extension code
587
+ is unaffected. No extension-author action required. Incidental substrate diff only.
588
+ -->
589
+
590
+ <!--
591
+ TML-2955 (expose the static ExecutionContext symmetrically): the built-in target
592
+ facades gain a client-safe `@internal/{mongo,postgres,sqlite}/static` entrypoint
593
+ (`<target>Static`) and expose `db.context` / `db.contract`. Internally, the mongo
594
+ adapter codec now imports `ObjectId` from `bson` instead of `mongodb` so the static
595
+ `ExecutionContext` is genuinely driver-free (client-bundle-safe). All additive /
596
+ internal — no extension-author API or surface change; existing extensions are
597
+ unaffected. No extension-author action required. Incidental substrate diff only.
598
+ -->
599
+
600
+ <!--
601
+ TML-2503 (extension-supabase slice D): `@internal/extension-supabase` gains a
602
+ secondary `.supabase` admin root on `asServiceRole()` — new `ServiceRoleDb` /
603
+ `SupabaseInternalDb` exports from `/runtime`, backed by the extension contract's own
604
+ execution context plus a second runtime sharing the app pool + `service_role` session.
605
+ Purely additive for extension authors — no other extension's API is affected, and no
606
+ released surface changed (the `WithExtensionNamespaces` export existed only on this
607
+ branch's earlier, unmerged merge-design revision and was removed before merge). No
608
+ extension-author API change. Incidental substrate diff only.
609
+ -->
610
+
611
+ <!--
612
+ TML-2892 (migration-author ContractView): the `unboundNamespace` helper that the
613
+ SQLite and Mongo runtimes use to unwrap their single default namespace was lifted
614
+ into the shared foundation (`@internal/framework-components/ir`); the two
615
+ extension runtimes (`packages/3-extensions/{mongo,sqlite}/src/runtime`) now import
616
+ it from there instead of defining a local copy. Behaviour-preserving — the runtime
617
+ facade surface (`db.enums`, `sql`, `orm`) is byte-identical. No extension-author
618
+ API or surface change; nothing to migrate. Incidental substrate diff only.
619
+ -->
620
+
621
+ <!--
622
+ TML-2915 (infer an enum's `@@type` from its members): a PSL `enum` block may now
623
+ omit `@@type` and have the codec inferred (text for bare/string members, int for
624
+ integers). Additive: the framework gains an optional `AuthoringEntityContext.enumInferenceCodecs`
625
+ and a `resolveEnumCodecId` export; each built-in target's config supplies its default
626
+ codec ids, and `@internal/adapter-mongo` gains a `./codec-ids` entrypoint. Explicit
627
+ `@@type` is unchanged. No extension-author action required — the new context field is
628
+ optional and framework-populated. Incidental substrate diff only.
629
+ -->
630
+
631
+ <!--
632
+ TML-2912 (PSL native scalar lists, end-to-end): PSL now lowers scalar-list fields
633
+ (`String[]`, `Int[]`, …) to native array storage columns instead of the JSONB
634
+ fallback, gated on the adapter-reported `scalarList` capability. The review-round
635
+ follow-up also makes the adapter capability matrix required end-to-end on the
636
+ contract-source seam — `ContractSourceContext.capabilities`,
637
+ `InterpretPslDocumentToSqlContractInput`, and the SQL PSL resolution inputs are no
638
+ longer optional. These are framework-internal contract-emission types that the
639
+ control stack always populates; extension authors do not construct them. The only
640
+ `packages/3-extensions/` touch is a one-line test-context update in
641
+ `postgres/test/psl-namespace-qualifier-routing.test.ts` (threading the now-required
642
+ `capabilities` field). No extension-author API changed — re-emit absorbs the
643
+ scalar-list contract shape. No extension-author action required. Incidental
644
+ substrate diff only.
645
+ -->
646
+
647
+ <!--
648
+ Postgres-RLS slice 2.5 (one-differ-two-ir-planner, the cutover to
649
+ `plan(start, end)`): the migration planner now diffs two derived schema IRs
650
+ via the generic node differ instead of the coordinate-based relational walk.
651
+ The only `packages/3-extensions/` touch is a fixture fix in
652
+ `pgvector/test/migrations/{planner.behavior,planner.contract-to-schema-ir}.test.ts`
653
+ — the hand-built `PostgresTableSchemaNode` foreign-key fixtures now stamp
654
+ `resolvedReferencedSchema` (the differ pairs FK nodes by id, which folds in
655
+ that field; an unresolved FK on a hand-built actual node no longer paired with
656
+ the derived expected side). Test-fixture-only; no extension-author API
657
+ changed. See the `sql-migration-planner-keep-diff-issue-to-ownership-oracle`,
658
+ `family-sql-collect-sql-schema-issues-removed`,
659
+ `sql-control-target-descriptor-diff-database-schema-removed`,
660
+ `migration-tools-aggregate-strategy-rename`,
661
+ `target-postgres-diff-postgres-database-schema-removed`,
662
+ `schema-issue-vocabulary-retired`, `schema-finding-lists-single-list`, and
663
+ `codec-verify-type-hook-returns-schema-diff-issue` entries above for the real
664
+ breaking changes this slice makes to the framework SPI.
665
+
666
+ TML-2976 (native Postgres enums, external Supabase types — this PR): the
667
+ `packages/3-extensions/` diff is additive. `@internal/extension-postgres` gains a
668
+ `db.nativeEnums` accessor (new `src/runtime/native-enums.ts`; `runtime/postgres.ts`,
669
+ `exports/runtime.ts`, and `static/postgres-static.ts` expose it) — a Postgres-only
670
+ sibling of `db.enums` for reading external native enum columns.
671
+ `@internal/extension-supabase` gains the same accessor and regenerates its bundled
672
+ contract (`src/contract/contract.{prisma,json,d.ts}`) to carry the `auth.aal_level`
673
+ native enum. A new `sql-orm-client` type test
674
+ (`test/native-enum.field-output.test-d.ts`) pins native-enum field-output typing.
675
+ All additive — the existing extension-author SPI is unchanged, and re-emit absorbs the
676
+ contract shape. No extension-author action required. Incidental substrate diff only.
677
+
678
+ TML-2962 (extension-aware contract infer, PR #919): `contract infer` now omits DB
679
+ elements a stack extension pack's contract space already describes, and resolves an
680
+ app table's foreign key into pack-owned space to the qualified cross-space relation
681
+ (`<spaceId>:<namespace>.<Model>`, e.g. `supabase:auth.AuthUser`) rather than a bare
682
+ local reference. The only `packages/3-extensions/` touch is the `supabase` package
683
+ gaining an `infer-cross-space-fk.integration.test.ts` and a `@internal/psl-printer`
684
+ devDependency for it — no extension-author API changed. One new behavior worth noting
685
+ for pack authors: a pack that declares a table's storage coordinate but no domain
686
+ model mapped to it now makes `contract infer` throw (malformed pack); packs normally
687
+ ship storage + domain together, so no action for well-formed packs. No extension-author
688
+ action required. Incidental substrate diff only.
689
+
690
+ TML-2965 (native-enum-ts-authoring): a native Postgres enum + `pg.enum` column is now
691
+ authorable in the TypeScript DSL, producing a contract byte-identical to the PSL
692
+ `native_enum` equivalent (including in a non-`public` schema). The `packages/3-extensions/`
693
+ diff is additive: `@internal/extension-postgres` gains `src/contract/native-enum.ts` —
694
+ `nativeEnum(name, ...values)` returns a handle whose entity name is `name` and whose
695
+ Postgres type name defaults to `name`; chain `.map(typeName)` to override the Postgres
696
+ type name only. A column binds the handle through `field.column(pg.enum(handle))` (the
697
+ deferred column descriptor resolved at contract-build time). The module exports
698
+ `nativeEnum` / `pg` / `NativeEnumHandle` from `src/exports/contract-builder.ts`;
699
+ `package.json` gains
700
+ `@internal/emitter` and `@internal/sql-contract-emitter` devDependencies for the
701
+ new test's `.d.ts` emission assertion. All net-new exports — nothing existing was
702
+ changed or removed. No extension-author action required. Incidental substrate diff only.
703
+ -->
704
+
705
+ <!--
706
+ TML-2960 (no-emit native-enum column typing): a `field.column(pg.enum(handle))`
707
+ column now types as its member-value literal union in `typeof contract` (the
708
+ no-emit path), matching what the emit path already produced. The
709
+ `packages/3-extensions/` diff is the feature itself plus its type test:
710
+ `postgres/src/contract/native-enum.ts` makes `pg.enum()` generic over the
711
+ handle's members (returning a descriptor whose `entityRef.entity` is
712
+ `PostgresNativeEnum<Members>`), and
713
+ `postgres/test/contract-builder/native-enum-typeof.test-d.ts` pins the
714
+ resulting `typeof contract` types. Runtime values and emitted
715
+ `contract.{json,d.ts}` are byte-identical. The extension-author-facing type
716
+ reshape this rides on (`ScalarFieldState`'s first generic) is recorded in the
717
+ `scalar-field-state-descriptor-generic` entry above; beyond that, no
718
+ extension-author action. Incidental substrate diff only.
719
+ -->
720
+
721
+ <!--
722
+ TML-2828 (variant relations on the narrowed accessor, PR #933): the
723
+ `packages/3-extensions/` diff is confined to `@internal/sql-orm-client` (itself an
724
+ extension). The `.variant('X')`-narrowed predicate accessor now surfaces relations the
725
+ variant model declares in the contract, alongside the base model's relations —
726
+ `createModelAccessor` resolves a variant-owned relation against the variant's
727
+ coordinates (variant table for MTI, base table for STI), and
728
+ `VariantAwareModelAccessor` intersects in the variant's relation accessors so
729
+ `t.variant('Feature').where(x => x.assignee.some(…))` type-checks and plans a correct
730
+ EXISTS. Purely additive to the ORM client's query surface; no extension-author SPI
731
+ (`@internal/contract`, `@internal/framework-components`, …) changed. No
732
+ extension-author action required. Incidental substrate diff only.
733
+ -->
734
+
735
+ <!--
736
+ TML-2883 (rls-ts-authoring): Postgres RLS is now authorable in the TypeScript DSL,
737
+ producing contracts wire-name-identical to the PSL `policy_*` / `@@rls` equivalents.
738
+ The `packages/3-extensions/` diff is additive: `@internal/postgres` gains
739
+ `src/contract/rls.ts` (frozen branded handles from `policySelect` / `policyInsert` /
740
+ `policyUpdate` / `policyDelete` / `policyAll` / `rlsEnabled(model)` / `role(name)`;
741
+ predicates are opaque strings); its `defineContract` accepts an optional
742
+ `entities?: readonly RlsEntityHandle[]` input. The lowering is target-side: the
743
+ generic contract build groups `entities` handles by the pack that registered each
744
+ `entityKind` and calls the pack's batch hook (`lowerEntityHandles`, a SQL-family
745
+ contributions extension exported from
746
+ `@internal/sql-contract/entity-handle-lowering-hook`), which target-postgres
747
+ implements beside its PSL lowering. A TS-declared `role(name)` lands in
748
+ `entries.role` under the `__unbound__` namespace, identical to a PSL `role` block
749
+ (roles are cluster-scoped). `@internal/extension-supabase` gains `anon` /
750
+ `authenticated` role-handle exports from `/contract`. Supporting additive exports
751
+ only elsewhere: `buildContractDefinition` from
752
+ `@internal/sql-contract-ts/contract-builder`; `formatRlsPolicyWireName` +
753
+ `POLICY_OPERATION_PREDICATES` from `@internal/target-postgres/rls-canonicalize`.
754
+ `entities` is the sole public channel for attaching pack entities; the internal
755
+ `packEntities` input never had a real author and was removed (test-only, never
756
+ documented as user-facing), so no extension-author action is required. Incidental
757
+ substrate diff only.
758
+ -->
759
+
760
+ <!--
761
+ Dependabot runtime-deps group bump (PR #962): the packages/3-extensions/
762
+ diff is package.json dependency version ranges only (arktype ^2.2.2 /
763
+ ~2.2.2). No extension-facing API, contract shape, or emitted artefact
764
+ changes. No user action required. Incidental substrate diff only.
765
+ -->
766
+
767
+ <!--
768
+ pg binding resolution by structure, not instanceof (PR #969): the
769
+ `packages/3-extensions/` diff is a bug fix plus additive exports. The postgres
770
+ extension (`@internal/postgres`) gains two net-new `/runtime` exports —
771
+ `isPgPool` / `isPgClient`, structural type guards that identify a `pg`
772
+ Pool/Client by shape instead of `instanceof`. `resolvePostgresBinding` and the
773
+ `@internal/extension-supabase` `toPool` helper now use them, so a
774
+ caller-supplied pool that came from a duplicated `pg` copy in an app bundle
775
+ resolves correctly instead of throwing `Unable to determine pg binding type`
776
+ at boot. The change only accepts inputs the old `instanceof` check rejected —
777
+ nothing that resolved before resolves differently — and the two guards are
778
+ additive. No extension-author action required. Incidental substrate diff only.
779
+ -->
780
+
781
+ <!--
782
+ TML-2980 (variant-declared SQL ORM includes, PR #976): the `packages/3-extensions/` diff fixes the existing `.variant().include()` API inside `@internal/sql-orm-client` so singleton variant narrowing can include relations declared by that variant, with union-valued narrowing rejecting shadowed ambiguous names. Mutation `RETURNING` rows now also map variant-owned physical columns back to their domain field names, matching reads and the existing static row type. No extension-author SPI, contract shape, syntax, or configuration changed, and existing consumers need no code migration. Incidental substrate diff only.
783
+ -->
784
+
785
+ <!--
786
+ postgres-rls project close-out (PR #979): the packages/3-extensions/ diff is
787
+ one documentation link in the supabase README — the RLS pointer into the
788
+ now-deleted projects/postgres-rls/ directory re-pointed at the promoted
789
+ ADR 234 and the Adapters & Targets subsystem doc, with the surface names
790
+ updated to the shipped forms. No code, API, contract shape, or emitted
791
+ artefact changes. No extension-author action required. Incidental docs-only
792
+ diff.
793
+ -->
794
+
795
+ <!--
796
+ PR #915 (middleware doc-comment lifecycle fixes): comments-only. The only
797
+ `packages/3-extensions/` touch is doc comments in
798
+ `packages/3-extensions/middleware-cache/src/cache-middleware.ts`, correcting
799
+ stale claims about the cache-hit lifecycle (a hit skips only the driver call
800
+ and per-row `onRow` hooks; `beforeExecute` has already run, `afterExecute`
801
+ still fires; `decodeRow` still runs). No SPI or behavioural change.
802
+ No user action required. Incidental substrate diff only.
803
+ -->