{"slug":"IWasCute","total":24,"limit":100,"offset":0,"since":null,"commits":[{"hash":"316515b","date":"2026-09-10 18:06:24 -0700","author":"Steve Abrams","subject":"TK-11412: add /privacy + /terms, and stop the licensor flow claiming a submission that never happened","body":"Two blockers on IWasCute public readiness, both verified live before changing anything.\n\n1. /privacy and /terms did not exist. The login and licensor pages link to both,\n   so every visitor following those links got a 404 - and a reachable, accurate\n   privacy policy is a hard AdSense requirement, not a nicety. Both pages are\n   written from what the code actually does: the two real third parties (AdSense\n   ca-pub-5278231299883833 and GA4 G-2DHDBP8R78, both in layout.tsx) and the real\n   columns in db/001_schema.sql - email, display name, adult confirmation,\n   photographer and copyright fields, the likeness signature, and the separate\n   editorial / commercial / AI-training consents. No boilerplate claims about data\n   we do not collect.\n\n2. ReviewSubmit simulated a submission. It waited 2.2s then set success on\n   Math.random() > 0.05, telling a real person their photos were in the queue and\n   that we would email them when cleared - for photographs that were never\n   transmitted - and showing a random failure the other 5% of the time. There is\n   no /api/licensor/submit endpoint (the only API routes are auth and admin), so\n   nothing was ever sent or stored. The flow now ends on an honest preview state\n   saying plainly that submissions are not open, nothing was uploaded, and the\n   data stayed in the browser.\n\n'success' is deliberately removed from SubmitState rather than left unused: it\nwould compile fine but render nothing, dropping the user back on the form.\n\nVerified: tsc --noEmit clean, next build succeeds, /privacy and /terms present in\nthe route table as static pages.\n\nDeploy is NOT included here and stays gated.\n\nCo-Authored-By: Claude Opus 5 <noreply@anthropic.com>"},{"hash":"cb37a2a","date":"2026-09-10 13:38:52 -0700","author":"Steve Abrams","subject":"iwascute: pin .deploy.conf PROJECT_NAME=gap-iwascute (real live pm2 name) so deploy reload succeeds (TK-11412)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QTGuKtAvmVMngA9PyTiftG"},{"hash":"3c1cc30","date":"2026-09-10 13:31:23 -0700","author":"Steve Abrams","subject":"iwascute: exclude prod verification/ artifacts from rsync deploy (delete-guard) (TK-11412)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QTGuKtAvmVMngA9PyTiftG"},{"hash":"5dd39c2","date":"2026-09-10 13:30:12 -0700","author":"Steve Abrams","subject":"iwascute: add sitewide AdSense adsbygoogle.js loader to root layout for Auto Ads eligibility (TK-11412)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QTGuKtAvmVMngA9PyTiftG"},{"hash":"c6ece76","date":"2026-09-10 13:03:14 -0700","author":"Steve Abrams","subject":"iwascute: add FAQ page (content depth), wire into footer + sitemap, scaffold canonical rsync .deploy.conf (TK-11412 AdSense readiness)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QTGuKtAvmVMngA9PyTiftG"},{"hash":"21032c0","date":"2026-09-10 12:54:49 -0700","author":"Steve Abrams","subject":"iwascute: canonicalize homepage for AdSense — redirect dev v1/v2/v3 variants to /, sitewide Privacy/About/Contact footer, drop dead Express-era static index/admin (TK-11412)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01QTGuKtAvmVMngA9PyTiftG"},{"hash":"f962e4a","date":"2026-09-10 12:00:39 -0700","author":"Steve Abrams","subject":"iwascute: redirect /privacy -> /privacy.html (AdSense URL consistency)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"edd2d57","date":"2026-09-10 11:51:24 -0700","author":"Steve Abrams","subject":"Add clean /privacy route (AdSense URL consistency)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"1106eb7","date":"2026-09-10 11:07:56 -0700","author":"Steve Abrams","subject":"Add privacy policy page for AdSense","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"443abe5","date":"2026-09-10 10:42:25 -0700","author":"Steve Abrams","subject":"Deploy IWasCute verification with preserved analytics and portable runtime proof","body":""},{"hash":"9205c24","date":"2026-09-10 10:38:24 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-10T10:34:55 (2 data files) — verification/TK-11380/canary/results.json verification/TK-11380/production.patch","body":""},{"hash":"a21f9dd","date":"2026-09-10 09:10:57 -0700","author":"Steve Abrams","subject":"Record IWasCute verification boundaries and deployment gates","body":""},{"hash":"9ee4d7d","date":"2026-09-10 09:10:12 -0700","author":"Steve Abrams","subject":"Verify AdSense ownership without loading ads in private photo flows","body":""},{"hash":"fc38976","date":"2026-09-09 16:02:11 -0700","author":"Steve","subject":"TK-11341: add AdSense Auto-Ads loader + ads.txt (revert to remove ads)","body":""},{"hash":"744445d","date":"2026-08-30 22:58:28 -0700","author":"Steve Abrams","subject":"add creds-in-URL fetch guard to gated pages (TK-10984)","body":""},{"hash":"22cd8ab","date":"2026-08-25 10:48:51 -0700","author":"Steve","subject":"creds-safe fetch guard: resolve relative fetch vs credential-free location (creds-in-URL trap)","body":"Fleet inoculation — opening this basic-auth app with credentials in the URL\npoisoned document.baseURI and made relative fetch('/api/…') throw. Guard resolves\nnon-absolute request URLs against location instead. Ref: creds-in-url-fetch-guard-fleet-pattern.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"4d594ed","date":"2026-08-04 11:49:25 -0700","author":"Steve Abrams","subject":"Strip DW marketing pixel + ad slot from internal tool (not a customer-facing site) [ads/tracking scope]","body":""},{"hash":"dfb7fc3","date":"2026-08-04 11:27:36 -0700","author":"Steve Abrams","subject":"Wire DW Meta Pixel 1431180262113856 + DW-network ad slot [ads/tracking rollout]","body":""},{"hash":"b4350f1","date":"2026-05-30 23:57:43 -0700","author":"Steve Abrams","subject":"harden .gitignore: add backup file patterns (*.bak-*, *.pre-*, *.orig, *.save, *.old, *~, copy-of-*)","body":"Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"d56ab2a","date":"2026-05-30 21:21:53 -0700","author":"Steve Abrams","subject":"fix: respect PORT env var in server.js; add missing express dep; guard division-by-zero in TvN slider","body":"- server.js: PORT was hardcoded 7350, ignoring process.env.PORT; now uses process.env.PORT||7350\n- package.json: express was used in server.js but never declared as a dependency (MODULE_NOT_FOUND on fresh install)\n- public/index.html: moveSlider() divided by pct which can be 0 when slider is at left edge, producing Infinity width on thenEl; guarded with pct>0 check\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"f0b70d3","date":"2026-05-30 09:49:20 -0700","author":"Steve","subject":"security: strip hardcoded dw_admin DSN password -> env-first/passwordless. No rotation/deploy.","body":""},{"hash":"d340dfc","date":"2026-05-20 00:27:37 -0700","author":"Steve","subject":"add: pre-stage Meta Pixel snippet (placeholder; flip via _dw-batch set-fb-pixel.sh)","body":"Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"12b7f89","date":"2026-05-13 08:57:55 -0700","author":"Steve","subject":"snapshot: 2 file(s) changed, +1 new, ~1 modified","body":""},{"hash":"5f5efec","date":"2026-05-06 10:25:05 -0700","author":"Steve Abrams","subject":"initial scaffold (gitify-all 2026-05-06)","body":""}]}