Build log

The build log.

Every change to this site, pulled straight out of the repository. Nobody writes this page — it is generated from the commit history, so it is exactly as current as the work is.

205 entries · first · most recent

August 2026 15

  1. /pricing, a real quote form, /work with numbers — and the case studies stop being hand-typed db3a2bc4
  2. Service-page FAQs, /agents, per-page OG cards — and 2.19 was already fixed twice 4d22f80a
  3. Phase 0 final five: the real price, honest metro names, and three false claims gone ce3de8a3
  4. Commit the audit, roadmap, session record and the B-G prompt specs ba467a33
  5. Case-study city links, 1200x630 OG cards, homepage entity signals, IndexNow --sitemap-diff 6c818b2d
  6. City titles and H1s: one deterministic shape for all 197 fb7c46dc
  7. Speculation Rules — with the analytics beacon guarded first 3dc45152
  8. IndexNow: the published root key is the source of truth; a second can't be minted c90a09fd
  9. robots Content-Signal, max-image-preview, /sitemap.xml redirect, preconnects c0b889d4
  10. /work gets an ItemList derived from facts.PAGES; case studies get identity and an image 564b03ba
  11. /thank-you: conversion destination + fetch-intercept on /quote (COPY IS A STUB) 3cfce2d9
  12. Homepage carousel points at the case studies; publish the out-of-scope rate 011592d7
  13. Footer link graph: Blog + About in the partial, /areas/remote/ and /maintenance-terms everywhere 6362a211
  14. Head/meta parity + advertise the 23 markdown twins with rel="alternate" 27f8173b
  15. Register sitemap-blog.xml as a child of the sitemap index 88fd2237

July 2026 157

  1. /maintenance-terms joins the core sitemap 60123358
  2. #org is LocalBusiness-eligible everywhere: @type ["Organization","ProfessionalService"] b671c4e9
  3. Tests: flatten a list @type instead of crashing on it d7c0b11b
  4. ai-crawler-log.md: logging is live, not dormant 246f4678
  5. Make the weekly monitor's green light mean something 086120d7
  6. Delete netlify.toml — dead config for a host this site does not use 46ab8614
  7. Asset versioning is markup-only; JSON-LD blocks ship byte-identical to source db5b55db
  8. search_index generated_at is the data's commit date, not the wall clock e6df2f7f
  9. Per-product WebPage dates + a --check gate that catches a stale dateModified 2c6aa984
  10. Run the Rule 9 uniqueness gate before the cache write; stop fabricating provenance bdf9935a
  11. Rule 13 measures the page under test; correct the SCAFFOLD_VARIANT_SHARE note d92cc987
  12. Trailing slash, offutt-afb meta, ProfessionalService descriptions; jsonld_soft -> fail a73e6da0
  13. Stage C §22: validate_pages can finally be pointed at the published tree 78c77d4b
  14. Stage C §21: referenced images FAIL; JSON-LD soft warnings stay WARN 1e7b9f61
  15. Stage C §20: page weight ceiling — FAIL, and nothing is close aed6b081
  16. Stage C §19: duplicate @id with divergent bodies — FAIL 456c8a95
  17. Stage C §18: internal link resolution — FAIL, and the 11 "broken links" are false positives 4e92150b
  18. Stage C §16: head completeness + URL form — both FAIL bda58f3d
  19. Stage C §15: sitemap <-> disk reconciliation — warn b3b91f34
  20. Stage C §17: the price / page-count assertion — the guard for Phase 0 c5055f78
  21. Stage C §14: scripts/guards.py — the comparator harness, all guards stubbed at warn a4cef3f2
  22. Stage A2: one Organization, one Person, one WebSite, one service catalog 5cffc70a
  23. Stage B: one page registry — facts.PAGES — disarms the sitemap trap 1791cd51
  24. Stage A1: scripts/facts.py — one fact table, byte-neutral 13223b25
  25. DEPLOY-CHECKLIST: smoke test that actually proves the Functions layer is alive 9e7af599
  26. Security quick wins (PROMPT-C §1-§12) 51df53c0
  27. Fix four defects from the corrected PROMPT-B spec, plus overflow 6d951bb1
  28. CSS + accessibility pass (PROMPT-B): no-JS fallback, contrast, focus, headings 55aa95ff
  29. Fix published facts, publish the NAP phone, de-hardcode the year 113d40f4
  30. Blog: publish "Why Isn't My Business Showing Up on Google Maps?" 606e3e44
  31. Areas: strengthen the Pleasant Hill MO angle (source only, nothing published) c4351785
  32. Areas (voice v5): per-city angle directives; publish Newton IA + Gretna NE (196/197) 8f759aa9
  33. Areas (voice v5): publish Merriam KS + Harrisonville MO (194/197) 64bfb30c
  34. Areas (voice v5): publish 7 forced-regen holds (192/197) 4c6ac86b
  35. Areas (voice v5): publish 25 first-person cities (185/197) 776e785b
  36. Blog: register the 2 new posts in blog_posts.py (fix drift guard) 75b0ea0c
  37. Areas (voice v5): publish 15 first-person cities (160/197) 60a3ead1
  38. Add 2 blog posts (Wix vs custom, ChatGPT recommendations) + blog UI/UX refresh bad28076
  39. Add Many Parts, One Body case study; feature on homepage 957b5241
  40. Areas (voice v5): publish 26 first-person cities (145/197) ef7d6566
  41. Areas (voice v5): publish 12 first-person cities (119/197) b8f1104b
  42. Areas (voice v5): publish 11 first-person cities (107/197) 236ff851
  43. Areas (voice v5): publish 16 first-person cities (96/197) 2f252bf9
  44. Areas (voice v5): publish 14 first-person cities (80/197) c0bfb8cf
  45. analytics: add LiveDash cookieless snippet sitewide + tag quote-form submit f83ebbb2
  46. Areas hub: search-first "do I cover you?" redesign d770dab3
  47. Areas (metro tier): honest city counts + singular/plural grammar 5186500a
  48. Blog: publish "Do I need a website if I have a Facebook page?" fcb527b5
  49. Areas: publish v5 first-person voice for 7 cities (66/197) 011a375a
  50. AI-crawler verify: drop Google (unmapped ranges), fix redirect-caching 65d6cbd4
  51. AI-crawler log: probe classification + verified-bot IP check 43f56313
  52. Areas: revert 3 near-duplicate v5 cities (corpus-health gate) e97f7087
  53. Areas: publish v5 first-person voice for 16 cities (62/197) 6da1f9fa
  54. Areas: ship /areas/remote/ national remote landing page + integration 8dfe94bb
  55. Schema: add verified GBP entity (kgmid) to Organization sameAs sitewide 15d6550b
  56. Nav: fix blog hamburger overlay + cramped blog header nav 389c0c6d
  57. Case studies: dark page treatment so the .cs palette renders correctly c7bc1ddc
  58. Directory pack: canonical source for agency-directory listings 2801b811
  59. Case studies: ship 4 /work/<slug>/ pages + overhaul /work ea7b182e
  60. Voice: publish 14 v5 first-person cities (batch 2026-07-08) fea5674e
  61. Voice tooling: v5 batch runner + Gemini client pacing/session dead-marking 673e9779
  62. Nav unification (phase 2): Blog link + id=hdr sitewide; canonical 404; .scrolled parity 81ab207c
  63. Content: "The State of Kansas City Small-Business Websites (2026)" — the study 466ccc99
  64. Study (roadmap #2) session 3: PSI measurement + aggregation 050108f9
  65. Study (roadmap #2) session 2: reachability pre-filter + seeded sampling 8fe008e3
  66. Study (roadmap #2) session 1: reproducible KC-website candidate collection bac3a128
  67. Content: "I Made My Website Agent-Ready" — the agent-ready build writeup 380cd326
  68. WebMCP veneer: site-wide OT token + 3 read tools + declarative quote form 61ec94e3
  69. Agent layer: service-area + process endpoints + discovery manifest f8997c50
  70. Agent layer: unified services catalog -> /agent/services.json (drift-gated) 3f03d372
  71. Activate AI-crawler logging: enable AI_CRAWLER Analytics Engine binding d75cd67b
  72. Unblock deploy: ship AI-crawler middleware dormant until Analytics Engine is enabled 91ff8b81
  73. Measure AI crawler traffic: edge middleware -> Analytics Engine (roadmap #7) 932142a4
  74. Schema: homepage Organization hasOfferCatalog linking the 4 service @ids 10d18f18
  75. Test: make the no-stale guard migration-aware (Rule 34 during v5 rollout) 69fd6145
  76. Fix deploy: cache-authoritative render (render_only) + re-sync area tree 0fc72f50
  77. AEO: markdown twins + llms.txt + llms-full.txt (build-time, drift-proof) 83cf057b
  78. Content: deepen KC website-cost guide with sourced DIY + WordPress breakdowns 2c2d2625
  79. Content: add extractable answer capsules to service + pricing pages 7f0bd3bf
  80. Voice: publish 4 cleanup cities to live /areas/ (first-person voice) 5464a0eb
  81. Voice: casual section headings + stable-anchor render (build_areas.py) fea131f8
  82. Voice: publish 28 judged v5 cities to live /areas/ (first-person voice) 13829dd4
  83. Voice: v5 batch 2026-07-07 (run 2) — 10 more cities in first-person voice 08aa3b31
  84. Voice: v5 batch 2026-07-07 — 10 cities regenerated in first-person voice f09b21a3
  85. Voice: backfill 13 new-voice cities to v5 (no regeneration) dee3479d
  86. Voice: PROMPT_VERSION 4->5 + anti-repetition prompt rule (voice campaign) 00573537
  87. Voice: commit first-person Adam scaffold voice (the prompt that generated the 13 done cities) 01e9467d
  88. Perf: repoint visible logos to emblem-sm.webp site-wide (~47 KiB/page saved) 708fecec
  89. Perf: defer Google Analytics off the critical path (site-wide) 922a58e7
  90. A11y: fix four homepage carousel defects (mobile 86 -> 100) 6fcc3e63
  91. Perf: right-size homepage images (~166 KiB mobile transfer saved) 09cedc52
  92. Perf: metric-adjusted font fallbacks to stop font-swap LCP re-trigger d86146cb
  93. Perf: fix mobile LCP render delay — hero warm-turn paragraph paints at FCP b0fa81bb
  94. Blog: add speed post + complete three-way cost/overcharging/speed cluster 96bef517
  95. Blog: add flagship cost post + wire bidirectional cost<->overcharging cluster link 25313169
  96. Blog: add first real post (KC web-developer overcharging), retire placeholder 46d69457
  97. Blog part 2/2: nav link, sitemap-blog.xml, RSS feed, CI guard, per-post OG 397cb806
  98. Blog byline: dedicated square avatar (img/adam-avatar.webp?v=2a62e6e9ff), face centred both axes 5cc6e830
  99. Nudge blog byline avatar crop 20% -> 30% (evenly centre the face) 08fadcf3
  100. Fix blog byline avatar crop: bias object-position up (source is a portrait) 0713cb31
  101. Add blog render engine (part 1/2): template + build_blog.py, noindexed preview 10c8b4ec
  102. Fix social/iMessage preview: dark 1200x630 OG banner across 15 marketing pages 93a1be4f
  103. docs: deploy-stamp #2 to force Pages rebuild for corrected R2_ACCOUNT_ID 7a629aac
  104. Fix /send CSP: fold blob: + R2 origin into the global /* policy 8f87ce52
  105. docs: deploy-stamp to force Pages rebuild for /send env vars 4e4eafe7
  106. Fix R2 CORS command in runbook: cors set --file (R2 rules JSON), not put --rules 4ad0ca8e
  107. Rename /upload -> /send and bake the URL key in (bare link works, bots gated) 789a8283
  108. Port /upload backend from standalone Worker to same-origin Pages Functions 81367007
  109. Add private, noindex /upload photo tool + standalone R2 upload Worker 4283c5ce
  110. Homepage close CTA: "reasons"->"excuses", "results"->"solutions" a955e092
  111. Remove Process + Why 2k from the footer "Company" column, sitewide cbcffffb
  112. Remove Process + Why 2k from the header nav (desktop + overlay), sitewide dce23965
  113. Fix cropped carousel screenshots: reshape image slot 16:11 -> 16:9 315d1542
  114. Hero strike: slow the sequence ~3s -> ~4s (stagger 600ms -> 800ms beat) 8efe88ad
  115. Hero excuses: shorter one-line copy + slow ~3s one-by-one strike fb7a5767
  116. Fix hero strikethrough on wrapped excuses: use real line-through 6a44a377
  117. Restyle hello-world easter egg to the site's dark theme (scoped to this page) 97d4905f
  118. Add 'self' to CSP frame-src so the hello-world game iframe can load b59a8f72
  119. Fix invisible .reveal content: restore reveal observer in js/nav.js?v=09c6dad7d1 957efc00
  120. Propagate overlay menu sitewide + retire legacy mobile menu ea95f843
  121. Add full-screen overlay mobile menu (js/nav.js?v=09c6dad7d1) — proof on 2 pages 62bd18ab
  122. Tokenize the dark-strip accent purple (--purple-on-dark); no visual change f7fb43ab
  123. Promote Strikethrough homepage to live index.html (indexable) 6f9a706b
  124. Reorder index-v2 work carousel: Blindfold Tattoo first 43c7929c
  125. Fix index-v2: two-line strikethrough + receipts overflow (mobile) 3ad0570f
  126. Fix index-v2 carousel: kill page-level horizontal scroll + centered peek 73185a44
  127. Add noindex homepage redesign preview: index-v2.html ("The Strikethrough") 0e93e30b
  128. Fix stale checkout.js comment; retire obsolete test_phase8 a9850362
  129. Promote market-anchor estimator + sticky quote CTA to live city pages (197) b9ccce2a
  130. Add noindex market-rate estimator v2 preview (one city, live template untouched) e0e278db
  131. Fix the-nerdy-friend JSON-LD dates: restore true datePublished 2026-06-25 c6a2a24d
  132. Promote the-nerdy-friend to the multi-step application; retire v2 preview 6793ec7b
  133. Add the-nerdy-friend-v2 (noindex): accessible multi-step signup preview e5699635
  134. Fix iOS focus-zoom: bump quote + nerdy-friend form inputs 15px -> 16px f5414f2d
  135. Prune dead subscription-tier embedded-checkout scaffolding c44ad7bb
  136. Promote v2 signup pages to canonical LIVE URLs; retire v1 + previews 3bf13980
  137. plans.css: stop desktop clipping of the "Most popular" badge overhang 3424f144
  138. Services v2 (noindex previews): single-source, build-time static pricing 8d208087
  139. Services: wire the six retainer tiers to their Stripe recurring links 4bd5cbed
  140. Footer: add self-serve "Become a Nerdy Friend – $25/mo" Stripe signup link 5bd76c30
  141. Portfolio: normalize all four cards to uniform 16:9 (1200x675), heroes fill edge-to-edge 15509bc3
  142. Home/Work: add Blindfold Tattoos as lead portfolio card + refresh the three existing card screenshots 719467bc
  143. Nav: mobile Services taps to open dropdown (not navigate) + 'All services' link preserves /services access; revert loud chevron to subtle indicator b3435f03
  144. Nav: make Services dropdown indicator obviously clickable — bigger accent chevron + rotate-on-open + tap affordance, mobile + desktop, both stylesheets aada3466
  145. Fix mobile nav: center Services dropdown to match other items (both stylesheets) + header overlap + restore area-page arrow 0a4a67e3
  146. Audit lows: F10 (combobox a11y), F12 (estimator $750 floor), F13 (metro og:image — flagged), F11 (checkout hardening — applied) + sitemap lastmod trueup a5d3f3b8
  147. Sitemap: bump homepage lastmod to 2026-07-02 (honest — index.html #website edited in F7) 5a494a60
  148. Audit F6 (301! → 301 for CF Pages redirects) + F7 (SearchAction: wired ?q into hub search) c952b715
  149. F5: emit self-contained Org/Person nodes on service pages so provider @id resolves (was dangling cross-page) 4785fe32
  150. Durable asset versioning: auto content-hash ?v= on CSS/JS/images at build (kills manual ?v= footgun + stale-cache breakage; covers area pages + srcset) 833d82cc
  151. Homepage marquee: optically normalize logo sizes within tiles (even visual weight, per-logo tuning, box size unchanged) 2a7af218
  152. Homepage marquee: add visible client names to tiles + remove "KC" from eyebrow 55663af9
  153. Fix homepage logo marquee break: cache-bust styles.css (was stale immutable CSS) b781d383
  154. homepage: flowing CSS logo marquee (5 clients, normalized, reduced-motion-safe, INP-clean) 15791641
  155. M7: hub coverage number → 197 provable paged-cities (data-derived; reverts 363) 0dc95b32
  156. Fable-audit F3 (extensionless URL standardization) + F8-followup (render hub FAQ visibly, matches schema) + M7 (hub coverage wording → communities, data-derived) b3011bb4
  157. Fable-audit F8+F2: derive hub state list from data (5→7 states, kills FAQ contradiction) + honest per-URL lastmod in the sitemap generator (no more uniform-today clobber) dd2e516d

June 2026 33

  1. SEO/measurement: GA4 AI-referral capture script (ai_referral event by source) — item 20 decfb991
  2. SEO/CWV: self-host Leaflet (drop unpkg, tighten CSP) + INP audit (items 7 + M2) d0883de1
  3. SEO: image pass — area-map responsive srcset (M1 mobile-LCP) + footer emblem lazy/async (item 13) 6913cf53
  4. SEO: semantic-HTML + heading-ID structural fixes for passage extractability (items 18+19) 0b440941
  5. Add build-time JSON-LD schema validation guard (hard-fail on broken schema, warn on soft gaps) — item 21 aa4bba6b
  6. SEO: sitemap honest lastmod cleanup — index + child dates reflect real last-change (item 3) 66f2e01e
  7. SEO: link services hub from homepage #services section (close #8 internal-linking gap) dfe46522
  8. H5: CSP allowlist re-verified complete → flipped to enforcing 185ef14a
  9. SEO: freshness dates (real, git-sourced) + safe audit cleanup (sitemap gaps, logo compress, casing, contrast, img attrs, docstring) 5a1065f4
  10. SEO/AEO: Service + Offer schema with real starting prices (web $750/client-owned, SEO $250, custom=quote) + areaServed/hasOfferCatalog — items 9+14 89709706
  11. SEO/AEO: align hand-page BreadcrumbList schema names to visible breadcrumb labels (quote/pay/privacy/accessibility) c4287b40
  12. Add The Nerdy Friend as server-enforced fixed $250 one-time add-on (pay.html + checkout function + client labels) 1df07d35
  13. AEO/GEO: robots.txt — explicit allow for AI citation crawlers (GPTBot/ClaudeBot/PerplexityBot/Google-Extended etc.), 2026 best practice db3839d2
  14. Add Cloudflare _headers: HSTS + security headers (enforcing) + CSP (Report-Only first) — H5 39e93b33
  15. Converge hand pages to templated standard: canonical + OG/Twitter + skip-link/<main> + meta-desc + hamburger aria (H3/H4/H7/M10/M11/M12) 924503c8
  16. Re-sync stale area tree to current source (hub #website @id + structural layer); guard against future area drift (H1) 4dcd546d
  17. Add build-time guard: fail on unrendered Jinja tokens in dist/ + wire validate_pages into CI (H2 root-cause fix) 6c1510d9
  18. Fix live unrendered template tokens: ToS page (maintenance-terms) + care-hosting portal link + 2k casing 79310c8b
  19. Fix desktop audit: metro city-list multi-column, 'Metro Area area' typo, homepage About teaser portrait de5a3a8b
  20. Fix mobile audit issues: /about header, cookie-banner overlap, portrait+hero object-fit, eyebrow contrast, hamburger aria-expanded 7dc06eaa
  21. Add GA4 conversion events (generate_lead, begin_checkout) + form autocomplete tokens af147646
  22. Add connected Organization + Person entity graph (JSON-LD, sameAs) 7c52c964
  23. WCAG 2.2 AA audit + remediation; add accessibility statement a709e37c
  24. Sharpen header/footer emblem — re-key from hi-res source at exact 1.61:1 ratio 36747662
  25. Add GA4 analytics (G-330JW0TV89), cookie-consent notice, update privacy disclosure f79f114b
  26. Point Stripe return_url to live 2kwebdev.com domain 6cde2424
  27. Add /quote page + form, wire Get-a-free-quote CTA, fix maintenance-terms email 46344068
  28. Switch contact email to working adam@2kwebdev.com e11edabd
  29. Switch Stripe checkout to live keys (pk_live + live Price IDs) e0f0aa7d
  30. Add GitHub Actions workflow for Cloudflare Pages auto-deploy 3bfc636b
  31. Sync repo with live site: Stripe embedded_page fix, in-modal success + /pay/success 5af14e61
  32. Add wrangler.toml for Cloudflare Pages deploy bb9dff25
  33. Initial commit — 2k Web Developments site + Stripe checkout scaffolding ef7a764d

Subject lines only, and only real changes — merges and routine bot commits are filtered out. The full history, diffs and all, is public.

Still shipping. Room for one more.

If the list above is still moving, so am I. Tell me what your business needs and you’ll get a real number and a real timeline.