One binary answers platform, composer and ORM — and the grammar check guards every release - #164
Conversation
…e + rc1, STOPs open The slice contract for S7: mount the ORM family, make the grammar completeness check fail the build, create the prisma package, commit all product pins, and extend publish.yml to emit and verify the rc1 artifacts. Eight operator questions are open (trigger shape, the one action, package shape, exception-list ratification, S6 wiring, S8 ordering, pin convergence, publish credentials); nothing dispatches until they are ruled. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…is one binary Applies the operator's two rulings (2026-08-12): rc1 ships as @prisma/cli under the existing prisma-cli bin, with the bare prisma name a follow-up; the slice's goal is combining all available commands into one binary, with exception-list reconciliation also deferred. Closes STOP-2/3/4/8; records working defaults so D1/D2 proceed while STOP-1/5/6/7 stay open. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
… of a prisma package Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
`prisma migration list`, `prisma db verify`, `prisma init` and the rest of the ORM family existed in no binary this repo shipped. They were published in @prisma/orm-toolchain, mounted nowhere. This mounts the family in the v8 shell, so one binary answers platform, composer and ORM commands. The family keys its commands by the path they mount at, so the mount is its own map spread in whole; its `orm` config section, docs base and redirect table ride the family object, with nothing wired per command. Four group briefs (contract, db, migration, ref) join cliGroups. The dependency is exact and committed at 8.0.0-rc.1-dev.40, the interim version the contract's working default names. It pins @prisma/cli-engine 0.0.9 while this workspace ships 8.0.0-rc.1, the same second engine copy composer's pin already installs; both close when the rc lines converge. Tests: the mount-coverage check gains the family and its 22 paths, and a new v8-orm-mount suite runs `migration list` end to end against a fixture project (exit 0, real result), proves the config section is validated before a command runs, proves `migration apply` settles as the family's typed redirect, and proves the root help names the new groups. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
The mount-coverage check ran in the test suite only, and the publish path runs `pnpm build` plus `pnpm test:scripts` — so a tree missing a command could be packed and published without that check ever seeing it. It is now `pnpm check:grammar`: the same vitest file, run as a turbo task that builds its dependencies first and is never cached, wired into pr-quality.yml as its own required job and into publish.yml before the first publish step, under the same publish == 'true' condition its neighbours carry. Nothing is reimplemented; the check that guards the tree in tests is the check that guards the release. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
An 8.x publish whose declared bin was the retiring commander shell would misdescribe itself: `prisma-cli` resolved dist/cli.js, which answers no composer and no ORM command. The bin map now points at dist/v8/cli.js — the tree the grammar check guards. The legacy entry keeps building and shipping inside the tarball; deleting it is S2d. The new e2e test starts from the manifest rather than a hard-coded path: it reads the declared bin, runs it with --version on plain Node in a bare environment, and asserts the lockstep version comes back in the result envelope at exit 0. Piped stdout is not a TTY, so the shell answers in its JSON stream, and the test asserts the frame. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
|
Warning Review limit reached
Next review available in: 51 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Summary by CodeRabbit
WalkthroughThe S7 change mounts the ORM Toolchain command family into the v8 CLI and adds mount-completeness and behavior tests. It switches the declared 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
Operator review of the ORM mount: spreading the family's own command map made the family, not the shell, the source of truth for where its commands mount — against R12. The 22 mounts are now written out per path, like every other family's. Writing them out also put the ORM paths in front of the e2e-coverage scan for the first time (it reads the source text, and a spread has no keys to read). They are excluded with the reason the convention asks for: ORM commands never call the management API this suite covers — their real e2e lives in prisma/prisma per R7, and the shell proves composition in v8-orm-mount.test.ts per R8. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
The publish workflow built, checked the grammar, and published. Nothing between those steps ever installed the tarball the way a user would, so a packed artifact that could not start outside the workspace would have shipped without any check noticing. The pipeline now packs both publishable tarballs and installs the CLI's in a sandbox outside the repo: npm with --ignore-scripts (the runner holds id-token: write; third-party postinstalls do not run at the pipeline's most privileged moment), the unpublished engine resolved through a computed npm override with an absolute file: path and a version-qualified key, and every declared bin started on plain Node at exit 0 — which since the bin flip means the v8 tree, so the start crosses the composer and ORM import boundaries. The verified tarballs upload as workflow artifacts and attach to the GitHub Release, so what was verified is what is retrievable. The dry-run dispatch exercises all of it without registry writes. The override computation is a pure function with its own tests, run by test:scripts. The mechanics follow S6's check-3b design (ruled 2026-08-12: S7 carries the check itself while S6 lands in parallel), so the conformance slice absorbs this as a move, not a rewrite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
…ipeline Operator rulings 2026-08-12: the existing publish mechanisms stand (STOP-1); S7 carries the install smoke while S6 lands in parallel (STOP-5); pin convergence waits until 8.0.0-rc.1 publishes (STOP-7). STOP-6 closed by events - #162 merged first and this branch carries the merge. versioning.md documents the verification stage between the version decision and the registry; plan.md and deferred.md record where S7 stands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Operator ruling 2026-08-12: merging an RC-line bump PR must not move latest - the pre-v8 CLI keeps serving bare installs until the line is ready. Each release now publishes under its version's canonical dist-tag, decided by one pure function: next for 8.0.0-rc.N, latest for stable. The GitHub Release (with the smoked tarballs attached) follows releases rather than the latest tag, so RC releases get their prerelease Release too. The dispatch input's default changes from latest to empty, which resolves to the canonical tag - so a routine re-publish dispatch of an RC can never move latest by accident. Passing latest explicitly for an RC version is the deliberate cutover act, and the input says so. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with 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.
Inline comments:
In @.drive/projects/prisma-cli-v8/assets/rollout-plan.md:
- Around line 23-29: Update the RC dist-tag references in the rollout plan’s
table and step 4 to specify next only, removing any latest or rc alternatives
for RC versions. Keep the existing deliberate latest promotion guidance
unchanged.
In @.drive/projects/prisma-cli-v8/plans/s7-release.md:
- Line 22: Restore the Markdown heading hierarchy in plans/s7-release.md by
changing every `### D*` heading, including the headings identified in the
review, to `## D*`; leave the heading text and surrounding content unchanged.
In @.drive/projects/prisma-cli-v8/specs/s7-release.md:
- Line 227: Update the text beginning with “#162” in the release notes to avoid
Markdown interpreting it as heading syntax, using “PR `#162`” or an escaped hash
while preserving the statement’s meaning.
- Around line 278-279: Synchronize the S7 dispatch records with the final
rulings: in .drive/projects/prisma-cli-v8/specs/s7-release.md lines 278-279,
replace the STOP-5(a) and confirmed STOP-7 assumptions with STOP-5(b) and
deferred STOP-7; in .drive/projects/prisma-cli-v8/plans/s7-release.md lines
3-15, reference contract revision 2 and closed STOP-1/STOP-5 status; in lines
63-80, replace the STOP-5(a) blocked-pipeline plan with the selected
inline-smoke path; and in lines 98-103, remove the bare-prisma package
documentation task because that cutover is deferred.
In `@docs/oss/versioning.md`:
- Line 69: Update the publish workflow’s package-publishing step to tolerate
versions already present in npm, skipping those packages or otherwise handling
the registry conflict without failing the job. Ensure reruns continue to GitHub
Release creation and asset upload, while preserving failure behavior for
unrelated publish errors.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 71c0a3e6-fed4-4283-ad78-ee610652d9e4
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (26)
.drive/projects/prisma-cli-v8/assets/rollout-plan.md.drive/projects/prisma-cli-v8/assets/s2/parity-divergences-s7.md.drive/projects/prisma-cli-v8/deferred.md.drive/projects/prisma-cli-v8/plan.md.drive/projects/prisma-cli-v8/plans/s7-release.md.drive/projects/prisma-cli-v8/specs/s7-release.md.github/workflows/pr-quality.yml.github/workflows/publish.yml.gitignoredocs/oss/versioning.mdpackage.jsonpackages/cli/e2e/declared-bin.e2e.tspackages/cli/package.jsonpackages/cli/src/v8/cli.tspackages/cli/tests/e2e-coverage.test.tspackages/cli/tests/fixtures/v8-orm-project/migrations/.gitkeeppackages/cli/tests/v8-mount-coverage.test.tspackages/cli/tests/v8-orm-mount.test.tspnpm-workspace.yamlscripts/determine-version-utils.test.tsscripts/determine-version-utils.tsscripts/determine-version.tsscripts/tarball-smoke-utils.mjsscripts/tarball-smoke-utils.test.mjsscripts/tarball-smoke.mjsturbo.json
…the rulings Review findings (CodeRabbit). The substantive one: a workflow rerun or re-publish dispatch met npm's refusal to publish over an existing version and died before the Release step could repair a missing Release or its assets. The publish step now treats an already-published version as done and still fails on every other error. The rest are record consistency: the rollout table's @prisma/cli row follows the next-tag ruling; the spec and dispatch plan are marked revision 3 with the final STOP dispositions instead of the working defaults they were drafted against; two markdownlint complaints (heading levels, a line starting with #162) fixed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
packages/cli's bin points at dist/v8/cli.js — the same value PR #164 writes on its branch, byte for byte, so whichever lands second resolves a trivial conflict. The tsdown build drops the legacy entry, the root prisma and prisma-cli scripts point at the v8 bin, the prisma-v8 working name is gone, and six dependencies with no importer left (commander among them) leave the manifest. Proven from a packed tarball on plain Node: the declared bin resolves, --version answers with the lockstep version at exit 0, and auth whoami --format json settles signed-out with a sign-in next action. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
The S7 merge (#164) mounted the ORM family, whose grammar includes a top-level init — colliding with the platform's compute-config wizard this branch ports to the same path. Resolution ruled by the operator (2026-08-12): the ORM's project initializer mounts at `orm init`, and top-level `init` is the platform wizard, as the S2d contract wrote it. The merge also closes a coverage hole it exposed. The e2e coverage manifest's scan matched only quoted mount keys, so bare identifier mounts (init, feedback — and after this merge format, lsp, migrate) were invisible to the every-command-needs-a-happy-path rule. The scan now sees bare keys; init gains a real e2e happy path against the built binary (run against the live API before committing); the ORM paths take the family's existing exclusion reason; feedback is excluded because a per-CI-run post to the real feedback service is spam, not a test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
Records only — no code. Follows the S3 close-out precedent (#157). ## What this records The S7 contract's seven acceptance items verified against source, merged PRs (#164, #166), two dry-run dispatches, and the registry: `@prisma/cli@8.0.0-rc.1` and `@prisma/cli-engine@8.0.0-rc.1` are live under `next`, `latest` untouched — the project DoD's artifact exists, published by the operator's own action. The Close-out section in `specs/s7-release.md` records the evidence per acceptance item, the two incidents from the first real publish (npm's trusted publisher still naming the deleted `publish-cli.yml`; the immutable Release freezing assetless before its upload) with their dispositions, and the one deliberately amended item: "Release with tarballs attached" holds from #166 onward, not for `v8.0.0-rc.1` itself. `plan.md` marks the slice closed. `deferred.md` gains the offered-but-undecided publish-script extraction. ## Out of scope here The S5 cutover (brief in #167, dispatched elsewhere), S2d and S6 (both dispatched elsewhere), S9. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The grounding example
Before this branch, the unified CLI did not exist as a thing you could run:
After it, one binary answers all three families, the bin the package declares is that binary, and the publish pipeline proves the packed artifact survives a user's install before anything reaches the registry:
The decision
Six commits, in dependency order:
@prisma/orm-toolchain@8.0.0-rc.1-dev.40(exact, committed) contributesormCommandFamilyfrom its./clisubpath; config section, docs base and redirect table ride the family object. A newv8-orm-mountsuite runsmigration listend to end against a fixture project, proves section validation precedes the run, provesmigration applysettles as the typed redirect, and proves root help names the new groups.pnpm check:grammar— the same vitest file as a never-cached turbo task — running inpr-quality.ymlas its own job and inpublish.ymlbefore the first publish step.prisma-climoves fromdist/cli.js(the retiring commander) todist/v8/cli.js. The legacy entry keeps shipping in the tarball; its deletion is S2d. A new e2e test reads the declared bin from the manifest, runs it with--versionon plain Node in a bare environment, and asserts the lockstep version in the result envelope at exit 0.scripts/tarball-smoke.mjspacks both publishable tarballs and installs the CLI's in a sandbox outside the workspace: npm with--ignore-scripts(the runner holdsid-token: write; third-party postinstalls do not run at the pipeline's most privileged moment), the unpublished engine resolved through a computed npm override (absolutefile:path, version-qualified key — a pure function with its own tests), every declared bin started on plain Node at exit 0. Since the bin flip, that start crosses the composer and ORM import boundaries. The verified tarballs upload as workflow artifacts and attach to the GitHub Release; the dry-run dispatch exercises all of it without registry writes.next;latestwaits for the deliberate flip (operator ruling 2026-08-12). Each release ships under its version's canonical dist-tag —nextfor8.0.0-rc.N,latestfor stable — decided by one pure function. The GitHub Release (smoked tarballs attached, marked pre-release) follows releases, not thelatesttag. The dispatch input's default becomes "the canonical tag", so a routine re-publish can never movelatestby accident; passinglatestexplicitly for an RC is the cutover act.docs/oss/versioning.mddocuments the verification stage, plan and deferred entries updated.The operator's release action is exactly one: merging the
chore(release)bump PR. Everything between that merge and the published, Release-attached artifacts is the workflow — and while the line is RC, that merge publishes undernextand leaveslatestuntouched.Interim state, recorded
The orm-toolchain pin is a
dev-tag version and installs a second engine copy (0.0.9beside the workspace8.0.0-rc.1), the same shape composer's pin already has. Ruled 2026-08-12: convergence waits until8.0.0-rc.1publishes — the sequence (engine publish → product pin bumps → rc1 bump PR) is recorded indeferred.mdand the contract's STOP-7.Verification
Engine suite 795 passed; cli suite 1262 passed;
check:grammar10 passed; script tests 49 passed; declared-bin e2e 2 passed; tarball smoke green locally (2 packages packed, bin starts on plain Node);pnpm typecheckand rootpnpm lintexit 0. Two dry-run dispatches of the publish workflow ran green from this branch (runs 31601868449 and 31602392124): build → grammar check → script tests → pack + smoke → artifact upload → dry-run publish, with the real publish and Release steps correctly skipped; the second resolved the empty dist-tag input tonextfor8.0.0-rc.1. Branch carries main's S8 merge; the predicted mount-path collision resolved as the textual union.Alternatives considered
prismanpm package this slice — ruled out 2026-08-12; the bare name is not free untilprisma7ships. The cutover is recorded follow-up work.pnpm conformance— ruled out (STOP-5); S6 lands in parallel, and the smoke here is written to S6's check-3b design so absorption is a move, not a rewrite.🤖 Generated with Claude Code