Parent
#1122 — build spec 2 of the Prisma 8 architecture spec. Lands on the prisma-8 integration branch, not main.
Surfaced while fixing #1204 (which implemented #1144). Flagged by the implementer as a real ergonomic gap, out of that PR's scope.
Problem
context.unsafe.raw and context.unsafe.sql are typed as object when reached through the structural UnsafeCapableClient that the context uses to cross the seam. So the raw tag is untypeable from application code without a cast — and casts are banned by this repo's conventions.
The concrete symptom: examples/rag-openai-chatbot/scripts/install-pgvector.ts is exactly the migration-script use case the Unsafe surface exists to serve, and it could not route through context.unsafe. It now opens its own pg client against DATABASE_URL instead — which works, but means the stack's own example bypasses the surface the stack just built for that purpose.
This undercuts two of the spec's user stories directly:
- "As an app developer writing a migration script, I want the Unsafe surface to hand me Prisma's typed SQL builder and raw tag untouched, so that I have total fidelity with the cost stated." Untouched at runtime, yes — but not usably typed through the context.
- "As an app developer, I want
query(plan) on the Unsafe surface to return Prisma's streaming result, so that a bulk re-embed can consume rows with a cursor." A bulk re-embed is precisely a script that needs the raw tag.
The surface's own tests do not catch this because they build over a concrete client type, where the lanes are precise. Only a consumer reaching it through StackContext sees object.
What to build
Key the Unsafe surface's lanes to the app's emitted contract so sql and raw keep Prisma's own types through the context, rather than degrading to object at the structural boundary. packages/core/src/unsafe.ts carries a Known limits entry describing this as awaiting spec 3's contract keying — confirm whether spec 3 (#1123) actually closes it, and if so, close this as part of that work rather than duplicating it.
Whatever the mechanism, it must not reintroduce a cast: the surface is currently cast-free and that is worth preserving.
Acceptance criteria
Notes
Related: #1123 (spec 3, the secured surface's reads and the contract keying), #1129 (spec 9, examples and docs conversion).
Parent
#1122 — build spec 2 of the Prisma 8 architecture spec. Lands on the
prisma-8integration branch, notmain.Surfaced while fixing #1204 (which implemented #1144). Flagged by the implementer as a real ergonomic gap, out of that PR's scope.
Problem
context.unsafe.rawandcontext.unsafe.sqlare typed asobjectwhen reached through the structuralUnsafeCapableClientthat the context uses to cross the seam. So the raw tag is untypeable from application code without a cast — and casts are banned by this repo's conventions.The concrete symptom:
examples/rag-openai-chatbot/scripts/install-pgvector.tsis exactly the migration-script use case the Unsafe surface exists to serve, and it could not route throughcontext.unsafe. It now opens its ownpgclient againstDATABASE_URLinstead — which works, but means the stack's own example bypasses the surface the stack just built for that purpose.This undercuts two of the spec's user stories directly:
query(plan)on the Unsafe surface to return Prisma's streaming result, so that a bulk re-embed can consume rows with a cursor." A bulk re-embed is precisely a script that needs the raw tag.The surface's own tests do not catch this because they build over a concrete client type, where the lanes are precise. Only a consumer reaching it through
StackContextseesobject.What to build
Key the Unsafe surface's lanes to the app's emitted contract so
sqlandrawkeep Prisma's own types through the context, rather than degrading toobjectat the structural boundary.packages/core/src/unsafe.tscarries aKnown limitsentry describing this as awaiting spec 3's contract keying — confirm whether spec 3 (#1123) actually closes it, and if so, close this as part of that work rather than duplicating it.Whatever the mechanism, it must not reintroduce a cast: the surface is currently cast-free and that is worth preserving.
Acceptance criteria
context.unsafe.raw/.sqlgets Prisma's own types, with no cast and noanyexamples/rag-openai-chatbot/scripts/install-pgvector.tsroutes throughcontext.unsaferather than opening its ownpgclientKnown limitsentry inpackages/core/src/unsafe.tsis removed rather than left describing a fixed defectNotes
Related: #1123 (spec 3, the secured surface's reads and the contract keying), #1129 (spec 9, examples and docs conversion).