Link-Rot Detection
Concept of the skill
What it is: The scheduled audit mechanism that scans markdown content for external links that no longer resolve correctly. Mental model: Treat link checking as a batch health report, not a live page-rendering feature. Why it exists: Broken or redirected links erode trust quietly, so the project needs a repeatable scan with clear evidence. What it is NOT: It is not a one-off production incident investigation or UI design for broken-link badges. Adjacent concepts: Markdown link extraction, status-code classification, soft-404 detection, polite crawling. One-line analogy: It is a periodic inspection report for all outbound references. Common misconception: HTTP 200 means healthy; soft-404s, unrelated redirects, and rate-limit behavior also need interpretation.
Coverage
- Markdown link extraction — pulling every
[text](url)and[text][ref]reference link out of every.mdand.mdxfile in the content tree - External vs internal classification — what counts as external (different host) and what gets skipped (relative path, anchor link, mailto, tel)
- Status-code interpretation — 200 is healthy, 301/308 is a redirect (record the new URL but don't fail), 302/307 is transient (re-check next run), 404/410 is dead (flag), 5xx is transient (retry with backoff before flagging)
- Soft-404 detection — pages that return HTTP 200 but render an "unknown page" interstitial (compare body length / content against known soft-404 patterns)
- Rate-limiting and politeness — concurrent request budget per origin host, honoring
robots.txtcrawl-delay, exponential backoff on 429 - Reporting shape — the scanner's output is a structured report (JSON + markdown summary), not a live alert; the report is the audit artifact
Philosophy of the skill
External links rot. Every site that's older than two years has at least a few. The choice is between knowing about them on a schedule or finding out from a user. A periodic scan with a published report turns link health into a maintenance task instead of an emergency. The discipline is to be conservative — distinguish persistent failures (404 across 3 runs) from transient ones (one 503 on a Tuesday) — and to never let the scanner itself become a denial-of-service vector against the targets it's checking.
Verification
Before merging any change to the link-rot scanner or its config:
- The scanner extracts every link in
[text](url)and[text][ref]form from.mdand.mdxfiles; reference links resolve their targets before classification - Internal links (relative paths, same-host absolute, anchors, mailto, tel) are explicitly excluded — confirmed by a fixture test with mixed link types
- Persistent failures are distinguished from transient ones — a link is only flagged after N consecutive failures across separate runs (default N=3)
- The scanner respects per-host concurrency limits and honors
robots.txtcrawl-delay; a single host getting many requests in tight sequence is a bug - Soft-404 detection has a defined pattern set and an explicit "unknown" bucket for cases that don't match any known soft-404
- The scanner produces both a JSON report (machine-readable) and a markdown summary (human-readable) with link, status code, last-seen-OK timestamp, and recommendation
Do NOT Use When
| Use instead | When |
|---|---|
| (a frontend a11y / UX skill) | The task is rendering a "this link may be broken" badge in the live UI |
debugging |
A specific link broke for a specific user and you need to reproduce |
documentation |
The task is writing the link-health policy doc, not the scanner |
refactor |
The task is restructuring the scanner without changing the detection contract |