← back to Robet Site
OVERNIGHT-LOOP.md
79 lines
# ROBERT — overnight officer-yolo refinement loop
**Site:** robert.agentabrams.com → Kamatera 45.61.58.125 :9790 (pm2 `robert-site`) · local mirror :9788
**Pipeline:** DTD committed the order once (no per-cycle Codex cost); each wake executes the next item.
**Rails (HARD):** every pass is LOCAL + reversible (commit per pass). Redeploy = rsync + pm2 reload +
SMOKE TEST; on smoke-fail → pm2 rollback to last-good, never leave live broken. NO gated action
(DNS, new domains, secret rotation, destructive) runs unattended — those stay queued for Steve.
## DTD-committed priority order (3-LLM panel, unanimous lean)
1. [x] (a) Cross-browser + interaction verify & self-heal (/5x: Chrome/Safari/Firefox + clickthrough)
2. [x] (b) Accessibility — hamburger focus-trap/ARIA/keyboard + APCA hero contrast (hero-readability-auditor)
3. [x] (c) Mobile responsive polish
4. [x] (e) Contact-form hardening — honeypot + validation + rate-limit
5. [x] (f) Security headers (CSP/helmet-style) + 404 page
6. [x] (d) SEO/OG meta + favicon + sitemap.xml + robots.txt
7. [x] (g) Admin UX — show/hide key toggle + inline validation
8. [x] (i) Lightweight test suite
9. [x] (h) Graphic-designer + interior-designer advisory critique → apply
→ when list exhausted: fresh DTD for round 2 (deeper polish).
## Ledger (append per cycle)
| # | item | result | commit | deployed |
|---|------|--------|--------|----------|
| 1 | (a) cross-browser | Chromium PASS (0 console errs, nav+render OK); WebKit/FF binaries absent → pending | — | n/a (no code change) |
| 2 | (b) accessibility | focus-trap+ARIA OK, esc-restore OK, hero 17.9:1 (APCA>60) | 672fd87 | ✅ smoke PASS |
| 3 | (c) mobile polish | overflow 0px @320/375/414/720; nav OK @320; tap targets ≥44 | ba41017 | ✅ smoke PASS |
| 4 | (e) form hardening | honeypot drops bot, bad-email 400, valid stored, rate-limit 429 — all verified + smoke PASS | 06d8277 | ✅ |
| 5 | (f) security + 404 | CSP+5 headers live, booking allowlisted, admin script externalized, custom 404 (status 404) | 44d16c0 | ✅ smoke PASS |
_Note: app + nginx both set X-Frame-Options/X-Content-Type (harmless duplicate); trim nginx ones in a later cleanup pass._
| 6 | (d) SEO | OG+Twitter meta, 1200x630 OG card, SVG favicon, robots.txt, sitemap.xml, canonical — all 200 + smoke PASS | 31ca91f | ✅ |
| 7 | (g) admin UX | show/hide toggle OK, live validation disables Save until valid + red hint on bad name — verified + smoke PASS | 80f29c7 | ✅ |
| 8 | (i) test suite | 7/7 node --test pass: home/config/headers/SEO/404/contact/admin — no regression + smoke PASS | ba29b47 | ✅ |
| 9 | (h) design crit | shorter mobile hero (content surfaced), lighter mobile shadow, copy neutralized; 7/7 tests + smoke PASS | f3aa79c | ✅ |
**ROUND 1 COMPLETE (9/9).** Flag for Steve: services copy is now GENERIC because Robert's actual business is unknown — tell me what Robert does and I'll tailor it.
## ROUND 2 — DTD-committed polish order (panel: Codex+Qwen+Claude; verdict correctness-first, dissent: Qwen wanted a11y #1)
10. [x] (7) Server-side robustness — try/catch around file writes + graceful 500s (protects booking/contact data)
11. [x] (1) A11y — skip-to-content link + prefers-reduced-motion (disable hover transforms/transitions)
12. [x] (5) Contact form ARIA live-region (announce success/error to screen readers)
13. [x] (3) Static-asset cache-control + ETag (perf)
14. [x] (2) JSON-LD structured data (Person/booking action) for SEO
15. [x] (4) PWA-lite — web manifest + apple-touch-icon PNG fallback
16. [x] (6) Booking-embed loading skeleton + better fallback timing
17. [~] (8) Trim duplicate nginx/app headers (prod nginx edit)
| 10 | (7) server robustness | try/catch on writes (graceful 500), global JSON error handler, process guards; 8/8 tests + smoke PASS | 4b3c114 | ✅ |
| 11 | (1) a11y skip+motion | skip-link first in tab order, reveals on focus, jumps to main; reduced-motion honored; 8/8 + smoke PASS | 2b5ea41 | ✅ |
| 12 | (5) contact ARIA live | formMsg+admin msg role=status aria-live=polite; submit announces; 0 JS errs; 8/8 + smoke PASS | b3a76e0 | ✅ |
| 13 | (3) cache + ETag | images max-age=86400, html/css/js no-cache; ETag→304 verified local+prod; 8/8 + smoke PASS | 65be242 | ✅ |
| 14 | (2) JSON-LD | Person + ScheduleAction→booking URL, valid JSON, 0 CSP errors, +validity test (9/9) + smoke PASS | 19f4d34 | ✅ |
| 15 | (4) PWA-lite | manifest (200 application/manifest+json) + 180/192/512 icons + apple-touch-icon, links present, 0 CSP errs; 9/9 + smoke PASS | ab5c2bb | ✅ |
| 16 | (6) embed skeleton | skeleton + MutationObserver iframe-detect + 7s timeout fallback; settles (no perpetual spinner), 0 JS errs; 9/9 + smoke PASS | 6e8cd06 | ✅ |
| 17 | (8) trim nginx dupes | DEFERRED — gated (shared prod nginx, classifier blocked autonomous edit). App keeps headers (tested); nginx trim queued for Steve. | — | ⏸ gated |
**ROUND 2: 7/8 shipped, 1 (#17) DEFERRED to Steve (gated shared-infra).**
## ROUND 3 — DTD-committed polish order (Codex+Claude agree, correctness-first; Qwen timed out)
18. [x] (1) Real cross-browser verify on WebKit + Firefox (install playwright browsers or Browserbase) — closes the round-1 engine gap
19. [x] (2) Image lazy-loading + explicit width/height attrs (CLS / layout-shift prevention)
20. [x] (8) Lighthouse-style self-audit + quick-win fixes
21. [x] (3) :focus-visible keyboard focus-ring styling across interactive elements
22. [x] (5) Graceful 500 error page wired to the global error handler
23. [x] (6) Footer privacy/no-tracking note (site sets no cookies/analytics)
24. [x] (7) Content/microcopy polish pass
25. [x] (4) Print stylesheet
| 18 | (1) WebKit+FF verify | FOUND+FIXED: embed loader returns text/html→uncaught SyntaxError; switched to iframe /book?embed=1 + escape link; 0 syntax errs all 3 engines; 9/9 + smoke PASS | dc71cfa | ✅ |
| 19 | (2) CLS/lazy-load | 0 img tags (hero=CSS bg, iframe already lazy); measured CLS 0.017→0.000 desktop+mobile via static heroSub; 9/9 + smoke PASS | ae066fb | ✅ |
| 20 | (8) Lighthouse audit | real lh 12.8.2: P100/A96→100/BP100/SEO100; fixed contact-dt contrast (3.28→5.63:1) + preconnect; 9/9 + smoke PASS | 9411ab2 | ✅ |
| 21 | (3) focus-visible | two-layer keyboard ring (yellow outline + ink halo) visible on dark+paper; main ringless; 9/9 + smoke PASS | 3014445 | ✅ |
| 22 | (5) 500 page | global handler serves styled 500.html for browser GETs (404-parity), JSON for API; 9/9 + smoke PASS | b4b22f4 | ✅ |
| 23 | (6) privacy note | "No cookies. No tracking. No analytics." footer — verified 0 set-cookie + 0 tracking refs before claiming; 9/9 + smoke PASS | 52b5071 | ✅ |
| 24 | (7) microcopy | unified first-person singular voice (Talk to me / I'll be in touch / my end); 9/9 + smoke PASS | (prev) | ✅ |
| 25 | (4) print css | black-on-white, hide interactive-only, booking link shows URL; verified print media; 9/9 + smoke PASS | 693c574 | ✅ |
**ROUND 3 COMPLETE (8/8).** Site at perfect Lighthouse 100/100/100/100, CLS 0, cross-browser clean, 9/9 tests. Loop PAUSED — DNS is the one real action.
**BUSINESS IDENTIFIED (Steve): Robert is a BARBER.** Re-themed: BOOK A CUT hero + barber-pole SVG, Cut/Fade/Beard&Shave services, HairSalon JSON-LD, barber OG card. Lighthouse held 100s, 9/9 tests, deployed.