Skip to content

Commit ad67ec6

Browse files
committed
Merge branch 'main' of https://github.com/prisma/prisma-next into feat-temp-tables
2 parents 4b189fa + 9ccebe0 commit ad67ec6

1,715 files changed

Lines changed: 120461 additions & 44381 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/rules/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Rules below are listed by bare filename; the canonical file is `.agents/rules/<n
3939
- `schema-driven-architecture.mdc` — Read the architecture overview before writing code
4040
- `doc-maintenance.mdc` — Keep docs/READMEs/rules up‑to‑date
4141
- `no-direct-lockfile-edits.mdc` — Never edit `pnpm-lock.yaml` manually; use `pnpm install`
42+
- `workspace-package-not-found-run-pnpm-install.mdc` — A missing `@prisma-next/*` module is a build/install-state issue, not a code bug: verify with `require.resolve` (pnpm links per-consumer, NOT at repo root — a root check lies), then `pnpm build` (stale dist) / `pnpm install` (new dep)
4243
- `omit-should-in-tests.mdc` — Test descriptions omit "should"
4344
- `no-transient-project-ids-in-code.mdc` — No transient project/milestone/task IDs in code, comments, ADRs, or tests
4445
- `optimize-for-human-time-on-prs.mdc` — Optimize for reviewer time; default to fewer, larger PRs
@@ -48,6 +49,7 @@ Rules below are listed by bare filename; the canonical file is `.agents/rules/<n
4849
- `avoid-cleavage-in-prose.mdc` — Don't use "cleavage" as a metaphor in prose; prefer split/boundary/distinction
4950
- `git-staging.mdc` — Git commit best practices: stage files explicitly, avoid `git add -A`, sign off
5051
- `running-tests.mdc` — How to run tests (and other slow verification commands): save output to a file once, read the file; don't re-run to grep different lines
52+
- `fix-the-class-not-the-instance.mdc` — A review comment names a class of defect; sweep the whole diff for the class, fix every instance in one round
5153

5254
## Testing
5355
- `test-import-patterns.mdc` — Test import patterns (source files, relative paths, don't export for tests)
@@ -76,6 +78,7 @@ Rules below are listed by bare filename; the canonical file is `.agents/rules/<n
7678

7779
## Imports & Layering
7880
- `import-validation.mdc` — Layering rules and exceptions
81+
- `no-family-vocabulary-in-framework.mdc` — No family/target vocabulary in packages/1-framework; enforced by lint:framework-vocabulary
7982
- `no-inline-imports.mdc` — Prohibit inline type imports in source files
8083
- `shared-plane-packages.mdc` — Pattern for creating shared plane packages
8184
- `multi-plane-packages.mdc` — Packages that span multiple planes (shared, migration, runtime)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
description: A review comment names a class of defect, not a point-fix. Sweep the whole diff for the class before replying; fix every instance in one round.
3+
alwaysApply: true
4+
---
5+
6+
# Fix the class, not the instance
7+
8+
When a reviewer flags a defect, the flagged line is an *example*, not the scope. Treating it as a point-fix makes the reviewer re-find the same defect in the next round at review cost — the most expensive possible linter.
9+
10+
## Required response to any review comment
11+
12+
1. **Name the class.** State the general rule the instance violates ("SQL vocabulary on a framework type", "strategy encoded as a string enum", "logic in a shared-types module").
13+
2. **Sweep the entire PR diff for the class** before replying — grep plus reading, not just the flagged file. Include surface the PR *added to* pre-existing types, not only new types.
14+
3. **Fix every instance in one round.** If an instance is genuinely out of scope (pre-existing, not touched by this PR), say so explicitly with evidence and a tracking ticket — and remember grandfathering never covers surface this PR authored.
15+
4. **The reply states the sweep**: what class, what was searched, what was found and fixed, what was excluded and why.
16+
17+
## Don't
18+
19+
- Don't fix the flagged line and re-ship — the next round finding the same class elsewhere in the diff is a process failure, not a new finding.
20+
- Don't treat design as settled because a doc or an earlier round blessed it. Design is never settled; a reviewer comment that invalidates a design invalidates every consequence of it, and the sweep must chase those consequences.
21+
- Don't have a reviewer subagent inherit the author's framing. Review-pass briefs state the class-sweep duty and the relevant layer/vocabulary audits explicitly (for framework-touching diffs: every added line under `packages/1-framework` justified against the family-blindness test).

.agents/rules/never-hand-edit-contract-fixtures.mdc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ pnpm fixtures:check # re-emit + git diff --exit-code; fails if stale
1515

1616
`fixtures:emit` knows which packages contribute fixtures: examples, apps, `sql-builder`, `sql-orm-client`, extension `build:contract-space`, extension migration regen (`migrations:regen` / `scripts/regen-extension-migrations.mjs`), and example-app migration regen (`migrations:regen:examples` / `scripts/regen-example-migrations.mjs`). The example-app migration regen covers `{start,end}-contract.*` snapshots in `examples/*/migrations/**`. Don't second-guess it by emitting only one package.
1717

18+
**`fixtures:check` gates contract *emission*, not planner *operations*.** Its diff glob is contract files only (`contract.*`, `expected.contract.json`, `{start,end}-contract.*`) — `ops.json` is excluded, and example `migration.ts` ops are static (regen re-serializes them, never calls `plan()`). So a green `fixtures:check` does **not** prove `MigrationPlanner.plan()` still emits the same ops. Prove planner-op parity with the planner suites, the `migration plan` e2e tests, and a golden diff of real `plan()` output vs the committed example ops. Full mechanism: [`docs/onboarding/fixtures-emit-and-check.md`](../../docs/onboarding/fixtures-emit-and-check.md).
19+
1820
## What's forbidden
1921

2022
For any `contract.json`, `contract.d.ts`, `expected.contract.json`, or migration `{start,end}-contract.{json,d.ts}`:
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
description: The framework domain (packages/1-framework) carries no family- or target-specific vocabulary — types, fields, hooks, or strategy values. Enforced by lint:framework-vocabulary.
3+
globs: ["packages/1-framework/**"]
4+
alwaysApply: false
5+
---
6+
7+
# No family vocabulary in the framework domain
8+
9+
`packages/1-framework` is consumed by every family (SQL, Mongo) and every target. A concept may enter it only if it is genuinely family-blind.
10+
11+
**The test for every new framework export, field, hook, or member:** *would Mongo populate or consume this meaningfully?* If not, it belongs in the family layer (e.g. `@prisma-next/sql-contract`), behind a structural interface + type predicate at the boundary.
12+
13+
## Do
14+
15+
- Keep framework mechanisms family-blind: registries, opaque payloads (`object | undefined` narrowed by the consuming family), merge/collision plumbing.
16+
- Put family vocabulary (`nativeType`, CHECK constraints, schema qualification, dialect names) in the owning family layer; targets implement family interfaces structurally.
17+
- Express strategies as **codec-owned hooks/behavior** on the strategy owner's descriptor — never as string-enum fields threaded through shared types (see `storage-type-hooks.mdc`).
18+
- Run `pnpm lint:framework-vocabulary` — a committed high-water-mark threshold over a forbidden-term list (`scripts/lint-framework-vocabulary.config.json`); the count may only shrink, and the recorded threshold must be lowered whenever it does.
19+
20+
## Don't
21+
22+
- Don't add a family term to a framework type because a sibling already has one — pre-existing surface is grandfathered debt (tracked, e.g. TML-2966), never precedent for new surface.
23+
- Don't dress family concepts as generic. The tells, each seen in practice: a `never`-typed parameter bridge to make a family callback assignable; a shape "declared here (not imported from the family) so the surface stays family-agnostic"; a `'strategy-a' | 'strategy-b'` union naming family mechanisms; a doc comment that needs a family example to explain the member.
24+
- Don't argue by analogy to an existing framework member without checking the analogy's ground: `renderValueLiteral` is framework because Mongo renders value literals; a member only SQL renders is not.

.agents/rules/no-transient-project-ids-in-code.mdc

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,26 @@ alwaysApply: true
44
---
55
# No transient project planning IDs in code
66

7-
Source code, comments, test names, and identifier strings must **never** reference transient project planning artefacts. Plans and specs are scratch documents that get deleted at project close-out; encoding their identifiers into the code makes the code lie about itself the moment the plan is rewritten or removed.
7+
Source code, comments, test names, identifier strings, and hash fixtures must **never** reference transient project planning artefacts. Plans/specs are scratch documents deleted at close-out; encoding their IDs makes the code lie the moment the plan is rewritten or removed.
88

9-
## What counts as a transient ID
9+
**Transient (forbidden in code)** — anything under `projects/<x>/` or in a plan/spec/review doc:
1010

11-
If it lives under `projects/<project>/` or in a project plan / spec / review document, it is transient. Specifically forbidden in code:
11+
- Task IDs (`T1.1`, `D7`, `M3.2`), test-case IDs (`TC-1`, `TC18`), AC/FR/NFR IDs (`AC1`, `FR2`, `NFR5`), phase/round/checkpoint IDs (`P3 R2`, `CKPT-2`, `M2 review`)
12+
- Prose attributions to the plan ("out of scope per the spec", "sub-spec § 4", "deferred per project plan")
13+
- `projects/<x>/...` paths anywhere in source (incl. JSDoc `@link`s and string literals)
14+
- Hash fixtures named after IDs (`'sha256:tc12-ext-contract'`)
1215

13-
- **Task IDs**: `T1.1`, `T2.4`, `T3.5`, `T4.1`, `T5.2`, `D7`, `M3.2`
14-
- **Test-case IDs**: `TC-1`, `TC-18`, `TC18`
15-
- **Acceptance-criterion / functional-requirement / non-functional-requirement IDs**: `AC1`, `AC11`, `AM12`, `AC-13`, `FR2`, `NFR5`
16-
- **Phase / round / checkpoint IDs**: `P3 R2`, `R4 design choice`, `CKPT-2`, `M2 review`, `M5 closeout`
17-
- **Prose attributions to the plan**: "out of scope per the spec", "sub-spec § 4", "sub-spec OQ3", "deferred per project plan", "post-M2 follow-up"
18-
- **`projects/<x>/...` paths anywhere in source files** (including JSDoc `@link`s and string literals)
19-
- **Hash fixtures named after IDs**: `'sha256:tc12-ext-contract'`, `'sha256:ac6-fixture'`
20-
21-
## What is allowed
22-
23-
Stable references that survive close-out are fine:
24-
25-
- **Linear ticket IDs**: `TML-2408`, `TML-2506` (these don't disappear)
26-
- **ADR numbers**: `ADR 211`, `ADR 212`
27-
- **PR numbers**: `PR #494`
28-
- **Permanent docs paths**: `docs/architecture docs/...`, `docs/onboarding/...`
29-
- **Source paths inside the repo's durable layout**: `packages/...`, `test/...`, `examples/...`
30-
31-
## Why
32-
33-
Transient IDs in code:
34-
35-
- **Decay silently.** When the plan is renumbered, regenerated, or deleted at close-out, the comment becomes a dangling reference. Reviewers can't verify the claim because the artefact is gone.
36-
- **Lose the "why".** "Refresh TC-8 alongside this wiring" tells you nothing six months later. "Per-space verify projects the schema to the space's slice, so the failure cause shifts" tells you everything, regardless of whether TC-8 still exists.
37-
- **Leak orchestration mechanics into the codebase.** The plan's structure (phases, rounds, checkpoints) is a scaffolding artefact for the maker, not a property of the system. The system's documentation should describe the system.
38-
- **Are easy to ban, hard to retrofit.** Catching them at write time costs nothing; scrubbing them after merge costs much more (and reviewers tend to wave them through).
16+
**Allowed (durable):** Linear ticket IDs (`TML-2408`), ADR numbers (`ADR 211`), PR numbers (`PR #494`), permanent doc paths (`docs/...`), durable source paths (`packages/...`, `test/...`, `examples/...`).
3917

4018
## How to comply
4119

42-
When a comment, test name, or fixture *needs* to explain something the plan currently captures:
20+
Describe the constraint or behaviour itself, not its plan row. Say "the runner skips ops with already-satisfied postchecks", not "see T3.4's postcheck-skip rule". Test names pin the property (`it('runs both spaces in caller order')`), not the coverage-table row. JSDoc cross-refs point at durable artefacts, never into `projects/`. Name fixtures/constants after their role (`'sha256:mongo-ext-contract'`), not the introducing test-case ID.
4321

44-
1. **Describe the constraint or behaviour itself.** What does this code make true? Why is the alternative wrong? Write the answer.
45-
2. **Don't attribute the answer to the plan.** Say "the runner skips ops with already-satisfied postchecks", not "see T3.4's postcheck-skip rule".
46-
3. **For test names**: name the property the test pins, not the row in a coverage table. `it('runs both spaces in caller order')` — not `it('runs both spaces in caller order (TC-7)')`.
47-
4. **For JSDoc**: if you need a cross-reference, link to a durable artefact (`docs/architecture docs/...`, ADR, sibling source file). Never link into `projects/`.
48-
5. **For hash fixtures and constants**: name them after the role they play (`'sha256:mongo-ext-contract'`, `EXT_FIXTURE_HASH`), not the test-case ID that introduced them.
49-
50-
## Quick check before committing
51-
52-
Before staging code, scan your `+` diff for these patterns. The check takes seconds:
22+
Before committing, scan your `+` diff for token-shaped IDs:
5323

5424
```bash
55-
git diff --cached -- '*.ts' '*.tsx' '*.js' '*.mjs' \
56-
| grep -E '^\+' \
57-
| grep -oE '\b(T[0-9]+\.[0-9]+|TC-?[0-9]+|AC-?[0-9]+|FR[0-9]+|NFR[0-9]+|CKPT-[0-9]+|AM[0-9]+|D[0-9]+|M[0-9]+\.[0-9]+|P[0-9]+ R[0-9]+|M[0-9]+ review)\b' \
58-
| sort -u
25+
git diff --cached -- '*.ts' '*.tsx' '*.js' '*.mjs' | grep -E '^\+' \
26+
| grep -oE '\b(T[0-9]+\.[0-9]+|TC-?[0-9]+|AC-?[0-9]+|FR[0-9]+|NFR[0-9]+|CKPT-[0-9]+|M[0-9]+\.[0-9]+|P[0-9]+ R[0-9]+)\b' | sort -u
5927
```
6028

61-
Output should be empty. If it isn't, rewrite the comment / test name to describe the property in its own words and try again.
62-
63-
Note: the regex catches token-shaped IDs only. Freeform prose attributions to the plan ("per spec", "sub-spec § 4", "sub-spec OQ3", "deferred per project plan", etc.) are equally banned but require a manual scan — no token regex can catch them reliably.
64-
65-
## Companion rule
66-
67-
This rule is a focused companion to the project-workflow guidance in `doc-maintenance.mdc` ("Source-code comments must not reference transient project artefacts"). That rule covers the broader "transient artefact" surface (links from durable docs into `projects/`, prose attributions, etc.); this rule narrows the focus to the specific failure mode of leaving plan IDs inside source code.
29+
Output should be empty. Freeform prose attributions ("per spec", "deferred per project plan") aren't token-catchable — scan manually. Companion to `doc-maintenance.mdc`, which covers the broader transient-artefact surface; this rule narrows to plan IDs left in source.

0 commit comments

Comments
 (0)