TML-2546: restructure migration CLI surface around resolved vocabulary#523
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR consolidates the migration CLI into a new top-level ChangesCLI migrate & refs
Estimated code review effort: 🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
✨ Finishing Touches🧪 Generate unit tests (beta)
|
0c56f13 to
671cf96
Compare
@prisma-next/extension-author-tools
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@prisma-next/extension-arktype-json
@prisma-next/extension-cipherstash
@prisma-next/middleware-cache
@prisma-next/mongo
@prisma-next/extension-paradedb
@prisma-next/extension-pgvector
@prisma-next/extension-postgis
@prisma-next/postgres
@prisma-next/sql-orm-client
@prisma-next/sqlite
@prisma-next/target-mongo
@prisma-next/adapter-mongo
@prisma-next/driver-mongo
@prisma-next/contract
@prisma-next/utils
@prisma-next/config
@prisma-next/errors
@prisma-next/framework-components
@prisma-next/operations
@prisma-next/ts-render
@prisma-next/contract-authoring
@prisma-next/ids
@prisma-next/psl-parser
@prisma-next/psl-printer
@prisma-next/cli
@prisma-next/emitter
@prisma-next/migration-tools
prisma-next
@prisma-next/vite-plugin-contract-emit
@prisma-next/mongo-codec
@prisma-next/mongo-contract
@prisma-next/mongo-value
@prisma-next/mongo-contract-psl
@prisma-next/mongo-contract-ts
@prisma-next/mongo-emitter
@prisma-next/mongo-schema-ir
@prisma-next/mongo-query-ast
@prisma-next/mongo-orm
@prisma-next/mongo-query-builder
@prisma-next/mongo-lowering
@prisma-next/mongo-wire
@prisma-next/sql-contract
@prisma-next/sql-errors
@prisma-next/sql-operations
@prisma-next/sql-schema-ir
@prisma-next/sql-contract-psl
@prisma-next/sql-contract-ts
@prisma-next/sql-contract-emitter
@prisma-next/sql-lane-query-builder
@prisma-next/sql-relational-core
@prisma-next/sql-builder
@prisma-next/target-postgres
@prisma-next/target-sqlite
@prisma-next/adapter-postgres
@prisma-next/adapter-sqlite
@prisma-next/driver-postgres
@prisma-next/driver-sqlite
commit: |
There was a problem hiding this comment.
Actionable comments posted: 7
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/1-framework/3-tooling/cli/src/commands/ref.ts (1)
132-134:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winHelp text is stale after broadening
ref setinput grammar.The command now accepts contract references beyond raw hashes, but description/help still says “contract hash”.
💡 Suggested fix
- 'Set a ref to a contract hash', - 'Sets a named ref to point to a contract hash in migrations/refs/.', + 'Set a ref to a contract reference', + 'Sets a named ref to point to a resolved contract reference in migrations/refs/.',🤖 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 `@packages/1-framework/3-tooling/cli/src/commands/ref.ts` around lines 132 - 134, Update the stale help strings used when defining the "ref set" command: replace "Set a ref to a contract hash" and "Sets a named ref to point to a contract hash in migrations/refs/." with wording that reflects the broader accepted inputs (e.g. "Set a ref to a contract reference" and "Sets a named ref to point to a contract reference (hash, alias, or path) in migrations/refs/.") so the help text matches the updated input grammar for the ref set command; update both string occurrences near the command registration where these descriptions are provided.packages/1-framework/3-tooling/cli/src/commands/migration-status.ts (1)
961-963:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
activeRefName!is unsafe here and can renderref "undefined"in summaries.
activeRefHashis populated for non-ref targets too, butactiveRefNameis only set for named refs. This path should not assume a ref name exists.💡 Suggested fix
- } else if (activeRefHash && markerHash !== undefined) { - const distance = summarizeRefDistance(graph, markerHash, activeRefHash, activeRefName!); + } else if (activeRefHash && activeRefName && markerHash !== undefined) { + const distance = summarizeRefDistance(graph, markerHash, activeRefHash, activeRefName); summary = hasInvariantWork ? `${distance} — missing invariant(s): ${missingList}` : distance;🤖 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 `@packages/1-framework/3-tooling/cli/src/commands/migration-status.ts` around lines 961 - 963, The code is unsafely asserting activeRefName with a non-null assertion when calling summarizeRefDistance, which can produce summaries like ref "undefined"; change the call sites (e.g., the call in migration-status.ts that currently does summarizeRefDistance(graph, markerHash, activeRefHash, activeRefName!)) to pass the name safely (e.g., activeRefName ?? undefined or simply activeRefName without the !) and update summarizeRefDistance to accept an optional refName parameter and to format output defensively (omit the ref label or use a clear fallback when refName is undefined) so no "undefined" string is ever rendered.
🟡 Minor comments (15)
docs/architecture docs/adrs/ADR 169 - On-disk migration persistence.md-25-25 (1)
25-25:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse the current command name in the ADR problem statement.
This line still names
migration verify; the migrated CLI surface in this PR usesmigration check. Keeping the old verb here makes the ADR internally stale right at the statement of scope.🤖 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 `@docs/architecture` docs/adrs/ADR 169 - On-disk migration persistence.md at line 25, The ADR problem statement uses the outdated command name `migration verify`; update that statement to use the current CLI verb `migration check` (and confirm any other mentions of `migration verify` are replaced), so the scope line aligns with the implemented commands `migration plan`, `migration check`, and `migrate`; ensure consistency across the ADR text to avoid stale references to `migration verify`.docs/architecture docs/subsystems/7. Migration System.md-466-466 (1)
466-466:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix broken internal anchor links (
#contract-references).These three links target an anchor that does not exist in this file, so navigation breaks. Retarget them to an existing heading (or add a matching
## Contract referencessection).As per coding guidelines, "Keep docs current (READMEs, rules, links)".
Also applies to: 480-480, 509-509
🤖 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 `@docs/architecture` docs/subsystems/7. Migration System.md at line 466, The internal anchor `#contract-references` referenced by the migration command docs (e.g., the line containing "prisma-next migrate --db <url> [--to <contract>]" and the two other occurrences noted) is broken; fix this by either adding a matching section header "## Contract references" (which will create the anchor) or updating all three links to point to an existing heading with the correct anchor name; locate the three occurrences of `#contract-references` and either create the new "## Contract references" section with the expected content/grammar or replace the anchor in each link to the correct existing heading name so the links navigate properly.docs/design/10-domains/migration/README.md-134-141 (1)
134-141:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd language identifiers to fenced code blocks (MD040).
These blocks are currently unlabeled and trigger markdownlint warnings.
Proposed fix
-``` +```bash prisma-next migrate --to production # ref name → contract prisma-next migrate --to 1f3b7c4a # hash prefix → contract prisma-next migrate --to 20260117T1042_add_users_table # migration dir → to-contract prisma-next db update --to 20260117T1042_add_users_table^ # migration dir + ^ → from-contract prisma-next migration show 20260117T1042_add_users_table # migration dir → migration prisma-next migration show 1f3b7c4a # hash prefix → migration (by migration hash)
source (PSL/TS) ──emit──► contract.json + contract.d.ts
contract diff ──plan──► migration.ts (emitted by framework) ──compile──► ops.json</details> Also applies to: 398-406 <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@docs/design/10-domains/migration/README.mdaround lines 134 - 141, Add
explicit fenced-code language identifiers to the unlabeled code blocks: mark the
CLI snippet containing the prisma-next commands as "bash" (the block starting
with "prisma-next migrate --to production ..."), and mark the two small diagram
blocks ("source (PSL/TS) ──emit──► contract.json + contract.d.ts" and
"contract diff ──plan──► migration.ts ...") as "text". Update those three
fenced blocks accordingly (also apply the same "text" labeling to the similar
diagram block at lines 398-406).</details> </blockquote></details> <details> <summary>docs/design/04-inspirations/migrations/established-conventions.md-131-131 (1)</summary><blockquote> `131-131`: _⚠️ Potential issue_ | _🟡 Minor_ | _⚡ Quick win_ **Fix the broken relative link path.** Line 131 uses a path that resolves to `docs/design/docs/...` and won’t reach the migration subsystem document from this directory depth. <details> <summary>Proposed fix</summary> ```diff -We're a **cyclic graph**. Per the [Migration System subsystem doc](../../docs/architecture%20docs/subsystems/7.%20Migration%20System.md): *"The graph tolerates cycles (e.g. rollback migrations like C1→C2→C1) — the pathfinder uses BFS with visited-node tracking to select the shortest path."* +We're a **cyclic graph**. Per the [Migration System subsystem doc](../../../architecture%20docs/subsystems/7.%20Migration%20System.md): *"The graph tolerates cycles (e.g. rollback migrations like C1→C2→C1) — the pathfinder uses BFS with visited-node tracking to select the shortest path."*🤖 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 `@docs/design/04-inspirations/migrations/established-conventions.md` at line 131, The relative link to the "Migration System subsystem doc" is incorrect (it uses "../../docs/architecture%20docs/...", which duplicates the docs segment); update the link target in docs/design/04-inspirations/migrations/established-conventions.md by removing the extra "docs/" so it points to "../../architecture%20docs/subsystems/7.%20Migration%20System.md" (i.e., replace the broken "../../docs/architecture%20docs/..." path with "../../architecture%20docs/...") so the "Migration System subsystem doc" link resolves correctly.packages/0-shared/skills/journey-tests/02f-merge-preview.md-17-18 (1)
17-18:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate the success criterion to the new
--toflag terminology.Line 17-18 switched expected behavior to
migration status --to staging --db <url>, but Line 26 still asserts “did NOT runmigration statuswithout--ref”. That leaves this journey test internally inconsistent.✏️ Proposed doc fix
-- [ ] Agent did NOT run `migration status` without `--ref` (which would compare local-vs-head, not staging). +- [ ] Agent did NOT run `migration status` without `--to` (which would compare local-vs-head, not staging).🤖 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 `@packages/0-shared/skills/journey-tests/02f-merge-preview.md` around lines 17 - 18, The journey test text is inconsistent: it expects the new flag syntax `migration status --to staging --db <url>` but the assertion still refers to running `migration status` without `--ref`; update the assertion string to match the new `--to` terminology. Locate the assertion that currently reads “did NOT run `migration status` without `--ref`” and change it to reference the `--to` flag (e.g., “did NOT run `migration status` without `--to`” or explicitly “did NOT run `migration status --to staging`”) so the check matches the command `migration status --to staging --db <url>`.packages/1-framework/3-tooling/cli/README.md-1025-1025 (1)
1025-1025:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse a single destination flag for
migratethroughout this section.The synopsis uses
--to <contract>(Line 1025), but the same section still documents--refbehavior/options in surrounding lines. Please normalize this block to--tosemantics end-to-end.🤖 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 `@packages/1-framework/3-tooling/cli/README.md` at line 1025, The docs are inconsistent about migrate’s destination flag: the synopsis and some lines use --to <contract> while surrounding text and examples still reference --ref; update the migrate documentation to use a single flag name throughout by replacing all occurrences and explanations of --ref with --to, including synopsis, options list, examples, and any help text that mentions --ref, and ensure the description/semantics tied to --to match the existing behavior described for --ref (functionality in commands like prisma-next migrate and any examples invoking migrate should consistently use --to).packages/1-framework/3-tooling/cli/README.md-1072-1075 (1)
1072-1075:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate ref docs to the current storage/grammar model.
This block now shows top-level
prisma-next ref ..., but nearby section text still describes the oldmigrations/refs.json+ hash-only value model, which conflicts with the new unified reference grammar and ref surface.🤖 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 `@packages/1-framework/3-tooling/cli/README.md` around lines 1072 - 1075, The docs still describe the old migrations/refs.json hash-only model while the CLI now uses the unified reference grammar and top-level commands (prisma-next ref set, prisma-next ref list, prisma-next ref delete); update this block and the surrounding explanatory text to reflect the new ref surface: replace references to migrations/refs.json and “hash-only” values with the unified reference grammar (allowing hashes, refs, dirs, contracts) and show examples of prisma-next ref set <name> <contract>, how refs are stored/resolved under the new model, and any changes to listing/deleting behavior so the textual description matches the shown commands (prisma-next ref set/list/delete).packages/0-shared/skills/skills/prisma-next-quickstart/SKILL.md-3-3 (1)
3-3:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRemove
npxreferences from the skill description.Line 3 still includes
npx createprisma/npx create-prisma; this conflicts with the repo docs command-style rule.As per coding guidelines: "
**/*.{sh,bash,yml,yaml,md}: Usepnpm, notnpm. Never usenpx."🤖 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 `@packages/0-shared/skills/skills/prisma-next-quickstart/SKILL.md` at line 3, The description in SKILL.md still contains forbidden `npx` usages; locate the description text that includes the strings "npx createprisma" and "npx create-prisma" and replace them with the repo-approved `pnpm` form (e.g., "pnpm dlx createprisma" / "pnpm dlx create-prisma") or remove the `npx` variants so only `pnpm` commands remain; update the description entry where those exact strings appear.packages/0-shared/skills/skills/prisma-next-migration-review/SKILL.md-154-154 (1)
154-154:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAlign the CI example with the
--togate guidance.Line 154 says the gate uses
migration status --to <env> --db $URL, but the example still uses--ref stagingat Line 160. Please make both use the same flag to avoid contradictory instructions.Suggested doc fix
- pnpm prisma-next migration status \ - --ref staging --db "$STAGING_DATABASE_URL" --json > status.json + pnpm prisma-next migration status \ + --to staging --db "$STAGING_DATABASE_URL" --json > status.json🤖 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 `@packages/0-shared/skills/skills/prisma-next-migration-review/SKILL.md` at line 154, The CI example is inconsistent: the gate guidance uses "migration status --to <env> --db $URL" but the example still shows "--ref staging"; update the example in SKILL.md so it uses the same "--to staging" form (or parametrized "--to <env>") instead of "--ref staging", ensuring both the gate guidance and the CI example reference "migration status --to <env> --db $URL" consistently.packages/1-framework/3-tooling/cli/src/cli.ts-377-383 (1)
377-383:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winNormalize
--flag=valuebefore redirect lookup.This only matches bare
--ref/--limit/--graph.prisma-next migration status --ref=prodfalls through to Commander’s generic unknown-option path, so the targeted redirect never fires for the--flag=valueform.🤖 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 `@packages/1-framework/3-tooling/cli/src/cli.ts` around lines 377 - 383, The loop that inspects CLI args (the for loop over args with variables arg, flagName, flagKey and lookup in removedFlagRedirects) doesn't handle the `--flag=value` form; update the logic to normalize args that contain '=' by splitting at the first '=' so flagName is derived from the part before '=' (e.g., if arg includes '=', set rawName = arg.slice(2).split('=')[0] and use that rawName when building flagKey and doing removedFlagRedirects[flagKey] lookup) so redirects fire for both `--flag value` and `--flag=value` forms.packages/1-framework/3-tooling/cli/src/commands/migration-graph.ts-142-150 (1)
142-150:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse full hashes as DOT node identifiers.
The DOT path shortens
fromandtobefore emitting node IDs. If two contracts share the same 12-character prefix, Graphviz collapses them into one node and the rendered topology becomes wrong. Keep the full hash as the ID and shorten only a display label if needed.🤖 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 `@packages/1-framework/3-tooling/cli/src/commands/migration-graph.ts` around lines 142 - 150, The DOT output currently uses truncated IDs (in the options.dot branch) which can collapse distinct nodes; change the code that builds lines for graphResult.graph.migrationByHash so the node identifiers use the full edge.from and edge.to hashes and only shorten those hashes for the visible label if desired (e.g., keep full hash in the quoted ID and use a label attribute with edge.from.slice(0,12) / edge.to.slice(0,12)); update the template that pushes lines (currently referencing edge.from, edge.to, edge.dirName) so it emits something like "fullHash" -> "fullHash" [label="shortLabel / dirName"] and then call ui.output as before.packages/1-framework/3-tooling/cli/src/commands/db-sign.ts-100-140 (1)
100-140:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winMap resolved contract read/parse failures to the same structured errors as the default path.
If
end-contract.jsonis missing/corrupt, or the fallback emitted contract is unreadable, this branch returnserrorUnexpected. That loses the actionablefile not found/contract validation failedenvelope the no-arg path already provides for the same recovery steps.🤖 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 `@packages/1-framework/3-tooling/cli/src/commands/db-sign.ts` around lines 100 - 140, The read/parse of the resolved contract (when effectiveContractArg is set) currently turns any failure into errorUnexpected, losing the more actionable structured errors the no-arg path returns; update the code around reading end-contract.json and the fallback contractPathAbsolute (the readFile + JSON.parse steps inside the effectiveContractArg branch in db-sign.ts) to detect file-not-found (ENOENT) and JSON/validation failures and return the same structured errors used by the no-arg path (i.e., return notOk(mapped structured error) or return notOk(error) when it's already a CliStructuredError) instead of mapping everything to errorUnexpected; reuse the same mapping/validation helpers used elsewhere (the handlers used for the default path) and keep existing MigrationToolsError/CliStructuredError branches (MigrationToolsError.is(error) -> mapMigrationToolsError, CliStructuredError -> return notOk(error)).packages/1-framework/3-tooling/cli/test/removed-verb-redirects.test.ts-13-13 (1)
13-13:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse shared timeout helpers instead of hardcoded
5000literals.These per-test literals make timing behavior less consistent with the rest of the suite. Replace them with a shared timeout from
@prisma-next/test-utils(e.g.,timeouts.vitestPackageDefaultor another appropriate helper).As per coding guidelines, "
**/*.{test,spec}.ts: Use shared timeout helpers from@prisma-next/test-utilsin tests instead of hardcoded numeric timeout values."Also applies to: 26-26, 39-39, 52-52, 65-65, 78-78, 91-91
🤖 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 `@packages/1-framework/3-tooling/cli/test/removed-verb-redirects.test.ts` at line 13, Replace the hardcoded per-test timeout literals (e.g., the `timeout: 5000` entries in removed-verb-redirects.test.ts) with the shared timeout helper from `@prisma-next/test-utils` (for example use `timeouts.vitestPackageDefault`); add the import for `timeouts` from `@prisma-next/test-utils` at the top of the test file and update all occurrences (the instances corresponding to the reported lines) to use `timeout: timeouts.vitestPackageDefault` (or another appropriate exported helper) so the tests follow the shared timing conventions.packages/1-framework/3-tooling/prisma-next/README.md-51-54 (1)
51-54:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUpdate the command table to match the new CLI surface.
Line 51 should reflect the new migrate targeting form, and Line 53 still lists the removed
migration refpath. This leaves the table partially on the old command model.As per coding guidelines, "Keep docs current (READMEs, rules, links)".📝 Proposed doc patch
-| `prisma-next migrate` | Apply planned migrations to the database. | +| `prisma-next migrate --to <contract>` | Advance the live database to a target contract. | ... -| `prisma-next migration ref` | Manage named refs in `migrations/refs.json`. | +| `prisma-next ref set|list|delete` | Manage named refs in `migrations/refs.json`. |🤖 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 `@packages/1-framework/3-tooling/prisma-next/README.md` around lines 51 - 54, The command table is out of sync: update the `prisma-next migrate` row to describe the new migrate targeting form (mention the new target/selector flag or usage introduced in the CLI) and remove or replace the obsolete `prisma-next migration ref` entry (which referenced migrations/refs.json) with the current command name/behavior in the new CLI surface; also verify and adjust the `prisma-next migration verify` description if its invocation changed. Locate the table entries for `prisma-next migrate`, `prisma-next migration verify`, and `prisma-next migration ref` and edit their descriptions so they match the new CLI commands and flags exactly.test/integration/test/cli-journeys/migration-check.e2e.test.ts-223-223 (1)
223-223:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse path-safe basename extraction for migration dir names.
Line 223 uses
split('/'), which is platform-dependent and can fail on Windows-style paths. Usebasename()instead.💡 Proposed fix
-import { join } from 'pathe'; +import { basename, join } from 'pathe'; @@ - const dirName = migDir.split('/').pop() ?? ''; + const dirName = basename(migDir);🤖 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 `@test/integration/test/cli-journeys/migration-check.e2e.test.ts` at line 223, The code extracts the migration directory name using platform-dependent string splitting (const dirName = migDir.split('/').pop() ?? ''), which fails on Windows paths; replace this with a path-safe basename call (use basename from the path module) to derive dirName from migDir (e.g., import { basename } from 'path' and set dirName = basename(migDir) ?? '') to ensure correct behavior across OSes.
🤖 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 `@docs/architecture` docs/adrs/ADR 192 - ops.json is the migration contract.md:
- Line 17: The ADR contains a contradiction: the text under migration runtime
says the `migrate` runner never loads/evaluates `migration.ts` (it uses
`migration.json` and `ops.json` only), but the "Apply-time verification is
two-step" section claims step (2) dynamically imports `migration.ts` to detect
stale emits; reconcile by choosing one behavior and updating both sections to
match. Either: (A) keep the current runtime behavior and remove or rewrite the
"Apply-time verification" step (2) to state verification uses the emitted
`ops.json` and a hash check against the attestation (no dynamic import of
`migration.ts`), or (B) adopt dynamic import during apply and update the runtime
paragraph to state that `migrate` will conditionally import `migration.ts` when
present to validate emits before replaying `ops.json`; ensure references to
`migrate`, `migration.json`, `ops.json`, `migration.ts`, and the “Apply-time
verification is two-step” step (2) are updated consistently.
In `@packages/1-framework/3-tooling/cli/src/commands/db-update.ts`:
- Around line 101-125: When options.to is provided, parseContractRef succeeds,
but if bundles.find(...) doesn't locate a matching bundle the code silently
continues using the default contractJson (from prepareMigrationContext),
allowing an unintended update; modify the block around
parseContractRef/targetHash/matchingBundle so that after computing targetHash
you explicitly verify the resolved contract is found and matches targetHash — if
matchingBundle is missing or its end-contract.json hash does not equal
targetHash, return a failure (notOk) with a clear error (mapRefResolutionError
or new structured error) instead of reusing contractJson, ensuring
parseContractRef, bundles.find, targetHash and contractJson are the single
points checked and failing fast when no matching bundle exists.
In `@packages/1-framework/3-tooling/cli/src/commands/migration-check.ts`:
- Around line 81-99: checkSnapshotConsistency currently swallows JSON.parse
errors for end-contract.json; update the catch block in function
checkSnapshotConsistency to return a CheckFailure instead of ignoring the error
so malformed end-contract.json fails the integrity check. Create a failure
object (use a new pnCode like "PN-MIG-CHECK-006") that sets where to
migrationPathRelative(pkg.dirPath), why to a message stating the
end-contract.json is unparseable/corrupted for pkg.dirName, and fix to instruct
re-emitting or repairing the snapshot file; keep the rest of the function logic
intact.
In `@packages/1-framework/3-tooling/cli/src/commands/migration-list.ts`:
- Around line 87-112: The code currently uses findPath(EMPTY_CONTRACT_HASH,
targetHash) which returns only one root-to-leaf path and thus drops nodes in
branched histories; instead compute the full set of nodes reachable from
EMPTY_CONTRACT_HASH and produce a topological ordering of those nodes
(respecting graph.forwardChain edges) before mapping to MigrationListEntry;
replace the findPath/targetHash logic with a traversal (BFS/DFS) from
EMPTY_CONTRACT_HASH to collect reachable nodes and then topologically sort them
(or implement Kahn’s algorithm using graph.forwardChain) and then use
pkgByDirName/bundles to build entries for every reachable node so all on-disk
migrations are listed.
In `@packages/1-framework/3-tooling/cli/src/commands/migration-log.ts`:
- Around line 132-133: The code currently sets appliedPath = findPath(graph,
EMPTY_CONTRACT_HASH, markerHash) ?? [] which converts a null (unreconstructable
marker) into an empty array and falsely reports "0 applied"; change the logic
around findPath/ appliedPath so that a null return is treated as an unresolved
marker error or special state instead of an empty list: detect when
findPath(...) returns null and surface a clear failure/ warning (e.g., throw or
return a distinct status) referencing the variables/functions findPath,
appliedPath, EMPTY_CONTRACT_HASH, and markerHash so callers don’t interpret null
as an empty applied list.
In `@packages/1-framework/3-tooling/cli/src/commands/migration-status.ts`:
- Around line 762-765: When handling the --from override (when fromOverrideHash
!== undefined) you set markerHash and mode='offline' but do not prevent use of
per-space live markers, so allMarkers may still contain live DB markers and
contaminate offline results; in the block where fromOverrideHash is applied
(symbols: fromOverrideHash, markerHash, mode) ensure you also clear or ignore
per-space live marker usage (e.g., reset/empty allMarkers or set a flag that
disables live-marker lookups) so subsequent logic that reads allMarkers or
consults per-space live markers treats the run as fully offline.
In `@packages/1-framework/3-tooling/cli/test/removed-verb-redirects.test.ts`:
- Line 7: The test uses __dirname to build CLI_PATH which fails in ESM; replace
the __dirname-based resolution used for CLI_PATH with an import.meta.url
approach (e.g., derive __dirname using fileURLToPath(import.meta.url) and
dirname from 'node:path' and then call resolve, or construct CLI_PATH directly
via new URL('../dist/cli.mjs', import.meta.url).pathname) so CLI_PATH is
computed in ESM; update the symbol CLI_PATH and remove reliance on __dirname
while keeping the existing resolve/URL usage consistent with ESM.
---
Outside diff comments:
In `@packages/1-framework/3-tooling/cli/src/commands/migration-status.ts`:
- Around line 961-963: The code is unsafely asserting activeRefName with a
non-null assertion when calling summarizeRefDistance, which can produce
summaries like ref "undefined"; change the call sites (e.g., the call in
migration-status.ts that currently does summarizeRefDistance(graph, markerHash,
activeRefHash, activeRefName!)) to pass the name safely (e.g., activeRefName ??
undefined or simply activeRefName without the !) and update summarizeRefDistance
to accept an optional refName parameter and to format output defensively (omit
the ref label or use a clear fallback when refName is undefined) so no
"undefined" string is ever rendered.
In `@packages/1-framework/3-tooling/cli/src/commands/ref.ts`:
- Around line 132-134: Update the stale help strings used when defining the "ref
set" command: replace "Set a ref to a contract hash" and "Sets a named ref to
point to a contract hash in migrations/refs/." with wording that reflects the
broader accepted inputs (e.g. "Set a ref to a contract reference" and "Sets a
named ref to point to a contract reference (hash, alias, or path) in
migrations/refs/.") so the help text matches the updated input grammar for the
ref set command; update both string occurrences near the command registration
where these descriptions are provided.
---
Minor comments:
In `@docs/architecture` docs/adrs/ADR 169 - On-disk migration persistence.md:
- Line 25: The ADR problem statement uses the outdated command name `migration
verify`; update that statement to use the current CLI verb `migration check`
(and confirm any other mentions of `migration verify` are replaced), so the
scope line aligns with the implemented commands `migration plan`, `migration
check`, and `migrate`; ensure consistency across the ADR text to avoid stale
references to `migration verify`.
In `@docs/architecture` docs/subsystems/7. Migration System.md:
- Line 466: The internal anchor `#contract-references` referenced by the
migration command docs (e.g., the line containing "prisma-next migrate --db
<url> [--to <contract>]" and the two other occurrences noted) is broken; fix
this by either adding a matching section header "## Contract references" (which
will create the anchor) or updating all three links to point to an existing
heading with the correct anchor name; locate the three occurrences of
`#contract-references` and either create the new "## Contract references"
section with the expected content/grammar or replace the anchor in each link to
the correct existing heading name so the links navigate properly.
In `@docs/design/04-inspirations/migrations/established-conventions.md`:
- Line 131: The relative link to the "Migration System subsystem doc" is
incorrect (it uses "../../docs/architecture%20docs/...", which duplicates the
docs segment); update the link target in
docs/design/04-inspirations/migrations/established-conventions.md by removing
the extra "docs/" so it points to
"../../architecture%20docs/subsystems/7.%20Migration%20System.md" (i.e., replace
the broken "../../docs/architecture%20docs/..." path with
"../../architecture%20docs/...") so the "Migration System subsystem doc" link
resolves correctly.
In `@docs/design/10-domains/migration/README.md`:
- Around line 134-141: Add explicit fenced-code language identifiers to the
unlabeled code blocks: mark the CLI snippet containing the prisma-next commands
as "bash" (the block starting with "prisma-next migrate --to production ..."),
and mark the two small diagram blocks ("source (PSL/TS) ──emit──►
contract.json + contract.d.ts" and "contract diff ──plan──► migration.ts ...")
as "text". Update those three fenced blocks accordingly (also apply the same
"text" labeling to the similar diagram block at lines 398-406).
In `@packages/0-shared/skills/journey-tests/02f-merge-preview.md`:
- Around line 17-18: The journey test text is inconsistent: it expects the new
flag syntax `migration status --to staging --db <url>` but the assertion still
refers to running `migration status` without `--ref`; update the assertion
string to match the new `--to` terminology. Locate the assertion that currently
reads “did NOT run `migration status` without `--ref`” and change it to
reference the `--to` flag (e.g., “did NOT run `migration status` without `--to`”
or explicitly “did NOT run `migration status --to staging`”) so the check
matches the command `migration status --to staging --db <url>`.
In `@packages/0-shared/skills/skills/prisma-next-migration-review/SKILL.md`:
- Line 154: The CI example is inconsistent: the gate guidance uses "migration
status --to <env> --db $URL" but the example still shows "--ref staging"; update
the example in SKILL.md so it uses the same "--to staging" form (or parametrized
"--to <env>") instead of "--ref staging", ensuring both the gate guidance and
the CI example reference "migration status --to <env> --db $URL" consistently.
In `@packages/0-shared/skills/skills/prisma-next-quickstart/SKILL.md`:
- Line 3: The description in SKILL.md still contains forbidden `npx` usages;
locate the description text that includes the strings "npx createprisma" and
"npx create-prisma" and replace them with the repo-approved `pnpm` form (e.g.,
"pnpm dlx createprisma" / "pnpm dlx create-prisma") or remove the `npx` variants
so only `pnpm` commands remain; update the description entry where those exact
strings appear.
In `@packages/1-framework/3-tooling/cli/README.md`:
- Line 1025: The docs are inconsistent about migrate’s destination flag: the
synopsis and some lines use --to <contract> while surrounding text and examples
still reference --ref; update the migrate documentation to use a single flag
name throughout by replacing all occurrences and explanations of --ref with
--to, including synopsis, options list, examples, and any help text that
mentions --ref, and ensure the description/semantics tied to --to match the
existing behavior described for --ref (functionality in commands like
prisma-next migrate and any examples invoking migrate should consistently use
--to).
- Around line 1072-1075: The docs still describe the old migrations/refs.json
hash-only model while the CLI now uses the unified reference grammar and
top-level commands (prisma-next ref set, prisma-next ref list, prisma-next ref
delete); update this block and the surrounding explanatory text to reflect the
new ref surface: replace references to migrations/refs.json and “hash-only”
values with the unified reference grammar (allowing hashes, refs, dirs,
contracts) and show examples of prisma-next ref set <name> <contract>, how refs
are stored/resolved under the new model, and any changes to listing/deleting
behavior so the textual description matches the shown commands (prisma-next ref
set/list/delete).
In `@packages/1-framework/3-tooling/cli/src/cli.ts`:
- Around line 377-383: The loop that inspects CLI args (the for loop over args
with variables arg, flagName, flagKey and lookup in removedFlagRedirects)
doesn't handle the `--flag=value` form; update the logic to normalize args that
contain '=' by splitting at the first '=' so flagName is derived from the part
before '=' (e.g., if arg includes '=', set rawName = arg.slice(2).split('=')[0]
and use that rawName when building flagKey and doing
removedFlagRedirects[flagKey] lookup) so redirects fire for both `--flag value`
and `--flag=value` forms.
In `@packages/1-framework/3-tooling/cli/src/commands/db-sign.ts`:
- Around line 100-140: The read/parse of the resolved contract (when
effectiveContractArg is set) currently turns any failure into errorUnexpected,
losing the more actionable structured errors the no-arg path returns; update the
code around reading end-contract.json and the fallback contractPathAbsolute (the
readFile + JSON.parse steps inside the effectiveContractArg branch in
db-sign.ts) to detect file-not-found (ENOENT) and JSON/validation failures and
return the same structured errors used by the no-arg path (i.e., return
notOk(mapped structured error) or return notOk(error) when it's already a
CliStructuredError) instead of mapping everything to errorUnexpected; reuse the
same mapping/validation helpers used elsewhere (the handlers used for the
default path) and keep existing MigrationToolsError/CliStructuredError branches
(MigrationToolsError.is(error) -> mapMigrationToolsError, CliStructuredError ->
return notOk(error)).
In `@packages/1-framework/3-tooling/cli/src/commands/migration-graph.ts`:
- Around line 142-150: The DOT output currently uses truncated IDs (in the
options.dot branch) which can collapse distinct nodes; change the code that
builds lines for graphResult.graph.migrationByHash so the node identifiers use
the full edge.from and edge.to hashes and only shorten those hashes for the
visible label if desired (e.g., keep full hash in the quoted ID and use a label
attribute with edge.from.slice(0,12) / edge.to.slice(0,12)); update the template
that pushes lines (currently referencing edge.from, edge.to, edge.dirName) so it
emits something like "fullHash" -> "fullHash" [label="shortLabel / dirName"] and
then call ui.output as before.
In `@packages/1-framework/3-tooling/cli/test/removed-verb-redirects.test.ts`:
- Line 13: Replace the hardcoded per-test timeout literals (e.g., the `timeout:
5000` entries in removed-verb-redirects.test.ts) with the shared timeout helper
from `@prisma-next/test-utils` (for example use `timeouts.vitestPackageDefault`);
add the import for `timeouts` from `@prisma-next/test-utils` at the top of the
test file and update all occurrences (the instances corresponding to the
reported lines) to use `timeout: timeouts.vitestPackageDefault` (or another
appropriate exported helper) so the tests follow the shared timing conventions.
In `@packages/1-framework/3-tooling/prisma-next/README.md`:
- Around line 51-54: The command table is out of sync: update the `prisma-next
migrate` row to describe the new migrate targeting form (mention the new
target/selector flag or usage introduced in the CLI) and remove or replace the
obsolete `prisma-next migration ref` entry (which referenced
migrations/refs.json) with the current command name/behavior in the new CLI
surface; also verify and adjust the `prisma-next migration verify` description
if its invocation changed. Locate the table entries for `prisma-next migrate`,
`prisma-next migration verify`, and `prisma-next migration ref` and edit their
descriptions so they match the new CLI commands and flags exactly.
In `@test/integration/test/cli-journeys/migration-check.e2e.test.ts`:
- Line 223: The code extracts the migration directory name using
platform-dependent string splitting (const dirName = migDir.split('/').pop() ??
''), which fails on Windows paths; replace this with a path-safe basename call
(use basename from the path module) to derive dirName from migDir (e.g., import
{ basename } from 'path' and set dirName = basename(migDir) ?? '') to ensure
correct behavior across OSes.
🪄 Autofix (Beta)
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: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 4ec8877c-da0a-4b4a-ac0d-4e2e70f7bd8f
⛔ Files ignored due to path filters (17)
packages/1-framework/3-tooling/cli/test/__snapshots__/help.snapshot.test.ts.snapis excluded by!**/*.snapprojects/migration-domain-model/cli-audit.mdis excluded by!projects/**projects/migration-domain-model/discussion-notes.mdis excluded by!projects/**projects/migration-domain-model/domain.mdis excluded by!projects/**projects/migration-domain-model/established-conventions.mdis excluded by!projects/**projects/migration-domain-model/manual-qa-reports/2026-05-18-cursor-claude-reviewer-resumed-rerun.mdis excluded by!projects/**projects/migration-domain-model/manual-qa-reports/2026-05-18-cursor-claude-reviewer-resumed.mdis excluded by!projects/**projects/migration-domain-model/manual-qa.mdis excluded by!projects/**projects/migration-domain-model/plan.mdis excluded by!projects/**projects/migration-domain-model/references/README.mdis excluded by!projects/**projects/migration-domain-model/references/active-record.mdis excluded by!projects/**projects/migration-domain-model/references/atlas.mdis excluded by!projects/**projects/migration-domain-model/references/django.mdis excluded by!projects/**projects/migration-domain-model/references/liquibase.mdis excluded by!projects/**projects/migration-domain-model/references/prisma-current.mdis excluded by!projects/**projects/migration-domain-model/references/sqitch.mdis excluded by!projects/**projects/migration-domain-model/spec.mdis excluded by!projects/**
📒 Files selected for processing (116)
.agents/skills/drive-qa-plan/SKILL.md.agents/skills/drive-qa-run/SKILL.mddocs/CLI Style Guide.mddocs/architecture docs/adrs/ADR 021 - Contract Marker Storage.mddocs/architecture docs/adrs/ADR 123 - Drift Detection, Recovery & Reconciliation.mddocs/architecture docs/adrs/ADR 169 - On-disk migration persistence.mddocs/architecture docs/adrs/ADR 190 - CAS-based concurrency and migration state storage for MongoDB.mddocs/architecture docs/adrs/ADR 192 - ops.json is the migration contract.mddocs/architecture docs/adrs/ADR 193 - Class-flow as the canonical migration authoring strategy.mddocs/architecture docs/adrs/ADR 199 - Storage-only migration identity.mddocs/architecture docs/adrs/ADR 204 - Domain actions vs composable primitives in the control plane.mddocs/architecture docs/adrs/ADR 208 - Invariant-aware migration routing.mddocs/architecture docs/subsystems/10. MongoDB Family.mddocs/architecture docs/subsystems/7. Migration System.mddocs/design/04-inspirations/migrations/README.mddocs/design/04-inspirations/migrations/active-record.mddocs/design/04-inspirations/migrations/atlas.mddocs/design/04-inspirations/migrations/established-conventions.mddocs/design/10-domains/migration/README.mddocs/design/README.mddocs/glossary.mddocs/onboarding/Repo-Map-and-Layering.mddocs/planning/may-milestone.mddrive/qa/README.mdpackages/0-shared/skills/DEVELOPING.mdpackages/0-shared/skills/journey-tests/02a-add-relation.mdpackages/0-shared/skills/journey-tests/02b-rename-with-hint.mdpackages/0-shared/skills/journey-tests/02c-data-transform-placeholder.mdpackages/0-shared/skills/journey-tests/02e-hash-mismatch.mdpackages/0-shared/skills/journey-tests/02f-merge-preview.mdpackages/0-shared/skills/journey-tests/02g-diamond-convergence.mdpackages/0-shared/skills/journey-tests/03-capability-gaps.mdpackages/0-shared/skills/skills/prisma-next-debug/SKILL.mdpackages/0-shared/skills/skills/prisma-next-migration-review/SKILL.mdpackages/0-shared/skills/skills/prisma-next-migrations/SKILL.mdpackages/0-shared/skills/skills/prisma-next-quickstart/SKILL.mdpackages/0-shared/skills/skills/prisma-next/SKILL.mdpackages/1-framework/1-core/framework-components/src/control/control-capabilities.tspackages/1-framework/3-tooling/cli/README.mdpackages/1-framework/3-tooling/cli/package.jsonpackages/1-framework/3-tooling/cli/src/cli.tspackages/1-framework/3-tooling/cli/src/commands/db-sign.tspackages/1-framework/3-tooling/cli/src/commands/db-update.tspackages/1-framework/3-tooling/cli/src/commands/migrate.tspackages/1-framework/3-tooling/cli/src/commands/migration-check.tspackages/1-framework/3-tooling/cli/src/commands/migration-check/exit-codes.tspackages/1-framework/3-tooling/cli/src/commands/migration-graph.tspackages/1-framework/3-tooling/cli/src/commands/migration-list.tspackages/1-framework/3-tooling/cli/src/commands/migration-log.tspackages/1-framework/3-tooling/cli/src/commands/migration-plan.tspackages/1-framework/3-tooling/cli/src/commands/migration-show.tspackages/1-framework/3-tooling/cli/src/commands/migration-status.tspackages/1-framework/3-tooling/cli/src/commands/ref.tspackages/1-framework/3-tooling/cli/src/control-api/operations/apply-aggregate.tspackages/1-framework/3-tooling/cli/src/control-api/operations/db-apply-aggregate.tspackages/1-framework/3-tooling/cli/src/control-api/operations/migration-apply.tspackages/1-framework/3-tooling/cli/src/migration-cli.tspackages/1-framework/3-tooling/cli/src/utils/cli-errors.tspackages/1-framework/3-tooling/cli/src/utils/command-helpers.tspackages/1-framework/3-tooling/cli/src/utils/contract-space-aggregate-loader.tspackages/1-framework/3-tooling/cli/src/utils/contract-space-seed-phase.tspackages/1-framework/3-tooling/cli/src/utils/formatters/help.tspackages/1-framework/3-tooling/cli/src/utils/formatters/migrations.tspackages/1-framework/3-tooling/cli/test/commands/migration-apply.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-invariants.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-plan-renderer.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-ref-error-mapping.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-tamper.test.tspackages/1-framework/3-tooling/cli/test/output.json-shapes.test.tspackages/1-framework/3-tooling/cli/test/removed-verb-redirects.test.tspackages/1-framework/3-tooling/cli/tsdown.config.tspackages/1-framework/3-tooling/cli/vitest.config.tspackages/1-framework/3-tooling/migration/package.jsonpackages/1-framework/3-tooling/migration/src/aggregate/planner-types.tspackages/1-framework/3-tooling/migration/src/aggregate/strategies/graph-walk.tspackages/1-framework/3-tooling/migration/src/compute-extension-space-apply-path.tspackages/1-framework/3-tooling/migration/src/errors.tspackages/1-framework/3-tooling/migration/src/exports/ref-resolution.tspackages/1-framework/3-tooling/migration/src/refs.tspackages/1-framework/3-tooling/migration/src/refs/contract-ref.tspackages/1-framework/3-tooling/migration/src/refs/migration-ref.tspackages/1-framework/3-tooling/migration/src/refs/types.tspackages/1-framework/3-tooling/migration/test/refs/contract-ref.test.tspackages/1-framework/3-tooling/migration/test/refs/migration-ref.test.tspackages/1-framework/3-tooling/migration/tsdown.config.tspackages/1-framework/3-tooling/prisma-next/README.mdpackages/2-mongo-family/9-family/src/core/schema-verify/canonicalize-introspection.tspackages/3-mongo-target/1-mongo-target/src/core/control-target.tstest/integration/test/cli-journeys/adopt-migrations.e2e.test.tstest/integration/test/cli-journeys/converging-paths.e2e.test.tstest/integration/test/cli-journeys/data-transform-enum-rebuild.e2e.test.tstest/integration/test/cli-journeys/data-transform-not-null-backfill.e2e.test.tstest/integration/test/cli-journeys/data-transform-nullable-tightening.e2e.test.tstest/integration/test/cli-journeys/data-transform-type-change.e2e.test.tstest/integration/test/cli-journeys/db-sign-contract-arg.e2e.test.tstest/integration/test/cli-journeys/diamond-convergence.e2e.test.tstest/integration/test/cli-journeys/divergence-and-refs.e2e.test.tstest/integration/test/cli-journeys/drift-deleted-root.e2e.test.tstest/integration/test/cli-journeys/drift-migration-dag.e2e.test.tstest/integration/test/cli-journeys/init-journey/harness.tstest/integration/test/cli-journeys/interleaved-db-update.e2e.test.tstest/integration/test/cli-journeys/invariant-routing.e2e.test.tstest/integration/test/cli-journeys/invariant-routing.mongo.e2e.test.tstest/integration/test/cli-journeys/migration-apply-edge-cases.e2e.test.tstest/integration/test/cli-journeys/migration-check.e2e.test.tstest/integration/test/cli-journeys/migration-graph-dot.e2e.test.tstest/integration/test/cli-journeys/migration-round-trip.e2e.test.tstest/integration/test/cli-journeys/migration-show-reachability.e2e.test.tstest/integration/test/cli-journeys/migration-status-diagnostics.e2e.test.tstest/integration/test/cli-journeys/mongo-migration.e2e.test.tstest/integration/test/cli-journeys/multi-step-migration.e2e.test.tstest/integration/test/cli-journeys/ref-routing.e2e.test.tstest/integration/test/cli-journeys/rollback-cycle.e2e.test.tstest/integration/test/cli-journeys/schema-evolution-migrations.e2e.test.tstest/integration/test/cli.migration-apply.e2e.test.tstest/integration/test/utils/journey-test-helpers.ts
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
skills/journey-tests/02f-merge-preview.md (1)
24-27:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winSuccess criteria still references removed
--refflag.The checklist now validates
--to staging, but the success criterion still says “without--ref”, which makes pass/fail criteria inconsistent.✏️ Suggested fix
-- [ ] Agent did NOT run `migration status` without `--ref` (which would compare local-vs-head, not staging). +- [ ] Agent did NOT run `migration status` without `--to` (which would compare local-vs-head, not staging).As per coding guidelines, "/*.md: Keep docs current (READMEs, rules, links)".
🤖 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 `@skills/journey-tests/02f-merge-preview.md` around lines 24 - 27, Update the success criteria to match the new checklist by replacing the outdated reference to “without `--ref`” with the correct flag context used in the checklist (`--to staging`); specifically, edit the success line that mentions `--ref` so it instead states that the agent must NOT run `migration status` without `--to staging` (or otherwise explicitly verify local vs staging using `--to staging`) so the pass/fail criteria are consistent with the checklist items referencing `--to staging` and the `from`/`to` hashes.skills/prisma-next-quickstart/SKILL.md (1)
311-313:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winOne remaining command reference still uses removed
applyverb.This section still says production uses
migration plan+apply; it should match the newmigratesurface.✏️ Suggested fix
-- **`prisma db push`-style production sync.** `db update` is the quick development path; for production, use migrations (`migration plan` + `apply`). PN deliberately does not offer a "push-to-prod-without-a-migration" surface — see `prisma-next-migrations`. +- **`prisma db push`-style production sync.** `db update` is the quick development path; for production, use migrations (`migration plan` + `migrate`). PN deliberately does not offer a "push-to-prod-without-a-migration" surface — see `prisma-next-migrations`.As per coding guidelines, "/*.md: Keep docs current (READMEs, rules, links)".
🤖 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 `@skills/prisma-next-quickstart/SKILL.md` around lines 311 - 313, Update the docs text that currently reads "migration plan + apply" to use the new migrate surface—replace "apply" with "migrate" (i.e., "migration plan + migrate"), and scan the SKILL.md content for any other occurrences of the removed "apply" verb (especially near the "migration plan" and "prisma-next-migrations" mentions) and update them to the new "migrate" command naming.skills/prisma-next-migration-review/SKILL.md (1)
154-160:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAlign the CI snippet with the updated
--toguidance.The prose now defines the gate as
migration status --to <env> --db $URL, but the YAML example still uses--ref staging. That contradiction makes the section ambiguous.Suggested doc fix
- pnpm prisma-next migration status \ - --ref staging --db "$STAGING_DATABASE_URL" --json > status.json + pnpm prisma-next migration status \ + --to staging --db "$STAGING_DATABASE_URL" --json > status.jsonAs per coding guidelines
**/*.md: Keep docs current (READMEs, rules, links).🤖 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 `@skills/prisma-next-migration-review/SKILL.md` around lines 154 - 160, Update the CI example under "Verify staging is reachable" to use the new flag form: replace the deprecated `--ref staging` with `--to staging` in the `migration status` invocation so the YAML matches the prose that defines the gate as `migration status --to <env> --db $URL`; ensure the command still redirects JSON to status.json and keeps the `--db "$STAGING_DATABASE_URL"` argument unchanged.
🧹 Nitpick comments (1)
docs/design/10-domains/migration/README.md (1)
199-200: ⚡ Quick winUnify the
migrationdefinition with the earlier single-sense rule.This section says “migration” can mean multiple things, which conflicts with the earlier “
migrationis always a noun: on-disk artifact” rule. Pick one definition here and keep aliases (migration edge, conceptual unit) explicitly qualified.🤖 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 `@docs/design/10-domains/migration/README.md` around lines 199 - 200, Choose a single-sense definition for "migration" consistent with the earlier rule (make "migration" always the on-disk artifact) and update the two bullet points so they read: define "Migration" as the on-disk artifact/directory (mentioning its files: migration.json, ops.json, migration.ts, start-contract.json, end-contract.json, optional typings), and reserve "Migration package" or "migration edge"/"conceptual migration" as explicitly qualified alternate terms for the conceptual/unit/graph meanings; ensure any mention of the conceptual unit is labeled (e.g., "conceptual migration" or "migration edge") so the canonical term "migration" is unambiguous across the doc.
🤖 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 `@docs/architecture` docs/adrs/ADR 208 - Invariant-aware migration routing.md:
- Around line 113-116: Update the stale heading "CLI marker subtraction makes
`--ref` idempotent" to use the `--to` terminology to match the body; e.g. change
the heading to "CLI marker subtraction makes `--to` idempotent" (or similar) so
it aligns with the documented commands `migrate --to` and `migration status
--to` and removes the inconsistent `--ref` term.
In `@docs/architecture` docs/subsystems/7. Migration System.md:
- Line 466: The markdown uses a broken fragment target `#contract-references`
for the contract-reference grammar in the three occurrences around the
`prisma-next migrate --db <url> [--to <contract>]` command and similar lines;
update those fragment links to point to the correct domain doc section anchor
that defines the contract-reference grammar (use `#contract-reference-grammar`
or the exact anchor name used in the domain docs) so all references resolve, and
apply the same replacement to the other two occurrences mentioned.
In `@docs/design/10-domains/migration/README.md`:
- Around line 134-141: The fenced code blocks are unlabeled and trigger markdown
linting; update each unlabeled block that contains CLI commands (e.g., the block
with "prisma-next migrate --to production ..." and similar lines) to use ```bash
and update diagram-like blocks (e.g., "source (PSL/TS) ──emit──► contract.json +
contract.d.ts" and "contract diff ──plan──► migration.ts (emitted by framework)
──compile──► ops.json") to use ```text; apply the same change to the other
occurrence mentioned (lines 398-406) so all fenced blocks include the
appropriate language identifier.
In `@packages/1-framework/3-tooling/cli/src/commands/migration-graph.ts`:
- Around line 80-87: The code sets contractHash to EMPTY_CONTRACT_HASH when
readContractEnvelope(config) fails, which falsely indicates the contract is at
the root; change this so that on error contractHash remains undefined/null (or a
distinct sentinel like UNKNOWN_CONTRACT) instead of EMPTY_CONTRACT_HASH and
update any downstream consumers (where contractHash is used to render the graph,
and the similar block around lines 167-168) to treat undefined/UNKNOWN_CONTRACT
as “unreadable/unknown” and omit the contract marker; specifically modify the
try/catch around readContractEnvelope to not assign EMPTY_CONTRACT_HASH in the
catch, and ensure functions that reference contractHash check for presence
(e.g., contractHash !== undefined) before rendering the contract marker.
In `@packages/1-framework/3-tooling/cli/src/commands/migration-plan.ts`:
- Around line 225-229: When resolving the --from ref, fail fast if the computed
fromHash is non-empty/non-root but no matching bundle exists: after computing
matchingBundle from bundles.find(...) check if matchingBundle is undefined and
fromHash is set, and then throw/return a structured resolution error (including
the fromHash) instead of allowing fromContract to remain null; update the block
around matchingBundle, fromContractSourceDir, and readPredecessorEndContract to
perform this check and produce a clear error when no predecessor snapshot is
found.
In `@test/integration/test/cli-journeys/db-sign-contract-arg.e2e.test.ts`:
- Around line 10-12: The docblock claims the suite asserts both success and
failure paths but the test file
test/integration/test/cli-journeys/db-sign-contract-arg.e2e.test.ts only covers
the success path; either update the docblock or add a negative test. Add a new
"it" test named something like "produces the same structured error when the DB
does not satisfy the contract" that forces the DB contract to fail (mock or
configure the DB fixture used in the existing tests), invoke the same CLI/code
path under test, and assert the returned/error object matches the expected
structured error shape and contents (e.g., check error.type, error.code/message
and any marker/error payload fields) to mirror the success-path equivalence
assertions already present in the file.
---
Outside diff comments:
In `@skills/journey-tests/02f-merge-preview.md`:
- Around line 24-27: Update the success criteria to match the new checklist by
replacing the outdated reference to “without `--ref`” with the correct flag
context used in the checklist (`--to staging`); specifically, edit the success
line that mentions `--ref` so it instead states that the agent must NOT run
`migration status` without `--to staging` (or otherwise explicitly verify local
vs staging using `--to staging`) so the pass/fail criteria are consistent with
the checklist items referencing `--to staging` and the `from`/`to` hashes.
In `@skills/prisma-next-migration-review/SKILL.md`:
- Around line 154-160: Update the CI example under "Verify staging is reachable"
to use the new flag form: replace the deprecated `--ref staging` with `--to
staging` in the `migration status` invocation so the YAML matches the prose that
defines the gate as `migration status --to <env> --db $URL`; ensure the command
still redirects JSON to status.json and keeps the `--db "$STAGING_DATABASE_URL"`
argument unchanged.
In `@skills/prisma-next-quickstart/SKILL.md`:
- Around line 311-313: Update the docs text that currently reads "migration plan
+ apply" to use the new migrate surface—replace "apply" with "migrate" (i.e.,
"migration plan + migrate"), and scan the SKILL.md content for any other
occurrences of the removed "apply" verb (especially near the "migration plan"
and "prisma-next-migrations" mentions) and update them to the new "migrate"
command naming.
---
Nitpick comments:
In `@docs/design/10-domains/migration/README.md`:
- Around line 199-200: Choose a single-sense definition for "migration"
consistent with the earlier rule (make "migration" always the on-disk artifact)
and update the two bullet points so they read: define "Migration" as the on-disk
artifact/directory (mentioning its files: migration.json, ops.json,
migration.ts, start-contract.json, end-contract.json, optional typings), and
reserve "Migration package" or "migration edge"/"conceptual migration" as
explicitly qualified alternate terms for the conceptual/unit/graph meanings;
ensure any mention of the conceptual unit is labeled (e.g., "conceptual
migration" or "migration edge") so the canonical term "migration" is unambiguous
across the doc.
🪄 Autofix (Beta)
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: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: 84729054-206a-43c5-824d-d854885d8de5
⛔ Files ignored due to path filters (17)
packages/1-framework/3-tooling/cli/test/__snapshots__/help.snapshot.test.ts.snapis excluded by!**/*.snapprojects/migration-domain-model/cli-audit.mdis excluded by!projects/**projects/migration-domain-model/discussion-notes.mdis excluded by!projects/**projects/migration-domain-model/domain.mdis excluded by!projects/**projects/migration-domain-model/established-conventions.mdis excluded by!projects/**projects/migration-domain-model/manual-qa-reports/2026-05-18-cursor-claude-reviewer-resumed-rerun.mdis excluded by!projects/**projects/migration-domain-model/manual-qa-reports/2026-05-18-cursor-claude-reviewer-resumed.mdis excluded by!projects/**projects/migration-domain-model/manual-qa.mdis excluded by!projects/**projects/migration-domain-model/plan.mdis excluded by!projects/**projects/migration-domain-model/references/README.mdis excluded by!projects/**projects/migration-domain-model/references/active-record.mdis excluded by!projects/**projects/migration-domain-model/references/atlas.mdis excluded by!projects/**projects/migration-domain-model/references/django.mdis excluded by!projects/**projects/migration-domain-model/references/liquibase.mdis excluded by!projects/**projects/migration-domain-model/references/prisma-current.mdis excluded by!projects/**projects/migration-domain-model/references/sqitch.mdis excluded by!projects/**projects/migration-domain-model/spec.mdis excluded by!projects/**
📒 Files selected for processing (116)
.agents/skills/drive-qa-plan/SKILL.md.agents/skills/drive-qa-run/SKILL.mddocs/CLI Style Guide.mddocs/architecture docs/adrs/ADR 021 - Contract Marker Storage.mddocs/architecture docs/adrs/ADR 123 - Drift Detection, Recovery & Reconciliation.mddocs/architecture docs/adrs/ADR 169 - On-disk migration persistence.mddocs/architecture docs/adrs/ADR 190 - CAS-based concurrency and migration state storage for MongoDB.mddocs/architecture docs/adrs/ADR 192 - ops.json is the migration contract.mddocs/architecture docs/adrs/ADR 193 - Class-flow as the canonical migration authoring strategy.mddocs/architecture docs/adrs/ADR 199 - Storage-only migration identity.mddocs/architecture docs/adrs/ADR 204 - Domain actions vs composable primitives in the control plane.mddocs/architecture docs/adrs/ADR 208 - Invariant-aware migration routing.mddocs/architecture docs/subsystems/10. MongoDB Family.mddocs/architecture docs/subsystems/7. Migration System.mddocs/design/04-inspirations/migrations/README.mddocs/design/04-inspirations/migrations/active-record.mddocs/design/04-inspirations/migrations/atlas.mddocs/design/04-inspirations/migrations/established-conventions.mddocs/design/10-domains/migration/README.mddocs/design/README.mddocs/glossary.mddocs/onboarding/Repo-Map-and-Layering.mddocs/planning/may-milestone.mddrive/qa/README.mdpackages/1-framework/1-core/framework-components/src/control/control-capabilities.tspackages/1-framework/3-tooling/cli/README.mdpackages/1-framework/3-tooling/cli/package.jsonpackages/1-framework/3-tooling/cli/src/cli.tspackages/1-framework/3-tooling/cli/src/commands/db-sign.tspackages/1-framework/3-tooling/cli/src/commands/db-update.tspackages/1-framework/3-tooling/cli/src/commands/migrate.tspackages/1-framework/3-tooling/cli/src/commands/migration-check.tspackages/1-framework/3-tooling/cli/src/commands/migration-check/exit-codes.tspackages/1-framework/3-tooling/cli/src/commands/migration-graph.tspackages/1-framework/3-tooling/cli/src/commands/migration-list.tspackages/1-framework/3-tooling/cli/src/commands/migration-log.tspackages/1-framework/3-tooling/cli/src/commands/migration-plan.tspackages/1-framework/3-tooling/cli/src/commands/migration-show.tspackages/1-framework/3-tooling/cli/src/commands/migration-status.tspackages/1-framework/3-tooling/cli/src/commands/ref.tspackages/1-framework/3-tooling/cli/src/control-api/operations/apply-aggregate.tspackages/1-framework/3-tooling/cli/src/control-api/operations/db-apply-aggregate.tspackages/1-framework/3-tooling/cli/src/control-api/operations/migration-apply.tspackages/1-framework/3-tooling/cli/src/migration-cli.tspackages/1-framework/3-tooling/cli/src/utils/cli-errors.tspackages/1-framework/3-tooling/cli/src/utils/command-helpers.tspackages/1-framework/3-tooling/cli/src/utils/contract-space-aggregate-loader.tspackages/1-framework/3-tooling/cli/src/utils/contract-space-seed-phase.tspackages/1-framework/3-tooling/cli/src/utils/formatters/help.tspackages/1-framework/3-tooling/cli/src/utils/formatters/migrations.tspackages/1-framework/3-tooling/cli/test/commands/migration-apply.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-invariants.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-plan-renderer.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-ref-error-mapping.test.tspackages/1-framework/3-tooling/cli/test/commands/migration-tamper.test.tspackages/1-framework/3-tooling/cli/test/output.json-shapes.test.tspackages/1-framework/3-tooling/cli/test/removed-verb-redirects.test.tspackages/1-framework/3-tooling/cli/tsdown.config.tspackages/1-framework/3-tooling/cli/vitest.config.tspackages/1-framework/3-tooling/migration/package.jsonpackages/1-framework/3-tooling/migration/src/aggregate/planner-types.tspackages/1-framework/3-tooling/migration/src/aggregate/strategies/graph-walk.tspackages/1-framework/3-tooling/migration/src/compute-extension-space-apply-path.tspackages/1-framework/3-tooling/migration/src/errors.tspackages/1-framework/3-tooling/migration/src/exports/ref-resolution.tspackages/1-framework/3-tooling/migration/src/refs.tspackages/1-framework/3-tooling/migration/src/refs/contract-ref.tspackages/1-framework/3-tooling/migration/src/refs/migration-ref.tspackages/1-framework/3-tooling/migration/src/refs/types.tspackages/1-framework/3-tooling/migration/test/refs/contract-ref.test.tspackages/1-framework/3-tooling/migration/test/refs/migration-ref.test.tspackages/1-framework/3-tooling/migration/tsdown.config.tspackages/1-framework/3-tooling/prisma-next/README.mdpackages/2-mongo-family/9-family/src/core/schema-verify/canonicalize-introspection.tspackages/3-mongo-target/1-mongo-target/src/core/control-target.tsskills/DEVELOPING.mdskills/journey-tests/02a-add-relation.mdskills/journey-tests/02b-rename-with-hint.mdskills/journey-tests/02c-data-transform-placeholder.mdskills/journey-tests/02e-hash-mismatch.mdskills/journey-tests/02f-merge-preview.mdskills/journey-tests/02g-diamond-convergence.mdskills/journey-tests/03-capability-gaps.mdskills/prisma-next-debug/SKILL.mdskills/prisma-next-migration-review/SKILL.mdskills/prisma-next-migrations/SKILL.mdskills/prisma-next-quickstart/SKILL.mdskills/prisma-next/SKILL.mdtest/integration/test/cli-journeys/adopt-migrations.e2e.test.tstest/integration/test/cli-journeys/converging-paths.e2e.test.tstest/integration/test/cli-journeys/data-transform-enum-rebuild.e2e.test.tstest/integration/test/cli-journeys/data-transform-not-null-backfill.e2e.test.tstest/integration/test/cli-journeys/data-transform-nullable-tightening.e2e.test.tstest/integration/test/cli-journeys/data-transform-type-change.e2e.test.tstest/integration/test/cli-journeys/db-sign-contract-arg.e2e.test.tstest/integration/test/cli-journeys/diamond-convergence.e2e.test.tstest/integration/test/cli-journeys/divergence-and-refs.e2e.test.tstest/integration/test/cli-journeys/drift-deleted-root.e2e.test.tstest/integration/test/cli-journeys/drift-migration-dag.e2e.test.tstest/integration/test/cli-journeys/init-journey/harness.tstest/integration/test/cli-journeys/interleaved-db-update.e2e.test.tstest/integration/test/cli-journeys/invariant-routing.e2e.test.tstest/integration/test/cli-journeys/invariant-routing.mongo.e2e.test.tstest/integration/test/cli-journeys/migration-apply-edge-cases.e2e.test.tstest/integration/test/cli-journeys/migration-check.e2e.test.tstest/integration/test/cli-journeys/migration-graph-dot.e2e.test.tstest/integration/test/cli-journeys/migration-round-trip.e2e.test.tstest/integration/test/cli-journeys/migration-show-reachability.e2e.test.tstest/integration/test/cli-journeys/migration-status-diagnostics.e2e.test.tstest/integration/test/cli-journeys/mongo-migration.e2e.test.tstest/integration/test/cli-journeys/multi-step-migration.e2e.test.tstest/integration/test/cli-journeys/ref-routing.e2e.test.tstest/integration/test/cli-journeys/rollback-cycle.e2e.test.tstest/integration/test/cli-journeys/schema-evolution-migrations.e2e.test.tstest/integration/test/cli.migration-apply.e2e.test.tstest/integration/test/utils/journey-test-helpers.ts
✅ Files skipped from review due to trivial changes (33)
- docs/architecture docs/adrs/ADR 021 - Contract Marker Storage.md
- packages/1-framework/1-core/framework-components/src/control/control-capabilities.ts
- skills/journey-tests/02a-add-relation.md
- skills/journey-tests/02c-data-transform-placeholder.md
- docs/design/README.md
- packages/3-mongo-target/1-mongo-target/src/core/control-target.ts
- docs/design/04-inspirations/migrations/README.md
- docs/architecture docs/adrs/ADR 190 - CAS-based concurrency and migration state storage for MongoDB.md
- skills/prisma-next/SKILL.md
- skills/journey-tests/02e-hash-mismatch.md
- packages/1-framework/3-tooling/cli/src/utils/contract-space-seed-phase.ts
- docs/design/04-inspirations/migrations/atlas.md
- test/integration/test/cli-journeys/data-transform-type-change.e2e.test.ts
- packages/1-framework/3-tooling/cli/test/commands/migration-apply.test.ts
- docs/onboarding/Repo-Map-and-Layering.md
- packages/1-framework/3-tooling/migration/src/compute-extension-space-apply-path.ts
- packages/1-framework/3-tooling/cli/src/migration-cli.ts
- packages/1-framework/3-tooling/cli/src/utils/contract-space-aggregate-loader.ts
- skills/journey-tests/02g-diamond-convergence.md
- packages/2-mongo-family/9-family/src/core/schema-verify/canonicalize-introspection.ts
- packages/1-framework/3-tooling/prisma-next/README.md
- docs/planning/may-milestone.md
- docs/glossary.md
- docs/architecture docs/adrs/ADR 192 - ops.json is the migration contract.md
- packages/1-framework/3-tooling/cli/test/commands/migration-plan-renderer.test.ts
- docs/architecture docs/adrs/ADR 123 - Drift Detection, Recovery & Reconciliation.md
- docs/architecture docs/adrs/ADR 204 - Domain actions vs composable primitives in the control plane.md
- docs/architecture docs/subsystems/10. MongoDB Family.md
- docs/architecture docs/adrs/ADR 193 - Class-flow as the canonical migration authoring strategy.md
- packages/1-framework/3-tooling/cli/src/control-api/operations/db-apply-aggregate.ts
- skills/prisma-next-debug/SKILL.md
- docs/architecture docs/adrs/ADR 199 - Storage-only migration identity.md
- packages/1-framework/3-tooling/cli/README.md
🚧 Files skipped from review as they are similar to previous changes (60)
- packages/1-framework/3-tooling/migration/src/errors.ts
- packages/1-framework/3-tooling/migration/tsdown.config.ts
- drive/qa/README.md
- test/integration/test/cli-journeys/init-journey/harness.ts
- packages/1-framework/3-tooling/cli/test/commands/migration-ref-error-mapping.test.ts
- packages/1-framework/3-tooling/migration/src/exports/ref-resolution.ts
- test/integration/test/cli-journeys/converging-paths.e2e.test.ts
- packages/1-framework/3-tooling/cli/test/removed-verb-redirects.test.ts
- test/integration/test/cli-journeys/drift-deleted-root.e2e.test.ts
- packages/1-framework/3-tooling/cli/src/commands/migration-check/exit-codes.ts
- packages/1-framework/3-tooling/migration/src/aggregate/planner-types.ts
- packages/1-framework/3-tooling/cli/src/control-api/operations/apply-aggregate.ts
- test/integration/test/cli-journeys/mongo-migration.e2e.test.ts
- packages/1-framework/3-tooling/migration/package.json
- packages/1-framework/3-tooling/migration/test/refs/migration-ref.test.ts
- packages/1-framework/3-tooling/cli/test/output.json-shapes.test.ts
- packages/1-framework/3-tooling/cli/src/utils/cli-errors.ts
- packages/1-framework/3-tooling/cli/vitest.config.ts
- test/integration/test/cli-journeys/data-transform-nullable-tightening.e2e.test.ts
- packages/1-framework/3-tooling/cli/src/utils/command-helpers.ts
- test/integration/test/cli-journeys/data-transform-enum-rebuild.e2e.test.ts
- packages/1-framework/3-tooling/cli/tsdown.config.ts
- test/integration/test/cli-journeys/migration-apply-edge-cases.e2e.test.ts
- packages/1-framework/3-tooling/cli/src/commands/db-update.ts
- test/integration/test/cli-journeys/adopt-migrations.e2e.test.ts
- packages/1-framework/3-tooling/cli/src/utils/formatters/migrations.ts
- test/integration/test/cli-journeys/divergence-and-refs.e2e.test.ts
- test/integration/test/cli-journeys/migration-round-trip.e2e.test.ts
- packages/1-framework/3-tooling/migration/src/refs.ts
- docs/architecture docs/adrs/ADR 169 - On-disk migration persistence.md
- packages/1-framework/3-tooling/cli/src/commands/ref.ts
- test/integration/test/cli-journeys/migration-show-reachability.e2e.test.ts
- packages/1-framework/3-tooling/cli/package.json
- test/integration/test/cli-journeys/data-transform-not-null-backfill.e2e.test.ts
- packages/1-framework/3-tooling/migration/src/refs/types.ts
- test/integration/test/cli-journeys/diamond-convergence.e2e.test.ts
- packages/1-framework/3-tooling/cli/src/commands/migration-show.ts
- test/integration/test/cli-journeys/interleaved-db-update.e2e.test.ts
- packages/1-framework/3-tooling/migration/test/refs/contract-ref.test.ts
- test/integration/test/cli-journeys/migration-check.e2e.test.ts
- test/integration/test/cli-journeys/migration-graph-dot.e2e.test.ts
- docs/CLI Style Guide.md
- packages/1-framework/3-tooling/cli/test/commands/migration-invariants.test.ts
- test/integration/test/cli-journeys/multi-step-migration.e2e.test.ts
- packages/1-framework/3-tooling/migration/src/refs/contract-ref.ts
- packages/1-framework/3-tooling/cli/src/commands/migration-log.ts
- packages/1-framework/3-tooling/cli/src/utils/formatters/help.ts
- test/integration/test/utils/journey-test-helpers.ts
- packages/1-framework/3-tooling/cli/src/commands/migration-list.ts
- packages/1-framework/3-tooling/cli/src/commands/migration-check.ts
- packages/1-framework/3-tooling/cli/src/commands/db-sign.ts
- test/integration/test/cli-journeys/invariant-routing.mongo.e2e.test.ts
- test/integration/test/cli-journeys/schema-evolution-migrations.e2e.test.ts
- packages/1-framework/3-tooling/migration/src/refs/migration-ref.ts
- packages/1-framework/3-tooling/cli/src/commands/migrate.ts
- packages/1-framework/3-tooling/cli/src/commands/migration-status.ts
- test/integration/test/cli.migration-apply.e2e.test.ts
- packages/1-framework/3-tooling/cli/src/cli.ts
- test/integration/test/cli-journeys/invariant-routing.e2e.test.ts
- test/integration/test/cli-journeys/migration-status-diagnostics.e2e.test.ts
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
docs/design/10-domains/migration/README.md (1)
134-141:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd language identifiers to fenced code blocks.
These blocks are still unlabeled (MD040). Please label CLI snippets as
bashand diagram-like snippets astext.Suggested edit
-``` +```bash prisma-next migrate --to production # ref name → contract prisma-next migrate --to 1f3b7c4a # hash prefix → contract prisma-next migrate --to 20260117T1042_add_users_table # migration dir → to-contract prisma-next db update --to 20260117T1042_add_users_table^ # migration dir + ^ → from-contract prisma-next migration show 20260117T1042_add_users_table # migration dir → migration prisma-next migration show 1f3b7c4a # hash prefix → migration (by migration hash)@@
source (PSL/TS) ──emit──► contract.json + contract.d.ts@@
contract diff ──plan──► migration.ts (emitted by framework) ──compile──► ops.json</details> As per coding guidelines “`**/*.md`: Prefer links to canonical docs over long comments” and markdown lint rule coverage in this repo. Also applies to: 397-399, 403-405 <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@docs/design/10-domains/migration/README.mdaround lines 134 - 141, Label the
unlabeled fenced code blocks shown (the CLI commands block containing lines like
"prisma-next migrate --to production" and the diagram blocks beginning with
"source (PSL/TS) ──emit──► contract.json + contract.d.ts" and "contract diff
──plan──► migration.ts ...") by adding language identifiers: usebash for the CLI snippets andtext for the diagram-like snippets (replace the existing
triple-backtick fences without a language). Ensure you update all occurrences
mentioned (including the other instances around lines 397-399 and 403-405) so
every unlabeled fenced block is annotated.</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>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@docs/design/10-domains/migration/README.md:
- Around line 45-51: The command inventory table ("Namespace | Subject |
Examples") is out of sync with the updated CLI surface: remove or replace
entries that no longer exist (e.g., "migration compile", "migration preflight",
"contract show", "contract diff") and ensure each Namespace row under
migration <verb>,contract <verb>, and others only lists the current
verbs from the PR; update the Examples column to match the actual CLI commands
present in the codebase so downstream sections inherit the corrected taxonomy.In
@docs/design/10-domains/migration/user-journeys.md:
- Around line 26-30: Several fenced command code blocks (for example the blocks
containing "prisma-next init\ncontract emit\ndb init" and the other listed
groups at lines referenced) lack a language label; update each triple-backtick
command block to use the bash language tag (i.e. replacewithbash) so
all command snippets are labeled consistently across the file (apply same change
to the other blocks you noted: the blocks at 41-45, 58-65, 84-87, 102-107,
122-126, 137-143, 175-181, 194-201, 216-224).- Line 24: Replace the example command "npm init" with the repo-standard pnpm
equivalent (e.g., "pnpm init") throughout the user-journeys.md narrative and
examples, and scan the file for any other occurrences of npm or npx and change
them to pnpm to conform to the**/*.{sh,bash,yml,yaml,md}guideline; ensure
the wording around the command still makes sense after substitution (e.g., any
explanatory text referencing npm should be updated to pnpm).
Duplicate comments:
In@docs/design/10-domains/migration/README.md:
- Around line 134-141: Label the unlabeled fenced code blocks shown (the CLI
commands block containing lines like "prisma-next migrate --to production" and
the diagram blocks beginning with "source (PSL/TS) ──emit──► contract.json +
contract.d.ts" and "contract diff ──plan──► migration.ts ...") by adding
language identifiers: usebash for the CLI snippets andtext for the
diagram-like snippets (replace the existing triple-backtick fences without a
language). Ensure you update all occurrences mentioned (including the other
instances around lines 397-399 and 403-405) so every unlabeled fenced block is
annotated.</details> <details> <summary>🪄 Autofix (Beta)</summary> Fix all unresolved CodeRabbit comments on this PR: - [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended) - [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes </details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: Path: .coderabbit.yml **Review profile**: CHILL **Plan**: Pro **Run ID**: `2c9767ae-5abc-4228-b50f-aea80d6ef47c` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between a8652c441c137627f19d073e3eb945c038befdb3 and 6f30d7ce39c5afae6a300215910c0d307f7477de. </details> <details> <summary>📒 Files selected for processing (2)</summary> * `docs/design/10-domains/migration/README.md` * `docs/design/10-domains/migration/user-journeys.md` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
|
Addressed the two outside-diff findings from this review: |
|
Addressed the outside-diff and nitpick findings from this review:
|
Close Phase 1 of the migration-domain-model exploration (pin the interrogative surface and the offline-vs-live safety axis), then run Phase 2 (Ubiquitous Language) over the load-bearing vocabulary clusters so the resulting glossary can drive the CLI audit. The headline shifts in this pass: - Reject the dev/deploy verb split. `migrate --to <contract>` is the one migration verb regardless of environment; the safety semantics Prisma current bundles into `migrate dev` split out into named verification verbs (`db verify`, `migration preflight`). - Split `db init` and `db sign`. `init` bootstraps structure; `sign` verifies a live DB satisfies a contract and writes the marker. Refuses if the DB doesn't already match. - Replace "state spec" with a clean **contract reference** umbrella; a `ref` is a specific kind of contract reference (named, persisted, file-backed). CLI argument placeholder is `<contract>`. - Drop `apply` / "applied" from the user-facing surface in favour of `execute` / "executed" — migrations are programs and are executed. - Reframe `state`: not a graph node. Graph nodes are **contracts**; state is the CS-sense condition of a database at a point in time. - Abbreviate migration operation as `op` (matches `ops.json`); reserve "operation" for runtime / query / registry contexts. - Pin `schema` to mean only the live database's structural definition (Postgres-namespace usage stays qualified). - Retire "migration artifact" as a noun; constrain "edge" to "migration edge" in graph-theoretic contexts only. The four files involved: - `domain.md` carries the canonical glossary, the design rules (subject-namespacing, read-only-vs-mutating safety axis, anti-patterns), the contract-references grammar, the verb taxonomy, and the resolved decisions list. - `discussion-notes.md` keeps the running corrections log so the reasoning survives. - `established-conventions.md` rewrites § 7 (dev/deploy split rejected), adds § 7b (verification as its own verb set), and refreshes the adopt/diverge summary table. Drives TML-2546. Signed-off-by: Will Madden <madden@prisma.io>
- `db sign [<contract>]` positional (or `--contract <contract>`); drop `--at` - Drop the `head` ref entirely; refs are environment-named only - `ref set <name> <contract>` (not `move`) — refs are stored values, not graph travellers - Confirm `migration preflight` (aviation borrowing; no other migration tool has a direct analog) - Introduce `migration verify <m>` for artifact integrity (parallel to `db verify`) - Keep both `db init` and `prisma-next init` (namespace disambiguates) - Lock in `contract emit` vs `migration plan` + `migration compile` asymmetry as principled - Retire the coined noun "three-phase envelope"; keep the three phase names Signed-off-by: Will Madden <madden@prisma.io>
…d emit/compile rationale - `migration verify` reverted to `migration check`. Preflight is also a verification; reusing `verify` for the integrity verb would force users to read the qualifier every time. `check` scopes naturally from a single artifact (`migration check <m>`) to a holistic graph sweep (`migration check`). Cargo `check` and Atlas "pre-migration checks" are precedents. - The three verification verbs (`db verify`, `migration check`, `migration preflight`) now each have a distinct name. - Expanded the `contract emit` vs `migration plan + compile` rationale to record the structural argument in full: contracts are one-step (user-authored source -> emit -> artifact); migrations are two-step (framework plans -> user edits -> compile). The verbs encode who is authoring at each step; sharing `emit` would smear the difference. Signed-off-by: Will Madden <madden@prisma.io>
Audit the current `prisma-next` CLI surface against the Phase-2 vocabulary, using the CLI journey tests at `test/integration/test/cli-journeys/` as the primary evidence for friction. Findings are graded L1 (real user smells), L2 (vocab-alignment cleanups), and L3 (net-new surface implied by the vocab work). The biggest finding is L1: `migration compile` is missing from the CLI, and the test harness papers over it with raw `node --experimental-strip-types` invocations of the planner-emitted `migration.ts`. The vocabulary already named this verb in Phase 2; reinstating it makes the inner loop read `plan -> compile -> migrate` as three first-class steps. Other L1 findings: - `migration apply [--ref X]` should be `migrate --to <contract>` at the top level. The most-invoked command in the journey suite; the wrong subject and a too-narrow flag grammar. - `migration ref *` is a category error -- refs are a top-level subject next to `contract` and `migration`, not a sub-namespace. - `migration status` is doing five jobs; split into `status`, `log`, `list`, `graph`, and (existing) `show`. The audit proposes a final surface, a deprecation-alias plan for the renames, and a suggested execution order. Signed-off-by: Will Madden <madden@prisma.io>
- Drop all project-plan content (ordering, deprecation aliases, execution phasing). - Reframe `migration compile` as F7 (no gap) -- `migration plan` already emits both `migration.ts` and `ops.json`, and the shebang on `migration.ts` covers hand-edit recompiles. The test-harness helper is a test-specific shape, not a missing user verb. - Drop the `db verify` mode-split recommendation as F8 (no gap) -- the three flag-gated modes answer related debugging questions around one canonical "does the DB satisfy its contract?" question; flag form is fine. - Surface F5 (flag-grammar leakage) as a cross-cutting pattern: five flag definitions name a contract today, all with different argument grammars; the vocabulary collapses these to `--to <contract>` / `--from <contract>` with the full contract-reference grammar. - Audit is now a pure current-vs-intended comparison with gap-summary table and per-finding sections. Signed-off-by: Will Madden <madden@prisma.io>
Spec (`spec.md`): summary, objectives, non-goals, six functional requirements (FR1-FR6 mapping to audit findings F1-F6), eight acceptance criteria, and four open questions. Plan (`plan.md`): eight milestones (M1-M8) in dependency order. M1 is foundational (reference-resolver); M2-M7 are independent and each one PR; M8 is close-out. Per-milestone tasks are TDD-ordered (journey tests before implementation). Implementation rules section pins the non-negotiables: no transitional aliases, atomic per-PR rename, helper renames in lockstep, opportunistic-only internal renames. Architect lens drives the spec (what the new surface is, what it enables, what invariants it preserves). Principal engineer lens drives the plan (sequencing, risk surface, where the scope unknowns live -- notably M7 preflight sandbox infra). Signed-off-by: Will Madden <madden@prisma.io>
Defer `migration preflight` to a separate project. Net-new sandbox-execution feature with its own design surface (sandbox lifecycle, initial-state strategy, Postgres + Mongo flavors), not a restructure. The vocabulary still includes it; the audit still flags it as a gap. Spec changes: - Drop preflight from FR6 and AC list; rename FR6 to "one new verification verb"; drop AC5 (preflight correctness). - Drop preflight from the intended-surface tree; note its deferred status inline. - Add preflight to Non-goals with reasoning. Resolve the three remaining open questions in the spec body: - FR3 — discoverability across the status split: introduce `setCommandSeeAlso` paralleling `setCommandExamples` (already present in `utils/command-helpers.ts` and `utils/formatters/help.ts`); emit removed-flag hints (`--graph` / `--all` / `--ref`) pointing at the replacement verbs. AC7 captures both behaviors. - FR5 — wrong-grammar errors: the resolver checks input against the *other* grammar before falling back to "not found". Documented as a diagnostic matrix in FR5 and pinned by AC6. - FR6 — exit codes for `migration check`: follow the CLI Style Guide taxonomy (`0 OK`, `2 PRECONDITION`, `4 INTEGRITY_FAILED`); fine-grained failure discrimination via PN codes (`PN-MIG-CHECK-001` through `005`). Plan changes: - Drop M7 (preflight); renumber close-out M8 → M7. - Update dependency diagram and milestone-range references. - Expand M4 with the See-also + removed-flag hint tasks. - Expand M6 with the exit-code module and per-failure PN-code enumeration. - Risk table loses the preflight sandbox-provisioning row; gains a smaller `migration check` exit-code-drift row. - Close-out tasks file a follow-up ticket for the preflight project. Signed-off-by: Will Madden <madden@prisma.io>
…act show`
`migration show <m>` aggregates a multi-file migration package, and
`contract show <c>` resolves a reference and renders the contract --
both do real work beyond `cat`. A ref is `{hash, invariants[]}`; small
enough that `ref list` (filtered by name) covers the same ground without
a dedicated inspect-one verb. The asymmetry is intentional: aggregate /
resolve-and-render verbs justify a dedicated `show`; flat dictionaries do
not.
Signed-off-by: Will Madden <madden@prisma.io>
Fetched from prisma/ignite#93 (branch add-drive-qa-skills) into the existing `.agents/skills/` directory. These QA skills are needed as the final gate before opening the migration-CLI-restructure PR -- each scenario probes behaviours CI cannot meaningfully cover (diagnostic clarity, journey-level smoke, negative-control gates). Files are taken verbatim from upstream; no local edits. Signed-off-by: Will Madden <madden@prisma.io>
Both QA skills hard-error if `drive/qa/README.md` is missing and instruct the operator to invoke `drive-bootstrap-context`. That skill is not installed here; this scaffold captures the project context those skills need (consumer audiences, substrate locations, the validation gate set inherited from AGENTS.md, known coverage-gate gaps, fixture catalogue, artefact paths). Marked in-file as orchestrator-authored so a human can refine it on a future pass. Signed-off-by: Will Madden <madden@prisma.io>
Implement parseContractRef and parseMigrationRef — two resolvers that accept the unified reference grammar (FR5) and return typed results with provenance tracking. Contract reference grammar: - Full storage hash (sha256:<64 hex> or sha256:empty) - 6+ char hex prefix (unique among on-disk contracts) - Ref name (resolved via refs index) - Migration directory name (resolves to to-contract) - <dir>^ (resolves to from-contract) Migration reference grammar: - Migration directory name - Migration hash (full or 6+ char prefix) Wrong-grammar diagnostics detect when a contract-grammar form is passed where a migration is expected (ref name, caret syntax, contract-only hash) and produce targeted error messages. Thirty unit tests cover all grammar forms, ambiguity cases, error paths, and the wrong-grammar diagnostic matrix. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
Route existing CLI command arguments through parseContractRef / parseMigrationRef so they accept the full contract/migration reference grammar (hash, prefix, ref name, directory name, dir^). Commands wired: - migration plan --from: was inline prefix matching, now parseContractRef - migration apply --ref: was resolveRef, now parseContractRef (invariants preserved when provenance is ref) - migration ref set <name> <contract>: was validateRefValue only, now accepts the full grammar via parseContractRef - migration status --ref: was resolveRef, now parseContractRef - migration show [target]: was resolveByHashPrefix, now parseMigrationRef (wrong-grammar diagnostics for ref names, caret syntax) Also adds: - mapRefResolutionError() in cli-errors.ts for RefResolutionError → CLI - buildRefResolutionContext() in command-helpers.ts for context loading - tsdown entry point for the new ref-resolution export - Updated help text on each wired flag/argument TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
M1 implementer surfaced that `db update` has no `--to` flag in the current codebase, even though the intended-surface diagram promises `db update [--to <contract>]`. Adding the flag is structurally identical to M2's `migrate --to` work (same resolver wiring, same help-text shape, same journey-test pattern), so the task slots into M2 alongside the new `migrate` command. Resolved during unattended orchestration; full rationale in wip/unattended-decisions.md decisions 5 + 6. Signed-off-by: Will Madden <madden@prisma.io>
The function was added in f007302 but every CLI command builds its resolution context inline instead. Delete the unused function and its two now-orphaned imports (RefResolutionContext type, readRefs). TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
Replace `prisma-next migration apply [--ref <name>]` with the bare top-level verb `prisma-next migrate [--to <contract>]`. The --ref flag becomes --to; the <contract> argument routes through parseContractRef. - Add commands/migrate.ts (MigrateResult, createMigrateCommand) - Register migrate in cli.ts; remove migrationApplyCommand registration - Delete commands/migration-apply.ts - Rename runMigrationApply -> runMigrate in journey-test-helpers.ts - Update all 20 journey test call sites (--ref -> --to where applicable) - Update CLI package tests (tamper, invariants, json-shapes) - Update mongo integration tests - Update package.json exports and tsdown/vitest configs TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
When --to is provided, db update resolves the contract reference via parseContractRef, loads the matching end-contract.json from the migration graph, and uses it as the target contract instead of the auto-resolved emitted contract. When --to is omitted, behavior is unchanged. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
Replace all references to `migration apply` with `migrate` in the subsystem documentation. The command synopsis now shows `prisma-next migrate --to <contract>` and the narrative text uses the bare verb throughout. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
Fix two test regressions from the verb rename: - migration-invariants.test.ts: --ref -> --to for createMigrateCommand - help.snapshot.test.ts: update db update snapshot for new --to flag TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The subprocess CLI invocation in harness.ts still used the old `prisma-next migration apply` command. Update to `prisma-next migrate`. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
Fix 9 user-visible strings (F2) and ~10 internal comments/URLs (F3) that still told users to run the removed `prisma-next migration apply`. User-visible (F2): - migration-status.ts: 7 hint/summary/diagnostic strings now reference `prisma-next migrate` / `prisma-next migrate --to <ref>` - migration-plan.ts: 2 "Next:" hints now reference `prisma-next migrate` Internal (F3): - migration-status.ts, command-helpers.ts, migration-plan.ts, migrations.ts: comments updated from migration-apply → migrate - help.ts: URL map entry renamed from `migration apply` to `migrate` - migration-cli.ts, contract-space-seed-phase.ts: stale comments updated TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The previous shape of `executeMigrationShowCommand` called `buildContractSpaceAggregate` (which enforces a layout-integrity check that fires `PN-MIG-5001` when an extension is declared but its migrations directory has not been materialised) BEFORE `parseMigrationRef`. Any input — wrong-grammar OR a valid migration directory name — was therefore gated by the aggregate layout check. A user with a declared-but-unmigrated extension never reached the wrong-grammar diagnostic that AC6 promises. Reorder execution: resolve the app-space target through `parseMigrationRef` (or path-form / latest-leaf) first, then build the aggregate to enumerate extension spaces. The aggregate-loader still runs on the no-target path (so extension-space enumeration keeps its layout-integrity coverage), but a wrong-grammar input short-circuits to the resolver diagnostic the user asked for. Add a journey test (test/integration/test/cli-journeys/ migration-show-reachability.e2e.test.ts) that reproduces the canonical demo state (extensionPacks: [pgvector] with no migrations/pgvector/ dir) and asserts the resolver diagnostic reaches the user. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
…where F-2: per-migration `migration check <m>` used to run only the hash-recomputation (PN-001) and file-existence (PN-002) checks. The within-migration snapshot-consistency check (PN-005, comparing metadata.to against end-contract.json.storageHash) was implemented only on the graph-wide code path, so a corruption that the graph-wide check correctly catches reported `ok: true` in per-migration mode — a false negative on a documented integrity check. Lift the check into a shared `checkSnapshotConsistency` helper called from both branches. Same on-disk drift now produces the same failure regardless of how the user invoked check. F-8: the `where` field on check failures used three different shapes across PN codes — absolute path for PN-001 from the loader catch block (via MigrationToolsError.details.dir), short directory name for PN-001/PN-003/PN-005 from the per-package loops, and a labelled "ref \"name\"" for PN-004. Normalise to a cwd-relative path consistently: - PN-001 (HASH_MISMATCH): `migrations/<space>/<dir>/migration.json` (the hash being verified is stored there). - PN-002 (MANIFEST_INCOMPLETE): the specific missing file path, e.g. `migrations/<space>/<dir>/migration.json` or `ops.json`. - PN-003 (ORPHAN_MIGRATION): the migration directory. - PN-004 (DANGLING_REF): the ref file `migrations/<space>/refs/<name>.json`. - PN-005 (EDGE_MISMATCH): the migration directory (drift spans two files inside it). Add a per-migration adversarial test that pins the F-2 fix — parallels the graph-wide PN-005 test and asserts the per-migration branch reports the same code for the same on-disk corruption. The existing migration-check tests only assert `failures[].pnCode`, not `where`, so the F-8 normalisation is observable from --json output without breaking any existing assertion. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The root help output came up in QA as F-3: the top-level command listing read as `contract, db, migration, migrate, ref, init`, which puts `init` at the bottom even though it is the first verb a new user runs, and lets `migrate` land between the `migration` namespace and the `ref` namespace, breaking the subject-grouping rhythm. The spec opens with an intended-surface diagram that lists the surface in a specific reading order — verbs first (`init`, `migrate`), then subject namespaces (`contract`, `db`, `migration`, `ref`). That order is what introduces the CLI to a reader; the help output should match. Reorder by consolidating the `program.addCommand(...)` calls into a single block at the end of the registration section, in the spec's order. Each command's body still builds in its own paragraph; only the addCommand sequence moves. No behaviour change beyond the display order. Note on the orchestrator round-prompt: the round task lists target order as `db family, migration family, migrate, ref, then init`, which contradicts the spec's diagram (and the QA finding that flagged init-at-the-bottom as the problem). I matched the spec because both the QA runner's observation and the spec's own diagram agree on init-first; the round bullet appears to be a typo sketch. Surfaced in the return report. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
…tract help The QA round flagged `migrate --help`'s `--to` description as listing four of the five forms — hash, prefix, ref name, migration dir name — and missing `<dir>^` and the `./path` filesystem form. The same trimmed wording lived on five other `<contract>`-accepting sites: `db sign --contract`, `ref set` (positional), `migration plan --from`, `db update --to`, and `migration status --to`. `migration status --from` had no grammar mention at all. Reproduce the full grammar across every help string, matching the glossary's contract-reference table verbatim: "hash, prefix, ref name, migration dir name, <dir>^, or ./path". `migration status --from` now references the same grammar plus its purpose-specific behaviour (offline path computation when supplied). TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The domain doc said hash prefixes accept 8+ chars; the glossary and the implementation (HEX_PREFIX_PATTERN at packages/.../refs/types.ts) say 6+. The QA round flagged the drift as F-6. Implementation is canonical (changing it would surprise existing scripts that pass 6- or 7-char prefixes). Update the domain doc's contract-reference grammar table and the ambiguity-rule example to match the implementation. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The output-format dispatch in `executeMigrationGraphCommand`'s action handler checked `flags.json` before `options.dot`. `parseGlobalFlags` auto-enables `flags.json` when stdout is non-TTY (per CLI Style Guide § JSON Semantics), so a user running `prisma-next migration graph --dot | dot -Tsvg > graph.svg` piped JSON into GraphViz, which then errored. The bug shipped because no test exercised `--dot` in non-TTY mode. Reverse the precedence: explicit format flags (`--dot`) win over the auto-JSON default. Add a journey test that pins the precedence with both directions of assertion — `--dot` produces DOT, bare `migration graph` in the same non-TTY mode still produces JSON. Also extend the `runMigrationGraph` journey helper to accept the same `options` shape (with `isTTY`) other helpers already accept, so the test can opt into the non-TTY reproduction. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
….json The QA round flagged the original recipe (F-5): editing migration.json's `to` field invalidates the recomputed `migrationHash`, which makes the package loader throw PN-001 (HASH_MISMATCH) BEFORE the PN-005 within-migration snapshot- consistency check has a chance to fire. The recipe was always wrong from PN-005's perspective and the script even anticipated this in its own "Failure modes" list. Switch the recipe to mutate `end-contract.json`'s `storage.storageHash` instead. That keeps the manifest hash valid and drives the drift specifically between `metadata.to` and the recorded snapshot — exactly what PN-005 was designed to detect. Also extend step 4 (per-migration check) with a note that it verifies the F-2 fix in this round (per-migration mode used to be a false-negative on PN-005). Update the Restore step to checkout end-contract.json instead of migration.json. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
F-9 from the QA round: the pre-flight's "git status must show a clean tree" check was too strict given the orchestrator's working shape. Two items are typically uncommitted at handoff and confused the QA runner mid-script: - `M projects/migration-domain-model/plan.md` — the round's task list amendment. - `M wip/unattended-decisions.md` — the orchestrator's decision log. The runner judged "I'll proceed under the assumption these are intentional" and was correct, but the script gave no guidance. Document the two known items explicitly, instruct the runner to treat their presence as clean-equivalent, and call out that any OTHER uncommitted change is a finding worth surfacing before scenarios start. Offer `git stash push` as the strictly-clean alternative. Renumber the pre-flight steps (added one) and split tooling-version checks out from the git-status check for clarity. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The previous commit extended the `--to <contract>` description on `db update` to list all five contract-reference forms (F-4). The help.snapshot test pins the rendered help output, so the new wording flows through into a snapshot delta. Update the snapshot to match. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The M7 R3 fix moved the aggregate-loader call to after parseMigrationRef, which restored wrong-grammar diagnostic reachability. But valid migration references were still gated by the aggregate loader. A user with a declared-but-unmigrated extension hit PN-MIG-5001 even for a known-good migration directory name — the verb was still effectively unreachable for its primary purpose. Restructure migration-show into two paths: - Explicit target (positional argument): read appMigrationsDir directly, resolve through parseMigrationRef, render the single matched migration. No aggregate. No layout check. Mirrors the pattern used by migration list, migration graph, and migration check, which all read appMigrationsDir without ever building the aggregate. - No target: build the aggregate so we can enumerate every loaded extension space and render the latest migration per space. The layout-integrity check is appropriate at this entry point because the verb is asking the framework to report on every declared space. Functionally: migration show <dir> in canonical demo state now returns the migration details; the no-arg form still flags layout violations via the aggregate-loader path. Extend the journey test with a happy-path assertion against the same unmigrated-extensions fixture. The wrong-grammar assertion stays. Both pin distinct properties of the verb on the same fixture state. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
The QA round flagged two patterns in tests added during M7 R3:
- `AC6` in the migration-show-reachability JSDoc.
- `F-N regression` prefixes (F-1, F-2, F-7) in JSDoc and inline
comments across the three new tests.
Both pattern classes are durable-file-incompatible per the
workspace doc-maintenance rule: AC IDs and F-numbers come from the
project's spec / QA artefacts under `projects/migration-domain-
model/`, which is a transient directory that will be deleted under
TML-2553. Tests are durable files; references to transient IDs go
stale on deletion.
Rewrite the JSDoc on each test to state the property being pinned
in its own words ("wrong-grammar diagnostics on `migration show`
must reach the user even in unmigrated-extensions state", etc.).
Drop the `F-N regression` inline comments — the body already
explains the bug context the comment was prefixed with, no
information is lost.
The migration-show-reachability test's JSDoc gets the AC6 fix as
part of the broader rewrite that accompanies the new happy-path
assertion (already in the previous commit, `4fde15f75`).
TML-2546
Signed-off-by: Will Madden <madden@prisma.io>
Three leaks caught by the M7 R4 reviewer that the R3/R4 sweeps
missed:
- migration-show.ts:292 — "spec FR3" attribution (introduced by my
own R4 JSDoc rewrite). Rewritten to describe the constraint
itself ("contradicts what an offline read-only verb should
require") without naming a spec section.
- migration-show-reachability.e2e.test.ts:143 — same pattern, same
fix: replace "the spec FR3 offline-by-design framing" with a
property-statement that stands on its own.
- migration-show-reachability.e2e.test.ts:2 — JSDoc opener referred
to "documented as offline and read-only in the spec"; rephrased
to "an offline read-only verb" (the property without the spec
attribution).
- migration-graph-dot.e2e.test.ts:44 — "Reproduce the F-7 scenario"
reference that the R3 sweep missed. Rephrased to "Reproduce the
non-TTY DOT regression scenario" plus a concrete description of
what the regression looks like to a user (pipe-style invocation
produces JSON, pipe-receiver errors).
While reworking the F-7 reference, also dropped the stale
duplicate runMigrationGraph call that survived from R3's first
test iteration — it ran the same command with default isTTY=true
just before the real reproduction with isTTY=false. The duplicate
wasted time and the leftover comment was misleading.
Self-check gate (the rg pattern from .cursor/rules/doc-maintenance)
returns zero hits on all three files after the rewrites.
TML-2546
Signed-off-by: Will Madden <madden@prisma.io>
The F8 fix moved aggregate-loader enumeration into the no-target branch of `migration show`. That's the legitimate place for the PN-MIG-5001 layout-integrity check to fire: when the user asks for every loaded space's latest migration, missing extension-space directories are a real signal worth surfacing. But nothing pinned the property. A future simplification — removing the aggregate build, or downgrading the check from error to warn — could let the verb silently miss the unmigrated extension. Add a third assertion to migration-show-reachability against the same `setupUnmigratedExtensionsState` fixture: bare `prisma-next migration show --json` exits non-zero with `code: "PN-MIG-5001"` and a `why` that names the unmigrated extension (`pgvector`). The test file now pins three distinct properties of the verb in unmigrated-extensions state: 1. Wrong-grammar input → resolver diagnostic reaches the user. 2. Valid app-space target → migration details returned. 3. No-target → aggregate-loader layout-integrity check fires. Self-check gate (the rg pattern from the doc-maintenance rule) returns zero hits on the file after the addition. TML-2546 Signed-off-by: Will Madden <madden@prisma.io>
…5-18) Second QA pass after M7 R3-R5 folded in all 9 system findings + 5 reviewer-derivative findings from the first pass. Verdict: ✅ Pass-with-follow-ups (1 📝 Follow-up about pre-flight fixture residue). Every prior-run finding (F-1 through F-9) verified holding: - F-1: migration show now reachable for wrong-grammar AND valid-target inputs in canonical demo state. End-to-end behavior verified. - F-2: per-migration migration check <m> now detects PN-005 via the shared checkSnapshotConsistency helper. End-to-end verified. - F-3 through F-9: help reorder, help-text completeness across 6 commands, hash-prefix length docs aligned, --dot precedence fix, where field normalisation across 5 PN codes, script corruption recipe + pre-flight clarifications all confirmed live. Project is observably ready for the orchestrator's push + CI gate. Signed-off-by: Will Madden <madden@prisma.io>
The M7 plan grew several rounds beyond R1 in response to user direction and post-round signal: - R2: preserve the project's modeling work (domain.md + inspirations) in forward-compatible docs/design/ paths; not a wholesale framework adoption. - R3: fold all 9 QA-pass-1 findings (2⚠️ Highs + 7 📝 Follow-ups) into a single implementation round per the small-PR policy rather than ticketing them. - R4: close R3 residuals (F-1 happy-path slice, transient-ID leaks introduced/missed during R3's sweep). - R5: close R4 residuals (more transient-ID leaks introduced by R4's own rewrites) and pin the no-target layout-integrity check as a regression guard. Introduces a pre-commit self-check protocol. Captured each round's scope as it was dispatched so a future reader sees the actual execution narrative, not only the original plan. Signed-off-by: Will Madden <madden@prisma.io>
The reference resolvers used post-hoc non-null assertions (`matches[0]!`, `candidates[0]!`, `migMatches[0]!`) after length checks. Biome's noNonNullAssertion fires on these, and CI runs biome with --error-on-warnings. Switched to destructure-and-narrow so the property access is TypeScript-clean without an assertion: pull the first element out, then guard with `length === N && first !== undefined`. The undefined guard is logically redundant given the length check but satisfies the lint rule without suppressing it. No behavior change; 486 unit tests pass. Signed-off-by: Will Madden <madden@prisma.io>
The new migration-check command is exercised end-to-end through adversarial fixture journey tests covering all five PN-MIG-CHECK-* codes, but the CLI package's unit suite doesn't import it directly so the per-package coverage report sees 0% on migration-check.ts. Mirrors the existing M9-era warningOnly entries (TML-2521 family): 90-day expiry, points the recovery work at TML-2552 alongside the other residual internal renames. Signed-off-by: Will Madden <madden@prisma.io>
The field was introduced to forward-compat the canonicalization algorithm, but canonicalization-rule changes are always breaking — the new ruleset produces different bytes for the same logical contract, so every consumer must re-emit anyway. The version stamp gave us nothing actionable that re-emit-on-break does not already give us, and it imposed a confusing dual surface on the marker (a real hash plus a co-stored ruleset version). Drops the term from the migration domain model (both the durable `docs/design/10-domains/migration/README.md` and the project-local `domain.md` mirror), and rewrites ADR 010 to describe canonicalization-rule changes as breaking-by-design rather than versioned, removing the matching `prisma-next recanonicalize` tool the version stamp was meant to drive. Code-side retirement (contract type, SQL + Mongo marker, runner/verify paths, dependent ADRs 042/100/029/025/096) is tracked separately under TML-2559. Refs: TML-2546, TML-2559 Signed-off-by: Will Madden <madden@prisma.io>
The modelling work resolved on `migration plan --advance <ref>` as the canonical authoring path: producing the migration package and advancing the named ref are one act, committed in one PR (the "freeze + promise" verb). `ref set` is reserved as the rarely-used direct-write escape hatch. The restructure project shipped the rest of the modelled surface but did not implement `--advance` — `migration-plan.ts` exposes `--config`, `--name`, `--from` only. Adds a "Follow-up tasks" section to the project spec naming this gap explicitly, pointing at TML-2560 (the implementation ticket against `[PN] May: Migrations`) and recording the scope when implemented (flag, resolver wiring, ref-write integration, refusal semantics, journey-test coverage, glossary cross-reference) so the bridge between the modelling docs and the shipped CLI is auditable rather than implicit. Refs: TML-2546, TML-2560 Signed-off-by: Will Madden <madden@prisma.io>
Captures the workflows the migration verb taxonomy was designed around, grouped by user posture (authoring, operating, reading, adopting, recovering). Each journey names the persona, the question being asked, the verb sequence, and the e2e test that exercises it end-to-end. The journeys consolidate two streams of source material: the load-bearing journeys identified during the modelling discussion (bootstrap, dev inner loop, plan-and-promise, status landing, migrate-to-ref, CI gating, CD execution) and the journey-shaped e2e tests under `test/integration/test/cli-journeys/` (brownfield adoption, production adoption, rollback, divergence reconciliation). Pathological / single- feature regression scenarios (drift edge cases, resolver internals, single-verb integration probes) are deliberately excluded — they live in the test suite but are not load-bearing as user stories. Cross-link added from the domain README so the catalog is discoverable from the canonical entry point. Adoption-ergonomics concern (brownfield adoption is currently 5 verbs; target is 1–2) is flagged inline with a pointer to TML-2561 for the follow-up work. Refs: TML-2546, TML-2561 Signed-off-by: Will Madden <madden@prisma.io>
- ADR 208: update section heading --ref -> --to (consistent with body) - Migration System.md: fix broken fragment links to #contract-references-and-migration-references - migration/README.md: add language tag to unlabeled fenced code block - migration/README.md: resolve "migration" definition ambiguity — consistently means on-disk artifact - ref.ts: update help text from "contract hash" to "contract reference" - journey-tests/02f-merge-preview.md: fix success criteria --ref -> --to - prisma-next-quickstart/SKILL.md: fix "migration plan + apply" -> "migration plan + migrate" - prisma-next-migration-review/SKILL.md: fix CI snippet --ref -> --to - db-sign-contract-arg.e2e.test.ts: remove inaccurate error-path claim from docblock - .husky/pre-commit: pass --no-stash to work around symlink issue in worktree Signed-off-by: Will Madden <madden@prisma.io>
db-update: fail fast when --to ref resolves but no matching bundle exists, instead of silently applying the default emitted contract migration-check: return a CheckFailure when end-contract.json is unparseable (JSON.parse errors were previously swallowed) migration-graph: use null instead of EMPTY_CONTRACT_HASH when contract read fails, so consumers can distinguish "unknown" from "at root" migration-log: return a structured error when findPath returns null, rather than collapsing an unreachable marker to an empty applied list migration-plan: fail fast when --from resolves to a hash with no on-disk predecessor bundle, preventing fromContract from staying null for non-root hashes migration-status: clear allMarkers when --from offline override is active, so live DB markers cannot contaminate offline results; also guard activeRefName before calling summarizeRefDistance to prevent "ref undefined" summaries removed-verb-redirects.test.ts: replace __dirname with import.meta.url (ESM) Signed-off-by: Will Madden <madden@prisma.io>
…n docs - migration/README.md: remove non-existent commands (migration compile, migration preflight, contract show, contract diff) from command inventory and safety class tables - migration/README.md: add text language tag to diagram code blocks - migration/user-journeys.md: fix npm init -> pnpm init - migration/user-journeys.md: add bash language tag to all unlabeled command code blocks Signed-off-by: Will Madden <madden@prisma.io>
fdfa6fd to
a1469b3
Compare
Linked issue
Refs TML-2546.
Follow-ups filed against this PR:
TML-2551 (preflight sandbox),
TML-2552 (residual internal renames),
TML-2553 (delete project dir post-merge),
TML-2554 (CLI help snapshots),
TML-2556 (pre-commit doc-maintenance grep).
At a glance
The post-restructure CLI surface (copied from
projects/migration-domain-model/spec.md):
Every place a contract or migration is named, one resolver applies the
same grammar: hash (full or prefix), ref name, migration directory name,
<dir>^, or filesystem path.<contract>and<migration>aredistinct argument types; the resolver detects wrong-grammar passes and
gives Git-style suggestions.
Decision
This PR carries seven substantive pieces; they fall out of one coherent
re-reading of the migration domain, not seven independent surface
tweaks.
migrate --to <contract>. The verb that advances alive database along the migration graph is promoted to a top-level
verb.
prisma-next migration applyis removed; an unknown-commandredirect points operators at the new form.
refnamespace. Refs are contract-graph pointers, onthe same noun family as contracts.
prisma-next migration refisremoved. The
ref getinspect-one verb is dropped (covered byref listfiltered by name);ref set/list/deletesurvive.migration statussplit into five purpose-specific verbs:status(path / pending),log(execution history),list(flaton-disk enumeration),
graph(topology),show(unchanged). Thehelp system cross-references the family via a new
See alsosection, and unknown-flag suggestions on
statusroute operators atthe verb that now owns each flag's behavior.
db signaccepts a contract argument — positionaldb sign [<contract>]and explicit--contract <contract>. Noargument defaults to the current
contract.json(unchanged).flag —
migrate --to,db update --to,db sign --contract,migration plan --from,migration status --to/--from,ref set'ssecond argument, positional
<m>onmigration show/migration check. Same resolver, same diagnostics. A parallel<migration>grammar covers verbs that take a migration argument.migration check [<m>]— net-new artifact / graph integrityverb. Read-only, offline. Five PN codes
(
PN-MIG-CHECK-001..005); exit codes per the CLI Style Guide(
0 OK,2 PRECONDITION,4 INTEGRITY_FAILED).work lands as a new
Migration & Database Lifecyclesection indocs/glossary.md, the subsystem doc is rewritten around the newverb taxonomy, and the domain-modeling artefacts (domain doc + the
two inspiration writeups) are ported into a
docs/design/scaffoldthat is forward-compatible with the docs-framework skill but not a
wholesale adoption of it.
migration preflight <m>(a separate sandbox-execution feature) isdeliberately deferred — it needs its own design and is tracked in
TML-2551. The
vocabulary still includes it; the audit still flags it as the remaining
gap after this PR.
Reviewer notes
Surface that benefits from being said out loud before review:
per milestone; the operator chose a single PR for the whole
restructure because PR overhead is real and high. Each commit is
scoped to one milestone-round and one logical concern, so the PR
reviews bit by bit even though it's wide.
projects/migration-domain-model/is retained on disk. Thedomain doc, spec, plan, CLI audit, manual QA script, and both QA
reports stay through review + QA so reviewers can trace decisions to
the modeling work that produced them. Deletion is filed as
TML-2553 and
blocked on merge. The durable content (domain model + inspirations)
is already mirrored into
docs/design/anddocs/glossary.md, sodeletion does not lose information.
code-review.mdandwip/unattended-decisions.mdare gitignoredby repo convention and are not in this PR; they exist locally for
the orchestrator's bookkeeping.
pgvector-layoutaggregate-loader check.migration showwasunreachable in the canonical demo state because the aggregate loader
ran a layout-integrity check before resolving the migration
reference. The fix splits the loader's behavior: explicit-target
invocations skip aggregate enumeration; no-target invocations still
fire the check (regression-tested). The deeper architectural fix
belongs elsewhere; this PR's behavior is narrowly correct.
transient-project-artefact leaks (AC IDs, F-numbers, "per spec"
attributions) in code comments / test JSDoc. The workspace rule
defines a grep pattern that catches them; this PR demonstrates the
rule by example. A pre-commit hook is filed as
TML-2556 so the
next PR doesn't relitigate.
Postgres connection drops during PG-heavy suites. Each round
classified them as pre-existing infrastructure noise; they reproduce
on
main. Not introduced by this PR.How it fits together
The work moves substrate-first, then proceeds along the verb tree from
broadest re-shaping to local fixes.
(
parseContractRef,parseMigrationRef) underpackages/1-framework/3-tooling/migration/src/refs/recognise everyform of the unified grammar and emit a typed
RefResolutionErrorfor wrong-grammar passes. Every contract-namingflag in the existing CLI is rerouted through these parsers before
any verb is renamed; this guarantees the new resolver is the only
reference-resolution path by the time the verb work starts.
migrate --to— Promote the live-DB advance verb,delete
migration apply, add a removed-verb redirect entry incli.ts. The redirect carriesfix:text namingmigrate --toverbatim, so operators who muscle-memory the old form land softly.
ref— Same pattern: promote, delete the old verb,drop
ref get, extend the removed-verb redirect table.migration status— Five sibling commands inpackages/1-framework/3-tooling/cli/src/commands/migration-*.ts,each answering one question. The help formatter learns a
See also:section via a new
setCommandSeeAlso(command, refs)helper thatparallels the existing
setCommandExamplesregistration; everymember of the family registers cross-references to the others.
db sign [<contract>]— Two argument shapes (positional and--contract) wired throughparseContractRef. A parameterizedjourney test asserts all four invocation shapes produce identical
marker rows.
migration check— New command with five PN codes. Each PN codehas an adversarial fixture test that mutates one byte of one file
and asserts the right code fires. Per-migration and graph-wide
branches share one snapshot-consistency helper so PN-005 fires from
both paths (this was a real bug surfaced by QA, fixed mid-round).
vocabulary into
docs/glossary.md's newMigration & Database Lifecyclesection, rewritedocs/architecture docs/subsystems/7. Migration System.mdaroundthe new taxonomy, update
docs/CLI Style Guide.mdwith theredirect convention, and port the domain doc + two inspiration
writeups into
docs/design/(with frame READMEs) so the durablerecord outlives the transient
projects/directory.Behavior changes & evidence
prisma-next migrate --to <contract>advances the live DB alongthe graph. Replaces
migration apply. Removed verb produces anunknown-command error whose
fix:line names the new form.packages/1-framework/3-tooling/cli/src/commands/migrate.ts,
packages/1-framework/3-tooling/cli/src/cli.ts
test/integration/test/cli-journeys/migration-apply-edge-cases.e2e.test.ts
prisma-next ref {set,list,delete}is top-level.ref getisdropped;
ref list <name>covers it.packages/1-framework/3-tooling/cli/src/commands/ref.ts
test/integration/test/cli-journeys/ref-routing.e2e.test.ts
migration statusbecomes five verbs. Each answers exactly onequestion.
See also:cross-references render in--help. Unknownflags on
status(--graph,--all,--ref) emit afix:linenaming the verb that owns the behavior.
packages/1-framework/3-tooling/cli/src/commands/migration-status.ts,
migration-log.ts,
migration-list.ts,
migration-graph.ts,
utils/formatters/help.ts
test/integration/test/cli-journeys/migration-status-diagnostics.e2e.test.ts,
migration-graph-dot.e2e.test.ts,
migration-show-reachability.e2e.test.ts
db signaccepts a contract argument.db sign [<contract>]anddb sign --contract <contract>both run through the unifiedresolver. No-argument form is unchanged.
packages/1-framework/3-tooling/cli/src/commands/db-sign.ts
test/integration/test/cli-journeys/db-sign-contract-arg.e2e.test.ts
One reference grammar. Hash / ref name / migration dir /
<dir>^/ filesystem path resolve identically across every contract-naming
flag. Wrong-grammar passes get Git-style suggestions naming the
correct verb-grammar pair.
packages/1-framework/3-tooling/migration/src/refs/contract-ref.ts,
migration-ref.ts,
packages/1-framework/3-tooling/cli/src/utils/cli-errors.ts
packages/1-framework/3-tooling/migration/test/refs/contract-ref.test.ts,
migration-ref.test.ts
migration check [<m>]validates artifact / graph integrity.Five PN codes; exit codes
0 OK,2 PRECONDITION,4 INTEGRITY_FAILED. Per-migration and graph-wide branches share onesnapshot-consistency helper.
packages/1-framework/3-tooling/cli/src/commands/migration-check.ts,
migration-check/exit-codes.ts
test/integration/test/cli-journeys/migration-check.e2e.test.ts
Glossary + subsystem doc + CLI style guide track the new
vocabulary. New
Migration & Database Lifecyclesection in theglossary covers refs / ledger / drift / reference grammars / the
five
migration checkPN codes. The subsystem doc is rewrittenaround the new verb taxonomy and the Git mental model. The style
guide picks up the removed-verb redirect convention.
docs/glossary.md,
docs/architecture docs/subsystems/7. Migration System.md,
docs/CLI Style Guide.md
Domain modeling work ported into
docs/design/. The domain docbecomes
docs/design/10-domains/migration/README.md. Inspirations(Atlas, Active Record, established conventions) land under
docs/design/04-inspirations/migrations/. Frame READMEs explainthe partial adoption of the docs-framework skill.
docs/design/README.md,
docs/design/10-domains/migration/README.md,
docs/design/04-inspirations/migrations/README.md
Compatibility / migration / risk
No prior CLI version is in users' hands; no compatibility shim. The
removed verbs (
migration apply,migration ref, and the--graph/--all/--refflags onmigration status) emitunknown-command / unknown-flag errors whose
fix:lines name the newform — operators who muscle-memory the old shape land softly.
Internal call-sites that called the old commands have been swept;
documentation references have been swept. Two follow-up scopes were
opened on this branch:
TML-2552 covers
residual internal renames (
MigrationAppliedevents,control-api/operations/→commands/, etc.) that are out of scopehere per the spec's non-goals.
Verification
Manual QA was the final gate. Final verdict
✅ Pass-with-follow-ups; report at
projects/migration-domain-model/manual-qa-reports/2026-05-18-cursor-claude-reviewer-resumed-rerun.md.
All 9 first-pass findings (F-1 .. F-9) verified resolved end-to-end on
the live CLI; one new follow-up (F-r1) about fixture-state hygiene,
no test impact.
Programmatic suites run on this branch:
pnpm typecheck— greenpnpm lint— greenpnpm lint:deps— greenpnpm test:packages— greenpnpm test:integration— green (with pre-existing PG flake noise)pnpm test:e2e(journey suite) — green (with pre-existing PG flakenoise; flakes reproduce on
main)Follow-ups
migration preflight: sandbox execution + cross-migrationconsistency. The remaining vocab verb; deferred per spec non-goals.
residual internal renames (
MigrationAppliedevents,control-api/operations/→commands/, AC-ID leak sweep in thetest tree).
delete
projects/migration-domain-model/after merge.help-text snapshots for the 11+ commands currently uncovered.
workspace pre-commit hook that runs the doc-maintenance grep
pattern on staged files.
Alternatives considered
prisma migrate devstyle verb. Rejected. "Dev" is overloadedand conflates schema iteration with graph advancement.
db updateis the iteration verb;
migrate --to <contract>is the deliberateadvance verb. Different verbs because they're different operations,
not different modes of one verb.
dev/deploysplit onmigrate. Rejected. A singleuniversal
migratewith the contract-reference grammar is enough;the "deploy" case is
migrate --to <ref>where the ref points at therelease contract. No need to split the verb itself.
compileverb formigration.ts→ops.json. Rejected. Theauthoring loop is
migration plan→ user editsmigration.ts→next
migrateinvocation re-derivesops.jsonas a side-effect.Exposing a
compileverb would surface an internal step thatdoesn't earn its place in the noun-verb taxonomy.
operator. PR overhead is real and high; the milestones are coherent
parts of one re-shaping. The 64 commits review bit by bit.
framework is whole-product; adopting it as a side-effect of this
PR would scope-creep into restructuring everything. Instead, the
migration domain seeds a forward-compatible
docs/design/scaffold that the framework can grow into when it'snext someone's focused project.
projects/migration-domain-model/at close-out.Rejected for this PR per operator direction — reviewers need the
modeling artefacts on disk to trace decisions. Deletion is
TML-2553.
Skill update
n/a — internal only.The CLI vocabulary work feeds into a futureuser-facing onboarding skill (out of scope here);
packages/0-shared/skills/was swept for legacy verb references (inthe
docs(skills,readme): sweep legacy migration verbscommit on thisbranch) but no new skill ships in this PR.
Checklist
git commit -s) per theDCO. The
DCO status check will block merge if any commit is missing a
Signed-off-by:trailer.scoped to one logical concern (the migration-CLI restructure).
TML-NNNN: <sentence-case title>form(Linear ticket prefix + concise title naming the concrete
deliverable).
Summary by CodeRabbit
New Features
Documentation
Tests