agentleFS
robritacca-dotcomrobritacca-dotcom/rift-ds/.claude/skills/content-audit/SKILL.md

content-audit

Skill9 starsChanged 7 days agoMITView on GitHub

Audit prose against content-design.md for AI-writing tells, voice violations, and register mismatches. Use when asked to audit copy, check content quality, review prose for AI slop, or check writing against the content guide.

25 other projects use a version of this, 1 of them edited.

Adopted by

Most recently taken up by

Used with

Projects with it also use asset-spec, create-control-manifest and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • lilangMaxSkill

    asset-spec

    Generate per-asset visual specifications and AI generation prompts from GDDs, level docs, or character profiles. Produces structured spec files and updates the master asset manifest. Run after art bible and GDD/level design are approved, before production begins.

    Also in 10 projects that use this

  • lilangMaxSkill

    create-control-manifest

    After architecture is complete, produces a flat actionable rules sheet for programmers — what you must do, what you must never do, per system and per layer. Extracted from all Accepted ADRs, technical preferences, and engine reference docs. More immediately actionable than ADRs (which explain why).

    Also in 10 projects that use this

  • +10 more from lilangMax

The file

We split this skill into the rules it gives an agent

3 rules. 0 are common, 3 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 24 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when asked to audit copy, check prose quality, find AI-writing tells, or review text against the content guide — phrases …

    line 15
  2. Distinctive:

    If nothing is found: "No content violations found.

    line 77
  3. Distinctive:

    Run the guide's Self-Review Tests over the longest passage in scope and report the result, pass or fail

    line 78

“Common” is measured: kept by at least 6 in 10 of the 24 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

content-audit

Audit prose against content-design.md, and report violations with suggested rewrites.

When invoked

Use this skill when asked to audit copy, check prose quality, find AI-writing tells, or review text against the content guide — phrases like "content audit", "audit the copy on the homepage", "does this read like AI", "check this against content-design.md".

Instructions

  1. Determine scope. Accept one of:
    • A specific file path (a page, a data file, a markdown doc)
    • release-log → website/src/data/release-log.json (titles + story bodies, plus the predecessor versions' one-line summaries)
    • registry → the description fields in src/components/registry.json, and the chat widget's description and per-subpath strings in src/chat/registry.json (rendered on its component page and served by MCP)
    • package-meta → the npm package description: PACKAGE_DESCRIPTION in scripts/package-manifest.mjs, mirrored into the root package.json (renders on the npmjs.com package page — its register row calls it production copy at the README's bar; no validator judges its prose, and the readme scope never reaches it)
    • corpus-prose → the hand-written connective paragraphs inside scripts/generate-site-corpus.mjs (the chat model can repeat any of them verbatim to a visitor — its register row holds them to the page-prose bar; the corpus validators screen for leaks, never for voice, so the judgement rules stay this scope's. Fix the generator's strings, never the generated file)
    • readme → README.md prose plus src/stories/Configure.mdx. README's marked regions (the doc block of scripts/generate-readme-content.mjs owns the list) are generated by scripts/generate-readme-content.mjs (the component regions from src/components/registry.json, the rest from scripts/brand.mjs) — a rewrite inside them silently reverts on the next build, so fix the source instead (component copy through the registry scope); the /blueprints page copies under website/public/ are generated too (synced from the root specs by scripts/sync-blueprints.mjs on every build), so edit the root file, never the copy
    • skills → the displayDescription frontmatter strings and the invoke phrase lists across .claude/skills/ (both render on /skills — the descriptions as card copy, the invoke phrases as visible chips — so both are published copy; skill instruction bodies are out of scope)
    • website → user-visible strings in website/src/app/** page files; a page slug (e.g. overview) scopes to that page folder
    • chat → the chat's shipped prose, in two layers. The package's (src/chat/, shipped to every consumer): the greeting fragments in greeting.ts, the default tagline, disclaimer, locked-model line, the composer's placeholder while a question set holds it (questionsPlaceholder) and the Chat position menu's label inline in ChatWidget.tsx, that menu's row labels in placement.ts, the placeholder replies in useChat.ts, the transport's failure lines in transport.ts, the package's fallback follow-up pool in followups.ts, the handlers' default notices, the follow-ups prompt, the ask_user tool's description and its error line, and the questions intro line in server.ts, the ask_user schema's field descriptions in questions.ts (read by the model, so the tool-copy register applies), QuestionCard's default labels in src/components/QuestionCard/QuestionCard.tsx, ActionCard's default labels in src/components/ActionCard/ActionCard.tsx, the starters prompt (startersSystemPrompt in server.ts), the model-facing lines skippedText and confirmationLine write in actions.ts and selectionLines writes in selectionContext.ts (the tool-copy register applies), the guardrail notices in upstash.ts, and the demo's staged copy — the turns, chip labels and question prompts and options in demo-script.ts, the fixtures in demo-fixtures.ts, the welcome fillings in DemoWelcome.tsx, the agent panes in demo-agent-panes.tsx and their empty-state lines in demo-agent.tsx, the artifact panel's empty state in ChatArtifactPane.tsx and the demo's two artifacts in demo-artifacts.tsx (the framed page's own copy included), and the scripted transport's own fallback replies in sim.ts. The site's (its configuration of the package): the component-page and fallback starter pools in website/src/components/SiteChat/starters.ts (each static page's own pool lives in page-summaries.json, the page-summaries scope) and the written follow-up fallbacks in website/src/lib/chat-followups.ts (chip length is build-covered by scripts/validate-chat-starters.mjs; register, voice and banned words stay this scope's), the site's tagline, disclaimer and placeholder in website/src/components/SiteChat/useSiteWidgetProps.tsx, the highlight notes in website/src/components/SiteChat/siteFocus.tsx, the merchant sales assistant's persona and tool copy in website/src/app/api/merchant-chat/route.ts, the model names and one-line descriptions in website/src/lib/chat-model.ts (rendered in the composer's picker; unscanned by any validator), the persona strings in website/src/app/api/chat/persona.ts, the tool descriptions, trace points and notice copy in website/src/app/api/chat/route.ts, the guardrail notice copy in website/src/app/api/chat/guardrails.ts (all visitor-visible; the guardrail notices' register row is content-design.md's — say what happened and what to do next, never blame the visitor), the event-rail copy in website/src/app/playground/ChatDirector.tsx, and the view modules under website/src/app/playground/views/ (TypeView's tier notes and labels). The em-dash half is split: scripts/validate-shipped-prose.mjs build-scans the story and handler modules' string literals (STORY_MODULES is its list), so this scope's em-dash job there is done by the build — but the widget's inline strings and the persona stay unscanned, and every judgement-level rule (register, voice, banned words) stays this scope's across all of it
    • footer → the sitemap footer's shipped copy: the column titles and the bottom row's copyright and author credit in website/src/components/SiteFooter/SiteFooter.tsx, and the link labels in website/src/config/social.ts (the credited name and its URL are AUTHOR_NAME/AUTHOR_URL in scripts/brand.mjs — audit the sentence around them, never the values) (visible on every non-chromeless page, but outside app/**, so the website scope misses them — the same gap the chat scope closes for the panel)
    • palette → the command palette's shipped copy: the group labels, per-item descriptions, the ask-chat row's trailing chip label and the search placeholder in website/src/components/SitePalette/ (reachable from every non-chromeless page, but outside app/**, so the website scope misses it — the same gap the chat and footer scopes close for theirs; no validator scans it). The ask-chat row's label is the visitor's own typed query — unauthored by design, never a finding — but its trailing chip ("Ask <ASSISTANT_NAME>" — ASSISTANT_NAME in scripts/brand.mjs owns the name) is authored copy in scope; the empty state is unreachable (the ask row matches every query), so there is none to audit
    • nav → the navigation config's shipped copy: the section and link descriptions, group labels and the mega showcase card's overline, title and description in website/src/config/navigation.ts (rendered in the mega panel, the sidebars, the footer's derived columns and the home and DS-landing cards — outside app/**, so the website scope misses it, the same gap the chat, footer and palette scopes close for theirs; no validator scans it)
    • agent-skill → the consumer agent skills' instructional prose, the manifest's one-line summaries and the agent starter's prose (assembleAgentStarter(), published as website/public/AGENTS.md), all hand-written inside scripts/generate-agent-skill.mjs (their register row is in the guide's table). The published folders under website/public/skill/ (AGENT_SKILLS in scripts/brand.mjs owns the names) are generated and byte-compared, so fix the generator, never the files; scripts/validate-agent-skill.mjs build-covers the em-dash ban there, and register, voice and banned words stay this scope's. The reference tables (the component catalogue, the token reference) derive from registry data and are not prose to audit, and the sibling surface, the per-component .md pages, deliberately has no scope for the same reason
    • theme-export → the playground theme export's shipped copy: the themed AGENTS.md's theme section and the THEME.md and agent prompt templates in website/src/lib/theme/theme-export.ts (the AGENTS.md's other sections are the agent starter, the agent-skill scope's), the From the source section's fit lines and traits (the DESIGN.md match report's row notes and the trait texts in website/src/lib/theme/design-md.ts, which ship in the export whenever the theme came from a file), the export dialog's description in website/src/app/playground/ExportThemeDialog.tsx, and the lever words in LEVER_VOCABULARY in website/src/lib/theme/theme-overrides.ts, which the rail prints beside each slider and THEME.md uses to describe the look (a visitor carries the exported files into their own repo, but all of it lives in lib/ modules and a component file, so the website scope's page scan never reaches it, and /playground is chromeless and outside the corpus, so no corpus check does either). scripts/validate-theme-export.mjs build-covers the token names the templates use, the band ranges, the colours the prose names (held to the ones the exported CSS draws) and the From the source section over a fixture, scripts/validate-design-md-import.mjs holds every report note and trait line free of em dashes, and scripts/validate-shipped-prose.mjs's module scan build-covers the em-dash ban in all three files; register, voice and banned words stay this scope's. Their register row is the guide's Playground theme export entry: imperative and addressed to the reader's coding agent in the templates, declarative in the dialog description, and one plain word per band in the vocabulary
    • cli → the package init bin's terminal output: the usage block, error lines, the deprecation line and success lines in src/cli/init.mjs (prints in a consumer's terminal, so it is shipped copy; the em-dash half is build-covered through validate-shipped-prose.mjs's module scan, and its register row in the guide holds errors to the Microcopy standard — what happened, then what to do next), plus the scaffold templates the init subcommands write into a consumer's project, every folder under src/cli/templates/ (init chat's, init app's and init block's; the block comments at the top of each file and the widget's placeholder title, tagline and disclaimer; read as instructions in a stranger's repository, so every path and env name is checked against the files that exist — scripts/validate-chat-widget.mjs holds the chat scaffold's file and env names to the docs page and every template's imports to the package, scripts/validate-blocks.mjs the blocks' files to their registry, nothing holds the comments — and no validator scans them for em dashes)
    • page-summaries → the FAB panel's per-page TLDR copy: the title, text, chip labels and starters labels in website/src/data/page-summaries.json (routes and essays maps — the essays map is empty by design, since this site has no essays feature — rendered to every visitor on the chat FAB's summary panel, but a data file outside app/**, so the website scope misses it, the same gap the footer scope closes for its copy). scripts/validate-page-summaries.mjs build-covers length, the full stop and the em-dash ban; register, voice and banned words stay this scope's — its register row lives in the guide's table
    • loops → the loops registry's shipped copy: the description, cadence, trigger, stages and guardrails strings in website/src/data/loops.json (rendered verbatim as the /loops cards and embedded in the chat corpus, but a data file outside app/**, so the website scope misses it — the same gap the page-summaries scope closes for its copy). scripts/validate-loops.mjs build-covers structure and scripts/validate-shipped-prose.mjs the em-dash ban; register, voice and banned words stay this scope's — its register row lives in the guide's table
    • schemas → the hand-written prose in the meta-schemas at the top of website/public/schema/ (title, description, $comment) and the $description strings scripts/generate-token-values.mjs writes into the DTCG files (content-design.md's Schema prose row owns the register)
    • mcp → the agent-facing routes' shipped copy: the tool blurbs and example prompts in website/src/lib/mcp-tools.ts, the connect snippets in website/src/lib/mcp-clients.ts, the server instructions and browser landing page in website/src/app/api/mcp/route.ts, the shared tool implementations' error and hint strings in website/src/lib/site-tools.ts (read by agents over MCP and repeated by the chat model to visitors), the CHAT_TOOLS descriptions in website/src/app/api/chat/route.ts (read by the model choosing a tool), and the /llms.txt section intros in website/src/app/llms.txt/route.ts (route handlers and lib/ modules, not page files, so the website scope misses all of them — scripts/validate-mcp-tools.mjs holds the roster to the registered tools but judges no prose; their register rows live in the guide's table)
    • stage → the immersive stages' floating chrome: the toolbar labels and tooltips in website/src/components/StageToolbar/, the control-bar labels in website/src/components/StageControlBar/, inspect mode's labels and pin/release states in website/src/components/InspectMode/, the playground's theme-source import (the dropzone and source cards in website/src/app/playground/ and the DESIGN.md match report's row notes and the trait list under it in website/src/lib/theme/design-md.ts, all four in validate-shipped-prose.mjs's module scan), and the graph instrument's panel and caption copy in website/src/components/SystemGraph/ — whose column labels ship from scripts/generate-dependency-graph.mjs, so fix the generator's strings, never dependency-graph.generated.ts (all rendered on the chromeless stage routes, so the chat/footer/palette scopes never reach them, and outside app/**, so the website scope misses them too — the same gap those scopes close for theirs; scripts/validate-shipped-prose.mjs scans the two SystemGraph modules for the em-dash ban, and otherwise no validator scans any of them). Their register row is the guide's Immersive stage copy entry, with the Microcopy section as the label-style standard
  2. Read content-design.md first — it is the only rule source. The Words to Avoid and Patterns to Avoid tables, the Voice rules, the Register by Surface table, and the Microcopy section are the checklist. This skill deliberately maintains no word list and no pattern list of its own: when the guide changes, the audit changes with it. If a rule seems missing, the fix is an entry in content-design.md (per its Iteration Guide), never a rule added here.
  3. Scan the scoped prose and classify every finding at one of three severities:

    Banned (the guide allows no use in shipped copy):

    • Hard-ban words and phrases from the Words to Avoid table
    • Em dashes anywhere in shipped copy. scripts/validate-shipped-prose.mjs already fails the build on these, so a clean tree means the surfaces it reads are clear and you are checking the ones it cannot judge: the chat's persona and greeting strings, and any prose outside its scope (its doc block is authoritative). Report a hit there as Banned exactly as before
    • Title Case in shipped headings, buttons, or labels
    • First person in surfaces whose register says "None" (check the Register by Surface table for the scoped surface)
    • Emoji, exclamation marks in UI copy, unsourced statistics

    Rationed (legitimate in a narrow sense; flag for a density check):

    • Words from the Rationed table — flag every use, note which look literal, and count per page
    • American spellings in prose (colour/color and friends) — never flag code identifiers, token names, CSS properties, or file paths

    Judgment (needs a reader, not a regex — quote the passage and say why):

    • Rhythm uniformity: three or more similar-length sentences in a row
    • Rule-of-three adjective stacks, copula avoidance, participial tails, negative parallelism, hedge stacking, elegant variation, bolded-label bullets, summary closers, throat-clearing openers
    • Register mismatches: promotional tone in a neutral surface, a tagline restating its section name, an empty state describing absence instead of the next action
  4. Never flag:
    • content-design.md itself, and quoted examples anywhere (a rule must be able to name what it bans)
    • Skill instruction bodies, design.md, CLAUDE.md — agent-facing references, out of scope by design (see the guide's Overview)
    • Code, identifiers, token names, class names, and anything inside backticks or code fences
    • Text authored by third parties (external-skill copies keep their upstream voice)
    • The labs rebuilds under website/src/app/labs/** and the template screens under website/src/components/templates/** (served under /templates/<slug>, whether or not they began in labs) — their copy is fictional demo data staging a product screen, excluded from the chat corpus for the same reason, so register and voice rules do not apply to it. The /templates index page's own prose is ordinary page copy and stays in scope
  5. For each finding, output:

    • File path (repo-relative) and line number, or the entry label for JSON surfaces
    • Severity, the offending text, and the guide rule it breaks
    • A suggested rewrite that keeps the sentence's meaning and any links intact

    Format: website/src/app/example/page.tsx:42 — banned — "a seamless theming journey" → "theming by overriding one primitive"

  6. Summarise at the end:
    • Counts per severity, then the strongest single finding
    • If nothing is found: "No content violations found. Prose follows content-design.md."
    • Run the guide's Self-Review Tests over the longest passage in scope and report the result, pass or fail

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.