Skip to content

Gevell Primary-Domain Migration Runbook

Make gevell.com the primary corporate + product domain, rebranding the product family from TheAccessibleX to Gevell <Descriptor>, while keeping theaccessible.org alive as a permanent 301 redirect.

This is a full brand + infrastructure migration touching 21 apps, 30+ Cloudflare Workers, ~780 code references, DNS, email, DMARC, auth, Stripe, and Supabase. Treat it as a program of parallel workstreams behind a single cutover, not a one-shot find-and-replace.


0. Decisions locked (2026-09-07)

#DecisionChoice
D1Rebrand scopeFull rebrand. Products rename and move to *.gevell.com.
D2Naming schemeSpaced descriptor — Gevell PDF, Gevell Audit, … (single word “Gevell” + space + descriptor).
D3theaccessible.org fate301 redirect, keep alive indefinitely. Domain stays registered/renewed to preserve SEO equity, inbound links, and email reputation.
D4Email sending domainMove to gevell.com, dual-send during transition. Verify gevell.com in Resend; keep theaccessible.org sending valid through the redirect window.

Inputs still required before execution (fill in — DO NOT start Phase 2 without these)

  • gevell.com registrar + current nameservers — RESOLVED (received 2026-09-07, implemented in this PR): confirmed movable to Cloudflare (nameserver delegation) under account c6cce84d1636ec85ec946a19edef0103 (Larry@anglin.com).
  • New Gevell color kit — RESOLVED (received 2026-09-07, implemented in this PR): full primary-50…950 scale + accent/semantic colors with measured contrast matrix at docs/admin/brand/gevell/ (gevell-tokens.json).
  • New Gevell logo set — RESOLVED (received 2026-09-07, implemented in this PR): logo/mark/favicon/OG assets at docs/admin/brand/gevell/export/.
  • Legal/entity — is “Gevell” a new legal entity, DBA, or brand-only? Affects footer copyright, ToS/Privacy, Stripe statement descriptor, invoices.
  • Trademark clearance for “Gevell” and each Gevell <Descriptor> product name.

1. Canonical name & domain mapping (source of truth for the whole migration)

Every workstream below references this table. Products keep their existing app directory and subdomain slug; only the display name and apex domain change.

App dirOld nameNew nameOld domainNew domain
apps/webTheAccessiblePDFGevell PDFpdf.theaccessible.orgpdf.gevell.com
apps/remediateTheAccessibleWebGevell Webremediate.theaccessible.orgremediate.gevell.com
apps/auditTheAccessibleAuditGevell Auditaudit.theaccessible.orgaudit.gevell.com
apps/vpatTheAccessibleReportCardGevell Report Cardacr.theaccessible.orgacr.gevell.com
apps/advising-worksheetTheAccessibleWorksheetGevell Worksheetworksheet.theaccessible.orgworksheet.gevell.com
apps/course-mapTheAccessibleCourseMapGevell Course Mapmap.theaccessible.orgmap.gevell.com
apps/org-chartTheAccessibleOrgChartGevell Org Chartorgchart.theaccessible.orgorgchart.gevell.com
apps/home (workshops)TheAccessibleWorkshopGevell Workshoptheaccessible.org/workshopsgevell.com/workshops
apps/powerTheAccessibleSlidesGevell Slidespptx.theaccessible.orgpptx.gevell.com
apps/formsTheAccessibleFormsGevell Formsforms.theaccessible.orgforms.gevell.com
apps/linksTheAccessibleLinksGevell Linkslinks.theaccessible.orglinks.gevell.com
apps/photosTheAccessiblePhotosGevell Photosphotos.theaccessible.orgphotos.gevell.com
apps/musicTheAccessibleMusicGevell Musicmusic.theaccessible.orgmusic.gevell.com
apps/flowchartTheAccessibleFlowchartGevell Flowchartflow.theaccessible.orgflow.gevell.com
apps/home(corporate marketing)Gevelltheaccessible.orggevell.com

Non-product surfaces that also carry the brand/domain: apps/admin (admin.theaccessible.org), apps/beta, apps/bugs, apps/pro, apps/skills, apps/tag-editor, apps/upload, docs/user (help site), and the API hosts (api.theaccessible.org on Node .4, api-pdf.theaccessible.org Lambda, worker.theaccessible.org CF worker).

Naming discipline: update the canonical table in root CLAUDE.md (“Canonical product names”) and packages/accessible-org-ui/src/products.ts first — they are the declared single source of truth. The old TheAccessibleX tokens become the new “retired variants” list.


2. Phase plan (dependency-ordered)

Phase 0 Prep & inventory ............ no user-visible change
Phase 1 Cloudflare zone + DNS ....... gevell.com onboarded, subdomains created (not yet primary)
Phase 2 Email + DMARC .............. gevell.com verified sender, dual-send
Phase 3 Brand kit (colors + logos) . assets swapped in code, behind build
Phase 4 Mass substitution .......... names + domains + product registry
Phase 5 Auth / Stripe / Supabase ... allow-lists + redirect URLs updated
Phase 6 Staging verification ....... full family on *.gevell.com preview
Phase 7 Cutover ................... flip primary + deploy all
Phase 8 Redirects + SEO ........... theaccessible.org → gevell.com 301s
Phase 9 Post-cutover watch ......... DMARC, deliverability, 404s, analytics

Phases 1–5 are build work with zero user impact (nothing is primary yet). Phase 7 is the only irreversible-feeling step, and it’s covered by rollback in §13.


3. Phase 0 — Prep & inventory

  • Create tracking epic in GitHub (chore/gevell-rebrand), one child issue per app + one per workstream (DNS, email, brand, auth).
  • Create a long-lived migration branch off main: feature/gevell-primary-domain. Land workstreams as stacked PRs into it; merge to main only at cutover.
  • Snapshot the reference inventory (regenerate before you start — counts drift):
    Terminal window
    # every human-facing brand string
    grep -rIn "TheAccessible" --include="*.ts" --include="*.tsx" \
    --include="*.json" --include="*.md" --include="*.toml" --include="*.html" . \
    | grep -v node_modules > /tmp/gevell-names.txt
    # every hardcoded domain
    grep -rIn "theaccessible\.org" --include="*.ts" --include="*.tsx" \
    --include="*.json" --include="*.md" --include="*.toml" . \
    | grep -v node_modules > /tmp/gevell-domains.txt
    wc -l /tmp/gevell-*.txt
  • Classify each hit: user-facing (translate/rebrand), infra/config (domain swap), do-not-touch (historical docs, docs/admin/audits/*, memory files, retired-variant tables that must retain the old strings).
  • Inventory external references NOT in the repo:
    • Cloudflare zones, Workers routes, Pages projects, KV/R2 bindings
    • Supabase Auth redirect URLs + Site URL (per project)
    • Stripe: business profile, statement descriptor, webhook endpoints, checkout branding, Payment Links
    • Resend: verified domains + sending identities
    • Google Workspace / MX (if email hosting, not just transactional)
    • Uptime Kuma monitors, Grafana dashboards, OG/social profiles, app-store listings, GitHub org/repo names
  • Confirm do-not-rewrite zones are protected in the substitution tooling (§6):
    • docs/admin/audits/**, .claude/**, **/memory/**
    • The “retired variants” columns in CLAUDE.md and products.ts (these MUST keep the TheAccessibleX strings)
    • TestFiles/**, corpus/**, generated dist/**, out/**

4. Phase 1 — Cloudflare zone + DNS

Account: c6cce84d1636ec85ec946a19edef0103 (Larry@anglin.com) — same account that holds theaccessible.org, the redirects worker, and DMARC worker.

  • Add gevell.com as a zone in Cloudflare — DONE 2026-09-07: Cloudflare is the registrar; zone active on acct c6cce84d… (zone id 4fec00f83d3f24a02039a4b80c1c93d8).
  • Recreate the DNS records that today point *.theaccessible.org at their targets, for *.gevell.com:
    • Product subdomains → Cloudflare Pages / Workers custom domains (added in Phase 6/7 as each app’s Pages project gets the custom domain attached).
    • api.gevell.com → Node .4 origin (10.1.1.4 behind the tunnel/proxy currently serving api.theaccessible.org).
    • api-pdf.gevell.com → Lambda/API Gateway (or keep API hosts on theaccessible.org — see note).
    • worker.gevell.com → CF worker (workshop checkout + Stripe webhook).
  • API host decision: API hostnames (api., api-pdf., worker.) are internal integration endpoints, not brand surfaces. Recommended: keep them on theaccessible.org through cutover to avoid re-plumbing Stripe webhooks, CORS allow-lists, and Lambda env in the same window. Migrate API hosts in a separate, later phase once the brand cutover is stable. Flag this explicitly to avoid scope creep.
  • Set TTLs low (300s) on records you’ll flip during cutover; raise back afterward.
  • Keep all theaccessible.org records intact — they will serve the redirect worker (Phase 8), not be deleted.

5. Phase 2 — Email + DMARC (gevell.com)

Current transactional email: Resend, from noreply@gevell.com, with a DMARC aggregate-ingestion worker (workers/dmarc, dmarc@theaccessibleorg.com → worker) and alerts to larry@anglin.com.

5a. Resend sender domain

  • Add gevell.com as a verified domain in Resend — created 2026-09-07 (domain id 1b2f4de0-c490-40d8-917c-1884095cd22e, us-east-1); VERIFIED 2026-09-07, first test email sent from noreply@gevell.com. (scripts/gevell-dns-setup.sh = record reference.)
  • Add the Resend-provided DKIM CNAME/TXT records — DONE 2026-09-07 (all 6 gevell.com records + cross-domain report TXT imported via dashboard BIND import; verified at authoritative NS).
  • SPF — DONE 2026-09-07: root SPF is v=spf1 include:_spf.google.com ~all (Gmail alias sends); Resend sends via its send.gevell.com subdomain (own SPF include:amazonses.com), so the root record does not need a Resend include.
  • DMARC — DONE 2026-09-07 at p=none (warm-up clock started; tighten after ~2 clean weeks):
    _dmarc.gevell.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@theaccessibleorg.com; ruf=mailto:dmarc@theaccessibleorg.com; fo=1"
    Reuse the existing dmarc@theaccessibleorg.com ingestion mailbox/worker (cross-domain report auth already exists — extend it for gevell.com).
  • After ~1–2 weeks of clean aggregate reports, tighten gevell.com DMARC to p=quarantine, then p=reject.

5b. DMARC worker

  • workers/dmarc/wrangler.toml: dual-domain config deployed 2026-09-07 (version edf2f23d); update ALERT_EMAIL_FROM to noreply@gevell.com once verified. Keep ingesting theaccessible.org reports (dual-send window).
  • Cross-domain report authorization TXT — DONE 2026-09-07 (gevell.com._report._dmarc.theaccessibleorg.com TXT "v=DMARC1"). Reverse direction if ever needed: update so gevell.com can send reports about theaccessible.org and vice-versa if needed.

5c. Application sender identity (dual-send window)

  • Introduce a single env var for the from-address (EMAIL_FROM=noreply@gevell.com) and route ALL senders through it. Grep the hardcoded senders and replace:
    Terminal window
    grep -rIn "noreply@theaccessible\.org" --include="*.ts" . | grep -v node_modules
    Known senders: workers/api, workers/gemini-alert, workers/dmarc, workers/phone, workers/course-map-api, workers/email-intake, ~/.claude/scripts/send-email.sh (global — update separately), and the @anglinai/logger EmailAlertTransport config.
  • Keep theaccessible.org verified in Resend so any missed sender still delivers during the window (dual-send safety net).
  • Update reply-to / support addresses and the footer “Contact Support” mailto.

5d. Inbound / MX

  • Decision 2026-09-07: gevell.com becomes a Gmail alias (synonym) domain for theaccessible.org — Larry configures in Google Admin; DNS side (Google MX + SPF) is in scripts/gevell-dns-setup.sh. No per-user config needed.
  • If mailboxes (not just transactional) are hosted, plan MX cutover separately and later — do not move inbound mail in the brand cutover window. Confirm whether gevell.com needs Google Workspace / mailbox provisioning.

6. Phase 3 — Brand color kit + logos

6a. Color system

The palette lives in the shared UI package and Tailwind preset (per global standards: primary-50…950, current default #054fb9). Do not scatter new hex values — update the source once and let every app inherit.

  • Obtain the Gevell primary-50…950 scale + accent/semantic tokens (blocker input from §0).
  • Verify WCAG 2.2 AA/AAA contrast for every token before adoption — contrast overrides brand per project rules. The primary-500 used for interactive text on white must clear 4.5:1 (done: Gevell #003DA5 measures 9.5:1 AAA; old #054fb9 was 7.43:1). Reject any brand hex that fails; pick the nearest in-hue shade that passes.
  • Update the palette in the shared UI source (@anglinai/ui tailwind-preset + theme.css, mirrored into packages/accessible-org-ui). Bump the package version and republish per the “Adding New Shared Components” flow.
  • Sweep hardcoded #054fb9 (and any inline brand hexes) in packages/accessible-org-ui/src/components/* and app code:
    Terminal window
    grep -rIn "054fb9" --include="*.ts" --include="*.tsx" --include="*.css" . | grep -v node_modules
  • Re-run the a11y test suite (test:a11y) for every app in light and dark mode.

6b. Logos & static assets

Every app requires public/logo.png + public/logo-dark.png (shared footer/header render these; missing files = broken footer). Full set per app also includes favicon(s), apple-touch-icon.png, SVG mark, and OG images.

  • Produce the Gevell asset set (light/dark PNG, SVG, favicon.ico/png/svg, apple-touch-icon, OG image, per-product OG variants if used).
  • Replace assets in every apps/*/public/ and the root logos/ working set. Script the copy; verify each app has both logo.png and logo-dark.png.
  • Update any logo references in products.ts icons, email templates, PDF/report headers, and the flipbook/player chrome.
  • Update manifest/PWA icons, favicon links in each layout.tsx/<head>, and social-card meta.

7. Phase 4 — Mass substitution (names + domains + registry)

Do this as discrete, reviewable passes, not one global sed. Order matters: registry first, then names, then domains.

7a. Product registry + canonical table (do first)

  • Edit packages/accessible-org-ui/src/products.ts: new name, url (→ *.gevell.com), taglines/copy. Move old names into a documented “retired variants” comment.
  • Edit root CLAUDE.md canonical-names table: new canonical column, old names → retired variants, domains → *.gevell.com. Update project CLAUDE.md domain/deploy notes.
  • These two files drive the footer Products column, homepage grid, and CrossPromoStrip — verify those render the new names after the change.

7b. Display-name substitution (user-facing strings)

  • For each product, replace its exact old token with the new name. Because the new name contains a space, do NOT blind-replace TheAccessiblePDF → Gevell PDF in identifiers — only in display strings, titles, metadata, marketing copy, and locale files. Keep code identifiers/slugs (theAccessiblePdf, package names, ids) as-is or rename in a separate deliberate pass.
  • Externalize to i18n where a t() key exists; add new keys to locales/en.json rather than hardcoding.
  • Update each app’s <title>, <meta name="description">, OpenGraph/Twitter tags, and JSON-LD to the new name.
  • Protected zones (must retain old strings): docs/admin/audits/**, **/memory/**, .claude/**, retired-variant tables, TestFiles/**, corpus/**.

7c. Domain substitution

  • Replace *.theaccessible.org product/marketing hostnames with *.gevell.com in: wrangler.toml routes, NEXT_PUBLIC_*_URL env, products.ts URLs, sitemaps/robots, canonical tags, CORS allow-lists, deep links, cross-promo/workshop-bar apiBase.
  • Leave API hosts on theaccessible.org per §4 API-host decision (separate later phase). Explicitly exclude api., api-pdf., worker. from this pass.
  • Update sitemap.ts/sitemap.xml, robots.txt, and any hardcoded absolute URLs in help docs (docs/user).
  • Re-run typecheck + full test suite per workspace after each pass; coverage must not drop.

7d. Tooling for the sweep

  • Write a scoped codemod (Node script or ripgrep+sed with an explicit allow/deny path list) rather than editor-wide replace. Dry-run → diff review → apply. Commit each product’s rename as its own commit for reviewability and easy revert.

8. Phase 5 — Auth / Stripe / Supabase allow-lists

8a. Supabase Auth (per project — converter vuvwmfxssjosfphzpzim, org-chart, etc.)

  • DONE 2026-09-07: https://*.gevell.com/** + https://gevell.com/** added to Redirect URLs on accessible-pdf-converter (vuvwmfxssjosfphzpzim) and orgchart-anglin-com (rmwscaavdmzoerqyppbf). All old origins kept.
  • DONE 2026-09-07: https://admin.theaccessible.org/** added to the converter allow-list (34 entries total). The old-domain list is per-host (no *.theaccessible.org wildcard) and the new admin app hostname was missing; admin.gevell.com / admin-docs.gevell.com need no explicit entries — the *.gevell.com wildcard covers them. admin-docs is static + Cloudflare-Access-only (no Supabase auth), so no old-domain entry needed either.
  • AT CUTOVER: update Site URL per project (converter: pdf.theaccessible.org → pdf.gevell.com; orgchart: orgchart.anglin.com stays — it’s the anglin.com product). Deferred: Site URL feeds live email links.
  • Update email-template branding (magic link, confirm, reset) and the /auth/confirm + /auth/callback link hosts to gevell.com. Recall the confirm-on-gesture pattern (no GET-verified links) and the PKCE double-exchange guard.
  • N/A for Supabase-mediated OAuth (provider callbacks point at <project>.supabase.co/auth/v1/callback, which doesn’t change with our domain). Only revisit if any app adds direct OAuth.

8b. Stripe (acct_1RuytL9k5uu7pMLw, dashboard → Settings → Business)

  • Support email → larry@gevell.com — DONE 2026-09-07 (works pre-cutover via Gmail alias domain).
  • AT CUTOVER (Phase 7 step; deliberately deferred — all customer-visible immediately):
    • Public business name: TheAccessibleOrg → Gevell (Business details → Public details → Edit)
    • Business website: theaccessible.org → https://gevell.com
    • Customer support URL → https://gevell.com/support; Privacy → /privacy; ToS → /terms
    • Statement descriptor → GEVELL (Settings → Business → Account details)
    • Branding tab: Gevell logo + primary #003DA5 (checkout, receipts, invoices)
  • Statement descriptor (what shows on cardholder statements) — update if it referenced the old brand (requires re-review by Stripe; plan lead time).
  • Checkout/branding: logo, colors, and any Payment Links pointing at old domains.
  • Webhook endpoints: if worker.theaccessible.org (workshop checkout + webhook) moves, register the new endpoint and keep the old active until traffic drains. If API hosts stay on theaccessible.org (recommended §4), no webhook change needed now — note this to avoid an unnecessary, risky edit.

8c. Cloudflare Access (admin surfaces)

  • DONE 2026-09-07: admin.gevell.com added to the admin Access app and admin-docs.gevell.com to the admin-docs app (existing policies cover both; via Zero Trust dashboard).

9. Phase 6 — Staging verification

  • Deploy the full family to *.gevell.com preview/staging (Pages preview or the 10.1.1.17 staging server) with the migration branch.
  • Verify per app: header/footer logos (light+dark), product name everywhere, footer Products column, CrossPromoStrip, WorkshopPromoBar, canonical/OG tags, sitemap/robots.
  • Run the mandatory gates on each app: test, test:a11y, test:mobile, typecheck, lint. Contrast in both modes.
  • End-to-end smoke: sign-up/login (Supabase redirect), a conversion job (PDF/forms/audit), a Stripe checkout (test mode), a transactional email (confirm it sends from gevell.com, passes SPF/DKIM/DMARC — check headers).
  • Verify email deliverability with mail-tester.com or Google Postmaster for gevell.com.

10. Phase 7 — Cutover

STATUS 2026-09-07: cutover EXECUTED (accelerated for UTHealth/TX-RAMP). Merging #2748 flipped every Worker app’s custom domain to gevell.com in the same deploy (the branch’s wrangler.toml routes carried the new domains), which dropped the old-domain bindings — 16 theaccessible.org hostnames went dark until the 301 layer (Phase 8 pulled forward, deployed same evening) restored them as permanent redirects. DMARC stays p=none during warm-up (does not gate cutover). Remaining at-cutover items tracked below and in §8a/§8b.

  1. Merge feature/gevell-primary-domain → main — DONE 2026-09-07 (#2748, squash 63350cb).
  2. Custom domains — DONE 2026-09-07: Worker apps flipped automatically on deploy (wrangler routes); Pages projects attached via dashboard (audit, remediate, pro, polish, admin, admin-docs); help via docs/user wrangler deploy. Photos serves at images.gevell.com (mismatch resolved on the branch).
  3. Deploys — DONE 2026-09-07: CI Deploy + Deploy AWS green; .4 rebuilt (healthy on 63350cb3); workers/api production deployed manually (gevell CORS verified; needed a @napi-rs/canvas stub alias — pre-existing flipbook-import bundling break); help docs deployed. NOTE apps/web “Deploy PDF” job failed only on its verify step (old URL now a 301) — fixed in #2760.
  4. DNS — DONE (custom-domain attachment auto-created records).
  5. Switch app sender identity env to noreply@gevell.com — still blocked on SES-verifying pdf.gevell.com; senders stay @pdf.theaccessible.org until then.
  6. Verified 2026-09-07: all 19 gevell.com hosts serving (admin/admin-docs 302 = Access challenge, correct).
  7. Raise TTLs back to normal once verified.

Also done at cutover: converter Supabase Site URL → https://pdf.gevell.com; workshop worker CORS allows both origins.


11. Phase 8 — Redirects + SEO (theaccessible.org → gevell.com)

Per D3, theaccessible.org becomes a permanent 301 layer. Reuse/extend the existing workers/redirects worker (already bound to the theaccessible.org zone, same CF account).

  • DONE 2026-09-07 (pulled forward — the #2748 deploy dropped the old-domain Worker bindings, so the 301 layer went live the same evening): theaccessible-redirects owns 17 retired hostnames as custom domains and 301s host+path+query to gevell.com (chart→orgchart, photos→images overrides; API hosts excluded). Old-domain Pages hostnames (audit/remediate/pro/polish/admin/admin-docs) still dual-serve — migrate them into the redirect worker later if desired.
  • Extend the redirects worker to 301 every theaccessible.org (and *.theaccessible.org) path to the matching gevell.com path:
    • pdf.theaccessible.org/x → pdf.gevell.com/x
    • theaccessible.org/workshops → gevell.com/workshops
    • apex + www → gevell.com
  • Preserve full path + query string; use 301 (permanent) so SEO equity transfers.
  • Keep rel=canonical on gevell.com pages pointing to themselves (self-canonical); ensure no page canonicalizes back to the old domain.
  • Submit the new sitemaps to Google Search Console / Bing; add gevell.com as a property; use GSC Change of Address where applicable.
  • Update robots.txt on both domains (old domain: allow crawl of redirects so they’re followed).
  • Update external references you control: GitHub repo/org metadata, social profiles, app-store listings, email signatures, docs links, Uptime Kuma monitor URLs, Grafana links.
  • Keep theaccessible.org registered and auto-renewing indefinitely (D3) — put a renewal reminder in the calendar; a lapsed redirect domain kills the SEO transfer and can be domain-squatted.

12. Phase 9 — Post-cutover watch (first 2 weeks)

  • DMARC: watch gevell.com aggregate reports daily; confirm ~100% SPF+DKIM alignment before tightening to p=quarantine→p=reject.
  • Deliverability: monitor bounce/complaint rates in Resend; Google Postmaster reputation for gevell.com.
  • 404s / redirect gaps: watch CF analytics + worker logs for old-domain paths that don’t map; add explicit redirect rules for any misses.
  • Analytics: verify traffic transfers to gevell.com; watch GSC coverage/impressions for the new property and the old-domain 301 crawl.
  • Auth errors: watch for redirect-URL / PKCE errors indicating a missed allow-list entry.
  • Uptime: all monitors green on new hostnames.
  • After 2 clean weeks: tighten DMARC, consider retiring the dual-send theaccessible.org sender identity (but keep the domain + redirects per D3).

13. Rollback

Everything before Phase 7 is non-primary and reversible by not merging. After cutover:

  • DNS: records were pre-created and low-TTL; the old theaccessible.org production records/deploys are untouched until Phase 8 — repoint DNS back and the old sites serve again within the TTL window.
  • Email: theaccessible.org stays verified and dual-sending, so reverting the EMAIL_FROM env restores the old sender instantly.
  • Redirects: don’t enable the 301 worker (Phase 8) until Phase 7 is confirmed healthy — keeps the old domain serving real content as a fallback.
  • Code: the rebrand is one squash-merge; git revert + redeploy restores old branding. Keep the pre-cutover production build artifacts/tags.

Point of no easy return: once GSC Change-of-Address + p=reject DMARC are set and the old sites are 301-only for weeks, reverting is a fresh migration. Don’t do those until the watch window (§12) is clean.


14. Cross-cutting checklist (don’t-forget bin)

  • Global ~/.claude/scripts/send-email.sh sender (noreply@gevell.com) + ~/.claude/CLAUDE.md references — separate from repo, update deliberately.
  • @anglinai/logger EmailAlertTransport from-address.
  • PDF/report/ACR/VPAT document headers + generated-file branding (these embed the product name into deliverables).
  • Flipbook player chrome + workshop registration emails/receipts.
  • OG/social preview images regenerated with new brand.
  • docs/user (Docusaurus help sites) — branding, domain, deploy target (help.gevell.com?).
  • Legal pages: Privacy, Terms, DMCA, footer copyright entity + year.
  • Dependabot/CI badges, README brand references.
  • Monitoring/alert channel names, Grafana dashboard titles.
  • Decide the fate of theaccessibleorg.com (the DMARC report domain) — keep as-is (it’s just report ingestion) or add a gevell report mailbox.

15. Open risks

  1. Color kit not yet defined — blocks Phase 3; a wrong brand hex that fails contrast will fail the a11y gate and can’t ship.
  2. API-host scope creep — moving api./api-pdf./worker. in the same window multiplies webhook/CORS/Lambda-env risk. Runbook defers them; hold that line.
  3. Space in product name — Gevell PDF must not leak into identifiers, slugs, package names, or domain labels. Enforce display-only substitution.
  4. Email reputation — new sending domain starts with no reputation; dual-send + p=none warm-up + Postmaster monitoring mitigate cold-start spam foldering.
  5. SEO transfer — depends on permanent 301s, kept-alive old domain, and GSC Change of Address. A lapsed theaccessible.org renewal would forfeit it.
  6. Manual-deploy apps (vpat/pro/admin/tag-editor/audit) are easy to forget in a family-wide cutover — the per-app issue checklist (Phase 0) is the guard.