Why this session exists
Every repo visitor opens the README first, and most open nothing else. It is where Session 1's 30-second reader makes the read-or-leave call, where Session 2's crisp sentences earn their keep, and where Session 3's scannable structure gets its hardest test. You have already written the raw material: an audience statement, scope statements, a numbered run procedure, a config table. Today we assemble it.
Anatomy of a README 7 min live
makeareadme.com gives the canonical section order: Name, Description, Badges, Visuals, Installation, Usage, Support, Roadmap, Contributing, Authors and acknowledgment, License, Project status. The craft is not filling all twelve - it is choosing which your reader needs, in that order, and skipping the rest on purpose.
LiveThe section order, and what Pulse skips3 min▶
makeareadme.com's advice is blunt: write the README before you publish, keep it in Markdown at the top of the repo, and when in doubt, too long beats too short. But "long" means depth in the sections you keep, not keeping every section. Pulse is an internal pipeline, so we choose:
| Section | Pulse verdict | Why |
|---|---|---|
| Name, Description | Keep | The 30-second scan lives here |
| Installation, Usage | Keep | The primary audience action: run it |
| Configuration | Keep (added) | Pipelines live and die by their config |
| Project status | Keep | Tells a newcomer this repo is alive |
| Badges, Visuals | Skip | No CI to badge, nothing visual to show - decoration |
| Roadmap, Contributing, License | Skip | Internal repo: no external contributors, no license question |
Every skip is a decision, not an omission. If Pulse ever goes open source, the Self-study card below has the full template waiting.
LiveDescription = your Session 1 statements, landing2 min▶
You do not write the description from scratch - you already wrote it. Session 1's scope, non-scope and audience statements ARE the description paragraph:
- Scope: "Pulse turns raw event CSVs into daily metrics with a LOW-volume alert."
- Non-scope: "It does not schedule itself and does not serve dashboards - it produces one CSV."
- Audience: "Written for analysts new to the team; assumes you can run Python scripts from a terminal."
Three sentences, and the 30-second reader knows what this is, what it is not, and whether it is for them. That is the entire job of the top band.
Self-studyThe full 12-section template, for open-source repos3 min read▶
When a repo faces the public, the sections Pulse skipped start earning their place. The full makeareadme.com order: Name, Description, Badges, Visuals, Installation, Usage, Support, Roadmap, Contributing, Authors and acknowledgment, License, Project status.
- Badges answer "is this maintained and passing?" at a glance - build status, coverage, package version.
- Visuals earn their place for anything with a UI or an output worth seeing; a screenshot beats three paragraphs.
- Contributing matters the moment a stranger can send a pull request: how to set up a dev environment, run tests, and what you will and will not merge.
- License is non-negotiable for open source - no license means nobody can legally use it, which is usually not what you meant.
- Project status is the kindest section in the template: "development has slowed, looking for maintainers" saves a stranger a month of betting on abandonware.
Code on the page 6 min live
A README full of commands lives or dies on whether those commands actually work when pasted. Google's developer documentation style guide has precise rules for text that touches code - fonts, placeholders, samples - and they all serve one goal: the reader can copy, paste, run, and verify.
LiveCode font, bold UI, and CAPS placeholders3 min▶
Three visual conventions carry almost all of Google's computer-interface style:
- Code font for anything code-related: filenames (
config.yaml), commands (python3 pulse/ingest.py), column names (event_id), values (LOW). The font itself tells the reader "this string is literal - type it exactly". - Bold for UI elements: "click Run", "open the Settings tab". Pulse has no UI, so this rule mostly waits - but your BI tools and cloud consoles need it constantly.
- Placeholders in capitalized italic code font:
PULSE_RAW_DIR,PROJECT_ID. The capitals scream "replace me"; regular code font whispers "type me literally". Confusing the two is how a reader ends up with a folder literally named PULSE_RAW_DIR.
The companion rule: commands must be exactly copy-pasteable, and every command shows its expected output. For Pulse's sample data the run prints 10 rows staged, then 8 rows kept, then the metrics path - so the README says so, and the reader knows within a minute whether their setup works.
LiveExample hygiene: safe names, teaching data2 min▶
Google's rules for examples are safety rules as much as style rules:
- Reserved example domains only:
example.comand friends exist precisely so your docs never point readers at a real site. Never a colleague's real email, never a real customer ID, never production data pasted "just to show the shape". - Code samples must be runnable and follow the language's own conventions; comments explain why, not what. A sample that errors on paste teaches the reader to distrust the whole doc.
- Teaching data is designed, not sampled. Pulse's
events_2026-07-01.csvhas exactly 10 rows and deliberately includes one duplicateevent_id, one invalidclickevent type, and one timezone-naive timestamp. That is not sloppiness - it is a fixture. It guarantees every reader sees the pipeline actually filter something: 10 in, 8 out, every time.
The demo that paged a stranger. A team's onboarding doc used a real internal service URL as its example. New hires dutifully pasted it, and the service owner got a small wave of malformed test traffic every onboarding week - and eventually an alert at 3am. One find-and-replace to example.com ended it. Example hygiene is incident prevention.
Self-studyLinks that say where they go2 min read▶
Google's linking rule fits in one line: link text describes the destination, never "click here" or "this page". "See the configuration reference" tells the reader what they get before they commit a click; "click here" tells them nothing and reads terribly in a screen reader's link list.
- Make the destination's name the link: "see How to diagnose a LOW alert day" - the title is the description.
- Link nouns, not verbs: link "the config table", not "look at" the config table.
- One link per destination per section is plenty; a paragraph with six links is a paragraph nobody finishes.
Assemble the README's top half ★ 8 min · everyone follows
Create README.md at the top of the repo and build the bands that win the scan: name, description, prerequisites, install, quickstart. Almost every line already exists in docs/AUDIENCE.md and Session 3's numbered run procedure - this is assembly, not authorship.
Create README.md in the repo root. Title: # Pulse, then one plain-words subtitle line: "CSV events in, daily metrics out."
Write the description as the three Session 1 sentences: scope ("turns raw event CSVs into daily metrics with a LOW-volume alert"), non-scope ("no scheduler, no dashboard - it produces one CSV"), audience ("assumes you can run Python scripts from a terminal").
Prerequisites: Python 3.10+ and pyyaml. Install is one copy-pasteable line: pip install pyyaml.
Quickstart: the three commands in fixed order - python3 pulse/ingest.py, python3 pulse/clean.py, python3 pulse/metrics.py - each with its expected output: 10 rows staged, 8 rows kept, then pulse/data/metrics/daily_metrics.csv written.
Usage, configuration, and the full skeleton ★ 8 min · build your own
The bottom half serves the reader who is past "does it run" and into "what does it mean": paste Session 3's config table, add an output-columns table, and document what a LOW alert actually says. Here is the complete skeleton, real commands and real config keys included.
Usage: one line per script saying what it validates, keeps, or writes - lifted from Session 2's rewritten notes.
Configuration: paste the S3 config table covering paths, events.valid_types, and alerts.min_daily_events.
Output: a columns table for daily_metrics.csv, and one sentence defining LOW: fewer than 50 events on that day after cleaning.
Project status: one honest dated line. Then commit - milestone 1 ships.
The 30-second test ★ 6 min · pairs
Session 1 opened with three questions a newcomer asks of Pulse. The README's exit exam: can a fresh reader answer all three from the README alone, fast?
Swap screens with a partner (or close the README for ten minutes and return with fresh eyes).
Start a timer. Using ONLY the README, answer: How do I run it, and in what order? Which event types are valid? What does the LOW alert mean?
Score it: all three inside 30 seconds of scanning each is a pass. For any miss, note WHERE the reader looked first - that is where the answer belongs, regardless of where you put it.
Fix the misses by moving content up or renaming a heading - not by adding more prose. Scan failures are structure failures.
Try it yourself - this week ◐ 30-45 min total
- Finish the Pulse
README.mdif you didn't complete it live, and run the 30-second test on someone who has never seen the repo. - Open the README of a repo you own. Check three things: does the top band declare scope, non-scope and audience? Does every command show expected output? Are placeholders visibly different from literal text? Fix the worst offender.
- Run the ★ Try it now three-sentence description exercise on your team's main repo.
- Read the Self-study cards: the full 12-section template and the linking rules.
- Optional depth: makeareadme.com for the template with rationale, and Google's developer documentation style guide for the full computer-interface rules.
Official sources covered
This session teaches the working content of these sources. What stays with the originals: makeareadme.com's full FAQ and history, and the Google style guide's exhaustive word-level entries.
Three questions before you go 🎯 ◐ 90 seconds
1 · Which part of a README decides whether the 30-second reader stays?
The scan lands on the top band and rarely goes deeper. Scope, non-scope and audience in the first paragraph is how the right reader stays and the wrong reader leaves happy.
2 · How should a replace-me value like a project ID appear in a doc?
Capitals plus italics visually separate "replace me" from "type me literally". In plain code font, readers paste the placeholder as-is and get a folder named PULSE_RAW_DIR.
3 · Why does the Pulse quickstart print "10, then 8, then a file path" in the README?
Every command gets its expected output so the reader has a checkpoint. A quickstart without output is a hope; with output it's a test the reader runs on their own setup.