Rendered at build time from Search_Strategy.md in the repo — edit the source
file and rebuild to update this page.
The single live plan for SEO / AEO / UX on honey-doers.com. This file is state, not history — edited in place. Four sections: who we're up against and how each channel is doing, what to work on right now, what's still a hypothesis rather than a scheduled task, and the numbers that say whether any of it is working.
Current focus, 2026-08-19: I11 Phase 1 is closed, the tracked-query baseline is frozen, and E1 is enrolled at 5 treated / 7 control (Lakeville deliberately excluded). Do not read a verdict before 2026-10-14. Next up while that clock runs: E3, I5t, I11 Phase 3 tail cities. If you're here for an I11 Phase 3 session, go straight to LOCAL_PAGE_REMEDIATION.md — it's self-contained.
| File | Holds |
|---|---|
| LOCAL_PAGE_REMEDIATION.md | I11 — the active workstream. Self-contained: problem, standard, per-city queue, session protocol |
| REFRESH_BACKLOG.md | I6 — the refresh queue. Self-contained: tiering rules, ranked backlog, session protocol |
| COMPASS_EXTERIORS_MERGE.md | I12 — retiring compassexteriors.com into honey-doers.com. Phase 1 (3 service pages) + Phase 3's inbound redirect reversal shipped 2026-09-04; Phase 2 (blog triage, ~85 posts left) and Phase 3's outbound side next |
| SERVER_SIDE_CONVERSIONS.md | I13 — replacing client-side Google Ads conversion tracking with a server-side upload, mirroring the OpenAI Ads pattern already live in functions/api/contact.ts. Self-contained: problem, phased plan, open decisions. Phases 0–2 shipped; Basic Access approved 2026-09-05; two logging gaps found and fixed same day. A real-gclid test then surfaced the actual blocker — Google has closed the legacy upload endpoint to new integrations, mandatory Data Manager API migration for everyone by 2026-06-15. Phase 2b (new, scoped, not started) covers the rewrite |
| REVENUE_ATTRIBUTION.md | I14 — closing the loop from a visit or phone tap to a sold job in JobTread, then layering in post-lead/post-sale communication: static tracked phone number (vendor vs. Twilio build) + a JobTread API lead push + status/newsletter/review/referral sequences. Self-contained: problem, phased plan, open decisions. Scoping only, not started |
| Search_Strategy_Rules.md | Operating rules, experiment mechanics + contamination controls, Business Questions register (B1–B17), decisions log |
| SEO_FINDINGS.md | Dated audits and data sessions, append-only, never edited |
| TOPIC_MAP.md | Per-post inventory + de-facto GSC query, regenerated per data pull |
seo-baseline.json + scripts/seo-baseline.mjs |
Frozen tracked-query baseline; freeze / compare against a GSC deep pull |
scripts/city-page-uniqueness.mjs |
I11 acceptance check — run against dist/ after build |
Two rules worth carrying even if you read nothing else: no ranking or performance claim
without a dated source (a row in seo-baseline.json or a section of SEO_FINDINGS.md), and every
commit that advances a tracked item names its ID ([I11], [E1], [B6]). Full rule set in
Search_Strategy_Rules.md.
Four competitors audited to date — three live-web audits 2026-08-19, plus two from the earlier
SERP baseline (I2a, 2026-07-29). Full detail and methodology in SEO_FINDINGS.md.
| Competitor | Service overlap | Organic showing | Named in AEO answers? | Notable difference from us |
|---|---|---|---|---|
| Country Creek Builders (Lakeville) | Exact match — kitchen/bath/basement/whole-home, same 8 South Metro cities | Best of the four: 2 of 4 page-1 hits | Yes, both queries run — the only one of the three named | Publishes real pricing tiers on-site and in a blog post built around the exact "cost in [region]" query pattern; that post outranked ours in AI-answer synthesis (2026-08-19) |
| James Barton Design-Build (Apple Valley) | Same 4 services + exteriors/additions | 1 of 4 — only their own HQ-city (Rosemount) page | No, in any of 3 queries | One consolidated page per city (not per city×service) at ~2,500 words; "20+ years" as core claim; no pricing |
| Your Home Improvement Co. (Bath Planet dealer) | Bath only, and narrower (fast tub/shower conversion, not design-build) | 0 of 4 | No | 3-level hierarchy (city → service → product variant); largest review volume (676) but no FAQ, no pricing; 9-state footprint dilutes MN focus |
| South Metro Remodel / thin templated competitors (I2a, Eagan) | Kitchen/basement | Outranks our pages on several tracked queries at 950–1,400 words, near-zero city-specific content | Not tested | Thin but keyword-matched; ranking despite ~half our word count is why depth alone was never the explanation — see I11 |
What this set says, net: page-1 organic for generic service+city queries is hard to win even for well-established local competitors — JBDB and YHIC combined for 1 of 8 attempts on their own turf. Aggregator directories (Angi, Houzz, BBB) fill most of the remaining top slots regardless of who's competing. The one differentiator that visibly moved an AI-answer result was Country Creek's paired pricing-transparency + AEO-shaped content — see B17 in the backlog.
| Channel | Baseline | Target by Jan 2027 | Read |
|---|---|---|---|
| Non-brand organic clicks | 46 | 250+ | Pages are ~10–15 weeks old; not yet evidenced either way (Rule 9) |
| City-service bucket clicks | 12 | 75+ | Same age caveat |
| Service bucket clicks | 17 | 50+ | — |
| Blog bucket clicks / CTR | 192 / 0.60% | — / 1.0%+ | — |
| GBP: profile views / interactions / calls (6mo) | 1,600 / 228 / 27 | — | Discovery is 76% Search-driven, not Maps; search terms are almost entirely brand/junk, <15 impressions each for real service queries |
| AI Assistant channel (GA4) | 3 leads/90d (claude.ai, copilot) | — | Quarterly watch only, per I7 |
| Genuine form leads (estimated) | ~55–65 | 75+ with page attribution | Estimate until GTM fix lands 30 consecutive days of lead_form_success |
Local pack context: with one Lakeville address, GBP cannot win pack placement in distant cities — reviews only break ties among proximate businesses. Organic city pages are the only winnable placement beyond the Lakeville radius, which is why I11/E1 carry the weight they do.
Replaces the old initiative-status table. An item moves right as its gate clears; it doesn't get re-argued each time, just re-filed.
form_submit counts, not real demand) — both predate every tracked initiative, neither changes
what I11/E1/I6 are already doing, and neither is being pursued further unless it recurs. Full
detail: SEO_FINDINGS.md, 2026-08-22
and the lead-event follow-up.
Read for planning: this is not a signal to change course — I11/E1's actual job (drive more
organic volume into a funnel that's demonstrably converting well) has more evident leverage now,
not less. But the rising-CVR trend itself needs to survive I1 shipping before it's trusted as
more than directional — see I1 below, now scoped explicitly around this.observe): it already carries preferential internal linking
for reasons unrelated to this experiment, so putting it in either arm would confound the reading.
enrolledAt = 2026-08-19 for the whole treated cohort. Starting match: treated avg position
11.6, control avg 10.6 — well matched, once a real measurement bug was fixed same day (below).
Do not read a verdict before 2026-10-14 (8 weeks) — compare enforces this and prints
TOO EARLY before then regardless of what the raw numbers show. And when it is time to read it,
the number that matters is treated's delta minus control's delta (how much each arm moved,
not where each arm ends up) — see verdicts() in scripts/seo-baseline.mjs. Conversion rate by
arm as a secondary read is worth adding once I1 ships verified-success lead events (not before —
same reason as the organic-CVR trend above, form_submit isn't trustworthy enough to split by arm
yet) — not a redesign of E1, just an additional metric alongside position delta at the 2026-10-14
read if the data's clean by then."{Service} in {City}, MN | Honey-Doers" to "{Service} in {City}, MN | Free Estimates" — a common shock, no arm split, no interaction with E1. Metric is CTR binned by GSC
position band, pre-ship (ending 2026-08-19) vs. post-ship. Earliest read: 2026-09-10 (3
weeks); confirm at ≥15% relative CTR lift at matched position, revert below ≤5%. Full
pre-registration in Search_Strategy_Rules.md.compassexteriors.com is a Honey-Doers sister company, not a competitor, and roofing content
will eventually merge back into honey-doers.com, so writing new roofing content now would likely
get redone or discarded. Revisit alongside the merge (I12).is-a-kitchen-remodel-worth-it actually
published 2026-08-13 (not 08-18 as previously recorded here) and sat 7 days without its
consolidation redirect. Fixed: how-a-kitchen-remodel-can-add-to-the-value-of-your-home,
how-important-are-kitchen-designs-for-home-value, and remodeling-your-kitchen-for-ultimate-resell-value
deleted and 301'd to the keeper (public/_redirects, both slash variants, plus the three legacy
category-prefix rules pointed straight at the keeper instead of chaining); 4 live posts that
linked to the old URLs repointed directly.kitchen-remodeling-timeline- planning-guide, drafted for a 2026-09-08 publish, turned out to target the same query as the
live 2018 post the-kitchen-remodel-timeline — a query-gate check that should have run at draft
time and hadn't been recorded. Rather than ship a second URL for the same query, the draft's
content (listicle nav, phase table, FAQ block, direct-answer openers) was rolled wholesale into
the-kitchen-remodel-timeline in place (commit 7525020); the draft file was deleted, never
published. how-long-does-the-average-kitchen-remodel-take was already redirect-only with no
live .mdoc. All _redirects entries for both legacy slugs already pointed at
/blog/the-kitchen-remodel-timeline/, so no redirect changes were needed. This board's own
"Now" tracking of the item was stale for a full day (still described it as "not yet due,
2026-09-08" on 2026-09-02) because the shipping session didn't update it — a live instance of
exactly the doc-drift the "mop up in the same edit" rule exists to prevent; caught and fixed here
instead. I10 is now fully closed; remaining items are non-urgent housekeeping — see
Later.site-explorer-organic-keywords against named competitors +
keywords-explorer-overview for volume/difficulty) before drafting — each one a keyword bet with
a stated volume/difficulty/traffic-potential number, not a guess. Uses the same Ahrefs Lite
account as the Web Analytics trial below (100,000 API units/mo; the test post below cost 1,479 —
effectively no ceiling risk at this cadence). Full evaluation trail, including the Soro/Dylan
audit that motivated this: feedback/project memory (session-local, not in-repo).
Deliberately concentrated, not spread thin — basement first: basement is already flagged as
a margin-leader cluster (claim still pending B2/B6 sourcing, per the Business Questions register)
and I11's active experiment arm, so it's the target for demonstrable domination before opening a
second cluster. Country Creek Builders (already-audited I2a-adjacent competitor) ranks
#1–15 across a basement keyword set with thin content — the plan is to out-rank them on it, not
just publish adjacent to it.CONTENT_VALUE_REGISTER.md.
The gate above only checked demand before writing; nothing tracked whether the target
actually converted to GSC performance once live — the same reach gap (172/220 posts, 0 clicks
in 90d) this initiative exists to fix could reappear silently even with every post passing the
Ahrefs gate. Seeded with the four posts published in the week before this entry
(how-to-finish-an-unfinished-basement-right, basement-bar-ideas,
basement-finishing-budget-planning-guide, custom-cabinets-vs-stock-cabinets) — Ahrefs
baseline logged now, first GSC read due 4 weeks after each post's live date. Every post run
through this gate going forward gets a row at write/schedule time, not backfilled after the
fact.basement-bar-ideas (published 2026-08-26), targeting "basement bar
ideas" (6,700/mo, KD 1) — Honey-Doers had zero "bar" keyword rankings before this. Full brief
and value-check trail: CONTENT_VALUE_REGISTER.md.4-basement-ceiling-ideas-to-finish-your-basement pre-refresh ranked avg.
position 22.4 for "basement ceiling ideas" (4,027 imp/90d, 9 clicks — real demand, not a
Tier-A zero-click case). Country Creek's
basement-ceiling-options...drop-ceilings-vs-drywall-vs-exposed post ranks #1 for
"basement ceiling" (700/mo, KD 0) with a direct comparison framing ours lacked — what
changed, the pre-refresh baseline, and the read date are in the "Both refreshes shipped" and
"Pre-refresh Ahrefs baseline" bullets below.6-basement-finishing-ideas-to-maximize-your-roi pre-refresh ranked avg.
position 26.6 for "return on investment basement renovation" (1,017 imp/90d, 8 clicks). Country
Creek has a dedicated ROI post targeting "how much does finishing a basement add to home value"
(100/mo, KD 12) — same reach-not-tier-A shape as Move 2; detail below.basement-remodeling-ideas (2,015
words, drafted 2026-09-01), a content-gap pull against Country Creek's basement footprint
targeting "basement renovation/remodeling ideas" and variants (~2,200/mo combined, KD 5–6) —
a genuine gap versus existing adjacent posts. Took over the
how-to-increase-your-homes-appraisal-value slot; stays pinned to 2026-09-29 through
subsequent cadence compressions — don't let a later backfill move it. Full brief and
value-check trail: CONTENT_VALUE_REGISTER.md.basement-bar-ideas
(Move 1)'s first CONTENT_VALUE_REGISTER.md read lands on 2026-09-23 — it's the cleanest
test case (exact-match term, near-zero difficulty), and by that date the other three posts in
the opening batch (how-to-finish-an-unfinished-basement-right 09-22,
basement-finishing-budget-planning-guide 09-24, custom-cabinets-vs-stock-cabinets 09-29 —
check this last one a few days late) will have landed too, so the read covers the whole
opening cluster, not one data point. Decision rule: real position/click movement across
that batch → schedule Move 5 and the roundup post next. Flat or no signal → hold both rather
than add more basement content on the same unproven assumption; revisit reasons, not just the
date, at that point.9-ideas-walk-in-tub-luxury-spa-bathroom (2,405 words, drafted 2026-09-01); the sunroom brief
was sent back to Dylan to retarget (weak keyword set, no service page); panel-ready appliances
became Move 7. Author corrected to Adam Berres, 2026-09-01 — Spenser overrode the skill's
Rick/Adam alternation for all posts going forward (see feedback memory, session-local, not
in-repo). Full brief and value-check trail: CONTENT_VALUE_REGISTER.md.7-critical-pros-and-cons-of-panel-ready-appliances (2,064 words, drafted 2026-09-01),
targeting "panel ready appliances" (700/mo, KD 0) — deliberately not the higher-volume but
shopping-intent "panel ready refrigerator." Author: Adam Berres. Full brief and value-check
trail: CONTENT_VALUE_REGISTER.md.project_id 10266158, shared account — previously held one
unrelated tracked keyword, "kitchen remodelers near me"; confirm with Dylan before assuming
exclusive use) — the new post's target cluster, both refresh targets' queries, and the
cluster's already-strong performers (egress/bedroom-requirements, humidity, dryness, planning)
as a check that the domination push doesn't cost ground elsewhere. MCP access is read-only for
Rank Tracker (no add-keyword endpoint exposed); the list was hand-entered via the Ahrefs
dashboard, not automated.TOPIC_MAP.md's next regeneration post-2026-08-26 — GSC needs
real time to index and attribute the new post; Ahrefs Rank Tracker gives an earlier read on
live SERP position, independent of GSC's pull cadence, for exactly this reason.75cc546, 398bdf4) as light edits, not full
rewrites — SERP research (below) showed the head terms are a hard climb for on-page work
alone, so the pre-rewrite Ahrefs snapshot guard didn't apply; the pre-refresh baseline below
still stands as this initiative's annotation. Both carry the E1-treatment links through intact
per post-refresh-audit's Experiment guard (verified verbatim, not just "still present").
What actually changed, and why — SERP-driven, not a blind content-depth pass:serp-overview for "basement ceiling ideas" — the SERP is Reddit/
YouTube/Pinterest/Lowe's/AI Overview, not other remodeler blogs; a DR55 competitor post only
reaches position 10. Out-ranking that field on-page alone is unrealistic. It did surface four
People-Also-Ask questions verbatim, so the edit built an FAQ section from those exact
questions (a PAA/AI-Overview-citation target, not a blue-link ranking play) plus a {% stat %}
block and tightened excerpt/metaDescription to include the literal phrase "basement ceiling
ideas" (previously absent from both).{% stat %} block for the existing 86% JLC figure and two FAQ entries from PAA data
answerable from cost/ROI figures already verified in the post; two other PAA questions ("30%
rule," property-tax impact) were deliberately skipped — no primary source in hand, and this
skill's checklist treats unverifiable cost/code claims as the highest-damage error class.site-explorer-organic-keywords, mode: exact,
per-URL): ceiling post currently ranks for exactly one keyword — "unfinished basement bathroom
ideas" (250/mo, position 3); its own target term "basement ceiling ideas" (4,800/mo) is
confirmed gone — consistent with a full-domain Ahrefs export the user pulled the same day
showing several refreshed basement/interior posts losing previously top-ranking long-tail
terms after full rewrites (not confined to E1-carrier posts; not conclusively refresh-caused
either, since an untouched post lost terms too — logged as a refresh-skill guard above, not a
settled causal claim). ROI post currently ranks for zero keywords
in Ahrefs' index — nothing to lose there; all current signal on it is GSC-only (1,017 imp/90d,
avg. position 26.6). Both refresh targets' queries are already in the 19-keyword Rank Tracker
set added the same day (project_id 10266158), so live-position movement is trackable
independent of GSC's pull cadence.TOPIC_MAP.md's next
regeneration for the GSC-side read. Compare against the baseline immediately above, not just
"did it go up" — the ceiling post in particular has room to regain the lost 4,800/mo term as
well as improve its GSC position.4-basement-ceiling-ideas-to-finish-your-basement and
6-basement-finishing-ideas-to-maximize-your-roi are two of the four posts carrying E1's
actual link treatment (Decisions Log, 2026-08-19: 4 new in-body links each to the 3 treated
cities, shipped from "ceiling, bedroom-requirements, dry-basement, ROI posts"). A content
refresh on either must preserve those exact treatment links untouched until the 2026-10-14
read — this is a real edit-collision risk, not the post-refresh-audit experiment guard's
usual "don't mention a control city" case, since these two posts are the treatment.keywords-explorer-overview) on all ~19
originally-proposed keywords: only one carried a transactional intent tag —
"basement remodeler" (1,400/mo, KD 0, $1.90 CPC, local intent, traffic potential 11,000) — a
real hire-intent term with essentially no competition. Most of the rest were pure-informational
with no commercial tag at all, including the ceiling post's own head term ("basement ceiling
ideas" — zero commercial intent per Ahrefs, consistent with the Reddit/YouTube-dominated SERP
found earlier the same session). Reframed the keep/cut decision around hire-intent vs.
DIY-intent rather than commercial-tag-vs-informational-tag, since a few terms ("drywall
basement ceiling," "how to keep basement dry without dehumidifier") actively self-select DIYers
away from hiring anyone./services/basement-remodeling/ + the four basement city+service pages) is
structurally ready to compete for this term. Found and fixed a real, sitewide bug: every one of
the 9 service pages' <title> said "Minneapolis" while its <h1> said "Lakeville" — inconsistent,
and Minneapolis isn't a priority market. Fixed all 9 to say Lakeville (commits 00947a7,
a3c46e3). City+service pages themselves were already clean (title/H1 match, city-specific,
generated per-city). Sitewide LocalBusiness schema (NAP, geo, areaServed, aggregateRating)
is solid via SEOHead.astro, though sameAs only links Facebook/Instagram — no Google Business
Profile URL, worth adding if/when available. Live SERP for "basement remodeler near me" is
dominated by directories (Houzz, Thumbtack, Yelp) and other contractors' city-named pages — the
Map Pack itself (the actual local-ranking battleground) isn't visible via the API and is
off-site GBP work, not a repo-side fix. Net: page structure was not the gap here; the fixed
title/H1 bug was real but incidental to what actually decides "near me," and five
metaDescription fields still literally say "Minneapolis" (bathroom, whole-home, laundry,
closet, garage) — flagged, deliberately not fixed this session, out of scope for the title/H1
ask.TOPIC_MAP.md +
keywords-explorer-overview). Every one had a fluent, editorial-sounding title that carried
zero search volume, sitting right next to a shorter "how to [verb] [noun]" phrasing that
tested with real volume and low difficulty:how-to-prepare-for-a-remodel-before-work-begins (date since drifted with cadence
compression — check the file's frontmatter for its current slot, not this note).how-to-increase-your-homes-appraisal-value
(date since drifted with cadence compression — check the file's frontmatter for its current
slot, not this note).
Diagnosis: Soro doesn't check live keyword volume at brief-generation time — it optimizes
for a title that reads well editorially, not one that matches an actual query. This is
consistent with the original 2026-08-25 audit's finding (session-local project/feedback
memory) that Soro's keyword targeting was weak, now with a 3/3 in-session replication.
Config change, 2026-09-01 — user edited Soro's settings to steer around this:keywords-explorer-overview before publishing. Re-check this note's
hit rate against the next batch of Soro drafts before treating the config edit as proven.CONTENT_SOURCING.md
generalizes this same method (competitor content-gap sweeps, category keyword sweeps) for once
the Compass backlog itself dries up too — read that file, not this note, when that transition
is actually underway.whole-home-renovation-checklist only serves whole-home searchers; a kitchen/bath searcher
landing on it may not find it useful. Structure as a general "home renovation checklist" hub
linking down to service-specific checklist spokes (kitchen, bathroom; basement excluded, see
below), with whole-home-renovation-checklist becoming the whole-home spoke rather than staying
the sole checklist page on the site.Not the same plan as the 2026-07-29 deferred hub/spoke reorg (basement "Dream [Room]"
naming — session-local project-hub-spoke-deferred memory, not in-repo). That one was killed
because it was a speculative reorg of a head term the site didn't rank for, and the GSC audit
found reach — not cannibalization — was the actual bottleneck ([[feedback-content-cannibalization]]
equivalent: SEO_FINDINGS.md, 2026-07-28 topic-map audit). I16 is the
opposite case: the spokes below are open keyword gaps with no existing post, so building
them adds reach rather than reorganizing existing content.
Ahrefs data behind this call, pulled 2026-08-31 — mcp__ahrefs__keywords-explorer-overview,
country: "us", select: "keyword,volume,difficulty,traffic_potential":
| Keyword | Volume/mo | Difficulty | Traffic potential | Existing coverage |
|---|---|---|---|---|
| home renovation | 17,000 | 58 | 89,000 | N/A — confirmed unwinnable, do not target (this is the term the original Soro draft targeted; see below) |
| home renovation checklist | 200 | 1 | 600 | whole-home-renovation-checklist, but ranks avg. position 59.3 for it — weak return on a difficulty-1 term |
| kitchen remodel checklist | 350 | 3 | 300 | none — open gap |
| bathroom remodel checklist | 400 | 4 | 250 | none — open gap |
| kitchen renovation checklist | 150 | 2 | 300 | none — open gap, secondary phrasing |
| bathroom renovation checklist | 200 | 4 | 150 | none — open gap, secondary phrasing |
| basement remodel checklist | 10 | 0 | 30 | none — volume too thin to justify a dedicated post |
| basement renovation checklist | 10 | null | null | none — same, too thin |
Companion check, mcp__ahrefs__site-explorer-organic-keywords on www.honey-doers.com
(mode: subdomains, country: us) confirmed the site holds no live ranking for any
"home renovation" variant — consistent with the 2026-08-25 audit's "avg. site position ~#31"
finding on the bare term.
Basement gets no dedicated checklist spoke — 10/mo volume on both phrasings doesn't clear
the bar. Link basement content into the hub directly instead (existing basement-cluster posts:
4-basement-ceiling-ideas-to-finish-your-basement, 6-basement-finishing-ideas-to-maximize-your-roi,
egress/bedroom-requirements, dry-basement — see I15 above).
Hub post = the Soro "Home Renovation Planning for Fewer Surprises" draft, repurposed, not
published as-is. Its planning/budget/priorities framing fits a hub far better than it fit as
a standalone post targeting the unwinnable bare term. Retarget its H1/title/metaDescription to
"home renovation checklist" (200/mo, difficulty 1) before publishing, and add outbound links to
each spoke once built. Raw, unedited draft preserved at
drafts/soro/home-renovation-planning-for-fewer-surprises.md
specifically so the eventual rewrite can be diffed against what Soro actually produced — not
committed to src/content/blog (would publish it as-is via the glob loader), not deleted.
Sequencing, not yet started: (1) rewrite the hub post from the preserved draft, retargeted
per above, through the new-blog-post skill's standards; (2) add whole-home-renovation-checklist
as a spoke — link up to the hub, no content rewrite needed; (3) draft new kitchen and bathroom
checklist spokes; (4) cross-link hub ↔ all spokes once all four posts exist. No read-date yet —
set one once the hub ships.
SEOHead.astro (next to the existing GTM/OpenAI-pixel pattern, env-independent — no feature flag,
just live). Purpose is narrow: an independent, cookieless traffic count to cross-check GA4's totals,
not a GSC replacement — it validates "is GA4 undercounting visits" (consent banners/ad-blockers/ITP
can suppress GA4's tag), not "is Google's search-performance reporting honest," which only GSC can
speak to. Pagespeed impact assessed as negligible (async, ~1KB, no render-blocking). Review by
2026-11-20 (90 days): compare Ahrefs' pageview counts against the same-window GA4 total: if the
two track within a small margin, drop the extra script (redundant); if Ahrefs reads meaningfully
higher, that's a real signal GA4 is undercounting, worth keeping and noting as a caveat on any GA4-
sourced number in this file going forward. Separately, the same Ahrefs account also has the backlink
tool — real referring-domains numbers for honey-doers.com (and ideally
countrycreekbuilders.com/southmetroremodel.com/compassexteriors.com) are still owed and would
upgrade E5 and the I12 manual scan from proxies to real data.GA4 Lead Form Success (Verified) (trigger on lead_form_success → GA4) and
GA4 Ads Lead Conversion (Verified) (trigger on conversion_event_submit_lead_form → GA4, which
feeds the Ads SUBMIT_LEAD_FORM conversion action via its existing GA4-event import — not a raw
Ads Conversion Tracking tag, since Ads' "Lead form - Submit" action turned out to be an unrelated
Google-hosted lead-form-asset conversion). Verified live via GA4 DebugView against the real
/contact-us/ page. Found and fixed a real bug during verification: the standalone
/contact-us/ page runs its own inline form-submit script (separate from the ContactForm.astro
component used sitewide) and was missing the lead_form_success push entirely — only
conversion_event_submit_lead_form fired there. Fixed in f5cab01. Also found and removed a
duplicate Ads conversion action — SUBMIT_LEAD_FORM (1), a GA4-import action pointed at a
never-fired event name (conversion_event_submit_lead_form_1); deactivated 2026-08-22, no site
code targets that name and none should. Today's test conversion won't show in Ads, and that's
expected, not a fault: it fired under GTM Preview/debug mode, which GA4 excludes from the
GA4→Ads export by design, and even real (non-debug) conversions take Google up to a few hours to
import — don't expect Ads reporting to reflect this until a real production lead comes in and some
time passes.
What "airtight" means here, concretely: today's lead figures come from form_submit /
phone_clicks — events that fire on any submission, not a verified success, which is exactly how
the Sep–Dec 2025 bot spike got counted as 100+ "leads" in a single month. Now that
lead_form_success / conversion_event_submit_lead_form are live and confirmed firing everywhere:
(1) recompute the organic CVR quarterly series above against verified-success events only and
confirm the trend survives — it may move, since a bot-contaminated period sits inside the current
series' Q4 2025 point even after excluding it from the headline read; (2) treat the current
1.51%→9.74% figure as provisional until that recompute happens, and give it a few days to
accumulate verified-success volume before pulling the recompute.
First read, 2026-09-03 — partial, not the full recompute. lead_form_success has no history
before 2026-08-22, so only the current quarter can ever be checked against it — the pre-2026-08-22
points in the series below stay form_submit-based permanently. At 12 days / 128 organic sessions
/ 7 leads, lead_form_success and form_submit counts matched exactly, day for day — no sign of
the verified/unverified gap the Q4 2025 caveat worried about, at least in the Organic Search
channel. But 5.47% CVR in this window sits below both Q2 2026 (7.05%) and the Q3 partial read
(9.74%) — too small a sample (7 leads) to call that a reversal, just not yet confirmation the
rising trend held either. Full detail: SEO_FINDINGS.md, 2026-09-03.
Re-read once ~30 days of verified-event history exist (≈2026-09-21) — same threshold B4
already names — before trusting either direction.75dfbc9 (2026-08-01, derived live from each
post's own FAQ section — no second copy to drift), and responsive images in a four-commit follow-
up (e5591a4, 961aa31, d037162, c79b86c, 2026-08-01–08-04) covering blog covers, project
gallery, remaining images, and inline body images via astro:assets. Verified 2026-08-20: zero
plain <img> tags remain in src/ outside one documented fallback case for unmigrated inline
images. No action taken — removing a stale line, not doing new work.Ready to start as soon as the item above it clears, or already queued with no remaining blocker.
/services/roofing/, /services/siding-windows/, /services/decks-exteriors/) are live in
src/data/services.ts, each with a supporting blog-post refresh, per the redirect/consolidation
plan in COMPASS_REDIRECT_MAP.md. /our-services/roofing-and-exterior/
no longer forwards to compassexteriors.com — repointed to /services/roofing/. The 15-post
roofing-insurance/claims cluster, the window-installation cluster, and the four-season-decking
cluster are all triaged — per-post dispositions in COMPASS_REDIRECT_MAP.md. Project-gallery
CTA/carousel hidden on all 3 exterior pages (ServiceData.hasProjects) until real case studies
exist for those categories. Full plan and Phase 0 decisions (NAP → Lakeville, GBP merges, Compass
brand dissolves entirely) in
COMPASS_EXTERIORS_MERGE.md. Blog cadence bumped to
3×/week (Tue/Thu + one exterior slot) to work the remaining backlog — see
Recurring cadence. First backlog pick shipped 2026-09-06:
roof-flashing-repair-how-to-spot-damage (scheduled 2026-09-19) — the exterior slot had gone
unfilled through 2026-10-20 despite the cadence bump, so this was written to close that gap, not
picked mechanically off the category list. Quality-filtered via Ahrefs against several roofing-
category candidates from the backlog; "roof flashing repair" (2,700/mo, KD 1) was the clear
winner — real transactional+local intent, near-zero difficulty, genuine open gap (no existing HD
post owns flashing). Content rewritten fresh in HD voice from Compass's source topic, not ported.
Full brief: CONTENT_VALUE_REGISTER.md. Second pick shipped
2026-09-06: window-sill-replacement-is-it-worth-it (scheduled 2026-09-26), rotation moved to
siding-windows — fills the week-of-Sep-21 gap, which had also dropped to 2x with no exterior
post. "Window sill replacement" (1,500/mo, KD 0) won a quality-filter pass against several other
siding-windows candidates (foggy windows, bay window cost, asbestos siding removal — all still
viable future picks). September's cadence gaps are now fully filled. Third pick shipped
2026-09-06: deck-skirting-ideas-five-alternatives-to-lattice (scheduled 2026-10-03), rotation
moved to decks-exteriors — fills the week-of-Sep-28 gap. "Deck skirting ideas" (3,700/mo, KD 1)
won against deck privacy ideas, patio vs. deck, curb appeal ideas, and garage ventilation (all
still viable future picks); genuine open gap, no existing HD content mentioned skirting or
lattice at all. Both cover images sourced and committed same day. Fourth pick shipped
2026-09-06: how-to-tell-if-your-roof-is-properly-ventilated (scheduled 2026-10-10), rotation
back to roofing — fills the week-of-Oct-5 gap. "Roof ventilation" (3,500/mo, KD 0) won against
attic insulation cost, rooftop deck, and metal roofing cost (riskier at KD 16); deliberately
cross-links to the flashing post since both are ice-dam mechanisms — a small intentional
cluster, not incidental overlap. All identified gaps through mid-October are now filled.
Next action: continue the same quality-filter-then-write pattern for the next open exterior
slot as the runway extends — sequencing detail in
COMPASS_REDIRECT_MAP.md's version history. Phase 3's
outbound half (Compass domain → HD, ~97 URLs) still unbuilt, depends on Phase 2 resolving exact blog
targets. Unblocks I10 Item 7 once content migration lands.TOPIC_MAP.md +
updatedDate, no more re-deriving it from this board each session. Watch it: lowest-friction
work quietly eats the slots meant for E1 if not budgeted deliberately. Hard cap of 1-2
refreshes/week, set 2026-09-06 — owner flagged that a burst of same-session publishing (several
refreshes and/or new posts in one sitting) reads as AI-generated output regardless of individual
content quality; full reasoning and the pacing rules are in
REFRESH_BACKLOG.md § Cadence — don't
re-derive or loosen this from scratch in a future session./locations/<city>/<service>/) are being retired, not remediated; their content merges into the
location hub. Full reasoning and evidence (competitor review, GSC index-coverage export, 90-day
GSC click/impression data) in
LOCAL_PAGE_REMEDIATION.md §Level 2 collapse.
Delivery sequence in §Delivery:36d0e75).
LocationHubPageV2.astro replaced LocationPageLayout + the 4 LocationServicePageLayout
pages at /locations/lakeville/; the 4 retired service URLs 301 cleanly (confirmed against
production, scripts/check-redirects.mjs 391/391 healthy). Full change list in
LOCAL_PAGE_REMEDIATION.md's v1.31–1.33 entries.
Case-study schema upgrade (was step 2) turned out not to be needed — the pilot shipped using
projects.ts's existing fields.LocationServicePageLayout.astro once every batch redirects clean with
no regression.
Phase 3 tail research (2 of 9 non-arm cities remaining past Minneapolis/St. Paul) is paused, not
cancelled — packets still feed the hub merge, just don't publish new standalone service pages.www.google.com/ccm/collect; the smaller half of that finding (the OpenAI Ads
client-side pixel) was fixed the same day by deleting it outright, since its server-side lead
conversion tracking already existed independently. Google Ads has no server-side equivalent yet, so
this is a build-then-cutover, not a deletion. Second consumer, added 2026-09-02: the
new-blog-post skill's primary-query volume gate (triangulating Ahrefs volume against a live
SERP/PAA check) treats Google Keyword Planner as an optional third, first-party-Google input —
currently skipped since it isn't connected. Once I13 ships, the gate picks it up automatically,
no separate wiring needed. Phase 0 (credentials) done, 2026-09-03 — a manager account was
required first, not just a developer token (unexpected step, not scoped originally); full detail
in SERVER_SIDE_CONVERSIONS.md's Phase 0.
Phases 1 and 2 also shipped, same day (cf0bdaf, e38ad85) — gclid capture, credentials
in Cloudflare Pages secrets, a new dedicated Conversion Action ID (7746080556,
secondary/not-bidding until verified) separate from the three existing GA4-imported actions, and
the upload code itself in contact.ts. Basic Access approved 2026-09-05 (2 days after filing,
faster than the ~5-business-day estimate). Live verification that day found a real bug: the
upload code treated Google's HTTP 200 responses as success even when they carried a
partialFailureError (the API's partialFailure: true mode embeds per-conversion failures in
the body rather than the status code) — a rejected conversion was silently indistinguishable from
a real one. Fixed same day (76bfd50). A same-day follow-up test with a real gclid (VPN +
branded-term ad click, lead E5331A) missed log capture the same way — the tail was attached to
a deployment that got superseded mid-session by an unrelated commit's rebuild. Rather than just
retry the fragile live-tail approach, fixed the underlying gap instead (de627e6): wrangler tail only shows a lead's outcome to whoever is watching at that exact moment, so added a
LEAD_LOG KV namespace plus a short diagnostic email that record every upload attempt's
outcome, checkable any time after the fact. With that KV namespace bound and a real-gclid test
re-run (lead 1AEA4D), the diagnostic email delivered the real answer: Google has closed
ConversionUploadService.uploadClickConversions to new integrations —
everyone migrates to the Data Manager API by 2026-06-15,
new integrations already can't use the legacy endpoint. Phase 2's code isn't broken; it targets
an API Google is retiring. Phase 2b (new, scoped 2026-09-05, not started): migrate to the
Data Manager API — different auth model (service-account impersonation per Google's docs, vs.
the OAuth-refresh-token flow used today; needs confirming whether that flow can be adapted),
different endpoint (datamanager.googleapis.com), different request/response shape, and a
fail-fast rather than partial-failure model. Full field-mapping table and migration sequence in
SERVER_SIDE_CONVERSIONS.md's Phase 2b.tel: tap, neither form nor phone leads are confirmed to reliably
reach JobTread, and there's no documented communication layer before or after the sale (status
updates while a lead is open, newsletter/review/referral sequences once it closes) — together
these block every question in the Business Questions register that depends on a closed lead→sale
loop (B1, B3, B5, B6, B10, B15) and are the building blocks of a mature sales motion, not just a
tracking fix. Phased: tracked number → JobTread lead push → communication sequences, each phase
depending on the last. Presented to the owner 2026-08-26, not decided: vendor call-tracking
SaaS (CallRail/WhatConverts) vs. a Twilio build is still open, same shape of blocker as I12/I13 —
don't pick this up as a session until that decision lands. One independent piece did get a
greenlight that day: testing the JobTread lead-push API call (see MEETING_NOTES.md).Contingent on something above reporting first, or genuinely low-urgency.
SEO_FINDINGS.md.No schedule, no owner yet, revisit if a trigger fires.
Hypotheses and open questions that aren't scheduled work yet — either because they need an answer first, or because they're genuinely speculative. Full detail for the B-register in Search_Strategy_Rules.md.
countrycreekbuilders.com and southmetroremodel.com to know if
DR 31 is ahead or behind; sizes whether I9 (link building) or E1 (on-page) is the higher-value
lever.owlroofing.com (DR 36, ~685 organic keywords, ~2.6K est. monthly organic
traffic — a real but modest single-metro roofer, not a juggernaut) found their top-traffic pages
are almost entirely blog content, not their templated /roofing/[city]/ doorway pages or their
network of city-specific EMDs (roofingwoodbury.com etc. — same NAP as the main site; a
doorway-domain pattern flagged as not worth emulating, see decisions log). The single
most-repeated winning shape: self-authored "best roofing companies in [city]" roundup posts that
list their own company favorably (best-roofing-companies-maple-grove-mn ranks #2 for "maple
grove roofing," similar posts rank page-1 for Minneapolis, St. Paul, Brooklyn Park, Blaine,
Minnetonka, and even an adjacent category — "7 Best Gutter Companies in Osseo"). Low-risk since
it's genuinely useful comparison content, not a template swap, and it's a different shape than
anything currently in REFRESH_BACKLOG.md or the Now/Next board. Open question, resolved
2026-09-01: live evidence arrived unprompted — Country Creek runs a "Top 10 Basement
Remodelers in the South Metro"-style roundup that names Honey-Doers alongside 9 other
competitors (user-observed, not yet pulled into an Ahrefs audit of that specific page). Checked
the keyword-volume question this was blocked on: "best basement contractors near me" (100/mo,
KD 0, local+commercial, parent topic "basement remodeling contractors" at 2,200/mo),
"best basement finishing companies" (80/mo, KD 1), "best basement remodeling companies" (30/mo,
KD 0) — modest direct volume, all at essentially zero difficulty. "Best kitchen remodelers near
me" is the bigger prize (1,000/mo) but also much harder (KD 57), confirming the original framing
that this format's value isn't really the direct search volume — it's the same AEO-citation
mechanism as Country Creek's pricing-transparency post (SEO_FINDINGS.md, 2026-08-19): getting
named in the answer, not just ranking for the roundup query itself. Being named by a
competitor's version of this post is free evidence the format works and that Honey-Doers is
already considered comparison-worthy — self-authoring the Honey-Doers-favorable version is the
natural next step. Recommendation: worth doing, low risk (genuine comparison content, not a
template swap) and low cost (KD 0–1). Fits the current basement concentration if scoped as
"Best Basement Remodeling Companies in the South Metro" rather than a general roundup. Not yet
scheduled or slotted — a sixth basement candidate alongside Move 5, gated on the same
reevaluation trigger (Move 1's 2026-09-23 read) logged under I15's Now entry — check
there before scheduling, don't re-derive the timing here.SEO_FINDINGS.md 2026-08-28):
their remodeling category page carries a dedicated safety/compliance section on lead-paint and
asbestos handling (EPA RRP certification named). We have nothing on this anywhere in the interior
remodeling content reviewed. Twin Cities housing stock genuinely spans pre-1978 construction
where lead paint is a live, federally-regulated renovation concern — this is dated, checkable,
locally-relevant subject matter that fits the site's existing sourcing standard (dli.mn.gov /
EPA-style citations), not competitor-chasing filler. Not sized or scheduled — a candidate topic
for the next new-post slot or a refresh addition to kitchen/bathroom/basement pages that involve
older housing stock, whichever comes up first.serp-overview finding above — Reddit/YouTube/Pinterest own that SERP, not
remodeler blogs), and the framing is meant to read as genuine value/inspiration content, not an
SEO play. Validation bar before this becomes real work: one page published, check for any
impressions/clicks once indexed, and whether the contributor actually keeps feeding the doc past
the first batch (adoption risk is as real as the traffic risk). A doc template and sample page
mockup exist (session of 2026-08-31) to help decide if it's worth doing at all.
Pilot page picked, 2026-09-01: how-to-choose-bathroom-tile-materials-that-last (queued,
publishes 2026-09-17). Its Ahrefs value-check (see I15 below) surfaced a real intent gap:
"bathroom tile ideas" carries 14,000/mo commercial-intent volume the post's actual
durability/material-selection angle doesn't address, while an inspiration/lookbook-style
treatment is exactly what that query wants. Plan: publish the durability content on schedule as-
is, then add a curated "Bathroom Tile Inspiration" lookbook section as a refresh once the
contributor's doc has enough tagged images — bump updatedDate, sitemap lastmod follows
automatically per this doc's sitemap rules. This is the validation instance for the item above,
not a separate one-off: track impressions/clicks after the section lands and whether the
contributor keeps feeding the doc, per the validation bar just above.3riversmn.com has a /careers/ page
in its own nav, noted for reference only — not the reason for this item). Not sized or scoped
yet — open questions before this becomes real work: standalone page vs. a section on /about/
vs. routing to an external ATS/job-board listing; whether it needs JobPosting schema; and
whether this is an SEO play (capturing "[role] jobs [city]" queries) or purely an operational/HR
need that happens to live on the marketing site. Needs a scoping conversation, not a page yet.Re-verified against the codebase; numbers drift, re-check before citing anything below as current.
| Fact | Value |
|---|---|
| Blog posts (incl. scheduled) | 232 |
Posts with no metaDescription |
144 |
Posts never refreshed (no updatedDate) |
170 |
Posts with no coverImage |
59 |
| Blog → city×service links (of which basement) | 30 (12) |
| Tracked-query baseline | frozen 2026-08-19 — see Performance tracking |
| Metric | Pre-I11 (2026-08-02) | Now | Source |
|---|---|---|---|
| Pages meeting the 30% standard | 1 of 104 (Lakeville bathroom, 31.7%) | 60 of 104 (13 arm cities + 2 early tail cities) | city-page-uniqueness.mjs |
| Pages with "Photos Coming Soon" placeholder | 104 of 104 | 0 of 104 | LocationServicePageLayout.astro |
Cities with neighborhoods content |
5 of 26 | 15 of 26 | locations.ts |
Cities with cityFaqOverrides |
1 of 26 (Lakeville, kitchen+bath only) | 15 of 26 | locationServices.ts |
Cities with costBands |
0 of 26 | 0 of 26 — blocked on B1/B6 export | locations.ts |
| Testimonials attributed to a city | 0 of 23 | 9 of 23 | src/data/testimonials.ts |
node scripts/seo-baseline.mjs freeze, GSC range 2026-05-19 → 2026-08-16. 29 tracked queries,
24 with GSC data. Re-frozen once, same day, same GSC pull — see the measurement bug below —
so this reflects the corrected numbers, not the original run.
| Finding | Value |
|---|---|
| Total impressions across all 29 tracked queries | 3,480 |
| Total clicks across all 29 tracked queries | 0 |
| Queries where the tracked page has zero GSC presence | 0 of 24 found — every tracked page has some data for its query |
| Queries cannibalized (tracked page ranks, but a competing page on our own site has more impressions) | 5 of 24 — Apple Valley basement, one Lakeville query, Edina, and both Minneapolis queries; the position reported is still the tracked page's own, per the fix below |
| E1-treated avg position, final arm (5 cities, 7 queries found) | 11.6 |
| E1-control avg position, final arm (7 cities, 7 queries found) | 10.6 |
A real measurement bug was found and fixed the same day this froze, before the window meant
anything. The original measure() sorted each query's GSC rows by impressions and reported
whichever page won as "the" position — so for basement remodeling edina, it reported /blog/'s
position (61.4, 7 impressions) instead of the actual tracked page's position, which GSC separately
reported at 11 (3 impressions). This wasn't isolated to Edina: the same logic corrupted Apple
Valley's number too (city hub's 14.1 got reported instead of the real page's 17.6). The fix reports
the tracked page's own row when it has any GSC data at all, and surfaces competing pages as a
"cannibalized by" note rather than letting them override the actual metric. Net effect: the arms
went from looking badly mismatched (11.1 treated vs. 17.8 control, driven almost entirely by
Edina's phantom 61.4) to genuinely well matched (11.6 vs. 10.6) — the original mismatch was a
scoring artifact, not a real property of the cities. Full detail in scripts/seo-baseline.mjs's
measure() comment.
The zero-click finding is the headline result of this freeze, not a rounding artifact — verified against the raw GSC pull, which shows 159 total clicks site-wide in the window, entirely on brand-name variants ("honey doers," "honeydoers," etc.). Every one of the 29 non-brand tracked queries — the exact query set this whole program is trying to move — converted zero clicks from 3,480 impressions. This sharpens the existing thesis (Honey-Doers converts people who already know the name) into something starker: right now the non-brand city-page channel isn't just underperforming, it is producing no measured clicks at all on its own tracked terms. Per Operating Rule 9, these pages are still ~13 weeks old and E1's actual link treatment hasn't shipped — so this is the honest starting line, not a verdict on the lever.
The wrong-page findings are a free, non-experimental fix. Six tracked queries resolve to the
wrong URL — most visibly Apple Valley's basement query landing on the city hub instead of the
service page, and both Lakeville queries and both Minneapolis queries landing on / or a service
hub. Fixing internal linking/canonicalization so these resolve to the intended page doesn't touch
any experiment arm (it's correcting an error, not adding a treatment) and could recover impressions
that are currently misattributed. Worth a session on its own.
node scripts/seo-baseline.mjs compare <new-gsc-deep.json> prints treated−control differentials
per experiment arm against this frozen baseline, and refuses a verdict before 8 weeks
post-enrollment (enrolledAt = 2026-08-19, set the day E1's link treatment shipped).
Re-run city-page-uniqueness.mjs after each Phase 3 city ships to track the 60-of-104 →
~92-of-104 march; log the count here at each monthly pull rather than only in
LOCAL_PAGE_REMEDIATION.md.
At each quarterly review, append a new dated block to Verified State above rather than editing the existing one — this section is a time series, not a snapshot.
Organic conversion rate — new standing metric, added 2026-08-22. Pull GA4 Organic-Search
sessions and form_submit+phone_clicks events by yearMonth, roll up to quarter, append a row
below. Baseline series (GA4 ground truth, stats-dashboard/scripts/fetch-ga4-monthly-trend.mjs):
| Quarter | Organic sessions/mo | Organic leads/mo | Organic CVR |
|---|---|---|---|
| Q1 2025 | 1,342 | 20.3 | 1.51% |
| Q2 2025 | 1,159 | 21.7 | 1.87% |
| Q3 2025 | 905 | 27.3 | 3.02% |
| Q4 2025 | 465 | 22.7 | 4.88% ⚠️ bot-contaminated total-lead quarter; organic figure itself not excluded but treat cautiously |
| Q1 2026 | 410 | 21.0 | 5.12% |
| Q2 2026 | 374 | 26.3 | 7.05% |
| Q3 2026 (partial: Jul + 22 days Aug) | 416 | 40.5 | 9.74% |
Provisional until I1 ships. These leads are form_submit/phone_clicks — any submission, not
verified success. Once lead_form_success is live, recompute this whole series against
verified-success events only before treating the rising trend as confirmed rather than directional
— see I1 in Now.
The thesis this all tests: Honey-Doers converts people who already know the name; the growth surface is the ~25K non-brand impressions producing 46 clicks sitewide (this freeze shows none of them land on the 29 tracked city-page queries specifically), concentrated in basement remodeling by city, where the right pages already rank page 2 in priority cities. Reviews can't buy local-pack placement outside the Lakeville radius, so organic city pages are the only winnable placement — and I11 existed because those pages looked deep by word count but were ~95% boilerplate before remediation, which is a plausible reason page 2 hasn't moved yet. The frozen baseline above is what E1's actual link treatment will be measured against.
Publish cadence: 3×/week (Tue/Thu + one exterior slot), changed 2026-09-04 from the standing Tue/Thu 2×/week set 2026-08-17. The third slot is dedicated to working I12's Compass Exteriors blog backlog (~85 posts categorized in COMPASS_REDIRECT_MAP.md) now that Phase 1 gives that content somewhere real to land — not a general capacity increase. Four picks shipped 2026-09-06 (roof flashing, window sill, deck skirting, roof ventilation); repeatable pick process and both conditions for reverting to 2×/week (backlog empties out, or the quality filter stops finding a real gap — whichever comes first) are in COMPASS_REDIRECT_MAP.md § Picking the next exterior-slot post — don't re-derive either the process or the sunset call from scratch here.
| Rhythm | Actions |
|---|---|
| Per session (while I11 is active) | Top unticked city from the I11 work queue; close with node scripts/city-page-uniqueness.mjs --cities <city> |
| Weekly | GSC anomaly glance; confirm 30-day publish runway; check I11 progress against freeze date |
| Monthly | gh workflow run fetch-analytics-data.yml; seo-baseline.mjs compare once frozen; regenerate TOPIC_MAP; update this file's Now/Next/Later/Someday buckets |
| Monthly | Ahrefs Site Audit → Link Explorer broken-links export, remediated against the live site. Most flagged rows are Ahrefs' bot getting blocked (403/406/429/401 from Houzz, JLC, EPA, HGTV, ScienceDirect, etc.) — verify each domain with a UA-spoofed curl (and a real browser tab for stubborn ones) before touching anything; only chase rows that are still broken for a real user. Genuine hits are usually one of: an old category-path redirect that dead-ends because a post slug changed since migration, a stray internal link, or a dead outbound citation needing a live replacement (reword the citation if the original claim no longer traces to a live source). See 2026-08-22 session for the full method and the redirect/citation fixes it produced. |
| Quarterly | Append a dated block to Performance tracking; append the next row to the organic conversion rate series; review Backlog B-questions, record any answers with their date |
| Trigger-based | Refreshes fire on decay triggers, not annually — see the post-refresh-audit skill |
Full operating rules, experiment pre-registration mechanics, contamination controls, and the append-only decisions log: Search_Strategy_Rules.md.