[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-automattic-qa":3,"mdc--jkrgdl-key":35,"related-repo-automattic-qa":1552,"related-org-automattic-qa":1665},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":24,"repoUrl":25,"updatedAt":26,"license":27,"forks":28,"topics":29,"repo":30,"sourceUrl":33,"mdContent":34},"qa","verify WXR content against source sites","Compare extracted WXR content against the original source site page by page. Find missing text, headings, images, and links. Fix by patching the WXR or re-extracting individual pages. Produces a health score and structured report. Use when asked to \"qa\", \"check extraction\", \"compare content\", or \"verify extraction quality\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"automattic","Automattic","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fautomattic.png",[12,16,18,21],{"name":13,"slug":14,"type":15},"Data Quality","data-quality","tag",{"name":17,"slug":4,"type":15},"QA",{"name":19,"slug":20,"type":15},"WordPress","wordpress",{"name":22,"slug":23,"type":15},"Testing","testing",31,"https:\u002F\u002Fgithub.com\u002FAutomattic\u002Fdata-liberation-agent","2026-05-10T05:48:09.926363",null,1,[],{"repoUrl":25,"stars":24,"forks":28,"topics":31,"description":32},[],"Extract content from closed web platforms into WordPress-compatible WXR files.","https:\u002F\u002Fgithub.com\u002FAutomattic\u002Fdata-liberation-agent\u002Ftree\u002FHEAD\u002Fskills\u002Fqa","---\nname: qa\ndescription: Compare extracted WXR content against the original source site page by page. Find missing text, headings, images, and links. Fix by patching the WXR or re-extracting individual pages. Produces a health score and structured report. Use when asked to \"qa\", \"check extraction\", \"compare content\", or \"verify extraction quality\".\nallowed-tools:\n  - Bash\n  - Read\n  - Write\n  - Edit\n  - Glob\n  - Grep\n  - AskUserQuestion\n---\n\n# QA: Compare → Fix → Verify\n\nYou are a QA engineer for content migrations. Compare every page in a WXR file against its original source URL — check that text, headings, images, and links made it through extraction intact. When you find gaps, fix them by patching the WXR or re-extracting the page. Produce a structured report with before\u002Fafter evidence.\n\n## Setup\n\n**Parse the user's request for these parameters:**\n\n| Parameter | Default | Override example |\n|-----------|---------|-----------------|\n| WXR file | Auto-detect `output.wxr` in the resolved site output dir | `\u003CoutputDir>\u002Foutput.wxr` |\n| Tier | Standard | `--quick`, `--exhaustive` |\n| Scope | All pages | `Focus on the blog posts` |\n\n**Tiers determine which issues get fixed:**\n- **Quick:** Fix critical (fail grade) only\n- **Standard:** Fix critical + warn grade (default)\n- **Exhaustive:** Fix all, including minor discrepancies\n\n**If no WXR path is given:** Call `liberate_paths({ url })` to resolve the site output dir (default base: `~\u002FStudio\u002F_liberations\u002F\u003Chost>`, overridable via `--output` \u002F `DLA_OUTPUT_DIR`). If the user has not provided a URL, ask for it. If multiple sites exist, ask which to QA.\n\n---\n\n## Workflow\n\n### Phase 1: Initialize\n\n1. Locate the WXR file\n2. Read it with `readWxr()` from `src\u002Flib\u002Fwxr-reader.ts`\n3. Count pages\u002Fposts with `_source_url` — these are testable\n4. Count pages\u002Fposts without `_source_url` — these are skipped (warn the user)\n5. Start timer for duration tracking\n\n### Phase 2: Compare\n\nFor each page\u002Fpost with a `_source_url`:\n\n1. **Fetch the origin page** via HTTP\n2. **Parse both** — origin HTML and WXR content — into a content model (text, headings, images, links) using `parseContent()` from `src\u002Flib\u002Fcontent-parser.ts`\n3. **Diff** using `diffContent()` from `src\u002Flib\u002Fcontent-differ.ts`\n4. **Grade** the page:\n   - **pass** (>90% weighted match) — content faithfully extracted\n   - **warn** (70-90%) — minor gaps\n   - **fail** (\u003C70%) — significant content missing\n   - **error** — fetch failed or page unreachable\n5. **Document immediately** — don't batch. Log each result.\n\n**Per-page checks:**\n\n| Dimension | What to check | Weight |\n|-----------|--------------|--------|\n| Text | Word-level similarity (Jaccard on word sets) | 50% |\n| Headings | h1-h6 count, text, order match | 20% |\n| Images | Count match, missing images by filename | 20% |\n| Links | Count match, missing hrefs | 10% |\n\n**Depth judgment:** Spend more attention on pages that fail — these need investigation. Pass pages just get logged.\n\n### Phase 3: Compute Health Score\n\n```\nContent Health Score (0-100):\n\n  Text fidelity (50%):\n    All pages pass     → 100\n    1-2 pages warn     → 80\n    1-2 pages fail     → 50\n    3+ pages fail      → 20\n\n  Heading fidelity (20%):\n    0 missing headings → 100\n    Each missing       → -10 (min 0)\n\n  Image fidelity (20%):\n    0 missing images   → 100\n    Each missing       → -15 (min 0)\n\n  Link fidelity (10%):\n    0 missing links    → 100\n    Each missing       → -10 (min 0)\n\n  score = Σ (dimension_score × weight)\n```\n\n### Phase 4: Report (Before Fixes)\n\nShow the comparison report to the user:\n\n**Per-page results:**\n```\nPage: \u002Fabout (https:\u002F\u002Fwww.example.com\u002Fabout)\n  Text:     98% ✓\n  Headings: 3\u002F3 ✓\n  Images:   2\u002F3 ⚠ missing: hero-banner.jpg\n  Links:    5\u002F5 ✓\n  Grade:    warn\n```\n\n**Summary:**\n```\nContent QA: 10 pages checked, 2 skipped (no source URL)\n  8 pass  1 warn  1 fail  0 error\n  Health score: 74\u002F100\n\n  Top issues:\n  1. \u002Fproject-3 [fail] — text similarity 42%, 3 missing images\n  2. \u002Fabout [warn] — 1 missing image (hero-banner.jpg)\n```\n\n### Phase 5: Triage\n\nSort issues by severity, then decide which to fix based on tier:\n\n- **Quick:** Fix `fail` grade only. Mark `warn` as deferred.\n- **Standard:** Fix `fail` + `warn`. (default)\n- **Exhaustive:** Fix all, including pages with minor discrepancies.\n\nMark pages with `error` grade (fetch failed) as deferred — can't fix what you can't compare.\n\n### Phase 6: Fix Loop\n\nFor each fixable page, in severity order (fail first, then warn):\n\n#### 6a. Assess\n\nRead the diff details. What's missing?\n- Missing alt text on existing images → **patchable**\n- Missing images entirely → **needs re-extraction**\n- Missing text sections → **needs re-extraction**\n- Minor text differences → **acceptable, skip**\n\n#### 6b. Fix\n\n**Level 1: Patch the WXR** (for minor fixes)\n- Run `runQa({ wxrFile, fix: true })` which patches missing alt text and minor gaps directly in the WXR\n\n**Level 2: Re-extract** (for major gaps)\n- If content is too far off (text similarity \u003C50%), the page needs full re-extraction\n- Flag it for the user: \"Page \u002Fproject-3 needs re-extraction — text similarity is 42%\"\n- If the user approves, re-run extraction for just that URL through the adapter\n\n#### 6c. Verify\n\nAfter fixes, re-run the comparison on fixed pages:\n```typescript\nconst result = await runQa({ wxrFile, fix: false });\n```\n\nCheck: did the fix improve the grade? If a fix made things worse, revert the WXR from the backup.\n\n#### 6d. Self-Regulation\n\nAfter every 5 fixes, evaluate:\n- Are the remaining issues actually fixable from the WXR?\n- Are we making things better or just churning?\n- If all remaining issues are `warn` with >80% similarity, stop — that's good enough.\n\n**Hard cap: 20 fix attempts.** After 20, stop and report.\n\n#### 6e. Escalate to \u002Fdiagnose\n\nIf after fixing, pages still have `fail` grades that can't be patched — especially if the failures share a pattern (e.g. all blog posts fail, all product pages are empty) — suggest running `\u002Fdiagnose` to investigate the root cause. QA finds the symptoms; diagnose finds the cause.\n\n### Phase 7: Final Report\n\nAfter all fixes:\n\n```\nContent QA Complete — 10 pages checked\n\n  Before: 74\u002F100  →  After: 92\u002F100\n\n  Fixed:\n    \u002Fabout — patched missing alt text on hero-banner.jpg (warn → pass)\n    \u002Fproject-3 — re-extracted (fail → pass)\n\n  Deferred:\n    \u002Fproject-5 — origin returns 404, cannot compare\n\n  Health score: 74 → 92 (+18)\n```\n\nInclude:\n- Total pages checked\n- Fix count (patched: X, re-extracted: Y)\n- Deferred issues with reasons\n- Health score delta: before → after\n\n---\n\n## Using the Code\n\n```typescript\nimport { runQa } from '.\u002Fsrc\u002Flib\u002Fqa-runner.js';\n\n\u002F\u002F Compare only (no fixes)\nconst result = await runQa({ wxrFile: '\u003CoutputDir>\u002Foutput.wxr' });\n\n\u002F\u002F Compare and fix\nconst fixResult = await runQa({ wxrFile: '\u003CoutputDir>\u002Foutput.wxr', fix: true });\n```\n\nThe `QaResult` contains:\n- `pages[]` — per-page results with slug, sourceUrl, grade, diff details\n- `skipped` — count of pages without `_source_url`\n- `summary` — { pass, warn, fail, error, fixed }\n\nThe QA log is written to `qa-log.jsonl` alongside the WXR file.\n\n---\n\n## Important Rules\n\n1. **Compare before fixing.** Always show the report first. Ask user before applying fixes.\n2. **Minimal fixes.** Patch what's safe (alt text, minor gaps). Flag major gaps for re-extraction.\n3. **Verify after fixing.** Re-run comparison on fixed pages. If the fix made things worse, revert.\n4. **No WordPress site needed.** QA compares the WXR against the origin site directly.\n5. **Log everything.** Every comparison and fix goes to `qa-log.jsonl`.\n6. **Don't over-fix.** Some text differences are acceptable (navigation, footers, cookie banners). Focus on the main content.\n7. **Pages without `_source_url` can't be QA'd.** Warn the user if many pages lack source URLs — they need re-extraction with a newer version that records source URLs.\n8. **Self-regulate.** Stop after 20 fix attempts or when remaining issues are minor.\n9. **Log discoveries.** If you find a pattern of content loss specific to a platform (e.g. \"Squarespace always drops image captions\"), add it to `DISCOVERIES.md` so future extractions can be improved.\n",{"data":36,"body":45},{"name":4,"description":6,"allowed-tools":37},[38,39,40,41,42,43,44],"Bash","Read","Write","Edit","Glob","Grep","AskUserQuestion",{"type":46,"children":47},"root",[48,57,63,70,79,195,203,238,280,284,290,297,355,361,373,495,503,601,611,617,629,635,640,648,657,665,674,680,685,742,754,760,765,772,777,819,825,835,851,861,879,885,890,985,990,996,1001,1026,1036,1042,1062,1068,1073,1082,1087,1110,1113,1119,1355,1368,1409,1422,1425,1431,1546],{"type":49,"tag":50,"props":51,"children":53},"element","h1",{"id":52},"qa-compare-fix-verify",[54],{"type":55,"value":56},"text","QA: Compare → Fix → Verify",{"type":49,"tag":58,"props":59,"children":60},"p",{},[61],{"type":55,"value":62},"You are a QA engineer for content migrations. Compare every page in a WXR file against its original source URL — check that text, headings, images, and links made it through extraction intact. When you find gaps, fix them by patching the WXR or re-extracting the page. Produce a structured report with before\u002Fafter evidence.",{"type":49,"tag":64,"props":65,"children":67},"h2",{"id":66},"setup",[68],{"type":55,"value":69},"Setup",{"type":49,"tag":58,"props":71,"children":72},{},[73],{"type":49,"tag":74,"props":75,"children":76},"strong",{},[77],{"type":55,"value":78},"Parse the user's request for these parameters:",{"type":49,"tag":80,"props":81,"children":82},"table",{},[83,107],{"type":49,"tag":84,"props":85,"children":86},"thead",{},[87],{"type":49,"tag":88,"props":89,"children":90},"tr",{},[91,97,102],{"type":49,"tag":92,"props":93,"children":94},"th",{},[95],{"type":55,"value":96},"Parameter",{"type":49,"tag":92,"props":98,"children":99},{},[100],{"type":55,"value":101},"Default",{"type":49,"tag":92,"props":103,"children":104},{},[105],{"type":55,"value":106},"Override example",{"type":49,"tag":108,"props":109,"children":110},"tbody",{},[111,143,173],{"type":49,"tag":88,"props":112,"children":113},{},[114,120,134],{"type":49,"tag":115,"props":116,"children":117},"td",{},[118],{"type":55,"value":119},"WXR file",{"type":49,"tag":115,"props":121,"children":122},{},[123,125,132],{"type":55,"value":124},"Auto-detect ",{"type":49,"tag":126,"props":127,"children":129},"code",{"className":128},[],[130],{"type":55,"value":131},"output.wxr",{"type":55,"value":133}," in the resolved site output dir",{"type":49,"tag":115,"props":135,"children":136},{},[137],{"type":49,"tag":126,"props":138,"children":140},{"className":139},[],[141],{"type":55,"value":142},"\u003CoutputDir>\u002Foutput.wxr",{"type":49,"tag":88,"props":144,"children":145},{},[146,151,156],{"type":49,"tag":115,"props":147,"children":148},{},[149],{"type":55,"value":150},"Tier",{"type":49,"tag":115,"props":152,"children":153},{},[154],{"type":55,"value":155},"Standard",{"type":49,"tag":115,"props":157,"children":158},{},[159,165,167],{"type":49,"tag":126,"props":160,"children":162},{"className":161},[],[163],{"type":55,"value":164},"--quick",{"type":55,"value":166},", ",{"type":49,"tag":126,"props":168,"children":170},{"className":169},[],[171],{"type":55,"value":172},"--exhaustive",{"type":49,"tag":88,"props":174,"children":175},{},[176,181,186],{"type":49,"tag":115,"props":177,"children":178},{},[179],{"type":55,"value":180},"Scope",{"type":49,"tag":115,"props":182,"children":183},{},[184],{"type":55,"value":185},"All pages",{"type":49,"tag":115,"props":187,"children":188},{},[189],{"type":49,"tag":126,"props":190,"children":192},{"className":191},[],[193],{"type":55,"value":194},"Focus on the blog posts",{"type":49,"tag":58,"props":196,"children":197},{},[198],{"type":49,"tag":74,"props":199,"children":200},{},[201],{"type":55,"value":202},"Tiers determine which issues get fixed:",{"type":49,"tag":204,"props":205,"children":206},"ul",{},[207,218,228],{"type":49,"tag":208,"props":209,"children":210},"li",{},[211,216],{"type":49,"tag":74,"props":212,"children":213},{},[214],{"type":55,"value":215},"Quick:",{"type":55,"value":217}," Fix critical (fail grade) only",{"type":49,"tag":208,"props":219,"children":220},{},[221,226],{"type":49,"tag":74,"props":222,"children":223},{},[224],{"type":55,"value":225},"Standard:",{"type":55,"value":227}," Fix critical + warn grade (default)",{"type":49,"tag":208,"props":229,"children":230},{},[231,236],{"type":49,"tag":74,"props":232,"children":233},{},[234],{"type":55,"value":235},"Exhaustive:",{"type":55,"value":237}," Fix all, including minor discrepancies",{"type":49,"tag":58,"props":239,"children":240},{},[241,246,248,254,256,262,264,270,272,278],{"type":49,"tag":74,"props":242,"children":243},{},[244],{"type":55,"value":245},"If no WXR path is given:",{"type":55,"value":247}," Call ",{"type":49,"tag":126,"props":249,"children":251},{"className":250},[],[252],{"type":55,"value":253},"liberate_paths({ url })",{"type":55,"value":255}," to resolve the site output dir (default base: ",{"type":49,"tag":126,"props":257,"children":259},{"className":258},[],[260],{"type":55,"value":261},"~\u002FStudio\u002F_liberations\u002F\u003Chost>",{"type":55,"value":263},", overridable via ",{"type":49,"tag":126,"props":265,"children":267},{"className":266},[],[268],{"type":55,"value":269},"--output",{"type":55,"value":271}," \u002F ",{"type":49,"tag":126,"props":273,"children":275},{"className":274},[],[276],{"type":55,"value":277},"DLA_OUTPUT_DIR",{"type":55,"value":279},"). If the user has not provided a URL, ask for it. If multiple sites exist, ask which to QA.",{"type":49,"tag":281,"props":282,"children":283},"hr",{},[],{"type":49,"tag":64,"props":285,"children":287},{"id":286},"workflow",[288],{"type":55,"value":289},"Workflow",{"type":49,"tag":291,"props":292,"children":294},"h3",{"id":293},"phase-1-initialize",[295],{"type":55,"value":296},"Phase 1: Initialize",{"type":49,"tag":298,"props":299,"children":300},"ol",{},[301,306,325,338,350],{"type":49,"tag":208,"props":302,"children":303},{},[304],{"type":55,"value":305},"Locate the WXR file",{"type":49,"tag":208,"props":307,"children":308},{},[309,311,317,319],{"type":55,"value":310},"Read it with ",{"type":49,"tag":126,"props":312,"children":314},{"className":313},[],[315],{"type":55,"value":316},"readWxr()",{"type":55,"value":318}," from ",{"type":49,"tag":126,"props":320,"children":322},{"className":321},[],[323],{"type":55,"value":324},"src\u002Flib\u002Fwxr-reader.ts",{"type":49,"tag":208,"props":326,"children":327},{},[328,330,336],{"type":55,"value":329},"Count pages\u002Fposts with ",{"type":49,"tag":126,"props":331,"children":333},{"className":332},[],[334],{"type":55,"value":335},"_source_url",{"type":55,"value":337}," — these are testable",{"type":49,"tag":208,"props":339,"children":340},{},[341,343,348],{"type":55,"value":342},"Count pages\u002Fposts without ",{"type":49,"tag":126,"props":344,"children":346},{"className":345},[],[347],{"type":55,"value":335},{"type":55,"value":349}," — these are skipped (warn the user)",{"type":49,"tag":208,"props":351,"children":352},{},[353],{"type":55,"value":354},"Start timer for duration tracking",{"type":49,"tag":291,"props":356,"children":358},{"id":357},"phase-2-compare",[359],{"type":55,"value":360},"Phase 2: Compare",{"type":49,"tag":58,"props":362,"children":363},{},[364,366,371],{"type":55,"value":365},"For each page\u002Fpost with a ",{"type":49,"tag":126,"props":367,"children":369},{"className":368},[],[370],{"type":55,"value":335},{"type":55,"value":372},":",{"type":49,"tag":298,"props":374,"children":375},{},[376,386,409,432,485],{"type":49,"tag":208,"props":377,"children":378},{},[379,384],{"type":49,"tag":74,"props":380,"children":381},{},[382],{"type":55,"value":383},"Fetch the origin page",{"type":55,"value":385}," via HTTP",{"type":49,"tag":208,"props":387,"children":388},{},[389,394,396,402,403],{"type":49,"tag":74,"props":390,"children":391},{},[392],{"type":55,"value":393},"Parse both",{"type":55,"value":395}," — origin HTML and WXR content — into a content model (text, headings, images, links) using ",{"type":49,"tag":126,"props":397,"children":399},{"className":398},[],[400],{"type":55,"value":401},"parseContent()",{"type":55,"value":318},{"type":49,"tag":126,"props":404,"children":406},{"className":405},[],[407],{"type":55,"value":408},"src\u002Flib\u002Fcontent-parser.ts",{"type":49,"tag":208,"props":410,"children":411},{},[412,417,419,425,426],{"type":49,"tag":74,"props":413,"children":414},{},[415],{"type":55,"value":416},"Diff",{"type":55,"value":418}," using ",{"type":49,"tag":126,"props":420,"children":422},{"className":421},[],[423],{"type":55,"value":424},"diffContent()",{"type":55,"value":318},{"type":49,"tag":126,"props":427,"children":429},{"className":428},[],[430],{"type":55,"value":431},"src\u002Flib\u002Fcontent-differ.ts",{"type":49,"tag":208,"props":433,"children":434},{},[435,440,442],{"type":49,"tag":74,"props":436,"children":437},{},[438],{"type":55,"value":439},"Grade",{"type":55,"value":441}," the page:\n",{"type":49,"tag":204,"props":443,"children":444},{},[445,455,465,475],{"type":49,"tag":208,"props":446,"children":447},{},[448,453],{"type":49,"tag":74,"props":449,"children":450},{},[451],{"type":55,"value":452},"pass",{"type":55,"value":454}," (>90% weighted match) — content faithfully extracted",{"type":49,"tag":208,"props":456,"children":457},{},[458,463],{"type":49,"tag":74,"props":459,"children":460},{},[461],{"type":55,"value":462},"warn",{"type":55,"value":464}," (70-90%) — minor gaps",{"type":49,"tag":208,"props":466,"children":467},{},[468,473],{"type":49,"tag":74,"props":469,"children":470},{},[471],{"type":55,"value":472},"fail",{"type":55,"value":474}," (\u003C70%) — significant content missing",{"type":49,"tag":208,"props":476,"children":477},{},[478,483],{"type":49,"tag":74,"props":479,"children":480},{},[481],{"type":55,"value":482},"error",{"type":55,"value":484}," — fetch failed or page unreachable",{"type":49,"tag":208,"props":486,"children":487},{},[488,493],{"type":49,"tag":74,"props":489,"children":490},{},[491],{"type":55,"value":492},"Document immediately",{"type":55,"value":494}," — don't batch. Log each result.",{"type":49,"tag":58,"props":496,"children":497},{},[498],{"type":49,"tag":74,"props":499,"children":500},{},[501],{"type":55,"value":502},"Per-page checks:",{"type":49,"tag":80,"props":504,"children":505},{},[506,527],{"type":49,"tag":84,"props":507,"children":508},{},[509],{"type":49,"tag":88,"props":510,"children":511},{},[512,517,522],{"type":49,"tag":92,"props":513,"children":514},{},[515],{"type":55,"value":516},"Dimension",{"type":49,"tag":92,"props":518,"children":519},{},[520],{"type":55,"value":521},"What to check",{"type":49,"tag":92,"props":523,"children":524},{},[525],{"type":55,"value":526},"Weight",{"type":49,"tag":108,"props":528,"children":529},{},[530,548,566,583],{"type":49,"tag":88,"props":531,"children":532},{},[533,538,543],{"type":49,"tag":115,"props":534,"children":535},{},[536],{"type":55,"value":537},"Text",{"type":49,"tag":115,"props":539,"children":540},{},[541],{"type":55,"value":542},"Word-level similarity (Jaccard on word sets)",{"type":49,"tag":115,"props":544,"children":545},{},[546],{"type":55,"value":547},"50%",{"type":49,"tag":88,"props":549,"children":550},{},[551,556,561],{"type":49,"tag":115,"props":552,"children":553},{},[554],{"type":55,"value":555},"Headings",{"type":49,"tag":115,"props":557,"children":558},{},[559],{"type":55,"value":560},"h1-h6 count, text, order match",{"type":49,"tag":115,"props":562,"children":563},{},[564],{"type":55,"value":565},"20%",{"type":49,"tag":88,"props":567,"children":568},{},[569,574,579],{"type":49,"tag":115,"props":570,"children":571},{},[572],{"type":55,"value":573},"Images",{"type":49,"tag":115,"props":575,"children":576},{},[577],{"type":55,"value":578},"Count match, missing images by filename",{"type":49,"tag":115,"props":580,"children":581},{},[582],{"type":55,"value":565},{"type":49,"tag":88,"props":584,"children":585},{},[586,591,596],{"type":49,"tag":115,"props":587,"children":588},{},[589],{"type":55,"value":590},"Links",{"type":49,"tag":115,"props":592,"children":593},{},[594],{"type":55,"value":595},"Count match, missing hrefs",{"type":49,"tag":115,"props":597,"children":598},{},[599],{"type":55,"value":600},"10%",{"type":49,"tag":58,"props":602,"children":603},{},[604,609],{"type":49,"tag":74,"props":605,"children":606},{},[607],{"type":55,"value":608},"Depth judgment:",{"type":55,"value":610}," Spend more attention on pages that fail — these need investigation. Pass pages just get logged.",{"type":49,"tag":291,"props":612,"children":614},{"id":613},"phase-3-compute-health-score",[615],{"type":55,"value":616},"Phase 3: Compute Health Score",{"type":49,"tag":618,"props":619,"children":623},"pre",{"className":620,"code":622,"language":55},[621],"language-text","Content Health Score (0-100):\n\n  Text fidelity (50%):\n    All pages pass     → 100\n    1-2 pages warn     → 80\n    1-2 pages fail     → 50\n    3+ pages fail      → 20\n\n  Heading fidelity (20%):\n    0 missing headings → 100\n    Each missing       → -10 (min 0)\n\n  Image fidelity (20%):\n    0 missing images   → 100\n    Each missing       → -15 (min 0)\n\n  Link fidelity (10%):\n    0 missing links    → 100\n    Each missing       → -10 (min 0)\n\n  score = Σ (dimension_score × weight)\n",[624],{"type":49,"tag":126,"props":625,"children":627},{"__ignoreMap":626},"",[628],{"type":55,"value":622},{"type":49,"tag":291,"props":630,"children":632},{"id":631},"phase-4-report-before-fixes",[633],{"type":55,"value":634},"Phase 4: Report (Before Fixes)",{"type":49,"tag":58,"props":636,"children":637},{},[638],{"type":55,"value":639},"Show the comparison report to the user:",{"type":49,"tag":58,"props":641,"children":642},{},[643],{"type":49,"tag":74,"props":644,"children":645},{},[646],{"type":55,"value":647},"Per-page results:",{"type":49,"tag":618,"props":649,"children":652},{"className":650,"code":651,"language":55},[621],"Page: \u002Fabout (https:\u002F\u002Fwww.example.com\u002Fabout)\n  Text:     98% ✓\n  Headings: 3\u002F3 ✓\n  Images:   2\u002F3 ⚠ missing: hero-banner.jpg\n  Links:    5\u002F5 ✓\n  Grade:    warn\n",[653],{"type":49,"tag":126,"props":654,"children":655},{"__ignoreMap":626},[656],{"type":55,"value":651},{"type":49,"tag":58,"props":658,"children":659},{},[660],{"type":49,"tag":74,"props":661,"children":662},{},[663],{"type":55,"value":664},"Summary:",{"type":49,"tag":618,"props":666,"children":669},{"className":667,"code":668,"language":55},[621],"Content QA: 10 pages checked, 2 skipped (no source URL)\n  8 pass  1 warn  1 fail  0 error\n  Health score: 74\u002F100\n\n  Top issues:\n  1. \u002Fproject-3 [fail] — text similarity 42%, 3 missing images\n  2. \u002Fabout [warn] — 1 missing image (hero-banner.jpg)\n",[670],{"type":49,"tag":126,"props":671,"children":672},{"__ignoreMap":626},[673],{"type":55,"value":668},{"type":49,"tag":291,"props":675,"children":677},{"id":676},"phase-5-triage",[678],{"type":55,"value":679},"Phase 5: Triage",{"type":49,"tag":58,"props":681,"children":682},{},[683],{"type":55,"value":684},"Sort issues by severity, then decide which to fix based on tier:",{"type":49,"tag":204,"props":686,"children":687},{},[688,711,733],{"type":49,"tag":208,"props":689,"children":690},{},[691,695,697,702,704,709],{"type":49,"tag":74,"props":692,"children":693},{},[694],{"type":55,"value":215},{"type":55,"value":696}," Fix ",{"type":49,"tag":126,"props":698,"children":700},{"className":699},[],[701],{"type":55,"value":472},{"type":55,"value":703}," grade only. Mark ",{"type":49,"tag":126,"props":705,"children":707},{"className":706},[],[708],{"type":55,"value":462},{"type":55,"value":710}," as deferred.",{"type":49,"tag":208,"props":712,"children":713},{},[714,718,719,724,726,731],{"type":49,"tag":74,"props":715,"children":716},{},[717],{"type":55,"value":225},{"type":55,"value":696},{"type":49,"tag":126,"props":720,"children":722},{"className":721},[],[723],{"type":55,"value":472},{"type":55,"value":725}," + ",{"type":49,"tag":126,"props":727,"children":729},{"className":728},[],[730],{"type":55,"value":462},{"type":55,"value":732},". (default)",{"type":49,"tag":208,"props":734,"children":735},{},[736,740],{"type":49,"tag":74,"props":737,"children":738},{},[739],{"type":55,"value":235},{"type":55,"value":741}," Fix all, including pages with minor discrepancies.",{"type":49,"tag":58,"props":743,"children":744},{},[745,747,752],{"type":55,"value":746},"Mark pages with ",{"type":49,"tag":126,"props":748,"children":750},{"className":749},[],[751],{"type":55,"value":482},{"type":55,"value":753}," grade (fetch failed) as deferred — can't fix what you can't compare.",{"type":49,"tag":291,"props":755,"children":757},{"id":756},"phase-6-fix-loop",[758],{"type":55,"value":759},"Phase 6: Fix Loop",{"type":49,"tag":58,"props":761,"children":762},{},[763],{"type":55,"value":764},"For each fixable page, in severity order (fail first, then warn):",{"type":49,"tag":766,"props":767,"children":769},"h4",{"id":768},"_6a-assess",[770],{"type":55,"value":771},"6a. Assess",{"type":49,"tag":58,"props":773,"children":774},{},[775],{"type":55,"value":776},"Read the diff details. What's missing?",{"type":49,"tag":204,"props":778,"children":779},{},[780,790,800,809],{"type":49,"tag":208,"props":781,"children":782},{},[783,785],{"type":55,"value":784},"Missing alt text on existing images → ",{"type":49,"tag":74,"props":786,"children":787},{},[788],{"type":55,"value":789},"patchable",{"type":49,"tag":208,"props":791,"children":792},{},[793,795],{"type":55,"value":794},"Missing images entirely → ",{"type":49,"tag":74,"props":796,"children":797},{},[798],{"type":55,"value":799},"needs re-extraction",{"type":49,"tag":208,"props":801,"children":802},{},[803,805],{"type":55,"value":804},"Missing text sections → ",{"type":49,"tag":74,"props":806,"children":807},{},[808],{"type":55,"value":799},{"type":49,"tag":208,"props":810,"children":811},{},[812,814],{"type":55,"value":813},"Minor text differences → ",{"type":49,"tag":74,"props":815,"children":816},{},[817],{"type":55,"value":818},"acceptable, skip",{"type":49,"tag":766,"props":820,"children":822},{"id":821},"_6b-fix",[823],{"type":55,"value":824},"6b. Fix",{"type":49,"tag":58,"props":826,"children":827},{},[828,833],{"type":49,"tag":74,"props":829,"children":830},{},[831],{"type":55,"value":832},"Level 1: Patch the WXR",{"type":55,"value":834}," (for minor fixes)",{"type":49,"tag":204,"props":836,"children":837},{},[838],{"type":49,"tag":208,"props":839,"children":840},{},[841,843,849],{"type":55,"value":842},"Run ",{"type":49,"tag":126,"props":844,"children":846},{"className":845},[],[847],{"type":55,"value":848},"runQa({ wxrFile, fix: true })",{"type":55,"value":850}," which patches missing alt text and minor gaps directly in the WXR",{"type":49,"tag":58,"props":852,"children":853},{},[854,859],{"type":49,"tag":74,"props":855,"children":856},{},[857],{"type":55,"value":858},"Level 2: Re-extract",{"type":55,"value":860}," (for major gaps)",{"type":49,"tag":204,"props":862,"children":863},{},[864,869,874],{"type":49,"tag":208,"props":865,"children":866},{},[867],{"type":55,"value":868},"If content is too far off (text similarity \u003C50%), the page needs full re-extraction",{"type":49,"tag":208,"props":870,"children":871},{},[872],{"type":55,"value":873},"Flag it for the user: \"Page \u002Fproject-3 needs re-extraction — text similarity is 42%\"",{"type":49,"tag":208,"props":875,"children":876},{},[877],{"type":55,"value":878},"If the user approves, re-run extraction for just that URL through the adapter",{"type":49,"tag":766,"props":880,"children":882},{"id":881},"_6c-verify",[883],{"type":55,"value":884},"6c. Verify",{"type":49,"tag":58,"props":886,"children":887},{},[888],{"type":55,"value":889},"After fixes, re-run the comparison on fixed pages:",{"type":49,"tag":618,"props":891,"children":895},{"className":892,"code":893,"language":894,"meta":626,"style":626},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const result = await runQa({ wxrFile, fix: false });\n","typescript",[896],{"type":49,"tag":126,"props":897,"children":898},{"__ignoreMap":626},[899],{"type":49,"tag":900,"props":901,"children":903},"span",{"class":902,"line":28},"line",[904,910,916,922,928,934,939,944,949,954,960,964,970,975,980],{"type":49,"tag":900,"props":905,"children":907},{"style":906},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[908],{"type":55,"value":909},"const",{"type":49,"tag":900,"props":911,"children":913},{"style":912},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[914],{"type":55,"value":915}," result ",{"type":49,"tag":900,"props":917,"children":919},{"style":918},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[920],{"type":55,"value":921},"=",{"type":49,"tag":900,"props":923,"children":925},{"style":924},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[926],{"type":55,"value":927}," await",{"type":49,"tag":900,"props":929,"children":931},{"style":930},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[932],{"type":55,"value":933}," runQa",{"type":49,"tag":900,"props":935,"children":936},{"style":912},[937],{"type":55,"value":938},"(",{"type":49,"tag":900,"props":940,"children":941},{"style":918},[942],{"type":55,"value":943},"{",{"type":49,"tag":900,"props":945,"children":946},{"style":912},[947],{"type":55,"value":948}," wxrFile",{"type":49,"tag":900,"props":950,"children":951},{"style":918},[952],{"type":55,"value":953},",",{"type":49,"tag":900,"props":955,"children":957},{"style":956},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[958],{"type":55,"value":959}," fix",{"type":49,"tag":900,"props":961,"children":962},{"style":918},[963],{"type":55,"value":372},{"type":49,"tag":900,"props":965,"children":967},{"style":966},"--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC",[968],{"type":55,"value":969}," false",{"type":49,"tag":900,"props":971,"children":972},{"style":918},[973],{"type":55,"value":974}," }",{"type":49,"tag":900,"props":976,"children":977},{"style":912},[978],{"type":55,"value":979},")",{"type":49,"tag":900,"props":981,"children":982},{"style":918},[983],{"type":55,"value":984},";\n",{"type":49,"tag":58,"props":986,"children":987},{},[988],{"type":55,"value":989},"Check: did the fix improve the grade? If a fix made things worse, revert the WXR from the backup.",{"type":49,"tag":766,"props":991,"children":993},{"id":992},"_6d-self-regulation",[994],{"type":55,"value":995},"6d. Self-Regulation",{"type":49,"tag":58,"props":997,"children":998},{},[999],{"type":55,"value":1000},"After every 5 fixes, evaluate:",{"type":49,"tag":204,"props":1002,"children":1003},{},[1004,1009,1014],{"type":49,"tag":208,"props":1005,"children":1006},{},[1007],{"type":55,"value":1008},"Are the remaining issues actually fixable from the WXR?",{"type":49,"tag":208,"props":1010,"children":1011},{},[1012],{"type":55,"value":1013},"Are we making things better or just churning?",{"type":49,"tag":208,"props":1015,"children":1016},{},[1017,1019,1024],{"type":55,"value":1018},"If all remaining issues are ",{"type":49,"tag":126,"props":1020,"children":1022},{"className":1021},[],[1023],{"type":55,"value":462},{"type":55,"value":1025}," with >80% similarity, stop — that's good enough.",{"type":49,"tag":58,"props":1027,"children":1028},{},[1029,1034],{"type":49,"tag":74,"props":1030,"children":1031},{},[1032],{"type":55,"value":1033},"Hard cap: 20 fix attempts.",{"type":55,"value":1035}," After 20, stop and report.",{"type":49,"tag":766,"props":1037,"children":1039},{"id":1038},"_6e-escalate-to-diagnose",[1040],{"type":55,"value":1041},"6e. Escalate to \u002Fdiagnose",{"type":49,"tag":58,"props":1043,"children":1044},{},[1045,1047,1052,1054,1060],{"type":55,"value":1046},"If after fixing, pages still have ",{"type":49,"tag":126,"props":1048,"children":1050},{"className":1049},[],[1051],{"type":55,"value":472},{"type":55,"value":1053}," grades that can't be patched — especially if the failures share a pattern (e.g. all blog posts fail, all product pages are empty) — suggest running ",{"type":49,"tag":126,"props":1055,"children":1057},{"className":1056},[],[1058],{"type":55,"value":1059},"\u002Fdiagnose",{"type":55,"value":1061}," to investigate the root cause. QA finds the symptoms; diagnose finds the cause.",{"type":49,"tag":291,"props":1063,"children":1065},{"id":1064},"phase-7-final-report",[1066],{"type":55,"value":1067},"Phase 7: Final Report",{"type":49,"tag":58,"props":1069,"children":1070},{},[1071],{"type":55,"value":1072},"After all fixes:",{"type":49,"tag":618,"props":1074,"children":1077},{"className":1075,"code":1076,"language":55},[621],"Content QA Complete — 10 pages checked\n\n  Before: 74\u002F100  →  After: 92\u002F100\n\n  Fixed:\n    \u002Fabout — patched missing alt text on hero-banner.jpg (warn → pass)\n    \u002Fproject-3 — re-extracted (fail → pass)\n\n  Deferred:\n    \u002Fproject-5 — origin returns 404, cannot compare\n\n  Health score: 74 → 92 (+18)\n",[1078],{"type":49,"tag":126,"props":1079,"children":1080},{"__ignoreMap":626},[1081],{"type":55,"value":1076},{"type":49,"tag":58,"props":1083,"children":1084},{},[1085],{"type":55,"value":1086},"Include:",{"type":49,"tag":204,"props":1088,"children":1089},{},[1090,1095,1100,1105],{"type":49,"tag":208,"props":1091,"children":1092},{},[1093],{"type":55,"value":1094},"Total pages checked",{"type":49,"tag":208,"props":1096,"children":1097},{},[1098],{"type":55,"value":1099},"Fix count (patched: X, re-extracted: Y)",{"type":49,"tag":208,"props":1101,"children":1102},{},[1103],{"type":55,"value":1104},"Deferred issues with reasons",{"type":49,"tag":208,"props":1106,"children":1107},{},[1108],{"type":55,"value":1109},"Health score delta: before → after",{"type":49,"tag":281,"props":1111,"children":1112},{},[],{"type":49,"tag":64,"props":1114,"children":1116},{"id":1115},"using-the-code",[1117],{"type":55,"value":1118},"Using the Code",{"type":49,"tag":618,"props":1120,"children":1122},{"className":892,"code":1121,"language":894,"meta":626,"style":626},"import { runQa } from '.\u002Fsrc\u002Flib\u002Fqa-runner.js';\n\n\u002F\u002F Compare only (no fixes)\nconst result = await runQa({ wxrFile: '\u003CoutputDir>\u002Foutput.wxr' });\n\n\u002F\u002F Compare and fix\nconst fixResult = await runQa({ wxrFile: '\u003CoutputDir>\u002Foutput.wxr', fix: true });\n",[1123],{"type":49,"tag":126,"props":1124,"children":1125},{"__ignoreMap":626},[1126,1172,1182,1192,1256,1264,1273],{"type":49,"tag":900,"props":1127,"children":1128},{"class":902,"line":28},[1129,1134,1139,1143,1147,1152,1157,1163,1168],{"type":49,"tag":900,"props":1130,"children":1131},{"style":924},[1132],{"type":55,"value":1133},"import",{"type":49,"tag":900,"props":1135,"children":1136},{"style":918},[1137],{"type":55,"value":1138}," {",{"type":49,"tag":900,"props":1140,"children":1141},{"style":912},[1142],{"type":55,"value":933},{"type":49,"tag":900,"props":1144,"children":1145},{"style":918},[1146],{"type":55,"value":974},{"type":49,"tag":900,"props":1148,"children":1149},{"style":924},[1150],{"type":55,"value":1151}," from",{"type":49,"tag":900,"props":1153,"children":1154},{"style":918},[1155],{"type":55,"value":1156}," '",{"type":49,"tag":900,"props":1158,"children":1160},{"style":1159},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[1161],{"type":55,"value":1162},".\u002Fsrc\u002Flib\u002Fqa-runner.js",{"type":49,"tag":900,"props":1164,"children":1165},{"style":918},[1166],{"type":55,"value":1167},"'",{"type":49,"tag":900,"props":1169,"children":1170},{"style":918},[1171],{"type":55,"value":984},{"type":49,"tag":900,"props":1173,"children":1175},{"class":902,"line":1174},2,[1176],{"type":49,"tag":900,"props":1177,"children":1179},{"emptyLinePlaceholder":1178},true,[1180],{"type":55,"value":1181},"\n",{"type":49,"tag":900,"props":1183,"children":1185},{"class":902,"line":1184},3,[1186],{"type":49,"tag":900,"props":1187,"children":1189},{"style":1188},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1190],{"type":55,"value":1191},"\u002F\u002F Compare only (no fixes)\n",{"type":49,"tag":900,"props":1193,"children":1195},{"class":902,"line":1194},4,[1196,1200,1204,1208,1212,1216,1220,1224,1228,1232,1236,1240,1244,1248,1252],{"type":49,"tag":900,"props":1197,"children":1198},{"style":906},[1199],{"type":55,"value":909},{"type":49,"tag":900,"props":1201,"children":1202},{"style":912},[1203],{"type":55,"value":915},{"type":49,"tag":900,"props":1205,"children":1206},{"style":918},[1207],{"type":55,"value":921},{"type":49,"tag":900,"props":1209,"children":1210},{"style":924},[1211],{"type":55,"value":927},{"type":49,"tag":900,"props":1213,"children":1214},{"style":930},[1215],{"type":55,"value":933},{"type":49,"tag":900,"props":1217,"children":1218},{"style":912},[1219],{"type":55,"value":938},{"type":49,"tag":900,"props":1221,"children":1222},{"style":918},[1223],{"type":55,"value":943},{"type":49,"tag":900,"props":1225,"children":1226},{"style":956},[1227],{"type":55,"value":948},{"type":49,"tag":900,"props":1229,"children":1230},{"style":918},[1231],{"type":55,"value":372},{"type":49,"tag":900,"props":1233,"children":1234},{"style":918},[1235],{"type":55,"value":1156},{"type":49,"tag":900,"props":1237,"children":1238},{"style":1159},[1239],{"type":55,"value":142},{"type":49,"tag":900,"props":1241,"children":1242},{"style":918},[1243],{"type":55,"value":1167},{"type":49,"tag":900,"props":1245,"children":1246},{"style":918},[1247],{"type":55,"value":974},{"type":49,"tag":900,"props":1249,"children":1250},{"style":912},[1251],{"type":55,"value":979},{"type":49,"tag":900,"props":1253,"children":1254},{"style":918},[1255],{"type":55,"value":984},{"type":49,"tag":900,"props":1257,"children":1259},{"class":902,"line":1258},5,[1260],{"type":49,"tag":900,"props":1261,"children":1262},{"emptyLinePlaceholder":1178},[1263],{"type":55,"value":1181},{"type":49,"tag":900,"props":1265,"children":1267},{"class":902,"line":1266},6,[1268],{"type":49,"tag":900,"props":1269,"children":1270},{"style":1188},[1271],{"type":55,"value":1272},"\u002F\u002F Compare and fix\n",{"type":49,"tag":900,"props":1274,"children":1276},{"class":902,"line":1275},7,[1277,1281,1286,1290,1294,1298,1302,1306,1310,1314,1318,1322,1326,1330,1334,1338,1343,1347,1351],{"type":49,"tag":900,"props":1278,"children":1279},{"style":906},[1280],{"type":55,"value":909},{"type":49,"tag":900,"props":1282,"children":1283},{"style":912},[1284],{"type":55,"value":1285}," fixResult ",{"type":49,"tag":900,"props":1287,"children":1288},{"style":918},[1289],{"type":55,"value":921},{"type":49,"tag":900,"props":1291,"children":1292},{"style":924},[1293],{"type":55,"value":927},{"type":49,"tag":900,"props":1295,"children":1296},{"style":930},[1297],{"type":55,"value":933},{"type":49,"tag":900,"props":1299,"children":1300},{"style":912},[1301],{"type":55,"value":938},{"type":49,"tag":900,"props":1303,"children":1304},{"style":918},[1305],{"type":55,"value":943},{"type":49,"tag":900,"props":1307,"children":1308},{"style":956},[1309],{"type":55,"value":948},{"type":49,"tag":900,"props":1311,"children":1312},{"style":918},[1313],{"type":55,"value":372},{"type":49,"tag":900,"props":1315,"children":1316},{"style":918},[1317],{"type":55,"value":1156},{"type":49,"tag":900,"props":1319,"children":1320},{"style":1159},[1321],{"type":55,"value":142},{"type":49,"tag":900,"props":1323,"children":1324},{"style":918},[1325],{"type":55,"value":1167},{"type":49,"tag":900,"props":1327,"children":1328},{"style":918},[1329],{"type":55,"value":953},{"type":49,"tag":900,"props":1331,"children":1332},{"style":956},[1333],{"type":55,"value":959},{"type":49,"tag":900,"props":1335,"children":1336},{"style":918},[1337],{"type":55,"value":372},{"type":49,"tag":900,"props":1339,"children":1340},{"style":966},[1341],{"type":55,"value":1342}," true",{"type":49,"tag":900,"props":1344,"children":1345},{"style":918},[1346],{"type":55,"value":974},{"type":49,"tag":900,"props":1348,"children":1349},{"style":912},[1350],{"type":55,"value":979},{"type":49,"tag":900,"props":1352,"children":1353},{"style":918},[1354],{"type":55,"value":984},{"type":49,"tag":58,"props":1356,"children":1357},{},[1358,1360,1366],{"type":55,"value":1359},"The ",{"type":49,"tag":126,"props":1361,"children":1363},{"className":1362},[],[1364],{"type":55,"value":1365},"QaResult",{"type":55,"value":1367}," contains:",{"type":49,"tag":204,"props":1369,"children":1370},{},[1371,1382,1398],{"type":49,"tag":208,"props":1372,"children":1373},{},[1374,1380],{"type":49,"tag":126,"props":1375,"children":1377},{"className":1376},[],[1378],{"type":55,"value":1379},"pages[]",{"type":55,"value":1381}," — per-page results with slug, sourceUrl, grade, diff details",{"type":49,"tag":208,"props":1383,"children":1384},{},[1385,1391,1393],{"type":49,"tag":126,"props":1386,"children":1388},{"className":1387},[],[1389],{"type":55,"value":1390},"skipped",{"type":55,"value":1392}," — count of pages without ",{"type":49,"tag":126,"props":1394,"children":1396},{"className":1395},[],[1397],{"type":55,"value":335},{"type":49,"tag":208,"props":1399,"children":1400},{},[1401,1407],{"type":49,"tag":126,"props":1402,"children":1404},{"className":1403},[],[1405],{"type":55,"value":1406},"summary",{"type":55,"value":1408}," — { pass, warn, fail, error, fixed }",{"type":49,"tag":58,"props":1410,"children":1411},{},[1412,1414,1420],{"type":55,"value":1413},"The QA log is written to ",{"type":49,"tag":126,"props":1415,"children":1417},{"className":1416},[],[1418],{"type":55,"value":1419},"qa-log.jsonl",{"type":55,"value":1421}," alongside the WXR file.",{"type":49,"tag":281,"props":1423,"children":1424},{},[],{"type":49,"tag":64,"props":1426,"children":1428},{"id":1427},"important-rules",[1429],{"type":55,"value":1430},"Important Rules",{"type":49,"tag":298,"props":1432,"children":1433},{},[1434,1444,1454,1464,1474,1491,1501,1518,1528],{"type":49,"tag":208,"props":1435,"children":1436},{},[1437,1442],{"type":49,"tag":74,"props":1438,"children":1439},{},[1440],{"type":55,"value":1441},"Compare before fixing.",{"type":55,"value":1443}," Always show the report first. Ask user before applying fixes.",{"type":49,"tag":208,"props":1445,"children":1446},{},[1447,1452],{"type":49,"tag":74,"props":1448,"children":1449},{},[1450],{"type":55,"value":1451},"Minimal fixes.",{"type":55,"value":1453}," Patch what's safe (alt text, minor gaps). Flag major gaps for re-extraction.",{"type":49,"tag":208,"props":1455,"children":1456},{},[1457,1462],{"type":49,"tag":74,"props":1458,"children":1459},{},[1460],{"type":55,"value":1461},"Verify after fixing.",{"type":55,"value":1463}," Re-run comparison on fixed pages. If the fix made things worse, revert.",{"type":49,"tag":208,"props":1465,"children":1466},{},[1467,1472],{"type":49,"tag":74,"props":1468,"children":1469},{},[1470],{"type":55,"value":1471},"No WordPress site needed.",{"type":55,"value":1473}," QA compares the WXR against the origin site directly.",{"type":49,"tag":208,"props":1475,"children":1476},{},[1477,1482,1484,1489],{"type":49,"tag":74,"props":1478,"children":1479},{},[1480],{"type":55,"value":1481},"Log everything.",{"type":55,"value":1483}," Every comparison and fix goes to ",{"type":49,"tag":126,"props":1485,"children":1487},{"className":1486},[],[1488],{"type":55,"value":1419},{"type":55,"value":1490},".",{"type":49,"tag":208,"props":1492,"children":1493},{},[1494,1499],{"type":49,"tag":74,"props":1495,"children":1496},{},[1497],{"type":55,"value":1498},"Don't over-fix.",{"type":55,"value":1500}," Some text differences are acceptable (navigation, footers, cookie banners). Focus on the main content.",{"type":49,"tag":208,"props":1502,"children":1503},{},[1504,1516],{"type":49,"tag":74,"props":1505,"children":1506},{},[1507,1509,1514],{"type":55,"value":1508},"Pages without ",{"type":49,"tag":126,"props":1510,"children":1512},{"className":1511},[],[1513],{"type":55,"value":335},{"type":55,"value":1515}," can't be QA'd.",{"type":55,"value":1517}," Warn the user if many pages lack source URLs — they need re-extraction with a newer version that records source URLs.",{"type":49,"tag":208,"props":1519,"children":1520},{},[1521,1526],{"type":49,"tag":74,"props":1522,"children":1523},{},[1524],{"type":55,"value":1525},"Self-regulate.",{"type":55,"value":1527}," Stop after 20 fix attempts or when remaining issues are minor.",{"type":49,"tag":208,"props":1529,"children":1530},{},[1531,1536,1538,1544],{"type":49,"tag":74,"props":1532,"children":1533},{},[1534],{"type":55,"value":1535},"Log discoveries.",{"type":55,"value":1537}," If you find a pattern of content loss specific to a platform (e.g. \"Squarespace always drops image captions\"), add it to ",{"type":49,"tag":126,"props":1539,"children":1541},{"className":1540},[],[1542],{"type":55,"value":1543},"DISCOVERIES.md",{"type":55,"value":1545}," so future extractions can be improved.",{"type":49,"tag":1547,"props":1548,"children":1549},"style",{},[1550],{"type":55,"value":1551},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1553,"total":1664},[1554,1571,1588,1603,1616,1635,1649],{"slug":1555,"name":1555,"fn":1556,"description":1557,"org":1558,"tags":1559,"stars":24,"repoUrl":25,"updatedAt":1570},"adapt","build platform adapters for content extraction","Build a new platform adapter to extract content from an unsupported platform (Blogger, Ghost, Tumblr, etc.)",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1560,1563,1566,1569],{"name":1561,"slug":1562,"type":15},"Automation","automation",{"name":1564,"slug":1565,"type":15},"Data Cleaning","data-cleaning",{"name":1567,"slug":1568,"type":15},"Data Engineering","data-engineering",{"name":19,"slug":20,"type":15},"2026-05-09T05:32:13.987972",{"slug":1572,"name":1572,"fn":1573,"description":1574,"org":1575,"tags":1576,"stars":24,"repoUrl":25,"updatedAt":1587},"compose-page-blocks","compose WordPress block markup from HTML","Compose a single liberated page's WordPress block-editor markup from its rendered HTML and screenshot. Inputs are a sanitized HTML file, a desktop screenshot, the design-foundation tokens, the URL's archetype (page\u002Fpost\u002Fproduct\u002Fetc.), and the source URL. Output is a string of valid block markup that round-trips through parse_blocks, uses theme tokens (no inlined hex colors), and contains only text drawn from the source HTML. Call per-page during the streaming watch loop after extraction has produced HTML+screenshot for that URL. Use when a freshly-imported page needs `post_content` upgraded from raw HTML into block-editor markup so the replica theme's tokens, gradients, and patterns actually render.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1577,1580,1583,1586],{"name":1578,"slug":1579,"type":15},"Block Editor","block-editor",{"name":1581,"slug":1582,"type":15},"Content Creation","content-creation",{"name":1584,"slug":1585,"type":15},"HTML","html",{"name":19,"slug":20,"type":15},"2026-06-08T08:17:34.212397",{"slug":1589,"name":1589,"fn":1590,"description":1591,"org":1592,"tags":1593,"stars":24,"repoUrl":25,"updatedAt":1602},"creating-blocks","create new WordPress blocks","Templates and guidelines for creating new WordPress blocks from scratch — load this before generating block files",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1594,1595,1598,1601],{"name":1578,"slug":1579,"type":15},{"name":1596,"slug":1597,"type":15},"Full Site Editing","full-site-editing",{"name":1599,"slug":1600,"type":15},"Plugin Development","plugin-development",{"name":19,"slug":20,"type":15},"2026-06-08T08:17:49.413995",{"slug":1604,"name":1604,"fn":1605,"description":1606,"org":1607,"tags":1608,"stars":24,"repoUrl":25,"updatedAt":1615},"creating-themes","create WordPress block themes","Guidelines for creating new WordPress block themes from scratch — load this before generating theme files",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1609,1610,1611,1614],{"name":1578,"slug":1579,"type":15},{"name":1596,"slug":1597,"type":15},{"name":1612,"slug":1613,"type":15},"Themes","themes",{"name":19,"slug":20,"type":15},"2026-06-08T08:17:50.666611",{"slug":1617,"name":1617,"fn":1618,"description":1619,"org":1620,"tags":1621,"stars":24,"repoUrl":25,"updatedAt":1634},"design-foundations","build design foundation JSON from sites","Build a coherent design-foundation JSON from a liberated site — semantic color\u002Ftypography\u002Fspacing roles with evidence trails. Consumes the partial scaffold produced by liberate_design_foundation_scaffold plus aggregate HTML\u002FCSS analysis and representative rendered HTML; produces a complete design-foundation matching the schema. Call after liberation, before theme generation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1622,1625,1628,1631],{"name":1623,"slug":1624,"type":15},"Data Modeling","data-modeling",{"name":1626,"slug":1627,"type":15},"Design","design",{"name":1629,"slug":1630,"type":15},"Design System","design-system",{"name":1632,"slug":1633,"type":15},"Frontend","frontend","2026-06-08T08:17:44.457834",{"slug":1636,"name":1636,"fn":1637,"description":1638,"org":1639,"tags":1640,"stars":24,"repoUrl":25,"updatedAt":1648},"design-qa","run visual QA on WordPress themes","Visual-QA loop run after replica theme install and content import. Captures replica screenshots, applies a hard responsiveness gate at 390px AND a hard per-section visual-parity gate (measured SectionParity records, verdict computed by buildRunReport), runs qualitative vision review of source\u002Freplica pairs, checks accessibility, and drives a per-section escalation ladder of fixes via editing-themes\u002Fediting-blocks\u002Frebuild-section (R1 CSS → R2 spec-rebuild → R3 re-extract → R4a AI canonical-block rebuild → R4b deterministic styled-island floor) — escalating unresolved divergences to the operator rather than shipping them. Orchestration-internal — invoked by the replicate-with-blocks\u002Fliberate orchestrators, not directly by users.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1641,1642,1645,1646,1647],{"name":17,"slug":4,"type":15},{"name":1643,"slug":1644,"type":15},"Screenshots","screenshots",{"name":22,"slug":23,"type":15},{"name":1612,"slug":1613,"type":15},{"name":19,"slug":20,"type":15},"2026-06-08T08:17:45.698278",{"slug":1650,"name":1650,"fn":1651,"description":1652,"org":1653,"tags":1654,"stars":24,"repoUrl":25,"updatedAt":1663},"diagnose","debug failed data extraction processes","Debug failed or low-quality extractions by analyzing logs, probing the source site, and identifying root causes",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1655,1656,1659,1662],{"name":1567,"slug":1568,"type":15},{"name":1657,"slug":1658,"type":15},"Debugging","debugging",{"name":1660,"slug":1661,"type":15},"Logs","logs",{"name":17,"slug":4,"type":15},"2026-05-10T05:48:11.267642",21,{"items":1666,"total":1836},[1667,1686,1699,1713,1730,1745,1755,1770,1785,1796,1809,1825],{"slug":1668,"name":1668,"fn":1669,"description":1670,"org":1671,"tags":1672,"stars":1683,"repoUrl":1684,"updatedAt":1685},"annotate","collect visual feedback with browser annotation tools","Open a browser with visual annotation tools. The user clicks elements on their site and leaves feedback — the agent reads annotations and makes changes. Use this when the user wants to point at specific elements to fix, tweak, or redesign.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1673,1674,1677,1680],{"name":1632,"slug":1633,"type":15},{"name":1675,"slug":1676,"type":15},"Productivity","productivity",{"name":1678,"slug":1679,"type":15},"UX Copy","ux-copy",{"name":1681,"slug":1682,"type":15},"UX Design","ux-design",484,"https:\u002F\u002Fgithub.com\u002FAutomattic\u002Fstudio","2026-05-06T05:40:01.516544",{"slug":1687,"name":1687,"fn":1688,"description":1689,"org":1690,"tags":1691,"stars":1683,"repoUrl":1684,"updatedAt":1698},"block-content","write editable WordPress block markup","Write editable WordPress block markup for local Studio sites, including core\u002Fhtml limits, block-theme layout rules, full-width sections, validation, and skeleton-first page\u002FCSS recipes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1692,1693,1696,1697],{"name":1578,"slug":1579,"type":15},{"name":1694,"slug":1695,"type":15},"CSS","css",{"name":1584,"slug":1585,"type":15},{"name":19,"slug":20,"type":15},"2026-05-27T07:01:55.629681",{"slug":1700,"name":1700,"fn":1701,"description":1702,"org":1703,"tags":1704,"stars":1683,"repoUrl":1684,"updatedAt":1712},"hosting-plans-helper","provide WordPress.com hosting plan information","Answer WordPress.com plan, pricing, upgrade, and feature-tier questions (plan names, what each tier unlocks — plugins, themes, custom code, SSH, hosting — and current prices) from authoritative live data. Load before answering ANY plan, pricing, or feature-gating question; never answer these from memory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1705,1708,1711],{"name":1706,"slug":1707,"type":15},"Pricing","pricing",{"name":1709,"slug":1710,"type":15},"Reference","reference",{"name":19,"slug":20,"type":15},"2026-07-02T07:42:33.654791",{"slug":1714,"name":1714,"fn":1715,"description":1716,"org":1717,"tags":1718,"stars":1683,"repoUrl":1684,"updatedAt":1729},"liberate","migrate websites to WordPress","Import and rebuild a website from a closed platform (Wix, Squarespace, Webflow, Shopify, GoDaddy, Hostinger, HubSpot, Weebly) into a Studio WordPress site. Extracts pages\u002Fposts\u002Fproducts + media, then reconstructs the design as editable blocks + WooCommerce OR as a high-fidelity replica theme. Invoke when the user wants to migrate, import, liberate, or rebuild a site from one of these platforms.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1719,1722,1725,1728],{"name":1720,"slug":1721,"type":15},"CMS","cms",{"name":1723,"slug":1724,"type":15},"Migration","migration",{"name":1726,"slug":1727,"type":15},"Web Development","web-development",{"name":19,"slug":20,"type":15},"2026-07-09T06:47:33.454311",{"slug":1731,"name":1731,"fn":1732,"description":1733,"org":1734,"tags":1735,"stars":1683,"repoUrl":1684,"updatedAt":1744},"need-for-speed","run frontend performance audits for WordPress sites","Run a frontend performance audit on a WordPress site and get actionable optimization recommendations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1736,1739,1740,1743],{"name":1737,"slug":1738,"type":15},"Audit","audit",{"name":1632,"slug":1633,"type":15},{"name":1741,"slug":1742,"type":15},"Performance","performance",{"name":19,"slug":20,"type":15},"2026-05-06T05:40:06.433267",{"slug":1746,"name":1746,"fn":1747,"description":1748,"org":1749,"tags":1750,"stars":1683,"repoUrl":1684,"updatedAt":1754},"plugin-recommendations","recommend WordPress plugins for site features","Choose recommended plugins and plugin-provided blocks for features core WordPress blocks do not cover - ecommerce (WooCommerce), forms and newsletters (Jetpack), online courses and quizzes (Sensei LMS), polls, surveys and ratings (Crowdsignal), spam protection (Akismet) - while keeping generated content editable and avoiding raw HTML fallbacks. Any request to sell products or build a shop, store, or storefront requires WooCommerce with products.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1751,1752,1753],{"name":1581,"slug":1582,"type":15},{"name":1599,"slug":1600,"type":15},{"name":19,"slug":20,"type":15},"2026-05-27T07:01:58.249105",{"slug":1756,"name":1756,"fn":1757,"description":1758,"org":1759,"tags":1760,"stars":1683,"repoUrl":1684,"updatedAt":1769},"rank-me-up","run on-page SEO audits for WordPress sites","Run an on-page SEO audit on a WordPress site and get actionable recommendations to improve search visibility.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1761,1762,1765,1768],{"name":1737,"slug":1738,"type":15},{"name":1763,"slug":1764,"type":15},"Marketing","marketing",{"name":1766,"slug":1767,"type":15},"SEO","seo",{"name":19,"slug":20,"type":15},"2026-05-06T05:40:05.196367",{"slug":1771,"name":1771,"fn":1772,"description":1773,"org":1774,"tags":1775,"stars":1683,"repoUrl":1684,"updatedAt":1784},"site-spec","gather specifications for new WordPress sites","Gather the site name and layout preference before building a WordPress site. Run this before creating any new site.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1776,1777,1780,1783],{"name":1626,"slug":1627,"type":15},{"name":1778,"slug":1779,"type":15},"Product Management","product-management",{"name":1781,"slug":1782,"type":15},"Specs","specs",{"name":19,"slug":20,"type":15},"2026-05-06T05:40:02.739409",{"slug":1786,"name":1786,"fn":1787,"description":1788,"org":1789,"tags":1790,"stars":1683,"repoUrl":1684,"updatedAt":1795},"studio-cli","manage local WordPress sites with Studio CLI","Use the Studio CLI to manage local WordPress sites, authentication, and preview sites. Invoke this skill when you need to run Studio CLI commands, manage sites, or troubleshoot site issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1791,1794],{"name":1792,"slug":1793,"type":15},"CLI","cli",{"name":19,"slug":20,"type":15},"2026-04-06T18:02:57.150231",{"slug":1797,"name":1797,"fn":1798,"description":1799,"org":1800,"tags":1801,"stars":1683,"repoUrl":1684,"updatedAt":1808},"taxonomist","optimize WordPress category taxonomy","Analyze and optimize a WordPress site's category taxonomy. Exports all posts, uses AI to suggest an improved category structure — merging duplicates, retiring dead categories, creating missing ones, writing descriptions, and re-categorizing posts. Run this when the user wants to clean up or improve their categories.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1802,1805,1806,1807],{"name":1803,"slug":1804,"type":15},"Content Strategy","content-strategy",{"name":1564,"slug":1565,"type":15},{"name":1766,"slug":1767,"type":15},{"name":19,"slug":20,"type":15},"2026-05-06T05:40:03.966799",{"slug":1810,"name":1810,"fn":1811,"description":1812,"org":1813,"tags":1814,"stars":1683,"repoUrl":1684,"updatedAt":1824},"visual-design","plan and execute visual design direction","Plan and execute high-quality visual direction for site creation, redesign, layout, typography, color, motion, and visual polish.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1815,1818,1819,1822],{"name":1816,"slug":1817,"type":15},"Animation","animation",{"name":1626,"slug":1627,"type":15},{"name":1820,"slug":1821,"type":15},"Typography","typography",{"name":1823,"slug":1810,"type":15},"Visual Design","2026-07-24T05:40:57.887452",{"slug":1826,"name":1826,"fn":1827,"description":1828,"org":1829,"tags":1830,"stars":1683,"repoUrl":1684,"updatedAt":1835},"visual-polish","verify and polish website visual design","Verify and polish a built or redesigned site by diagnosing rendered-DOM issues against intent and fixing them in a planned, batched screenshot-and-fix loop.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1831,1832,1833,1834],{"name":1657,"slug":1658,"type":15},{"name":1632,"slug":1633,"type":15},{"name":1643,"slug":1644,"type":15},{"name":1823,"slug":1810,"type":15},"2026-06-06T07:09:59.809812",81]