Use when the user wants a concept, spec, RFC, protocol, API or mechanism explained as a published interactive HTML page in the visual-harness repo — "/explain X", "make a page for X", "visualise X", "add X to the index", "explain and push". Also use when they paste a link and ask to turn it into an explainer.
One run produces concepts/<slug>/index.html, a catalog.json entry, a rebuilt index.html,
and (on publish) a live URL https://bibryam.github.io/visual-harness/concepts/<slug>/.
The page is for a technical reader with two minutes. Visual first, ~350 words of prose, one interactive sequence they can step through, the real bytes on the wire, plain language.
Input: $ARGUMENTS
catalog.json and assets/harness.js exist).
If not: stop and tell the user to cd into it.reference/page-contract.md, reference/primitives.md, reference/writing.md once per session.| Mode | Trigger | Stops for the user? |
|---|---|---|
| interactive (default) | /explain <topic> | twice: after the brief, and before publish |
| auto | /explain <topic> --auto, or the user says "don't ask, publish" | never; prints the URL at the end |
Auto mode is for named topics only. If the input is a URL or the research surprised you
(sources contradict, the concept is contested), downgrade to interactive even when --auto
was passed, and say why.
Intake. Name the concept in its common form; the spec id is the subtitle, not the slug
(oauth2-token-exchange / "RFC 8693"). Slug: kebab-case, no dates, no version numbers unless
the version is the point. Check catalog.json for an existing slug; if present, this is an
update, not a new page.
Research. Fetch the primary source (RFC, spec, official docs) and 2–4 secondary sources (implementations, a good overview). Extract, in this order:
catalog.json — mechanical links only
(output↔input, base↔extension, replaces); if the concept is a revision of an existing
page, build a delta page (see page kinds in reference/page-contract.md).
Never invent a field name, URN, header or URL. If the source is silent, say so on the page.Brief. Write the explainer brief in the shape given in reference/brief.md: cast, ASCII
sequence diagram, proposed compare, details, links, slug, one-sentence definition.
Generate.
node scripts/new-concept.mjs <slug> "<Title>" "<Subtitle>"Then fill concepts/<slug>/index.html section by section per reference/page-contract.md,
using the primitives in reference/primitives.md. Fill the catalog entry (summary ≤ 30
words, tags lower-case, sources with the primary URL, minutes = ceil(words/120)+1).
Every TODO and {{PLACEHOLDER}} must be gone.
Fact-check (accuracy gate). Follow reference/fact-check.md: list every technical
claim the page makes, re-verify each against the primary source, and mark it
verified / inferred (and labeled as such on the page) / removed. Sweep for internal
consistency: nothing one section shows may contradict another (a token's claims must
match the request that minted it). In auto mode, any claim that fails verification
downgrades the run to interactive — accuracy beats autonomy.
Seal, validate, smoke, look at it.
node scripts/seal.mjs <slug> # lock the page's inline script into its CSP
node scripts/validate.mjs <slug> # contract + security scan (XSS sinks, schemes, CSP)
node scripts/build-index.mjs # regenerate index.html (self-sealing)
node scripts/smoke.mjs <slug> # headless Chrome: page renders, JS ran under CSP,
# no console errors or CSP refusals
scripts/serve.sh # http://127.0.0.1:8787/concepts/<slug>/smoke.mjs is the floor, not the ceiling: also open the page yourself (Chrome tools if available). Check: every flow step renders and its payload reads correctly; inspect panel answers for every field; compare switches; both themes legible; nothing scrolls horizontally. Fix, re-validate.
Publish.
scripts/publish.sh "Add <Title> (<Subtitle>)". It validates,
rebuilds the index, commits with -s, pushes, waits for the Pages build, prints URLs.Report in ≤ 6 lines: live URL, what the page contains (steps, compare, details count), the fact-check tally (n verified / n inferred / n removed), anything unverified or left out.
| Item | Budget |
|---|---|
| one-sentence definition | ≤ 25 words |
| "Why it exists" | ≤ 3 sentences |
| actors | 3–5 |
| flow steps | 5–9, label ≤ 40 chars, note ≤ 30 words |
| code sample | ≤ 15 lines each |
| prose total | ~350 words (warn at 450) |
| details cards | 3–6 |
| links | 3–6, each verified |
POST /token · grant_type=token-exchange.concepts/<slug>/, catalog.json, and the
generated index.html. Framework files (assets/, scripts/, skills/, templates/,
manifests) are never touched by an explain run; scripts/publish.sh refuses to publish if
they changed.<strong> <em> <code> <b> <i> <br> — the runtime
strips everything else, and the validator rejects event handlers, executable URL schemes,
extra scripts, external resources, and unsealed CSP. Run node scripts/validate.mjs --self-test after changing the validator.git diff --stat that publish.sh prints; in interactive mode
wait for "ship".90ab207
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.