Copy Editing skill for Codex
Tighter text that still sounds like the author. Codex agrees an edit level before touching text, builds a style sheet of terms, spelling and number conventions, then makes separate passes for clarity, concision, consistency and correctness. Code, identifiers and quotations stay untouched, anything that could change technical meaning becomes an author query, and changes come back as a word-level diff you can review.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- copy-editing Installs to ~/.agents/skills/copy-editing/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install copy-editing The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project copy-editing Installs to .agents/skills/copy-editing/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/copy-editing.zipunzip -o copy-editing.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) copy-editing PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $copy-editing, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Copy-edits existing prose - docs, READMEs, blog drafts, UI text, reports - for clarity, concision, consistency and correctness while preserving the author's meaning and voice. Works in agreed edit levels (light, standard, heavy), builds a style sheet of terms and conventions, runs focused passes, returns a reviewable diff, and raises author queries instead of guessing. Can enforce rules with Vale. Use when asked to proofread, tighten, polish, clean up, make consistent, or cut the length of written text without rewriting what it says.
Use it when
- Finished text needs proofreading, tightening or consistency fixes
- Several authors used different names and spellings for the same thing
- A document must be shortened without changing what it says
Use something else when
- The text needs restructuring or a different argument: use technical-writing
- The audience is non-specialist and the reading level must drop: use plain-language
- You need to create the house style rules themselves: use style-guide-creation
How to check the result
Five sampled changes keep the original meaning, style sheet terms are applied everywhere, code blocks are byte-identical, and Vale shows no new alerts.
The mistake it prevents
Tightening a sentence in a way that quietly changes a technical claim, such as turning 'at least' into 'exactly' or 'must' into 'should'.
A copy edit is done when the text says exactly what the author meant in fewer, clearer words, the same thing is named the same way everywhere, there are no errors of grammar, spelling, fact or formatting, and every change can be reviewed and reverted. The author should recognise their own voice.
Agree the edit level first
| Level | Changes | Does not change | Typical length cut |
|---|---|---|---|
| Light (proofread) | Spelling, grammar, punctuation, typos, broken formatting | Wording that is correct, structure | 0-5% |
| Standard (copy edit) | Above + wordiness, unclear sentences, terminology, consistency, house style | Order of sections, argument, voice | 10-20% |
| Heavy (line edit) | Above + sentence restructuring, paragraph order within sections, cuts of redundant passages | The overall argument, facts, conclusions | 20-40% |
If the user just says “polish this”, default to standard and say so. Restructuring a
whole document or changing its argument is not copy editing; propose it as a separate
step (see $technical-writing).
Inspect first
- Read
AGENTS.md, anySTYLE.md,docs/style-guide.md,.vale.iniand Vale styles in the repo. The house style wins over your preferences. - Determine the spelling variant (US or UK) and heading case from the existing text if no guide says so. Do not switch it.
- Read the whole piece once before changing anything. Note the purpose, reader and voice.
Workflow
- [ ] 1. Confirm the edit level and any house style
- [ ] 2. Read the full text once without editing; note purpose and voice
- [ ] 3. Build the style sheet (terms, spelling, capitalisation, numbers, formatting)
- [ ] 4. Pass 1: clarity (sentences a reader would misread or reread)
- [ ] 5. Pass 2: concision (cut words that carry no meaning)
- [ ] 6. Pass 3: consistency (apply the style sheet everywhere)
- [ ] 7. Pass 4: correctness (grammar, spelling, punctuation, links, numbers, code refs)
- [ ] 8. Produce the diff, the change summary and author queries
Separate passes catch more than one combined read, because each pass looks for one kind of problem.
Style sheet
Build it as you go and include it in the output; it is how consistency survives later edits.
| Item | Decision | Notes |
|---|---|---|
| Spelling | US (color, canceled) | matches 90% of existing text |
| Product name | Acme Cloud (not AcmeCloud, ACME cloud) | per website footer |
| "sign in" / "log in" | sign in (verb), sign-in (noun/adj) | UI uses Sign in |
| Headings | Sentence case | |
| Numbers | Numerals for 10+, units with a space (5 MB) | |
| Code terms | `config.yaml`, `--dry-run` in code format | |
| Lists | No terminal periods unless items are full sentences | |
| Oxford comma | Yes | |
Clarity and concision fixes
| Pattern | Before | After |
|---|---|---|
| Wordy phrase | in order to, due to the fact that, at this point in time | to, because, now |
| Hidden verb (nominalisation) | perform an installation of | install |
| Empty opener | It should be noted that the cache… | The cache… |
| Weak there-is | There are three flags that control… | Three flags control… |
| Redundant pair | each and every, final outcome, completely eliminate | each, outcome, eliminate |
| Unnamed actor | The file is then parsed. | The loader then parses the file. |
| Vague intensifier | very important, really fast, quite large | Delete, or quantify |
| Stacked nouns | user account permission error message text | the text of the error shown when a user lacks permission |
| Ambiguous pronoun | It fails when it is empty. | The import fails when the CSV is empty. |
| Long sentence (>30 words) with two ideas | …and also… | Split into two sentences |
| Hedge pile | may possibly help to somewhat reduce | reduces (if true) |
Delete on sight in technical text: “simply”, “just”, “easily”, “obviously”, “of course”, “basically”, “actually”. They add nothing or imply the reader is slow.
What not to touch
- Code blocks, commands, identifiers, error strings, quoted output and API names. Fix surrounding prose only; if code looks wrong, raise a query.
- Technical meaning. If tightening a sentence could change what it claims (“must” vs “should”, “all” vs “most”, “at least” vs “exactly”), keep it and query.
- Direct quotations, legal text, and text the author marked as fixed.
- Deliberate voice: humour, first person, short punchy fragments in a blog post.
- Correct but different-from-your-taste choices (serial comma, “data is” vs “data are”) that the house style already settles.
Author queries
When the fix depends on knowledge you do not have, do not guess. Add a query:
Q1 (line 42): "requests time out after 30 seconds" but the table on line 88 says 60. Which is correct?
Q2 (line 57): "the old endpoint" - which endpoint? Suggest naming it: `/v1/export`.
Q3 (line 103): sentence can read as "all users" or "all admin users". Intended scope?
Tooling
Vale enforces style rules mechanically and is worth running before and after:
vale --output=line docs/page.md # one alert per line
vale --minAlertLevel=warning docs/ # skip suggestions
If the repo has no Vale setup and the user wants one, start from a packaged style
(Packages = Google or Microsoft in .vale.ini, then vale sync, which needs
network) plus a project vocabulary file. Treat Vale output as hints; it cannot judge
meaning.
Spelling: npx cspell "docs/**/*.md" if the project uses cspell; add real project terms
to its dictionary instead of ignoring them inline.
Output
Return changes in a reviewable form, never a silently rewritten file:
- For files in a repo: edit in place and show
git diff --word-diffso the user reviews word-level changes. Keep unrelated formatting (line wrapping) unchanged to keep the diff small. - For pasted text: return the edited text, then a change summary.
**Edit level:** standard (confirmed)
**Length:** 1,920 -> 1,540 words (-20%)
**Main changes:** cut 14 wordy phrases; unified "workspace" (was also "project", "space"); split 9 sentences over 35 words; fixed 6 typos and 2 broken links
**Style sheet:** attached (12 entries)
**Untouched by design:** code blocks, CLI output, quoted error messages
**Author queries:** 3 (timeout value conflict, unnamed endpoint, scope of "all users")
Gotchas
- Rewrapping every line of a Markdown file so the diff becomes unreviewable.
- “Fixing” a technical term into a common word (a “lease” is not a “lock”).
- Changing spelling variant halfway through because one paragraph used the other.
- Cutting the only sentence that explains why, because it looked like filler.
- Applying title case or sentence case to product and UI labels that must match the interface exactly.
- Editing text inside screenshots’ captions so it no longer matches the screenshot.
Verification
- Reread the edited text in full once, start to finish, for flow; passes can create choppy transitions.
- Spot-check five changes against the original: meaning unchanged in each.
- Style sheet decisions applied everywhere:
rg -n -i "log in|login|log-in" docs/etc. - Vale (if configured) shows no new alerts compared with the original.
- Links and anchors still resolve; code blocks byte-identical to the original
(compare with
git difflimited to fenced regions, or eyeball the diff).
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Copy Editing"
short_description: "Tighter text that still sounds like the author"
default_prompt: "$copy-editing Proofread this README and fix typos without changing the wording" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.