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
-
/pricing, a real quote form, /work with numbers — and the case studies stop being hand-typed
db3a2bc4 -
Service-page FAQs, /agents, per-page OG cards — and 2.19 was already fixed twice
4d22f80a -
Phase 0 final five: the real price, honest metro names, and three false claims gone
ce3de8a3 -
Commit the audit, roadmap, session record and the B-G prompt specs
ba467a33 -
Case-study city links, 1200x630 OG cards, homepage entity signals, IndexNow --sitemap-diff
6c818b2d -
City titles and H1s: one deterministic shape for all 197
fb7c46dc -
Speculation Rules — with the analytics beacon guarded first
3dc45152 -
IndexNow: the published root key is the source of truth; a second can't be minted
c90a09fd -
robots Content-Signal, max-image-preview, /sitemap.xml redirect, preconnects
c0b889d4 -
/work gets an ItemList derived from facts.PAGES; case studies get identity and an image
564b03ba -
/thank-you: conversion destination + fetch-intercept on /quote (COPY IS A STUB)
3cfce2d9 -
Homepage carousel points at the case studies; publish the out-of-scope rate
011592d7 -
Footer link graph: Blog + About in the partial, /areas/remote/ and /maintenance-terms everywhere
6362a211 -
Head/meta parity + advertise the 23 markdown twins with rel="alternate"
27f8173b -
Register sitemap-blog.xml as a child of the sitemap index
88fd2237
July 2026 157
-
/maintenance-terms joins the core sitemap
60123358 -
#org is LocalBusiness-eligible everywhere: @type ["Organization","ProfessionalService"]
b671c4e9 -
Tests: flatten a list @type instead of crashing on it
d7c0b11b -
ai-crawler-log.md: logging is live, not dormant
246f4678 -
Make the weekly monitor's green light mean something
086120d7 -
Delete netlify.toml — dead config for a host this site does not use
46ab8614 -
Asset versioning is markup-only; JSON-LD blocks ship byte-identical to source
db5b55db -
search_index generated_at is the data's commit date, not the wall clock
e6df2f7f -
Per-product WebPage dates + a --check gate that catches a stale dateModified
2c6aa984 -
Run the Rule 9 uniqueness gate before the cache write; stop fabricating provenance
bdf9935a -
Rule 13 measures the page under test; correct the SCAFFOLD_VARIANT_SHARE note
d92cc987 -
Trailing slash, offutt-afb meta, ProfessionalService descriptions; jsonld_soft -> fail
a73e6da0 -
Stage C §22: validate_pages can finally be pointed at the published tree
78c77d4b -
Stage C §21: referenced images FAIL; JSON-LD soft warnings stay WARN
1e7b9f61 -
Stage C §20: page weight ceiling — FAIL, and nothing is close
aed6b081 -
Stage C §19: duplicate @id with divergent bodies — FAIL
456c8a95 -
Stage C §18: internal link resolution — FAIL, and the 11 "broken links" are false positives
4e92150b -
Stage C §16: head completeness + URL form — both FAIL
bda58f3d -
Stage C §15: sitemap <-> disk reconciliation — warn
b3b91f34 -
Stage C §17: the price / page-count assertion — the guard for Phase 0
c5055f78 -
Stage C §14: scripts/guards.py — the comparator harness, all guards stubbed at warn
a4cef3f2 -
Stage A2: one Organization, one Person, one WebSite, one service catalog
5cffc70a -
Stage B: one page registry — facts.PAGES — disarms the sitemap trap
1791cd51 -
Stage A1: scripts/facts.py — one fact table, byte-neutral
13223b25 -
DEPLOY-CHECKLIST: smoke test that actually proves the Functions layer is alive
9e7af599 -
Security quick wins (PROMPT-C §1-§12)
51df53c0 -
Fix four defects from the corrected PROMPT-B spec, plus overflow
6d951bb1 -
CSS + accessibility pass (PROMPT-B): no-JS fallback, contrast, focus, headings
55aa95ff -
Fix published facts, publish the NAP phone, de-hardcode the year
113d40f4 -
Blog: publish "Why Isn't My Business Showing Up on Google Maps?"
606e3e44 -
Areas: strengthen the Pleasant Hill MO angle (source only, nothing published)
c4351785 -
Areas (voice v5): per-city angle directives; publish Newton IA + Gretna NE (196/197)
8f759aa9 -
Areas (voice v5): publish Merriam KS + Harrisonville MO (194/197)
64bfb30c -
Areas (voice v5): publish 7 forced-regen holds (192/197)
4c6ac86b -
Areas (voice v5): publish 25 first-person cities (185/197)
776e785b -
Blog: register the 2 new posts in blog_posts.py (fix drift guard)
75b0ea0c -
Areas (voice v5): publish 15 first-person cities (160/197)
60a3ead1 -
Add 2 blog posts (Wix vs custom, ChatGPT recommendations) + blog UI/UX refresh
bad28076 -
Add Many Parts, One Body case study; feature on homepage
957b5241 -
Areas (voice v5): publish 26 first-person cities (145/197)
ef7d6566 -
Areas (voice v5): publish 12 first-person cities (119/197)
b8f1104b -
Areas (voice v5): publish 11 first-person cities (107/197)
236ff851 -
Areas (voice v5): publish 16 first-person cities (96/197)
2f252bf9 -
Areas (voice v5): publish 14 first-person cities (80/197)
c0bfb8cf -
analytics: add LiveDash cookieless snippet sitewide + tag quote-form submit
f83ebbb2 -
Areas hub: search-first "do I cover you?" redesign
d770dab3 -
Areas (metro tier): honest city counts + singular/plural grammar
5186500a -
Blog: publish "Do I need a website if I have a Facebook page?"
fcb527b5 -
Areas: publish v5 first-person voice for 7 cities (66/197)
011a375a -
AI-crawler verify: drop Google (unmapped ranges), fix redirect-caching
65d6cbd4 -
AI-crawler log: probe classification + verified-bot IP check
43f56313 -
Areas: revert 3 near-duplicate v5 cities (corpus-health gate)
e97f7087 -
Areas: publish v5 first-person voice for 16 cities (62/197)
6da1f9fa -
Areas: ship /areas/remote/ national remote landing page + integration
8dfe94bb -
Schema: add verified GBP entity (kgmid) to Organization sameAs sitewide
15d6550b -
Nav: fix blog hamburger overlay + cramped blog header nav
389c0c6d -
Case studies: dark page treatment so the .cs palette renders correctly
c7bc1ddc -
Directory pack: canonical source for agency-directory listings
2801b811 -
Case studies: ship 4 /work/<slug>/ pages + overhaul /work
ea7b182e -
Voice: publish 14 v5 first-person cities (batch 2026-07-08)
fea5674e -
Voice tooling: v5 batch runner + Gemini client pacing/session dead-marking
673e9779 -
Nav unification (phase 2): Blog link + id=hdr sitewide; canonical 404; .scrolled parity
81ab207c -
Content: "The State of Kansas City Small-Business Websites (2026)" — the study
466ccc99 -
Study (roadmap #2) session 3: PSI measurement + aggregation
050108f9 -
Study (roadmap #2) session 2: reachability pre-filter + seeded sampling
8fe008e3 -
Study (roadmap #2) session 1: reproducible KC-website candidate collection
bac3a128 -
Content: "I Made My Website Agent-Ready" — the agent-ready build writeup
380cd326 -
WebMCP veneer: site-wide OT token + 3 read tools + declarative quote form
61ec94e3 -
Agent layer: service-area + process endpoints + discovery manifest
f8997c50 -
Agent layer: unified services catalog -> /agent/services.json (drift-gated)
3f03d372 -
Activate AI-crawler logging: enable AI_CRAWLER Analytics Engine binding
d75cd67b -
Unblock deploy: ship AI-crawler middleware dormant until Analytics Engine is enabled
91ff8b81 -
Measure AI crawler traffic: edge middleware -> Analytics Engine (roadmap #7)
932142a4 -
Schema: homepage Organization hasOfferCatalog linking the 4 service @ids
10d18f18 -
Test: make the no-stale guard migration-aware (Rule 34 during v5 rollout)
69fd6145 -
Fix deploy: cache-authoritative render (render_only) + re-sync area tree
0fc72f50 -
AEO: markdown twins + llms.txt + llms-full.txt (build-time, drift-proof)
83cf057b -
Content: deepen KC website-cost guide with sourced DIY + WordPress breakdowns
2c2d2625 -
Content: add extractable answer capsules to service + pricing pages
7f0bd3bf -
Voice: publish 4 cleanup cities to live /areas/ (first-person voice)
5464a0eb -
Voice: casual section headings + stable-anchor render (build_areas.py)
fea131f8 -
Voice: publish 28 judged v5 cities to live /areas/ (first-person voice)
13829dd4 -
Voice: v5 batch 2026-07-07 (run 2) — 10 more cities in first-person voice
08aa3b31 -
Voice: v5 batch 2026-07-07 — 10 cities regenerated in first-person voice
f09b21a3 -
Voice: backfill 13 new-voice cities to v5 (no regeneration)
dee3479d -
Voice: PROMPT_VERSION 4->5 + anti-repetition prompt rule (voice campaign)
00573537 -
Voice: commit first-person Adam scaffold voice (the prompt that generated the 13 done cities)
01e9467d -
Perf: repoint visible logos to emblem-sm.webp site-wide (~47 KiB/page saved)
708fecec -
Perf: defer Google Analytics off the critical path (site-wide)
922a58e7 -
A11y: fix four homepage carousel defects (mobile 86 -> 100)
6fcc3e63 -
Perf: right-size homepage images (~166 KiB mobile transfer saved)
09cedc52 -
Perf: metric-adjusted font fallbacks to stop font-swap LCP re-trigger
d86146cb -
Perf: fix mobile LCP render delay — hero warm-turn paragraph paints at FCP
b0fa81bb -
Blog: add speed post + complete three-way cost/overcharging/speed cluster
96bef517 -
Blog: add flagship cost post + wire bidirectional cost<->overcharging cluster link
25313169 -
Blog: add first real post (KC web-developer overcharging), retire placeholder
46d69457 -
Blog part 2/2: nav link, sitemap-blog.xml, RSS feed, CI guard, per-post OG
397cb806 -
Blog byline: dedicated square avatar (img/adam-avatar.webp?v=2a62e6e9ff), face centred both axes
5cc6e830 -
Nudge blog byline avatar crop 20% -> 30% (evenly centre the face)
08fadcf3 -
Fix blog byline avatar crop: bias object-position up (source is a portrait)
0713cb31 -
Add blog render engine (part 1/2): template + build_blog.py, noindexed preview
10c8b4ec -
Fix social/iMessage preview: dark 1200x630 OG banner across 15 marketing pages
93a1be4f -
docs: deploy-stamp #2 to force Pages rebuild for corrected R2_ACCOUNT_ID
7a629aac -
Fix /send CSP: fold blob: + R2 origin into the global /* policy
8f87ce52 -
docs: deploy-stamp to force Pages rebuild for /send env vars
4e4eafe7 -
Fix R2 CORS command in runbook: cors set --file (R2 rules JSON), not put --rules
4ad0ca8e -
Rename /upload -> /send and bake the URL key in (bare link works, bots gated)
789a8283 -
Port /upload backend from standalone Worker to same-origin Pages Functions
81367007 -
Add private, noindex /upload photo tool + standalone R2 upload Worker
4283c5ce -
Homepage close CTA: "reasons"->"excuses", "results"->"solutions"
a955e092 -
Remove Process + Why 2k from the footer "Company" column, sitewide
cbcffffb -
Remove Process + Why 2k from the header nav (desktop + overlay), sitewide
dce23965 -
Fix cropped carousel screenshots: reshape image slot 16:11 -> 16:9
315d1542 -
Hero strike: slow the sequence ~3s -> ~4s (stagger 600ms -> 800ms beat)
8efe88ad -
Hero excuses: shorter one-line copy + slow ~3s one-by-one strike
fb7a5767 -
Fix hero strikethrough on wrapped excuses: use real line-through
6a44a377 -
Restyle hello-world easter egg to the site's dark theme (scoped to this page)
97d4905f -
Add 'self' to CSP frame-src so the hello-world game iframe can load
b59a8f72 -
Fix invisible .reveal content: restore reveal observer in js/nav.js?v=09c6dad7d1
957efc00 -
Propagate overlay menu sitewide + retire legacy mobile menu
ea95f843 -
Add full-screen overlay mobile menu (js/nav.js?v=09c6dad7d1) — proof on 2 pages
62bd18ab -
Tokenize the dark-strip accent purple (--purple-on-dark); no visual change
f7fb43ab -
Promote Strikethrough homepage to live index.html (indexable)
6f9a706b -
Reorder index-v2 work carousel: Blindfold Tattoo first
43c7929c -
Fix index-v2: two-line strikethrough + receipts overflow (mobile)
3ad0570f -
Fix index-v2 carousel: kill page-level horizontal scroll + centered peek
73185a44 -
Add noindex homepage redesign preview: index-v2.html ("The Strikethrough")
0e93e30b -
Fix stale checkout.js comment; retire obsolete test_phase8
a9850362 -
Promote market-anchor estimator + sticky quote CTA to live city pages (197)
b9ccce2a -
Add noindex market-rate estimator v2 preview (one city, live template untouched)
e0e278db -
Fix the-nerdy-friend JSON-LD dates: restore true datePublished 2026-06-25
c6a2a24d -
Promote the-nerdy-friend to the multi-step application; retire v2 preview
6793ec7b -
Add the-nerdy-friend-v2 (noindex): accessible multi-step signup preview
e5699635 -
Fix iOS focus-zoom: bump quote + nerdy-friend form inputs 15px -> 16px
f5414f2d -
Prune dead subscription-tier embedded-checkout scaffolding
c44ad7bb -
Promote v2 signup pages to canonical LIVE URLs; retire v1 + previews
3bf13980 -
plans.css: stop desktop clipping of the "Most popular" badge overhang
3424f144 -
Services v2 (noindex previews): single-source, build-time static pricing
8d208087 -
Services: wire the six retainer tiers to their Stripe recurring links
4bd5cbed -
Footer: add self-serve "Become a Nerdy Friend – $25/mo" Stripe signup link
5bd76c30 -
Portfolio: normalize all four cards to uniform 16:9 (1200x675), heroes fill edge-to-edge
15509bc3 -
Home/Work: add Blindfold Tattoos as lead portfolio card + refresh the three existing card screenshots
719467bc -
Nav: mobile Services taps to open dropdown (not navigate) + 'All services' link preserves /services access; revert loud chevron to subtle indicator
b3435f03 -
Nav: make Services dropdown indicator obviously clickable — bigger accent chevron + rotate-on-open + tap affordance, mobile + desktop, both stylesheets
aada3466 -
Fix mobile nav: center Services dropdown to match other items (both stylesheets) + header overlap + restore area-page arrow
0a4a67e3 -
Audit lows: F10 (combobox a11y), F12 (estimator $750 floor), F13 (metro og:image — flagged), F11 (checkout hardening — applied) + sitemap lastmod trueup
a5d3f3b8 -
Sitemap: bump homepage lastmod to 2026-07-02 (honest — index.html #website edited in F7)
5a494a60 -
Audit F6 (301! → 301 for CF Pages redirects) + F7 (SearchAction: wired ?q into hub search)
c952b715 -
F5: emit self-contained Org/Person nodes on service pages so provider @id resolves (was dangling cross-page)
4785fe32 -
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 -
Homepage marquee: optically normalize logo sizes within tiles (even visual weight, per-logo tuning, box size unchanged)
2a7af218 -
Homepage marquee: add visible client names to tiles + remove "KC" from eyebrow
55663af9 -
Fix homepage logo marquee break: cache-bust styles.css (was stale immutable CSS)
b781d383 -
homepage: flowing CSS logo marquee (5 clients, normalized, reduced-motion-safe, INP-clean)
15791641 -
M7: hub coverage number → 197 provable paged-cities (data-derived; reverts 363)
0dc95b32 -
Fable-audit F3 (extensionless URL standardization) + F8-followup (render hub FAQ visibly, matches schema) + M7 (hub coverage wording → communities, data-derived)
b3011bb4 -
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
-
SEO/measurement: GA4 AI-referral capture script (ai_referral event by source) — item 20
decfb991 -
SEO/CWV: self-host Leaflet (drop unpkg, tighten CSP) + INP audit (items 7 + M2)
d0883de1 -
SEO: image pass — area-map responsive srcset (M1 mobile-LCP) + footer emblem lazy/async (item 13)
6913cf53 -
SEO: semantic-HTML + heading-ID structural fixes for passage extractability (items 18+19)
0b440941 -
Add build-time JSON-LD schema validation guard (hard-fail on broken schema, warn on soft gaps) — item 21
aa4bba6b -
SEO: sitemap honest lastmod cleanup — index + child dates reflect real last-change (item 3)
66f2e01e -
SEO: link services hub from homepage #services section (close #8 internal-linking gap)
dfe46522 -
H5: CSP allowlist re-verified complete → flipped to enforcing
185ef14a -
SEO: freshness dates (real, git-sourced) + safe audit cleanup (sitemap gaps, logo compress, casing, contrast, img attrs, docstring)
5a1065f4 -
SEO/AEO: Service + Offer schema with real starting prices (web $750/client-owned, SEO $250, custom=quote) + areaServed/hasOfferCatalog — items 9+14
89709706 -
SEO/AEO: align hand-page BreadcrumbList schema names to visible breadcrumb labels (quote/pay/privacy/accessibility)
c4287b40 -
Add The Nerdy Friend as server-enforced fixed $250 one-time add-on (pay.html + checkout function + client labels)
1df07d35 -
AEO/GEO: robots.txt — explicit allow for AI citation crawlers (GPTBot/ClaudeBot/PerplexityBot/Google-Extended etc.), 2026 best practice
db3839d2 -
Add Cloudflare _headers: HSTS + security headers (enforcing) + CSP (Report-Only first) — H5
39e93b33 -
Converge hand pages to templated standard: canonical + OG/Twitter + skip-link/<main> + meta-desc + hamburger aria (H3/H4/H7/M10/M11/M12)
924503c8 -
Re-sync stale area tree to current source (hub #website @id + structural layer); guard against future area drift (H1)
4dcd546d -
Add build-time guard: fail on unrendered Jinja tokens in dist/ + wire validate_pages into CI (H2 root-cause fix)
6c1510d9 -
Fix live unrendered template tokens: ToS page (maintenance-terms) + care-hosting portal link + 2k casing
79310c8b -
Fix desktop audit: metro city-list multi-column, 'Metro Area area' typo, homepage About teaser portrait
de5a3a8b -
Fix mobile audit issues: /about header, cookie-banner overlap, portrait+hero object-fit, eyebrow contrast, hamburger aria-expanded
7dc06eaa -
Add GA4 conversion events (generate_lead, begin_checkout) + form autocomplete tokens
af147646 -
Add connected Organization + Person entity graph (JSON-LD, sameAs)
7c52c964 -
WCAG 2.2 AA audit + remediation; add accessibility statement
a709e37c -
Sharpen header/footer emblem — re-key from hi-res source at exact 1.61:1 ratio
36747662 -
Add GA4 analytics (G-330JW0TV89), cookie-consent notice, update privacy disclosure
f79f114b -
Point Stripe return_url to live 2kwebdev.com domain
6cde2424 -
Add /quote page + form, wire Get-a-free-quote CTA, fix maintenance-terms email
46344068 -
Switch contact email to working adam@2kwebdev.com
e11edabd -
Switch Stripe checkout to live keys (pk_live + live Price IDs)
e0f0aa7d -
Add GitHub Actions workflow for Cloudflare Pages auto-deploy
3bfc636b -
Sync repo with live site: Stripe embedded_page fix, in-modal success + /pay/success
5af14e61 -
Add wrangler.toml for Cloudflare Pages deploy
bb9dff25 -
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.