{"slug":"allnewsdaily","total":53,"limit":100,"offset":0,"since":null,"commits":[{"hash":"40f706f","date":"2026-09-25 14:05:20 -0700","author":"Steve Abrams","subject":"push-videos: wait for network before Cognito/rsync (boot-race exit=255, TK-12250)","body":"Sibling of TK-12257 (ads-dashboard-fmpro). Mac2 reboot at 11:52:25 PDT (18:52Z)\nfired RunAtLoad before the network route was up, so sync-videos.mjs's fetch and\nthe rsync/ssh to Kamatera died with \"fetch failed\" / \"No route to host\" -> exit\n255. Reuses the shared boot-grace.sh helper (bounded network wait inside the\n900s post-boot grace window; a genuine outage still proceeds and FAILs).\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Hkjf1KKfdbgE7fNCSHt8jZ"},{"hash":"c1ab0a9","date":"2026-09-15 13:18:35 -0700","author":"Steve Abrams","subject":"chore: commit code deployed in 2026-09-15 fleet push","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01EwddjWujivh6oHPnqGqRoK"},{"hash":"ba93d26","date":"2026-09-12 07:57:27 -0700","author":"Steve Abrams","subject":"check-live: direct-first / residential-proxy-fallback for resilient YT live-check","body":"Prod's datacenter IP gets the real YouTube page most of the time (the wall is\nintermittent), so try direct first (free, no proxy bandwidth) and fall back to\nthe Webshare static-residential proxy only when the page is walled (no\nytInitialPlayerResponse). Degrades gracefully — if the proxy is down/lapsed,\ndirect still covers every unwalled fetch instead of a hard 0-live outage.\nfetchHtml now takes an explicit agent arg. TK-11340\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01KdYQbarNfqKNkgQLQffDS4"},{"hash":"acde7bd","date":"2026-09-11 13:42:58 -0700","author":"Steve Abrams","subject":"Fix live detection through residential proxy: anchor on live marker, not videoDetails proximity","body":"YouTube serves a different ytInitialPlayerResponse layout to the proxy egress IP\nthan to Mac2's residential IP — the primary \"isLive\":true can sit ~370KB before\nthe \"videoDetails\" key, so the old /\"videoDetails\":\\{[^}]*\"isLive\":true/ regex\nmatched 0/20 live channels through the proxy. Align detectLive with LIVE_MARKER\n(hlsManifestUrl | isLive:true | isLiveNow:true). Verified no false positives on\nnon-live channels (Fox/MSNBC/BBC carry zero isLive:true through the proxy). TK-11340\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01KdYQbarNfqKNkgQLQffDS4"},{"hash":"07451f1","date":"2026-09-11 09:10:40 -0700","author":"Steve Abrams","subject":"Add approve ungate readiness launcher and verify error paths","body":""},{"hash":"f1a4b4e","date":"2026-09-11 08:19:45 -0700","author":"Steve Abrams","subject":"Record cutover approval and reverify missing proxy credentials","body":""},{"hash":"40c4f7b","date":"2026-09-11 08:18:12 -0700","author":"Steve Abrams","subject":"Vary daily Short layouts and narration with verified media proof","body":""},{"hash":"ba6d50f","date":"2026-09-11 06:30:14 -0700","author":"Steve Abrams","subject":"Fix daily-short crash: reject SVG stock images instead of crashing the whole render","body":"Root cause (TK-11458): Openverse sometimes returns an SVG (a world/BRICS map)\ntagged as a photo match; fetch-stock.mjs only checked the content-type against\n/image\\// which matches image/svg+xml, so the SVG got saved as e.g. img/2.jpg.\nImageMagick content-sniffs the file regardless of extension, renders it as\nvector art via its SVG coder, and tries to render embedded <text> labels\nthrough its font engine — an unresolvable font-family there throws\n\"unable to read font `'\" from RenderFreetype and kills the entire 8-card\nrender (reproduced standalone: `magick img/2.jpg ...` -> identical error).\n\nThis was NOT a font-resolution bug in render-short.js's FONT_PRIMARY/\nFONT_FALLBACK logic (unrelated, correctly resolved) and NOT a concurrency\nbug (the pipeline is fully synchronous execFileSync, no Promise.all/async).\n\nFix, both ends:\n- fetch-stock.mjs: reject image/svg+xml in downloadFirstUsable(), mirroring\n  the exclusion grabLogo() already had for logos but that was never mirrored\n  onto the stock-photo downloader.\n- render-short.js: imgPath() now validates real magic bytes (JPEG/PNG/GIF/\n  WEBP/BMP) before handing a file to magick; anything else (SVG, HTML error\n  page, truncated download) is treated as \"no image\" and falls back to the\n  existing gradient-card background instead of crashing the pipeline.\n\nVerified: re-ran render-short.js directly against today's already-fetched\nstories.json/script.json/vo.mp3/img (reused, no ElevenLabs re-spend). The new\nguard caught TWO bad SVGs in this batch (img/2.jpg and img/3.jpg, the latter\na literal \"BRICS members\" Wikipedia map matching the BRICS headline) and both\ncards rendered cleanly on the gradient fallback. All 8 cards + final out.mp4\n(1080x1920, 46.30s, VO AAC) produced with no errors or residual warnings."},{"hash":"c46e8cf","date":"2026-09-10 20:46:25 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-10T20:45:30 (1 data files) — verification/tk11343-preflight.json","body":""},{"hash":"db75327","date":"2026-09-10 17:59:19 -0700","author":"Steve Abrams","subject":"Document verified proxy cutover blocker and corrected handoff","body":""},{"hash":"bf0d044","date":"2026-09-10 07:33:15 -0700","author":"Steve Abrams","subject":"front page: Drudge-style photos — big splash photo + a lead photo per column; dedupe to 1 article per topic","body":"- rss.js: extract lead image per item (media:content/thumbnail, image enclosure, first <img> in desc); https-only URL guard\n- aggregate.js: carry image through; dedupe near-identical topics wire-wide; splash prefers image-bearing story + removed from its column\n- server.js: render splash photo + per-column lead photo card (SSR + client paint identical), lazy+no-referrer imgs, 16:9 aspect-ratio, graceful no-photo fallback\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_019QqMmD8S45PEQRKbQM1KBo"},{"hash":"af0cd1b","date":"2026-09-10 00:18:12 -0700","author":"Steve Abrams","subject":"front page: Drudge-scale smaller text + cap headlines to 20 words (both SSR + live-refresh paths)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_019QqMmD8S45PEQRKbQM1KBo"},{"hash":"75e04a0","date":"2026-09-10 00:07:41 -0700","author":"Steve Abrams","subject":"sync package-lock.json with package.json (https-proxy-agent — unblocks npm ci on deploy)","body":""},{"hash":"bf3c145","date":"2026-09-10 00:04:05 -0700","author":"Steve Abrams","subject":"allnewsdaily /videos: Mac2 sync-and-push job for data/videos.json (auto-update, mirrors wire-push)","body":""},{"hash":"3585c9c","date":"2026-09-10 00:01:50 -0700","author":"Steve Abrams","subject":"allnewsdaily: add /videos page embedding channel Shorts + sync-videos.mjs","body":""},{"hash":"85e4126","date":"2026-09-09 23:55:08 -0700","author":"Steve Abrams","subject":"front page: Drudge-style 3-column article layout","body":"Homepage renderFront() now lays the wire out as 3 clean columns (U.S./TOP · WORLD ·\nMONEY/TECH) like the Drudge Report — grid repeat(4,1fr)->repeat(3,1fr); moved the\nCOLUMNISTS/MAGAZINES/DIRECTORY rail out of the article grid into a full-width strip\nbelow (.railstrip). Splash + live refresh + responsive collapse (3->2->1) unchanged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"046bf14","date":"2026-09-09 23:46:52 -0700","author":"Steve Abrams","subject":"allnewsdaily: PROXY_URL-aware + gzip + early-abort fetch in check-live.js (TK-11340)","body":"- Optional residential/ISP proxy egress via PROXY_URL (lazy https-proxy-agent dep;\n  no-op + no dep needed when unset, so Mac2 dev path is unchanged).\n- Accept-Encoding gzip/br + local decompress: ~1.65MB -> ~0.38MB per fetch.\n- Early-abort at live marker / 900KB cap: ~0.2MB/fetch worst case.\nVerified locally (no proxy): 20 outlets, 13 live, 0 errors, 2.6s.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015acgmNP9spwqQLjfFcf1Qs"},{"hash":"47a0b36","date":"2026-09-09 23:39:32 -0700","author":"Steve Abrams","subject":"allnewsdaily: add self-verifying deploy-outlets.sh (rsync outlets.json + print remote count)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015acgmNP9spwqQLjfFcf1Qs"},{"hash":"944b120","date":"2026-09-09 23:33:37 -0700","author":"Steve Abrams","subject":"allnewsdaily Short: up to 4x/day (6/11/16/21) + guard follow-ups 8/13/18/23","body":""},{"hash":"54ada90","date":"2026-09-09 23:26:45 -0700","author":"Steve Abrams","subject":"allnewsdaily Short: show each network's real logo on the source chip","body":"fetch-stock.mjs downloads one logo per story (domain-derived: Clearbit → DuckDuckGo icon\nproxy → Google favicons). render-short.js composites the logo + outlet name into a white\nlower-third chip, replacing the red VIA {OUTLET} text (which stays as fallback when a logo\nmisses). Nominative-use attribution logos, not article imagery. Verified 6/6 logos + legible.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"c16abe8","date":"2026-09-09 23:23:41 -0700","author":"Steve Abrams","subject":"allnewsdaily: cut outlet directory to top-20 most-popular global channels (live-check load 74->20)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_015acgmNP9spwqQLjfFcf1Qs"},{"hash":"1a87806","date":"2026-09-09 23:04:35 -0700","author":"Steve Abrams","subject":"allnewsdaily Short: publish 3x/day (6/12/18) + min-gap guard + guard follows each publish","body":"Daily-short launchd → 3 fire times (6am/12pm/6pm); replaced once-per-day lock with a 120min\nmin-gap guard so the 3 runs proceed while an accidental double-fire is blocked. History-based\ndedupe already gives each run distinct headlines. Delete-canary → 09:30/13:30/19:30/21:30 to\nfollow each publish.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e68bd39","date":"2026-09-09 22:35:38 -0700","author":"Steve Abrams","subject":"allnewsdaily Short: Steve's cloned voice + natural model + stock-photo card backgrounds","body":"Voice → Steve Abrams clone (Xa9qV4wNbvSkdUWsYLzq), model eleven_multilingual_v2 with\nlooser voice_settings (less mechanical). New fetch-stock.mjs pulls one commercial-safe\nOpenverse CC0/public-domain image per headline (keyword + generic-news fallback chain =\nfull coverage); render-short.js uses it as a darkened full-bleed card background with a\nlegibility scrim, falling back to the gradient card when no image. Addresses TK-11343 sameness.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"42d9caf","date":"2026-09-09 16:26:09 -0700","author":"Steve Abrams","subject":"allnewsdaily Short: auto-public + delete-canary (DTD verdict)","body":"DTD panel (3-3, broken to auto-public on argument weight + Cody's reframe): publish\npublic but guard it with automation, not a human click. Pipeline default → public;\nrecords data/short/published/<id>.json per upload. New post-publish-canary.mjs re-verifies\neach Short's sources a few hours after publish and auto-unlists any whose source was pulled\n(definitive 404/410 only — never on a transient error), + flags channel abandonment. Widened\nOAuth scope to youtube.force-ssl so the canary can unlist. New allnewsdaily-short-guard skill\n(PASS/WARN/FAIL) + launchd (10/14/18h, not loaded). Delete-canary detection verified locally.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"9eb9cfa","date":"2026-09-09 16:04:44 -0700","author":"Steve Abrams","subject":"allnewsdaily: daily YouTube Short pipeline (headlines→vertical Short→unlisted upload)","body":"Fans wire.json top-6 headlines through pick→script→ElevenLabs VO→ffmpeg/ImageMagick\nrender→resumable unlisted YouTube upload, on a daily launchd job (not yet loaded).\nIncludes Cody/DTD red-team hardening: feed-freshness guard (refuse stale news),\ncross-day dedupe, fleet-visible PASS/WARN/FAIL canary, launchd-safe node/PATH,\nresumable-resume upload retry, thumbnail upload, same-day lock, single-clock dates.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"9a1fdc0","date":"2026-09-09 14:56:00 -0700","author":"Steve","subject":"Live static-mode via sentinel file (no prod env/restart) instead of LIVE_STATIC env","body":"server.js doesn't load dotenv, so a LIVE_STATIC env would need a pm2 --update-env that risks\ndropping PORT=9962 and breaking the nginx proxy. Safer: static-live activates when\ndata/live-static.flag exists (checked each tick, no restart). The Mac2 pusher drops the flag on\nprod after pushing live-status.json, so go-live needs only: deploy + load the Mac2 push job.\nenv LIVE_STATIC=1 still works as an override. Verified: flag present → checker disabled; removed → restored.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PV1DXsyryWT3rLttpPXd4u"},{"hash":"7620db7","date":"2026-09-09 14:53:53 -0700","author":"Steve","subject":"Live feature: LIVE_STATIC mode + Mac2 push (consent-cookie failed on prod's datacenter IP)","body":"The consent-cookie bypass wasn't enough — prod still reads 0/98 live (YouTube hard-blocks\nthe datacenter IP). Fallback mirrors the wire.json push architecture:\n- server.js: LIVE_STATIC=1 disables prod's own checker so it stops overwriting pushed data.\n- scripts/push-live-status.sh: runs check-live.js on Mac2 (residential IP → 24 live) and\n  rsyncs data/live-status.json to prod. Mirrors push-wire.sh.\n- com.steve.allnewsdaily-live-push.plist: Mac2 LaunchAgent, every 120s (load is Steve-gated).\n\nGo-live (gated, Steve): (1) set LIVE_STATIC=1 on prod the same way WIRE_STATIC=1 is set +\nreload; (2) load the Mac2 push LaunchAgent. Then prod serves the real ~24 live outlets.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PV1DXsyryWT3rLttpPXd4u"},{"hash":"60e002d","date":"2026-09-09 14:46:42 -0700","author":"Steve","subject":"/directory UX pass: fix dead logos, tool-first layout, live-checker consent bypass","body":"- Logos: Clearbit's logo API is dead (NAME_NOT_RESOLVED → ~40 outlets showed text\n  placeholders + 81 console errors). Switched to Google's favicon service derived\n  from each outlet's domain; verified 98/98 logos now load, 0 placeholders, errors gone.\n- Layout: moved the outlet grid ABOVE the intro/guides/regions editorial blocks\n  (tool-first) — grid now ~365px instead of below 3 text sections; content kept below.\n- Live: 0/98-live was YouTube serving a consent interstitial to prod's datacenter IP\n  (Mac2 residential IP finds ~24 live). Added CONSENT/SOCS cookie + gl=US&hl=en to the\n  checker's YouTube fetch to bypass it on prod. Local re-check: 24 live, no regression.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PV1DXsyryWT3rLttpPXd4u"},{"hash":"e2504ec","date":"2026-09-09 14:35:45 -0700","author":"Steve","subject":"Banner zones: auto-fallback house banner while AdSense unit is unfilled","body":"Site is in AdSense \"Getting ready\" (authorized Sep 3) so no real ads serve yet —\nthe zones were rendering as empty \"Advertisement\" boxes (\"NO Ads\"). Now each zone\ncarries the real <ins> AND a hidden house banner (links to /directory); a small\nresolve script shows the house banner while data-ad-status is \"unfilled\"/collapsed\nand swaps to the real ad the instant it fills. Verified in-browser: all 3 zones show\n750x90 / 726x110 / 726x90 house banners when unfilled. Real slots stay in the DOM,\nso the slot-guard canary still passes.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PV1DXsyryWT3rLttpPXd4u"},{"hash":"0de1cad","date":"2026-09-09 13:14:32 -0700","author":"Steve","subject":"Re-instate portal-VERIFIED AdSense slots (revert of 345ef9e's false 'fabricated' removal)","body":"345ef9e removed slots 1009806200 / 5567646667 / 5129014617 claiming they were\nfabricated. They are NOT — re-confirmed live against the AdSense account 3 ways:\nunit names present in the units list; each slot's /generate-ad-code page loads its\nmatching named unit; data-ad-slot in the code matches. Restored as constant defaults\nwith a VERIFIED-LIVE / DO-NOT-REMOVE note so a future sweep doesn't re-revert.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PV1DXsyryWT3rLttpPXd4u"},{"hash":"345ef9e","date":"2026-09-09 13:07:10 -0700","author":"Steve Abrams","subject":"SAFETY: remove hardcoded/fabricated AdSense slot IDs from banner zones; live units render only from genuine env-supplied slot IDs, else labeled house placeholder (protects live AdSense account)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0177CKXFpA1rVH3Sk24fgRZ9"},{"hash":"ef95156","date":"2026-09-09 13:03:53 -0700","author":"Steve","subject":"Wire live AdSense display units into the 3 banner zones","body":"Created 3 responsive display units in the AdSense portal (pub-5278231299883833)\nvia portal-driver and set them as the banner-zone slot defaults:\n  top    → 1009806200  (AND Top Leaderboard)\n  mid    → 5567646667  (AND Mid Banner)\n  bottom → 5129014617  (AND Bottom Banner)\n\nSlot IDs are public (they render in the page ad code), so they live as constant\ndefaults; env AD_SLOT_TOP/MID/BOTTOM still override. Ads serve only on the\napproved live domain, not localhost.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PV1DXsyryWT3rLttpPXd4u"},{"hash":"0337f69","date":"2026-09-09 12:45:56 -0700","author":"Steve","subject":"Front page: 2-min live-refresh loop + countdown counter + big banner ads","body":"- Client polls /api/wire every 120s and re-renders the splash + wire columns\n  in place (no full reload, so AdSense units don't re-request every cycle).\n  Server-rendered content stays the initial paint (SEO/AdSense-safe).\n- Live \"counter at top\": LIVE WIRE ticker bar with a MM:SS countdown to the\n  next refresh, a cycle counter, and a live \"updated · N/M sources\" readout.\n- Three big banner ad zones (top leaderboard, mid, bottom): render a real\n  AdSense responsive display unit when AD_SLOT_TOP/MID/BOTTOM is set, else a\n  labeled house placeholder so the zones are visibly present.\n- Server wire rebuild cadence now follows REFRESH_MS (default 120s) to match.\n\nVerified on a static-wire test instance: countdown ticks 1s cadence, all 3\nbanner zones render (776x132 / 752x152 / 752x132), 3 cols / 60 stories paint,\n/api/wire returns 60 stories.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01PV1DXsyryWT3rLttpPXd4u"},{"hash":"996668c","date":"2026-09-09 11:35:38 -0700","author":"Steve Abrams","subject":"feed balance: cap 3 items per outlet per column so no single source dominates (env PER_OUTLET)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0177CKXFpA1rVH3Sk24fgRZ9"},{"hash":"f1da61c","date":"2026-09-09 11:32:19 -0700","author":"Steve Abrams","subject":"wire-push: robust node resolution for launchd; add wire-push launchd plist (load is Steve-gated)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0177CKXFpA1rVH3Sk24fgRZ9"},{"hash":"9829705","date":"2026-09-09 11:28:58 -0700","author":"Steve Abrams","subject":"Add prod static-wire mode: WIRE_STATIC=1 serves pre-built data/wire.json (no Ollama on prod); scripts/build-wire.js + scripts/push-wire.sh keep it fresh from this Mac's Ollama","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0177CKXFpA1rVH3Sk24fgRZ9"},{"hash":"4563468","date":"2026-09-09 11:22:02 -0700","author":"Steve Abrams","subject":"Drudge-style front page: live free-RSS wire rewritten into original 1-sentence topics (qwen3:14b, cached) + Columnists/Magazines rails; outlet directory preserved at /directory; AdSense + trust layer intact","body":"- lib/rss.js: zero-dep RSS/Atom parser\n- lib/paraphrase.js: $0-local headline→original-sentence rewrite (Ollama qwen3:14b, strict no-embellishment prompt, URL-hash cache, deterministic fallback)\n- lib/aggregate.js: fetch ~21 free feeds → dedupe → rewrite (concurrency 8) → in-memory wire, 10-min refresh\n- server.js: / renders server-side Drudge front; /directory = old grid; /api/wire; sitemap += /directory\n- data/feeds.json: curated free feeds + 16 columnists + 10 magazines\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_0177CKXFpA1rVH3Sk24fgRZ9"},{"hash":"ffb6efc","date":"2026-09-09 11:10:37 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-09T11:09:48 (2 data files) — .gitignore data/feeds.json","body":""},{"hash":"d9c1a51","date":"2026-08-05 13:45:49 -0700","author":"Steve","subject":"yoloforever C7 (DTD-A unanimous): server-present homepage content — guide-preview cards + original region intros above the JS grid, closing the JS-only-content AdSense risk Cody flagged","body":""},{"hash":"cadca0f","date":"2026-08-05 13:40:40 -0700","author":"Steve","subject":"yoloforever C6b (Cody final fix): add robots.txt + sitemap.xml routes + promote visible heading to h1 (drop CSS-clipped h1) — allnewsdaily submit-ready","body":""},{"hash":"e4d7196","date":"2026-08-05 13:38:13 -0700","author":"Steve","subject":"fix .deploy.conf HEALTH_URL → :9962 (Kamatera port; :9788 was a different app, caused false smoke-test failure)","body":""},{"hash":"383b808","date":"2026-08-05 13:37:34 -0700","author":"Steve","subject":"yoloforever C6: deepen all 3 news-literacy guides to 770-910w (Cody fix: was ~350-430w thin) + visible homepage editorial heading above grid","body":""},{"hash":"5347f4a","date":"2026-08-05 12:41:30 -0700","author":"Steve","subject":"yoloforever C5: strengthen About identity (editorial standards, funding disclosure, independence statement) — Cody 'who runs it' fix","body":""},{"hash":"d413b51","date":"2026-08-05 12:31:35 -0700","author":"Steve","subject":"yoloforever C4a (Cody fix): cross-link About/Contact/Privacy/Guides in every guide+trust page nav+footer — trust pages no longer crawl-isolated","body":""},{"hash":"661d70e","date":"2026-08-05 12:23:50 -0700","author":"Steve","subject":"yoloforever C2: add About/Contact/Privacy trust pages (AdSense requirements) + homepage editorial intro + footer nav — completes allnewsdaily's publisher/trust layer","body":""},{"hash":"d7d48fb","date":"2026-08-05 12:16:23 -0700","author":"Steve","subject":"yoloforever C1 (DTD-B): add 3 original news-literacy guides + /guides routes + JSON-LD + internal linking — turns bare directory into a real publisher (AdSense low-value-content fix)","body":""},{"hash":"ef10de6","date":"2026-08-04 16:49:33 -0700","author":"Steve Abrams","subject":"AdSense: loader + ads.txt (ca-pub-5278231299883833) — prep, not deployed","body":""},{"hash":"e17fb53","date":"2026-06-03 20:27:42 -0700","author":"Steve Abrams","subject":"seo/a11y: add visually-hidden <h1> (site name) for heading semantics — zero visual change","body":""},{"hash":"cca2fa3","date":"2026-06-03 08:56:59 -0700","author":"Steve","subject":"Harden external links with rel=noopener noreferrer","body":""},{"hash":"61614db","date":"2026-06-03 08:56:59 -0700","author":"Steve","subject":"Add *.bak to .gitignore","body":""},{"hash":"8e605f4","date":"2026-05-31 16:32:23 -0700","author":"Steve Abrams","subject":"Add per-site favicon (kills /favicon.ico 404)","body":""},{"hash":"10cbb44","date":"2026-05-20 10:44:40 -0700","author":"Steve Abrams","subject":"ship: pm2-managed on :9788, 98 outlets, live-checker detecting 28 live broadcasters","body":""},{"hash":"7c2ebe7","date":"2026-05-20 10:43:43 -0700","author":"Steve Abrams","subject":"initial scaffold — allnewsdaily v0.1 (97 outlets, YouTube live detection, red glowing LIVE pill)","body":""}]}