diff --git a/.lane/reports/fix-agent-desk-canonical-apex-lane1.md b/.lane/reports/fix-agent-desk-canonical-apex-lane1.md new file mode 100644 index 00000000..8f64cee4 --- /dev/null +++ b/.lane/reports/fix-agent-desk-canonical-apex-lane1.md @@ -0,0 +1,67 @@ +# Lane 1 — retired "TinyStudio Agent Desk" title/snippet (f41c8af0f8) — 2026-08-15 + +## Verdict + +The one remaining repo-side mechanism still feeding the retired name to +Google is closed: the legacy `/agent-desk` surface no longer declares the +apex root as its canonical/og:url, and a regression guard now fails the +build if that claim returns. The canonical fix has been blocked in open PR +#91 since 2026-08-10; this branch lands the corrected version. + +## Why the item was still live + +- The 2026-08-09 de-indexing pass (PR #46) added `noindex, nofollow` and + retired framing to `public/agent-desk.html` — that part has held. +- The 2026-08-14 pass (the www-host 301) collapsed the duplicate + `www.tinystudio.io` site entity that carried the stale "TinyStudio Agent + Desk" site name — that part has held too. +- But `public/agent-desk.html` still declared + `` and + `og:url` = `https://tinystudio.io/` — the exact consolidation mechanism by + which the retired title reached the homepage URL (q5/google capture + 2026-08-06). Verified live on 2026-08-15: `/agent-desk` serves that + apex-root claim, and the page is noindex, so its canonical tells Google the + legacy surface is a duplicate of the homepage. +- The canonical fix has been open in PR #91 since 2026-08-10 and is still + unmerged on main; main and live therefore still served the apex-root claim. + +## The change + +- `public/agent-desk.html`: canonical and og:url now name the legacy page's + own address `https://tinystudio.io/agent-desk` — the clean form that serves + 200 — never the apex root. (PR #91 pointed them at `/agent-desk.html`, but + that form 307-redirects to `/agent-desk`; the repo's own canonical + convention, which the audit page already follows, requires naming the + 200-serving address.) +- `scripts/check-site.mjs`: the retired-desk index guard now also requires + exactly one canonical and one og:url, both naming + `https://tinystudio.io/agent-desk`. Regression proof: re-pointing them at + the apex root makes `npm run check` fail with both messages. + +## Verification + +- `node scripts/check-site.mjs` → "TinyStudio.io checks passed." +- `npm test` → 121 tests, 0 failures (6 headings, 7 sitemap, 80 agent-worker, + 16 agent-UI, 8 product-contract, 4 first-viewport-audience), plus the + narrow-viewport suite PASS. +- `git diff --check` clean. +- Guard negative test: apex-root canonical → `npm run check` exit 1 with + both canonical and og:url failures; restored fix → green. +- Live baseline (2026-08-15, before deploy): `/agent-desk` 200 carrying + `canonical https://tinystudio.io/` + `og:url https://tinystudio.io/`; + `/agent-desk.html` 307 → `/agent-desk`. + +## Files touched + +- `public/agent-desk.html` — canonical/og:url point at the legacy page's own + 200-serving address. +- `scripts/check-site.mjs` — guard requires canonical/og:url = + `https://tinystudio.io/agent-desk`. +- `.lane/reports/fix-agent-desk-canonical-apex-lane1.md` — this report. + +## PR relationship + +PR #91 (`fix/agent-desk-canonical-lane1`) carries the same fix intent but +points the canonical at the 307-redirecting `/agent-desk.html` form and its +guard covers only the canonical, not og:url. This branch is the corrected +delivery; #91 is closed as superseded so exactly one delivery path remains. diff --git a/public/agent-desk.html b/public/agent-desk.html index 4f68447e..18de745f 100644 --- a/public/agent-desk.html +++ b/public/agent-desk.html @@ -15,8 +15,8 @@ content="The self-serve Agent Desk is retired and is not the current offer. TinyStudio's current offer is the free leak audit of high-ticket service homepages." /> - - + + diff --git a/scripts/check-site.mjs b/scripts/check-site.mjs index dd69347e..df5bfcc2 100644 --- a/scripts/check-site.mjs +++ b/scripts/check-site.mjs @@ -1266,7 +1266,12 @@ for (const [pageName, pageHtml] of ownedPages) { // The legacy page must therefore stay out of the index: its head keeps a // robots noindex, nofollow meta, and its title and description frame the // surface as retired, so neither the search index nor a scraper can re-present -// the retired self-serve product as the current offer. +// the retired self-serve product as the current offer. Its canonical and +// og:url must name the legacy page itself — the clean /agent-desk address +// that serves 200 — never the apex root: while the page declared the root as +// its canonical, Google consolidated the retired title onto the homepage URL +// (the q5/google capture), and a canonical that points at the root keeps +// handing the retired name to the homepage's SERP entry. const retiredDeskHead = retiredDesk.match(/
]*>([\s\S]*?)<\/head>/i)?.[1] ?? ""; const robotsMeta = /]*\bname="robots")(?=[^>]*\bcontent="noindex,\s*nofollow")[^>]*>/i; if (!robotsMeta.test(retiredDeskHead)) { @@ -1280,6 +1285,29 @@ const retiredDeskDescription = if (!/\bretired\b/i.test(retiredDeskDescription)) { failures.push("Retired Agent Desk description must frame the surface as retired."); } +// The retired page must never claim the apex root. Exactly one canonical and +// one og:url, both naming the clean /agent-desk address that serves 200. +const retiredDeskLive = retiredDesk.replace(//g, ""); +const retiredDeskCanonical = + retiredDeskLive.match(/]*\brel\s*=\s*["']canonical["'][^>]*>/gi) ?? []; +if (retiredDeskCanonical.length !== 1) { + failures.push(`Retired Agent Desk canonical must appear exactly once (found ${retiredDeskCanonical.length}).`); +} else { + const href = retiredDeskCanonical[0].match(/\bhref\s*=\s*["']([^"']*)["']/i)?.[1] ?? ""; + if (href.trim() !== "https://tinystudio.io/agent-desk") { + failures.push(`Retired Agent Desk canonical must point at https://tinystudio.io/agent-desk (found "${href}").`); + } +} +const retiredDeskOgUrl = + retiredDeskLive.match(/]*\bproperty\s*=\s*["']og:url["'][^>]*>/gi) ?? []; +if (retiredDeskOgUrl.length !== 1) { + failures.push(`Retired Agent Desk og:url must appear exactly once (found ${retiredDeskOgUrl.length}).`); +} else { + const content = retiredDeskOgUrl[0].match(/\bcontent\s*=\s*["']([^"']*)["']/i)?.[1] ?? ""; + if (content.trim() !== "https://tinystudio.io/agent-desk") { + failures.push(`Retired Agent Desk og:url must point at https://tinystudio.io/agent-desk (found "${content}").`); + } +} // ---- Meta descriptions (dogfood) ------------------------------------------- // The leak audit this site sells flags a homepage whose served HTML carries no