Write or review technical prose — markdown documentation, wiki pages, README or config comments. USE FOR: explaining a contract, behavior, decision, or API in human-readable text, and reviewing that prose says something a reader cannot already infer. DO NOT USE FOR: C# code comments (use csharp-style), or C# XML documentation comments (use writing-xml-doc-comments).
Write to an enterprise production standard in a strict technical register, never a tutorial or a marketing voice.
Open with the fact the reader needs, describe observable behavior, and cut anything a reader can already infer.
When to use
Writing or reviewing any markdown in a repository.
Writing the body of an issue, a pull request, or a comment on one.
Reviewing a text that reads as a narration of the change instead of a statement of the result.
Writing or reviewing a comment that annotates a declaration, a key, or a block of a configuration file.
Rules
Use plain technical English and the third-person present indicative in reference prose.
Write one sentence per line, and keep one idea per sentence.
Ignore the line length; a sentence occupies one line however long it runs, and no line is wrapped by hand.
The IDE reflows the file to the limits configured for it.
Use a heading that names its subject, with a colon where the heading introduces a variant or a qualifier.
Use a list only where the reader acts on, compares, or remembers several items.
Use a table where several items share the same set of attributes.
State a negative only where a competent reader would otherwise make a plausible, harmful assumption.
Link the maintained list of identifiers, endpoints, or values; never copy it.
State no count and no enumeration the neighbouring source already carries: the rows of a table, the members of a list below, the files a directory holds.
The reader takes them from the source, and a restatement falls out of date on the change that adds one.
Avoid corporate language, filler, meta-preambles, and trailing including… examples.
Comment the intent, the constraint, or the invariant a file cannot state itself; add none where the file already states it.
A declaration carries its own meaning through its name, and a comment stands only where a competent reader draws a wrong conclusion without one.
A comment never restates the name, the value, or the block it stands above.
Judge every sentence as final standalone text.
The reader has the page as it stands, with no previous version, diff, or request to compare against.
Cut every purpose, result, cause, and comparison clause: so, that makes, which makes, because, rather than.
A clause carrying a fact the reader needs becomes its own sentence.
Name an operation with the term its own domain defines.
Attribute no intent, no perception, and no motion to a component: it does not ask, answer, want, know, or decide, and a value does not travel.
Examples
<!-- BAD -->
This page describes external events. We added them because the API is not reachable from a modeless window, which makes a direct call fragile, so a queue was introduced to solve the problem.
<!-- GOOD -->
An external event carries a unit of work into the Revit API context.
A caller constructs the event and raises it from any thread, and Revit invokes the handler inside the API context.
An external event opens no transaction; the handler opens its own.
<!-- BAD -->
The view model asks the repository for the open document and answers the command with the result.
The binding wants a source that is not null, and the validator decides whether the entry is valid.
An event travels to every subscriber.
<!-- GOOD -->
The view model requests the open document from the repository and returns the result to the command.
The binding requires a source that is not null, and the validator reports whether the entry is valid.
An event reaches every subscriber.
A comment on a declaration names the role that declaration holds in the whole system, or the invariant behind a value.
# BAD
# The catalogue viewer, a second process of the frontend group on a port of its own, declared in this same file.
# The internal gateway alone carries this route, and every public gateway resolves the frontend on its plain port, so no public host reaches it.
component "catalogue" {
# GOOD
# The gateway of the public applications and of the internal-only endpoints.
component "gateway" {
# GOOD
# The cache every service of the environment shares.
component "cache" {
# BAD
# The instance count, two in production and one everywhere else.
instances = environment == "production" ? 2 : 1
# GOOD
# The second instance holds the route open while a rolling replacement takes the first.
instances = environment == "production" ? 2 : 1
Review
The text describes behavior, not implementation mechanics.
Prose follows one-sentence-per-line formatting, and no line is wrapped at a column limit.
Every sentence states a fact in the present indicative, and none narrates the change or argues why.
No list of constants, endpoints, or options is copied where the authoritative source can be linked.
No sentence states a count or an enumeration the neighbouring source carries.
The first sentence of a section carries information the heading does not.
Every comment states what its file cannot, and none restates the name, the value, or the block below it.
Every commented declaration is one a reader would otherwise misread, and the rest carry no comment.
No component asks, answers, wants, knows, or decides, and no value travels; every operation carries the term its domain defines.
Common Pitfalls
Pitfall
Correct approach
A preamble before the point ("This section describes…")
Lead with the fact the reader needs.
Copying a list of constants or endpoints into prose
Link the authoritative source.
A count or an enumeration the source beside it carries
Point at the source; the reader reads it there.
Restating the heading in the first sentence
Add new information.
Documenting how the code works today
Document the observable contract.
Narrating the edit ("renamed X to Y because…")
State what the code now is.
A rationale clause ("… so …", "… that makes …", "rather than")
State each fact in its own present-indicative sentence.
A component that asks, answers, wants, knows, or decides
Name the operation its domain defines.
A paragraph promising work still to come
Leave a // TODO: in the code at the place it belongs.
A paragraph hard-wrapped at 80 or 120 characters
One sentence, one line, whatever its length.
A comment naming the key it stands above
State the constraint the key carries.
A comment paraphrasing the block it opens
Drop it; the block states itself.
A comment pointing at the file it lives in
State the role the declaration holds in the system.
A comment above every declaration of a file
Comment the one declaration a reader misreads.
A name that needs a comment to be understood
Rename the declaration.
1---2name: technical-writing3description: Write or review technical prose — markdown documentation, wiki pages, README or config comments. USE FOR: explaining a contract, behavior, decision, or API in human-readable text, and reviewing that prose says something a reader cannot already infer. DO NOT USE FOR: C# code comments (use csharp-style), or C# XML documentation comments (use writing-xml-doc-comments).4license: MIT5---67# Technical Writing89Write to an enterprise production standard in a strict technical register, never a tutorial or a marketing voice.10Open with the fact the reader needs, describe observable behavior, and cut anything a reader can already infer.1112## When to use1314- Writing or reviewing any markdown in a repository.15- Writing the body of an issue, a pull request, or a comment on one.16- Reviewing a text that reads as a narration of the change instead of a statement of the result.17- Writing or reviewing a comment that annotates a declaration, a key, or a block of a configuration file.1819## Rules2021- Use plain technical English and the third-person present indicative in reference prose.22- Write one sentence per line, and keep one idea per sentence.23- Ignore the line length; a sentence occupies one line however long it runs, and no line is wrapped by hand.24 The IDE reflows the file to the limits configured for it.25- Use a heading that names its subject, with a colon where the heading introduces a variant or a qualifier.26- Use a list only where the reader acts on, compares, or remembers several items.27- Use a table where several items share the same set of attributes.28- State a negative only where a competent reader would otherwise make a plausible, harmful assumption.29- Link the maintained list of identifiers, endpoints, or values; never copy it.30- State no count and no enumeration the neighbouring source already carries: the rows of a table, the members of a list below, the files a directory holds.31 The reader takes them from the source, and a restatement falls out of date on the change that adds one.32- Avoid corporate language, filler, meta-preambles, and trailing `including…` examples.33- Comment the intent, the constraint, or the invariant a file cannot state itself; add none where the file already states it.34 A declaration carries its own meaning through its name, and a comment stands only where a competent reader draws a wrong conclusion without one.35 A comment never restates the name, the value, or the block it stands above.36- Judge every sentence as final standalone text.37 The reader has the page as it stands, with no previous version, diff, or request to compare against.38- Cut every purpose, result, cause, and comparison clause: `so`, `that makes`, `which makes`, `because`, `rather than`.39 A clause carrying a fact the reader needs becomes its own sentence.40- Name an operation with the term its own domain defines.41 Attribute no intent, no perception, and no motion to a component: it does not ask, answer, want, know, or decide, and a value does not travel.4243## Examples4445```markdown46<!-- BAD -->47This page describes external events. We added them because the API is not reachable from a modeless window, which makes a direct call fragile, so a queue was introduced to solve the problem.4849<!-- GOOD -->50An external event carries a unit of work into the Revit API context.51A caller constructs the event and raises it from any thread, and Revit invokes the handler inside the API context.52An external event opens no transaction; the handler opens its own.53```5455```markdown56<!-- BAD -->57The view model asks the repository for the open document and answers the command with the result.58The binding wants a source that is not null, and the validator decides whether the entry is valid.59An event travels to every subscriber.6061<!-- GOOD -->62The view model requests the open document from the repository and returns the result to the command.63The binding requires a source that is not null, and the validator reports whether the entry is valid.64An event reaches every subscriber.65```6667A comment on a declaration names the role that declaration holds in the whole system, or the invariant behind a value.6869```text70# BAD71# The catalogue viewer, a second process of the frontend group on a port of its own, declared in this same file.72# The internal gateway alone carries this route, and every public gateway resolves the frontend on its plain port, so no public host reaches it.73component "catalogue" {7475# GOOD76# The gateway of the public applications and of the internal-only endpoints.77component "gateway" {7879# GOOD80# The cache every service of the environment shares.81component "cache" {82```8384```text85# BAD86# The instance count, two in production and one everywhere else.87instances = environment == "production" ? 2 : 18889# GOOD90# The second instance holds the route open while a rolling replacement takes the first.91instances = environment == "production" ? 2 : 192```9394## Review9596- [ ] The text describes behavior, not implementation mechanics.97- [ ] Prose follows one-sentence-per-line formatting, and no line is wrapped at a column limit.98- [ ] Every sentence states a fact in the present indicative, and none narrates the change or argues why.99- [ ] No list of constants, endpoints, or options is copied where the authoritative source can be linked.100- [ ] No sentence states a count or an enumeration the neighbouring source carries.101- [ ] The first sentence of a section carries information the heading does not.102- [ ] Every comment states what its file cannot, and none restates the name, the value, or the block below it.103- [ ] Every commented declaration is one a reader would otherwise misread, and the rest carry no comment.104- [ ] No component asks, answers, wants, knows, or decides, and no value travels; every operation carries the term its domain defines.105106## Common Pitfalls107108| Pitfall | Correct approach |109|----------------------------------------------------------------|---------------------------------------------------------|110| A preamble before the point ("This section describes…") | Lead with the fact the reader needs. |111| Copying a list of constants or endpoints into prose | Link the authoritative source. |112| A count or an enumeration the source beside it carries | Point at the source; the reader reads it there. |113| Restating the heading in the first sentence | Add new information. |114| Documenting how the code works today | Document the observable contract. |115| Narrating the edit ("renamed X to Y because…") | State what the code now is. |116| A rationale clause ("… so …", "… that makes …", "rather than") | State each fact in its own present-indicative sentence. |117| A component that asks, answers, wants, knows, or decides | Name the operation its domain defines. |118| A paragraph promising work still to come | Leave a `// TODO:` in the code at the place it belongs. |119| A paragraph hard-wrapped at 80 or 120 characters | One sentence, one line, whatever its length. |120| A comment naming the key it stands above | State the constraint the key carries. |121| A comment paraphrasing the block it opens | Drop it; the block states itself. |122| A comment pointing at the file it lives in | State the role the declaration holds in the system. |123| A comment above every declaration of a file | Comment the one declaration a reader misreads. |124| A name that needs a comment to be understood | Rename the declaration. |
Run npx skillmds@latest add nice3point/technical-writing in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Write or review technical prose — markdown documentation, wiki pages, README or config comments. USE FOR: explaining a contract, behavior, decision, or API in human-readable text, and reviewing that prose says something a reader cannot already infer. DO NOT USE FOR: C# code comments (use csharp-style), or C# XML documentation comments (use writing-xml-doc-comments). It is listed under Docs & Writing on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
nice3point (@nice3point) published this skill. Their other Agent Skills are listed on their SkillMD profile.