From 6a4de75d801adfa097bbc2d9d9f0bb1ceddfc423 Mon Sep 17 00:00:00 2001 From: David Montague <35119617+dmontagu@users.noreply.github.com> Date: Fri, 3 Jul 2026 08:54:30 -0600 Subject: [PATCH 1/3] Add a user-facing copy standard to CLAUDE.md Claude-Session: https://claude.ai/code/session_01VRXHUAwM4RjifoaouEwooF --- CLAUDE.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index c2c5fc844..3390f5c41 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,6 +13,25 @@ Pre-commit automatically runs ruff and pyright, but you can also run `make forma Docs are rendered and deployed through the `pydantic/unified-docs` pipeline. Do not use MkDocs checks in this repository. +# Writing for Users + +Every user-facing string this repo produces — docs pages, exception messages, warnings, CLI output, public docstrings — is held to one standard: + +> If an expert in some other field who has just started building with AI tools wouldn't know what it means, we spell out the acronym, we explain the term in place, or we rewrite the sentence to be human friendly. + +This reader is not a caricature of a confused user. They're smart, motivated, and perfectly capable of understanding anything we take a sentence to explain. What they haven't done is spend years marinating in observability infrastructure, so words that feel like plain English to us (`span`, `exporter`, `instrument`, `OTLP`, `sampling`, `scrubbing`) can be a closed door to them. A specialist walking us through their own field wouldn't drop a term of art and move on; they'd give the plain-language version the first time. We extend the same courtesy. + +This is not dumbing down. Precise terms stay — they're often the thing the user needs to learn to succeed with the product. The standard is about _introducing_ terms, not avoiding them: give the real word and, at its first use on a page, a plain-language hand-hold. + +When you write or touch a user-facing string, check: + +- **Acronyms are spelled out at first use on each page** — "OpenTelemetry Protocol (OTLP)", "personally identifiable information (PII)". Assume the reader opens the page directly from a search; no acronym is "already established" by another page. +- **The page says what it's for.** Every docs page opens with what this is and why you'd use it, before any code or configuration. A feature name is not a description. +- **Copy describes the user's goal, not our mechanism.** "See every request your app handles", not "Attach the ASGI middleware span processor". If a word names a piece of our internals, it doesn't belong in user-facing text. +- **Instructions say where.** "Run this in your terminal", "Copy this from your project settings page in Logfire". A step asking for a value the user has to fetch from somewhere else must say where that somewhere is. +- **Consequences are stated plainly** — especially when data leaves the user's machine, something costs money, or an action can't be undone. If a setting sends more telemetry, say so; if data is dropped or redacted, say what and when. +- **Errors and warnings name what went wrong and what to do next.** Never a bare "invalid configuration", never an internal detail as the whole user-facing explanation. Say which value failed, why, and what a working one looks like. + # Core Structure ``` From b650b472cc674b1e4ffe994d60e05f9f682c9de2 Mon Sep 17 00:00:00 2001 From: David Montague <35119617+dmontagu@users.noreply.github.com> Date: Fri, 3 Jul 2026 08:58:40 -0600 Subject: [PATCH 2/3] Scope the writing standard to public docs only Claude-Session: https://claude.ai/code/session_01VRXHUAwM4RjifoaouEwooF --- CLAUDE.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 3390f5c41..93eb30902 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,9 +13,9 @@ Pre-commit automatically runs ruff and pyright, but you can also run `make forma Docs are rendered and deployed through the `pydantic/unified-docs` pipeline. Do not use MkDocs checks in this repository. -# Writing for Users +## Writing standard -Every user-facing string this repo produces — docs pages, exception messages, warnings, CLI output, public docstrings — is held to one standard: +Every page in the public docs (`docs/`) is held to one standard: > If an expert in some other field who has just started building with AI tools wouldn't know what it means, we spell out the acronym, we explain the term in place, or we rewrite the sentence to be human friendly. @@ -23,14 +23,15 @@ This reader is not a caricature of a confused user. They're smart, motivated, an This is not dumbing down. Precise terms stay — they're often the thing the user needs to learn to succeed with the product. The standard is about _introducing_ terms, not avoiding them: give the real word and, at its first use on a page, a plain-language hand-hold. -When you write or touch a user-facing string, check: +When you write or touch a docs page, check: - **Acronyms are spelled out at first use on each page** — "OpenTelemetry Protocol (OTLP)", "personally identifiable information (PII)". Assume the reader opens the page directly from a search; no acronym is "already established" by another page. -- **The page says what it's for.** Every docs page opens with what this is and why you'd use it, before any code or configuration. A feature name is not a description. -- **Copy describes the user's goal, not our mechanism.** "See every request your app handles", not "Attach the ASGI middleware span processor". If a word names a piece of our internals, it doesn't belong in user-facing text. +- **The page says what it's for.** It opens with what this is and why you'd use it, before any code or configuration. A feature name is not a description. +- **Copy describes the user's goal, not our mechanism.** "See every request your app handles", not "Attach the ASGI middleware span processor". If a word names a piece of our internals, it doesn't belong in the docs. - **Instructions say where.** "Run this in your terminal", "Copy this from your project settings page in Logfire". A step asking for a value the user has to fetch from somewhere else must say where that somewhere is. - **Consequences are stated plainly** — especially when data leaves the user's machine, something costs money, or an action can't be undone. If a setting sends more telemetry, say so; if data is dropped or redacted, say what and when. -- **Errors and warnings name what went wrong and what to do next.** Never a bare "invalid configuration", never an internal detail as the whole user-facing explanation. Say which value failed, why, and what a working one looks like. + +This standard is for docs prose. Docstrings and other in-code text follow normal API-reference conventions and are not expected to introduce terms this way. # Core Structure From 4dfb1919b4f8d5fe44ea9488994a2ec0d2d98a22 Mon Sep 17 00:00:00 2001 From: David Montague <35119617+dmontagu@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:02:28 -0600 Subject: [PATCH 3/3] Cover both observability and AI jargon in the docs writing standard Claude-Session: https://claude.ai/code/session_01VRXHUAwM4RjifoaouEwooF --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 93eb30902..3becd2cd7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,7 +19,7 @@ Every page in the public docs (`docs/`) is held to one standard: > If an expert in some other field who has just started building with AI tools wouldn't know what it means, we spell out the acronym, we explain the term in place, or we rewrite the sentence to be human friendly. -This reader is not a caricature of a confused user. They're smart, motivated, and perfectly capable of understanding anything we take a sentence to explain. What they haven't done is spend years marinating in observability infrastructure, so words that feel like plain English to us (`span`, `exporter`, `instrument`, `OTLP`, `sampling`, `scrubbing`) can be a closed door to them. A specialist walking us through their own field wouldn't drop a term of art and move on; they'd give the plain-language version the first time. We extend the same courtesy. +This reader is not a caricature of a confused user. They're smart, motivated, and perfectly capable of understanding anything we take a sentence to explain. But our docs sit at the intersection of observability and AI tooling, and few readers arrive fluent in both — so words that feel like plain English to us (`span`, `exporter`, `OTLP`, `evals`, `sampling`, `scrubbing`) can be a closed door to them. A specialist walking us through their own field wouldn't drop a term of art and move on; they'd give the plain-language version the first time. We extend the same courtesy. This is not dumbing down. Precise terms stay — they're often the thing the user needs to learn to succeed with the product. The standard is about _introducing_ terms, not avoiding them: give the real word and, at its first use on a page, a plain-language hand-hold.