بنقرة واحدة
docs-pr-review
// Review a docs PR from someone else. Triage issues by severity, draft comments with rationale, and focus on what matters. Use when reviewing a PR, not when checking your own work (use docs-pre-ship-review for that).
// Review a docs PR from someone else. Triage issues by severity, draft comments with rationale, and focus on what matters. Use when reviewing a PR, not when checking your own work (use docs-pre-ship-review for that).
Convert ClickHouse blog content into docs pages. Use when porting a feature announcement, tutorial, or deep-dive from the blog into the docs site. Covers content extraction, asset handling, structural transformation, and voice conversion.
Voice, style, and content rules for writing ClickHouse docs. Use when drafting new pages, rewriting sections, or applying editorial polish. Covers identity, voice, pacing, sentence habits, anti-patterns, AI-ism removal, prose tightening, editorial instinct, linking, keywords, content integrity, and marketing site alignment.
Review a ClickHouse docs page before shipping. Runs the self-review checklist, Vale linting, and PR review rubric. Use when doing a final check, running Vale, or when asked "is this ready to ship."
| name | docs-pr-review |
| description | Review a docs PR from someone else. Triage issues by severity, draft comments with rationale, and focus on what matters. Use when reviewing a PR, not when checking your own work (use docs-pre-ship-review for that). |
Review PR #[number] using the docs-pr-review skill.
Pass 1 runs first (diff-scoped, 13 checks). Pass 2 runs second (full file, pre-existing quality issues).
Review someone else's docs PR. Your job is to triage and communicate. This skill is read-only — do not edit files, stage changes, or commit. Output a list of comments, suggestions, and questions. The user decides what to act on.
Scope note: Changes to files under i18n/ (jp, ko, ru, zh) are not
worth flagging — translations sync automatically from the English source.
This is different from pre-ship review (checking your own work). Here you're balancing thoroughness with respect for the author's time.
No shortcuts. No laziness. Catch every problem, every time.
A different session reviewing the same PR must produce the same findings, the same line numbers, and the same severity tiers. This is the quality bar — reviews that miss issues or report wrong line numbers are failures, not approximations. Every check runs completely, every finding is verified before it is reported, and every line number is mechanically computed. No step is skipped because the PR is large, because the content looks fine at a glance, or because a similar check already passed.
This review has two distinct passes with different scopes.
Get the diff. Use gh pr diff to see only what the contributor changed.
All review comments must be scoped to lines in the diff.
Line numbers — compute them mechanically, never estimate:
Every line number in the review output must be exact and deterministic.
A different session reviewing the same PR must produce identical line
numbers. Never use ~ prefixes, never round, never eyeball.
gh pr diff N | grep -nE '^\+\+\+ b/|^@@ ' to get the
diff-output line number of every file boundary and @@ hunk header.gh pr diff N | grep -n '^+#.*{#' (or similar targeted greps)
to find the diff-output line number of the content you need to cite.@@ header shows the target file line where the hunk starts
(e.g., @@ -0,0 +1,42 @@ → file line 1; @@ -85,7 +89,10 @@ →
file line 89).file_line = diff_output_line - @@_header_linefile_line = hunk_start + (diff_output_line - @@_line - 1)
(only counting + and context lines, not - lines).Content between hunks (gaps): The @@ start line tells you where
the hunk begins, not where unchanged content between hunks lives.
For content in a gap:
prev_hunk_start + new_count - 1.@@ header.next_hunk_start - prev_hunk_end - 1 unchanged lines.@@ start —
compute its exact position by counting.Verification step: Before including any line number in the review
output, confirm it was computed (not estimated) and trace back to the
@@ header or Read tool output that produced it. If you cannot trace
a number back to a mechanical computation, recompute it before
proceeding.
For Pass 2 (local file reads), the Read tool prints N→ content —
cite N verbatim.
Never estimate line numbers by reading the diff and guessing.
Always compute from @@ headers. Never write awk scripts or custom
tooling either.
Read the local copies of changed files for context. Do not checkout the PR branch — it fails on forks and risks disrupting local git state.
Collect Pass 2 inputs. Do both of these now — results go in Pass 2, not Pass 1.
.md files. CI already runs
Vale on the PR's diff, so don't report Vale issues on diff lines —
focus on issues outside the diff that CI won't catch. Run vale
directly on the local file path. Cross-reference Vale line numbers
against the diff's @@ hunk headers — issues on lines outside the
diff are pre-existing and go in Pass 2. If the PR renames or moves a
file, skip Vale — the old path still has the content locally, but
line numbers won't match the post-merge state.Run the checklist below in order. Check every item; only report items that fail. This is the complete list — do not invent additional review categories.
Triage findings into the three severity tiers below.
Draft comments following the comment style guidelines.
Summarize your review: what you'd block on, what you'd suggest, and what you'd let go.
| # | Check | Tier if failed |
|---|---|---|
| 1 | Frontmatter complete — slug, title, sidebar_label, description, keywords present | Block |
| 2 | MDX/build safety — imports exist, no broken JSX, images referenced exist | Block |
| 3 | Technical accuracy — commands, SQL, column/table names, config keys are correct | Block |
| 4 | No secrets — no hardcoded credentials, internal URLs, or API keys | Block |
| 5 | Product terminology — correct product names (ClickStack vs HyperDX, etc.) | Block |
| 6 | Grammar, spelling, typos — misspellings, wrong verb forms, missing words, wrong articles | Block |
| 7 | Sentence casing — headings must use sentence case, not Title Case | Block |
| 8 | Content preservation on rewrites — substantial deletions or rewrites must preserve original information, or the new content must cover it or render it moot | Block |
| 9 | Vale errors in diff — CI covers these; only flag if CI is not running on this PR | Block/Suggest |
| 10 | Voice/style in diff — mechanical pre-screen for AI density, then watchlist scan; "you" not "users," active voice | Suggest / Block on AI cluster |
| 11 | First-mention links — ClickHouse features/concepts link to their docs on first use | Suggest |
| 12 | Component opportunities — numbered steps → VerticalStepper, variants → Tabs, etc. | Suggest |
| 13 | Structure and flow — sections in logical order, prerequisites before procedures, page organization matches sibling pages | Suggest |
| 14 | Screenshot utility — screenshots used as shortcuts ("refer to the screenshot") without sufficient prose context | Suggest |
Block-tier checks (#1–#8) must be exhaustive — every instance found, not sampled. Some checks have deterministic patterns that grep can catch; others require careful reading. Run the two modes separately, in order: grep-based checks first (fast, mechanical), then a reading pass (slower, requires comprehension). Do not try to do both in a single pass through the diff — that's how things get missed.
Mode 1: Pattern-based checks (run first, via grep)
These checks have deterministic patterns. Grep the diff to get a complete list, then verify each result.
Sentence casing (#7):
Run gh pr diff N | grep -n '^+#.*{#' to extract every added heading
with its diff-output line number. Check each heading: only the first
word and proper nouns may be capitalized. Compute the file line for every
violation using the @@-header method above.
Common proper nouns in this codebase: ClickHouse, ClickStack, HyperDX, Helm, Kubernetes, MongoDB, OpenTelemetry Collector, OTEL, AWS, GKE, EKS, AKS, API, SQL, TLS, DNS, JSON, YAML, ConfigMap, Secret (K8s resource types).
Frontmatter (#1):
For every changed or new .md file, verify the frontmatter block in the
diff contains all required fields: slug, title, sidebar_label,
description, keywords. Integration guides also need pagination_prev,
pagination_next, and doc_type.
Mode 2: Comprehension checks (reading pass)
These checks require understanding the content — grep can't catch them. Read through the diff content carefully, file by file.
Technical accuracy (#3):
A reviewer's job is not to re-run every command — that's the author's
responsibility (covered by docs-pre-ship-review). Your job is to catch
what looks wrong and flag what you can't verify. Use this hierarchy:
Verify yourself (fast, do these):
find docs/ -name '*.md' | xargs grep -l 'slug:' | head -20 to spot-check that a referenced page exists.grep -r 'MergeTree' docs/ --include='*.md' -l) to confirm it's real and consistently spelled.doc_type is one of guide, reference, changelog, landing-page — anything else is wrong.clickhouse-client --help output is documented in docs/interfaces/cli.md).Ask the author (you cannot verify these without running the system):
When asking the author, be specific: "Can you confirm this command runs without error against a fresh install?" is more useful than "Please verify this is correct."
Flag as Block if:
Flag as Suggest (ask author) if:
Do not flag claims you have no specific reason to doubt. Skepticism without evidence is noise.
Grammar, spelling, typos (#6): Read the prose in added lines. Watch for wrong articles, missing words, subject-verb disagreement, and misspellings that pass spellcheck (e.g., "form" for "from").
Content preservation on rewrites (#8):
Only run this check when the diff is a substantial rewrite or large deletion — skip it for small edits. Trigger when any of these are true:
For each substantial deletion, list the distinct claims, warnings, examples, and links being removed, then map each one to:
Litmus test: "If a reader needed information X, could they still find it after this change?" If no, flag.
Flag as Block if:
Do not flag content that is genuinely redundant with what remains, clearly outdated, or replaced by a tighter treatment of the same point.
No secrets (#4), product terminology (#5), MDX/build safety (#2): These surface during reading. Flag hardcoded credentials, wrong product names, and missing imports as you encounter them.
Voice/style and AI-isms (#10):
Check the doc_type in frontmatter before running this check. The
watchlist and thresholds differ by type.
Run this check in three stages: mechanical pre-screen, watchlist scan, escalation decision. Sophisticated AI output (e.g., recent Claude) avoids the obvious phrase-based tells in the watchlist below — the structural tells (punctuation density, intensifier frequency, header voice) are what catches it. Run the pre-screen first; it's deterministic and surfaces patterns the eyeball pass misses.
Stage 1: Mechanical pre-screen.
# Em-dash count in additions
gh pr diff N | grep '^+' | grep -v '^+++' | grep -o '—' | wc -l
# Em-dash locations (skim to separate bullet "term — def" from prose)
gh pr diff N | grep -n '^+.*—'
# Semicolon usage in prose additions (excludes table rows)
gh pr diff N | grep -nE '^\+[^|+].*;'
# "actually" as intensifier
gh pr diff N | grep -niE '^\+.*\bactually\b'
# Added section headings (review for folksy/blog-post voice)
gh pr diff N | grep -nE '^\+#{2,} '
Thresholds for a new or substantially rewritten page:
term — def
definitions) is a signal. Watch especially for multiple em-dashes
in a single sentence ("X — Y — Z") or em-dashes in consecutive
paragraphs.Record counts and note which thresholds tripped. Don't flag yet — feed into Stage 3.
Stage 2: Watchlist scan.
Read added prose and flag instances from this watchlist.
Phrase-based (often grep-friendly):
Pattern tells (require reading):
High-severity-only subset (for reference and landing-page types):
tapestry, mosaic, fabric, paradigm shift, seamless, groundbreaking,
revolutionary, game-changing, landscape, ecosystem, north star,
unlock, leverage, empower, in today's fast-paced, in an era of, thank
you for reading. Plus em-dash overuse (5+ prose em-dashes). Reference
pages are structured by nature (parallel lists, topic sentences are
expected); only the cliches above are flagged.
Stage 3: Escalation decision.
Tally hits across both stages. Categories: punctuation (em-dash, semicolon), sentence patterns (contrast, question-answer, re-explanation, tricolon, fragment summaries, meta-commentary), transitions, hedging/filler, buzzwords, metaphor, voice (folksy headers, anthropomorphism, "actually" intensifier), formatting (bold abuse).
doc_type | Hits | Action |
|---|---|---|
guide | 0 | Move on, no comment. |
guide | 1–2 in one category | Single batched comment with rewrites. Suggest. |
guide | 3+ in one category | Batched comment with rewrites. Suggest. Reference load required (see below). |
guide | 3+ categories (cluster) | Block. Reference load required (see below). Flag whole page as AI-generated; ask for a revision pass before merge. Don't comment line-by-line — the page needs a voice rewrite, not patches. |
reference / landing-page | < 3 hits | Move on. |
reference / landing-page | 3+ hits | Batched comment. Suggest. Reference load required (see below). |
reference / landing-page | 5+ hits or 3+ categories | Block. Reference load required (see below). |
If doc_type is missing from frontmatter, default to guide thresholds.
Reference load (gating step — required when any row above says so).
When a threshold triggers a reference load, STOP before drafting any AI-tell findings. In order:
references/ai-tells.md in full (use the Read tool, not a grep
or partial read).A review that flags an AI cluster without §-citations is incomplete —
the catalogue exists so rewrites are reproducible across sessions, and
improvised remediation defeats that purpose. If you find yourself
drafting AI-tell rewrites without the catalogue loaded, stop and load
it before continuing.
A whole-page AI cluster is qualitatively different from scattered style nits. A reader can tell the difference between docs written by a person and docs written by an LLM with light edits; a page that trips the cluster threshold reads as the latter and shouldn't ship as the former.
Always check general voice issues regardless of doc type: third person ("the user," "users") in second-person docs, passive voice where active is clearer.
Screenshot utility (#14): Scan for crutch phrases like "refer to the screenshot", "see screenshot", "as shown in the screenshot below", or "see the image above." These indicate the author is relying on a visual instead of explaining the step in prose.
Apply this litmus test: could the reader succeed with the task based only on the prose description, without looking at the screenshot?
Screenshots earn their place by showing the result of a step (confirmation), orienting the reader in a complex UI, or surfacing a non-obvious option. They don't earn their place when they substitute for writing a clear instruction.
Structure and flow (#13): Read the full file (not just the diff) to evaluate page organization. Check that sections follow a logical progression — context before procedures, prerequisites before steps, conceptual overview before reference detail. Read 2–3 sibling files in the same directory to see whether the page matches the section ordering conventions around it. Flag cases where a reader would need to scroll back to understand something, where procedural steps are buried after reference tables, or where the page structure diverges from its neighbors without reason. Don't flag structure that is clear and works even if you'd organize it differently — this check targets disorienting layouts, not style preferences.
This pass uses the Vale output and manual read-through you collected in Pass 1 step 3. Both are required — Vale catches mechanical issues (spelling, contractions, wordy phrases) while the manual read catches grammar errors, voice violations, and formatting problems that Vale misses.
Always scan the full files touched by the PR for pre-existing quality issues — regardless of how small the diff is. Even a one-line change is an opportunity to catch issues in the surrounding page. These are tracked separately, never raised as PR comments.
Flag only these categories:
Do NOT flag:
Observations (no ticket, reported separately):
Nothing in Pass 2 blocks the PR. It's all informational for the human reviewer to decide what to act on.
Edge case — renamed/moved files: If the PR renames or moves a file, pre-existing issues will reference a path that doesn't exist yet (before merge) or no longer exists (after merge). In this case, flag the issues in the review output but do not draft a Linear ticket — note that the file is being moved and the issues can be addressed after merge.
Output: Present findings in two groups:
Quality issues (ticket candidates) — grammar, formatting, voice. Draft a Linear ticket preview using the Historical Docs Quality Fixes - PRs project, low priority, with file path and bullet-form issues. Do not create the ticket without the user confirming the preview. Format:
Title: Quality fixes: <page name>
Description:
Pre-existing quality issues found during review of PR #XXXX.
`path/to/file.md`
* Line X: description of issue
* Lines X, Y: description of repeated issue (N occurrences)
* Line X: description of issue
Observations (no ticket) — potential inaccuracies, gaps, or concerns the reviewer should be aware of. Flag them so the human can decide whether to raise with the contributor or investigate further.
These prevent the PR from shipping. The author must address them.
These are real issues but shouldn't block the PR. The author can address them in this PR or a follow-up.
Don't leave comments on these. They create noise and slow down the review.
Every comment should help the author understand what to change and why.
TimestampTime" tells the author what's at stake.When drafting review comments for the user, format each as:
**Line X** (block/suggest): <comment text>
Group by severity — blocks first, then suggestions. End with a one-line summary of your recommendation (approve, approve with suggestions, or request changes).
When drafting Slack messages, PR descriptions, or Linear comments: