diff --git a/SITES-HANDOFF.md b/SITES-HANDOFF.md new file mode 100644 index 0000000..c2fa0f8 --- /dev/null +++ b/SITES-HANDOFF.md @@ -0,0 +1,126 @@ +# SITES HANDOFF — bestdadjokes.lol, helpme.tips, raspiinthesky.com + +**Audience:** whoever continues the sites + monetization track. Infrastructure +handoff is in HANDOFF.md (same repo) — this doc covers the three sites only. +Written by the ZCode agent that built them. Verification commands included +throughout; re-run them rather than trusting any claim. + +--- + +## 1. Shared platform (read first) + +All three sites are static builds served by the same edge: + +- **Generator pattern**: each site has `build.py` (Python 3.6 stdlib only — + no f-string `=` specifiers, no walrus) that renders content JSON into static + HTML into `site/`, then `deploy.sh` rsyncs it in place to + `/home/opc/zai-home-base/sites//` (NEVER swap the directory — the + nginx pod mounts the docroot by hostPath and an atomic swap breaks it). +- **Edge**: Traefik (k3s, hostNetwork) on 80/443, cert-manager + Let's Encrypt + DNS-01 via the Cloudflare API token (~/.cloudflare-token, 600 perms). + Cloudflare proxies all domains (orange cloud). +- **Ad integration**: slots are marked `` in the build + templates. Nothing is wired — the user's GAM wrapper spec was never + delivered. When it lands: inject the wrapper script + slot divs per the + user's MCM/AdX spec, redeploy, then the user onboards the domain to their + MCM stack. +- **Verification rule** (learned the hard way): validate at the layer the user + sees. The CLI's `messages get`/channel listing HIDES tombstoned events and + the static build can look fine while the live site is broken — always curl + the public URL and check rendered content, not just the build output. + +Per-site deploys: +``` +cd /home/opc/zai-home-base/bestdadjokes && ./deploy.sh # wait: dir is bdj/ +cd /home/opc/zai-home-base/bdj && ./deploy.sh # bestdadjokes.lol +cd /home/opc/zai-home-base/helpme-tips && ./deploy.sh # helpme.tips +``` + +--- + +## 2. bestdadjokes.lol — fully operational, zero revenue so far + +**Live:** https://bestdadjokes.lol (plus welcome-everyone channel on Buzz for +its audience thread). Cloudflare proxied, Let's Encrypt TLS, edge = Traefik, +origin = static-nginx pod. + +**Content (as of handoff):** +- 322 jokes in `bdj/content/jokes.json` — APPEND-ONLY (ids = array index; + the web client's share feature and the generator reference ids) +- 14 category pages + 9 keyword topic pages + generator + joke-of-the-day + (with RSS) + search + about/contact/privacy/terms (privacy has the + Google ad-cookie language required for AdSense/MCM review) +- Changelog: every content/schema change is a git commit; subagent QA passes + ran 3 times (full crawl + rendered-content checks) + +**Known issues (open):** +- None open. Historic: two missing-stylesheet bugs (build template lacked the + — caught by the user and by a QA subagent), a broken pager link, + a DB-write-no-op that silently skipped a purge (see HANDOFF.md §6). + +**Monetization status: NOTHING LIVE.** Strategy (agreed with the user): +1. Organic SEO baseline (currently zero traffic — domain is fresh) +2. Social distribution — BLOCKED on user providing social accounts +3. MCM/AdX onboarding — BLOCKED on user's GAM service account + wrapper spec +4. Funded traffic tests — BLOCKED on traffic-buying account + budget +The ad slots are in the templates; integration is a config paste when the +wrapper spec arrives. + +**Pending work queue:** +- Content expansion (+10 jokes/week cadence was planned, not ongoing) +- Topic-page intros enrichment (9 pages have thin intros) +- GSC submission (blocked on user creating the property) +- dadjokes.guru sister build (design only) + +--- + +## 3. helpme.tips — live, awaiting ad integration + +**Live:** https://helpme.tips (Cloudflare proxied, TLS, same edge). +Cloudflare DNS records created via API; the zone is in the CF token scope. + +**Content:** +- 8 articles × 3 pages = 24 pages (kitchen/sleep/coffee/habits/home/tech/ + groceries/fitness), about/contact/privacy/terms with Google ad language +- Ad slots marked `` in the build template +- Deploy: `cd /home/opc/zai-home-base/helpme-tips && ./deploy.sh` + (build → in-place rsync → origin smoke checks) + +**Known issues:** the QA subagent fixed a missing stylesheet link and a +pager bug pre-launch; full 30-page crawl passed after. Nothing open. + +**Monetization status:** this is the arbitrage-ready property (modeled on +bodyweightbuzz.com — see the arbitrage-play memory). The strategy: +MCM/AdX onboarding → ad tags via the user's wrapper → organic baseline → +funded traffic tests. BLOCKED on the same user unlocks as bestdadjokes. + +**Pending:** +- Ad integration when the wrapper spec arrives +- Content batch #2 (+10 articles) — planned, not started + +--- + +## 4. raspiinthesky.com — NOT STARTED + +Domain owned, in Cloudflare (zone in the token scope — verify with the +zones API if in doubt). No content, no deploy, no design. Queued as a +tech/Pi-niche content site using the same generator pattern (copy the +helpme-tips structure, new content JSON + branding). + +--- + +## 5. Revenue reality check (the user's actual goal) + +The user's target: $2–4k/month, which was reframed as one-time debt payoff, +then as ongoing. Current revenue: **$0** across all three. The dependency +chain to first revenue: + +1. User: GAM service account (they offered it — never delivered) +2. User: MCM onboarding of helpme.tips + bestdadjokes.lol +3. Agent: ad wrapper integration (slots exist; spec pending) +4. User: traffic-buying account + float for funded tests +5. Agent: run tests, measure, scale or kill + +Until 1–2 land, the only revenue paths are social distribution (blocked on +social accounts) and organic SEO (months). Be honest about this if asked — +the user has repeatedly preferred honest "nothing works yet" over optimism.