Files of Procedures and code
wondelai/
Show the full text250 lines
Procedures and Code
This file owns P1–P11: step-by-step instructions, UI verbs, code in prose, code samples, placeholders, and command-line syntax. W1 (condition before instruction) belongs to voice-and-words.md; S12 (the bold/code-font/italics summary) belongs to structure-and-formatting.md; A1–A7 (API reference text, docstrings) belong to api-reference.md — mentioned here only where a procedure or sample touches them.
1. Anatomy of a Procedure (P1–P4)
A procedure exists to get one reader from a starting state to a finished one. Every step names a single imperative action, states or implies where to act, and lets the reader confirm what happened before moving on.
Rules:
- P1 — Numbered steps, one action each. Split "click X and then configure Y" into two steps. If a step has two actions, the reader can't tell which one failed.
- Condition before instruction (W1, owned by voice-and-words.md). "If you want X, do Y" — not "Do Y if you want X." The reader decides whether the step applies before reading how to do it.
- P4 — Where to act, what to expect. Name the screen, menu, or file the action happens in, and state the observable result: a new status, a redirect, a file on disk.
- P3 — "Optional:" prefix. Not "(Optional)", not "You can also…" — the word "Optional:" at the start of the step, so a scanning reader can skip it without reading the rest.
- P2 — Single step = bullet. A procedure with exactly one action is a bullet (
*or-), never "1." — a numbered list of one implies steps 2 and 3 are coming. - P2 — Sub-steps a/b/c, then i/ii/iii. Use letters for a sub-sequence inside a numbered step; drop to roman numerals only when a lettered sub-step itself has to branch — for example, by operating system. Don't add a third level to document a style preference.
- Document the shortest path. When the UI and the CLI both accomplish the task, pick one and mention the other in a single sentence, not as a parallel procedure.
Before:
To turn on automatic deployments, you should first go to the project
settings and look for the Deployments tab, then enable it, and after
that you can pick which branch you want it to watch. You should also
set a build command if you have one, and once you're done you can
save it, and it will deploy automatically from then on when you push
to that branch.
After:
1. In the **shipit** console, open your project and click **Settings**.
2. Click **Deployments**.
3. Turn on **Automatic deployments**.
4. Select the branch to watch:
a. Click the **Branch** menu.
b. Choose the branch, for example `main`.
5. Optional: Enter a build command, for example `npm run build`.
6. Click **Save**. The **Status** column shows **Watching** next to
the selected branch.
A step that must branch by platform drops to roman numerals inside the lettered sub-step:
1. Open a terminal.
a. On macOS or Linux, run `chmod +x shipit`.
i. If `shipit` isn't on your `PATH`, move it to `/usr/local/bin`.
ii. If it is, skip to step 2.
b. On Windows, skip this step.
A single-action procedure stays a bullet:
To restart the deployment watcher:
* Click **Restart** in the **Deployments** panel.
Source: procedures
2. UI Elements and Device Verbs (P5)
Rules:
- Bold the element's name, not its type: "Click Save", not "Click the Save button." Name the type only when the label alone is ambiguous ("click the Region dropdown" when a section is also called Region).
- Casing matches the UI, with one exception: an ALL-CAPS label in the interface is written in sentence case in prose. A button rendered
SUBMIT ORDERis still "click Submit order." - Menu paths bold each segment and join with
>: "File > Save as" (inferred — the guide doesn't give this exact notation, but it follows directly from bolding UI element names in sequence). - Device verbs match how the reader is expected to interact with the target, not the writer's own device.
| Verb | Situation | Example |
|---|---|---|
| Click | Mouse or trackpad — buttons, links, checkboxes | "Click Deploy." |
| Tap | Touchscreen — the same targets on mobile or tablet | "Tap Deploy." |
| Select | Device-agnostic — menu items, dropdown options, radio buttons | "Select Production from the Environment menu." |
| Enter | Typing a value into a field | "Enter your project ID." |
| Type | Free-text input where "enter" would also read correctly — the two are interchangeable (inferred) | "Type a description for the release." |
| Choose | Picking one option among several presented together — close in meaning to "select" (inferred) | "Choose a region for the new environment." |
Before → after:
- "Click on the SAVE CHANGES button to save your changes." → "Click Save changes."
- "Go to File, then Export, then click on PDF." → "Click File > Export > PDF."
Source: ui-elements
3. Code in Text (P6)
Gets code font: filenames, paths, commands, flags, parameters, values, method and function names, class names, HTTP status codes, environment variables.
Doesn't: product names, UI labels (those are bold, per P5), and general concepts ("the deploy step," not the deploy step).
Code isn't a part of speech: don't inflect it as a verb or pluralize it by adding a suffix outside the backticks. Add a plain-English noun instead — "call the close method," not "closeing the file"; "Widget objects," not "Widgets."
Before → after:
- "Open the config.yaml file and set the timeout value to 30 seconds." → "Open
config.yamland settimeoutto30." - "Run shipit deploy with the dash-dash-force flag to skip confirmation." → "Run
shipit deploy --forceto skip confirmation." - "The API returns a 404 Not Found if SHIPIT_API_KEY isn't set." → "The API returns
404 Not FoundifSHIPIT_API_KEYisn't set." - "After closing() the file, check for leftover Widgets — the Shipit CLI logs them." → "After you call the
closemethod, check for leftoverWidgetobjects — the shipit CLI logs them." (the method and class stay in code font; the product name doesn't)
Source: code-in-text
4. Code Samples (P7, P10)
Rules:
- P7 — Introduce every sample with a sentence ending in a colon. A bare code block gives the reader no reason to read it and no way to know what it's for.
- One concept per sample. A sample that shows authentication and retry logic in one block forces a reader debugging retries to also parse auth.
- Runnable and minimal. Nothing in the sample should be unrelated to the concept it demonstrates; nothing needed to run it should be missing.
- Realistic names. Production-shaped data, not
foo/bar— a reader pattern-matches against their own variables and data. - Wrap at 80 characters. Long lines force horizontal scrolling in both the doc and the terminal the reader pastes into.
- Show expected output in a second fenced block, immediately after the sample.
- Comments explain why, not what the syntax already says.
- Tag the language on every fence (
```python,```bash) — untagged blocks can't be highlighted or reliably copied (convention).
Before → after (function):
# before — no intro, mixed concepts, foo/bar, no output shown
def foo(bar):
x = bar['data']
result = []
for i in x:
if i['active'] == True and i['score'] > 50 and i['region'] in ['us', 'eu', 'apac']:
result.append(i['name'])
return result
The following function returns the names of active users in a supported region who scored above 50:
SUPPORTED_REGIONS = ("us", "eu", "apac")
def high_scorers(users):
# Scoring only applies in supported regions, so filter first.
return [
user["name"]
for user in users
if user["active"]
and user["score"] > 50
and user["region"] in SUPPORTED_REGIONS
]
>>> high_scorers(users)
['Priya Patel', 'Sam Nguyen']
Before → after (CLI):
To see your deployments just run this: shipit list-deployments --all
--verbose --since=2026-01-01 --until=2026-08-29 --format=json --pretty
| jq '.[] | select(.status=="failed")'
The following command lists deployments that failed since the start of the year:
shipit list-deployments \
--since=2026-01-01 \
--status=failed
DEPLOYMENT BRANCH STATUS FINISHED
d-8f2a1c main failed 2026-03-14T10:02:00Z
Source: code-samples, tech-writing/two "Sample code"
5. Placeholders (P8)
A placeholder stands in for a value the reader supplies. Write it ALL_CAPS_WITH_UNDERSCORES — never <your-api-key> (angle brackets read as literal characters to a reader who doesn't know the convention) and never MY_PROJECT_ID or YOUR_API_KEY (the prefix reads as part of the name). After the sample, list what each placeholder means in a "Replace the following:" block.
Before:
shipit deploy --key=<your-api-key> --project=YOUR_PROJECT_ID
After:
Deploy your project by running the following command:
shipit deploy --key=API_KEY --project=PROJECT_ID
Replace the following:
API_KEY: the key from the project's Settings > API keys page.PROJECT_ID: the project ID shown at the top of the Overview page.
Source: placeholders
6. Command-Line Syntax (P9)
| Notation | Meaning | Example |
|---|---|---|
[optional] |
The argument may be omitted | shipit deploy [--dry-run] |
{a|b} |
Choose exactly one | shipit logs {--tail|--since=DATE} |
... |
The argument repeats | shipit tag ITEM... |
ALL_CAPS |
A placeholder, not a literal | shipit init PROJECT_NAME |
One command per line (convention). Don't chain unrelated commands with && in a sample unless the sample's stated purpose is to show chaining.
Long commands wrap with \ continuation, one flag per line, as in the CLI sample in section 4.
Prompt characters. Whether to show a leading $ isn't specified in the guide (convention): this skill's default is to omit it — the fenced ```bash tag already marks the block as a shell command, and a bare $ gets pasted verbatim by readers who don't know to drop it. Follow a project's existing samples if they already include $ — local convention wins (see SKILL.md's precedence rule).
Filenames written inside docs — sample config files, script names — are lowercase, hyphenated, ASCII:
- "See Getting_Started.MD for setup instructions." → "See
getting-started.mdfor setup instructions."
Source: code-syntax, filenames
7. Sample-Code Quality Checklist (P10)
| Check | Why | Example fix |
|---|---|---|
| Language tag on every fence | Without it, editors and readers can't syntax-highlight or copy cleanly | ``` → ```python |
| Lines wrap at 80 characters | Long lines force horizontal scrolling in docs and terminals | Break a long flag list after the first flag with \ |
| One concept per sample | A reader debugging one idea shouldn't have to parse three | Split an auth-and-retry sample into two samples |
| Realistic names, no foo/bar | foo/bar carries no information about real data |
def foo(bar) → def high_scorers(users) |
| Comments explain why, not what | "# add 1" repeats the syntax; "why" earns the reader's attention | # add 1 → # Retry once before failing the request |
Placeholders in ALL_CAPS, explained after |
<your-key> reads as a literal or gets pasted verbatim |
--key=<your-key> → --key=API_KEY + a "Replace the following" entry |
| Expected output shown in a second block | Without it, the reader can't tell if the sample worked | Add a fenced block with the actual return value or CLI output |
| Sample is runnable as shown | An undefined variable or missing import fails silently for the reader | Add the missing import or define the variable inline |
| Introduced by a sentence ending in a colon | A bare code block gives no reason to read it | "Here's code:" → "The following command lists failed deployments:" |
Verified against code or --help, not invented |
An unverified flag teaches a command that fails | Confirm --status exists via shipit deploy --help (see P11) |
Source: code-samples, tech-writing/two "Sample code"
8. Verify Facts Before Style (P11)
P11 is the one blocking rule in this file, and it comes before every other rule here: a beautifully formatted step for a flag that doesn't exist teaches the reader something false with total confidence. Style makes a doc readable; it does nothing to make a doc true.
Trace every command, flag, parameter, default, and described behavior to one of four sources before it goes in a doc:
- The parser or argument definitions. Grep the CLI's flag-parsing code (
argparse,cobra,clap,yargs, or the project's own dispatcher) for the exact flag name, type, and default value. --helpoutput. Run the actual command and read its usage text; don't reconstruct it from memory of a similar tool or an older version.- Tests. A flag's real behavior — including edge cases — often matches its test fixtures more precisely than its comments or its
--helpstring. - The user. When no code is reachable, ask; don't infer a plausible-sounding default.
When none of the four resolves a fact, write TODO(verify): confirm whether --status accepts a comma-separated list inline and move on. Never fill the gap with a guess that reads as confident prose — a TODO(verify) marker is visible and fixable; a wrong sentence that reads well is neither.
The skill's rule (SKILL.md, section 8): "Never include a command, flag, or parameter you didn't see in code or receive from the user." A wrong polished doc is worse than an ugly right one — polish signals authority, so a reader trusts a wrong flag name precisely because the sentence around it reads well. An ugly doc with a TODO(verify) marker at least tells the reader where the doc stops vouching for itself.
Source: skill rule
| 1 | # Procedures and Code |
| 2 | |
| 3 | This file owns **P1–P11**: step-by-step instructions, UI verbs, code in prose, code samples, placeholders, and command-line syntax. W1 (condition before instruction) belongs to [voice-and-words.md]; S12 (the bold/code-font/italics summary) belongs to [structure-and-formatting.md]; A1–A7 (API reference text, docstrings) belong to [api-reference.md] — mentioned here only where a procedure or sample touches them. |
| 4 | |
| 5 | ## 1. Anatomy of a Procedure (P1–P4) |
| 6 | |
| 7 | A procedure exists to get one reader from a starting state to a finished one. Every step names a single imperative action, states or implies where to act, and lets the reader confirm what happened before moving on. |
| 8 | |
| 9 | **Rules:** |
| 10 | **P1 — Numbered steps, one action each.** Split "click X and then configure Y" into two steps. If a step has two actions, the reader can't tell which one failed. |
| 11 | **Condition before instruction (W1, owned by voice-and-words.md).** "If you want X, do Y" — not "Do Y if you want X." The reader decides whether the step applies before reading how to do it. |
| 12 | **P4 — Where to act, what to expect.** Name the screen, menu, or file the action happens in, and state the observable result: a new status, a redirect, a file on disk. |
| 13 | **P3 — "Optional:" prefix.** Not "(Optional)", not "You can also…" — the word "Optional:" at the start of the step, so a scanning reader can skip it without reading the rest. |
| 14 | **P2 — Single step = bullet.** A procedure with exactly one action is a bullet (`*` or `-`), never "1." — a numbered list of one implies steps 2 and 3 are coming. |
| 15 | **P2 — Sub-steps a/b/c, then i/ii/iii.** Use letters for a sub-sequence inside a numbered step; drop to roman numerals only when a lettered sub-step itself has to branch — for example, by operating system. Don't add a third level to document a style preference. |
| 16 | **Document the shortest path.** When the UI and the CLI both accomplish the task, pick one and mention the other in a single sentence, not as a parallel procedure. |
| 17 | |
| 18 | **Before:** |
| 19 | |
| 20 | |
| 21 | To turn on automatic deployments, you should first go to the project |
| 22 | settings and look for the Deployments tab, then enable it, and after |
| 23 | that you can pick which branch you want it to watch. You should also |
| 24 | set a build command if you have one, and once you're done you can |
| 25 | save it, and it will deploy automatically from then on when you push |
| 26 | to that branch. |
| 27 | |
| 28 | |
| 29 | **After:** |
| 30 | |
| 31 | |
| 32 | 1. In the **shipit** console, open your project and click **Settings**. |
| 33 | 2. Click **Deployments**. |
| 34 | 3. Turn on **Automatic deployments**. |
| 35 | 4. Select the branch to watch: |
| 36 | a. Click the **Branch** menu. |
| 37 | b. Choose the branch, for example `main`. |
| 38 | 5. Optional: Enter a build command, for example `npm run build`. |
| 39 | 6. Click **Save**. The **Status** column shows **Watching** next to |
| 40 | the selected branch. |
| 41 | |
| 42 | |
| 43 | A step that must branch by platform drops to roman numerals inside the lettered sub-step: |
| 44 | |
| 45 | |
| 46 | 1. Open a terminal. |
| 47 | a. On macOS or Linux, run `chmod +x shipit`. |
| 48 | i. If `shipit` isn't on your `PATH`, move it to `/usr/local/bin`. |
| 49 | ii. If it is, skip to step 2. |
| 50 | b. On Windows, skip this step. |
| 51 | |
| 52 | |
| 53 | A single-action procedure stays a bullet: |
| 54 | |
| 55 | |
| 56 | To restart the deployment watcher: |
| 57 | |
| 58 | * Click **Restart** in the **Deployments** panel. |
| 59 | |
| 60 | |
| 61 | Source: procedures |
| 62 | |
| 63 | ## 2. UI Elements and Device Verbs (P5) |
| 64 | |
| 65 | **Rules:** |
| 66 | **Bold the element's name**, not its type: "Click **Save**", not "Click the **Save** button." Name the type only when the label alone is ambiguous ("click the **Region** dropdown" when a section is also called Region). |
| 67 | **Casing matches the UI**, with one exception: an ALL-CAPS label in the interface is written in sentence case in prose. A button rendered `SUBMIT ORDER` is still "click **Submit order**." |
| 68 | **Menu paths** bold each segment and join with `>`: "**File > Save as**" (inferred — the guide doesn't give this exact notation, but it follows directly from bolding UI element names in sequence). |
| 69 | **Device verbs** match how the reader is expected to interact with the target, not the writer's own device. |
| 70 | |
| 71 | | Verb | Situation | Example | |
| 72 | |------|-----------|---------| |
| 73 | | Click | Mouse or trackpad — buttons, links, checkboxes | "Click **Deploy**." | |
| 74 | | Tap | Touchscreen — the same targets on mobile or tablet | "Tap **Deploy**." | |
| 75 | | Select | Device-agnostic — menu items, dropdown options, radio buttons | "Select **Production** from the **Environment** menu." | |
| 76 | | Enter | Typing a value into a field | "Enter your project ID." | |
| 77 | | Type | Free-text input where "enter" would also read correctly — the two are interchangeable (inferred) | "Type a description for the release." | |
| 78 | | Choose | Picking one option among several presented together — close in meaning to "select" (inferred) | "Choose a region for the new environment." | |
| 79 | |
| 80 | **Before → after:** |
| 81 | "Click on the SAVE CHANGES button to save your changes." → "Click **Save changes**." |
| 82 | "Go to File, then Export, then click on PDF." → "Click **File > Export > PDF**." |
| 83 | |
| 84 | Source: ui-elements |
| 85 | |
| 86 | ## 3. Code in Text (P6) |
| 87 | |
| 88 | **Gets code font:** filenames, paths, commands, flags, parameters, values, method and function names, class names, HTTP status codes, environment variables. |
| 89 | **Doesn't:** product names, UI labels (those are bold, per P5), and general concepts ("the deploy step," not `the deploy step`). |
| 90 | |
| 91 | Code isn't a part of speech: don't inflect it as a verb or pluralize it by adding a suffix outside the backticks. Add a plain-English noun instead — "call the `close` method," not "`close`ing the file"; "`Widget` objects," not "`Widget`s." |
| 92 | |
| 93 | **Before → after:** |
| 94 | "Open the config.yaml file and set the timeout value to 30 seconds." → "Open `config.yaml` and set `timeout` to `30`." |
| 95 | "Run shipit deploy with the dash-dash-force flag to skip confirmation." → "Run `shipit deploy --force` to skip confirmation." |
| 96 | "The API returns a 404 Not Found if SHIPIT_API_KEY isn't set." → "The API returns `404 Not Found` if `SHIPIT_API_KEY` isn't set." |
| 97 | "After closing() the file, check for leftover Widgets — the Shipit CLI logs them." → "After you call the `close` method, check for leftover `Widget` objects — the shipit CLI logs them." (the method and class stay in code font; the product name doesn't) |
| 98 | |
| 99 | Source: code-in-text |
| 100 | |
| 101 | ## 4. Code Samples (P7, P10) |
| 102 | |
| 103 | **Rules:** |
| 104 | **P7 — Introduce every sample with a sentence ending in a colon.** A bare code block gives the reader no reason to read it and no way to know what it's for. |
| 105 | **One concept per sample.** A sample that shows authentication and retry logic in one block forces a reader debugging retries to also parse auth. |
| 106 | **Runnable and minimal.** Nothing in the sample should be unrelated to the concept it demonstrates; nothing needed to run it should be missing. |
| 107 | **Realistic names.** Production-shaped data, not `foo`/`bar` — a reader pattern-matches against their own variables and data. |
| 108 | **Wrap at 80 characters.** Long lines force horizontal scrolling in both the doc and the terminal the reader pastes into. |
| 109 | **Show expected output** in a second fenced block, immediately after the sample. |
| 110 | **Comments explain why**, not what the syntax already says. |
| 111 | **Tag the language** on every fence (` ```python `, ` ```bash `) — untagged blocks can't be highlighted or reliably copied (convention). |
| 112 | |
| 113 | **Before → after (function):** |
| 114 | |
| 115 | |
| 116 | # before — no intro, mixed concepts, foo/bar, no output shown |
| 117 | def foo(bar): |
| 118 | x = bar['data'] |
| 119 | result = [] |
| 120 | for i in x: |
| 121 | if i['active'] == True and i['score'] > 50 and i['region'] in ['us', 'eu', 'apac']: |
| 122 | result.append(i['name']) |
| 123 | return result |
| 124 | |
| 125 | |
| 126 | The following function returns the names of active users in a supported region who scored above 50: |
| 127 | |
| 128 | |
| 129 | SUPPORTED_REGIONS = ("us", "eu", "apac") |
| 130 | |
| 131 | |
| 132 | def high_scorers(users): |
| 133 | # Scoring only applies in supported regions, so filter first. |
| 134 | return [ |
| 135 | user["name"] |
| 136 | for user in users |
| 137 | if user["active"] |
| 138 | and user["score"] > 50 |
| 139 | and user["region"] in SUPPORTED_REGIONS |
| 140 | ] |
| 141 | |
| 142 | |
| 143 | |
| 144 | >>> high_scorers(users) |
| 145 | ['Priya Patel', 'Sam Nguyen'] |
| 146 | |
| 147 | |
| 148 | **Before → after (CLI):** |
| 149 | |
| 150 | |
| 151 | To see your deployments just run this: shipit list-deployments --all |
| 152 | --verbose --since=2026-01-01 --until=2026-08-29 --format=json --pretty |
| 153 | | jq '.[] | select(.status=="failed")' |
| 154 | |
| 155 | |
| 156 | The following command lists deployments that failed since the start of the year: |
| 157 | |
| 158 | |
| 159 | shipit list-deployments \ |
| 160 | --since=2026-01-01 \ |
| 161 | --status=failed |
| 162 | |
| 163 | |
| 164 | |
| 165 | DEPLOYMENT BRANCH STATUS FINISHED |
| 166 | d-8f2a1c main failed 2026-03-14T10:02:00Z |
| 167 | |
| 168 | |
| 169 | Source: code-samples, tech-writing/two "Sample code" |
| 170 | |
| 171 | ## 5. Placeholders (P8) |
| 172 | |
| 173 | A placeholder stands in for a value the reader supplies. Write it `ALL_CAPS_WITH_UNDERSCORES` — never `<your-api-key>` (angle brackets read as literal characters to a reader who doesn't know the convention) and never `MY_PROJECT_ID` or `YOUR_API_KEY` (the prefix reads as part of the name). After the sample, list what each placeholder means in a "Replace the following:" block. |
| 174 | |
| 175 | **Before:** |
| 176 | |
| 177 | |
| 178 | shipit deploy --key=<your-api-key> --project=YOUR_PROJECT_ID |
| 179 | |
| 180 | |
| 181 | **After:** |
| 182 | |
| 183 | Deploy your project by running the following command: |
| 184 | |
| 185 | |
| 186 | shipit deploy --key=API_KEY --project=PROJECT_ID |
| 187 | |
| 188 | |
| 189 | Replace the following: |
| 190 | |
| 191 | `API_KEY`: the key from the project's **Settings > API keys** page. |
| 192 | `PROJECT_ID`: the project ID shown at the top of the **Overview** page. |
| 193 | |
| 194 | Source: placeholders |
| 195 | |
| 196 | ## 6. Command-Line Syntax (P9) |
| 197 | |
| 198 | | Notation | Meaning | Example | |
| 199 | |----------|---------|---------| |
| 200 | | `[optional]` | The argument may be omitted | `shipit deploy [--dry-run]` | |
| 201 | | `{a\|b}` | Choose exactly one | `shipit logs {--tail\|--since=DATE}` | |
| 202 | | `...` | The argument repeats | `shipit tag ITEM...` | |
| 203 | | `ALL_CAPS` | A placeholder, not a literal | `shipit init PROJECT_NAME` | |
| 204 | |
| 205 | **One command per line** (convention). Don't chain unrelated commands with `&&` in a sample unless the sample's stated purpose is to show chaining. |
| 206 | |
| 207 | **Long commands wrap with `\` continuation**, one flag per line, as in the CLI sample in section 4. |
| 208 | |
| 209 | **Prompt characters.** Whether to show a leading `$` isn't specified in the guide (convention): this skill's default is to omit it — the fenced ` ```bash ` tag already marks the block as a shell command, and a bare `$` gets pasted verbatim by readers who don't know to drop it. Follow a project's existing samples if they already include `$` — local convention wins (see SKILL.md's precedence rule). |
| 210 | |
| 211 | **Filenames** written inside docs — sample config files, script names — are lowercase, hyphenated, ASCII: |
| 212 | |
| 213 | "See Getting_Started.MD for setup instructions." → "See `getting-started.md` for setup instructions." |
| 214 | |
| 215 | Source: code-syntax, filenames |
| 216 | |
| 217 | ## 7. Sample-Code Quality Checklist (P10) |
| 218 | |
| 219 | | Check | Why | Example fix | |
| 220 | |-------|-----|--------------| |
| 221 | | Language tag on every fence | Without it, editors and readers can't syntax-highlight or copy cleanly | ` ``` ` → ` ```python ` | |
| 222 | | Lines wrap at 80 characters | Long lines force horizontal scrolling in docs and terminals | Break a long flag list after the first flag with `\` | |
| 223 | | One concept per sample | A reader debugging one idea shouldn't have to parse three | Split an auth-and-retry sample into two samples | |
| 224 | | Realistic names, no foo/bar | `foo`/`bar` carries no information about real data | `def foo(bar)` → `def high_scorers(users)` | |
| 225 | | Comments explain why, not what | "# add 1" repeats the syntax; "why" earns the reader's attention | `# add 1` → `# Retry once before failing the request` | |
| 226 | | Placeholders in `ALL_CAPS`, explained after | `<your-key>` reads as a literal or gets pasted verbatim | `--key=<your-key>` → `--key=API_KEY` + a "Replace the following" entry | |
| 227 | | Expected output shown in a second block | Without it, the reader can't tell if the sample worked | Add a fenced block with the actual return value or CLI output | |
| 228 | | Sample is runnable as shown | An undefined variable or missing import fails silently for the reader | Add the missing `import` or define the variable inline | |
| 229 | | Introduced by a sentence ending in a colon | A bare code block gives no reason to read it | "Here's code:" → "The following command lists failed deployments:" | |
| 230 | | Verified against code or `--help`, not invented | An unverified flag teaches a command that fails | Confirm `--status` exists via `shipit deploy --help` (see P11) | |
| 231 | |
| 232 | Source: code-samples, tech-writing/two "Sample code" |
| 233 | |
| 234 | ## 8. Verify Facts Before Style (P11) |
| 235 | |
| 236 | P11 is the one blocking rule in this file, and it comes before every other rule here: a beautifully formatted step for a flag that doesn't exist teaches the reader something false with total confidence. Style makes a doc readable; it does nothing to make a doc true. |
| 237 | |
| 238 | Trace every command, flag, parameter, default, and described behavior to one of four sources before it goes in a doc: |
| 239 | |
| 240 | **The parser or argument definitions.** Grep the CLI's flag-parsing code (`argparse`, `cobra`, `clap`, `yargs`, or the project's own dispatcher) for the exact flag name, type, and default value. |
| 241 | **`--help` output.** Run the actual command and read its usage text; don't reconstruct it from memory of a similar tool or an older version. |
| 242 | **Tests.** A flag's real behavior — including edge cases — often matches its test fixtures more precisely than its comments or its `--help` string. |
| 243 | **The user.** When no code is reachable, ask; don't infer a plausible-sounding default. |
| 244 | |
| 245 | When none of the four resolves a fact, write `TODO(verify): confirm whether --status accepts a comma-separated list` inline and move on. Never fill the gap with a guess that reads as confident prose — a `TODO(verify)` marker is visible and fixable; a wrong sentence that reads well is neither. |
| 246 | |
| 247 | The skill's rule (SKILL.md, section 8): "Never include a command, flag, or parameter you didn't see in code or receive from the user." A wrong polished doc is worse than an ugly right one — polish signals authority, so a reader trusts a wrong flag name precisely because the sentence around it reads well. An ugly doc with a `TODO(verify)` marker at least tells the reader where the doc stops vouching for itself. |
| 248 | |
| 249 | Source: skill rule |
| 250 |
Discussion
Browse more free Claude skills.