Runbook: author a new render-as-html artifact that passes the bar

Runbook · examples/runbook.html
The bar is the gate, not a suggestion
An artifact that flattens to static text losing only its diagram is styled prose, not an HTML artifact — it fails. The flatten test at step 7 is the hard gate. If the only things that die on flatten are cosmetics, do not ship and patch later — jump back to step 3 and redesign the HTML-native features before continuing. Shipping a flat artifact means it gets used as a viewer, the edit loop never happens, and the whole point is lost.
1
Read the content, extract its signals, and pick the page shape

Different content wants different bones. Read the source fully, then classify it against the auto-pick rules. The shape constrains every later decision, so getting it wrong here costs a full rewrite.

shape signal → decision
# Match the dominant structure, not the topic
>5 similar tables           dashboard
headings + prose, reference  document
dates as primary structure   timeline
ordered steps + commands     runbook   ← this file
sustained argument + entities editorial
X vs Y vs Z decision         comparison
ambiguous                    ask the user
Source: an ordered procedure with shell/code steps and a fallback path. Decision: runbook. Procedural + executed-not-read → unambiguous. Explicit user override of the shape always wins over auto-pick.
Write the chosen shape down before doing anything else. If you can't name it in one word, the content isn't understood yet — re-read.
2
Lock the register the shape dictates — reading vs instrument

The register is not a taste choice — the shape determines it. Reading register (serif, cream, 17–18px) for prose you read paragraph-to-paragraph. Instrument register (sans, 14–15px, dense) for things you operate. A runbook is operated, so it is instrument.

register is a function of shape
Reading     document, editorial, timeline
           serif display + body, 17–18px / 1.6, measure ≤46rem
Instrument  dashboard, comparison, developer,
              runbook, triage-board, network-map
           sans display + body, 14–15px / 1.5, dense, mono code
Never mix registers or let the user pick fonts ad hoc. A serif "report" wrapper around an instrument procedure reads as a converted document — exactly the anti-pattern the skill forbids.
3
Plan ≥3 HTML-native features — and write them down before any markup

Pick concrete features that do something static text cannot. At least three, named explicitly, on paper, before you write a tag. "It'll be styled nicely" is not a feature. For a runbook the load-bearing set is fixed.

written feature plan (runbook contract)
1. Per-step progress tracking (checkboxes → donut + bar + counter)
2. Per-code-block copy button with clipboard fallback
3. Conditional branch step (hidden until its condition fires)
4. "I'm stuck" copy-as-prompt that round-trips current state
# 4 named features. The skill requires ≥3. Branch step
# is the runbook's distinguishing primitive — keep it.
A four-line written list. If you skip writing it down you will discover at step 7 that you built styled prose. The list is the contract step 7 checks against.
This is the step the danger callout sends you back to. Treat the written list as binding — step 9's self-review reads it back.
4
Map the artifact to ≥4 of the 8 information dimensions

HTML can carry eight dimensions of information. An artifact leveraging fewer than four is under-using the medium. Name which four (or more) before writing — if you can only name two, redesign now, not after.

dimensions used by this runbook
Code          highlighted snippets, local CSS classes
Interaction   checkboxes, toggles, JS-driven progress
Workflows     ordered steps + a conditional branch
Illustrations inline SVG progress donut from live data
Design        register + palette tokens as information
# 5 of 8. Tables / Spatial / Images not needed here —
# don't add a chart just to pad the count.
Padding the count with a decorative chart is its own anti-pattern. Four real dimensions beat eight ornamental ones. Each must carry information the reader actually needs.
5
Write the self-contained file — one-truth palette tokens, no CDN

One file. All CSS inline, all JS inline and vanilla, no external fonts or CDN. Every color comes from one :root token set with a dark-mode override — never a hard-coded hex in markup. This is the single source of truth for the palette.

:root one-truth palette tokens
:root {
  --paper:    #faf6ef;  /* warm cream */
  --ink:      #1a1815;  /* warm near-black */
  --muted:    #736d62;  /* AA 4.76:1 on paper */
  --accent:   #8a3a1a;  /* terracotta — THE accent */
  --accent-2: #c2901a;  /* ochre — fill only */
}
@media (prefers-color-scheme: dark) {
  :root { --paper:#1a1815; --ink:#f0eee8;
          --muted:#9a948a; /* AA 5.89:1 */ }
}
# Ochre is a background fill with --ink text, never
# white-on-ochre and never ochre text on cream.
One primary accent, one affirmative-action color. No third accent, no corporate blue, no left-handle accent bars — use top-rules and type weight for emphasis instead.
6
Wire copy-as-prompt — round-trip live state back to this file

This is the load-bearing HTML-native feature. The artifact becomes an editing surface: the reader mutates state in the browser, hits a button, and gets a paste-able prompt that names this file and the exact deltas. ~20 lines of JS for a real edit loop.

copy-as-prompt JS skeleton
const ARTIFACT_PATH = 'examples/runbook.html';

function copyPrompt() {
  const changes = collectChanges();   // read mutated state
  const prompt =
    `In ${ARTIFACT_PATH}, apply these changes:\n` +
    formatAsInstructions(changes);
  const out = document.querySelector('#prompt-output');
  out.value = prompt;
  writeClipboard(prompt).catch(() => {
    out.focus(); out.select();   // visible fallback
  });
}
The prompt must name this .html file — never a notes file, source doc, or parallel document. The artifact is the source of truth; the round-trip edits the artifact, nothing else.
7
Run the flatten test — strip all CSS/JS, ask what disappears?

Mentally (or literally) flatten the artifact to static text. Enumerate everything that dies. If the dead list is only colors, spacing, and a diagram, you built styled prose. The dead list must include real interaction.

flatten-test mental checklist
# Flatten to plain text. What is GONE?
[ ] Per-step progress tracking (donut + bar + counter)
[ ] Per-code-block copy buttons
[ ] The conditional branch reveal
[ ] The "I'm stuck" copy-as-prompt generator
# If ALL four survive removal → it was never HTML-native.
# If only color/spacing/diagram die → styled prose.
PASS — flattening kills: progress tracking, code-copy, the branch reveal, the stuck-prompt generator. Those are content, not chrome. This artifact earns the medium.
If only cosmetics vanish on flatten — jump to step 3-R: redesign the HTML-native features
If the four load-bearing behaviors all disappear on flatten, the artifact passes the bar. Continue to step 8.
3R
Redesign the HTML-native features, then re-run the flatten test

Reached only when step 7's flatten test fails — the artifact is styled prose. Do not patch cosmetics. Go back to the step 3 written feature plan and replace decorative elements with behaviors that genuinely require HTML.

You are here because flatten left only colors/spacing/diagram. Adding more styling will not fix this. The fix is structural: real interaction the static version cannot reproduce.
redesign moves that survive flatten
# Swap ornament for behavior:
replace static "Done" badges   live checkbox + progress
replace a screenshot of code  copy-able code block
replace "if X see appendix"   conditional branch reveal
replace a "contact us" line   copy-as-prompt generator
then re-verify against the written plan
re-read the step 3 feature list  # still ≥3, still real?
re-run the step 7 flatten test  # dead list = behaviors?
loop until flatten kills behavior, not just chrome
After the redesigned artifact passes the flatten test, return to step 8 (accessibility pass). Steps 8–10 are the same regardless of how many redesign loops it took.
8
Accessibility & contrast pass — AA, colorblind-safe, real semantics

Every text token must meet WCAG AA on its background, including the lightest one. Color is never the only signal. Interactive elements use real controls with real labels and wired ARIA state.

a11y checklist
[ ] html lang set; one <main> landmark
[ ] --muted ≥4.5:1 on --paper, both light + dark
[ ] every checkbox / icon-button has aria-label
[ ] toggle headers: role=button + aria-expanded
       + aria-controls, kept in sync in the toggle JS
[ ] code copy buttons labelled ("Copy code")
[ ] progress SVG role=img + live aria-label
[ ] state carried by shape/text too, not color alone
All AA ratios pass. Done state = strikethrough + green + checked, not green alone. Donut aria-label updates as steps complete. Toggle JS writes aria-expanded on every open/close.
A keyboard-only, screen-reader, and colorblind pass all succeed? The artifact is accessible. Continue to self-review.
9
Self-review against Content discipline

Read the rendered artifact back as a critic. Surface the subject, never the fact that the artifact exists. Headlines argue a position; bodies add the mechanism the headline promised. Scan for the known decoration anti-patterns.

content-discipline scan
[ ] No artifact-counting hero stats ("12 sections")
[ ] Headlines take a position, not a noun label
[ ] Each body adds info beyond its own headline
[ ] No left-handle accent bars anywhere
[ ] No identical-tile SaaS grid; cards stack as columns
[ ] Search highlights actual matches, not whole blocks
[ ] 1–3 emoji total, not one per heading
"Found 6 claims" as a hero stat is slop. Live UI state ("3 / 10 complete") is feedback and fine. The distinction is whether the number describes the subject or the artifact's own production.
10
Ship — write the file, set the footer path, open it

Write the single self-contained file to its output path, stamp the footer with that exact path and the generated/updated timestamp, and open it so it lands in the browser — the browser is where this thing lives.

ship checklist
[ ] One file, self-contained, no external requests
[ ] Footer shows the artifact's own path + timestamp
[ ] copy-as-prompt path == the footer path == this file
[ ] If publishing public: run the sensitivity scan
       (creds, private IPs, /home or ~ paths, hostnames)
[ ] Open the file when the environment allows
Footer: examples/runbook.html · Generated <date> · render-as-html Sensitivity scan: clean. File opens in browser. Artifact is the source of truth — not an export of anything.
Shipped. The HTML file is the report and the instrument. Markdown source, if any, stays canonical alongside it — this artifact is the thing people read, edit, and round-trip.