Summary
Adopt Prisma Next (prisma/prisma-next, v0.14.0, Early Access) for NetScript's DB layer as an
opt-in, additive Postgres engine path running alongside the existing classic Prisma 7 +
custom Zod-generator layer. This is Option A (Postgres-first pilot), staged to widen as upstream
matures — not a cutover.
Implementation is DEFERRED. This will not land this week, likely not this month. The value
delivered now is a locked, build-ready design + a live upstream gap tracker, so that the
moment a precondition clears we execute a pre-designed slice instead of re-researching a
fast-moving Early-Access surface. Full spec:
.llm/tmp/run/epic-prisma-next-migration--supervisor/spec.md (build-ready, 12 sections).
Child of the Road-to-0.0.1-stable umbrella epic.
Why Prisma Next (the real wins)
Why NOT a full cutover (verified against source @ v0.14.0)
Two of the epic's original premises do not hold on Early Access today:
- Standard Schema output is NOT a core feature. Prisma Next ships no per-model validator
codegen — only a not-yet-shipped consumer-library pattern (arktype reference). But the custom
Zod generator is a hard build-dep of every scaffolded service (@database/zod CRUD barrel →
createCrudContract). So the Zod generator cannot be deleted until a validator consumer
exists — we build our own over the contract IR (see spec §5).
- Multi-DB coverage is partial. Postgres 17 (GA-track) + MongoDB supported; SQLite is Node
node:sqlite path-only; MySQL planned (no date); Turso/libsql absent; MSSQL absent &
unplanned. NetScript ships Postgres + MySQL + MSSQL + SQLite. Only Postgres can move today.
Plus: Deno is best-effort tier-2 (Node 24 primary; every DB path pulls a Node builtin/native
dep) against NetScript's Deno-native runtime → a Node control-plane split is required (spec §4.4).
Scope
- In: an opt-in
postgres × prisma-next engine path (--impl prisma-next); a defineContract
TS-schema workspace shape; a Node control-plane for migrate/init/apply; our own
contract.json → Zod barrel validator consumer emitting the exact CRUD alias names scaffolded
services already consume (behind a delegation seam to a future upstream consumer); a ./zod compat
alias so userland contract.ts compiles unchanged; a new POSTGRES_PRISMA_NEXT scaffold.runtime
axis added alongside (never replacing) the classic Postgres axis.
- Out (non-goals): no cutover; no MSSQL/MySQL/SQLite move to Prisma Next; no deletion of any
classic generator file until its precondition is met; no production dependency on Prisma Next; no
Turso work (nothing is wired today); no changes to service/contracts/sdk/kv/plugin-*-core
public surfaces (all verified schema-agnostic).
Multi-DB guarantee (holds throughout)
| Engine |
Path today |
Prisma Next path |
Precondition |
Fallback |
| postgres |
classic (E2E) |
this pilot |
validator consumer (gap b) |
stay classic (default) |
| mysql |
classic (E2E) |
later |
MySQL engine (gap c) + b |
stay classic indefinitely |
| mssql |
classic |
later |
MSSQL support (gap a, unplanned) |
stay classic — NOT dropped |
| sqlite |
classic (scaffold-only) |
later |
SQLite promotion + Deno-viable binding |
stay classic |
| turso/libsql |
not wired |
n/a |
libsql driver (gap d) |
no-op — nothing to preserve |
At every phase each engine keeps at least its classic column green. The pilot only ever adds a
Postgres column. MSSQL is not dropped — "MSSQL-in-Prisma-Next" is tracked precondition (a).
Delete-list (precondition-gated — nothing removed in the pilot)
Removed only after (a) our validator consumer ships + green, (b) the pilot passes scaffold.runtime,
and — for the default to flip — (c) all five gaps closed. Wave B (repo-wide) waits until no engine
depends on the classic lane.
Grounded Wave-B delete-list
packages/database/scripts/{generate-zod,fix-zod-imports,patch-prisma-client}.ts
packages/cli/src/kernel/assets/database/scripts/{generate-zod,fix-zod-imports,patch-prisma-client}.ts.template
packages/cli/src/kernel/assets/database/zod-generator.config.json.template
packages/database/tests/zod-crud-barrel_test.ts
db:zod / db:fix-zod / db:patch-client tasks + the zod generator block in schema.prisma.template
KEEP: migrate.ts + retry (classic engines), all adapters, ports, extensions, tracing,
@netscript/prisma-adapter-mysql.
Acceptance criteria
- Opt-in scaffold (
--db postgres --impl prisma-next) does init/generate/seed with no
schema-engine subprocess and no retry activation.
- Scaffolded service
contract.ts type-checks unchanged via the ./zod compat alias.
deno task e2e:cli run scaffold.runtime --cleanup --format pretty green on both the new pilot
Postgres axis and the classic axes (classic byte-for-byte unchanged).
- Quality trio green (root
deno task check + lint + fmt:check); arch:check green (no heavy
Node deps in the default Deno graph); type soundness (no any beyond the two accepted casts).
Staging (each a focused PR; none runs until scheduled)
- Research + design — DONE (this issue + spec + gap tracker).
- Deno-compat + control-plane spike (throwaway) → picks data-plane architecture 4a vs 4b.
@netscript/prisma-next-validators (the validator consumer — unblocks everything).
@netscript/database-next + PrismaNextPostgresAdapter (port-conformant, subpath-only heavy deps).
- Scaffolder pilot path + CLI
--impl prisma-next.
scaffold.runtime POSTGRES_PRISMA_NEXT axis (the expensive merge gate).
6+. Widen per gap tracker as upstream lands each precondition.
Upstream gap tracker (watch-for — each fires a pre-scoped slice on close)
Re-check mechanism: monthly (or on any .llm/tools/deps/ dependency-review pass) fetch
api.github.com/repos/prisma/prisma-next/releases + roadmap/changelog, compare against the pinned
v0.14.0 baseline, re-run each gap's status check, flip checkboxes and schedule slices on close. Any
version bump re-runs the Phase-1 Deno-compat spike before further work.
Open questions for the user
- Default-flip policy — at what upstream milestone does the default scaffold move to Prisma
Next for Postgres? (Proposal: not before beta + validator consumer + Postgres GA.)
- Matrix policy — is a Postgres-only Prisma Next path acceptable long-term while other engines
stay classic (this spec's assumption), or must all engines move together?
- Validator branch — confirm building our own consumer (branch ii) with a delegation seam vs
waiting for upstream. (Recommendation: build ii.)
Summary
Adopt Prisma Next (prisma/prisma-next, v0.14.0, Early Access) for NetScript's DB layer as an
opt-in, additive Postgres engine path running alongside the existing classic Prisma 7 +
custom Zod-generator layer. This is Option A (Postgres-first pilot), staged to widen as upstream
matures — not a cutover.
Child of the Road-to-0.0.1-stable umbrella epic.
Why Prisma Next (the real wins)
defineContract→ canonicalcontract.json(code-free IR) +types-only
contract.d.ts. Contract-first, standards-leaning, DX-first — fits NetScript 1:1.ERR_STREAM_PREMATURE_CLOSEflake class thatpackages/database/scripts/migrate.tsworks aroundwith a bounded retry (fix(database): deterministic db init - bounded retry on transient Prisma schema-engine crash #98/fix(database): make CLI db-init deterministically reliable (eliminate scaffold.runtime flake) #145). On the pilot path, that retry becomes inert.
Why NOT a full cutover (verified against source @ v0.14.0)
Two of the epic's original premises do not hold on Early Access today:
codegen — only a not-yet-shipped consumer-library pattern (arktype reference). But the custom
Zod generator is a hard build-dep of every scaffolded service (
@database/zodCRUD barrel →createCrudContract). So the Zod generator cannot be deleted until a validator consumerexists — we build our own over the contract IR (see spec §5).
node:sqlitepath-only; MySQL planned (no date); Turso/libsql absent; MSSQL absent &unplanned. NetScript ships Postgres + MySQL + MSSQL + SQLite. Only Postgres can move today.
Plus: Deno is best-effort tier-2 (Node 24 primary; every DB path pulls a Node builtin/native
dep) against NetScript's Deno-native runtime → a Node control-plane split is required (spec §4.4).
Scope
postgres × prisma-nextengine path (--impl prisma-next); adefineContractTS-schema workspace shape; a Node control-plane for migrate/init/apply; our own
contract.json → Zod barrelvalidator consumer emitting the exact CRUD alias names scaffoldedservices already consume (behind a delegation seam to a future upstream consumer); a
./zodcompatalias so userland
contract.tscompiles unchanged; a newPOSTGRES_PRISMA_NEXTscaffold.runtimeaxis added alongside (never replacing) the classic Postgres axis.
classic generator file until its precondition is met; no production dependency on Prisma Next; no
Turso work (nothing is wired today); no changes to
service/contracts/sdk/kv/plugin-*-corepublic surfaces (all verified schema-agnostic).
Multi-DB guarantee (holds throughout)
At every phase each engine keeps at least its classic column green. The pilot only ever adds a
Postgres column. MSSQL is not dropped — "MSSQL-in-Prisma-Next" is tracked precondition (a).
Delete-list (precondition-gated — nothing removed in the pilot)
Removed only after (a) our validator consumer ships + green, (b) the pilot passes
scaffold.runtime,and — for the default to flip — (c) all five gaps closed. Wave B (repo-wide) waits until no engine
depends on the classic lane.
Grounded Wave-B delete-list
packages/database/scripts/{generate-zod,fix-zod-imports,patch-prisma-client}.tspackages/cli/src/kernel/assets/database/scripts/{generate-zod,fix-zod-imports,patch-prisma-client}.ts.templatepackages/cli/src/kernel/assets/database/zod-generator.config.json.templatepackages/database/tests/zod-crud-barrel_test.tsdb:zod/db:fix-zod/db:patch-clienttasks + thezodgenerator block inschema.prisma.templateKEEP:
migrate.ts+ retry (classic engines), all adapters, ports, extensions, tracing,@netscript/prisma-adapter-mysql.Acceptance criteria
--db postgres --impl prisma-next) does init/generate/seed with noschema-engine subprocess and no retry activation.
contract.tstype-checks unchanged via the./zodcompat alias.deno task e2e:cli run scaffold.runtime --cleanup --format prettygreen on both the new pilotPostgres axis and the classic axes (classic byte-for-byte unchanged).
deno task check+lint+fmt:check);arch:checkgreen (no heavyNode deps in the default Deno graph); type soundness (no
anybeyond the two accepted casts).Staging (each a focused PR; none runs until scheduled)
@netscript/prisma-next-validators(the validator consumer — unblocks everything).@netscript/database-next+PrismaNextPostgresAdapter(port-conformant, subpath-only heavy deps).--impl prisma-next.scaffold.runtimePOSTGRES_PRISMA_NEXTaxis (the expensive merge gate).6+. Widen per gap tracker as upstream lands each precondition.
Upstream gap tracker (watch-for — each fires a pre-scoped slice on close)
→ build an MSSQL pilot axis; until then MSSQL stays classic (never dropped).
ships (Zod/Standard-Schema-compatible, build-time, sound) → our consumer delegates to it; this is
the unlock that eventually lets the Zod generator be deleted.
When Postgres GA + beta channel confirmed → candidate to flip the default off classic (Wave B).
Re-check mechanism: monthly (or on any
.llm/tools/deps/dependency-review pass) fetchapi.github.com/repos/prisma/prisma-next/releases+ roadmap/changelog, compare against the pinnedv0.14.0baseline, re-run each gap's status check, flip checkboxes and schedule slices on close. Anyversion bump re-runs the Phase-1 Deno-compat spike before further work.
Open questions for the user
Next for Postgres? (Proposal: not before beta + validator consumer + Postgres GA.)
stay classic (this spec's assumption), or must all engines move together?
waiting for upstream. (Recommendation: build ii.)