Skip to content

The prisma-composer binary is gone and nothing names it - #331

Merged
wmadden-electric merged 24 commits into
mainfrom
one-config-file/remove-binary
Oct 5, 2026
Merged

wmadden-electric merged 24 commits into
mainfrom
one-config-file/remove-binary

Conversation

@wmadden-electric

Copy link
Copy Markdown
Contributor

Slice 2 of the one-config-file project (spec in prisma/orm#30536), stacked on #328. After this PR there is no prisma-composer binary and nothing in the repository tells anyone to run one.

// examples/orm-demo/package.json
"scripts": {
  "deploy": "bun ../../node_modules/.bin/prisma deploy module.ts",
  "dev":    "bun ../../node_modules/.bin/prisma dev module.ts",
  "destroy": "bun ../../scripts/composer-destroy.ts module.ts --production"
},
"devDependencies": { "prisma": "catalog:" }
$ pnpm lint:retired-binary-name
docs/guides/testing.md:12: `prisma-composer deploy` names the retired binary; write `prisma deploy`

The decision

@prisma/composer-cli stops shipping a bin. The standalone command-line tool, its destroy and log commands, its runtime shell and the pass-through orm section it mounted so a shared config would load are deleted. Every guide, README, skill, error message and comment names prisma deploy and prisma dev; teardown and logs are the destroy and log operations on @prisma/composer/control, which stay and gain their own tests. A lint fails CI when the retired name comes back. The root version advances to 0.26.0 so the merge publishes a release. This closes TML-3340.

How the repository exercises its own family without a binary

The examples and CI used the binary to run the code under test. The published prisma host pins @prisma/composer-cli@0.25.0, so running it inside the workspace would test last release's family. The fix is one root pnpm.overrides entry pointing @prisma/composer-cli at the workspace, plus a root devDependency on it, which the hoisted linker needs to place the link where the hoisted host looks. Every example, test/integration and website declare prisma through a pnpm catalog entry and import definePrismaConfig from prisma/config, exactly as a user's project does. A check in the engine-pin script now proves the host resolves the workspace family and that host and family share one engine copy, with tests that make each assertion fail.

Two consequences of the hoisted linker are visible in package scripts and nowhere a user reads: the prisma bin exists only in the root node_modules/.bin, so scripts call it by a repo-relative path, and they keep the bun prefix because the example services use Bun APIs. The guides say to run under Node by default and under Bun when your services need it.

Teardown without a command

prisma has no teardown command, by the project's decision. CI's deploy-verify-destroy action, the docs-site deploy, the cron canary, the destroy guard and the examples' destroy scripts now call scripts/composer-destroy.ts, a repo-private script over the programmatic destroy that imports the app's prisma.config.ts and passes its composer section. Its four failure paths have documented exit codes and tests, and scripts/ is now typechecked so a change to the operation's input fails typecheck. The guides show the same script shape for users and put the credentials story in one place: prisma auth login or PRISMA_SERVICE_TOKEN for the commands, PRISMA_SERVICE_TOKEN plus PRISMA_WORKSPACE_ID for the operations.

The lint

scripts/lint-retired-binary-name.mjs scans README.md, root markdown, docs/guides, docs/oss, skills, skills-contrib, examples, website, .github and shipped source under packages/ for any standalone prisma-composer token, bin/prisma-composer, ./prisma-composer, .cmd/.js forms and the config-file name. Package and directory names like prisma-composer-core-concepts, the .prisma-composer/ state directory and prisma-composer.map.json are excluded by a boundary pattern. The migration passages that name the retired config file on purpose, the legacy-file diagnostic, and two historical records in gotchas.md are allowlisted by path and exact count, so an added mention still fails and a stale allowlist entry fails too. Dated project records under .drive/ and the friction report are not scanned; rewriting them would make them inaccurate.

Removed public surface, for the release notes

  • @prisma/composer-cli: the prisma-composer bin.
  • @prisma/composer-cli/testing: createControlDouble is now createOperationsDouble; ControlDouble, ControlDoubleCalls, ControlDoubleFixtures are now OperationsDouble, OperationsDoubleCalls, OperationsDoubleFixtures; the double no longer has destroy or log operations, the destroy, destroyEvents, log, logAppName, logServices, logLines fixtures, or the destroy/log entries in calls.
  • @prisma/composer-cli/family: unchanged; the host's startup probe matches dist/family.mjs.
  • @prisma/composer/control: unchanged; destroy and log stay.

Verification

  • Root typecheck (now including scripts/), lint, lint:deps, cast count unchanged at 21, test:scripts (224), lint:retired-binary-name, check:cli-engine-pin with the new host assertions, check:skill-packaging, check:publish-deps, check:family-static-graph, check:floor-imports, the website content test, and the cli, core, target, dev-emulators and local-target suites pass. pnpm install --frozen-lockfile is clean.
  • check:npm-effect-resolution run with network after building the tarballs: all shapes pass; the healthy shapes now prove it by importing the family module and Alchemy instead of running a binary.
  • From examples/orm-demo, bun ../../node_modules/.bin/prisma deploy --help printed a marker temporarily added to the workspace family, proving the host runs the code under test; the marker was removed.
  • The three local-dev proofs pass individually. The real-cloud deploy with prisma deploy and teardown with the script run in this PR's e2e workflow for the first time.

Alternatives rejected

  • A private, unpublished dev binary for the repository's own CI. It would have been the standalone tool under another name, with its own drift from the host.
  • Running prisma without the override. It would test the previous release's family.
  • Rewriting the dated project records. They describe what was true when written.

Agent: columbo-17

🤖 Generated with Claude Code

@prisma-gizmo

prisma-gizmo Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Warning

Gizmo skipped this review: 143 reviewable files exceeds the 100-file limit. Split the PR or review it manually.

@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: fb7b7843-d023-4c5d-9c56-b7aa172ce8a1
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@prisma/composer@331
npm i https://pkg.pr.new/@prisma/composer-cli@331
npm i https://pkg.pr.new/@prisma/composer-prisma-cloud@331

commit: 840bb0a

Base automatically changed from one-config-file/composer-section to main October 1, 2026 06:40
@wmadden-electric
wmadden-electric force-pushed the one-config-file/remove-binary branch from be95770 to 07e3465 Compare October 1, 2026 07:52
Comment thread scripts/check-cli-engine-pin.mjs Fixed
wmadden-electric and others added 23 commits October 5, 2026 11:53
…orkspace family

Every example, the website and test/integration now declare prisma@8.0.0-rc.19
(the host whose bin is `prisma`) and import definePrismaConfig from
prisma/config, the way a user project does. @prisma/cli-engine was only there
for definePrismaConfig, so it goes.

The published host pins @prisma/composer-cli@0.25.0 from the registry. A root
pnpm override points it at the workspace package, so inside this repository the
host mounts the family under test. The repo installs with node-linker=hoisted,
which hoists prisma to the root node_modules and does not create the overridden
link beside it; the root devDependency on @prisma/composer-cli puts the link
where the hoisted host resolves it.

test/integration pinned prisma@7.9.0. Nothing has used it since the local
Postgres emulator started resolving @prisma/dev from Composer itself, so it is
replaced by the host rather than kept alongside it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
The prisma CLI has deploy and dev but no destroy, and the examples and CI
still need to tear stacks down. scripts/composer-destroy.ts takes the same
arguments the old command did (<entry>, --production or --stage <name>,
optional --name), imports the composer section of the prisma.config.ts in the
current directory, and calls destroy from @prisma/composer/control resolved
from the app's own dependencies. A failure prints the structured error and
exits 1; bad arguments exit 2 before anything runs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
… script

Example deploy scripts, the deploy-verify-destroy action and the docs
workflow run the installed prisma bin under Bun instead of prisma-composer.
Bun stays because Load imports service modules that use Bun APIs, and the
prisma bin has a node shebang. The path is the root node_modules/.bin: the
repo installs with node-linker=hoisted, which links bins of hoisted packages
only at the root.

Example destroy scripts and destroy-guard.sh call scripts/composer-destroy.ts
with the same arguments as before, so the per-run --name, the stage handling
and the guard behaviour are unchanged. The cron canary reaches both through
the action.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…composer

The extension-config test and the two local-dev proofs now spawn the prisma
bin, which mounts the workspace family through the root override, so they
prove what a user runs. The bin is found by walking up to the nearest
node_modules/.bin that links it, because the hoisted install puts it at the
repository root rather than in each package.

cli.engine-shell tested only the standalone binary: its version, its help
listing destroy and log, and the engine exit codes it passed through. The
host owns all of that now, so the file goes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@prisma/composer-cli now ships only the command family and the testing
double. The manifest declares no bin and the tsdown config has no executable
bundle, so the packed tarball has no dist/bin.mjs.

The release checks stop expecting the executable. check-cli-engine-pin keeps
proving the engine stays external through the whole-dist sweep, which now
means family.mjs. check-family-static-graph walks family.mjs and testing.mjs.
check-npm-effect-resolution replaces running --help on the bin with importing
@prisma/composer-cli/family from the scratch install and listing its
commands: every healthy shape must mount deploy and dev, and the family must
still import in the broken tree, which is the same start-up guarantee without
a binary.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
The prisma host mounts the family and nothing runs the standalone shell any
more, so it goes: bin.ts, cli.ts, engine-cli.ts, the Node runtime adapter it
composed, the destroy and log commands it mounted on top of the family, the
target flag parser only destroy used, and the pass-through orm section.

destroy and log leave the family seam (ComposerOperations, realOperations and
the published control double), because only the deleted commands called
them. They stay programmatic operations on @prisma/composer/control, and a
new test drives each through that entry.

Tests that only proved the shell (host-adapter, runtime, node-compat and the
createComposerCli cases) go; the node-floor CI steps that ran the binary go
with them. The remaining family and section tests move to family.test.ts, and
deploy-destroy.test.ts keeps its deploy cases as deploy.test.ts. The legacy
prisma-composer.config.ts rule stays covered in section.test.ts and
operations.test.ts.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
The standalone binary is gone, so text that told users to run it now names
the command they have. The dev emulator and local preflight messages say
`prisma dev`, the generated stack-file headers name the operations that
write them, and the destroy-production remedy no longer cites a flag of a
command that does not exist. Comments across core, lowering, target, auth,
the examples and the integration tests follow. The streams entrypoint's
unused R2 account placeholder and the auth bootstrap header stop borrowing
the old name, and the log operation's doc no longer cites main.ts.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…l operations

The guides, README, skill and example README stop naming the standalone
binary. deploy and dev are `prisma deploy` and `prisma dev`. Teardown and
logs have no prisma command, so deploying.md and running-locally.md each show
a short script over the destroy and log operations of
@prisma/composer/control, and the skill mirrors both tersely.

Credentials change with the host: `prisma deploy` needs a signed-in identity
(`prisma auth login`, or PRISMA_SERVICE_TOKEN in CI), where the old binary
took only environment variables; the destroy operation still reads
PRISMA_SERVICE_TOKEN and PRISMA_WORKSPACE_ID. The skill's "no interactive
auth" gap is replaced by the missing teardown and log commands.

getting-started.md and running-locally.md drop the "[dev] logs:" line from
the sample dev output, which dev never prints. The migration passages that
name the retired config file stay. Contributor docs, the issue template, the
gitignore comment and three agent rules follow; user-facing-surface-changes
now points at the skill's real path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…nary

scripts/lint-retired-cli-name.mjs scans README.md, docs/guides, skills,
skills-contrib, examples, website and .github. It fails on the old binary as
a command (followed by a command word or flag, after bin/, or after a package
runner) and on the retired config-file name outside an allowlist of the
migration passages, given per file with the exact mention count so an added
mention still fails and a removed one flags the stale entry. Names that only
start with the old name (packages, the skill, the state directory, the map
file) are not mentions. It runs as its own step in the CI lint job, and its
test plants a command and an allowlist mismatch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Removing the prisma-composer binary and reading configuration only from the
composer section of prisma.config.ts are breaking changes, so this release
advances the minor version. pnpm bump-minor set 0.26.0 in all 41 workspace
manifests (and their workspace: specifiers), the lockfile, and the skill's
metadata.library_version.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Nothing imports @internal/cli itself; the entry existed for the binary's cli()
and shippedVersion(). The barrel, its tsdown entry, the exports-map line, the
types field and the dependency-cruiser alias go.

The WithDeps operation variants stay: 21 unit tests of destroy and log inject
fake converges and identities through them. Their comments now say that,
instead of citing the deleted CLI's RunDeps.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
createControlDouble doubles the operations the command family calls
(ComposerOperations: deploy and dev), not the four operations of /control.
It is now createOperationsDouble, with OperationsDouble, OperationsDoubleCalls
and OperationsDoubleFixtures, in operations-double.ts. Its doc says it does
not cover destroy and log. The name change is breaking for hosts that import
it from @prisma/composer-cli/testing and ships in 0.26.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…list

The check proves the family loads from a real install, including in a tree
whose effect breaks alchemy. It required the family to mount exactly deploy
and dev, so adding a command would have failed a dependency-resolution check.
It now requires deploy, the command whose graph effect affects; the family's
own test owns the full list.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…e operation's types

composer-destroy.ts imports DestroyTarget, DestroyEvent, CliStructuredError,
ComposerConfigSource and the destroy signature from @prisma/composer/control
as types, instead of restating them. A control entry that does not resolve, a
config file that throws on import or declares no composer section, and a
destroy call that throws each print one line and exit 1, as the header says,
instead of escaping as a raw stack. --config names a config file other than
./prisma.config.ts; the header says the script does not search parent
directories.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
… one engine

The examples and CI run the published prisma host, redirected to the
workspace family by a root pnpm override and a root devDependency. Nothing
checked that arrangement: a drifted override would let CI test the
registry's family and stay green, and a host bump that moves its engine
would load two engines.

check-cli-engine-pin now resolves @prisma/composer-cli/family from the
installed host and requires the workspace package, requires the host's own
@prisma/cli-engine pin to equal the workspace's, and requires the host and
the family to resolve the same engine copy. The host version moves into the
pnpm catalog, every manifest declares prisma as catalog:, and the check
rejects any other specifier. Dependabot ignores prisma for the same reason
it ignores the engine. gotchas.md explains why the override needs the root
devDependency under the hoisted linker. The root also depends on
@prisma/composer so the destroy script's type imports resolve.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
lint-retired-cli-name only matched the name followed by a word, so a wrapped
shell line, a bare `$ <name>` prompt, a package runner with `--` and a
backticked name all passed. It now flags every standalone token of the old
binary name, plus `bin/<name>` and the retired config file; names that only
start with it (packages, skill, state project, state directory, map file)
stay out by boundary, and a sentence-ending period still ends the token.

It now scans the root Markdown files, docs/oss and the packages' shipped
source too, where error messages and generated headers live; package tests
and fixtures are skipped, and only the two gitignored generated copies
(the rendered site and the staged skill) are excluded by path instead of
every folder named generated. The allowlist gives each deliberate file its
exact finding count: the two migration passages, the legacy-file diagnostic,
and the historical records in gotchas.md and open-chat-port-friction.md. The
test checks every allowlisted file exists.

It is renamed lint-retired-binary-name: the CLI is prisma and is not retired;
the binary name is. The two gotchas.md lines that record what was run at the
time go back to their original wording.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…cript imports

deploying.md states in one place how each surface signs in: `prisma deploy`
uses the prisma CLI's session (`prisma auth login`, or PRISMA_SERVICE_TOKEN
in CI), while the /control operations, and so a destroy script, never use
that session: deploy and destroy read PRISMA_SERVICE_TOKEN and
PRISMA_WORKSPACE_ID, which the Prisma Cloud container requires once it is
reached, and dev and log read neither. The destroy script says how to run it,
and getting-started tells a reader who only signed in that teardown needs
the two variables.

A new Runtime section says the bin starts under Node and runs under Bun only
when the modules module.ts imports use Bun APIs, which is the form the
examples use; getting-started says why pnpm prisma suits its app. "Driving
deploys from code" says a script imports only @prisma/composer/control, and
that extension /control entries are imported only by prisma.config.ts
(ADR-0017).

The store README says `prisma dev` and `prisma deploy` and points teardown
at the guide's script instead of a repository-relative bin path. The skill
mirrors all of it, and lists the teardown credential gap.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Node appends a require stack to module-not-found errors. The host checks now
quote only the first line, so the failure list stays one finding per line.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Nothing typechecked scripts/*.ts, so the destroy script's type import from
@prisma/composer/control checked nothing: a change to DestroyInput failed no
job. scripts/tsconfig.json extends the base config, and the root typecheck
runs it after the packages build (turbo builds @prisma/composer first). Eight
older scripts and tests that do not yet pass the strict base options are
excluded by name.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…sions

The pin check required the published host to declare the workspace's engine
pin. The release order is engine, then Composer, then the host, so between
releases the host declares an older engine; the check would have failed CI
and the publish job for no runtime reason. It now requires only what matters
at run time: the host resolves the workspace @prisma/composer-cli, and the
host and the family resolve the same @prisma/cli-engine copy. A mismatch names
the root engine override as the fix during a tandem release.

The host checks move to check-cli-engine-pin-host.mjs with a test that makes
each fail on a scratch tree: a nested registry copy of the family, a missing
root link, two engine copies. An unbuilt family now says to build
@prisma/composer-cli instead of blaming the override.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…every package folder but __tests__

The token pattern skipped `./prisma-composer` (a preceding slash) and
`prisma-composer.cmd` or `.js` (a following dot and word). A preceding `/` now
excludes only a path segment, not `./`, and only `.config` and `.map` after the
name mark another file. Under packages/ the walker skipped any folder named
test or fixtures at any depth; it now skips only __tests__ folders and
*.test.* files. The test adds each missed case.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…es its real republisher

The store README now writes `pnpm prisma dev` and `pnpm prisma deploy`, the
form getting-started uses. The cli package's testing entry is republished
through @prisma/composer-cli/testing, not @prisma/composer/testing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…ags are

gotchas.md says the examples declare @prisma/composer-cli so CI's filtered
build produces the family dist the host loads. The destroy script's header
says --production and --stage <name> spell the operation's two targets for
the examples' package scripts only, and that no prisma command takes them.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
…cktracking regex

The old pattern over the whole pnpm-workspace.yaml backtracked
catastrophically when catalog: was followed by long whitespace lines.
A test feeds that input and requires it to finish within 100ms.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@wmadden-electric
wmadden-electric force-pushed the one-config-file/remove-binary branch from 07e3465 to 840bb0a Compare October 5, 2026 10:00
@wmadden-electric
wmadden-electric merged commit a91a6dc into main Oct 5, 2026
26 checks passed
@wmadden-electric
wmadden-electric deleted the one-config-file/remove-binary branch October 5, 2026 13:28
RyanGarber pushed a commit to RyanGarber/prisma-orm-tmep that referenced this pull request Oct 9, 2026
```
$ git diff --stat main...HEAD | tail -1
 25 files changed, 1 insertion(+), 2833 deletions(-)
```

This closes the one-config-file project. It deletes the project's
working folder, `projects/one-config-file/`, and fixes one duplicate
number in the failure-mode catalogue. Linear: TML-3340.

The project moved Prisma Composer's configuration out of its own
`prisma-composer.config.ts` into the `composer` section of
`prisma.config.ts`, and deleted Composer's standalone `prisma-composer`
binary. Prisma 8 now has one CLI and one config file. The rest of this
description is the close-out record the Drive process asks for: what was
checked, where each decision now lives, and where each unfinished item
is tracked.

## What was delivered

| PR | What it did |
| --- | --- |
| prisma/composer#328 | Composer's configuration is the `composer`
section of `prisma.config.ts`. The old file and `configPath` are
refused. |
| prisma/composer#331 | The `prisma-composer` binary is gone. Docs,
examples and the shipped skill say `prisma deploy` and `prisma dev`.
Released as Composer 0.26.0. |
| prisma/prisma-cli#330 | The `prisma` host runs Composer 0.26.0.
Released as `prisma@8.0.0-rc.20`. |
| prisma/web#8387 | The public Composer docs describe the `composer`
section. |
| prisma/composer#332 | Found during testing: `prisma dev` and `prisma
deploy` failed in pnpm projects. Merged, not yet released (TML-3520). |
| prisma/composer#333 | An emulator test race that made CI flaky, plus
`PRISMA_COMPOSER_EMULATORS_DIR`. |

Three more PRs came out of this close-out and are open:

- prisma/composer#347 writes ADR-0050, which records the binary's
retirement. Without it the close-out failed the ADR audit, and four
older ADRs still described `prisma-composer` as the entry point.
- prisma/web#8415 fixes a tutorial page that still told readers to write
`prisma-composer.config.ts`.
- prisma/pdp-control-plane#5608 makes the platform's Compute import flow
write the `composer` section into `prisma.config.ts`, and recognise
repositories that already have it. Until now it wrote
`prisma-composer.config.mjs` and pinned Composer 0.25.0, so imported
repositories broke on upgrading to 0.26.0.

## Definition of Done

| Item | Verdict | Evidence |
| --- | --- | --- |
| orm-demo has one config file, and `prisma deploy` and `prisma dev` run
against it from the host | Met, with deviations | `examples/orm-demo`
has only `prisma.config.ts`. `prisma dev` from the host build reached
ready (slice 3 QA). A real `prisma deploy` of orm-demo succeeds in
Composer's e2e workflow on `main`, using the published host with the
workspace family. No deploy ran from the host build itself, because no
service token was available. |
| The old file and `configPath` get their diagnostics | Met, with a
deviation | `CONFIG.FILE_RETIRED` and `CONFIG.FIELD_RETIRED`, exit 2,
from the host binary. Shown with `prisma dev`, because `deploy` checks
credentials before reading the config. Both commands use the same
validator. |
| A broken `effect` install fails with `CLI.CONFIG_UNREADABLE`, and
`prisma --version` still works | Met, with the same deviation | Slice 3
QA, step 5. |
| Published packages have no `bin` and no stale name | Met |
`@prisma/composer-cli` and `@prisma/composer` 0.28.0 declare no `bin`.
Their unpacked tarballs name the old file only in the messages that
refuse it. |
| A CI check keeps the old name out | Met | `pnpm
lint:retired-binary-name` runs in CI. Its test plants a mention and
expects a failure. |
| TML-3340 Done, web pages updated | Met | TML-3340 is Done with a
closing comment. One page missed by #8387 is fixed in prisma/web#8415. |
| The consolidation plan says `deploy` and `dev` stay bare | Met |
`projects/consolidate-clis/cli-consolidation-plan.md`, and now ADR-0050
in prisma/composer. |
| Retro run, ADR merged, folder deleted | Met once #347 and this PR
merge | The retro's lesson is failure mode F42. ADR-0049 is merged.
ADR-0050 is in #347. |
| Repository references to the folder removed | Met | Nothing outside
the folder links to it. |
| Manual QA for each user-facing slice | Met, with a deviation | Slice 3
has a QA transcript. Slices 1 and 2 recorded their manual QA in the
Verification sections of #328 and #331. |

## Where each decision lives now

Every decision recorded in the deleted spec and design notes has a home
outside the folder:

- **Composer's configuration is the `composer` section, validated by the
section, with the old file and field refused:** ADR-0049, and the
`CONFIG` code list in ADR-0044.
- **The `effect` version pre-flight is deleted; a broken tree fails with
the engine's error:** ADR-0049. #347 adds the four rejected
alternatives, which until now were only in #328's description.
- **The binary is retired, and `destroy` and `log` stay programmatic:**
ADR-0050 in #347.
- **`deploy` and `dev` stay bare commands; `destroy` is not mounted:**
ADR-0050, and the consolidation plan.
- **The examples' `destroy` scripts keep `--production` and `--stage`:**
ADR-0050 records this as a repository-internal script grammar, not a
public command.
- **Examples and CI run the published host with a workspace override:**
`gotchas.md` and `scripts/check-cli-engine-pin*.mjs` in prisma/composer,
which enforce it.
- **Composer runs the `alchemy` installed beside `@prisma/composer`:**
ADR-0007's amendment and `docs/design/10-domains/deploy-cli.md` in
prisma/composer.

## Deferred items and their tickets

| Ticket | Item |
| --- | --- |
| TML-3520 | Release Composer 0.29.0 and pin it in the host, so
`prisma@latest` gets the pnpm fix. |
| TML-3521 | Teardown and logs have no `prisma` command. |
| TML-3522 | Two checkouts of one app still share a local Postgres
server. |
| TML-3523 | A compute emulator test is too tight on time and flakes
under load. |
| TML-3524 | Composer's examples pin an older `prisma` host than
`latest`. |
| TML-3525 | Drop the exact `effect` pin once `effect` 4 is stable or
Alchemy pins its peer. |
| TML-3526 | dependency-cruiser skips the examples' `prisma.config.ts`.
|
| TML-3527 | Edge cases in how Composer starts Alchemy. |
| TML-3528 | prisma/asks and prisma/streams still use the retired config
or command. |

Two smaller review notes are accepted without tickets. The prisma-cli
conformance check needs a new exception on each joint engine release,
which is visible when it happens. Windows edge cases are out of scope,
because Windows is documented as unsupported for local tooling.

## What this PR deletes

Every file under `projects/one-config-file/` is transient under
`drive/project/README.md`: the spec, plan, design notes, retro log,
README, and each slice's spec, plan, grounding notes, reviews and QA
transcript. None is methodology to migrate. The decisions are mapped
above. The full files stay readable in the history of prisma/orm#30536.

## The failure-mode number

The retro added its lesson to `drive/calibration/failure-modes.md` as
F39. prisma/orm#30613 had already used F39 two days earlier. This PR
renumbers ours to F42, the next free number.

Agent: saruman-38

🤖 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.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants