# ADR Index This document provides a comprehensive index of all Architectural Decision Records (ADRs) for the Prisma 8 prototype, organized by category and ADR number. ## When to add a record - Write an ADR when the maintainers have decided not to build something that the next agent or contributor would otherwise propose. Do not write one for every pull request, or for a choice the code already makes. - If an ADR already records the decision, add that ADR to the steering list instead of writing a second one. - The title states the no. The decision names what to use instead, or says that nothing exists. The consequences say what would reopen the decision, or that no revisit-if condition is recorded. Half a page is enough. Take the next free number. - Whoever declines a request for a reason no ADR records drafts the ADR from the maintainer's words, with status `Proposed`. The same pull request adds it to the steering list and to the [Product scope](#product-scope) table. A maintainer's approval of that pull request is consensus under the [governance](../oss/governance.md#decision-making), so the drafter then sets the status to `Accepted`. - To change a decision, write a new ADR and mark the old one superseded. Do not edit the old one. Take it off the steering list; its row stays under Product scope. ## Steering list Open this list before you propose a new feature or surface, or judge a feature request or a pull request. Each entry is a request the maintainers have answered with a no, and what to use instead. Every ADR on this list is accepted, including older ones written before ADRs carried a Status line. How to judge a request is on the [vision](../design/00-purpose/vision.md#how-to-use-this-page) page. - [ADR 007](adrs/ADR%20007%20-%20Types%20Only%20Emission.md): no generated client code; import the emitted contract and pass it to the client. - [ADR 222](adrs/ADR%20222%20-%20Version%20support%20policy.md): no CommonJS; Prisma 8 ships ES modules only. - [ADR 247](adrs/ADR%20247%20-%20Whole-query%20raw%20SQL%20is%20the%20fragment%20mechanism%20at%20statement%20position.md): no separate `$queryRaw`-style client method, an alternative the ADR rejects; write raw SQL with `db.raw.sql`, or `fns.raw` inside a builder query. - [ADR 286](adrs/ADR%20286%20-%20Prisma%208%20does%20not%20fully%20manage%20native%20Postgres%20enums.md): Prisma 8 does not fully manage native Postgres enums; declare an `enum` in the contract, stored with a `CHECK` constraint. - [ADR 287](adrs/ADR%20287%20-%20Prisma%208%20has%20no%20db%20push%20to%20production.md): no `db push` to production; run `migration plan`, review the migration, then `db migrate`. - [ADR 289](adrs/ADR%20289%20-%20Prisma%208%20has%20no%20%24extends%20client%20extensions.md): no `$extends`; use middleware, extension packages, contributed collection methods and collection classes. - [ADR 291](adrs/ADR%20291%20-%20Prisma%208%20has%20no%20%24on%20events.md): no `$on` events; use a middleware on the lifecycle events. - [ADR 293](adrs/ADR%20293%20-%20Validations,%20soft%20delete%20and%20lifecycle%20hooks%20are%20not%20in%20the%20core.md): no validations, soft delete or lifecycle hooks in the core; validate in application code (arktype), use a nullable `deletedAt` column with a `notDeleted` scope, and middleware. - [ADR 295](adrs/ADR%20295%20-%20New%20features%20do%20not%20land%20on%20Prisma%207.md): the team does no new feature work on Prisma 7; a community feature may land there when it is in line with Prisma 7's design and meets the quality bar, as a maintainer decides ([versioning](../oss/versioning.md#supported-versions)). Propose other features for Prisma 8 on `main`. - [ADR 296](adrs/ADR%20296%20-%20Prisma%208%20has%20no%20relationLoadStrategy.md): no `relationLoadStrategy`; include the relation, and the database joins it. - [ADR 298](adrs/ADR%20298%20-%20Prisma%208%20has%20no%20fluent%20relation%20API.md): no fluent relation API; load related rows with `.include(...)`. - [ADR 299](adrs/ADR%20299%20-%20Prisma%208%20has%20no%20Prisma.skip.md): no `Prisma.skip`; no document names what to use instead. - [ADR 300](adrs/ADR%20300%20-%20Prisma%208%20has%20no%20omit%20under%20that%20name.md): no `omit` under that name; name the fields you want with `select(...)`. - [ADR 301](adrs/ADR%20301%20-%20Prisma%208%20has%20no%20relationMode%20prisma.md): no `relationMode = "prisma"`; use foreign keys in the database. - [ADR 302](adrs/ADR%20302%20-%20Prisma%208%20does%20not%20split%20large%20IN%20lists.md): Prisma 8 does not split large `IN` lists; load related rows with `.include(...)`, which the database joins. - [ADR 303](adrs/ADR%20303%20-%20Prisma%208%20has%20no%20read%20replicas%20in%20the%20core.md): no read replicas in the core; create a separate `db` client for each data store. - [ADR 304](adrs/ADR%20304%20-%20Prisma%208%20has%20no%20automatic%20batching.md): no automatic batching of lookups; load related rows with `.include(...)`, which the database joins. - [ADR 305](adrs/ADR%20305%20-%20Prisma%208%20has%20no%20P2002-style%20error%20codes.md): no `P2002`-style error codes; branch on the dotted `code` of the error envelope. ## Core Architecture | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 001 | Migrations as Edges | Defines migrations as contract-to-contract transitions rather than sequential SQL files | [ADR 001 - Migrations as Edges.md](adrs/ADR%20001%20-%20Migrations%20as%20Edges.md) | | 002 | Plans are Immutable | Establishes Plans as immutable, auditable objects with contract hash and references | [ADR 002 - Plans are Immutable.md](adrs/ADR%20002%20-%20Plans%20are%20Immutable.md) | | 003 | One Query One Statement | Ensures Plans map to single SQL statements for predictability and guardrails | [ADR 003 - One Query One Statement.md](adrs/ADR%20003%20-%20One%20Query%20One%20Statement.md) | | 004 | Storage Hash vs Profile Hash | Separates storage identity hashing (`storageHash`) from pinned capability profile hashing (`profileHash`) | [ADR 004 - Storage Hash vs Profile Hash.md](adrs/ADR%20004%20-%20Storage%20Hash%20vs%20Profile%20Hash.md) | | 005 | Thin Core Fat Targets | Keeps core minimal while pushing target-specific behavior into adapters | [ADR 005 - Thin Core Fat Targets.md](adrs/ADR%20005%20-%20Thin%20Core%20Fat%20Targets.md) | | 140 | Package Layering & Target-Family Namespacing | Establishes ring-based package layout and per-family namespaces; introduces target-agnostic runtime core and family runtimes | [ADR 140 - Package Layering & Target-Family Namespacing.md](adrs/ADR%20140%20-%20Package%20Layering%20%26%20Target-Family%20Namespacing.md) | | 150 | Family-Agnostic CLI and Pack Entry Points | Config-only CLI, /cli vs /runtime entrypoints, family helpers + TargetFamilyHook | [ADR 150 - Family-Agnostic CLI and Pack Entry Points.md](adrs/ADR%20150%20-%20Family-Agnostic%20CLI%20and%20Pack%20Entry%20Points.md) | | 204 | Domain actions vs composable primitives in the control plane | Distinguishes action methods (single user intents, CLI envelopes, audit boundaries) from composable primitives (raw data, no audit), and forbids compound actions from calling peer actions | [ADR 204 - Domain actions vs composable primitives in the control plane.md](adrs/ADR%20204%20-%20Domain%20actions%20vs%20composable%20primitives%20in%20the%20control%20plane.md) | | 278 | Each database's packages live in one folder | **Accepted.** A database's target, adapter, driver, codec testkit and facade live in `packages/3-targets//`, numbered by dependency order; family folders are named `2--family`; extension packs stay in `packages/3-extensions/`. Amends ADR 140. | [ADR 278 - Each database's packages live in one folder.md](adrs/ADR%20278%20-%20Each%20database's%20packages%20live%20in%20one%20folder.md) | ## Contract & Schema | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 006 | Dual Authoring Modes | Supports both PSL-first and TS-first authoring with identical canonical artifacts | [ADR 006 - Dual Authoring Modes.md](adrs/ADR%20006%20-%20Dual%20Authoring%20Modes.md) | | 007 | Types Only Emission | Emits only TypeScript declarations, no runtime client code generation | [ADR 007 - Types Only Emission.md](adrs/ADR%20007%20-%20Types%20Only%20Emission.md) | | 008 | Dev Auto Emit CI Explicit Emit | Removes explicit generate step in development via plugins, requires explicit emit in CI | [ADR 008 - Dev Auto Emit CI Explicit Emit.md](adrs/ADR%20008%20-%20Dev%20Auto%20Emit%20CI%20Explicit%20Emit.md) | | 009 | Deterministic Naming Scheme | Establishes consistent naming patterns for constraints to ensure stable emission | [ADR 009 - Deterministic Naming Scheme.md](adrs/ADR%20009%20-%20Deterministic%20Naming%20Scheme.md) | | 010 | Canonicalization Rules | Defines exact key ordering and normalization rules for deterministic contract hashing | [ADR 010 - Canonicalization Rules.md](adrs/ADR%20010%20-%20Canonicalization%20Rules.md) | | 021 | Contract Marker Storage | Defines database storage for contract identity verification and alignment checks | [ADR 021 - Contract Marker Storage.md](adrs/ADR%20021%20-%20Contract%20Marker%20Storage.md) | | 042 | Contract Marker Evolution | Specifies marker table schema evolution and forward-compatible field additions | [ADR 042 - Contract Marker Evolution.md](adrs/ADR%20042%20-%20Contract%20Marker%20Evolution.md) | | 156 | Storage sets and check constraints | **Superseded.** Proposed `storage.sets` and structured `{ kind: "inSet", column, setRef }` checks to say “column value is in this set” in storage. The sets are replaced by the value set (`entries.valueSet`) that columns reference; the checks by [ADR 244](adrs/ADR%20244%20-%20Check%20constraints%20are%20opaque%20wire-named%20expressions.md), where a check is an opaque wire-named predicate. See [ADR 157's October 12, 2026 amendment](adrs/ADR%20157%20-%20Execution%20enums.md#amendment-october-12-2026--how-enums-are-realized) | [ADR 156 - Storage sets and check constraints.md](adrs/ADR%20156%20-%20Storage%20sets%20and%20check%20constraints.md) | | 159 | Definition-only contracts and separate TypeMaps for lane typing | Keeps contracts stack-independent and traversable; keeps runtime-real structural mappings on the runtime contract value; exports codec/operation type maps as a separate `TypeMaps` type (not part of `Contract`) | [ADR 159 - Definition-only contracts and type-only codec-operation maps.md](adrs/ADR%20159%20-%20Definition-only%20contracts%20and%20type-only%20codec-operation%20maps.md) | | 163 | Provider-invoked source interpretation packages | Keeps parsing/interpretation logic in provider-invoked authoring packages so CLI/control plane stay source-agnostic and IO-free | [ADR 163 - Provider-invoked source interpretation packages.md](adrs/ADR%20163%20-%20Provider-invoked%20source%20interpretation%20packages.md) | | 167 | Typed default literal pipeline and extensibility | Documents typed literal default flow across authoring/emission/verification/rendering and records deferred codec-keyed SPI follow-up | [ADR 167 - Typed default literal pipeline and extensibility.md](adrs/ADR%20167%20-%20Typed%20default%20literal%20pipeline%20and%20extensibility.md) | | 170 | Pack-provided type constructors and field presets | Composed registries for parameterized types and presets across PSL + TS; dot namespacing; hard-error duplicates; presets may imply constraints | [ADR 170 - Pack-provided type constructors and field presets.md](adrs/ADR%20170%20-%20Pack-provided%20type%20constructors%20and%20field%20presets.md) | | 171 | Parameterized native types in contracts | **Superseded by ADR 254.** Contracts represent parameterized storage types as base `nativeType` + structured `typeParams`; expansion to SQL strings was hook-driven per component, and is now declared by the data type | [ADR 171 - Parameterized native types in contracts.md](adrs/ADR%20171%20-%20Parameterized%20native%20types%20in%20contracts.md) | | 246 | Option arguments and select templates for authoring helpers | Adds a shared `option` argument kind (bare token in PSL, literal union in TS; one type across block parameters and helper arguments) and a `select` template node — registration-validated against the option's values — so preset vocabulary never leaks generator ids. An undefined execution-defaults phase omits the phase; an empty resolved `typeParams` omits the key — the two rules carry each other, and the `updatedAt()` ≡ `timestamptz(now, now)` shorthand is test-enforced, not structural. Per-codec preset name = codec base name. Records which check protects which surface (PSL validator vs TS literal union; the TS surface has no runtime validation) and which protects which argument object (weak type vs excess-property). | [ADR 246 - Option arguments and select templates for authoring helpers.md](adrs/ADR%20246%20-%20Option%20arguments%20and%20select%20templates%20for%20authoring%20helpers.md) | | 249 | Central attribute-spec registry | Registers every model-level and field-level PSL attribute of both families in one place, keyed by level and name, as a spec *factory* over a framework-owned construction-time context (`AttributeSpecContext` / `FieldAttributeSpecContext`) — the uniform signature is what lets the language server invoke the same factories the interpreters run. `assembleAttributeSpecs` merges family built-ins with [ADR 236](adrs/ADR%20236%20-%20Target-contributed%20model%20attributes.md)'s model-attribute descriptors into frozen plain records and restores the factory types core erases (they return `AttributeSpec`, because `refine` makes `Out` contravariant and `unknown` would reject every spec that refines). Registry keys drive unknown-attribute diagnostics at field and model level in both families; block attributes are declared on `AuthoringPslBlockDescriptor.attributes` and parsed by the kit. | [ADR 249 - Central attribute-spec registry.md](adrs/ADR%20249%20-%20Central%20attribute-spec%20registry.md) | | 250 | Models and views are emitted from the contract | `contract.d.ts` gains a `Models` namespace (one member per model, `_`, plus `_Any` for each polymorphic base) and a type-only `models` constant; relations are typed as the related member with a phantom `RelationKeys` key so `Scalars` names a default fetch's row and `Shape` names an application data structure derived from the model, and both ORM collections carry `_row` so `ResultType` names any query's result. To-one nullability is a family hook (SQL reads foreign keys and column nullability; Mongo takes the nullable default); name collisions and non-identifier names are emitter errors | [ADR 250 - Models and views are emitted from the contract.md](adrs/ADR%20250%20-%20Models%20and%20views%20are%20emitted%20from%20the%20contract.md) | | 253 | PSL red-root source ownership | A PSL parse registers the actual returned red document root with a named `SourceFile`; post-parse diagnostics resolve filenames from the node's owning root through `PslSources`, with no unnamed parse mode or singleton fallback. Output diagnostics may still serialize a `sourceId`, but it originates from `SourceFile.filename`; file-read errors and Prisma7 compatibility plumbing are explicit exceptions. | [ADR 253 - PSL red-root source ownership.md](adrs/ADR%20253%20-%20PSL%20red-root%20source%20ownership.md) | | 254 | Data types and casts | A data type is the type of a value Prisma stores or passes to the database, most often a database type made first-class, registered per target or extension by id (`pg/int8`, `pg/jsonb`), owning the names the database writes and reports for it, its parameters with their bounds and rendering, its canonical contract form, and its casts from other types; a database type's data type is what the database stores; a codec is one representation of a data type and several may share one; a contract column stores its codec, its data type and its parameters, and no type name; a written value has a type of its own (a number takes the narrowest target integer type that holds it, so it never rounds; the `json` tag returns the JSON type) and is admitted when the column's type is its type or casts from it; enum members are references; `sql` is the tag of `sql/expression`, which the SQL family defines and registers, the one type a family registers; a position with a fixed receiving type admits values through `dataTypeValue`; no family-level database types and no central convertibility rule. Replaces the PSL half of ADR 184 | [ADR 254 - Data types and casts.md](adrs/ADR%20254%20-%20Data%20types%20and%20casts.md) | | 257 | Scalar types are named after the target on every surface | A scalar type's PSL name, TypeScript helper and codec id share one token taken from the codec id (`mongo/int32@1` → `Int32`, `field.int32()`), so a name says what the target stores; codec ids never rename. `Json` (the JSON-representable subset) and MongoDB's `Bson` (any BSON value) are the encoding-named exceptions. A renamed PSL name stays one release line as a deprecated alias that warns through the contract source's warning channel; a reserved mechanism covers a codec id that must change | [ADR 257 - Scalar types are named after the target on every surface.md](adrs/ADR%20257%20-%20Scalar%20types%20are%20named%20after%20the%20target%20on%20every%20surface.md) | | 258 | List cardinality has independent container and element nullability | Nested list descriptors separate container and element nullability across SQL and Mongo, let element nullability decide whether the element check is derived, and record the intentional legacy-list wire incompatibility and historical-snapshot upgrade obligations. Complements ADR 178's value-object cardinality model | [ADR 258 - List cardinality has independent container and element nullability.md](adrs/ADR%20258%20-%20List%20cardinality%20has%20independent%20container%20and%20element%20nullability.md) | | 262 | Block specs bind top-level block values | A contributed top-level block declares its member-value grammar as a block spec built from the shared argument combinators — `structBlock` for closed key sets, `mapBlock` (with an optional bare-member sentinel) for arbitrary keys, `jsonValue()` for native JSON literals, `InferBlock` deriving the factory input type. Declarations are collected completely before any block is interpreted; only successful typed envelopes (`ParsedPslExtensionBlock`) are published and lowered, parsed AST is never stringified, and the print shape is constructed only by producers without an AST. SQL projects selected model references onto storage coordinates and lets factory outputs opt into destination placement via `pslPlacement`. Supersedes ADR 126's parameter-kind tables and descriptor-data validation. | [ADR 262 - Block specs bind top-level block values.md](adrs/ADR%20262%20-%20Block%20specs%20bind%20top-level%20block%20values.md) | | 264 | A model names its storage verbatim, and a rename is an operation | A model names its table, or its MongoDB collection, exactly as the model is written, and a field names its column by its own name; a different storage name is always stated with `@@map` or `@map`. Changing a storage name renames existing storage: the author states it in a migration with `this.renameTable({ table, to })`, which also renames every object whose name the planner derives from the table name | [ADR 264 - A model names its storage verbatim, and a rename is an operation.md](adrs/ADR%20264%20-%20A%20model%20names%20its%20storage%20verbatim%2C%20and%20a%20rename%20is%20an%20operation.md) | | 267 | A table may hold columns its model does not map | A model maps to a table that may hold columns the model does not map, and a table may have no model; such storage is created, verified and covered by the storage hash like any other, and the ORM reads, writes and types only the columns a model's fields map. The Prisma 7 reader lowers `@ignore` fields and `@@ignore` models to it, and Prisma 7's `_prisma_migrations` is left out of introspection | [ADR 267 - A table may hold columns its model does not map.md](adrs/ADR%20267%20-%20A%20table%20may%20hold%20columns%20its%20model%20does%20not%20map.md) | | 268 | Raw SQL is a value of the data type `sql/expression` | Every place that holds raw SQL (`@default`, `@@index(where:)`, `@@index(expression:)`, `@@fullTextIndex(where:)`, `@@check(expression:)`, a policy's `using` and `withCheck`, and, amended 2026-10-20, the argument of ``Raw(sql`...`)``) receives the data type `sql/expression`, which the SQL family defines and registers with the tag `sql` and from which nothing casts, so only a `sql` literal is admitted and a plain string is refused by the ADR 254 cast rule; specs declare the type with `dataTypeValue`; `@default` alone keeps checks on SQL text; one set of cast-rule codes; the TypeScript `sql` tag returns a `SqlExpression` value, which every TypeScript raw-SQL field takes | [ADR 268 - Raw SQL is a value of the data type sql-expression.md](adrs/ADR%20268%20-%20Raw%20SQL%20is%20a%20value%20of%20the%20data%20type%20sql-expression.md) | | 270 | ORM queries use the query builder's functions and a model's indexes | Every ORM callback that builds a condition or an order (`where`, `orderBy`, relation filters, fragment bodies, include refinements) receives a second argument `{ fns, indexes }`: the SQL query builder's functions for the contract, and the model's table's indexes as index references bound to the table as the query reads it, so an ORM query searches a weighted full-text index by naming it. Collection methods that packages contribute are ADR 272 | [ADR 270 - ORM queries use the query builder's functions and a model's indexes.md](adrs/ADR%20270%20-%20ORM%20queries%20use%20the%20query%20builder's%20functions%20and%20a%20model's%20indexes.md) | | 272 | Packages contribute collection methods computed from a model | **Accepted.** A package reads each model of the contract (target, name, fields, relations, storage table) and contributes collection methods under names it chooses; every SQL ORM collection offers them under the reserved member `using`, such as `db.orm.public.Post.using.post_search(q)` and `db.orm.public.Post.using.embedding_nearest(v)`. The type half registers in `CollectionMethodRegistry` by declaration merging through the package's own entry points, never through the emitted `contract.d.ts`; the run-time half goes on a target or extension descriptor. Two contributions that give a model the same name are a compile error and an `ORM.ARGUMENT_INVALID` at `orm()` | [ADR 272 - Packages contribute collection methods computed from a model.md](adrs/ADR%20272%20-%20Packages%20contribute%20collection%20methods%20computed%20from%20a%20model.md) | | 273 | A column of a type no data type claims is a raw column | A column whose database type no data type claims has data type `sql/raw`, whose parameter `sql` is the type exactly as the catalog prints it, and codec `sql/raw@1`, which passes values through typed `unknown`; migrations write the text into DDL and `db verify` compares it exactly; a Prisma 8 field declares one with ``Raw(sql`...`)``, and its default is a `sql` expression; the Prisma 7 reader reads `Unsupported("...")` as a raw column with no field | [ADR 273 - A column of a type no data type claims is a raw column.md](adrs/ADR%20273%20-%20A%20column%20of%20a%20type%20no%20data%20type%20claims%20is%20a%20raw%20column.md) | | 275 | Client generators are field attributes, and a type alias is expanded into each column | **Proposed.** `@onCreate(fn())` and `@onUpdate(fn())` set the client's generators, resolved from the column's codec through a generator function registry the stack assembles, with params from the column's type parameters; `@default` means a database default only; a `types {}` alias may carry `@default`, `@onCreate` and `@onUpdate`, is expanded into each column, and is never stored, so `storage.types` keeps only types a contract space registers; field presets are removed from SQL and Mongo, PSL and the TypeScript builder, and targets contribute aliases such as `temporal.UpdatedAt` | [ADR 275 - Client generators are field attributes, and a type alias is expanded into each column.md](adrs/ADR%20275%20-%20Client%20generators%20are%20field%20attributes%2C%20and%20a%20type%20alias%20is%20expanded%20into%20each%20column.md) | | 279 | Convenience types choose an explicit type from their arguments | A target can declare convenience types, named for what a field means, whose `as:` and `storage:` arguments pick one of its explicit, database-named types, with defaults that need no setup; the contract stores only the explicit type, and the tools write the convenience form. PostgreSQL's `DateTime`, `Date`, `Time` and `Duration` are the first | [ADR 279 - Convenience types choose an explicit type from their arguments.md](adrs/ADR%20279%20-%20Convenience%20types%20choose%20an%20explicit%20type%20from%20their%20arguments.md) | ## Query System | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 011 | Unified Plan Model | Establishes common Plan structure across all query lanes with AST, SQL, and metadata | [ADR 011 - Unified Plan Model.md](adrs/ADR%20011%20-%20Unified%20Plan%20Model.md) | | 012 | Raw SQL Escape Hatch | **Plan construction superseded by ADR 247.** Provides safe raw SQL execution with required annotations and verification; the annotation schema stands, the AST-less plan shape does not | [ADR 012 - Raw SQL Escape Hatch.md](adrs/ADR%20012%20-%20Raw%20SQL%20Escape%20Hatch.md) | | 013 | Lane Agnostic Plan Identity | Ensures Plan identity and hashing work consistently across all query lanes | [ADR 013 - Lane Agnostic Plan Identity.md](adrs/ADR%20013%20-%20Lane%20Agnostic%20Plan%20Identity.md) | | 162 | Kysely lane emits PN SQL AST | **Superseded.** The Kysely lane was removed from Prisma 8; this ADR is retained for historical context only | [ADR 162 - Kysely lane emits PN SQL AST.md](adrs/ADR%20162%20-%20Kysely%20lane%20emits%20PN%20SQL%20AST.md) | | 165 | ORM WhereArg literal normalization | Records Phase 2 decision to validate bound ToWhereExpr payloads then normalize ParamRef values into literals at ORM boundaries | [ADR 165 - ORM WhereArg literal normalization.md](adrs/ADR%20165%20-%20ORM%20WhereArg%20literal%20normalization.md) | | 018 | Plan Annotations Schema | Defines canonical JSON schema for Plan annotations and validation rules | [ADR 018 - Plan Annotations Schema.md](adrs/ADR%20018%20-%20Plan%20Annotations%20Schema.md) | | 019 | TypedSQL as Separate CLI | Establishes TypedSQL as out-of-tree tool that emits Plan factories | [ADR 019 - TypedSQL as Separate CLI.md](adrs/ADR%20019%20-%20TypedSQL%20as%20Separate%20CLI.md) | | 020 | Result Typing Rules | Defines how DSL and ORM compute result types from projections and joins | [ADR 020 - Result Typing Rules.md](adrs/ADR%20020%20-%20Result%20Typing%20Rules.md) | | 025 | Plan Caching Memoization | Establishes Plan caching strategy with memoization and invalidation | [ADR 025 - Plan Caching Memoization.md](adrs/ADR%20025%20-%20Plan%20Caching%20Memoization.md) | | 180 | Dot-path field accessor | Callable string accessor (`u("homeAddress.city")`) for value object fields and Mongo update operators; unified `FieldAccessor` used by both read and write callbacks in the Mongo query builder | [ADR 180 - Dot-path field accessor.md](adrs/ADR%20180%20-%20Dot-path%20field%20accessor.md) | | 201 | State-machine pattern for typed DSL builders | Three-class state machine (`CollectionHandle` → `FilteredCollection` → `PipelineChain`) with phantom marker types gating conditional terminals; pattern used in `mongo-query-builder`, candidate for reuse in a typed SQL query builder | [ADR 201 - State-machine pattern for typed DSL builders.md](adrs/ADR%20201%20-%20State-machine%20pattern%20for%20typed%20DSL%20builders.md) | | 247 | Whole-query raw SQL is the fragment mechanism at statement position | A `raw-query` node in `AnyQueryAst` sharing the fragment tag's parts representation; `.returnsRow(spec)` / `.affectedCount()` terminators, a hybrid row spec (contract column refs or explicit codec ids), embeddable iff row-returning (so data-modifying CTEs compose), strict-on-missing / drop-surplus decode. Supersedes ADR 012's AST-less plan construction | [ADR 247 - Whole-query raw SQL is the fragment mechanism at statement position.md](adrs/ADR%20247%20-%20Whole-query%20raw%20SQL%20is%20the%20fragment%20mechanism%20at%20statement%20position.md) | | 255 | Relation ordering lowers to correlated subqueries | A SQL ORM `orderBy` can order by a to-one relation's field or a to-many relation's `count(predicate?)`; each lowers to a correlated scalar subquery built from the same join `some`/`every`/`none` use, so the main query gains no join. `OrderByItem` carries `nulls` placement rendered per adapter; `cursor()` and `DISTINCT ON` refuse orders that are not plain columns | [ADR 255 - Relation ordering lowers to correlated subqueries.md](adrs/ADR%20255%20-%20Relation%20ordering%20lowers%20to%20correlated%20subqueries.md) | | 259 | Query fragments are functions | A row fragment is a function of the model accessor, which `where` and `orderBy` take; a query fragment is a function from a collection to a collection, which `with` runs, and a scope is a query fragment that only imposes conditions. The query API gains no control-flow methods. `db.orm.fragment(fields, body)` builds a fragment for any model with the given fields, `db.Post.fragment(body)` one for a single model, and `orderByField` checks an order field from a request against an allowed list | [ADR 259 - Query fragments are functions.md](adrs/ADR%20259%20-%20Query%20fragments%20are%20functions.md) | | 261 | Row locks are a select clause named after the SQL, with one capability per strength or option | The typed SQL builder and the ORM client lock the rows a select reads with `forUpdate()`, `forNoKeyUpdate()`, `forShare()` and `forKeyShare()`, each taking `nowait` or `skipLocked` (and `of` on the builder). Seven adapter-reported capabilities, one per strength or option, decide which methods and options exist; a survey of SQL databases shows coarser capabilities would need splitting. `SelectAst` carries a target-neutral `LockingClause` (`strength`, `of`, `waitPolicy`) that holds no validity rule; renderers write their syntax or refuse, never drop. The ORM always locks `OF` the model's table; combinations Postgres refuses are refused before a statement is sent with `ORM.LOCK_INCOMPATIBLE` | [ADR 261 - Row locks are a select clause named after the SQL, with one capability per strength or option.md](adrs/ADR%20261%20-%20Row%20locks%20are%20a%20select%20clause%20named%20after%20the%20SQL,%20with%20one%20capability%20per%20strength%20or%20option.md) | | 265 | A collection keeps its class through the chain | A custom `Collection` subclass registered with the client keeps its class through `where`, `orderBy`, `limit`, `include` and the other methods that keep the model's rows; what the chain has established (a filter, an order, extra fields on each row) is added to the type and never replaces the class, and a collection that may have no filter refuses the methods that need one. SQL ORM client only; the MongoDB client is unchanged | [ADR 265 - A collection keeps its class through the chain.md](adrs/ADR%20265%20-%20A%20collection%20keeps%20its%20class%20through%20the%20chain.md) | ## Runtime & Execution | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 014 | Runtime Hook API | **Superseded by ADR 271** (`beforeCompile` and `onRow` remain). Defines composable hook system for Plan lifecycle events and plugin integration | [ADR 014 - Runtime Hook API.md](adrs/ADR%20014%20-%20Runtime%20Hook%20API.md) | | 015 | ORM as Optional Extension | Establishes ORM layer as optional extension built on core DSL primitives | [ADR 015 - ORM as Optional Extension.md](adrs/ADR%20015%20-%20ORM%20as%20Optional%20Extension.md) | | 016 | Adapter SPI for Lowering | Defines stable adapter interface for SQL lowering and dialect-specific behavior | [ADR 016 - Adapter SPI for Lowering.md](adrs/ADR%20016%20-%20Adapter%20SPI%20for%20Lowering.md) | | 030 | Result decoding & codecs registry | Establishes codec registry for type-safe result decoding and parameter encoding | [ADR 030 - Result decoding & codecs registry.md](adrs/ADR%20030%20-%20Result%20decoding%20&%20codecs%20registry.md) | | 031 | Adapter capability discovery & negotiation | Defines capability discovery and negotiation flow between adapters and runtime | [ADR 031 - Adapter capability discovery & negotiation.md](adrs/ADR%20031%20-%20Adapter%20capability%20discovery%20&%20negotiation.md) | | 155 | Driver/Codec boundary and lowering responsibilities | Separates lowering vs codec encoding/decoding vs driver transport; standardizes codec↔driver boundary values as `string \| Uint8Array \| null` | [ADR 155 - Driver Codec Boundary and Lowering Responsibilities.md](adrs/ADR%20155%20-%20Driver%20Codec%20Boundary%20and%20Lowering%20Responsibilities.md) | | 251 | Target-owned Postgres list framing | Moves inbound Postgres list framing to the target so builtin and enum arrays share one raw-text parse path before scalar element decoding; records the outbound asymmetry and guarded driver array-OID set | [ADR 251 - Target-owned Postgres list framing.md](adrs/ADR%20251%20-%20Target-owned%20Postgres%20list%20framing.md) | | 157 | Execution enums | **Partially superseded.** An enum is a set of allowed values plus an explicit enforcement mechanism, and execution derives the allowed values from the contract. Its October 12, 2026 amendment replaces how this is realized: a domain enum with members in their stored form, a value set in storage that columns reference, a derived CHECK on `managed` tables (ADR 244), and native Postgres enums as `native_enum` storage entries | [ADR 157 - Execution enums.md](adrs/ADR%20157%20-%20Execution%20enums.md) | | 158 | Execution mutation defaults | Defines execution-plane mutation defaults (`execution.mutations.defaults`) and a section-owned hashing model to avoid marker churn | [ADR 158 - Execution mutation defaults.md](adrs/ADR%20158%20-%20Execution%20mutation%20defaults.md) | | 256 | Mutation-default generators are a framework runtime concern | The generator contract (`{ id, generate(params?), stability }`), the `'field'` / `'row'` / `'query'` stabilities and their caches, the availability check at execution-context creation, and the apply loop live once in `@internal/framework-components/runtime` and serve every family; a key present in `values` is explicit whatever its value; `buildExecutionSection` sorts and hashes the section for every authoring path | [ADR 256 - Mutation-default generators are a framework runtime concern.md](adrs/ADR%20256%20-%20Mutation-default%20generators%20are%20a%20framework%20runtime%20concern.md) | | 168 | Postgres JSON and JSONB typed columns | Adds first-class PostgreSQL `json`/`jsonb` codec and column support with Standard Schema-based typed emission in `contract.d.ts` | [ADR 168 - Postgres JSON and JSONB typed columns.md](adrs/ADR%20168%20-%20Postgres%20JSON%20and%20JSONB%20typed%20columns.md) | | 186 | Codec-dispatched type rendering | Codecs own TypeScript type rendering via `renderOutputType` and `FieldOutputTypes`; removes `EmissionSpi.generateModelsType?` override and legacy renderer infrastructure | [ADR 186 - Codec-dispatched type rendering.md](adrs/ADR%20186%20-%20Codec-dispatched%20type%20rendering.md) | | 169 | Declared applicability for mutation default generators | Records the decision to validate generator/column compatibility via contributor-declared applicability and to assemble generator implementations via composed registries | [ADR 169 - Declared applicability for mutation default generators.md](adrs/ADR%20169%20-%20Declared%20applicability%20for%20mutation%20default%20generators.md) | | 160 | Plan grouping keys for multi-statement orchestration | **Superseded by ADR 271** (the parent activity replaces `groupingKey`). Adds `meta.groupingKey` to correlate multiple statement executions that serve one higher-level operation | [ADR 160 - Plan grouping keys for multi-statement orchestration.md](adrs/ADR%20160%20-%20Plan%20grouping%20keys%20for%20multi-statement%20orchestration.md) | | 164 | Repository Layer | Defines `@internal/sql-orm-client` as a multi-query orchestration surface in the extensions integrations layer | [ADR 164 - Repository Layer.md](adrs/ADR%20164%20-%20Repository%20Layer.md) | | 202 | Codec trait system | Semantic capability traits (`equality`, `order`, `numeric`, `textual`, `boolean`) declared on codecs and consumed by query surfaces to gate operator availability by data type | [ADR 202 - Codec trait system.md](adrs/ADR%20202%20-%20Codec%20trait%20system.md) | | 203 | Trait-targeted operation arguments | Extends operation argument specs with `traits` to accept any codec carrying the required capability, alongside exact `codecId` targeting | [ADR 203 - Trait-targeted operation arguments.md](adrs/ADR%20203%20-%20Trait-targeted%20operation%20arguments.md) | | 204 | Single-tier runtime | Collapses `runtime-executor` into `framework-components`; family runtimes (`@internal/sql-runtime`, `@internal/mongo-runtime`) extend `RuntimeCore` directly via the `/runtime` subpath. Partially supersedes ADR 140's "Runtime Separation" two-tier model. | [ADR 204 - Single-tier runtime.md](adrs/ADR%20204%20-%20Single-tier%20runtime.md) | | 206 | Operations as TypeScript functions | Operations are authored as real TS functions — signature is the type surface, body builds the AST — with a minimal `self` dispatch hint for ORM column-helper reachability | [ADR 206 - Operations as TypeScript functions.md](adrs/ADR%20206%20-%20Operations%20as%20TypeScript%20functions.md) | | 210 | Prepared Statements: Author Surface and Driver SPI | Adds `runtime.prepare(declaration, callback)` (re-exposed on each DB facade as `db.prepare(...)`) and prepared execution through the existing `query()` driver SPI; lazy driver-allocated opaque handle, no global cache, cache lifetime bounded by user reference and connection. Family-level: per-driver caching strategies are out of scope here. | [ADR 210 - Prepared Statements - Author Surface and Driver SPI.md](adrs/ADR%20210%20-%20Prepared%20Statements%20-%20Author%20Surface%20and%20Driver%20SPI.md) | | 215 | Runtime middleware lifecycle: `beforeExecute` fires before `encodeParams` | **Amended by ADR 271** (the hook is now `beforeEncode`, in the same position, with the same parameter mutator). Reorders the SQL family runtime so `beforeExecute` fires between `lowerToDraft` and `encodeDraftParams`, with a pre-encode `paramsMutator` over user-domain values. Extracts `runBeforeExecuteChain` from `runWithMiddleware`; `intercept` always observes a post-`beforeExecute` plan. SPI shape unchanged. | [ADR 215 - Runtime middleware lifecycle beforeExecute before encodeParams.md](adrs/ADR%20215%20-%20Runtime%20middleware%20lifecycle%20beforeExecute%20before%20encodeParams.md) | | 220 | Plan execution identity for middleware correlation | **Superseded by ADR 271** (`activity.id` replaces `planExecutionId`). Adds `planExecutionId: string` to `RuntimeMiddlewareContext`, minted by the runtime via `crypto.randomUUID()` at the start of every runtime operation (`query`, prepared statement `query`, or `execute`). Per-operation identity (not per-plan), shared across all hooks within one operation, distinct across two operations of the same plan. Lives on the per-operation context, not on `PlanMeta`. Distinct from ADR 013's content-based `planId` and ADR 160's `groupingKey`. | [ADR 220 - Plan execution identity for middleware correlation.md](adrs/ADR%20220%20-%20Plan%20execution%20identity%20for%20middleware%20correlation.md) | | 266 | The cache middleware passes data to its store, and the store decides how to cache | The cache middleware works out each read's key and passes keys and opaque `meta` from annotations and `invalidate` to a pluggable store without interpreting them; the store decides how entries are grouped, how long they live, and keeps a version per key so a read that overlaps an invalidation cannot store stale rows, also across processes that share one store; tags, namespaces, strategies and request sharing are built by extensions, and a write can carry its invalidation, which the middleware runs once the write's effects are final | [ADR 266 - The cache middleware passes data to its store, and the store decides how to cache.md](adrs/ADR%20266%20-%20The%20cache%20middleware%20passes%20data%20to%20its%20store%2C%20and%20the%20store%20decides%20how%20to%20cache.md) | | 260 | Every query has an afterTransaction stage that fires when its enclosing transaction ends | **Superseded by ADR 271** (`activityFinalized` on a statement replaces `afterTransaction`). Adds an `afterTransaction(plan, result, ctx)` middleware hook that fires once per query with `committed`, `rolled-back` or `unknown`: right after `afterQuery`/`afterExecute` outside a transaction, and when the transaction's `commit()` or `rollback()` settles inside one; hook errors are logged and swallowed, and there is no transaction identity or transaction-level hook | [ADR 260 - Every query has an afterTransaction stage that fires when its enclosing transaction ends.md](adrs/ADR%20260%20-%20Every%20query%20has%20an%20afterTransaction%20stage%20that%20fires%20when%20its%20enclosing%20transaction%20ends.md) | | 271 | The runtime middleware observes a tree of activities, each started, ended and finalized | **Accepted.** An activity is one act by an actor (a statement, a transaction, an ORM call), with a parent to any depth; every activity has the lifecycle events `activityStarted`, `activityEnded` (`succeeded`, `failed` or `stopped`) and `activityFinalized` (`committed`, `rolled-back` or `unknown`), which fires right after the end with no transaction open and otherwise when the outermost enclosing transaction ends; statements also have the interceptors `beforeCompile`, `beforeEncode`, `intercept` and `onRow`, and `intercept` also serves client activities such as a cached ORM call; annotations live on the activity the user annotated, clients start activities through a queryable handle, a middleware keeps state with `ctx.state(key)`, and `afterTransaction`, the per-statement hooks and `groupingKey` become instances of it | [ADR 271 - The runtime middleware observes a tree of activities, each started, ended and finalized.md](adrs/ADR%20271%20-%20The%20runtime%20middleware%20observes%20a%20tree%20of%20activities%2C%20each%20started%2C%20ended%20and%20finalized.md) | ## Migration System | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 028 | Migration Structure & Operations | Defines migration file structure, on-disk formats, schemas, and operations for working with migration graphs | [ADR 028 - Migration Structure & Operations.md](adrs/ADR%20028%20-%20Migration%20Structure%20%26%20Operations.md) | | 037 | Transactional DDL Fallback | Specifies fallback behavior when adapters lack full transactional DDL support | [ADR 037 - Transactional DDL Fallback.md](adrs/ADR%20037%20-%20Transactional%20DDL%20Fallback.md) | | 038 | Operation idempotency classification & enforcement | The runner runs an operation's postchecks first and skips the operation when they all hold, so a postcheck may hold before the run only when the operation's full effect is in place; after the last operation the runner verifies the database against the end contract | [ADR 038 - Operation idempotency classification & enforcement.md](adrs/ADR%20038%20-%20Operation%20idempotency%20classification%20&%20enforcement.md) | | 039 | Migration graph path resolution & integrity | Specifies migration graph path computation, cycle detection, and deterministic tie-breaking | [ADR 039 - Migration graph path resolution & integrity.md](adrs/ADR%20039%20-%20Migration%20graph%20path%20resolution%20&%20integrity.md) | | 040 | Node task execution environment & sandboxing | Defines execution environment and sandboxing for migration node tasks | [ADR 040 - Node task execution environment & sandboxing.md](adrs/ADR%20040%20-%20Node%20task%20execution%20environment%20&%20sandboxing.md) | | 041 | Custom operation loading via local packages + preflight bundles | Establishes custom operation loading with security constraints and bundle support | [ADR 041 - Custom operation loading via local packages + preflight bundles.md](adrs/ADR%20041%20-%20Custom%20operation%20loading%20via%20local%20packages%20+%20preflight%20bundles.md) | | 043 | Advisory lock domain & key strategy | Defines advisory locking strategy for migration coordination and collision prevention | [ADR 043 - Advisory lock domain & key strategy.md](adrs/ADR%20043%20-%20Advisory%20lock%20domain%20&%20key%20strategy.md) | | 044 | Pre & post check vocabulary v1 | **Superseded.** Check shapes are now per-family: `{ description, sql }` for SQL ([ADR 028](adrs/ADR%20028%20-%20Migration%20Structure%20&%20Operations.md)), `{ description, source, filter, expect }` for MongoDB ([ADR 188](adrs/ADR%20188%20-%20MongoDB%20migration%20operation%20model.md)) | [ADR 044 - Pre & post check vocabulary v1.md](adrs/ADR%20044%20-%20Pre%20&%20post%20check%20vocabulary%20v1.md) | | 154 | Component-owned database dependencies | Sets component-owned verification as the target architecture; v1 uses adapter-owned ID-presence checks as a temporary compromise | [ADR 154 - Component-owned database dependencies.md](adrs/ADR%20154%20-%20Component-owned%20database%20dependencies.md) | | 161 | Explicit foreign key constraint and index configuration | **Superseded.** Foreign keys and indexes are discrete entities; a stored foreign key names its backing index (an index by name, the primary key, or a unique constraint by its columns), and the contract build removes duplicate indexes. The original per-FK booleans are kept as the record | [ADR 161 - Explicit foreign key constraint and index configuration.md](adrs/ADR%20161%20-%20Explicit%20foreign%20key%20constraint%20and%20index%20configuration.md) | | 166 | Referential actions for foreign keys | Adds optional `onDelete` / `onUpdate` action semantics to foreign keys and Postgres planner DDL emission (`ON DELETE` / `ON UPDATE`) | [ADR 166 - Referential actions for foreign keys.md](adrs/ADR%20166%20-%20Referential%20actions%20for%20foreign%20keys.md) | | 227 | Migration read commands share one graphical renderer with command-specific annotations | `migration list`, `graph`, and `status` all draw the same condensed tree; commands diverge only in per-edge `MigrationEdgeAnnotation` overlays keyed by `migrationHash`. Dagre deleted. Trunk = live-contract chain. `@contract` is app-space-only. Machine output stays flat. | [ADR 227 - Migration read commands share one graphical renderer with command-specific annotations.md](adrs/ADR%20227%20-%20Migration%20read%20commands%20share%20one%20graphical%20renderer%20with%20command-specific%20annotations.md) | | 228 | Migration apply ledger is a per-migration journal | One ledger row per applied edge (`space` + `migrationName` + `migrationHash` + `from`/`to` + `operationCount` + `appliedAt`). `migration status` reads it for applied/pending classification; `migration log` reads the unscoped flat table as the real apply history. | [ADR 228 - Migration apply ledger is a per-migration journal.md](adrs/ADR%20228%20-%20Migration%20apply%20ledger%20is%20a%20per-migration%20journal.md) | | 229 | Migration graph renderer uses a line/plane/occlusion model | The renderer is modelled around lines (not cells): each edge is a routed line carrying its own identity and colour, cells hold a z-ordered stack of lines, and the topmost line is drawn while the rest are occluded. Layout guarantees one drawable owner per cell (no tees, two columns per lane), so colour is correct by construction with no junction logic. | [ADR 229 - Migration graph renderer uses a line-plane-occlusion model.md](adrs/ADR%20229%20-%20Migration%20graph%20renderer%20uses%20a%20line-plane-occlusion%20model.md) | | 234 | Content-addressed wire names for Postgres-normalized objects | A Postgres-normalized object's physical name is `_<8 hex of SHA-256(canonical content)>`, so equivalence is a name match and the verifier never compares bodies the database reprints; a matching suffix under a different prefix is the rename signal | [ADR 234 - Content-addressed wire names for Postgres-normalized objects.md](adrs/ADR%20234%20-%20Content-addressed%20wire%20names%20for%20Postgres-normalized%20objects.md) | | 240 | Contract snapshots live in a content-addressed store | Every distinct migration contract is stored once per migrations root at `migrations/snapshots//contract.{json,d.ts}`, keyed by storage hash; the old per-package sibling contract files and per-space head copies are gone, and `migration.ts` imports resolve through the store. Amends ADR 197 and ADR 232. | [ADR 240 - Contract snapshots live in a content-addressed store.md](adrs/ADR%20240%20-%20Contract%20snapshots%20live%20in%20a%20content-addressed%20store.md) | | 243 | Name-identified indexes and exact-name adoption | Extends ADR 234's content-addressed wire names from RLS policies to every index, so expression and partial indexes become authorable and verifiable without comparing SQL bodies; adds an exact-name mode (`map:`/`@@map`) whose equivalence is content comparison, which makes a foreign database adoptable with zero operations; naming is a two-arm union (`wire`/`exact`) at construction with flat derived storage. Constraints stay outside the rule (amended: check constraints joined it in ADR 244). | [ADR 243 - Name-identified indexes and exact-name adoption.md](adrs/ADR%20243%20-%20Name-identified%20indexes%20and%20exact-name%20adoption.md) | | 244 | Check constraints are opaque wire-named expressions | Extends ADR 234's content-addressed wire names to a third object kind: a check is one opaque SQL predicate whose name commits to its content, so equivalence is name equality and introspection never parses a predicate. Supersedes ADR 156's structured `inSet` check shape. The target renders the SQL, the family composes and byte-caps the wire prefix, legacy exact-named checks adopt by drop + add rather than rename, and derivation is scoped to `managed` tables — the contract describes an external schema without prescribing enforcement for it. | [ADR 244 - Check constraints are opaque wire-named expressions.md](adrs/ADR%20244%20-%20Check%20constraints%20are%20opaque%20wire-named%20expressions.md) | | 239 | Errors are structural envelopes with dotted namespace codes | Every user-facing error is a structural envelope with a dotted `NAMESPACE.SUBCODE` code, recognized by field shape rather than `instanceof`, so it survives the control/execution split, the wire, and duplicate library copies; bugs take the separate `InternalError` path; the numeric `PN-DOMAIN-NNNN` codes retire against a published crosswalk. Amended 2026-08-11: a command that ran to its end and found problems reports them as diagnostics in a completed envelope with a documented `4`–`99` exit code (never a thrown failure at exit `2`), and the freeform `fix` prose field becomes typed `nextActions`. | [ADR 239 - Errors are structural envelopes with dotted namespace codes.md](adrs/ADR%20239%20-%20Errors%20are%20structural%20envelopes%20with%20dotted%20namespace%20codes.md) | | 245 | Errors are structured at origin; results carry one ok discriminator | Governs how ADR 239’s envelopes are built and carried: every surfaced failure is structured where it is raised, with its own dotted code, `why`, and typed `nextActions` (no catch-all codes; the generic factory takes the code as a required first argument; a non-structured error at a process boundary is a bug, exit 1); `code` is the error’s only machine identity (`meta` never carries an alternative one, and the error-reference registry records each code’s producing sites and meta shapes); every operation returns the shared `Result` with the single `ok` discriminator and a `CliStructuredError` failure (per-operation outcome enums banned). Error subclasses extend the one base class — structured data in `meta`, `name` untouched so structural recognition holds, no boundary mappers. Composer records the same rules as its ADR-0043/0044. | [ADR 245 - Errors are structured at origin; results carry one ok discriminator.md](adrs/ADR%20245%20-%20Errors%20are%20structured%20at%20origin%3B%20results%20carry%20one%20ok%20discriminator.md) | ## Guardrails & CI | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 022 | Lint Rule Taxonomy | Defines taxonomy and classification system for lint rules and violations | [ADR 022 - Lint Rule Taxonomy.md](adrs/ADR%20022%20-%20Lint%20Rule%20Taxonomy.md) | | 023 | Budget Evaluation | Establishes query budget evaluation and enforcement mechanisms | [ADR 023 - Budget Evaluation.md](adrs/ADR%20023%20-%20Budget%20Evaluation.md) | | 024 | Telemetry Schema | Defines telemetry schema and privacy controls for runtime observability | [ADR 024 - Telemetry Schema.md](adrs/ADR%20024%20-%20Telemetry%20Schema.md) | | 029 | Shadow DB preflight semantics | Superseded — the CLI never provisions a shadow database; diffing is fully offline against on-disk snapshots, and preflight is a database-extension hook | [ADR 029 - Shadow DB preflight semantics.md](adrs/ADR%20029%20-%20Shadow%20DB%20preflight%20semantics.md) | | 051 | PPg preflight-as-a-service contract | Superseded — the core preflight verb is abandoned; preflight is a database-extension hook, and Prisma Postgres will provide one | [ADR 051 - PPg preflight-as-a-service contract.md](adrs/ADR%20051%20-%20PPg%20preflight-as-a-service%20contract.md) | ## Extensions & Packs | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 017 | Extension Compatibility Policy | Establishes compatibility policy for extensions and alternate runtimes | [ADR 017 - Extension Compatibility Policy.md](adrs/ADR%20017%20-%20Extension%20Compatibility%20Policy.md) | | 104 | PSL extension namespacing & syntax | Defines namespaced PSL extension syntax and mapping to contract JSON | [ADR 104 - PSL extension namespacing & syntax.md](adrs/ADR%20104%20-%20PSL%20extension%20namespacing%20&%20syntax.md) | | 105 | Contract extension encoding | Specifies canonical extension section structure in contract JSON | [ADR 105 - Contract extension encoding.md](adrs/ADR%20105%20-%20Contract%20extension%20encoding.md) | | 106 | Canonicalization for extensions | Defines deterministic normalization rules for extension data | [ADR 106 - Canonicalization for extensions.md](adrs/ADR%20106%20-%20Canonicalization%20for%20extensions.md) | | 112 | Target Extension Packs | Establishes extension pack model as versioned, installable modules | [ADR 112 - Target Extension Packs.md](adrs/ADR%20112%20-%20Target%20Extension%20Packs.md) | | 113 | Extension function & operator registry | Defines function and operator registry for extension capabilities | [ADR 113 - Extension function & operator registry.md](adrs/ADR%20113%20-%20Extension%20function%20&%20operator%20registry.md) | | 114 | Extension codecs & branded types | Establishes codec model and branded types for extension values | [ADR 114 - Extension codecs & branded types.md](adrs/ADR%20114%20-%20Extension%20codecs%20&%20branded%20types.md) | | 115 | Extension guardrails & EXPLAIN policies | Defines guardrails and EXPLAIN policies for extension operations | [ADR 115 - Extension guardrails & EXPLAIN policies.md](adrs/ADR%20115%20-%20Extension%20guardrails%20&%20EXPLAIN%20policies.md) | | 116 | Extension-aware migration ops | Specifies extension-aware migration operations and capability gating | [ADR 116 - Extension-aware migration ops.md](adrs/ADR%20116%20-%20Extension-aware%20migration%20ops.md) | | 117 | Extension capability keys | Defines canonical capability keys and reserved namespaces | [ADR 117 - Extension capability keys.md](adrs/ADR%20117%20-%20Extension%20capability%20keys.md) | | 118 | Bundle inclusion policy for packs | Establishes bundle inclusion policy and security constraints for packs | [ADR 118 - Bundle inclusion policy for packs.md](adrs/ADR%20118%20-%20Bundle%20inclusion%20policy%20for%20packs.md) | | 121 | Contract.d.ts structure and relation typing | Complete specification for Tables, Models, and Relations namespaces with proper relation field typing | [ADR 121 - Contract.d.ts structure and relation typing.md](adrs/ADR%20121%20-%20Contract.d.ts%20structure%20and%20relation%20typing.md) | | 126 | PSL top-level block SPI | Defines SPI for packs to register new top-level blocks (views, enums, etc.); its parameter value-kind tables and descriptor-data validation are superseded by [ADR 262](adrs/ADR%20262%20-%20Block%20specs%20bind%20top-level%20block%20values.md) | [ADR 126 - PSL top-level block SPI.md](adrs/ADR%20126%20-%20PSL%20top-level%20block%20SPI.md) | | 129 | Tagged literals write values of data types | A qualified name followed by a string literal in backticks or quotes; the tag names the data type of the text; backtick strings only after a tag; one canonicalization for PSL and TypeScript; a tag is unprefixed when the family or a target owns its data type, by the rule in ADR 254; `sql` is the tag of the data type `sql/expression` and has no prefixed aliases; `` @default(sql`...`) `` is stored as the ordinary function-kind column default; a position with a fixed data type checks the tag while parsing through `dataTypeValue`; `contract infer` prints the SQL of indexes, checks and policies as `sql` literals and skips an exact-named object whose text would not read back unchanged | [ADR 129 - Template-Tagged Literals for Extensions.md](adrs/ADR%20129%20-%20Template-Tagged%20Literals%20for%20Extensions.md) | | 153 | Extension Package Naming Convention | Standardizes on `extension-*` prefix exclusively for extension pack npm names | [ADR 153 - Extension Package Naming Convention.md](adrs/ADR%20153%20-%20Extension%20Package%20Naming%20Convention.md) | | 214 | Extension operator surface: namespaced replacement operators and the predicate/helper split | Pattern for extension operators whose codec output cannot back a framework built-in's wire semantics: declare zero of the relevant traits + ship namespaced replacements. Predicate operators register as column methods through the operation registry; non-predicate operators (sort comparators, SELECT-expression accessors) ship as free-standing helper functions. Cipherstash is the canonical worked example. | [ADR 214 - Extension operator surface namespaced replacement operators.md](adrs/ADR%20214%20-%20Extension%20operator%20surface%20namespaced%20replacement%20operators.md) | ## Adapters & Targets | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 065 | Adapter capability schema & negotiation v1 | Defines adapter capability schema and negotiation protocol | [ADR 065 - Adapter capability schema & negotiation v1.md](adrs/ADR%20065%20-%20Adapter%20capability%20schema%20&%20negotiation%20v1.md) | | 068 | Error mapping to RuntimeError | Establishes stable mapping from engine/driver errors to RuntimeError envelope | [ADR 068 - Error mapping to RuntimeError.md](adrs/ADR%20068%20-%20Error%20mapping%20to%20RuntimeError.md) | | 263 | A serverless Postgres connection has the same query interface as a `postgres()` client | `postgres()` returns a client that serves every request from a pool; `postgresServerless()` returns a serverless client that holds no database connection, and each `postgres.connect({ url })` on it returns a connection that has every member of a client except `connect` and owns one database connection, which `await using` closes when the request ends | [ADR 263 - A serverless Postgres connection has the same query interface as a postgres client.md](adrs/ADR%20263%20-%20A%20serverless%20Postgres%20connection%20has%20the%20same%20query%20interface%20as%20a%20postgres%20client.md) | | 248 | PostgreSQL floor lowered to 15 | Amends ADR 222: the minimum supported PostgreSQL server version is 15 (previously 17), declared in `@internal/target-postgres`'s `package.json#prismaNext.minServerVersion`, mirrored by the CLI's `MIN_SERVER_VERSION`, and held equal by a drift test; 15 is the oldest version CI exercises, and nothing emitted or read needs more than 12 | [ADR 248 - PostgreSQL floor lowered to 15.md](adrs/ADR%20248%20-%20PostgreSQL%20floor%20lowered%20to%2015.md) | ## Development & Tooling | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 026 | Conformance Kit Certification | Defines conformance testing levels and certification requirements | [ADR 026 - Conformance Kit Certification.md](adrs/ADR%20026%20-%20Conformance%20Kit%20Certification.md) | | 027 | Error Envelope Stable Codes | Establishes stable error codes and envelope structure for consistent error handling | [ADR 027 - Error Envelope Stable Codes.md](adrs/ADR%20027%20-%20Error%20Envelope%20Stable%20Codes.md) | | 032 | Dev Auto Emit Integration | Specifies development tool integration for automatic contract emission | [ADR 032 - Dev Auto Emit Integration.md](adrs/ADR%20032%20-%20Dev%20Auto%20Emit%20Integration.md) | | 034 | Raw Plan factory manifest | Defines optional manifest for raw Plan factories with metadata | [ADR 034 - Raw Plan factory manifest.md](adrs/ADR%20034%20-%20Raw%20Plan%20factory%20manifest.md) | | 035 | Dual authoring conflict resolution | Specifies conflict resolution when both PSL and TS authoring exist | [ADR 035 - Dual Authoring Conflict Resolution.md](adrs/ADR%20035%20-%20Dual%20Authoring%20Conflict%20Resolution.md) | | 216 | CLI telemetry installation ID is a stored random UUID, not a system fingerprint | Adopts a stored v4 UUID under the user's config dir as the MAU dedup key; rejects MAC-hash, machine-id, IORegistry UUID, and Windows MachineGuid alternatives on trust, regulatory, and reset-symmetry grounds | [ADR 216 - CLI telemetry installation ID is a stored random UUID not a system fingerprint.md](adrs/ADR%20216%20-%20CLI%20telemetry%20installation%20ID%20is%20a%20stored%20random%20UUID%20not%20a%20system%20fingerprint.md) | | 217 | CLI telemetry runs in a detached subprocess spawned at command start | Forks the telemetry sender via `child_process.fork()` at command start (not exit); parent disconnects and unrefs immediately; child owns all I/O and swallows all errors; satisfies the strict isolation contract by construction rather than diligence | [ADR 217 - CLI telemetry runs in a detached subprocess spawned at command start.md](adrs/ADR%20217%20-%20CLI%20telemetry%20runs%20in%20a%20detached%20subprocess%20spawned%20at%20command%20start.md) | | 242 | Public npm surface: single `@prisma` scope with consolidated publish packages | The public surface is 17 `@prisma/*` packages — database facades, extension packs, framework/toolchain, families, targets — plus the `prisma` bin shim, all under `packages/9-public/`; every other workspace package is private and reaches npm only as a subpath entrypoint of a published shell (one module, one package, preserving registry/`instanceof` identity); framework runtime and tooling publish separately for serverless bundle weight; rejects a second `@prisma-orm` scope | [ADR 242 - Public npm surface - single @prisma scope with consolidated publish packages.md](adrs/ADR%20242%20-%20Public%20npm%20surface%20-%20single%20%40prisma%20scope%20with%20consolidated%20publish%20packages.md) | ## No-Emit Workflow | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 096 | TS-authored contract parity & purity rules | Ensures TS-authored contracts produce identical artifacts to PSL-first mode | [ADR 096 - TS-authored contract parity & purity rules.md](adrs/ADR%20096%20-%20TS-authored%20contract%20parity%20&%20purity%20rules.md) | | 097 | Tooling runs on canonical JSON only | Ensures tools consume canonical JSON artifacts, not TS source code | [ADR 097 - Tooling runs on canonical JSON only.md](adrs/ADR%20097%20-%20Tooling%20runs%20on%20canonical%20JSON%20only.md) | | 098 | Runtime accepts contract object or JSON | Defines runtime API for accepting both TS objects and JSON artifacts | [ADR 098 - Runtime accepts contract object or JSON.md](adrs/ADR%20098%20-%20Runtime%20accepts%20contract%20object%20or%20JSON.md) | | 099 | Contract authoring lint rules | Establishes ESLint rules for preventing non-deterministic contract authoring | [ADR 099 - Contract authoring lint rules.md](adrs/ADR%20099%20-%20Contract%20authoring%20lint%20rules.md) | | 100 | CI contract emission trust model | Defines sandbox and trust model for TS evaluation in CI environments | [ADR 100 - CI contract emission trust model.md](adrs/ADR%20100%20-%20CI%20contract%20emission%20trust%20model.md) | ## Migration Advisors | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 101 | Advisors Framework | Establishes uniform API for computing and surfacing migration advisories | [ADR 101 - Advisors Framework.md](adrs/ADR%20101%20-%20Advisors%20Framework.md) | | 102 | Squash-first policy & squash advisor | Defines policy for keeping migration graphs small through regular baselines | [ADR 102 - Squash-first policy & squash advisor.md](adrs/ADR%20102%20-%20Squash-first%20policy%20&%20squash%20advisor.md) | | 122 | Database Initialization & Adoption | Covers greenfield, brownfield-conservative, and brownfield-incremental adoption strategies including introspection, multi-service namespacing, and incremental contract expansion | [ADR 122 - Database Initialization & Adoption.md](adrs/ADR%20122%20-%20Database%20Initialization%20%26%20Adoption.md) | | 123 | Drift Detection, Recovery & Reconciliation | Comprehensive drift taxonomy (marker, schema, graph, capability, transactional, cache, canonicalization), detection mechanisms, and recovery strategies with idempotency patterns | [ADR 123 - Drift Detection, Recovery & Reconciliation.md](adrs/ADR%20123%20-%20Drift%20Detection%2C%20Recovery%20%26%20Reconciliation.md) | ## Product scope Requests answered with a no, with what to use instead. Every Accepted row is on the [steering list](#steering-list). | ADR | Title | Description | Link | | ----- | ------- | ------------- | ------ | | 286 | Prisma 8 does not fully manage native Postgres enums | A contract `enum` is stored with a `CHECK` constraint; native enums managed elsewhere only gain appended values | [ADR 286 - Prisma 8 does not fully manage native Postgres enums.md](adrs/ADR%20286%20-%20Prisma%208%20does%20not%20fully%20manage%20native%20Postgres%20enums.md) | | 287 | Prisma 8 has no `db push` to production | `db update` is for development; production changes go through `migration plan` and `db migrate` | [ADR 287 - Prisma 8 has no db push to production.md](adrs/ADR%20287%20-%20Prisma%208%20has%20no%20db%20push%20to%20production.md) | | 289 | Prisma 8 has no `$extends` client extensions | Extend with middleware (ADR 271), extension packages, contributed collection methods (ADR 272) and collection classes (ADR 265) | [ADR 289 - Prisma 8 has no $extends client extensions.md](adrs/ADR%20289%20-%20Prisma%208%20has%20no%20%24extends%20client%20extensions.md) | | 291 | Prisma 8 has no `$on` events | Middleware on the lifecycle events covers what `$on` did (ADR 271) | [ADR 291 - Prisma 8 has no $on events.md](adrs/ADR%20291%20-%20Prisma%208%20has%20no%20%24on%20events.md) | | 293 | Validations, soft delete and lifecycle hooks are not in the core | Each can be built in an extension or user code: arktype, a `notDeleted` scope, middleware | [ADR 293 - Validations, soft delete and lifecycle hooks are not in the core.md](adrs/ADR%20293%20-%20Validations,%20soft%20delete%20and%20lifecycle%20hooks%20are%20not%20in%20the%20core.md) | | 295 | New features do not land on Prisma 7 | Prisma 7 gets bug fixes and security updates, and no new feature work from the team; a community feature in line with Prisma 7's design that meets the quality bar may be accepted, as a maintainer decides (amended 2026-10-23) | [ADR 295 - New features do not land on Prisma 7.md](adrs/ADR%20295%20-%20New%20features%20do%20not%20land%20on%20Prisma%207.md) | | 296 | Prisma 8 has no `relationLoadStrategy` | Include the relation and the database joins it; there is nothing to choose | [ADR 296 - Prisma 8 has no relationLoadStrategy.md](adrs/ADR%20296%20-%20Prisma%208%20has%20no%20relationLoadStrategy.md) | | 298 | Prisma 8 has no fluent relation API | Load related rows with `.include(...)` | [ADR 298 - Prisma 8 has no fluent relation API.md](adrs/ADR%20298%20-%20Prisma%208%20has%20no%20fluent%20relation%20API.md) | | 299 | Prisma 8 has no `Prisma.skip` | No document names what to use instead | [ADR 299 - Prisma 8 has no Prisma.skip.md](adrs/ADR%20299%20-%20Prisma%208%20has%20no%20Prisma.skip.md) | | 300 | Prisma 8 has no `omit` under that name | Name the fields you want with `select(...)` | [ADR 300 - Prisma 8 has no omit under that name.md](adrs/ADR%20300%20-%20Prisma%208%20has%20no%20omit%20under%20that%20name.md) | | 301 | Prisma 8 has no `relationMode = "prisma"` | Use foreign keys in the database | [ADR 301 - Prisma 8 has no relationMode prisma.md](adrs/ADR%20301%20-%20Prisma%208%20has%20no%20relationMode%20prisma.md) | | 302 | Prisma 8 does not split large `IN` lists | `.include(...)` lets the database join, so Prisma 8 creates no large `IN` lists | [ADR 302 - Prisma 8 does not split large IN lists.md](adrs/ADR%20302%20-%20Prisma%208%20does%20not%20split%20large%20IN%20lists.md) | | 303 | Prisma 8 has no read replicas in the core | A separate `db` client for each data store | [ADR 303 - Prisma 8 has no read replicas in the core.md](adrs/ADR%20303%20-%20Prisma%208%20has%20no%20read%20replicas%20in%20the%20core.md) | | 304 | Prisma 8 has no automatic batching | Load related rows with `.include(...)`, which the database joins | [ADR 304 - Prisma 8 has no automatic batching.md](adrs/ADR%20304%20-%20Prisma%208%20has%20no%20automatic%20batching.md) | | 305 | Prisma 8 has no `P2002`-style error codes | Branch on the dotted `code` of the error envelope (ADR 239) | [ADR 305 - Prisma 8 has no P2002-style error codes.md](adrs/ADR%20305%20-%20Prisma%208%20has%20no%20P2002-style%20error%20codes.md) | | 306 | One plain-data definition and one builder per family | Every contract source of a family produces one plain-data definition and calls one builder, which returns refusals as keyed data | [ADR 306 - One plain-data definition and one builder per family.md](adrs/ADR%20306%20-%20One%20plain-data%20definition%20and%20one%20builder%20per%20family.md) | ## Notes - **ADRs 029 and 051** are superseded: the core-CLI shadow-DB preflight design is abandoned (diffing is fully offline against on-disk snapshots; preflight is a database-extension hook) - **ADR 156** is superseded: its `storage.sets` half by the value set described in ADR 157's October 12, 2026 amendment, and its check-constraint half by ADR 244 - **ADR 157** is partially superseded by its own October 12, 2026 amendment: the idea stands, and the amendment replaces how the contract realizes it - **ADR 170** is partially superseded by ADR 275: its field-preset half; type constructors and namespacing stand - **ADR 246** is superseded by ADR 275, except its two omission rules for `executionDefaults` and `typeParams` - **ADRs 104-118** form the core extension system architecture (decorators, attributes, capabilities, packs) - **ADRs 126-127** introduce PSL top-level blocks and views as composable extensions - **ADRs 096-100** cover the no-emit workflow for TypeScript-authored contracts ## Related Documentation - [Architecture Overview](../Architecture%20Overview.md) - High-level system architecture - [Subsystem Specifications](subsystems/) - Detailed subsystem documentation - [Extensions Glossary](../reference/extensions-glossary.md) - Extension terminology reference - [Capabilities Reference](../reference/capabilities.md) - Capability keys and namespaces