Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 13 additions & 12 deletions .drive/projects/prisma-cli-v8/assets/rollout-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ unified CLI reaches npm, from first pre-release through owning the bare

| npm name | Today | End state |
| --- | --- | --- |
| `@prisma/cli` | Platform CLI 3.x, published from this repo (OIDC) | Carries v8 RC releases under `latest` via merged bump PRs; deprecated at cutover |
| `@prisma/cli` | Platform CLI 3.x, published from this repo (OIDC) | Carries v8 RC releases under `next` via merged bump PRs (`latest` stays pre-v8 until the deliberate flip; ruling 2026-08-12); deprecated at cutover |
| `prisma-next` | Prisma 8 ORM CLI, published from prisma/prisma `main` | Handed off to this repo at S5; rc channel for ORM early adopters; deprecated at cutover |
| `prisma7` | Does not exist yet | The v7-and-under release train's new home, published from prisma/prisma |
| `prisma` | Prisma 7 CLI, published by prisma/prisma's release train | Owned by this repo via OIDC trusted publishing; the unified CLI |
Expand All @@ -20,14 +20,13 @@ unified CLI reaches npm, from first pre-release through owning the bare
the automatic `dev`-tag publish on main merges continues and is
harmless.
2. **S2 done (platform family ported).** v8 RC-line versions
(`8.0.0-rc.N`) publish as `@prisma/cli` under **`latest`**, moved
only by a deliberately merged version-bump PR (operator ruling
2026-08-10, supersedes the earlier next-tag interim: "Me creating a
version bump PR and merging it counts as a deliberate explicit
action to alter latest"). This repo already owns the name with
OIDC; no cross-repo coordination. Semantically honest: the first
v8 surface is the platform family, i.e. the next major of the
platform CLI.
(`8.0.0-rc.N`) publish as `@prisma/cli`. Tag ruling reversed again
(operator, 2026-08-12, during S7): RC-line bump PRs publish under
**`next`**; `latest` keeps serving the pre-v8 CLI until the operator
moves it deliberately (an explicit `dist-tag: latest` dispatch, or
widening `releaseDistTag` when the line is ready). Merging the bump
PR remains the deliberate publishing act. This repo already owns the
name with OIDC; no cross-repo coordination.
3. **S5 done (ORM family ported).** The `prisma-next` name is handed
off: prisma/prisma stops publishing it and its npm trusted-publisher
config moves to this repo (npm allows one publisher config per
Expand All @@ -54,9 +53,11 @@ unified CLI reaches npm, from first pre-release through owning the bare
- Every publish path uses OIDC trusted publishing with provenance; no
pasted tokens anywhere (a manual-token fallback for prisma/prisma was
considered and rejected — the `prisma7` rename makes it unnecessary).
- `latest` moves only through a deliberately merged version-bump PR (or
a manual workflow dispatch), on any of the names (reworded per the
2026-08-10 operator ruling; previously "never moves automatically").
- `latest` moves only by an explicit operator act, on any of the names
(tightened per the 2026-08-12 ruling: RC-line bump PRs publish under
`next`, so on this repo's names even a merged bump PR cannot move
`latest` while the line is RC — only an explicit `dist-tag: latest`
dispatch or a stable-version bump can).
- Version pins across the tandem packages follow the committed-versions
ruling (S3).

Expand Down
44 changes: 44 additions & 0 deletions .drive/projects/prisma-cli-v8/assets/s2/parity-divergences-s7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# S7 parity divergences — mounting the ORM family

**No user-visible divergence from any shipping CLI is introduced by
S7.** This file exists because S2 standing ruling 10 requires
divergences to be enumerated rather than discovered, and because a
slice that changes the command tree has to say so explicitly when the
answer is "none".

Why the answer is none: S7 mounts commands that no binary this repo
ships could reach before. `prisma migration list`, `prisma db verify`,
`prisma init` and the rest of the ORM family answer for the first time.
Adding an invocation that previously did not exist changes nothing a
user already relied on.

The divergences between the ORM commands as they run under this shell
and as they run under `prisma-next` — the engine's shared flags, json
framing, channel discipline, the `{bin}` substitution in help examples,
and everything else the port changed — belong to S5, which owns that
record and keeps it in prisma/prisma alongside the port. S7 mounts the
family; it does not change what the family does.

Nothing already shipped changes behaviour: the platform and composer
commands keep their paths, flags and output, no group brief was
reworded, and no existing invocation was retired or moved. The ORM
family's own redirect table (`migration apply`, `migration ref`, and
four retired `migration status` flags) arrives with the family, so it
describes invocations of `prisma-next` that were already retired there,
not invocations this shell used to answer.

## One operational fact, not a divergence

`@prisma/orm-toolchain`'s `./cli` entry statically imports `esbuild`
and `arktype` (and eight `@prisma/orm-framework` subpaths), so every
invocation of this bin now pays that import — including `prisma
--version`, which touches no ORM code. Composer's family avoids this by
keeping its heavy graph behind dynamic executor imports; the ORM family
does not do the same yet.

This costs startup time, not correctness, and no user-visible output
changes because of it. Fixing it means moving orm-toolchain's handler
imports behind dynamic imports, which is prisma/prisma's change to
make, not this repo's. Mirrored in
[`../../deferred.md`](../../deferred.md) under "Upstream, not ours to
land".
40 changes: 39 additions & 1 deletion .drive/projects/prisma-cli-v8/deferred.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ Work identified during a slice that is not part of that slice's
contract. Each entry: what, why it was deferred, where it lands.
Nothing here is tracked outside this file.

## After S7's first real publish

- **The `v8.0.0-rc.1` GitHub Release has no tarballs attached, and
none can be added.** The first real `next` publish (2026-08-12, run
31618278670) published both packages to npm successfully, then the
Release step published the Release before uploading assets — and this
repo's releases are immutable, so the upload was refused (HTTP 422)
and the Release froze empty. npm is unaffected; the smoked tarballs
remain retrievable from that run's workflow artifacts (which expire
on the repo's retention schedule) and from npm itself. PR #165 fixes
the step for every future release (draft → attach assets → publish,
the order GitHub's own docs recommend). Repairing rc.1's Release
itself, if ever wanted: merge #165 first, try
`gh release delete v8.0.0-rc.1` (docs are silent on whether a
published immutable release can be deleted; the attempt is the test),
and if deletion works, re-dispatch the publish workflow — the
already-published npm versions are tolerated and the run recreates
the Release complete. Operator ruling (2026-08-12): cosmetic, not
immediate.

## Still open after S3/D4 — mostly the composer repo, two items need both

D4 landed the prisma-cli half (the mount, the node floor, the divergence
Expand Down Expand Up @@ -48,7 +68,13 @@ composer can use it.
and the honest reason is that it is not worth writing: matching pins
is a **release requirement for the tandem release**, so the two-copy
install is a preview-only state to end rather than a configuration to
support.
support. S7 update (operator ruling, 2026-08-12): the convergence
choreography is deferred until `8.0.0-rc.1` publishes; the S7 branch
adds a third pin in the same shape (`@prisma/orm-toolchain@
8.0.0-rc.1-dev.40`, also carrying engine `0.0.9`). The sequence, when
it runs: engine `8.0.0-rc.N` publishes from this repo → orm-toolchain
and composer bump their engine pins and publish → the rc1 bump PR
here pins those versions.
- **The prisma bin's mount makes composer's help examples wrong.**
Composer writes them as `{bin} deploy src/service.ts`; mounted under
the `composer` root the invocation is `prisma composer deploy`, and
Expand Down Expand Up @@ -172,6 +198,18 @@ composer can use it.
"repair" forever. The deploy path is unaffected (it plans on props
only — see the S8 note below), so this is a courtesy report to the
maintainer, not a blocker.
- **The ORM family's entry module loads esbuild and arktype on every
invocation.** `@prisma/orm-toolchain`'s `./cli` subpath statically
imports `esbuild`, `arktype` and eight `@prisma/orm-framework`
subpaths, so mounting the family (S7 D1) makes every run of this bin
pay that import — `prisma --version` included, which touches no ORM
code. Composer solved the same problem by keeping its heavy graph
behind dynamic executor imports; orm-toolchain has not. It costs
startup time only: no output and no exit code changes. The fix is
prisma/prisma's to land (dynamic handler imports in orm-toolchain's
CLI entry), and it closes when a published orm-toolchain's `cli.mjs`
no longer imports those modules at the top level. Recorded also in
`assets/s2/parity-divergences-s7.md`.

## Answered, feeding a later slice

Expand Down
6 changes: 1 addition & 5 deletions .drive/projects/prisma-cli-v8/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,7 @@ One standing caveat: every endpoint above is marked experimental and subject to

### S7 — Release pipeline + rc1

Repo: prisma-cli. The `prisma` binary package assembled: full grammar
tree mounted with the build-time grammar check, committed-versions
release automation, pinned product versions, and the pipeline emitting
a publishable `prisma@8.0.0-rc1` artifact from a tagged commit. Ends
when the operator can publish with one action (project DoD).
Repo: prisma-cli. **In flight (PR #164).** Ruled 2026-08-12: rc1 publishes under the existing names (`@prisma/cli`, bin `prisma-cli`); the bare-`prisma` cutover follows once `prisma7` frees the name. Shipped so far: the ORM family mounted (one binary answers platform, composer and ORM), the grammar check promoted to `pnpm check:grammar` running in `pr-quality.yml` and before every publish, the declared bin flipped to the v8 tree, and the tarball install smoke in the publish path (packed tarballs verified out-of-workspace on plain Node, uploaded as artifacts, attached to the Release). The operator's one action is merging the bump PR, per `docs/oss/versioning.md`. Engine-pin convergence is deferred until `8.0.0-rc.1` publishes (contract STOP-7).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Record the immutable v8.0.0-rc.1 Release exception.

Line 126 says tarballs are attached to the Release. The existing v8.0.0-rc.1 Release has no assets and cannot be modified or recreated. State that future Releases attach assets while draft, and record this exception.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.drive/projects/prisma-cli-v8/plan.md at line 126, Update the release-status
entry in plan.md to record that the immutable v8.0.0-rc.1 Release has no assets
and cannot be modified or recreated. Clarify that future Releases will have
tarball assets attached while still in draft, while preserving the existing
shipped-work summary.


### S9 — The error-code catalogue (last)

Expand Down
112 changes: 112 additions & 0 deletions .drive/projects/prisma-cli-v8/plans/s7-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# S7 dispatch plan — Release pipeline + rc1 (revision 3)

Contract: `../specs/s7-release.md` rev 1. One repo (prisma-cli), branch
`claude/s7-release-pipeline-rc1-92c89d`, base `main`. Implementers on
Opus, reviewers on Opus-4.8-mid. Standing process rules as in the S2/S3
plans: tests before implementation, no `vi.mock`/`vi.doMock`, pnpm only
(tarball smoke's sandbox npm install excepted, as ruled in S6), explicit
staging, bot identity with dual sign-off, push to the bot remote only.

Rulings applied (2026-08-12): the goal is all available commands in one
binary; rc1 publishes under the current names (`@prisma/cli`, bin
`prisma-cli`); the bare-`prisma` cutover and the exception-list
reconciliation are follow-up work. STOP-2/3/4/8 closed. **All STOPs closed
2026-08-12; D1–D6 shipped on PR #164.**

Ordering: D1 → D2 are independent of the release machinery and can run
while STOP-5/7/8 settle; D3 → D4 → D5 are strictly ordered (the package
must exist before the automation covers it, the automation before the
pipeline verifies it); D6 closes. One PR for the slice.

## D1 — Mount the ORM family (packages/cli)

Tests first: extend `v8-mount-coverage.test.ts` (fails until the mount
lands — the 21 expected paths, `ormCommandFamily` in
`MOUNTED_FAMILIES`); a `v8-bin` semantic test running one ORM command
end to end through `createTestCli` (`migration list` against a fixture
project directory: envelope, presented rows, exit 0); a redirect test
(`migration apply` settles as the typed redirect, exit per engine); a
`--help` test naming the `contract`, `db`, `migration`, `ref` groups.
Then: the `@prisma/orm-toolchain` dependency at the STOP-7(ii) interim
exact version; `cli.ts` imports the family from
`@prisma/orm-toolchain/cli`, spreads its commands, adds the four group
briefs. Watch for: the family keys are full mount paths already — no
renaming layer; config-section and redirects ride the family object.
Divergence file `assets/s2/parity-divergences-s7.md` opened (expected
content: "none"; plus the deferred.md entry for the static-import cost).

## D2 — The completeness check fails the build (repo root + CI)

Tests first: a fixture-level test proving the check reports (a) a
family command absent from the tree, (b) a mounted command owned by no
family and not excepted — both via a constructed family/tree pair, not
by mutating the real mount. Then: `check:grammar` as a turbo task
(`dependsOn: ["^build"]`, `cache: false`) running the mount-coverage
suite file; wired into `pr-quality.yml` and `publish.yml` before the
first publish step under its `publish == 'true'` condition. The
exception list gets a doc comment naming STOP-4's ratification and the
rule that additions require an operator ruling.
Reshaped by: STOP-4 (if utilities move into the platform family, the
exception set shrinks to the telemetry trio).

## D3 — The shipped bin becomes the v8 tree (packages/cli)

Per the 2026-08-12 ruling: no `prisma` package. Tests first: a
packaging test asserting the DECLARED bin (`package.json` `bin`
entry read, not a hard-coded path) is the v8 entry and that running
it with `--version` on plain Node in a bare env prints the lockstep
version at exit 0. Then: flip `bin.prisma-cli` from `./dist/cli.js`
to `./dist/v8/cli.js`. The legacy entry keeps building and shipping
in the tarball (S2d owns its deletion). Nothing else changes.

## D4 — Committed versions + conformance wiring (manifests + CI)

RESOLVED 2026-08-12: STOP-5(b) ruled — the inline smoke path below
shipped; STOP-7 deferred until `8.0.0-rc.1` publishes. The STOP-5(a)
branch is kept only as the record of the road not taken:
`packages/cli` pins `@prisma/composer` and `@prisma/orm-toolchain`
exact (already the style; versions per STOP-7); `pnpm conformance`
added to `publish.yml` before publish steps; the S6-3c interim
exception entries (dated triples, one per family) committed if the
pins have not converged by then.
If STOP-5(b): D4 instead implements the inline smoke per the contract
(S6 3b mechanics, ~40 lines, written to S6's spec so absorption is a
move), and the 3c pin comparison is NOT built here — the pins' exactness
is still asserted by the existing manifest style plus D5's install
smoke resolving a single engine copy.

## D5 — The pipeline (publish.yml + scripts)

Blocked by: STOP-1. Written against 1(a):
Tests first where testable: the override-computation helper (workspace
package → packed tarball map, recursive) as a pure function with its
own unit tests in `scripts/`; `determine-version` untouched (nothing
dynamic added). Then, in `publish.yml`: pack stage (engine + cli
tarballs via `pnpm pack` — order matters, packing rebuilds dist per
S6's finding 16, so the grammar check and conformance run before
packing); out-of-workspace install smoke (npm, `--ignore-scripts`,
absolute `file:` overrides, every declared bin from every packed
manifest started with `--version` under a timeout, exit 0 required —
after D3 the declared bin IS the v8 tree, so the smoke exercises the
composer and ORM family boundaries); tarball upload as workflow
artifacts; Release assets attached in the existing Release step.
Dry-run dispatch path covers pack + smoke + upload, skipping registry
writes and Release — this is the verification surface for the whole
slice (never a real publish from this work; a real publish is the
operator's action).

## D6 — Docs, records, close-out prep

`docs/oss/versioning.md` (the `prisma` package, the artifact stage, the
guarded publish); `rollout-plan.md` step 4 pointed at the pipeline;
`plan.md` §S7 updated; `deferred.md`: close the two-copy-install entry
when STOP-7 convergence lands, add the ORM import-weight entry; PR
description per the ruled structure (grounding example first,
alternatives last). Slice review loop (architect + principal-engineer
personas), findings folded, operator walkthrough.

Completeness: D1 → the tree; D2 → the check that guards it; D3 → the
package rc1 ships as; D4 → the pins and their verification; D5 → the
automated path from release commit to verified artifact; D6 → the
records. Together: the operator merges one bump PR and rc1's artifacts
exist, verified, published where the registry allows.
Loading