docs: land retro learnings on validation gates and the upgrade-coverage gate - #30098
docs: land retro learnings on validation gates and the upgrade-coverage gate#30098StevenMcClankerton wants to merge 1 commit into
Conversation
…ge gate Two DoD gate notes: - Build before typechecking after a rebase/merge of origin/main. A stale or missing dist/ surfaces as a TS2307 naming a workspace subpath, which reads like a broken import but is build state. - Do not narrow a per-package test gate by path. A .test-d.ts whose assertions sit at module scope with no it()/test() wrapper red-fails with "No test suite found in file", and only an unnarrowed pnpm --filter <pkg> test observes it. Also corrects the record-upgrade-instructions skill, which described check:upgrade-coverage as only asserting that the transition directory exists. TML-2764 hardened the gate four days after that paragraph was written: the per-pr-declaration rule requires this PR own diff to touch instructions.md, so an existing file with covering entries fails, while touching it with changes: [] passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe dispatch DoD now requires builds before typechecking after base changes and complete filtered package tests when test files are added. Coverage guidance now defines mechanical checks for ChangesDispatch and coverage gate guidance
Estimated code review effort: 1 (Trivial) | ~5 minutes Merge Risk: ⚪ Minimal · up to This documentation-only change has no actionable merge-blocking risk remaining and is merge-ready after normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes the aggregate-pagination project and removes its working artifacts. Documentation-only — no source, no tests, no behaviour. ##⚠️ Merge order **This must merge after prisma#30098.** That PR lands the project's retro learnings into `drive/calibration/dod.md` and the upgrade-instructions skill. This project produced no long-lived documentation to migrate — the one guide it wrote was deleted on review — so the learnings are its only durable output. Merging this first deletes them. ## What the project delivered `.aggregate()` silently ignored `take` / `skip` / `cursor` / `distinct` / `distinctOn`, reducing over every matching row and returning a confident, wrong number with no signal. `groupBy()` had the same defect for everything chained before it. Both are fixed, with **clause position deciding meaning**: before a terminal, clauses shape the rows it reduces; after `groupBy()`, they page the groups. - prisma#30067 — root `aggregate()` honours the whole chain - prisma#30092 — `groupBy()` carries the chain before it; `GroupedCollection` gained `take` / `skip` / `orderBy` to page groups, with post-group pagination requiring a prior `orderBy` at the type level ## Definition of Done All items met, with one closed as deliberately refused: - Root `aggregate()` honours `take`/`skip`/`cursor` including bare `skip`, and `distinct()`/`distinctOn()` ✅ - Pre-group clauses scope rows, post-group clauses page groups, both verified with `having()` present ✅ - Post-group pagination gated on a prior `orderBy` in the type state ✅ - CI-enforced guard that an unpaginated aggregate's compiled AST is unchanged — the baseline snapshot is byte-identical across every commit of both slices ✅ - Integration tests assert values, not plan shape, on PGlite **and** SQLite for each chain position ✅ - `test/aggregate-pagination.test.ts` free of `it.fails` ✅ - No new ORM error subcode ✅ - Position rule documented where a user meets it — **closed as refused.** Both halves were rejected on operator review: TSDoc as restating the signatures, and a reference guide as unwarranted for what is a bug fix. The changelog entries in `v8.0.0-rc.5.md` carry the user-facing notice. ## Spun out, not dropped prisma#30099 fixes enum `ORDER BY` / `DISTINCT ON` losing declaration order behind any derived table. Manual QA found it through the grouped path, but it is **pre-existing and wider** — `.distinct().orderBy(enumCol)` has had it since `wrapWithRowNumberDedup` first aliased a derived table back to its base name. It ships separately, before rc.5 is cut, so no released version exposes the new route unfixed. ## Notes Two findings were deliberately not ticketed, per standing direction on QA follow-ups: an empty TSDoc hover at the `never`-narrowing error site (`cursor()` behaves identically, so it is a house-level property, not a slice regression), and the demo's namespaced contract requiring `db.orm.<ns>.<Model>` where flat-namespace examples use `db.orm.<Model>`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Steven McClankerton <tatarintsev@prisma.io> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Lands the durable output of a completed project's final retro. Docs only — no source, no CI wiring.
Every claim below was re-verified against this repo rather than carried over from the retro write-up; two of them did not survive that check and are corrected here.
What landed
drive/calibration/dod.md— two gate notes.Build before typechecking after a base change (under Always-run). A rebase or merge of
origin/maincan leave a producing package'sdist/stale or missing;pnpm typecheckthen fails with aTS2307naming a workspace subpath, which reads like a broken import but is build state. The note points at the existing always-apply ruleworkspace-package-not-found-run-pnpm-install.mdc, which already carries the diagnosis — the gap was that the DoD's typecheck gate never mentioned it, and the "syncorigin/mainbefore final validation" slice item says to re-run the always-run gates without saying to build first.Don't narrow the per-package test gate by path (extending the existing "Per-package test invocation" note).
pnpm --filter <pkg> test <path>selects only matching files, so a defect in a file the path misses stays invisible while every run is narrowed.skills-contrib/record-upgrade-instructions/SKILL.md— one paragraph corrected.The "PR commit shape" section claimed
check:upgrade-coverage"only asserts that the in-flight transition directory exists" and that a PR "can have a real substrate diff, contribute no entry, and still pass the gate green." The code no longer works that way.scripts/check-upgrade-coverage.mjshas aper-pr-declarationrule that requires this PR's own diff to touch<transition>/instructions.mdand that its frontmatter carry a parseablechanges:array.The drift is datable: the paragraph landed in
49a6d6fa98on 2026-06-01;230f4406c3(TML-2764, "harden check:upgrade-coverage to verify per-PR entry correspondence") hardened the gate on 2026-06-05 without updating the prose.The rewritten paragraph states what the gate actually checks — mechanical, not semantic, in both directions: an instructions file that already exists with covering entries still fails the gate unless re-touched, while touching it with
changes: []passes green. The reviewer responsibility the paragraph existed to establish is preserved, now resting on the second gap rather than the one that no longer exists.Verified and rejected
Two claims from the retro did not survive checking.
"Per-package
--filtertest gating cannot observe a suite-less test file" — false. This was the headline framing of the retro item, and it is also asserted in the fix commit3bc6c5e6be("Per-package gating (pnpm --filter <pkg> test) does not reproduce it; root vitest does"). I reproduced it with a minimal probe: a.test-d.tscarrying module-scopeexpectTypeOfassertions and noit()/test()wrapper, dropped intopackages/3-extensions/sql-orm-client/test/.pnpm --filter @internal/sql-orm-client test(unnarrowed) → exit 1,Test Files 1 failed | 70 passed,Error: No test suite found in file …pnpm --filter @internal/sql-orm-client test zzprobe-withsuite(narrowed past it) → exit 0, greenThe
--filtergate observes it fine. What hides it is path narrowing — the same vitest path-filter mechanism the existing DoD note already warns about for being too broad at workspace level, here being too narrow. The landed note says that, not the original claim. (Probe files were removed; nothing from the experiment is in this diff.)"There are two upgrade skills and the gate reads
skills/prisma-8-extension-upgrade/" — true but already documented, and misleadingly one-sided. The gate reads both, keyed by substrate:COVERAGE_SUBSTRATESroutesexamples/→skills/prisma-next-upgrade/andpackages/3-extensions/→skills/prisma-8-extension-upgrade/. The skill's own "Detection signals & routing" table already states this correctly. The project only ever saw the second because its diff was inpackages/3-extensions/. Nothing to land — the confusion came from a dispatch brief, not a doc gap, so adding prose would have duplicated a correct table.Upstream candidates — not landed here
Per
CLAUDE.md,drive-*skills anddocs/drive/are canonical in prisma/ignite; only project-context overlays live in this repo. Two retro items are Drive-framework guidance with no correct local home, so they are reported rather than landed:Proposal for the operator — a CI gate, deliberately not added
The retro suggested a grep gate asserting every
.test-d.tscontains anit(/test(. I have not added it:CLAUDE.mdrequires asking before changes affecting CI. Concretely, it would be:packages/**/test/**/*.test-d.tsmatches\b(it|test|describe)\s*\(.drive/calibration/grep-library.mdas a brief-specified gate (zero CI cost, opt-in per dispatch), orscripts/+ the Lint job for real enforcement.grouped-pagination-gate.test-d.tswas red from the commit that added it and stayed red across nine dispatches, because the runs that would have seen it were narrowed by path. It was the only one of that package's 20.test-d.tsfiles without a suite.My read: the DoD note landed here addresses the root cause (narrowed gating hides more than this one defect); the grep gate is a cheap belt-and-braces addition worth having only if narrowed runs are expected to keep happening. Operator's call.
🤖 Generated with Claude Code
Summary by CodeRabbit