diff --git a/.claude/skills/README.md b/.claude/skills/README.md index f0e9c004c9..4b85104fae 100644 --- a/.claude/skills/README.md +++ b/.claude/skills/README.md @@ -1,6 +1,6 @@ # Skills -Local skills for this repo. They help you write blog posts, create blog cover images, and write documentation in a consistent style. +Local skills for this repo. They help you write blog posts, create blog cover images, write documentation, and write the changelog in a consistent style. ## How skills work @@ -15,6 +15,7 @@ A skill is a folder with a `SKILL.md` (the instructions) and sometimes `referenc |-------|-----------|-----------------| | [`content-write-blog`](content-write-blog/SKILL.md) | Scaffold a new Prisma blog post (frontmatter + section stubs) | "Draft a blog post about connection pooling" | | [`content-create-hero-image`](content-create-hero-image/SKILL.md) | Generate a post's hero (SVG) and social/OG image (PNG) in the Eclipse house style | "Create a cover image for my Compute post" | +| [`content-write-changelog`](content-write-changelog/SKILL.md) | Write the entry for prisma.io/changelog from everything that shipped since the last one, and open the pull request | "Write this month's changelog" | | [`docs-writer`](docs-writer/README.md) | Write or rewrite developer docs (how-to, concept, reference) | "Write a how-to for deploying to Prisma Compute" | | [`docs-reader-review`](docs-reader-review/SKILL.md) | Check a written page reads for an ordinary user: banned-jargon, staccato, and AI-signs checks, then a fresh reviewer reads it cold and marks what it cannot follow | "Reader review this page" | | [`docs-reader-review/scripts/check-ai-signs.sh`](docs-reader-review/scripts/check-ai-signs.sh) | Runs in CI (`docs-prose.yml`) on every hand-written docs page a pull request adds or changes (the generated ORM and CLI error-reference pages are skipped; their text is fixed upstream); its word list is dated in `references/ai-writing-signs.md` and needs re-checking against Wikipedia's [Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) about every six months | "Update the AI-signs word list" | @@ -51,6 +52,21 @@ Generates a `hero` (editable SVG) plus a pixel-exact `meta` (Open Graph PNG) for For the render to use the real brand fonts, the bundled `assets/fonts/` is used automatically. See [`content-create-hero-image/README.md`](content-create-hero-image/README.md) for tooling details. +## content-write-changelog + +Writes the entry for [prisma.io/changelog](https://www.prisma.io/changelog) and opens the pull request. It gathers what merged since the last entry, keeps only what a user can see and what is already released, and explains each change from the reader's side, with the most impactful change at the top. + +**How to use:** + +1. Ask for the changelog ("write this month's changelog"). The window starts at the newest entry in `apps/site/content/changelog/`. +2. It lists the merged pull requests across the Prisma repositories with the `gh` CLI, then reads the release notes and the docs for the candidates it keeps. You need access to the Prisma organization for the private repositories, or the entry covers the public ones only. +3. It writes `apps/site/content/changelog/{date}.mdx` and adds screenshots to `apps/site/public/changelog/`. +4. It runs `content-write-changelog/scripts/check-entry.mjs`, which checks the frontmatter, compiles the MDX, and checks every link and anchor against production. +5. It runs the `docs-reader-review` checks and has a fresh reviewer read the entry cold, so that the entry explains each change instead of listing it the way a spec would. +6. It opens a pull request whose body lists everything it held back or excluded, with a reason for each. You review, edit, and merge. + +The skill reads the same positioning doc as `content-write-blog`, from the **prisma/ignite** repository. Its rules live in four short references: [gathering](content-write-changelog/references/gathering.md), [filtering](content-write-changelog/references/filtering.md), [voice](content-write-changelog/references/voice.md), and [structure](content-write-changelog/references/structure.md). + ## docs-writer Writes or rewrites developer-facing documentation a reader can follow without getting stuck. Covers how-to, concept, and reference pages. diff --git a/.claude/skills/content-write-changelog/SKILL.md b/.claude/skills/content-write-changelog/SKILL.md new file mode 100644 index 0000000000..fa296cf5b5 --- /dev/null +++ b/.claude/skills/content-write-changelog/SKILL.md @@ -0,0 +1,80 @@ +--- +name: content-write-changelog +description: Use when the operator asks to write, generate, or publish a changelog entry for prisma.io/changelog, says "this week's changelog" or "this month's changelog", asks what shipped since the last entry, or asks to open the changelog pull request. +metadata: + author: Prisma + version: "2026.10.2" +--- + +# Write the changelog entry + +Turn everything that shipped since the last entry into one dated MDX file at `apps/site/content/changelog/{YYYY-MM-DD}.mdx`, plus a triage note that lists every candidate you left out and why. Then open a pull request for humans to review. This skill never merges. + +The reader is a working developer with no time. In a ten-second scan the entry must answer three questions: what can I do now, what stopped hurting, and do I have to act. + +## Pre-conditions + +Stop and tell the operator if one of these is missing. + +1. **A checkout of this repo**, synced with the default branch. Work on a new branch or worktree, never on a branch that carries someone's unfinished work. +2. **The `gh` CLI, signed in** with access to the Prisma organization. Much of the platform is built in private repositories. Without access to them the entry covers the public repositories only, and you must say so in the pull request. +3. **The positioning doc**, read before you write a product claim. The authoritative copy is `docs/prisma/positioning.md` in the `prisma/ignite` repository, the same source `content-write-blog` uses. There is no copy in this repo. If you cannot read it, ask the operator for the current product names and maturity labels. + +## Rules that always apply + +- **Outcome first, product named in the same sentence.** The title, the opening paragraph, and the first sentence of each section lead with what the reader can now do and name the product. Write "You can now enroll a coding agent in Prisma with a credential of its own", not "Agent enrollment is now available". +- **Explain, do not state.** A changelog written from pull request titles reads like a spec. Say what each change means for the reader, in sentences a person would say aloud, with the "so" and "because" left in. `references/voice.md` and the `docs-reader-review` skill describe how. +- **Publish what the user can see, wherever the code lives.** A Console workflow, a CLI command, a REST API route, or a docs page is publishable even when its code is private. Describe the effect and link a public docs page, or link nothing. Never link a private pull request and never name a private repository. +- **Only what is released.** A merged pull request is not a shipped feature. Check each product's release before you write about it, as described in `references/gathering.md`. +- **Every claim has a source you have read.** Use a public one wherever it exists: a release note, a docs page, a blog post, or a public pull request. A change built in a private repository often has none yet. In that case the merged pull request is your source, the entry describes the effect without a link, and the item goes into the triage note as "no public PR" so that a reviewer confirms it in the product before the entry is merged. Quote dates, limits, and prices from the source and never from memory. +- **Full product names on every mention**, as the positioning doc spells them. Check the name and the maturity of each product against the docs when you write, because both change between entries. +- **Most impactful first, at every level.** The title is the biggest change. The headline sections, the bullets in a section, the actions a reader must take, and the fixes are each ordered by how many readers they reach and how much they change. +- **Never pad.** A window with a few fixes gets a short entry with no headline sections. A window with nothing user-facing gets no entry, and you report that instead. +- **No em dashes, no emoji, no vague adjectives, and no vocabulary from the source code.** State the behavior the reader will observe, in words the reader already has. + +## Workflow + +1. **Set the window.** The window starts at the newest entry in `apps/site/content/changelog/` and ends today. Read that entry in full: its structure is the precedent, and the pull requests it links mark where the window starts. + Done when you can name the start date, the end date, and the last pull request already covered. +2. **Gather.** Collect the merged pull requests, the releases, the new docs pages, and the new blog posts for the window, following `references/gathering.md`. + Done when every source in that file has been read or reported as unreachable. +3. **Gate.** Give each candidate one verdict from `references/filtering.md`: publish, rewrite, flag, or exclude. When unsure, flag. + Done when every candidate has a verdict and every flag and exclusion has a one-line reason. +4. **Confirm.** For each candidate you keep, find the public source, check that it is released, and note the docs page that documents it. + Done when no kept item rests on a pull request title alone. +5. **Write.** Read `references/voice.md` and the three `docs-reader-review` references it names, then draft the entry in the order `references/structure.md` gives. + Done when the frontmatter is valid, `slug` equals `date`, and the date is the day the entry lands. +6. **Check.** Run `node .claude/skills/content-write-changelog/scripts/check-entry.mjs apps/site/content/changelog/{YYYY-MM-DD}.mdx --links`. Then run the three scripts in `.claude/skills/docs-reader-review/scripts/` on the same file: `check-plain.sh`, `check-staccato.py`, and `check-ai-signs.sh`. The closing `---` before the Enterprise line is the one hit `check-ai-signs.sh` is expected to report. + Done when the scripts report nothing else. +7. **Have it read cold.** Give the entry to a fresh reviewer, as the `docs-reader-review` skill describes, and rewrite every sentence it could not restate. Repeat with a new reviewer until a round reports no sentence it could not restate and no word it had to guess. Then check every rewritten sentence against its source again, because rewriting drifts meaning. + Done when a round comes back clean, the facts have been checked again, and you have gone through the checklist below. +8. **Open the pull request.** Create the branch `changelog/{YYYY-MM-DD}`, commit the entry and its images as `docs(site): add changelog entry {YYYY-MM-DD}`, push, and open the pull request with the body in `references/structure.md`. If an entry for that date already exists, ask the operator whether to replace it or pick another date. + Done when the pull request is open and its body carries the triage note. +9. **Report and stop.** Give the operator the pull request link, the items that need a human decision, and anything you could not verify. Do not merge and do not enable auto-merge. + +## Checklist before you open the pull request + +- [ ] The title leads with a user action or outcome and names the product. It has no `Prisma:` prefix, no version number, and no chain of features joined by semicolons. +- [ ] The opening paragraph states the biggest change in its first sentence, and names every date the reader must act on. +- [ ] There are at most three headline sections, each one changes what a reader can do, and each heading states an outcome or an action. +- [ ] The most impactful item comes first in the entry, in every section, and in every list. +- [ ] "What you need to do" exists whenever a reader has to act, with one bullet per audience. +- [ ] Every breaking change says what to change. Every deprecation names the old surface, the replacement, and the date. +- [ ] Every documented surface links its docs page, and every link and anchor was checked against production. +- [ ] Every technical identifier is in backticks, and every term a reader of the previous version would not know is replaced or explained where it first appears. +- [ ] Headline sections and short product sections are paragraphs. Lists are used only for items the reader scans. +- [ ] Bold appears on the first sentence, on interface labels, on dates that need action, and on the first sentence of items in a scanned list, and nowhere else. +- [ ] No private pull request links, no private repository names, no internal names, no issue-tracker IDs, no customer names, and no description of how a security problem worked. +- [ ] No CI, dependency, refactor, test, SEO, or analytics items. +- [ ] Every image has alt text that describes what the screenshot shows. +- [ ] Every blog and guide link carries one sentence taken from what the page says, not from its title. +- [ ] The triage note lists every flagged and excluded candidate, including the ones with no public pull request. + +## Reference + +- `references/gathering.md`: where the changes come from, and how to tell merged from released. +- `references/filtering.md`: the verdicts, and the rules for private repositories, unreleased work, and security fixes. +- `references/voice.md`: how to turn a pull request into a sentence a reader can use. +- `references/structure.md`: frontmatter, section order, components, images, and the pull request body. +- `scripts/check-entry.mjs`: checks the frontmatter, the MDX, the images, and the links. +- The two newest entries in `apps/site/content/changelog/` are the samples. Match their shape before you match this document. diff --git a/.claude/skills/content-write-changelog/references/filtering.md b/.claude/skills/content-write-changelog/references/filtering.md new file mode 100644 index 0000000000..90317ea107 --- /dev/null +++ b/.claude/skills/content-write-changelog/references/filtering.md @@ -0,0 +1,90 @@ +# Filtering: what reaches the public changelog + +Run this on every candidate, including the ones that sit under a product heading in someone else's summary. Give each candidate exactly one verdict. When you are unsure, flag it. Every flag and every exclusion goes into the triage note with a one-line reason, so nothing is dropped silently. + +## The baseline test + +A changelog records what changed for the user, not how the team worked. + +Include user-visible behavior changes, new capabilities, fixes a reader would notice, performance gains stated as an effect, breaking changes, deprecations, and retirements. + +Exclude dependency bumps with no user effect, refactors, CI and build changes, repository configuration, test-only changes, and changes to internal documentation. + +## The four verdicts + +### Publish, or rewrite + +Publish a shipped change to a public product as it is. Rewrite a change that carries a real benefit wrapped in internal detail: strip the detail and keep the effect. + +### Flag + +Pull the item from the entry and list it for a human decision when: + +- you cannot confirm that the capability is public, for example a feature that is rolling out, limited to eligible accounts, or switched on by a flag +- it touches pricing, plan limits, a launch date, or a maturity label, and no public page states it +- it reverts something an earlier entry announced +- it is a fix with no user-visible change you can name +- you are not sure + +### Exclude + +Never publish: + +- **Internal names.** Codenames, internal tools, internal agents, and anything that is not in the public product vocabulary. +- **Internal references.** Issue-tracker IDs, chat channels, dashboards, and internal links. +- **Internal process.** CI, builds, dependency bumps, repository configuration, SEO, analytics, consent, and tracking. +- **Implementation detail.** Which vendor, model, or runtime powers a feature, how the infrastructure is laid out, and how a rollout is staged. +- **Security mechanics.** How a vulnerability worked, what a credential looks like, and how tokens are checked. +- **People and customers.** Customer names, support-ticket details, and the names or email addresses of individuals. + +## The strip test + +Remove the internal detail from a line and look at what is left. + +- Nothing a reader can use: exclude. +- A real benefit: rewrite it as user value. +- You cannot tell: flag. + +## Changes from private repositories + +Much of the platform is built in private repositories. Whether the repository is public does not decide the verdict. Whether the user can see the change does. + +Publish a Console workflow, a CLI command, a REST API route, a platform behavior, or a docs page. Describe what the user sees, link a public docs page when one exists, and otherwise link nothing. Add the item to the triage note as "no public PR". + +Exclude work that stays internal even though the product is public: how builds run, how a rollout is staged, where a service is hosted, and observability plumbing. + +Never link a private pull request. The link returns 404 for readers and gives away the repository name. + +## Products that are not generally available + +A product in Early Access or in release candidates often has a public repository full of internal engineering. Apply the test to each line, not to the repository. + +Publish a change that alters what a user can do or see: a new capability in the schema, a CLI command or flag, an editor feature, a query API addition, or a support policy. Keep the wording to what the release notes say. + +Exclude parser and compiler rewrites, internal type machinery, project close-outs, and architecture records. + +State the product's maturity once per entry, in the wording the docs use today. A change to a product before its public launch is not publishable. + +## Guides and articles + +Blog posts and docs guides are written for users, so list them. Link the published page and never the pull request that added it. + +Skip a post about an internal tool. Skip site mechanics such as redirects, metadata, images, and copy tweaks. + +A guide that is the main reference for a feature covered above is linked there, not repeated in the list. + +## Security fixes + +State the outcome, not the exploit. "Connection strings are now redacted from error logs" is publishable. The code path that leaked them is not. + +A dependency update that resolves a published advisory can be one neutral line. Name the advisory only if the public pull request already does. + +When in doubt, flag the item for a security reviewer. + +## Incidents + +A fix that follows an incident is published as the fix. Leave out the incident, the dates, the number of customers affected, and the cause. + +## People and customers + +Replace a named customer with a neutral phrase. "Fixed a replication lag issue reported by Acme" becomes "Fixed a replication lag issue that affected some databases". diff --git a/.claude/skills/content-write-changelog/references/gathering.md b/.claude/skills/content-write-changelog/references/gathering.md new file mode 100644 index 0000000000..4ab7fece31 --- /dev/null +++ b/.claude/skills/content-write-changelog/references/gathering.md @@ -0,0 +1,63 @@ +# Gathering: what shipped in the window + +A changelog entry is only as good as its sources. Read all of them before you write a line. + +## 1. Set the window from the last entry + +List `apps/site/content/changelog/` and open the newest file. The window starts on that entry's date. Because an entry is written on the day it lands, pull requests merged that same day may or may not be in it, so compare against the pull requests it links instead of trusting the date alone. + +## 2. Find the repositories + +The repositories that feed the changelog carry the `loggy-core` topic. Ask GitHub for the current list instead of keeping one in your head, because repositories get added and renamed: + +```bash +gh api --paginate 'search/repositories?q=org:prisma+topic:loggy-core&per_page=100' \ + --jq '.items[] | "\(.full_name)\t\(.private)"' +``` + +The second column tells you which repositories are private. Changes from those are published without a link, as `filtering.md` explains. If the search returns only public repositories, your `gh` session cannot see the private ones. Say so in the pull request, because the Console, the REST API, and most of Prisma Compute and Prisma Postgres will be missing. + +## 3. List the merged pull requests + +For each repository, list what merged in the window and keep the title, the merge date, and the body. `SINCE` and `UNTIL` are the dates from step 1, written as `YYYY-MM-DD`: + +```bash +gh pr list -R "$repo" --state merged --limit 1000 \ + --search "merged:$SINCE..$UNTIL" \ + --json number,title,mergedAt,url,body +``` + +Set `SINCE` a few days before the last entry's date, then drop what that entry already covers. If a repository returns exactly 1000 pull requests, the list was cut off, so split the window in two and run the command for each half. + +A month across every repository is close to a thousand pull requests. Do not read them all. Read the titles first, and set aside the ones that start with `chore`, `ci`, `test`, `refactor`, or `build`, along with dependency bumps and internal project close-outs. Read the body only for the candidates that are left. The body, not the title, tells you what the user sees and whether the change is behind a flag. + +## 4. Check what is released + +A merged pull request is not a shipped feature. Each product has its own check. + +- **Prisma ORM.** The release notes in the `docs/releases/` directory of the ORM repository are the authoritative source, one file per version. Use them for the wording of features, fixes, and breaking changes, and for the pull request each one links. A pull request merged after the last version bump is not released. Leave it for the next entry. `npm view prisma dist-tags` shows what `latest` and `prev` install today. +- **Prisma Studio.** Compare the merge dates with `gh release list -R prisma/studio`. A fix merged after the newest release has not reached users. +- **Console, REST API, Prisma MCP server, Prisma Compute, Prisma Postgres.** These deploy continuously, so a merged change is usually live. Read the body for the words "flag", "gate", "rollout", "internal", "eligible", and "behind". A feature that is on for some accounts only is flagged, not published. +- **This repo.** A docs page or blog post is live when its URL returns 200 on production. Check it, because a page can merge before the app that serves it is deployed. + +## 5. Find the public source for each item + +For every feature you keep, find the docs page that documents it. In `apps/docs/content/docs/`, the URL of a page is its file path: `postgres/migrate-from-ea-to-ga.mdx` is served at `/docs/postgres/migrate-from-ea-to-ga`, and a folder name in parentheses is dropped from the URL. + +A feature with a docs page gets a link to it. A feature with no docs page and no public pull request is described by its effect, gets no link, and goes into the triage note as "no public PR" so a reviewer can confirm it is live. + +Quote every date, limit, and price from the docs page. If a pull request and the docs disagree, the docs win, and the disagreement goes into the triage note. + +## 6. List the new guides and blog posts + +List the posts in `apps/blog/content/blog/` whose frontmatter `date` falls in the window, and the docs guides that were added. Take each one-sentence annotation from the post's `metaDescription` or its opening paragraph. A title alone is not enough to describe a post accurately. + +## 7. Collect the images + +A headline section about something visual carries one screenshot. + +- If the docs already publish a screenshot of the feature, copy it from `apps/docs/public/img/` instead of taking a new one. +- For a public page, capture the live page at a width of 1440 pixels, and crop out cookie banners and announcement bars. +- For a Console screen, ask the operator for a screenshot. It must come from a demo workspace and show no customer names, email addresses, or connection strings. + +Save images as `apps/site/public/changelog/{YYYY-MM-DD}-{short-name}.png`. diff --git a/.claude/skills/content-write-changelog/references/structure.md b/.claude/skills/content-write-changelog/references/structure.md new file mode 100644 index 0000000000..b09dbe9ec8 --- /dev/null +++ b/.claude/skills/content-write-changelog/references/structure.md @@ -0,0 +1,148 @@ +# Structure: the MDX file and the pull request + +The entry is one file at `apps/site/content/changelog/{YYYY-MM-DD}.mdx`. The two newest entries in that directory are the working samples. When they and this document disagree, follow the entries and update this document in the same pull request. + +## Frontmatter + +```yaml +--- +title: "Let your coding agent set up Prisma and ask before it touches production" +date: "2026-10-02" +version: "2026-10-02" +slug: "2026-10-02" +headline: "Let your coding agent set up Prisma and ask before it touches production" +tags: + - "Prisma" + - "Prisma Compute" + - "Prisma ORM" +canonical: "/changelog#log2026-10-02" +metaDescription: "Coding agents can now work in Prisma with their own credential and ask before they change production. Also new: ..." +share: + active: true + content: "Look at this page: " +--- +``` + +- `date` is the day the entry lands, and `slug` and `version` repeat it. `version` is never a product version. +- `headline` repeats `title`. +- `metaDescription` is one or two sentences that name the biggest change and the next two. +- `tags` start with `"Prisma"`, then list each product the entry covers. + +The index page at `/changelog` derives a single category for the entry from its tags, in `apps/site/src/lib/changelog-meta.ts`. The first match wins, in this order: a tag containing "Studio", then "Compute", then "Postgres" or "Accelerate", then "ORM". So tag a product only when the entry has real content for it, or the entry lands under the wrong filter. + +## Body, in this order + +Leave out any block that has no content. Do not repeat the title as a heading, because the page renders it from the frontmatter. + +1. **Opening.** The first sentence is the biggest change, in bold, and it has to stand alone because the index page shows only the start of the entry. The other headline changes follow in a sentence each. If the reader must act by a date, a second short paragraph names each date in bold and points to "What you need to do". + +2. **Up to three headline sections, the most impactful first.** Each is an `##` heading that states the outcome, either as a sentence (`## Coding agents get their own credential and ask before production changes`) or as an action the reader can take (`## Try Prisma ORM 8 on the schema you already have`). A heading that names only the feature, such as "Agent enrollment", tells a skimmer nothing. A change earns a headline section when it changes what a reader can do and can be explained in a few short paragraphs. A fix never does. Inside each section: + - paragraphs, not bullets: what the reader does today and what was wrong with it, then what is new, then how to start + - one screenshot when the change is visual + - one code block when the change is something the reader types + - a row of one or two buttons that lead to the product and to the docs + + Order them by impact: how many readers the change reaches and how much it changes what they can do. Lead with the commercial products only when two changes are of similar weight. + +3. **`## What you need to do`.** Include it whenever a reader has to act. One bullet per audience, opening with a bold condition that lets readers find themselves: `- **If you are on Prisma ORM 7**, you do not need to change anything.` Each bullet states the action, the deadline in bold, the reason, and the guide to follow. Put the nearest deadline and the largest loss first, so a bullet about data that will be deleted comes before one about a connection string. Say so when a group has nothing to do. + +4. **`## Breaking changes`.** One line saying which versions they apply to, then one bullet per change. The bullet opens with what changed in bold, then explains what the reader will see and what to write instead, then links the pull request. When a release has more breaking changes than most apps will hit, list the common ones and link the full release notes. + +5. **`## Deprecations`.** One bullet per deprecation, in full sentences: the product, what is deprecated, what replaces it, the date, and whether the old form still works. When the action is already under "What you need to do", link the guide and do not repeat the steps. + +6. **One `##` section per product**, headed with the exact product name. The section opens with its biggest change, explained in a short paragraph. Related smaller changes follow as further paragraphs, or as a list when there are several of the same kind, introduced by a sentence that says what they have in common. Put the most impactful first. Order the sections by how much changed for users. + +7. **`## Fixes`.** Always visible and grouped by product under bold labels. Within a product, wrong results and data loss come first, then failures, then cosmetic fixes. Each fix is a full sentence, and it says what went wrong before when that helps a reader recognize the bug. + +8. **`## Guides and articles`.** One bullet per new post or guide. Link the published page, and follow it with a colon and one sentence about what the reader gets. + +9. **Around Prisma.** Events and community news, each under its own `##` heading, and only when there is something a reader can attend or use. + +10. **The closing line.** A thematic break, then this line and nothing else: + + ```mdx + --- + + *Need help applying these changes in production? [Prisma Enterprise Support](/enterprise) can help with schema design, performance, security, and compliance.* + ``` + +## Short windows + +A week with a few fixes gets the opening paragraph, the product sections that have content, and the fixes. Do not promote a small change to a headline section to fill space. + +## Links + +- Docs links are absolute: `https://www.prisma.io/docs/...`. Site pages are relative: `/pricing`, `/extensions`, `/enterprise`. +- Link the docs page wherever a documented feature is mentioned. Use only paths you have checked against production. +- Pull request references trail the sentence in parentheses. For the ORM repository write `([#30365](https://github.com/prisma/orm/pull/30365))`. For any other public repository add its name: `([prisma-engines#5851](url))`. Changes from private repositories get no reference. +- A button that leads to the Console carries UTM parameters, as in `?utm_source=changelog&utm_medium=cta&utm_campaign=agent-enrollment`. + +## Components + +Buttons go in a wrapper that opts out of prose styling. Use the filled button for the main action and the outline button for the second one. `ctaLocation` is `changelog-` followed by a short name for the section. + +```mdx +