Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0a53f13
docs: conventions for the data-modeling plain-language pass
wmadden-electric Sep 14, 2026
7cdfd4b
docs(orm): data-modeling banned-term pass and fact check against rc.10
wmadden-electric Sep 14, 2026
9e3cdf6
docs(orm): data-modeling reader review round one
wmadden-electric Sep 14, 2026
e47b01c
docs(orm): data-modeling reader review round two
wmadden-electric Sep 14, 2026
f6b3dbb
docs(orm): data-modeling reader review round three
wmadden-electric Sep 14, 2026
b1b0518
docs(orm): data-modeling reader review round four
wmadden-electric Sep 14, 2026
ba11993
Merge remote-tracking branch 'origin/main' into docs/orm8-plain-langu…
wmadden-electric Sep 14, 2026
19138ba
docs(orm): data-modeling final fact re-check against rc.10
wmadden-electric Sep 14, 2026
b80e23d
docs: remove the data-modeling review reports before merge
wmadden-electric Sep 14, 2026
91ef340
docs(orm): data-modeling review fixes from CodeRabbit
wmadden-electric Sep 14, 2026
dc56811
docs(orm): list Release status and Supported databases in the ORM sid…
wmadden-electric Sep 15, 2026
94c4eee
docs: move Release status and Supported databases into the ORM section
wmadden-electric Sep 15, 2026
6b9376f
docs(orm): one Supported databases page
wmadden-electric Sep 15, 2026
8e91233
docs(orm): SQLite is an experimental package and MySQL is planned next
wmadden-electric Sep 15, 2026
ec5c89e
docs(orm): rejoin clipped sentences on the data-modeling pages
ankur-arch Sep 15, 2026
97ca48a
docs(orm): staccato pass over the ORM section
ankur-arch Sep 15, 2026
49b0e74
Merge branch 'main' into docs/orm8-plain-language-data-modeling
ankur-arch Sep 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .claude/skills/content-write-blog/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: content-write-blog
description: Use when the operator wants to write a blog post, draft a blog article, start a new post for the Prisma blog, or publish to prisma.io/blog.
metadata:
version: "2026.7.9"
version: "2026.9.15"
---

# Write Blog Post
Expand Down Expand Up @@ -180,7 +180,8 @@ The lead you draft, and the prose the author later writes over your stubs, ship
- **Be specific.** Replace "this changes everything" or "the implications are significant" with the concrete change. Drop "every", "always", and "never" where a real number fits better.
- **Cut filler.** No "really", "simply", "just", and no marketing verbs like "leverage", "unlock", "seamless", "powerful".
- **Say it straight.** "Not X, but Y" and "X isn't the problem, Y is" telegraph the reversal. State Y.
- **Vary sentence length**, and use a comma, colon, or period in place of em dashes.
- **Vary sentence length.** A run of short, clipped sentences with no connectives reads as staccato ("The fix shipped. Latency dropped. Users noticed."), and it is the most common tell of a model-drafted post. When facts are cause and effect or contrast, join them with "because", "so", or "but", and let a longer sentence carry them. Then let a short one land the point.
- **Use a comma, colon, or period in place of em dashes.**

## Anti-patterns

Expand Down
6 changes: 5 additions & 1 deletion .claude/skills/docs-reader-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Use it after `docs-writer` (or any other writing pass) and after the fact review

Run `scripts/check-plain.sh` on every changed page. It fails on the words in `references/banned-terms.md`, which lists source-code vocabulary and the plain words to use instead, and it ignores code blocks and inline code. Replace every hit before going further. Do not argue that a term is fine in context. The one exception: if the sentence itself defines the term in plain words, add `{/* plain-language:defined */}` to that line; the checker skips it and the reader review will confirm the definition landed. Terms the list marks "(unexplained)" are not checked by the script; the reviewer catches them.

### 1b. Run the staccato check

Run `scripts/check-staccato.py` on every changed page. It flags paragraphs with three or more consecutive sentences under nine words, the usual signature of a page whose long sentences were split without keeping the connectives. Read each flagged paragraph aloud. Rejoin sentences that are cause and effect, contrast, or condition and result with "because", "so", "but", "while", or a colon, and leave apart the ones that are separate ideas. The script only finds the worst runs; a paragraph of eleven-word sentences that all land the same way is still staccato, so read the whole page for rhythm, not only the hits. Reference entries that are fragments by design (a `Payload:` line, a one-line table note) are not prose and do not count.

### 2. Dispatch the reader

Hand the page to a fresh reviewer that has no memory of writing it, using `references/reader-persona.md` verbatim as its instructions. The reviewer reads the page once, top to bottom, with nothing else open, and reports:
Expand All @@ -42,7 +46,7 @@ For each reported sentence:
| The reviewer said | Do this |
| --- | --- |
| a word it had to guess | replace with the plain words from `references/banned-terms.md`, or define it in that sentence |
| too many ideas in one sentence | one idea per sentence; a table cell with three ideas becomes a note under the table |
| too many ideas in one sentence | one idea per sentence, keeping the connective (because, so, but) that ties related facts together; a row of clipped one-clause sentences is its own failure, not a fix. A table cell with three ideas becomes a note under the table |
| "so what do I type?" | add the command or the code, or the link to the page that has it |
| mechanism instead of action | delete the mechanism, keep what the reader does and what they see |
| a reference it could not resolve ("the plan", "the ref", "spec") | show the thing, or name where it comes from |
Expand Down
97 changes: 97 additions & 0 deletions .claude/skills/docs-reader-review/scripts/check-staccato.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""Flags staccato prose: runs of short, one-clause sentences with no connective between them.

Usage: check-staccato.py <file.mdx> [more files...] Exit 1 on any hit.

A hit is a paragraph containing three or more consecutive sentences that are each
under MAX_WORDS words. Fenced code, tables, headings, list items, front matter, and
import lines are skipped. Colons that introduce a code span or example are not
treated as sentence ends. The heuristic is deliberately simple: it finds the
paragraphs a human should read aloud, and the reader decides whether the sentences
belong together. Rejoin them with "because", "so", "but", "while", or a colon when
they are cause and effect, contrast, or condition and result. Leave them apart when
they are separate ideas.
"""
import re
import sys

MAX_WORDS = 9
RUN = 3

CODE = re.compile(r"`[^`]*`")
LINK = re.compile(r"\]\([^)]*\)")
SENT_END = re.compile(r"(?<=[.!?])\s+(?=[A-Z`\"'(])")


def paragraphs(text):
"""Yield (line_number, paragraph) for prose paragraphs only."""
lines = text.split("\n")
out, start, infence, infront = [], None, False, False
for i, line in enumerate(lines, 1):
if i == 1 and line.strip() == "---":
infront = True
continue
if infront:
if line.strip() == "---":
infront = False
continue
if re.match(r"^\s*(```|~~~)", line):
infence = not infence
continue
if infence or line.startswith((" ", "\t")):
continue
stripped = line.strip()
if not stripped:
if out:
yield start, " ".join(out)
out, start = [], None
continue
if re.match(r"^(#|\||[-*+] |\d+\. |import |export |<|{/\*)", stripped):
if out:
yield start, " ".join(out)
out, start = [], None
continue
if start is None:
start = i
out.append(stripped)
if out:
yield start, " ".join(out)


def sentences(para):
para = CODE.sub("CODE", para)
para = LINK.sub("]", para)
return [s.strip() for s in SENT_END.split(para) if s.strip()]


def check(path):
hits = []
text = open(path, encoding="utf-8").read()
for lineno, para in paragraphs(text):
sents = sentences(para)
short = [len(s.split()) < MAX_WORDS for s in sents]
run = 0
for j, is_short in enumerate(short):
run = run + 1 if is_short else 0
if run == RUN:
first = j - RUN + 1
hits.append((lineno, " | ".join(sents[first : j + 1])))
break
return hits


def main(argv):
status = 0
for path in argv:
hits = check(path)
if hits:
status = 1
print(f"== {path}")
for lineno, snippet in hits:
print(f"{lineno}: {snippet[:180]}")
print("staccato check: clean" if status == 0 else "staccato check: clipped runs found, read them aloud")
return status


if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
4 changes: 3 additions & 1 deletion .claude/skills/docs-writer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: docs-writer
description: Use when writing, rewriting, or improving technical docs (quickstarts, how-tos, tutorials, concept pages, or API references).
metadata:
author: Prisma
version: "2026.9.11"
version: "2026.9.15"
---

# Docs Writer
Expand Down Expand Up @@ -163,6 +163,7 @@ Model-drafted docs share habits a reviewer can spot in one pass. None of these i
- **Contrast slogans**: "X, not Y" constructions ("injected, not discovered", "built for agents, not just terminals", "refuses to guess"). One per page at most. A page of balanced contrasts reads like ad copy; state the behavior plainly instead.
- **Absolute stacking**: "never", "every", "nothing", "always", "cannot drift" piling up across a page. Each absolute is a promise the product has to keep. Keep the ones you can verify and that the reader needs; describe what happens rather than asserting what can't.
- **Exception-packed sentences**: one sentence carrying the normal case, an exception, its reason, the alternative, and a safety condition, held together by semicolons. One idea per sentence: state the default first ("By default, the command uses…"), then the exception as its own sentence ("In CI or other headless environments, set…"). A semicolon joining distinct ideas is usually two sentences.
- **Staccato**: the opposite failure, and the usual result of over-correcting the one above. A run of short, clipped sentences, each holding one fact, with no connective between them: "The field takes no `@default`. Omit `id` when you create a document and MongoDB assigns it." or "A profile needs a user. A user does not need a profile. So `Profile` holds `userId`." Every sentence lands with the same thud and the reader has to work out how the facts relate. One idea per sentence does not mean one clause per sentence. When two facts are cause and effect, contrast, or condition and result, join them with "because", "so", "but", "while", or a colon, and let one sentence carry both: "A profile needs a user, but a user does not need a profile, so `Profile` holds `userId`." Vary sentence length within a paragraph, and read it aloud before finishing: if three sentences in a row are under ten words, at least two of them probably belong together.
- **Manager-voice openers**: "`service` manages services…", "handles", "manages everything around". Lead with the user action or outcome ("Use `service` commands to manage…") and use concrete verbs: creates, stores, uses, selects, targets, deploys, builds.
- **Coined shorthand**: compressed phrases invented mid-page ("local pin", "pick a target") instead of saying what actually happens. Spell out the relationship, and keep one consistent user-facing vocabulary: service, project, configuration, deployment, credentials.
- **Implementation language**: internal detail that doesn't help the reader act ("the root node is `<entry>`'s default export"). Translate it into the behavior they observe ("the application exported as the default export from `<entry>`").
Expand Down Expand Up @@ -192,5 +193,6 @@ Before you finish, check:
- [ ] Is there a way to verify success at the end?
- [ ] Did you cut every phrase from "Cut the slop"?
- [ ] Did you check the page against every pattern in "Don't write like a model"?
- [ ] Did you read the prose aloud and rejoin any run of clipped sentences that belong together? `.claude/skills/docs-reader-review/scripts/check-staccato.py <page>` finds the worst runs.
- [ ] Are product names and limitations accurate?
- [ ] Has the page been through `docs-reader-review`? A fact review checks truth; the reader review checks whether a reader without your context can follow it. Nothing is finished until that pass reports no sentence the reader could not restate.
2 changes: 1 addition & 1 deletion apps/docs/content/docs/(index)/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ metaDescription: Choose a Prisma ORM quickstart for a new project or add Prisma

Start with a quickstart if you want [Prisma ORM](/orm) to create the app. Use the existing-project path if you already have an app and database.

Coming from an earlier version? [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7) maps every Prisma ORM 7 API to its Prisma ORM 8 form, and [Release status](/prisma-orm/release-status) says where Prisma ORM 8 stands today.
Coming from an earlier version? [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7) maps every Prisma ORM 7 API to its Prisma ORM 8 form, and [Release status](/orm/release-status) says where Prisma ORM 8 stands today.

## Start a new project

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/(index)/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ full: true
<WorkflowHero>

Prisma is a complete TypeScript stack with one workflow: **build** your app and run all of it on your machine, then **deploy** it to the Prisma platform with one command. Check out the [full-stack tutorial](/full-stack-tutorial).
<span className="mt-2 block">Here for the ORM? Jump straight to [Prisma ORM 7](/orm/v7) or [Prisma ORM 8](/orm), or check the [release status](/prisma-orm/release-status) first.</span>
<span className="mt-2 block">Here for the ORM? Jump straight to [Prisma ORM 7](/orm/v7) or [Prisma ORM 8](/orm), or check the [release status](/orm/release-status) first.</span>

<WorkflowGrid>
<WorkflowStage title="Build" description="Define the app in TypeScript and run everything locally before you ship.">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Use this path when you already have an application and database. Make sure the a

Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](/orm/v7) and its setup paths at [/v7/getting-started](/v7/getting-started).

For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/prisma-orm/release-status).
For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/orm/release-status).

:::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Use this path when you already have an application and database. Make sure the a

Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](/orm/v7) and its setup paths at [/v7/getting-started](/v7/getting-started).

For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/prisma-orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).
For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).

:::

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/docs/(index)/prisma-orm/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Prisma ORM 8 is a ground-up rebuild of Prisma ORM, from the runtime and query AP

Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](/orm/v7) and its setup paths at [/v7/getting-started](/v7/getting-started).

For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/prisma-orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).
For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).

:::

Expand Down
4 changes: 2 additions & 2 deletions apps/docs/content/docs/(index)/prisma-orm/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"defaultOpen": true,
"pages": [
"index",
"release-status",
"supported-databases",
"[Release status](/orm/release-status)",
"[Supported databases](/orm/supported-databases)",
"create-prisma",
"quickstart",
"add-to-existing-project"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Create a Prisma ORM app with MongoDB, apply the first migration, and run your fi

Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](/orm/v7) and its setup paths at [/v7/getting-started](/v7/getting-started).

For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/prisma-orm/release-status).
For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/orm/release-status).

:::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Create a Prisma ORM app with PostgreSQL and run your first query against seeded

Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](/orm/v7) and its setup paths at [/v7/getting-started](/v7/getting-started).

For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/prisma-orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).
For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).

:::

Expand Down
36 changes: 0 additions & 36 deletions apps/docs/content/docs/(index)/prisma-orm/supported-databases.mdx

This file was deleted.

2 changes: 1 addition & 1 deletion apps/docs/content/docs/cli/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Prisma ORM ships with a unified Prisma CLI. One binary contains the ORM commands

Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](/orm/v7) and its setup paths at [/v7/getting-started](/v7/getting-started).

For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/prisma-orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).
For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](/orm/release-status). For the Prisma ORM 8 name of every Prisma ORM 7 API, see [Coming from Prisma ORM 7](/orm/coming-from-prisma-orm-7).

:::

Expand Down
8 changes: 1 addition & 7 deletions apps/docs/content/docs/guides/deployment/meta.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
{
"title": "Deployment",
"pages": [
"cloudflare-workers",
"docker",
"turborepo",
"pnpm-workspaces",
"bun-workspaces"
]
"pages": ["cloudflare-workers", "docker", "turborepo", "pnpm-workspaces", "bun-workspaces"]
}
Loading
Loading