| name | visitor-audit |
| metadata | {"version":"0.1.0"} |
| description | Run a visitor-grade audit of a project's public-facing surfaces — verify pages, docs, READMEs, release pages, and announcements the way a first-time human visitor experiences them, not the way a developer diffs them. Reads every surface fully as rendered, follows EVERY link (counted, with per-link status), checks published checksums, and flags stale claims, jargon leaks, invisible links, mojibake, and misleading framing. Use whenever the user says "visitor audit", "audit the public surfaces", "click through everything", "is this actually done", or "/visitor-audit" — and proactively before announcing any page, doc, site, or release as done, and again after any deploy, even if the user doesn't say "audit". CI green is not a substitute for this check.
|
Visitor-Grade Audit
You are verifying public-facing surfaces the way a first-time human visitor experiences
them — not the way a developer diffs them.
The failure this exists to catch: work gets verified by proxies — CI green, the diff
landed, a grep found the string you just added — while the artifact itself is broken for a
real visitor: dead links, invisible affordances, stale claims, internal jargon, bug history
dressed up as product copy. Proxy checks answer "did my change land?"; this audit answers
the only question that matters: does the thing work for the person it's for?
Scope — what counts as a public surface
Unless the user names the surfaces, discover them yourself and list them before auditing:
- Published websites / landing pages (GitHub Pages, docs sites, deployed apps)
- The repo front door (README as rendered on the host), org/profile pages
- Release pages (bodies, assets, published checksums)
- User-facing docs rendered on the host (manual, FAQ, status, changelog, architecture,
troubleshooting, walkthroughs, compatibility/provenance pages)
- Announcements, forum/discussion posts, published artifacts of any kind
Present the discovered list, then audit ALL of them (or the subset the user picks).
If a surface is behind a login or session you can't reach, label it unverifiable in
the report — never skip it silently.
Per-surface protocol — exactly two jobs, both mandatory
1. Read the ENTIRE surface, rendered, as its audience
Fetch the live/rendered version (the published URL, not the source file) whenever one
exists. Read top to bottom — not just recently-edited sections. Flag:
- Stale claims — anything contradicting the project's current released state.
Establish the canonical facts FIRST (current version, feature set, requirements) from
the release page / changelog, and audit against them. Ground every stale-claim finding
in the canonical fact it contradicts; no vibes.
- Bug history on marketing copy — a fixed bug belongs in the changelog; on a product
page it becomes a positive capability claim ("fully self-contained"), never a warning.
- Jargon leaks — internal terms or first-name/insider references in plain-audience
sections.
- Encoding damage / placeholders — mojibake (
â€"), broken formatting, <FILL IN>,
TODO, local file paths (C:\Users\..., Desktop\...).
- Misleading hierarchy — one item highlighted as special without a reason a visitor
would understand.
- Invisible affordances — interactive elements that don't look interactive. A link
styled
color:inherit with hover-only affordance reads as dead text; links must LOOK
like links.
2. Follow EVERY link. Count them. Report the count.
Run scripts/check_links.py on each surface for the mechanical pass, then apply judgment
to the results:
- Absolute URLs: final status after redirects must be 200. Record status per link.
- Relative links: resolve against the actual publish root, not the repo root. The
classic trap: GitHub Pages publishes only
/docs, so ../FILE.md on a published page
escapes the site and 404s even though it works when browsing the repo. Pass the publish
root with --base. For markdown rendered on the host, verify the target file/anchor
exists at that path on the default branch.
- A link that resolves but lands somewhere unhelpful (raw file where a rendered page was
intended, wrong section, generic page where a specific one was promised) is a finding —
the script can't see this; you check the landings yourself.
- Published checksums/sizes: re-derive them from the actual published asset and compare
to every place the value is quoted.
Orchestration
Fan out one auditor per surface, in parallel (Workflow or subagents when available;
sequential otherwise). Give each auditor its own working directory (a unique temp subdir)
for downloads and scratch files — parallel auditors sharing a scratchpad clobber each
other's evidence and corrupt link checks. Auditors are read-only and adversarial: their
job is to find what is broken, not to confirm it's fine. Each returns:
{ surface, links_checked: <number>,
findings: [ { location, issue, severity: blocker|major|minor|nit,
confirmed: true|false, suggested_fix } ] }
Severity: blocker = a visitor hits a dead end or a false claim (404, wrong version,
wrong hash); major = visibly broken/misleading (mojibake, invisible links, coherence
contradiction between surfaces); minor = jargon leaks, unhelpful landings, tone;
nit = polish.
confirmed: true means you followed the link / fetched the page yourself; false means
a suspicion you couldn't verify — always distinguish the two.
Reporting and the fix loop
- Report ALL findings, most severe first, including embarrassing ones — an empty report
is only acceptable when the surfaces are genuinely clean. Include per-surface link
counts so "checked" is a number, not a vibe.
- If the user wants fixes applied: fix, then re-run the audit against the LIVE published
surface after deploy (cache-bust; deploys lag). The audit isn't done until the
re-check of the published artifact is clean — verifying the source file is the same
proxy trap this skill exists to kill.
- Never claim "done" on the strength of CI alone. CI gates are one input; the visitor
pass is the exit criterion.
- Historical documents (changelogs, dated audit reports) correctly describe the past;
only flag claims about the CURRENT state.