learn-tech-writing-with-phoebe / Session 3 of 8
Learn Tech Writing with Phoebe · Session 3 of 8

Structure readers can scan

Session 2 gave you good sentences. Nobody will read them - not top to bottom, anyway. Real readers scan: headings, lists, lead sentences, tables. Today you learn the structures that reward scanning, and you turn Pulse's facts into a numbered procedure and a config table.

🟢 Easy Practitioners Data & AI teams 45 min live + self-study depth
0-3 · Welcome 3-18 · Concepts (live cards) 18-40 · Build-along on Pulse 40-45 · Q&A
Part 0

Why this session exists

In Session 2 you rewrote Pulse's NOTES.txt into crisp active sentences (docs/notes-rewrite.md). But a page of good sentences is still a wall, and readers do not read walls - they scan them. This session is about the containers: lists, tables, paragraphs, and headings. Choose the right container and readers find the fact in five seconds; choose the wrong one and your perfect sentences go unread.

Live - presented in session Self-study - read after class ★ Try it now exercise Sources: Google TW One + Microsoft Style Guide
★ What you walk out with today Pulse's run instructions as a proper numbered procedure (imperative verbs, one action per step, condition-first warning) and every config.yaml fact as a scannable table. These two blocks are the raw material for Session 4, where they get assembled into the README.
Part 1 · covers Google TW One "Lists and tables"

Lists: the workhorse 8 min live

Google's guidance starts with one question: does order matter? Everything else about list craft - which list type, how steps begin, how items line up - follows from that answer. Most doc lists in the wild get at least one of these wrong.

Facts to present Order matters? steps · ranking · sequence yes Numbered list no Two dimensions? e.g. setting × meaning yes Table no Bulleted list order-free facts Whichever you pick: introduce it with a sentence ending in a colon, preferably containing "following".
🔍 Click to zoom - the list-or-table decision tree, from Google Technical Writing One's lists and tables unit
LiveBulleted vs numbered, and the first-verb rule3 min▶

The choice between list types is not aesthetic. It is a signal to the reader about whether they can rearrange the items:

  • Bulleted list: order does not matter. Rearranging the items changes nothing. Valid event types, prerequisites, known limitations - all bulleted.
  • Numbered list: order matters. Rearranging the items breaks the meaning. Pulse's run order (ingest, then clean, then metrics) must be numbered - a bulleted version silently tells readers they can run the scripts in any order.
  • Start each numbered step with an imperative verb. "Run the ingest script", not "The ingest script should be run" and not "Running the ingest script". Command verbs make steps executable at a glance.

And parallelism, the rule that makes lists feel professional: every item in a list matches every other item in grammar, category, capitalization, and punctuation. One item that starts with a noun in a list of verbs reads like a wrong note in a chord.

Non-parallel (spot the wrong notes)To run Pulse you need: - Python 3.10+ - installing pyyaml - The raw CSVs should be in pulse/data/raw.
Parallel (same grammar, category, punctuation)Before you run Pulse, confirm the following prerequisites: - Python 3.10 or later - The pyyaml package - Raw CSVs in pulse/data/raw
LiveConditions before instructions3 min▶

Google highlights this rule because getting it backwards causes real damage: state the condition BEFORE the instruction, not after. Readers execute instructions the moment they read them - a condition that arrives afterwards arrives too late.

Condition last - the reader already ran itRun ingest.py first if the staged folder is empty. Delete the cleaned folder if you want a full rebuild.
Condition first - the reader checks, then actsIf the staged folder is empty, run ingest.py first. If you want a full rebuild, delete the cleaned folder.

In pipeline docs this pattern is everywhere: "If metrics.py reports LOW days, check alerts.min_daily_events before paging anyone." The reader who needs the caveat gets it before they act; the reader who does not skips the whole line from the first two words.

Real world

The backwards warning. A team's runbook said "Rerun the backfill job - note this drops the staging table if the date range overlaps." An on-call engineer executed the first clause at 2am and read the second clause while the table was dropping. The fix in the postmortem was word order, nothing else: "If the date range overlaps, this drops the staging table. To proceed, rerun the backfill job."

Self-studyTables: when two dimensions demand one3 min read▶

A list holds one dimension of information. The moment each item carries two or more facts - a setting AND what it does AND whether you can touch it - a list forces the reader to parse prose for structure. A table hands them the structure directly:

Shape of the factsRight containerPulse example
One fact per item, order-freeBulleted listThe four valid event types
One action per item, in sequenceNumbered listThe three-script run order
Several facts per itemTableconfig.yaml: key × meaning × safe-to-change

Table hygiene, per Google:

  • Label every column with a meaningful header - readers scan headers before cells.
  • Keep cells short. If a cell needs three sentences, the content wants to be a paragraph or its own section, not a cell.
  • Introduce the table with a sentence ending in a colon, preferably containing "following": "The following table describes every config.yaml setting:"
Part 2 · covers Google TW One "Paragraphs" + Microsoft "Scannable content"

Paragraphs and headings 7 min live

Not everything fits in a list. For the prose that remains, two structures decide whether scanners survive: the lead sentence of each paragraph and the headings above them. Eye-tracking studies keep finding the same thing - readers sweep a page in an F shape, and only the left edge and the top lines actually get read.

Headings: scanned first short · task-based · sentence case · no period Lead sentences: actually read the story must survive on these alone Body: skimmed, often skipped depth for the readers who commit Write for the scan: headings plus lead sentences must carry the doc on their own.
🔍 Click to zoom - the F-scan: what readers actually read on your page, and what they skip
LiveThe lead sentence carries the paragraph3 min▶

Google's paragraph unit has one non-negotiable rule: the opening sentence establishes what the whole paragraph is about. Scanners read lead sentences and nothing else, so the lead sentence IS the paragraph for most readers.

  • The test: read ONLY the first sentence of every paragraph in your doc, top to bottom. If the story survives - you can still follow what the doc says and why - your structure works. If the story falls apart, your key points are buried mid-paragraph where scanners never look.
  • One topic per paragraph. The moment a second topic sneaks in, split. A paragraph is a unit of thought, not a unit of typing.
  • Three to five sentences. Under three, consider merging or promoting to a list. Over seven is a wall - readers' eyes slide off it, and walls are where facts go to hide.
★ Try it nowOpen docs/notes-rewrite.md from Session 2. Read only the first sentence of each paragraph. Can you still reconstruct how Pulse works? Mark every paragraph whose lead sentence fails - those are your Demo 3 targets.
LiveHeading craft2 min▶

Headings are the largest text on the page and the first thing scanned, yet most docs treat them as an afterthought. Microsoft's scannable-content guidance is specific:

  • Sentence case, always: "Run the pipeline", not "Run The Pipeline". Google's style guide agrees, so this one is settled across the industry.
  • No end punctuation on headings. No periods, no colons.
  • Task-based over topic-based. "Configure alert thresholds" tells the reader what they will be able to do; "Alerts" makes them open the section to find out. Verb-first headings double as a table of contents of actions.
  • Short. A heading that wraps to two lines is a sentence wearing a costume.
Writing tip Read your doc's headings alone, in order, ignoring everything else. That outline is what a scanner sees first. If the outline does not make sense on its own, no amount of body text will rescue it.
Self-studyThe what, why, how check2 min read▶

Google's completeness test for a paragraph: a good paragraph answers three questions. Not always in this order, but all three should be findable:

  • What are you telling the reader? The core fact or instruction.
  • Why does it matter to them? The consequence of knowing or ignoring it.
  • How should they use the knowledge? The action it enables, or the way to verify it worked.

Run the check on a paragraph like "Pulse flags LOW days." What: any day with fewer events than alerts.min_daily_events is flagged. Why: a LOW day usually means an upstream export failed, not a real traffic drop. How: check the raw folder for that date before trusting the metric. Three sentences, three answers, one complete paragraph.

Build-along 1 of 3

Turn the run order into a numbered procedure ★ 8 min · everyone follows

docs/notes-rewrite.md states Pulse's run order in prose. Prose is the wrong container for a sequence: it must become a numbered list with imperative first verbs, one action per step, and every condition placed before its instruction.

Find the run-order sentences in docs/notes-rewrite.md. Underline each distinct action - you should find exactly three, plus the prerequisites.

Write the prerequisites as a short bulleted list (order-free facts) and the actions as a numbered list (order matters). Start every step with an imperative verb.

Add one condition-first warning where a newcomer could go wrong. Check the word order: condition, comma, instruction.

Compare with the finished procedure below, then save yours as docs/run-procedure.md - Session 4 pastes it into the README.

docs/run-procedure.md - the finished procedure## Run the pipeline Before you start, confirm the following prerequisites: - Python 3.10 or later - The pyyaml package - Raw CSVs in pulse/data/raw Run the three scripts in the following order: 1. Ingest the raw CSVs: `python3 pulse/ingest.py` 2. Clean the staged events: `python3 pulse/clean.py` 3. Compute the daily metrics: `python3 pulse/metrics.py` If the staged folder is empty when you reach step 2, run ingest.py first. If you change config.yaml, rerun all three steps from step 1.
Writing tip One action per step. "Run ingest.py and check the staged folder" is two steps in a trench coat - the reader who hits an error cannot tell you which half failed.
Build-along 2 of 3

Turn config.yaml into a table ★ 8 min · build your own

Every config.yaml key carries three facts: what it is, what it does, and whether a newcomer can safely change it. Three facts per item is table territory - the decision tree from Part 1, applied for real.

Open pulse/config.yaml and list every key. There are six: four paths, the valid event types, and the alert threshold.

Build a markdown table with three columns: setting, what it does, safe to change. Keep every cell to one short phrase or sentence.

Introduce the table with a colon sentence containing "following", then check the columns read top to bottom as parallel phrases.

docs/config-table.md - the finished table## Configuration Pulse reads every setting from config.yaml. The following table describes each key: | Setting | What it does | Safe to change? | |---|---|---| | paths.raw | Folder ingest.py reads incoming CSVs from (pulse/data/raw) | Yes - point it at any folder | | paths.staged | Folder ingest.py writes staged events to | Yes - keep it inside pulse/data | | paths.cleaned | Folder clean.py writes validated events to | Yes - keep it inside pulse/data | | paths.metrics | Folder metrics.py writes daily_metrics.csv to | Yes - downstream readers must know | | events.valid_types | Event types clean.py keeps: page_view, signup, purchase, api_call | Only when adding a real new type | | alerts.min_daily_events | Daily event count below which a day is flagged LOW (50) | Yes - tune to your traffic
Markdown itself is a sibling course This session covers WHEN to use a list or table; the syntax for writing them in Markdown (and everything else Markdown can do) has its own beginner course: learn-markdown-with-phoebe.
Build-along 3 of 3

Lead-sentence audit on your own doc ★ 6 min · build your own

The lead-sentence test works on any doc, not just Pulse. Run it on the longest doc you personally own - the wiki page, the design note, the runbook - and watch it locate every buried key point in minutes.

Open your longest doc. Read ONLY the first sentence of every paragraph, top to bottom, and nothing else.

Score it: could a scanner reconstruct the doc's story from those sentences alone? Mark every paragraph where the answer is no.

For each marked paragraph, find the real key point (it is usually hiding in sentence three or four) and promote it to the front. Do not rewrite anything else yet.

Bonus pass: read the headings alone as an outline. Rewrite any heading that is topic-based ("Alerts") into task-based sentence case ("Diagnose a LOW day").

Real world

The audit that took eleven minutes. A data engineer ran the lead-sentence test on her team's 3,000-word onboarding doc. Nine of fourteen paragraphs failed - including the one holding the VPN step that every new hire had been Slacking her about. She promoted nine sentences, changed nothing else, and the doc started working. Structure was the whole problem.

Homework

Try it yourself - this week ◐ 30-45 min total

Source material

Official sources covered

This session teaches the working content of these source units. Markdown syntax itself is deliberately delegated to the sibling course.

✓Google TW One · Lists and tablesPart 1: list choice, imperative steps, parallelism, colon introductions, table hygiene
✓Google TW One · ParagraphsPart 2: lead sentence rule, one topic, 3-5 sentences, what/why/how
✓Microsoft Style Guide · Scannable contentPart 2: short headings, sentence case, no end punctuation, lists and tables for scanning
✓Microsoft Style Guide · Procedures and instructionsDemo 1: numbered steps, one action per step, condition-first warnings
◐Google TW One · MarkdownSyntax delegated to the sibling course: learn-markdown-with-phoebe
Check yourself

Three questions before you go 🎯 ◐ 90 seconds

1 · You're documenting Pulse's three run commands. Which container?

Numbered means "the sequence is load-bearing". A bulleted version silently tells the reader they can run clean.py before ingest.py - and someone will.

2 · Which warning follows Google's condition-placement rule?

Condition before instruction. Readers act the moment they read an instruction, so a trailing condition arrives after the damage - see the 2am backfill story.

3 · The lead-sentence test says your doc's structure works when...

Scanners read lead sentences and skip the rest, so the lead sentences ARE the doc for most readers. Short paragraphs help, but the survival test is the rule.

Session 3 cheat sheet · pin this

Numbered vs bulletedOrder matters = numbered. Order-free = bulleted. The list type is a promise about whether items can be rearranged.
Step anatomyImperative first verb, one action per step, parallel grammar/category/capitalization/punctuation across items.
Condition first"If X, do Y" - never "Do Y if X". Readers act on instructions the instant they read them.
Introduce with a colonEvery list and table gets a lead-in sentence ending in a colon, preferably containing "following".
Two dimensions = tableSeveral facts per item (setting × meaning × safe-to-change) outgrow a list. Short cells, labeled columns.
Lead sentence ruleFirst sentence carries the paragraph. Test: read only first sentences - the story must survive. One topic, 3-5 sentences.
Heading craftSentence case, task-based verbs, short, no end punctuation. Headings alone should read as an outline of actions.
Pulse statusRun procedure ✓ · config table ✓ - the two building blocks Session 4 assembles into the README.