Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 37 additions & 0 deletions .drive/projects/node-addressing/slices/a3-entry-in-config/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# A3 — dispatch plan

Spec: [spec.md](spec.md). Branch `drive/deploy-entry-in-config`, cut from `origin/main` `561f5336`. Dispatches run in order. The PR opens after review and QA.

### D1. Design records describe the entry in the config

- **Outcome:** ADR-0003, ADR-0049 and ADR-0050 carry amendment notes and updated text. ADR-0044 lists `CONFIG.ENTRY_MISSING`. `deploy-cli.md`, `local-dev.md` and the glossary show `prisma deploy` and `prisma dev` without a positional entry. The ADR index entries mention the amendments.
- **Builds on:** the spec.
- **Gate:** `pnpm lint`.

### D2. The config's entry, the `--entry` flag, and the operations

- **Outcome:** the section check accepts `entry`. `deploy`/`dev` take `--entry` and no positional. The operations take an optional `entry` that overrides `config.value.entry`. A missing entry fails with `CONFIG.ENTRY_MISSING`. The entry path given to the Alchemy child is absolute. Unit tests cover: the config entry resolved against the config file's directory from another cwd, the override, the missing case, an invalid `entry` value, and a leftover positional.
- **Builds on:** D1.
- **Gate:** `pnpm typecheck`, `pnpm lint`, cli package tests.

### D3. Every caller in the repo uses the config's entry

- **Outcome:** each example's and the website's `prisma.config.ts` has `entry`. Package scripts, `scripts/composer-destroy.ts` (now `--entry`), the deploy-verify-destroy action, `deploy-docs.yml`, the guides, the skill, `gotchas.md`, the READMEs and every test that passes a positional entry use the new form. `git grep` finds no `prisma deploy <file>` or `prisma dev <file>` outside ADR history text.
- **Builds on:** D2.
- **Gate:** `pnpm typecheck`, `pnpm lint`, `pnpm lint:deps`, cli tests, `scripts/*.test.ts`, `test/integration` after `pnpm build`.

### Review

`/drive-code-review` on the branch (no walkthrough). Fix findings in follow-up dispatches.

### D4. QA

- **Outcome:**
- From an example directory: `prisma deploy` with the config's entry deploys to the real platform.
- `prisma deploy --entry` from another directory works.
- With no entry, the error is `CONFIG.ENTRY_MISSING`.
- `prisma dev` and `prisma dev --detach`/`dev stop` run from the config's entry.

Every test Project is deleted afterwards.
- **Builds on:** review fixes.
- **Hands to:** evidence for the PR description.
48 changes: 48 additions & 0 deletions .drive/projects/node-addressing/slices/a3-entry-in-config/qa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# A3 QA: the entry lives in the config

Run on 2026-10-23 on branch `drive/deploy-entry-in-config` at `1bdd405f`, after `pnpm install` and `pnpm build`. Commands used the workspace's `prisma` (`bun ../../node_modules/.bin/prisma`, as the example's scripts do), with credentials from `~/.config/prisma-compose/deploy.env` and `PRISMA_REGION=us-east-1`. Logs are in `wip/qa-a3/` of this worktree, which git ignores. No secret values are recorded here.

**Verdict:** every check passed.

The app is `examples/storage`, used in place. Its `prisma.config.ts` has `entry: './module.ts'`, and its root module is `storage-example`.

## Step 1. Deploy from the config's entry

| Check | Result | Evidence |
|---|---|---|
| `prisma deploy --name qa-a3-4ca9r0` from `examples/storage`, with no entry argument | PASS | "Deployed qa-a3-4ca9r0 to production". It created Project `proj_vs7kdo4y09kzwcuztkn3shh1` with `qa-a3-4ca9r0.storage.db` (`db_g3armpvzim0y20jddcdabw7a`), `qa-a3-4ca9r0.storage.service` and `qa-a3-4ca9r0.blobs` (`cps_hdhuig86otxi183urfnrhppf`). |
| The service answers | PASS | `/health` returns the blob store banner. `PUT /blobs/qa-a3.txt` returns `size: 8`, and `GET` returns `hello-a3`. |
| The same deploy from `examples/storage/src/blobs` | PASS | It found `prisma.config.ts` and its `entry` from the subdirectory. It planned 13 updates and 2 replaces (the two Deployments) on the same resource ids, and created nothing new. The blob written before is still served. |

## Step 2. `--entry` overrides the config

| Check | Result | Evidence |
|---|---|---|
| `prisma deploy --entry qa-a3-other.ts` deploys that module | PASS | `qa-a3-other.ts`, a temporary file in `examples/storage`, exports the root module `qa-a3-other-grpzno`. The deploy created Project `qa-a3-other-grpzno` (`proj_are8u63veea3aylj69u608bl`) with `qa-a3-other-grpzno.storage.db`, `qa-a3-other-grpzno.storage.service` and `qa-a3-other-grpzno.blobs`. Its service answers. No `storage-example` Project was created, so the config's module was not used. |
| Cleanup | PASS | I deleted that Project with `prisma project delete`, and the API now returns `resource-not-found` for it. I removed the temporary file, and `git status` shows no change under `examples/storage`. |

## Step 3. Errors

These ran in `wip/qa-a3/noentry`, a copy of the example whose `node_modules` links to the example's.

| Check | Result | Evidence |
|---|---|---|
| No `entry` in the config and no `--entry` | PASS | The command exits with code 2, and the output is `✘ [CONFIG.ENTRY_MISSING] No entry module is set, so there is no app to load.` The fix line names both ways to set it: `entry: './module.ts'` in the `composer` section of prisma.config.ts, or `--entry <path>`. It fails in "load config and app" after 2 ms, before any "connect to project and branch" step. The same error appears with the platform credentials unset. No Project was created. |
| `prisma deploy module.ts` (a leftover positional) | PASS | The output is `✘ [CLI.INVALID_ARGUMENTS] Too many arguments, expected 0 but encountered "module.ts"`, from the CLI engine. |
| `entry` set to a missing file | PASS | The output is `✘ [COMPOSE.ENTRY_UNLOADABLE] Failed to import entry module ".../noentry/does-not-exist.ts"`. The fix line says ``Check `entry: "./does-not-exist.ts"` in .../noentry/prisma.config.ts. It is relative to that file's directory.`` |

I made one mistake along the way. My first attempt to remove `entry` from the copy did not remove it. That run loaded the entry and got as far as contacting the platform, where it stopped with `DEPLOY.CONTAINER_FAILED` because no region was set. It created nothing, and the API lists no `qa-a3-noentry` Project. That run is not evidence for any check above.

## Step 4. Local dev

| Check | Result | Evidence |
|---|---|---|
| `prisma dev --detach` from `examples/storage` with no entry | PASS | "dev: ready". It started `storage-example.blobs` on `http://localhost:3084` and `storage-example.storage.service` on `:3083`. The root name `storage-example` comes from the config's `module.ts`. |
| `prisma dev url storage-example.blobs` | PASS | It printed `http://localhost:3084`. A blob was written and read back. The short address `blobs` fails with `DEV.ADDRESS_UNKNOWN` and lists the full addresses. |
| `prisma dev stop` leaves nothing running | PASS | "Stopped storage-example". Ports 3083 and 3084 and the local database port 51963 no longer listen, and the service processes 51703 and 51742 are gone. The shared compute and postgres emulators on 4316 and 4302 started at 15:11, before this QA run, so I left them alone. |

## Step 5. Teardown

| Check | Result | Evidence |
|---|---|---|
| Every Project deleted | PASS | I deleted `qa-a3-4ca9r0` (`proj_vs7kdo4y09kzwcuztkn3shh1`) and `qa-a3-other-grpzno` (`proj_are8u63veea3aylj69u608bl`) with `prisma project delete <id> --confirm <id>`. `prisma project list` shows no `qa-a3` Project. `GET /v1/projects/<id>` returns `resource-not-found` for both. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Code review — A3, deploy's entry file lives in the config

Branch `drive/deploy-entry-in-config`, range `origin/main...HEAD`, 4 commits, 68 files. Reviewed against the slice [spec](../spec.md) and [plan](../plan.md), design note 6, and ADR-0003, ADR-0044, ADR-0049 and ADR-0050 as amended on the branch. Prisma CLI source read in `wip/prisma-cli` where needed.

Settled and not reopened: the entry is an input to the tool, not an application fact; the config's `entry` resolves against the config file's directory and `--entry` against the cwd; the positional is removed and the engine's own "Too many arguments" error is kept.

## Summary

The code is correct. One function, `resolveEntryPath` (`cli/src/pipeline.ts` lines 85–99), decides the entry for every command and operation:
- an override resolves against `cwd`;
- the section's `entry` resolves against the directory of the config file, which `checkConfigSource` has already made absolute;
- with neither, it raises `CONFIG.ENTRY_MISSING`.

The Alchemy child gets the absolute path from `loadEntry`, so it does not depend on the child's working directory. CI, the scripts and the package scripts all moved.

What remains is in the docs:
- two copy-paste commands still pass `module.ts` and now fail (F01);
- four decision records still state `prisma deploy <entry>` or show `prisma dev module.ts` as the current form (F02);
- there is no upgrade note for users whose config has no `entry` (F03).

## What looks solid

- **One resolution rule, used everywhere.** `runPipeline` (deploy, destroy and dev, including dev's rebuild on change, `execute-dev.ts` lines 82 and 320) and `resolveAppIdentity` (log) both call `resolveEntryPath`. The section's `entry` resolves against `path.dirname` of the file `checkConfigSource` resolved against `cwd`, so a relative `config.file` from a script also works.
- **The Alchemy child.** `generate-stack.ts` and `dev/generate-dev-stack.ts` take `entryPath` from `LoadedEntry.path`, which is absolute.
- **The section check.** `entry` is in the allowed keys. A non-string or empty value gives `CONFIG.FIELD_INVALID` with `field: 'entry'`, and the unknown-field messages list `entry`. Tests: `entry-path.test.ts`.
- **The commands.** `deploy` and `dev` take `--entry` and no positional. The family test runs `deploy module.ts` and `dev module.ts` and asserts exit 2, the engine's "Too many arguments" message, and that no operation was called.
- **The operations.** `entry` is optional on deploy, destroy, dev and log. Two tests cover the new behaviour: an operation test runs `deployWithDeps` from another cwd with a config `entry` and reaches Alchemy, and a missing-entry test asserts `CONFIG.ENTRY_MISSING` and that Alchemy never ran.
- **Callers moved.**
- Every example's `prisma.config.ts`, the website and the local-dev fixture have `entry`.
- The package scripts, the `deploy-verify-destroy` action, `deploy-docs.yml` and `destroy-guard.sh` (now two arguments) no longer pass a positional, and nothing calls `destroy-guard.sh` with three.
- `composer-destroy.ts` takes `--entry` and refuses positionals.
- The integration tests pass `--entry` or rely on the fixture's config.
- **ADR-0044** registers `CONFIG.ENTRY_MISSING`. ADR-0049 and ADR-0050 match the code.

## Findings

### F01 — Two documented commands still pass `module.ts`, which now fails

- **Location:** `docs/guides/deploying.md` line 67; `skills/prisma-composer-core-concepts/SKILL.md` line 362.
- **Issue:** Both show `bun node_modules/prisma/dist/prisma.js deploy module.ts`. That now exits 2 with "Too many arguments". The skill is what agents copy from.
- **Suggestion:** Drop `module.ts` from both. Re-run the plan's `git grep` with a pattern that matches this form, for example `deploy module.ts`, not only `prisma deploy <file>`.

### F02 — Four decision records still give the positional as the current command

- **Location:**
- ADR-0024 line 3 and ADR-0041 line 3, the ADR-0050 amendment notes: "deploys run as `prisma deploy <entry> …`" and "the command is `prisma dev <entry>`";
- ADR-0053 lines 12 and 18 (`prisma dev module.ts`, `prisma dev module.ts --detach`);
- ADR-0056 line 52 (`prisma dev module.ts`);
- the index entries for ADR-0041 (`docs/design/90-decisions/README.md` line 65) and ADR-0024.
- **Issue:** Agents treat these records as binding. ADR-0053 and ADR-0056 are recent and show the command as it is used now. ADR-0024 and ADR-0041 state the command shape in their own amendment notes. Only ADR-0003, ADR-0049 and ADR-0050 were amended.
- **Suggestion:** Add a one-line amendment note to each of the four, as the branch does for ADR-0003: "Amended 2026-10-23: `prisma dev`/`prisma deploy` take no positional entry; the entry is `entry` in the `composer` section, or `--entry` (ADR-0050)." Leave the bodies unchanged, and update the two index entries. This keeps each record's history and stops it reading as current.

### F03 — No upgrade note for an existing project

- **Location:** `docs/guides/deploying.md` and `docs/guides/getting-started.md` (no upgrade section).
- **Issue:** A user who upgrades and runs `prisma deploy module.ts` gets the engine's "Too many arguments, expected 0", which does not say where the entry went. Running `prisma deploy` without adding `entry` gives `CONFIG.ENTRY_MISSING`, which does. Keeping the engine's error is settled, so the guide is the only place that can connect the two.
- **Suggestion:** Add a short "Upgrading" paragraph: the positional entry is gone; add `entry: './module.ts'` to the `composer` section, or pass `--entry`.

### F04 — The guide says the commands "find it from any directory", but `prisma dev` keeps its record in the directory it runs in

- **Location:** `docs/guides/deploying.md` line 104.
- **Issue:** The entry is now found from a subdirectory too, because the engine uses the nearest `prisma.config.ts`. But `prisma dev` keeps its record of emulator instances, its bucket data and the state `prisma dev url` reads under `<cwd>/.prisma-composer/dev` (`execute-dev.ts` line 75; ADR-0052). Running it from a subdirectory starts a second, empty local copy of the app.
- **Suggestion:** Say that `prisma deploy` works from any directory, and that `prisma dev`, `dev url` and `dev stop` should be run from the same directory each time, normally the one holding `prisma.config.ts`.

### F05 — `CONFIG.ENTRY_MISSING` tells an API caller to pass `--entry`

- **Location:** `packages/0-framework/3-tooling/cli/src/composer-config.ts` lines 127–134.
- **Issue:** The same finding is raised for the operations, where the override is the `entry` input. The test asserts the CLI wording for `deployWithDeps`.
- **Suggestion:** Say "or pass `--entry <path>` (the `entry` input when calling `@prisma/composer/control`)".

### F06 — A wrong `entry` path fails without saying where the path came from

- **Location:** `packages/0-framework/3-tooling/cli/src/load-entry.ts` lines 38–42.
- **Issue:** `COMPOSE.ENTRY_UNLOADABLE` gives "Failed to import entry module "/abs/…": Cannot find module…" with no fix. Before this slice the user had just typed the path. Now it usually comes from a file they may not be looking at.
- **Suggestion:** Have `resolveEntryPath` return where the path came from, and add a fix naming it. For example: "Check `entry` in /path/prisma.config.ts (relative to that file)", or "Check the `--entry` path (relative to the current directory)".

### F07 — `composer-destroy.ts` says both entries resolve against the current directory

- **Location:** `scripts/composer-destroy.ts` lines 8–9.
- **Issue:** The section's `entry` resolves against the config file's directory. That matters when `--config` names a file somewhere else.
- **Suggestion:** "The entry is the section's `entry`, relative to the config file, or `--entry`, relative to the current directory."

### F08 — ADR-0050's amendment names only `destroy` and `log` as having an optional `entry`

- **Location:** ADR-0050 line 3.
- **Issue:** All four operations have it, as ADR-0049's amendment says.
- **Suggestion:** "The operations' `entry` input is optional and overrides the config's."

## Deferred (out of scope)

- `prisma dev` watching the entry file, and re-reading `entry` when the config changes during a session. The spec excludes both.

## Acceptance-criteria verification

| AC | Verdict | Detail |
| --- | --- | --- |
| The section takes an optional non-empty `entry`; `CONFIG.FIELD_INVALID` otherwise | **PASS** | `composer-config.ts` `checkFields`; `entry-path.test.ts` checks `''`, `42` and an array. |
| The config's `entry` resolves against the config file's directory; `--entry` against cwd | **PASS** | `resolveEntryPath`; unit tests, plus `operations.test.ts` running from another cwd and reaching Alchemy. |
| `deploy`/`dev` lose the positional and gain `--entry`, which wins | **PASS** | `commands/deploy.ts`, `dev.ts`; the family tests pass `--entry` through and leave it undefined without the flag. The precedence itself is tested in `resolveEntryPath`. |
| The operations' `entry` is optional and overrides the config | **PASS** | Types and `resolveEntryPath`; operation test for the config path. |
| No entry fails before any work with `CONFIG.ENTRY_MISSING`, naming both sources | **PASS** (F05) | Operation test asserts the code and fix text and that Alchemy did not run. |
| A leftover positional is not silently ignored | **PASS** | Family test asserts exit 2 and "Too many arguments" for `deploy` and `dev`. The engine's error is the accepted outcome; say so in the PR. |
| Every repo caller moved | **WEAK** | Code, CI, scripts and package scripts moved. Two documented commands did not (F01). |
| The Alchemy child gets an absolute entry path | **PASS** | `LoadedEntry.path`; `generate-stack.test.ts`, `stack-file-import.test.ts`. |
| ADR-0003, ADR-0049, ADR-0050 amended; ADR-0044 lists the code; domain docs, guides, skill, gotchas | **WEAK** | Done as listed, but ADR-0024, ADR-0041, ADR-0053 and ADR-0056 still state the positional (F02). |
| A real deploy of one example from its config's entry | **NOT VERIFIED** | QA (D4) not run. |

### Summary

| Result | Count | ACs |
| --- | --- | --- |
| PASS | 7 | field check, resolution, commands, operations, missing entry, leftover positional, absolute path |
| WEAK | 2 | repo callers, design records |
| NOT VERIFIED | 1 | real deploy |
| FAIL | 0 | |

---

# Round 2

Commits `a7184afe`, `1bdd405f` on top of `45236626`. **Verdict: SATISFIED.**

| Finding | Status | Evidence |
| --- | --- | --- |
| F01 positional in two commands | Fixed | `deploying.md` and `SKILL.md` show `… prisma.js deploy`. A repo-wide `git grep` for `deploy module.ts`, `dev module.ts`, `deploy <entry>` and `dev <entry>` now finds four kinds of hit: ADR bodies kept as history under their new amendment notes, the upgrade note (deliberate), and the retired-binary lint test's fixtures. |
| F02 records not amended | Fixed | ADR-0024, ADR-0041, ADR-0053 and ADR-0056 carry an amendment note that cites ADR-0050. The ADR-0024 and ADR-0041 index entries mention it. |
| F03 no upgrade note | Fixed | `deploying.md` quotes the engine's error for `prisma deploy module.ts` / `prisma dev module.ts` and gives both fixes. |
| F04 "from any directory" | Fixed | The guide now limits the claim to `prisma deploy` below the config, and says to run `prisma dev`, `dev url` and `dev stop` from one directory. |
| F05 missing-entry fix text | Fixed | The fix names the `entry` input for `@prisma/composer/control`; the test asserts the new text. |
| F06 unloadable entry | Fixed | `resolveEntryPath` returns the path and a fix that names its source: the config file and its `entry` value, or the `--entry` value and the cwd. `loadEntry` adds it to `COMPOSE.ENTRY_UNLOADABLE`. A new operation test asserts both texts. The JSX and default-export errors keep their own fixes, which is right. |
| F07 `composer-destroy.ts` header | Fixed | |
| F08 ADR-0050 operations list | Fixed | It names all four operations. |

QA (D4) is still outstanding for the real-deploy criterion.
Loading
Loading