TheLearnDen Research Lab
Free Learning Resource Survival Index — Wave 1
What happened when 511 education-resource and carrying-page URLs were checked again after the original link-rot audit.
Made by TheLearnDen Research Lab · Checked 22 August 2026 · Updated
- URLs rechecked
- 511
- Dead URLs restored
- 0
- School carrying pages still live
- 93%
Run window: 2026-08-22T01:52:13.357Z to 2026-08-22T01:53:00.374Z (single pass, UK time approx via system clock) Baseline: 422 verified placements from data/research/link-rot-2026/verified-dataset.csv, originally checked 2026-08-07/08. Sampling: none — every deduplicated URL in all three sets was probed.
Recommendation
Treat every "resurrected" or "still live" number below as wave-1, single-probe evidence only — not a verdict to act on yet. The next gate before any outreach or replacement-link decision is a second independent check 24–48 hours apart (a site that answers once under load or DNS flap can look dead or alive by chance). I'd schedule Wave 2 for at least 24 hours after this run, then only escalate a URL to "confirmed" once two consecutive passes agree.
Headline finding
Of the 172 distinct dead URLs from the baseline that were re-probed today, none came back as a working page — a 0% resurrection rate. Link rot in this cohort reads as effectively permanent on a single check: nothing recorded dead in August is confirmed back today.
Method
Node 20 global fetch, browser-like User-Agent, 12s timeout per hop, redirects followed manually up to 5 hops (chain recorded), concurrency 8. Three URL sets were pulled from the baseline CSV and deduplicated before probing: (a) every deadUrl, (b) every carryingPageUrl, (c) every non-empty replacementUrl (site-relative paths resolved against https://thelearnden.com). Response body capped at 64KB for speed; first 300 characters of stripped text kept as evidence alongside the <title>.
The Twinkl rule: a 200 status with a challenge-page body (Cloudflare interstitial, "just a moment", bot-check) is never counted as proof the resource exists. Classification checks the body/title for challenge and soft-404 language before accepting a 200 as live-equivalent.
Network-error taxonomy (fixed after wave-1 review): a fetch failure is read off err.cause.code (or err.code/err.name) rather than lumped into a single bucket. ENOTFOUND/EAI_AGAIN → dns-fail (the domain genuinely does not resolve); CERT_/ERR_TLS_/ERR_SSL_*/DEPTH_ZERO_SELF_SIGNED_CERT/UNABLE_TO_VERIFY_LEAF_SIGNATURE → tls-fail (the host resolves and answers, but the certificate is broken); ECONNREFUSED → conn-refused; ECONNRESET → conn-reset; AbortError/ETIMEDOUT → timeout; anything else → fetch-error:<code>. A tls-fail gets one automatic retry over plain http://; if that comes back 200 with a real (non-404, non-challenge) page it is classified live-http-only — the resource exists, only the TLS handshake is broken, which is a different failure mode from the site being gone.
Set A — dead URLs (resurrection check)
Probed: 172 of 172 intended (dedup of 172 total distinct dead URLs in baseline).
| Classification | Count |
|---|---|
| dns-fail | 78 |
| tls-fail | 66 |
| hard-fail | 27 |
| fetch-error:ERR_INVALID_URL | 1 |
Resurrection rate overall: 0.0% (0 of 172 classified live-equivalent or redirect-useful).
By dead-resource site (top 15 by baseline row count)
| Site | Baseline rows | Probed today | Resurrected | Resurrection rate | Baseline deadVerdict mix | Today's errorCode mix |
|---|---|---|---|---|---|---|
| primaryhomeworkhelp.co.uk | 224 | 66 | 0 | 0.0% | dead-404-behind-tls:224 | ERR_TLS_CERT_ALTNAME_INVALID:66 |
| woodlands-junior.kent.sch.uk | 165 | 79 | 0 | 0.0% | dead-site-gone:165 | ENOTFOUND:78, ERR_INVALID_URL:1 |
| topmarks.co.uk | 32 | 26 | 0 | 0.0% | dead-404:32 | n/a:26 |
| teachingideas.co.uk | 1 | 1 | 0 | 0.0% | dead-404:1 | n/a:1 |
Set B — carrying pages (are the linking pages still up?)
Probed: 320 of 320 intended.
| Classification | Count |
|---|---|
| live-equivalent | 271 |
| redirect-useful | 31 |
| fetch-error:UND_ERR_CONNECT_TIMEOUT | 8 |
| timeout | 6 |
| hard-fail | 2 |
| conn-reset | 2 |
| Linking domain type | Probed | Still live | Survival rate |
|---|---|---|---|
| school | 257 | 239 | 93.0% |
| other | 19 | 19 | 100.0% |
| school-named | 44 | 44 | 100.0% |
Baseline vs today: the baseline treated every carrying page as verified live at capture time (carryingPageVerified); the survival rate above is today's independent recheck of the same pages, not a diff against a stored baseline status field (the CSV only records yes/no verified, not a classification).
Set C — replacement URLs (are our own suggested replacements still live?)
Probed: 19 of 19 intended.
| Replacement class | Probed | Still live | Survival rate |
|---|---|---|---|
| exact | 9 | 9 | 100.0% |
| hub | 10 | 8 | 80.0% |
Limitations
- Single probe. This is one pass at one point in time. No 24-hour or 7-day retry has run yet — that is the next gate, not a nice-to-have, before any URL is called "confirmed alive" or "confirmed dead."
- No human confirmation. Classification is heuristic (status code + title/body pattern match). Anything borderline (soft-404 patterns that didn't match, unusual challenge pages, JS-rendered content) needs a human to open the evidence snippet and check.
- 64KB body cap — a real page could theoretically have its title or 404 marker past that cutoff on very large HTML documents; unlikely but not zero.
- Sampling: none applied; full dedup sets were probed.
- Redirect classification (
redirect-usefulvsredirect-drift) uses a same-host/sibling-domain heuristic plus a root-path check for "generic hub" — it will misclassify a same-domain deep 404 fallback that happens to redirect to a real-looking but unrelated deep page.
Files
recheck-2026-08-22.jsonl— full per-URL records with evidencerecheck-2026-08-22.csv— same data, flat CSVsummary.json— machine-readable counts behind every table above