[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CAS3JFA9TF1CEZ4YR2ZN4P":3,"skill-same:01M6CAS3JFA9TF1CEZ4YR2ZN4P":79},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":6,"ownerHtmlUrl":57,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":58,"install":59,"resources":72},"01M6CAS3JFA9TF1CEZ4YR2ZN4P","blocked-page-recovery",null,"Use when a fetch fails: 403\u002F429, paywall, WAF, bot wall.","adnichols\u002Fai-configs","adnichols","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F493746?v=4","01M6C33VRY9WF6XWYPT1AFA7JJ","Aaron Nichols","01M6C33VWTNKGRM92E9G643V4W",5,"MIT","https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fprofiles\u002Fwriting\u002Fskills\u002Fweb\u002Fblocked-page-recovery\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32],"recovery","page","blocked page recovery","macos","bot","linux","research","windows","waf","Citations","hermes","hermes agent","fetch","use","2026-11-10 10:12:30",false,"---\nname: blocked-page-recovery\ndescription: \"Use when a fetch fails: 403\u002F429, paywall, WAF, bot wall.\"\nversion: 1.0.0\nauthor: Hermes Agent\nlicense: MIT\nplatforms: [linux, macos, windows]\nmetadata:\n  hermes:\n    tags: [Research, Archives, Wayback, Paywall, WAF, Fallback]\n    related_skills: [grounded-citations]\n---\n\n# Blocked-Page Recovery\n\nWhen a page won't fetch — 403\u002F429, Cloudflare \"Just a moment...\", a paywall,\nor a bot-detection interstitial — don't give up and don't loop on the same\nURL. Third-party services often hold a **copy** of the page. Work down this\nladder, cheapest first.\n\n## The ladder\n\n```\n1. Wayback Machine  — archive.org \"available\" API  (snapshot + timestamp)\n2. archive.today    — domain rotation: archive.ph → .md → .li → .is\n3. Jina Reader      — only if JINA_API_KEY is set  (live server-side render)\n4. API-first pivot  — look for \u002Fapi\u002F, \u002Fgraphql, .json, or RSS on the same host\n5. Real browser     — browser tool as the last, most expensive resort\n```\n\nRun it in one shot with the bundled script:\n\n```bash\npython3 scripts\u002Frecover_page.py \"https:\u002F\u002Fexample.com\u002Fblocked-article\" --json\n```\n\nThe script tries each route in order, validates every body (see \"Fake\nsuccesses\" below), and prints the first genuine hit with its provenance.\n\n## Provenance discipline (non-negotiable)\n\nEvery recovered copy carries a provenance you MUST preserve when citing:\n\n| Route | Provenance | How to cite |\n|-------|-----------|-------------|\n| Wayback \u002F archive.today | `snapshot` | Cite WITH the snapshot date: \"as archived 2026-08-06\". Never present a snapshot as the live page — it may be stale. |\n| Jina Reader | `live` | Server-side re-render of the live page; cite normally. |\n| Live fetch \u002F browser | `live` | Cite normally. |\n\nIf the user needs *current* data (prices, availability, breaking news), a\nsnapshot is context, not an answer — say so explicitly and note its age.\n\n## Manual routes\n\n### 1. Wayback Machine (best provenance, try first)\n\n```bash\n# Discovery: returns closest snapshot URL + timestamp as JSON\ncurl -sL \"https:\u002F\u002Farchive.org\u002Fwayback\u002Favailable?url={URL}\"\n# Then fetch archived_snapshots.closest.url\n```\n\nFor enumerating many snapshots (or recovering deleted pages), the CDX index:\n\n```bash\ncurl -sL \"https:\u002F\u002Fweb.archive.org\u002Fcdx\u002Fsearch\u002Fcdx?url={URL}&output=json&limit=10\"\n```\n\nCDX intermittently returns 503 under load — if it does, fall back to the\n`available` API; don't retry-hammer it.\n\nWorks for: any publicly crawled URL. Fails for: robots-blocked sites,\nnever-crawled URLs, JS-only SPAs (snapshots don't render).\n\n### 2. archive.today (paywalls, deleted content)\n\nUser-submitted archives — often has paywalled news articles Wayback lacks.\nRate-limits aggressively (429) and rotates domains, so iterate:\n\n```bash\nfor d in archive.ph archive.md archive.li archive.is; do\n  curl -sL --max-time 20 \"https:\u002F\u002F$d\u002Fnewest\u002F{URL}\" -o ~\u002F.hermes\u002Fcache\u002Fscratch\u002Fpage.html \\\n    -w \"%{http_code}\" && break\ndone\n```\n\n**Validate the body, not the status code** — a 429 still ships several KB of\nrate-limit HTML that looks like a success to a size check alone.\n\n### 3. Jina Reader (requires JINA_API_KEY)\n\n`r.jina.ai` re-renders the live page in a real browser server-side and\nreturns markdown. Anonymous access is dead (401 → Turnstile); a key is\nrequired:\n\n```bash\ncurl -s -H \"Authorization: Bearer $JINA_API_KEY\" \"https:\u002F\u002Fr.jina.ai\u002F{URL}\"\n```\n\nHandles JS SPAs that archives can't. Skip this route entirely when the env\nvar is unset.\n\n### 4. API-first pivot\n\nWAFs protect the HTML surface far more aggressively than the data endpoints\nbehind it. After 2-3 blocked attempts on a site, stop fighting the HTML and\nlook for:\n\n- `\u002Fapi\u002F...`, `\u002Fgraphql`, or `.json` variants of the page URL\n- An RSS\u002FAtom feed (`\u002Ffeed`, `\u002Frss`, `\u003Clink rel=\"alternate\">` in any copy\n  you did recover)\n- A sitemap (`\u002Fsitemap.xml`) revealing canonical URLs that may not be gated\n\n## Fake successes — routes that LIE\n\nThese return HTTP 200 with a plausible body that is NOT the page. The script\nrejects them automatically; reject them manually too:\n\n- **Google Cache is dead** (since mid-2024). `webcache.googleusercontent.com`\n  returns 200 + tens of KB, but it's a Google Search interstitial with a JS\n  redirect, not a cache. Never use it.\n- **AMP caches** (`*.cdn.ampproject.org`) mostly return a ~300-byte\n  `\u003Ctitle>Redirecting\u003C\u002Ftitle>` meta-refresh stub pointing back at the\n  original (blocked) URL. Treating that as success creates a fetch loop.\n- **Rate-limit bodies**: archive.today 429 pages are multi-KB HTML. Check for\n  the target's actual content (title words, expected strings), not just size.\n\nDetection heuristics the script applies: body under a per-route byte floor;\nmeta-refresh\u002FJS-redirect stubs whose target is the original host; interstitial\ntitles (\"Just a moment\", \"Redirecting\", \"Google Search\", \"Attention Required\").\n\n## Proxy relays: don't\n\nGeneric \"web proxy\" relays are man-in-the-middle by construction. Never send\ncookies or Authorization headers through one, and don't use them for anything\nthe user will rely on — provenance is unverifiable. Prefer archives, which at\nleast timestamp their copies.\n","# Blocked-Page Recovery\n\nWhen a page won't fetch — 403\u002F429, Cloudflare \"Just a moment...\", a paywall,\nor a bot-detection interstitial — don't give up and don't loop on the same\nURL. Third-party services often hold a **copy** of the page. Work down this\nladder, cheapest first.\n\n## The ladder\n\n```\n1. Wayback Machine  — archive.org \"available\" API  (snapshot + timestamp)\n2. archive.today    — domain rotation: archive.ph → .md → .li → .is\n3. Jina Reader      — only if JINA_API_KEY is set  (live server-side render)\n4. API-first pivot  — look for \u002Fapi\u002F, \u002Fgraphql, .json, or RSS on the same host\n5. Real browser     — browser tool as the last, most expensive resort\n```\n\nRun it in one shot with the bundled script:\n\n```bash\npython3 scripts\u002Frecover_page.py \"https:\u002F\u002Fexample.com\u002Fblocked-article\" --json\n```\n\nThe script tries each route in order, validates every body (see \"Fake\nsuccesses\" below), and prints the first genuine hit with its provenance.\n\n## Provenance discipline (non-negotiable)\n\nEvery recovered copy carries a provenance you MUST preserve when citing:\n\n| Route | Provenance | How to cite |\n|-------|-----------|-------------|\n| Wayback \u002F archive.today | `snapshot` | Cite WITH the snapshot date: \"as archived 2026-08-06\". Never present a snapshot as the live page — it may be stale. |\n| Jina Reader | `live` | Server-side re-render of the live page; cite normally. |\n| Live fetch \u002F browser | `live` | Cite normally. |\n\nIf the user needs *current* data (prices, availability, breaking news), a\nsnapshot is context, not an answer — say so explicitly and note its age.\n\n## Manual routes\n\n### 1. Wayback Machine (best provenance, try first)\n\n```bash\n# Discovery: returns closest snapshot URL + timestamp as JSON\ncurl -sL \"https:\u002F\u002Farchive.org\u002Fwayback\u002Favailable?url={URL}\"\n# Then fetch archived_snapshots.closest.url\n```\n\nFor enumerating many snapshots (or recovering deleted pages), the CDX index:\n\n```bash\ncurl -sL \"https:\u002F\u002Fweb.archive.org\u002Fcdx\u002Fsearch\u002Fcdx?url={URL}&output=json&limit=10\"\n```\n\nCDX intermittently returns 503 under load — if it does, fall back to the\n`available` API; don't retry-hammer it.\n\nWorks for: any publicly crawled URL. Fails for: robots-blocked sites,\nnever-crawled URLs, JS-only SPAs (snapshots don't render).\n\n### 2. archive.today (paywalls, deleted content)\n\nUser-submitted archives — often has paywalled news articles Wayback lacks.\nRate-limits aggressively (429) and rotates domains, so iterate:\n\n```bash\nfor d in archive.ph archive.md archive.li archive.is; do\n  curl -sL --max-time 20 \"https:\u002F\u002F$d\u002Fnewest\u002F{URL}\" -o ~\u002F.hermes\u002Fcache\u002Fscratch\u002Fpage.html \\\n    -w \"%{http_code}\" && break\ndone\n```\n\n**Validate the body, not the status code** — a 429 still ships several KB of\nrate-limit HTML that looks like a success to a size check alone.\n\n### 3. Jina Reader (requires JINA_API_KEY)\n\n`r.jina.ai` re-renders the live page in a real browser server-side and\nreturns markdown. Anonymous access is dead (401 → Turnstile); a key is\nrequired:\n\n```bash\ncurl -s -H \"Authorization: Bearer $JINA_API_KEY\" \"https:\u002F\u002Fr.jina.ai\u002F{URL}\"\n```\n\nHandles JS SPAs that archives can't. Skip this route entirely when the env\nvar is unset.\n\n### 4. API-first pivot\n\nWAFs protect the HTML surface far more aggressively than the data endpoints\nbehind it. After 2-3 blocked attempts on a site, stop fighting the HTML and\nlook for:\n\n- `\u002Fapi\u002F...`, `\u002Fgraphql`, or `.json` variants of the page URL\n- An RSS\u002FAtom feed (`\u002Ffeed`, `\u002Frss`, `\u003Clink rel=\"alternate\">` in any copy\n  you did recover)\n- A sitemap (`\u002Fsitemap.xml`) revealing canonical URLs that may not be gated\n\n## Fake successes — routes that LIE\n\nThese return HTTP 200 with a plausible body that is NOT the page. The script\nrejects them automatically; reject them manually too:\n\n- **Google Cache is dead** (since mid-2024). `webcache.googleusercontent.com`\n  returns 200 + tens of KB, but it's a Google Search interstitial with a JS\n  redirect, not a cache. Never use it.\n- **AMP caches** (`*.cdn.ampproject.org`) mostly return a ~300-byte\n  `\u003Ctitle>Redirecting\u003C\u002Ftitle>` meta-refresh stub pointing back at the\n  original (blocked) URL. Treating that as success creates a fetch loop.\n- **Rate-limit bodies**: archive.today 429 pages are multi-KB HTML. Check for\n  the target's actual content (title words, expected strings), not just size.\n\nDetection heuristics the script applies: body under a per-route byte floor;\nmeta-refresh\u002FJS-redirect stubs whose target is the original host; interstitial\ntitles (\"Just a moment\", \"Redirecting\", \"Google Search\", \"Attention Required\").\n\n## Proxy relays: don't\n\nGeneric \"web proxy\" relays are man-in-the-middle by construction. Never send\ncookies or Authorization headers through one, and don't use them for anything\nthe user will rely on — provenance is unverifiable. Prefer archives, which at\nleast timestamp their copies.\n",{"name":5,"author":38,"license":15,"version":39,"metadata":40,"platforms":51,"description":7},"Hermes Agent","1.0.0",{"hermes":41},{"tags":42,"related_skills":49},[43,44,45,46,47,48],"Research","Archives","Wayback","Paywall","WAF","Fallback",[50],"grounded-citations",[24,22,26],"main","64e2fc9afa7bb3da1138eb73399144d0e7e73e9d","_hermes\u002Fdefault\u002Fprofiles\u002Fwriting\u002Fskills\u002Fweb\u002Fblocked-page-recovery",4,"https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs","https:\u002F\u002Fgithub.com\u002Fadnichols","2026-11-06 00:28:38",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add adnichols\u002Fai-configs --skill blocked-page-recovery",{"tool":65,"command":66},"bunx","bunx skills add adnichols\u002Fai-configs --skill blocked-page-recovery",{"tool":68,"command":69},"pnpm","pnpm dlx skills add adnichols\u002Fai-configs --skill blocked-page-recovery","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fprofiles\u002Fwriting\u002Fskills\u002Fweb\u002Fblocked-page-recovery\u002FSKILL.md",true,[73],{"path":74,"resourceType":75,"resourceTypeDesc":76,"sizeBytes":77,"sourceHtmlUrl":78},"scripts\u002Frecover_page.py","SCRIPT","脚本",8481,"https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fprofiles\u002Fwriting\u002Fskills\u002Fweb\u002Fblocked-page-recovery\u002Fscripts\u002Frecover_page.py",[80,86,120,145,156,172],{"skillNo":81,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":33},"01M6CB7RN791P5RRRCJWWC7DAR","https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fskills\u002Fweb\u002Fblocked-page-recovery\u002FSKILL.md",[],[19,20,21,23,85,32,31,30,29,28,27,26,25,24,22],"fallback",{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":105,"publishedAt":33},"01M6CB7NQY2VVYCQJ1QBXACQF4","writing-plans","Use when creating or updating executable software plans. Keep plans as local files unless the user explicitly asks to register them in Doct.","https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fskills\u002Fsoftware-development\u002Fwriting-plans\u002FSKILL.md",[92,97,100],{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":98,"categoryName":99,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":101,"categoryName":102,"taxonomyType":103,"taxonomyTypeDesc":104},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[106,107,108,109,110,111,112,113,114,115,116,117,32,118,30,29,119],"writing","writing plans","documentation","test","workflow","design","user","development","planning","files","implementation","html","ops","plan",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":135,"publishedAt":33},"01M6CB7JME246KZQHP73Z2STDF","test-driven-development","TDD: enforce RED-GREEN-REFACTOR, tests before code.","https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fskills\u002Fsoftware-development\u002Ftest-driven-development\u002FSKILL.md",[126,129,132],{"categoryNo":127,"categoryName":128,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":130,"categoryName":131,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":133,"categoryName":134,"taxonomyType":103,"taxonomyTypeDesc":104},"01JBSEEDCAT000000000000037","律师与法务",[109,113,136,137,138,30,29,139,119,140,141,142,22,143,24,144,26],"test driven development","red-green-refactor","superpowers","quality","refactor","code","debugging","tdd","testing",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":152,"publishedAt":33},"01M6CB7FQ407KQTD4Z9VAWKY54","systematic-debugging","4-phase root cause debugging: understand bugs before fixing.","https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fskills\u002Fsoftware-development\u002Fsystematic-debugging\u002FSKILL.md",[151],{"categoryNo":130,"categoryName":131,"taxonomyType":95,"taxonomyTypeDesc":96},[142,153,113,138,30,29,154,119,155,26,109,24,22],"systematic debugging","troubleshooting","investigation",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":165,"publishedAt":33},"01M6CB7D57MK88HE5YPZHKH68Q","spike","Throwaway experiments to validate an idea before build.","https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fskills\u002Fsoftware-development\u002Fspike\u002FSKILL.md",[162],{"categoryNo":163,"categoryName":164,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000021","资料检索与研究",[158,26,166,167,25,168,24,22,169,170,171,30,29,119,114],"validate","experiments","prototype","feasibility","sketch","experiment",{"skillNo":173,"name":174,"nameZh":6,"description":175,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":176,"categories":177,"keywords":182,"publishedAt":33},"01M6CB7APAQ37YE5YE1MAAFT42","simplify-code","Parallel 3-agent cleanup of recent code changes.","https:\u002F\u002Fgithub.com\u002Fadnichols\u002Fai-configs\u002Fblob\u002Fmain\u002F_hermes\u002Fdefault\u002Fskills\u002Fsoftware-development\u002Fsimplify-code\u002FSKILL.md",[178,179],{"categoryNo":98,"categoryName":99,"taxonomyType":95,"taxonomyTypeDesc":96},{"categoryNo":180,"categoryName":181,"taxonomyType":103,"taxonomyTypeDesc":104},"01JBSEEDCAT000000000000030","开发工程师",[183,184,141,185,30,29,186,119,140,187,188,189,113,26,109,24,190,22],"simplify code","simplify","subagent","parallel","code-review","delegation","cleanup","review"]