Grow My Ads · 1 July 2026 – 2 October 2026

Bohdan's projects

Two windows. Landing pages covers every page I have worked on since January 2026, with the client's service tier and whether the page was paid for separately. Tracking and other cover 1 July 2026 onward. Reconstructed from timestamped working prompts, my full Slack history across every client channel and DM, my client email, ClickUp, and the live containers, accounts and deployments themselves.

Landing pages from Jan 2026 Tracking & other 1 Jul 2026 – 2 October 2026 Projects 73 Total 793.6 h Updated 2 October 2026
Tracking
434.5h
43 projects
Landing pages
292.1h
22 projects
Other
67h
8 projects
Total
793.6h
73 projects since 1 July

How the hours were worked out. Two components. First, measured keyboard time - every prompt is timestamped, so I sum the real gaps between them, cap any single gap at 15 minutes so breaks do not inflate it, and merge all parallel terminal sessions into one timeline so nothing is double counted. Second, the platform work, which is most of the job and leaves no trace in those logs: GTM preview and debug, Google Ads and Merchant Center, GA4 DebugView, Meta Events Manager, Shopify admin, BigCommerce, CallRail, GHL, Marketing 360, HubSpot, WordPress, client calls, Looms, and the email threads I run directly with clients and their developers. 1 Jul onward: 283 h measured reviewed and corrected by me pre-July landing pages: estimated, not yet reviewed personal study time excluded

How each project is sized

The label describes what the work demanded — how many systems it touched, whether the cause was known at the start, and what it depended on. Hours follow from that, so the ranges below are what each level actually cost here rather than a rule applied in advance.

Quick
0.5 – 1.5 h
One system, cause already known, nothing to wait on. A check, a setting, a costed answer to a question. Example: proving why 7 CallRail calls showed as 6 in Ads.
Moderate
2 – 6.5 h
Several systems, or a real diagnosis before any fix was possible, but the path was clear once found. Often includes writing something for a client or developer. Example: consolidating CallRail into a second company and pool so two sites report separately at no extra cost.
Complex
8 – 12 h
Platforms that interact and can break each other, an unknown root cause, or a build with a live backend. Needed testing, rework, and usually a dependency on someone else. Example: fixing GA4 purchase on BigCommerce with no test purchase available, verifying against real orders over several days.
Major
13 – 35 h
Sustained work across weeks and many systems, with client or developer dependencies and real consequences if it goes wrong — money, legal exposure, or lost conversion data. Example: rebuilding an entire measurement stack so it survives a platform migration without losing a day of data.
Recurring
weekly
Scheduled work that repeats rather than completing. Hours shown are the total across the period, not per run.

Tracking

434.5 h GTM, GA4, Google Ads, Meta, call tracking, offline conversions. Sorted by start date, newest first.

Airport AssistTravel service · new website · GTM purchase tracking

4h1 Oct
Moderate Waiting on Joey and the developer 1 Oct
What I did

The client moved to a new site, so I checked the existing tracking and set up a new purchase event in GTM, using the site's own payment_success event for GA4 and Ads purchases instead of the old one. Built it as an import into a new workspace, tested it in Tag Assistant, and redid the import when the first version merged into the wrong place. It works; GTM is not published yet.

Asked Joey whether to reuse the existing purchase conversion, which has the history, or start a new one. Sent a short list for the developer: the contact form does not send enquiries anywhere and needs a generate_lead push, payment_success needs email and phone, begin_checkout always sends a value of 0, and staging bookings are reaching the live GA4 property.

McAdoo Estate PlanningLaw firm · nycestateplans.com · CallRail and phone numbers

5hStarted 24 Sep
Moderate In progress 24 – 25 Sep
What I did

CallRail stopped sending calls to Google Ads on 12 August. Checked every page on the main site, the consult page and the law subdomain for phone numbers, in links, as text and inside images, against the CallRail numbers and the website pool. The consult page was showing a business card number instead of a pool number, which I fixed myself, and I checked which keywords trigger the ads so a real user lands where we expect.

CallRail keeps no change history, so I rebuilt the call routing timeline from all 13,925 inbound calls since August 2024. It showed routing changed on 11 August, the same time the pool calls stopped and new users were added to the account, which is most likely when the pool's swap target was changed too. Checked whether two unused numbers had ever taken calls, and rechecked the ten calls with old gclids one by one rather than accept the first explanation. Left the law subdomain out on purpose and wrote a guide of what was found and what is fixed.

Ultimate FlagsWooCommerce · tracking & Merchant Center audit

24hStarted 21 Sep
Major Tracking live, feed fixes in progress 21 Sep – 1 Oct
Audit, 21 to 23 September

Ran the tracking audit call with Jonica on 21 September, then audited the Google Ads tracking and the Merchant Center feed. Purchases are not counted twice, but they are not fully accurate either. Form conversions tracked nothing. The biggest problem was the feed: 513 products break Google policy and were still being sent every day, 303 products that Google is fine with are switched off from ads, and the feed sends no product category, GTIN or MPN, with sizes and materials almost never set.

Pushed for the real source of the exclusions rather than guessing. There is no switch for it in WordPress; it is the "Show in ads" setting on each product in Merchant Center, and I confirmed it on a specific product with no issues that was still held out of ads. Reworked the Merchant Center sheet after the first version was wrong, and had the audit PDF reviewed twice by independent agents for false claims before it went out. Cut the section on what we could not reach and added what we will fix in GA4.

Tracking set up, 24 September

Jonica approved the fixes and said they only care about sales. Set up tracking in GTM for purchase, add to cart, begin checkout, phone clicks and dynamic remarketing. The new purchase conversion runs alongside the old one for a few weeks before switching over. Fixed product IDs that did not match the feed, so remarketing can show the products people viewed. Removed the old Universal Analytics tag and deactivated Google Analytics for WooCommerce, removed the form goal, and moved to Secondary the actions Google would allow. Set up the Google forwarding number, and told her it will not work until the phone number is on the site as text rather than inside an image.

Did not trust the container on my word. The first export would not import, the forwarding number script was missing, and dynamic remarketing was reading the old data layer version. I caught and fixed each one before saying it worked.

She answered the audit questions that evening: she removed most of the policy-blocked products herself, and the ads exclusions came from a previous agency.

Next: check on Monday that the new conversions are reporting, and work through the remaining feed fixes.

Hyros, ClickCease and the feed, 25 September to 1 October

Jonica asked whether Hyros would clash with the new GTM tracking. Checked and told her on 25 September that Hyros was installed but not activated, so it was sending nothing to Google Ads and not interfering, and that the Google Ads tracking templates still pointed at ClickCease, which they had cancelled years ago. She sent the Hyros login on 28 September. Went through Hyros billing, its Meta, Google Ads and Bing connections, the WooCommerce checkout link and the WordPress plugin, which reported the script missing from the domain, and checked the site header and custom code plugins for anything risky before planning the template change from ClickCease to Hyros. She also updated the Google for WooCommerce and GTM plugins on 28 September, so I checked nothing had broken.

Worked through the Merchant Center fixes from fresh product and issue exports on 28, 29 and 30 September. Tried to set Google product category through Merchant Center rules, which took hours and did not work cleanly, and confirmed from the plugin source that the WooCommerce plugin has no product category field. Built a supplemental feed in Google Sheets with a category for each product, mapped against all 439 store categories, and connected it to Merchant Center. Re-enabled the seven products still switched off from ads, unsynced one more product, and rechecked the 32 policy-blocked items against what Google actually shows. Kept titles and descriptions out of anything I uploaded, because those are the client's to change, and moved them, with lower priority items such as extra photos, into a separate client fix list stated as of 1 October.

Next: send the client fix list and switch the tracking templates to Hyros.

Magnus Home Products — account suspensionGoogle Ads billing policy

2h17 Sep
Moderate Fix given, awaiting reactivation 17 Sep
What I did

Josh's client's Google Ads account had gone dead and the interface said the client had cancelled it, which is what everyone assumed had happened. I did not accept that, because the account still showed as linked and nothing else fit, and I could find no confirmation anywhere that Google deactivates accounts the way the message implied.

Got into a chat with a Google Ads billing representative, who first said he would check and then went quiet, so I stayed with it until there was an answer. The real cause is a billing policy suspension: Google no longer accepts credit or debit cards from higher-spend advertisers, and the account had been moved onto invoicing or direct debit terms without anyone acting on it.

Got the exact remediation rather than a general direction - bank transfer set as the primary method and the cards removed from the account entirely, not merely demoted to backup - and wrote the client the verification steps for the deposit Google sends, since that is where this stalls. Pushed to get it confirmed while I still had the representative in the chat rather than losing the thread and starting again.

Then took it wider than this one client. Posted the whole thing in the billing channel with the specific wording to watch for in Google's warning emails, so anyone here seeing it on another account switches payment method before the deadline rather than discovering it the way we just did.

Clean Slate Land SolutionsLand clearing · Google Ads tracking audit

18hStarted 15 Sep
Major Lead sheet live, final tests pending 15 Sep – 29 Sep
What I did

New client off a strategy call. Ran the intro call on 15 September and the audit the next day, and delivered it as a document and PDF on the 17th with a short summary in the mail rather than a wall of findings.

Started by correcting two things the account was described with. The site is not Wix, it is a React application rebuilt three weeks earlier, and there is no GA4 property at all - checked against every property we can reach rather than taking the absence of a link as the answer. I had also been given the wrong container id, which turned out to belong to a different client entirely.

Worked out how the form conversion actually fires, which is not how the client believes it does. They think it is a thank-you page URL rule; it is a chunk that pushes the event only when the server renders the page with a real reference, so opening the thank-you URL directly does nothing. That matters because it means the conversion cannot be tested from outside without creating a real lead, and anyone checking it the obvious way would conclude it was broken.

Found what the client was actually describing when they said the account went into the ground. The form conversion signal died on 10 July and its replacement did not start until 5 September. Over that gap cost per click went from $4.21 to $21.05 and clicks fell from 1,111 to 108 on a flat budget. Told them to treat 5 September as the measurement baseline and never compare against anything earlier, because every before-and-after on this account is otherwise meaningless.

Set up CallRail with the minimum call duration for a reported conversion at 30 seconds, re-sent the invitation when the client said the link only refreshed at them, and flagged the trap for go-live: Google's own forwarding number tag has to be paused, not deleted, before CallRail's number swapping goes on, or both rewrite the same number.

Specified what the fixes need rather than describing them. For enhanced conversions, hashed customer data on submit, as a separate tag, with email and phone in a stated format and nothing else. For offline conversion import, the exact data points the client has to send - the click identifiers, conversion date and time, and value - so nobody has to guess, and no more than that. Wrote the handover for the strategist to pass on rather than as a client email, on the second attempt, after the first was aimed at the wrong reader.

Their developer had the changes implemented in a local build by the end of the window, including a 90-day attribution cookie, with publishing still to come.

Checked live, then a lead sheet with call data, 22 to 24 September

Checked on 22 September whether the developer's changes had gone live. They had not, so enhanced conversions still had no user data. Told Anna what was left: publish the changes so gclids are caught, and give us full access to their CRM so offline conversion import can be set up from it. The client published version 15 that evening.

After GTM was published on 24 September, submitted a test lead and checked the payload to confirm enhanced conversion data is actually sent and in the format Google Ads needs. Because their CRM access was not there yet, built an Apps Script and a single Google Sheet that records every inquiry and also pulls calls from CallRail through its API. Found that only 1 of 3 test calls came through, traced the filter that dropped the others, and had it fixed, since the only rule is calls over 30 seconds. Had the script reviewed by a separate agent before handing it over. Sent Brad a file to paste into the ChatGPT thread his site was built in, with a shared secret so only his site can write to the sheet. He published it the same day and it is ready for final tests.

Sheet connection finished, 25 to 29 September

Checked the Apps Script the site was actually running against my version, fixed the call filter so every voicemail is kept and only calls under 30 seconds are dropped, fixed the time zone mismatch between the script and the sheet, and tested with a manual submission through a UTM link. Added two conversions to Google Ads on 25 September, with only Converted lead Purchase importing a value, and the sheet syncing daily. On 29 September Brad's developer flagged a security point, so I had the script reviewed again by a separate security agent, rotated the shared secret and sent it through a one-time link rather than by email.

Hardwoods4LessShopify · flooring samples · tracking audit

13.5hStarted 15 Sep
Complex Form conversions added, Google app waiting on client 15 Sep – 28 Sep
Access first, 15 to 16 September

Josh asked me to send a Shopify access request to the client's store. Shopify wanted identity verification to do it from our side, which nobody here had hit before, so rather than sit on it I checked what the request actually requires, said it would be quicker for him to ask the client directly, and then sent the request from my own account once that route was confirmed. Confirmed what access had and had not arrived rather than waiting to discover the gaps mid-audit.

The audit, 17 September

Found purchases counted twice in Google Ads. Two purchase conversion actions are both set to Primary, one from the Google tag and one imported from GA4, and Google only removes duplicates within an action, never between two of them. Proved it arithmetically rather than inferring it from a ratio - the five Primary actions sum exactly to the account's conversion total. Checked GA4 itself before blaming it and it is clean, every transaction id appearing exactly once, so the duplication is created in Ads, not in Analytics. The fix is to demote the imported action, not delete it, so the history survives.

Flagged the thing that would cause real damage if nobody said it: this is a sample store with an average order around $9, while the real revenue comes from quotes and phone calls. It is a lead generation account wearing an ecommerce costume, and setting a return-on-spend target off $10 sample orders would be a serious mistake.

Lost time to something worth recording. The store runs a region blocker that redirects non-US visitors before any tag fires, so a browser audit from outside the US shows no tracking at all and reads as a total failure. Worked out how to get past it to see the real page. Also established the Google tag is loaded by their HubSpot pixel rather than by any Shopify app, which is not where anyone would look for it.

Left two things open honestly rather than closing them: Shopify admin is still not authenticated, and Merchant Center has not been reviewed - and the Shopify Google app must not be connected until the current feed source is confirmed in writing, or the feed they have now could be replaced.

Form conversions and the Google app, 18 to 24 September

Built the conversions the strategist actually asked for, Google Ads only and nothing in GA4 yet: Contact Form and Click For Quote as new form conversions in Shopify Customer Events, grouped, with Event Sign Up and Newsletter Signup left out on purpose. Kept the code in a customer pixel rather than the theme files. Told Josh that GA4 purchase has to move to Secondary so it stops doubling the Google Ads purchase, and offered a separate Customer Events purchase conversion as Secondary to verify against. Also found that HubSpot already stores gclids on form submissions, so an offline conversion import from HubSpot is possible later.

Josh wanted the Shopify Google app synced again. Did not connect it, because reconnecting can overwrite product IDs and the account Shopify offered did not include the Merchant Center we need (9353960). Took it to Anna first, then worked out that the only way to connect the right Merchant Center is to log in to the app as the store's only Super Admin, and asked Josh on 21 September to get the client to do that. Still not connected on 24 September, so I chased it.

Waiting on: the client logging in to the Shopify Google app as Super Admin.

CallRail and GA4, 25 to 28 September

Checked every page for phone numbers, including numbers inside images that CallRail cannot swap, then added the CallRail swap script to the Shopify theme as a single 3-line change, verified the live file and storefront, and found the PRO Desk number on two pages as plain text. Three days later confirmed GA4 was collecting properly again, unmarked four GA4 key events that were dead or inflating the count, and left phone calls unmarked to avoid double counting with CallRail. The duplicate purchase came back as predicted, so I recommended setting the GA4 purchase to Secondary and promoting the tag-based quote request lead, which caught twice as many.

Children's Ministry DealsSalem Church Products · Shopify · tracking audit

9hStarted 11 Sep
Complex Audit delivered, access requested 11 – 17 Sep
What I did

Returning client at roughly $39k a month in Google spend. Kickoff on 11 September, audit run on 16 September, delivered as a document and an eight-page PDF ahead of the strategy call.

The client asked us to confirm there were no issues plus answer two specific worries. Both answers turned out to be more interesting than the question. They were right that free checkouts fire the purchase tag - 1,603 of their 3,577 products are $0.00, and 78% of purchases attributed to paid channels are free downloads. I verified that by matching every zero-revenue order line to a real $0.00 catalogue product, rather than reporting it as a missing-value bug. But it is not corrupting bidding, because every live strategy is value-based and a $0 order carries no value, and not one dollar of Shopping spend went to a free product. The landmine is the four paused campaigns set to maximise conversions: switch any of those on and the account starts buying free downloads immediately. So the worry is true in the reports and false in the bidding, and both halves had to be said.

Found something they had not asked about and did not know. Shopping went dark three times, not once. They knew about the 13-day outage in June; it recovered, then went dark again for another 13 days that was never reported, about 25 dark days and roughly $42k of revenue not earned at their own baseline.

Separated the ROAS decline from the outage rather than letting it absorb the blame. Shopping ROAS fell as spend tripled, which is scaling, and year on year this autumn is actually slightly ahead of last. Search holds a far better return on a fraction of the budget but is mostly branded, so I said to split branded from non-branded before moving any money.

Checked a claim before repeating it. Sixteen ad groups carry a Triple Whale tracking template, and the obvious finding would have been that its query string breaks the landing page URL. It does not - Google rewrites its own separator when the final URL already has one - and I verified that against real production URLs and a scan of three and a half months of page addresses before saying so. The real problem is coverage: a third of the live ad groups have no template at all. Asked the client whether Triple Whale is still in use before proposing we touch it.

Answered the strategist, 17 September

Answered Cai's three questions with the evidence rather than a yes or no. Confirmed only purchase reaches bidding, proved at the campaign goal level rather than from the Primary flag, which is the stronger proof. Confirmed the feed came back clean after the outage, every serving product matching a live product. Said the part that is not clean: the purchase event sends no product ids at all, so purchaser exclusion and cross-sell audiences cannot work.

Named exactly what access is still missing and what each item unblocks, instead of asking for everything. Tag Manager access was granted once and disappeared, and without it, Merchant Center and Shopify customer events we cannot examine dynamic remarketing properly, fix enhanced conversions (currently sending name and address in a format Google discards), split free from paid orders into separate conversion actions, or remove a dormant conversion tag sitting in their container.

Pump SupermarketWooCommerce · conversion count reconciliation

8.5hStarted 11 Sep
Complex Fix specified, awaiting WordPress access 11 Sep – 28 Sep
What I did

The strategist reported Google Ads conversions falling, and separately that in May GA4 credited Google Ads with more purchases than Google Ads credited itself. Both turned out to be wrong readings of real data.

Found the trap first. GA4 has two purchase-like key events, and the second one fires on every load of the order confirmation page with no deduplication, so it inflates by 50 to 70%. One order fired 23 times across 23 separate sessions because customers keep reopening the confirmation link from their email, and each reopen creates a new session with a new source. That single event explains the May discrepancy exactly. Because both are flagged as key events, GA4's headline total is roughly double the real order count.

Cleared the Google Ads tag rather than leaving it under suspicion. It is the only purchase action counted, and its ratio against GA4 has sat in the same narrow band every month for a year, which is attribution modelling and cross-device, not a break. Ruled out double firing two separate ways, including by checking that the average order value it reports matches the site's, and established that the 90-day window is a red herring since three quarters of conversions land the same day.

Then found the one real problem: GA4 misses about 14% of orders outright, which also means the summer decline everyone was looking at is an artifact - the backend is flat.

Root cause, proved from their own served JavaScript. WooCommerce's attribution cookies are configured with a lifetime that rounds down to zero, which makes them session cookies, so they die when the browser closes and the buyer comes back as direct. That is the WooCommerce default, not a misconfiguration on their side. Three more leaks sit behind it: the order only ever reads the most recent source, so an organic return overwrites the ad click; Apple Pay and Google Pay create the order without submitting the form that carries the attribution, which is why the fix has to read the cookie server-side rather than a hidden field; and their attribution library only recognises one kind of click identifier, so ad clicks from iPhones are filed as organic.

Specified the fix as a small plugin covering all of it, and refused to promise what cannot be delivered: cross-device buyers cannot be closed by any cookie, so the honest promise is a floor, not a gap of zero. Gave the strategist the method as well as the answer - GA4 undercounts, so never compare its raw count to the backend; use it only for the channel share, apply that to the true order count, then compare. Two of the three months reconciled to within 5%. Also corrected my own earlier claim that Google gives partial credit when the last click is organic; it books a full conversion for any ad click in the window, and I proved it from the shape of the numbers the API returns.

Purchases falling, 28 September

Cai raised that purchases kept dropping while thank-you page views in GA4 did not. Rechecked GA4, Google Ads, GTM and WooCommerce and confirmed it could not be explained by the count method. Asked for four 99% discount codes for test purchases with and without variants, and for full WordPress admin, since we only had WooCommerce Analytics.

Waiting on: discount codes and WordPress access.

Launch Family EntertainmentGHL account handover off our subscription

1h9 Sep
Quick Options with the client 9 Sep
What I did

Luke asked whether we still use GoHighLevel at all before cancelling it outright. Checked what is actually running in there and found one client account, this one, sitting under our subscription, so cancelling would have taken their CRM with it.

Found the client channel and wrote the handover for Miles with the two real options: transfer the existing account to their own GHL login, or start a fresh account and move the data across. Put the cost change up front, $97 a month billed to them directly where we had been covering it, rather than letting them find it after agreeing. Held the detailed steps until they pick a path, and sent through the eject-to-a-new-agency route for the transfer itself.

Custom Sticker ShopWooCommerce · purchase tracking & dynamic remarketing

5hStarted 4 Sep
Moderate Rebuilt and published, IDs still unmatched 4 – 9 Sep
The blocker, 4 September

Google Ads reported that 100% of sold item IDs could not be matched and two dynamic remarketing audiences sat at zero. Traced it to the same product existing under three different IDs: the raw WooCommerce ID the website sends, and two Merchant Center feeds that each wrap it, one as woocommerce_gpf_251999_MAN and the other as woocommerce_gpf_251999. Established why the obvious fix does not exist before proposing anything, since only one ID can be sent per product, so sending both would make Google double count sales and remarketing, and fixing one feed leaves the other reporting nothing. Checked whether the site could send the suffixed and unsuffixed values together, including whether WordPress could carry it, and confirmed it cannot.

Wrote the decision up for Cai with the question to put to the client, which is why the same catalogue is uploaded twice at all, given the suffix only exists because Merchant Center refuses duplicate IDs, and what to ask if their developer cannot merge the feeds.

Also found that add to cart and begin checkout stopped recording on 16 and 17 July, when the previous agency's tracking came off, and that purchase itself was fine, with orders and revenue correct and no duplication. Said that plainly so nobody spent time on a purchase problem that did not exist, and took the question of whether the client cares about the polluted add-to-cart and begin-checkout history to the strategist rather than deciding it myself.

Rebuild, 7 September

Cai came back confirming the client is migrating to the CSS all products feed, so I built against those IDs. Product IDs, prices and quantities now go to Google Ads on purchase, add to cart and checkout start in the CSS feed format, add to cart and begin checkout are rebuilt, and dynamic remarketing is built, all in GTM and published. Wrote Cai the short version of what was broken and what was fixed so he could use it in client onboarding, and said I would check it over the following two days rather than calling it done.

9 September

Checked, and it is not proved. The 8 September orders still carried no product IDs and the match rate was still zero, so the fix is not reaching live purchases the way the preview said it would. Open at the end of the window, including whether the discount value needs a variable of its own.

Lamp BoyShopify · PMax build + enhanced conversions & dynamic remarketing

8.5hStarted 25 Aug
Complex PMax live, tracking fixes verifying 25 Aug – 8 Sep
What I did

A Navigator client where the strategist's audit had already been sent, so my job was turning it into work done: fix the tracking, then build the campaign the audit specified. Read the audit and the whole client email thread first and turned it into an action plan, rather than working from the audit alone - and when the two disagreed on budget I went with the email, because it came after.

Enhanced conversions and dynamic remarketing

Google's dashboard rated their enhanced conversions "Excellent" while coverage was about one purchase in ten. The cause was on the site, not in the account: the purchase event was passing no customer detail through to Google at all. Fixed that. Dynamic remarketing was sending nothing whatsoever - the code had never been configured to send it, and the product IDs it would have pulled no longer matched their Merchant Center feed anyway. Fixed both and tested live to confirm the right IDs now go out.

Chose to put dynamic remarketing in a separate Shopify customer pixel rather than bolting it onto the one handling GTM and enhanced conversions, so the two cannot break each other. Checked the existing customer pixel and GTM container export against the events in Google Ads to establish what was actually missing, and worked out whether enhanced conversions can pass real customer data out of Shopify's pixel sandbox at all before building on the assumption that it can. When the code found checkout.email empty I traced it to Shopify's protected customer data scopes rather than blaming my own code. Declined to place a test order at the client's cost, so this is verifying on real orders over the coming days - and I said that in the client email instead of implying it was confirmed.

Also verified the conversion settings while in there: purchases correctly set as the account default, and only one purchase action counting, so no double-counted sales. Had the whole tracking and remarketing setup reviewed by two independent agents, one Claude and one Codex, and fixed what they found.

The feed-only UK PMax build

Built UK PMax - Feed Only (GMA) paused, for the client to review before switching on. Wrote myself a step-by-step build guide first, then corrected it repeatedly against what the 2026 Google Ads UI actually shows - the campaign-type screen has no website URL field, the bidding screen was nothing like the guide claimed, and brand exclusions were not where the guide put them. Fixed the guide each time rather than improvising past it, and cut it down to instructions for me only, since the specialist checks the live setup in the account. Worked through the asset-group screens, the listing group, a Final URL validation error, and keeping it a draft rather than publishing it live.

On bidding I did not just follow the audit. It specified Target ROAS 300% from the start; the strategist said Maximize Conversions first. I took the conflict to both of them with the client's Loom rather than picking one, asked the follow-up question that mattered - how many conversions are enough to switch safely - and the audit author agreed the tROAS target had gone in by mistake.

Reviewed their product export and all feeds to work out how dynamic remarketing should be structured across countries when the campaign is UK-only, and asked the strategist about the nineteen existing audiences before adding any.

Wrote the client email myself: campaign built and paused, both tracking fixes explained in plain terms, and an explicit note that we are waiting on Google Ads to reflect the dynamic remarketing data and will check back next week rather than closing it out.

29 August. Ash switched the campaign on himself and came back thanking us for the tracking fixes as well as the build. The enhanced conversions and dynamic remarketing fixes are still proving out on real orders, so this is running rather than closed.

8 September. PMax had 9.33 conversions in ten days and was flagged limited by budget. Rather than approving a scale-up on that, I took it to Anna with Ryan's threshold attached, which is 25 or more conversions in 30 days before moving off Maximize Conversions to Target ROAS, and asked where the client's ongoing Shopping questions should go now that the build is finished. Answer was Navigator, so I chased how that process is actually set up for this client instead of pointing him at a channel and hoping.

Prestigious EntertainmentEvents · prentusa.com · GHL call tracking

25hStarted 24 Aug
Major Fixed, watching conversions 24 Aug – 1 Oct
What I did

New client, tracking audit booked off my own audit link. Ran the intro call, then worked through their setup on prentusa.com against their existing container (GTM-N2TNJT2H). Set the tracking template so UTMs carry campaign, ad group, creative, keyword, device and match type off the click, and submitted their website inquiry form myself with a tagged test address to confirm the submission actually lands rather than trusting the tag preview.

The call tracking problem

They run calls through GoHighLevel, and the question was whether GHL's own call tracking can replace CallRail. It cannot, and finding that out took the most work here. Established where their call history lives and how to export it, whether the number in the account is actually the GHL number, and that outgoing calls have to be excluded from any call-tracking count the way CallRail does - checked against documentation rather than assuming GHL behaves like CallRail.

The blocker is routing. Five people are currently rung simultaneously on their existing forwarding number, and GHL number pools cannot inherit that "Calls Go To" behaviour, so switching would change how the client receives calls today. Found the open GHL feature request confirming the limitation, including the report of it saving once and then erroring on edit, and sent the client the link rather than paraphrasing it. There is no support chat on this account, so every answer had to be sourced.

Priced the alternatives honestly instead of quoting a round number. Corrected my own CallRail figure downward - $55 for five numbers plus $3 per additional local number, starting at four and scaling to twelve, not the $140 first stated - and checked whether the Twilio relay-number workaround at roughly $35 is actually confirmed by anyone before offering it. Wrote the trade-off up in plain language for the client, because the real decision is theirs: either change how they currently accept calls, or pay for CallRail. The one thing I would not risk was breaking how five people answer the phone today.

CallRail account stood up, 1 to 3 September

Chased Anna for the new CallRail account and gave the client a firm date rather than leaving it open. Anna created the account and invited Josuah directly. Set the account timezone, which took working around the fact that CallRail has no New York timezone option in its list.

Calls arriving in GHL with no source

Calls were landing in GHL contacts but with no source and no UTMs, and the counts did not agree: CallRail recorded three calls for 2 and 3 September while GHL recorded six new contacts. Worked through where the extra GHL contacts come from and what would have to change for source and UTM data to reach the contact record.

Wrote the reply to the client's message point by point. Corrected the record that CallRail swaps numbers for the website and the Google Ads call asset only, not for Maps or other listings. Rewrote it twice on my own read: the first version read like a developer document rather than an answer to a client, and the tables in it would not have been legible, so those became plain sentences or screenshots.

Scoped SMS deliberately rather than dropping it. We are not sending anything; the requirement is only that an SMS to the CallRail number forwards to the GHL number and shows up there, so a lead who texts the number from a paid click is not lost.

Enhanced conversions on WordPress

Rejected my own first build of enhanced conversions as too complicated. Without GTM access the tag had to go in as custom HTML, so I checked first whether the Elementor form could be handled the simpler way before accepting that. Settled on firing the update tag on the submit button so it subscribes to the event on the thank-you page, rather than the heavier setup. Reviewed the exported GTM workspace (GTM-MM3ZHZ) against what is actually on the WordPress site and wrote a step by step verified setup. Handled an inconsistency where the form sometimes redirected to a thank-you page and sometimes did not by also firing on the form submission event, and kept the cookie and UTM persistence code in so values survive to submission.

Written for the client, 28 August to 3 September

Sent the audit as a document with a short summary in the mail rather than a wall of findings, covering Google Ads, GA4 and GoHighLevel and flagging that enhanced conversions were blocked on JotForm access. Ran the call, then sent the recording back as a Loom so Josuah had something to refer to. Set up his CallRail numbers and sent the list of which number shows where. His invitation would not open, twice, including in incognito, so I resent it from the account until it worked instead of leaving him to fight it.

He then challenged the cost, fairly, and asked whether he was paying twice. Instead of defending the estimate I measured it: three calls in the first two days, one just over six minutes, one about a minute and a 36-second robocall, which with CallRail's rounding up to whole minutes projects to 100 to 150 minutes a month against the 250 already included. Gave him the real bill, $56.50 as the $55 plan plus a $1.50 carrier fee for texting, and explained why the $140 worst case he could construct is theoretical rather than a risk. Priced WhatConverts, Nimbata, native GoHighLevel and a fixed number per campaign so he could compare rather than take my word for it. Conceded the part of his challenge that is true - he is paying a second time for a number, a recording and a call log - and separated it from the part that is not, since GoHighLevel charges him nothing extra.

Made clear how little of his phone traffic CallRail touches at all: tracking numbers only show to paid-ad visitors, so Maps, organic search, repeat customers and referrals never see them, out of 460 to 620 calls a month. Then gave him the number he had not asked for and needed most: across July and August only 56 of his 290 first-time callers reached a person. Four in five hit voicemail or nobody, which is a far bigger leak than the tracking bill.

He also replaced the JotForm booking form with an Elementor one mid-setup, so I reconfigured the form submission tag and added the enhanced conversion tag against the new form. Told him plainly what I could not verify without WordPress backend access - whether the hidden attribution fields are on the form - and set out that the GHL contact is created by a workflow but attribution only reaches the contact record once an incoming webhook is added and mapped, which I had already walked him through on the call.

8 September. Put a real request through the client's own booking form to confirm the rebuilt form tracking fires end to end on a live submission, rather than trusting the preview.

CallRail decision and GHL fields, 14 to 17 September

Two days before the trial expired I gave Josh the decision with the numbers attached rather than a reminder: 20 calls in a fortnight, 6 of them qualified. He confirmed he wanted to keep CallRail and paid for it. He also thought the Loom I had sent had no audio; it was his end, but I checked before assuming that.

He then created the custom fields in GoHighLevel himself and asked me to check them, including one field name GHL would not accept. Went to verify the whole path end to end and could not log into his GHL at all - the confirmation goes through but the session never lands - so I built a test link, submitted the form through it myself, and asked him to check what arrived on his side rather than guessing which half is broken.

Attribution fields found empty, 18 to 22 September

Josh said the new GHL attribution fields showed up blank. Tested again with a tagged test link and checked where the ads land, and confirmed the form saves the attribution data correctly. Told him that if the form has the data and the Zap has it too but the contact does not, the break is in the Zap. He checked and it was: the new custom fields had not been mapped in the LeadConnector step.

Lost form conversions and the backfill, 27 September to 1 October

Josh found Google Ads had recorded about 5 of roughly 28 form leads with a gclid from 24 to 28 September and sent me what his Claude had concluded. Confirmed the main cause on 28 September: the 22 September change moved the conversion from the thank-you page to the moment of submit, and the browser was leaving the page before the hit went out, losing about 28% on desktop and 89% on mobile. Reverted it to the thank-you page the same day and explained the effect on automated bidding.

He wanted the missing week back, so I created a one-time conversion action, Website Form Backfill GMA, and a Google Sheet for the upload, built from GHL contact exports with Google Ads time format and hashed email and phone, and listed which gclids were too old to use. The backfill was working on 30 September. The live conversion still was not recording, so I asked for WordPress admin.

Logged in on 1 October and found two real problems. The Seraphinite speed plugin was holding GTM on the thank-you page until the visitor moved the mouse or touched the screen, so a lead who closed the page counted nothing. And my helper script for enhanced conversions sometimes made the conversion tag fail. Replaced the helper with one footer script that passes the hashed email and phone on form submit, added four Seraphinite entries so Google's tags, that script and his header attribution script load immediately, left his header script untouched, and tested it myself and then with a manual submission before telling him. Added the remaining missing leads to the backfill. Explained to Austin and Anna what had gone wrong, including my own part in it.

Golf Cart PartsShopify · new tracking audit

10.5hStarted 20 Aug
Complex Code and access Loom sent 20 Aug – 22 Sep
What I did

New client. Ran the intro call with Anna and the owner, then sent the access request the same afternoon as a short list with a Loom per item rather than a paragraph of instructions. Access came back within the hour, but Customer Events was still missing, which is the one part the audit actually depends on. Instead of asking again in the same words, I checked what the owner would be seeing and pointed him at the permission, which sits under settings rather than in the section the Loom covered. He rebuilt the profile and it went through.

Also set up dedicated booking links for tracking audits and LP deployment calls, so this does not have to be arranged through a strategist's calendar next time.

The audit, 26 August

Ran the full review and the finding was that nothing is broken - which I checked hard before saying, because "it all works" is the easiest conclusion to get wrong. Reconciled the August online-store order count in Shopify against what tracking captured and got an exact match with no duplicates. Verified add to cart, begin checkout, add payment info, product views, page views and site search all firing. Confirmed GA4 revenue reconciles to Shopify and that the Ads link is correct, and that click tracking passes through with nothing duplicated or conflicting.

On dynamic remarketing I had it backwards at first and corrected myself: the product IDs are present site-wide and match the Merchant Center feed, and 3,613 individual products earned impressions over eight weeks, which proves the match in practice rather than on paper. Left it alone rather than "improving" a working setup, including declining to add collection-level remarketing, since it runs through the Google & YouTube app and reconnecting GA4 there risks double tracking.

Explained the "misconfigured" conversion flag in the client's terms: Google raises it when a conversion has had no data for a while, and their last order was 18 August and was recorded, so it clears itself with the next sale. Checked GA4 for actual submissions before saying so.

What I recommended adding: the per-product enquiry form and the contact form, which Google Ads cannot currently see. Wrote those into the audit document with the conversion labels ready to paste, and put call clicks in GA4 only. Then had the whole customer-pixel setup reviewed by two independent agents, one Claude and one Codex, and reworked what they caught. Delivered as a PDF with an explicit section on what the client still has to check manually and what is broken listed first.

Also flagged the thing the audit could not fix: the real constraint on this account is purchase volume, not measurement - Google's bidding is seeing fewer completed purchases than it needs to optimise confidently. Said that outright instead of leaving a clean report to imply everything is fine.

Waiting on: one Shopify permission - Manage and add custom pixels - to install the form tracking. We only hold View customer events, which inspects but cannot change.

Action plan and campaign review, 10 September

Pulled the account and the call history into two documents: one with the transcript and the current state, one an action plan. Restructured the plan on review so the first table lists the campaigns that exist now and what each needs, with removed campaigns dropped out of it rather than left in, and the campaigns to add in a second table. It reads as a decision list instead of an inventory.

Had the feed-only PMax build ready apart from the budget, and took that to Anna rather than picking a number, along with the CallRail confirmation for the client email and whether the call insights belong in front of the client at all. Checked the two live campaign budgets against what Luke actually said instead of carrying over a number I had assumed: Golf Cart Lithium Batteries is at $1 a day and stays there until tracking is verified and Austin has reviewed the account, and the Catch All Entire Store campaign has no stated condition for unpausing, so I said so rather than inventing one. Anna's call was that the product feed needs optimising before a feed-only campaign is worth building, so PMax is on hold.

Tracking code and access, 22 September

Jeremy wants the Google forwarding number, not CallRail, for now. Wrote the code as copy-paste files only: a customer pixel for the form and click-to-call conversions, and a separate file with the forwarding number snippet for the theme, because a customer pixel cannot change the live storefront. Put the instructions in the email rather than in the files. We still cannot edit the theme or create customer pixels, so I recorded a Loom on how to expand our access and offered the code for him to install himself.

Waiting on: theme and customer pixel access, or the client installing the code.

Retirement InvestmentsAffiliate finance · Google Ads conversion audit

5hStarted 13 Aug
Moderate Cleanup approved 13 – 19 Aug
What I did

Asked to check whether the tracking on the ad account was correct. It was not, in six separate ways, and I wrote them up as a spreadsheet for client sign-off rather than deleting anything first. Only two conversions were working properly. Goldco Clicks was counting four different partners at once, Advantage Gold had recorded zero clicks since it was created, Goldencrest Metals had no attribution at all, and single clicks on Augusta, Birch Gold and Noble Gold were each firing two conversions, so the numbers the account was bidding on were inflated.

Went past the conversion list into the URL layer, where the real problem was: the account-level tracking template conflicts with the ad-level final URLs and produces duplicate utm_medium and utm_campaign parameters, four parameters that do nothing, and two that clash with hardcoded affiliate IDs. Rather than rip it out, I asked what the template is for and whether their attribution tool needs any of it, because breaking affiliate tracking to fix Ads tracking is not a win. Same for two LinkClicky conversions still enabled for bidding with no data in twelve months.

The client's answer settled it: only the wecantrack purchase matters, the UTMs are not needed, and LinkClicky can go. Confirmed the scope back before touching anything, since it now also means clearing Google Ads goals and GTM, not just the conversions. Separately flagged that this client's Metrics profile has the wrong website on it.

GA4 estate cleanup & delegationInternal · account limits, dynamic remarketing handover

4hStarted 13 Aug
Moderate Ongoing 13 – 20 Aug
What I did

Two things that turned out to be the same thing. Clients kept hitting GA4's accounts-per-user limit when trying to share access with us, which blocks onboarding, and the only fix is knowing which of the accounts we hold are dead. Exported the full list of accounts and property IDs to a sheet, then worked through it rather than bulk deleting: kept Laser Eraser's four properties despite the duplication, because they genuinely run four sites advertising nearly the same thing, and kept pumpsupermarket, which is a current client that had been marked for removal. Set the rule that an unidentified property is only safe to delete if it has never collected data, and had the remainder marked in the sheet for me to check rather than decided by someone without the client context.

The other half was handing work over properly. Ran a call on dynamic remarketing with Oleg, recorded Looms for the current ecommerce client list and the reviews sheet, and got him access to the recordings. Asked him to move his task questions out of DMs and into the public thread, so the work he is doing is visible to Luke and the rest of the team rather than only to me.

Digestive WarriorShopify · Google deprecation notice

1.5hStarted 13 Aug
Quick Diagnosed 13 Aug
What I did

The client forwarded a Google notice about a deprecated tag configuration on the store. Rather than ask for admin access first, I established what was running from the outside: read the live storefront, the Google Ads account and the GA4 link, and mapped the two parallel Google setups the store has - the Google & YouTube app pixel, which is the configuration Google wants, and four custom pixels alongside it.

Confirmed the theme is clean instead of leaving the client searching for something that isn't there: no hardcoded tag manager or gtag anywhere in the home, product, cart, collection or page templates, and GA4 fires exactly once - loaded the site in headless Chrome and read the network log, because a second implementation anywhere would show as a second hit. With no checkout.liquid, no order-status scripts and a clean theme, the non-standard configuration Google flagged is the custom pixels, since that is the only non-app path left on the store.

GMA Guaranteed Growth funnelInternal · training.growmyads.com VSL A/B

37hStarted 6 Aug
Major Lead gen page tracked, offline events planned 6 Aug – 30 Sep
What I did

New internal funnel, asked for at short notice with a hard deadline before the requester goes away for ten days. Two VSL pages running identical copy so the A/B test measures the video angle alone, then a qualification survey, then a live calendar and a booked call.

Reviewed the pages while they were still on the Netlify preview and said plainly that the tracking would be rechecked once they were on the real domain, since there's no point tagging a temporary URL. Flagged that GTM has to be on the pages to push custom form events, and chased the repo access through two people to get it.

Mapped the funnel into the seven points it can actually be measured at — step 1 answered, contact details captured, all eight steps submitted, qualified and calendar unlocked, failed with a reason, a time clicked, booking confirmed — and put that list back rather than guessing which ones matter. Settled on two Meta conversions: Lead on the partial submission where phone, email and website are captured, and the confirmed booking on the thank-you page. Also established it needs to be a separate Meta campaign from the existing low-ticket funnel so the two don't share optimisation data.

Note for later: the pages are copied into the training-site repo by a sync script, so any pixel or tracking change has to go into the source repo or it gets overwritten.

The repo nobody's version matched, 10 to 12 August

Before writing any tracking I compared the committed source repo against what was actually serving on the live domain, and none of the six files matched - the repo held a 8-step form, live was running 6 steps, and the live app.js was newer than either repo. The sync script copies from a developer's local disk, so the deployed version existed only on his machine and any commit of mine would have been reverted by his next sync. I found that by checking rather than trusting the README, which says the source repo is the source of truth.

Handled it without making it his problem to solve: committed a baseline byte-identical to the five live files, added tracking on top as a separate commit so the diff stays honest, and pushed to both repos so they were in sync for the first time. Then wrote him a short Slack message plus a file his own AI agent could run - one that verifies his local files match live before changing anything and stops if they don't. Cut the message down twice; the first versions were written for me, not for him. Reviewed and corrected his own explanation back to him too, because "make sure my local copy is up to date" would have been read as an instruction to overwrite his new work.

Verified the GTM loader, noscript and dataLayer live on all four pages, with both Meta-mapped events firing and zero direct pixel calls, keeping the pixel in GTM as intended.

Why the server-side events reached nothing

Events fired on the page and arrived at the tagging server but never reached Meta. I drove the real funnel and captured the actual payload - hashed email, hashed phone, both Meta cookies and an event ID, correctly formatted - which proved the page and the web container were fine and moved the search downstream. Diffed our request against a training event that does work and established ours was a strict superset, so the transport was not the problem either.

The cause was the server container: its Meta tag is triggered on three specific training event names, so Lead and Schedule arrived with nothing listening for them. I had no access to that container and said so rather than producing another theory, and gave a two-minute bisect to confirm it. Both now land in Meta as genuine standard events from the server, not custom ones. Along the way I dropped two of my own recommendations: the extra event-data fields go nowhere unless the server tag maps them explicitly, so only the event ID was worth adding.

Researched rather than asserted: when asked why both a web and a server leg are needed, I went and got Stape's and Meta's own wording on deduplication with citations instead of calling it best practice, and confirmed the Data Tag transport already chosen was one of the two documented options - so nothing had to be undone.

Which repo actually serves the page, 20 August

The question of where training.growmyads.com/video-a is deployed from had been answered three different ways, so I stopped arguing about it and tested it: pushed an invisible marker into the repo, loaded the live page, and read the source. The live page comes from Luke's repo, not from the local copy on Alex's machine, which is why tracking kept disappearing. Reverted the marker straight after rather than leaving debris in a live page.

Open, 27 August. The booking system was switched to OnceHub and a new thank-you page is coming, so the funnel tracking has to be rebuilt against a different system. Asked which pages are affected before agreeing to anything, and it is being held until the thank-you page is synced.

Rebuilt the video-a tracking, 28 August to 2 September

Alex asked whether the tracking needed a full redo and the campaign a restart. It did not. The tracking on training.growmyads.com/video-a had stopped working, so I rewrote the page backend in the gma-lt-funnel-landing-pages repo to restore the events the existing GTM setup expects, without changing the design. Confirmed Lead and Schedule both firing to Meta again, and told Alex plainly that since GTM sends the same events, no campaign restart was needed.

Found the page passes data-lead-value="1500" for the $30K to $100K per month option and for no other option, so lead values are not usable for value-based optimisation as they stand. Raised it rather than sending a partial value; Alex chose not to send value for now.

The OnceHub booking problem

Bookings run inside a OnceHub iframe with no GTM of its own, so the tags could not fire where I first expected. Worked out where in the OnceHub flow the confirmation actually lands and tested repeatedly rather than trusting one pass, including checking whether repeat clicks or clicks on non-text parts of the button could double fire. Ran an independent critical review of my own setup afterwards.

Alex reported the numbers looked wrong: only about five real bookings in one to two weeks but Meta showing nine to twelve. Checked for duplication and found none. Pulled the OnceHub export and separated real bookings from the test ones left by me and others. Pushed back on the assumption that OnceHub was creating the Meta conversions, since OnceHub cannot send data to Meta at all, and kept digging until the count reconciled.

Raised a real gap in the flow: the OnceHub form has a "next" step and a "confirm" step, and only "confirm" redirects to the thank-you page. Prospects who see the confirmation message on screen at the confirm step may never click it, which would lose the conversion. Asked for OnceHub access to check, and Alex granted it.

Agreed with Alex that he would commit the thank-you page to the repo as a draft PR without deploying, so I could set the conversion up on that branch and push live only once it worked. Set the conversion to fire on video-a-thank-you, added GCLID and UTM capture, and verified end to end with a fresh test booking: UTMs saved into the OnceHub meeting details and the GTM tag fired exactly once. Also confirmed video-b is not in use anywhere, in ads or organically, so it needs no tracking yet.

Applied Luke's copy revisions to the live page and the PDF, after first producing a line by line list of exactly what changed or was deleted so the edits could be checked before going live.

Checked the funnel the way a prospect meets it, not just the way the tags fire: booked demos under test identities against a +verify address and confirmed the follow-up sequence actually arrives, both the abandoned-application chase and the guarantee emails. The hosts cancelled those test bookings from their side once they saw them.

Lead gen page and Meta campaigns, 21 to 24 September

Set up tracking for the new training.growmyads.com/lead-gen page and its CTA page. The booking happens inside OnceHub while the visitor is still on our page, so the Schedule conversion fires on OnceHub confirmation and no separate thank-you page is needed. Applied the fixes to both video-a and lead-gen. When my pushes stopped deploying, found the pages are on Netlify auto-deploy from Luke's repo, not our Cloudflare flow, and wrote Alex a short message on which repo and branch to push to. Tested after his push and tracking worked.

Built the Meta ads with Alex, copying the approved text and headline across the drafts and uploading the videos, and researched why he could not see my drafts: in Ads Manager they belong to the user, not the account. Confirmed Meta received Lead events.

Meta then showed Schedule conversions attributed to the lead gen campaign that did not fit. Checked the setup and could not find anything double-firing. The test bookings were made before the campaign went live, and two Schedule events came from go.growmyads.com after launch, which Meta may have credited through the cookies Stape saved. Told Alex that plainly rather than claiming a cause I could not prove. Also explained that the standard Lead event overlaps with Schedule because it fires as soon as a prospect enters a phone number, and that changing the redirect URL will not affect the Schedule conversion.

Planned sending show-up and qualified bookings back to Meta as offline events, with an independent review of the plan, and checked the real attribution window limit against more than one source rather than going from memory.

Lead gen page and offline events, 28 September to 30 September

Set up and verified tracking for the $100k page on training.growmyads.com and the lead gen page Alex wanted to launch, checked them in a real browser and with test UTM links rather than a headless run, and confirmed UTMs persist into OnceHub bookings. No changes were needed, and I told Alex so. Moved the Meta access handover to Oleg forward, then put it on hold when Alex said it was no longer needed.

Built the show-up and qualified events for Meta: an Apps Script that adds a Call Date column and the Facebook click ID per booking, taken from the OnceHub schedule event, keeps his master sheet sync in place, and stores the click ID visibly in its own sheet. Asked Alex whether to send No-show and Unqualified too for exclusion and lookalike audiences; he wanted taken and qualified calls only for now. As he asked, sent him the code and short step-by-step instructions on 30 September instead of changing anything myself, with the secret kept out of the page code.

Vovlift / Joy Sports StoreShopify + Simprosys · tracking audit

22hStarted 5 Aug
Major Live 5 Aug – 30 Sep
What I did

Opened the audit on two linked stores. Found two GA4 properties on joysportstore (G-V2GVVCLRYE and G-J4JVDP0DFF) with no clarity on which is live — they should be consolidated into one, but I need to inspect both first. Also found Stape server-side code on the site that isn't working, so I asked whether the subscription is still active and whether the client ever actually used it. Requested Shopify Apps + Customer Events access and GA4 admin.

Access cleared, then the audit run, 14 to 20 August

Access stalled twice. The client hit GA4's accounts-per-user limit when trying to share, so I cleared out old accounts on our side to free a slot rather than telling them it was their problem, and chased Customer Events on both stores across four days until it landed.

On JoySportStore the audit found scripts feeding three different Google Ads tags at once, AW-11487303697 and AW-16864449981 alongside the account's current AW-17514368465. Disabled the two stale ones. Simprosys itself is healthy but Enhanced Conversions were switched off on both stores, so I enabled them. On Vovlift I disabled a pixel that was firing to nothing. Flagged the Stape code again: it is only on JoySportStore and should come off Shopify unless they are still paying for it.

Chased the dynamic remarketing numbers rather than accepting that the setup "looked correct" while every product showed zero cost. Traced the feed through GTM-M374DT97 and Simprosys and found product IDs going out in upper case from Shopify against lower case in the Google Ads catalogue, plus two different identifiers, id and ecomprodid, being sent. Also found no tracking template on any campaign, so most sales were landing as source none, and set one. Noted the Shopify deadline to upgrade the Thank You and Order Status pages by 26 August, which JoySportStore has to do before the rest can be verified. Proposed a secondary ecommerce conversion on both stores so the counts can be compared in a few weeks instead of being taken on trust.

The order Google Ads never saw, 24 to 27 August

A $5,700 order was missing from the account's conversion value. Rather than accept the first plausible theory, I reconciled Google Ads conversions and conversion value against Shopify order value day by day for the whole of July and August, and kept going until the gap was explained: the conversion count matched at 14 while the value did not. Checked the order in Shopify admin directly through the live admin browser profile, since only that profile has access, and ruled out a draft order.

The answer was GA4, not Google Ads. GA4 fires on the same purchase events, but order #1392 ($5,700) and three others (#1348, #1358, #1381) never reached it - all four placed through Shop Pay, which is a known Shopify web-pixel gap with no fix yet. Said plainly that confirming it properly needs a 99% discount code or a $1 test product, and that the only way to recover those sales now is uploading them as offline conversions.

Past orders cannot be recovered because nothing was storing the click ID, so I fixed the forward case: a theme snippet that captures _gclid, _gbraid, _msclkid and the UTM set into the cart so every new order carries them. Tested it against the live store before touching the theme, and when it came back without fbclid I said so rather than claiming full coverage. Wrote a visual paste-in guide for Shopify, then had it reviewed twice by independent agents - one Claude, one Codex - and corrected the code and the guide where the reviews disagreed with what I had claimed, including collapsing it into a single snippet and reissuing it as a full replacement rather than an append.

Told the strategist the honest state: this code has not run on any other Shopify client yet, so it stays on Vovlift while I confirm it, and JoySportsStore gets it early next week. Also flagged that a theme swap or update wipes it, so it has to be re-pasted.

Snippet onto JoySportStore and CallRail, 2 to 3 September

Added the GCLID and UTM capture code to JoySportStore, the store it had deliberately been left off. Opened the theme through the Shopify CLI and checked whether the Vovlift code would behave the same on this store or needed changes, then had it independently reviewed before pasting, and confirmed which script slot it belonged in when one of the entries looked wrong in the admin.

Asked Anna for a CallRail account covering both stores, set up as one account with two companies inside it since they are separate Google Ads accounts but one client (Cyganka Partners). Told Miles a date he could give the client on his call the same afternoon rather than leaving him without an answer. Specified website pools with message routing on.

Corrected my own earlier audit on two points: add-to-cart and several other actions cannot be account goals or optimisation targets while they are set to secondary, and a number of the conversions the audit referred to are disabled or deleted. Also looked into detecting the Singapore traffic on these stores and what can be done about it, including whether CallRail can be limited to swapping numbers for US traffic only.

CallRail pools and the passkey wall, 4 September

Created the website pools and the Google Ads call asset numbers for both stores. Connecting CallRail to Google Ads then stopped on Google demanding a passkey on the shared admin account. I worked out what creating one actually commits us to first - it is added alongside any others and would then be required every time anyone logs into an account the team shares - and asked Anna to approve it rather than creating credentials on a shared account on my own judgement. She did. Adding the ads asset number then failed with an error that survived a page reload and a browser restart, so that piece is still open.

Closed out the Singapore traffic question with evidence rather than a theory: Shopify's own analytics shows the same session counts as Google's and no orders at all from those sessions, while the real orders come from Canada and one from India. Worked out what can honestly be recommended to the client to exclude it. Also inventoried every other phone number published across both sites beyond the header number, with the page or pages each one appears on, so the pools cover the numbers customers actually see.

CallRail handed over, 4 September

Wrote the whole CallRail state up for Miles to take to the client rather than leaving him to interpret it: both stores set up with number swapping active, the two Google Ads call asset numbers, and the GA4 integration confirmed running. Restricted dynamic number swapping to US visitors and said plainly what that costs, which is that a US visitor on a foreign VPN sees the static number, then offered CPC-only swapping as the alternative since nearly all their paid traffic is US. Because the shared admin account is locked out of the Google Ads integration for a week, I invited Miles to CallRail and gave him the exact click path to finish it, including selecting separate conversion actions for first-time and repeat callers. Priced the two ways to cover the extra hardcoded numbers, swapping them to match the main number against separate tracking pools at $24 a month for JoySportStore and $40 for Vovlift, so the client decides on cost rather than on my preference.

14 September. Three days left on the CallRail trial and no billing details on the account, so I asked Miles to get them from the client before it lapsed and the tracking numbers went dead.

21 September. The client said some numbers were dead. They are the CallRail numbers on the Google Ads call assets, so I asked Miles to call them and tell me what happens, so I know what to raise with CallRail support.

30 September. Miles asked for a template to upload the client's conversions. Sent a sheet with required and optional columns, offered to add matching gclids from CallRail for draft orders, and noted the 90-day limit and that email and phone must be hashed.

VesitiaShopify · inflated Google Ads conversions

3.5hStarted 4 Aug
Moderate Closed, access never granted 4 – 12 Aug
What I did

Ran the audit framework against them. Meta tracking is healthy, but Google Ads conversions are badly inflated — the GTM setup fires a purchase conversion on every page load. I checked the real numbers rather than accepting the summary: 3,248.75 conversions worth $1,795.51 over Jul 6 – Aug 4. Recommended pausing GTM immediately to see what the Google Shopify app records on its own, then rebuilding purchase and secondary ecommerce events in a customer pixel so the two can be compared before committing.

12 August: the client granted Shopify access but not the part that matters. Went back and specified Customer Events exactly, since that is the only place the new tracking can be built, asked them to confirm we can pause GTM, and requested GA4 on top.

9 September: closed the request out in ClickUp. The Shopify Customer Events access it needed never arrived, so the rebuild was never possible.

Watchmaker Genomics — tracking auditGenomics · Google Ads + HubSpot

15hStarted 31 Jul
Major Live 31 Jul – 4 Sep
What I did

Ran the full audit. Found their Google Ads is pointing at pages whose forms aren't tracked at all, while conversion actions sit created but unused in the account — and combined those into a single finding rather than reporting them as separate items. Found the thimRNA LPK pop-up form conversion was triggering on link clicks rather than actual submissions. Went into HubSpot through the browser to check the forms directly, since there's no API or MCP connection, and worked out exactly which HubSpot access level to request to wire a new form from the landing page.

Also analysed the campaign data to decide which product needed a new page: the WGS ad group had been paused at a $229 CPA, which reads as a page failure rather than weak demand, so cfDNA became the target.

Getting in the building: most of the elapsed time here was access, and I ran it directly with the client rather than through a strategist. Their HubSpot sat behind a corporate VPN that kept rejecting the portal address; I worked it through with their marketing manager, joined a call with their IT manager, and got the connection and the disconnect passcode sorted. HubSpot then only gave read-only forms access, so I specified exactly what I needed and why — they made me super admin, which meant giving up a paid seat, so I flagged that I'd tell them the moment it could be reverted.

The audit itself

Once super admin came through I had a limited window, so I wrote the check list first — a structured instruction covering every item the audit needed to touch — then ran it against their live HubSpot in the browser myself rather than working from screenshots. Where the instruction didn't match what HubSpot actually shows, I corrected the instruction rather than skipping the check, and recorded what was found at each step instead of just ticking it off.

Submitted real test leads through both the contact form and the download form with a fabricated gclid and a full set of UTMs, and confirmed the gclid does land on the HubSpot contact record, so click ID capture is working as it stands. The catch I flagged: the click ID is only captured if the person submits while still on a URL carrying it, so a visitor who arrives from an ad, browses to another page and then fills the form loses it. Also found their form payload carries no field values, which kills Enhanced Conversions as I had first written it, so I reworked that recommendation and noted what needs changing on the site.

Untangled why three conversion linker tags exist where one would do, and worked out whether HubSpot's own code needs to be on the site for the cookies to be usable. Warned that HubSpot's reported numbers will move once attribution starts working properly, so it doesn't get read as a data break. Reviewed the three HubSpot click-import conversions in Google Ads and confirmed which of them is safe to keep. Delivered the audit as a formatted document and a PDF built so every part of it stays selectable and copyable; the client booked a tracking review call off the back of it.

HubSpot audit and proof, 7 August

Once super admin access came through, audited the whole HubSpot side manually in the browser and recorded what I checked rather than reporting from memory. Rather than assume gclid capture worked, I submitted real test leads with a fake gclid and full UTM set and confirmed the values landed on the contact. Warned that HubSpot's reported numbers will shift once attribution starts working, so it does not look like a data break to stakeholders. Delivered as a fully copyable PDF.

Conversion rebuild, 11 August

Their forms were not tracked at all. Ads were instead optimising against document downloads that do not exist on the ad landing pages, and each download fired several conversions at once. Confirmed the rebuild with the client, then asked Anna whether to delete the misconfigured conversions immediately or run the new form conversions alongside them first, rather than destroying history on my own judgement.

Rebuilt the conversion actions, pulled the account data back afterwards to verify every label matched, and built and published a new GTM container with the container-builder skill. Verified conversions fire live in the browser with emphasis on Enhanced Conversions, then completed the GA4 side.

GA4 verification, 14 August

Did not treat the rebuild as finished. Re-ran the checklist against GA4 and found Became_Campaign_Member still present three days after it was deleted, even though it is no longer an enabled conversion in Google Ads. Rather than deleting it again and hoping, I first confirmed where it is still being generated from so the same event does not reappear. Read up on Google Groups for GA4 access as a possible equivalent of an MCC, and established it carries the same account cap, so there is no gain in moving to it.

26 August. The client came back on the old conversion actions, so I checked whether any of them is still used by a live campaign before saying they were safe to delete, rather than answering from the audit notes. On the conversion Google flags as misconfigured, I checked GA4 for real submissions in the window - and corrected the window to the roughly seven days since the new conversion was created, not the 30 days first assumed, which would have read as a dead conversion.

Document download question and the delivered doc, 4 September

The client asked which Tag Manager tag sends the GA4 document download event, because they could not find it. Rather than answering from the audit notes I went back through what we actually changed and stated it exactly: downloads were being counted before our work, and what changed was the set of pages the tag fires on. Exported the container to a folder they can read, with the tags carrying the old label deleted out of it first.

Then reworked the document already sent to them. Put it back to the earlier visual so it matched the previous PDF, cut the section asking them for decisions, and cut a sentence that was no longer true about a Tag Manager tag sending document clicks to Google Ads rather than to GA4. Had an independent agent check every remaining claim against the account before it went back out, because a false claim to this client costs more than a slow answer.

Made in TNShopify · purchase tracking & dynamic remarketing audit

2hStarted 31 Jul
Moderate Closed 31 Jul – 12 Aug
What I did

Checked Merchant Center against the Shopify storefront and confirmed the product IDs match, but there was no purchase event. Went into Google Ads tag activity and filtered purchase hits by pagetype. Checked Meta via MCP and found the last recorded purchase was 17 days old. Determined the Meta setup is the standard app rather than a custom pixel.

The wider finding matters more than this one client: I checked ten Shopify accounts in a row and none had purchase events structured with product IDs, because the Google & YouTube app doesn't send them on purchase. That's shipped app behaviour, not per-client misconfiguration. I then cross-checked with Digestive Warrior — 503 purchases in 30 days, but only 5 hits with IDs matching the feed — and took it to Anna, since it affects dynamic remarketing across the whole book.

Built as a by-product: a reusable Shopify audit framework and a per-point remediation file, which I then reran on Watchmaker and Vesitia to test it on other account types. Traps documented for whoever runs it next: the same gtag stream is not the same emitter, a custom pixel can only add events, the Ads API lowercases product_item_id, and you must check campaign_conversion_goal.biddable rather than trusting the interface.

9 September: closed the request out in ClickUp. The framework it produced is still in use on other accounts.

Drinkstuff — CallRail for a UK numberUK ecommerce

3.5hStarted 30 Jul
Moderate Porting scoped 30 Jul – 14 Aug
What I did

CallRail rejected their UK landline as invalid. Contacted support to get UK numbers enabled, which then required a UK Know Your Customer compliance registration. I completed it myself using the client's company details pulled from Metrics/Pipedrive and cross-checked against the UK companies register, rather than pushing the form back to the client and losing a week — then flagged to Anna to confirm that was the right call. Researched whether CallRail runs on Twilio in the UK, and issued the swap-code install instruction for the client's developer.

Number porting, 14 August

Trial ran out with the client still not having installed the swap code, added billing or accepted the invite, so I flagged it to the strategist a day before expiry rather than after. The ask then changed to porting their existing numbers into CallRail. I said plainly that this takes weeks rather than days, and listed exactly what is needed before anything can start: the exact numbers, their current provider, and the destination number, which is probably the main site number but should be confirmed rather than assumed. Going to CallRail support for the estimate and to find out what paperwork the client has to sign.

Dr BalconyAds tracking templates being overwritten

1hStarted 21 Jul
Quick Diagnosed 21 Jul
What I did

Found a HubSpot tracking template set at both account and campaign level. As long as the HubSpot integration is live, changing tracking templates in Google Ads is pointless — HubSpot rewrites them every time. Told the team to stop trying and get the client to either remove the integration or share HubSpot access, and flagged that we'll need GHL access once it's set up to confirm UTMs record correctly.

Seneca — calculator & funnel trackingCost segregation · multi-step calculator

18hStarted 20 Jul
Major Ongoing 20 Jul – 10 Aug
What I did

Tested the tracking end to end in their GHL, then decided against a staged proof when two real conversions had already come through — no point manufacturing a test to prove something the live data already showed.

Audited the calculator itself and found several distinct problems. The calculator still pushes the site-wide lead_form_submit alongside its own event, so one lead is counted two or three times in GA4. calculator_gate_completed carries no customer data, leaving Enhanced Conversions nothing to work with. A third step — booking a call — isn't tracked at all, because it redirects to a confirmation page with no GTM on it. And calculator_gate_step1 doesn't exist in GA4 at all, because GTM sends it under the old name calculator_tier1_completed; I asked for permission to rename rather than doing it silently, noting it was safe because the event has only a handful of submissions.

On the Ads side I changed the trigger so the Calculator tier-2 form conversion started collecting. Also caught that prospects could still see calculator results without submitting anything, and that the fields were structurally wrong — reported as a probable bug rather than assuming intent. Wrote the developer spec listing exactly which events to keep, remove and rename and what data each needs, scoped so nothing has to change in GTM on their side.

Attribution design. Separately worked out how to carry the email from step 1 to step 2 through localStorage so they can use one webhook instead of two, and wrote up first- and last-touch attribution in GHL — storing the first gclid on the guide-subdomain submission so a lead that later converts on the calculator can still be traced back to the guide campaign.

Reworked after a closer look

Pushed back on my own spec once I looked at the events firing side by side. On the Calculate button, calculator_gate_step1 and gate_shown fire together and measure the same thing, so I moved that measurement onto a click on the Calculate button instead and gave calculator_gate_step1 back to the step it actually describes, the name and email fill. Explained to the strategist why I'd rather keep exact per-page event names than reuse the site-wide lead_form_submit: their developer is inconsistent with naming, and unique names mean a broken event points straight at its cause. Rewrote the client PDF around that.

Then built it: one new Ads conversion created, three calculator goals renamed to match the new event naming, and the GA4 gate shown event set up. Put the open question back to the strategist on whether gate shown and step 1 completed should carry a conversion value at all, and the same for the guide landing page conversion.

Buena Vista NYFollow-up on blocked GTM

0.5h17 Jul
Quick Closed, sits with their dev 17 Jul
What I did

Chased the outstanding Popmenu problem, where the GTM snippet sits in the page payload but never executes, so nothing can be collected. Diagnosis was already delivered; this was keeping it from going quiet.

9 September: closed the request out in ClickUp. The diagnosis was delivered and the fix sits with their dev.

Low Cost Pet VaxOffline attribution — client explainer

1.5hStarted 16 Jul
Quick Delivered 16 Jul
What I did

Produced a Loom and a PDF for the client walking through the proposed offline attribution approach, so the concept could be sold without a technical call.

Laser EraserTattoo removal · four GTM containers into one

10.5hStarted 15 Jul
Complex Consolidated onto one account 15 Jul – 26 Aug
What I did

They were running four separate GTM containers across three WordPress sites plus Zenoti, each reporting into its own Ads account and GA4. I mapped what every container tracked, then consolidated to one container (GTM-N5TJZJS9), one site, one Ads account as they moved onto a single Next.js build. Reconfigured form tracking for the new form type, rebuilt the container with the container-builder skill, and set up the Zenoti booking tracking. Found form_cf7 wasn't set to primary in our Ads account and fixed it.

When the client insisted only one GTM was live, I proved otherwise: the containers are hardcoded in the app's root layout (app/layout.tsx), which is why they appear on every URL — visible directly in the React server payload in view-source. Sent that to the dev as evidence.

Still open: no backend access, and as of 6 Aug three containers are still on the site. Chased twice; also confirmed no access invites had arrived in the admin inbox.

26 August. They moved onto lasererasernow.com while the GTM and GA4 in use still carried the Laser Eraser Paramus naming, which is exactly the kind of mismatch that gets the wrong property read six months later. On the migration they decided to keep the Paramus Google Ads account, so all tracking moved onto Paramus GTM and Paramus GA4, and it now covers the new site only, since lasereraserparamus.com redirects straight to it.

Recommended either deactivating the leftover GTM containers and GA4 properties or at minimum tagging the Paramus property as the live one, so nobody reports off a dead property. We hold only view access on their GA4, so I sent the client the exact path to mark generate_lead as a key event themselves rather than reporting it as blocked.

La Residence InteriorsShopify · untracked Microsoft Ads traffic

6.5hStarted 15 Jul
Moderate Capture live, awaiting first Microsoft purchase 15 Jul – 11 Sep
What I did

Traffic was arriving unattributed. Identified it as paid Microsoft Ads and turned on auto-tagging to fix the attribution, with a tracking template as the fallback if it persists. While in there, updated their Shopify customer pixel code so Enhanced Conversions record correctly.

Microsoft Ads discrepancy, 28 August to 2 September

Ryan came back saying Shopify now shows the traffic as paid rather than unknown, but Microsoft Ads still sees only a fraction of it. Traced it to the msclkid not persisting all the way from an ad landing on the home page through to purchase, and implemented the best fix possible with the access we have.

Scoped the next step honestly instead of calling it finished: capture and store the msclkid inside Shopify and append it to the order notes, so a purchase can be definitively tied to a Microsoft Ads click and uploaded later as an offline conversion if needed. That needs theme access, which Ryan requested from the client for the admin email. Told him it should be quick once granted.

Theme access granted, 10 to 11 September

Theme file access came through, so I connected the store through the Shopify CLI to install the msclkid capture properly instead of pasting into the admin. Logging in took a detour because the CLI was already authenticated as a different account. Still in progress at the end of the window, with the theme edits kept to the code and its label and no explanatory comments, so the client's own developer is not reading around ours.

11 September. Pushed the capture code into the theme through the CLI and told Ryan it is in and waiting on the first Microsoft purchase to appear in Shopify, rather than reporting it as finished. Pushed the changed file only rather than republishing the theme, so the client's own history shows exactly what we touched.

Better Place Design Build — Zoho CRM lead syncConstruction · leads not reaching the CRM

1hStarted 14 Jul
Quick Awaiting access 14 Jul – 14 Sep
What I did

The client came to us saying leads weren't syncing into their CRM and they were losing customers over it. I watched the Loom he sent, and put a stop-gap in place the same day — every form submission now emails him directly from our admin address, so no lead is lost while the underlying sync is fixed. Requested admin-level Zoho CRM access to fix the sync itself. He also asked about a new landing page off the back of it.

20 August: five weeks on, still no Zoho access. Went back to the client directly rather than letting it lapse. The email notification workaround set up in July is still catching every form submission, so no leads are being lost while this waits.

14 September. Chased the client again, two months on. The email workaround set up in July is still catching every submission, so nothing is being lost while this waits.

Open BionicsProsthetics · Google + Meta · health-data constraints

26.5hStarted 10 Jul
Major Largely live 10 Jul – 27 Aug

The most constrained account I handle — a medical-device advertiser where the wrong parameter is a legal problem, not just a data problem.

Compliance research

Wrote a client-facing research document on what can and cannot legally be tracked, with at least three independent sources per claim and direct citations, built to be handed to their lawyer. Covered HIPAA, BAA and HHS obligations, and included a comparison of compliant booking schedulers — specifically checking, for each one, whether it can still pass call and booking conversions to Google and Meta while in BAA mode, since many disable exactly that. Produced it as a selectable, copyable PDF.

Meta rebuild

Their pixel was sending limb level as an event parameter. I replaced it with numeric conversion values by amputation level so Meta can optimise on lead quality without ever receiving a health attribute, and confirmed the account bills in GBP rather than assuming USD. Consolidated to a single Lead tag instead of the two-tag split I'd first proposed, after pushing back on my own design. Set up Contact for calendar-button clicks, tested live in Meta Test Events, and removed the test code afterwards. Audited every thank-you page and form to establish which were genuinely in use.

Custom audiences & the dead pixel

Built remarketing audiences from scratch, and while doing it found audiences split across two different pixels — one of them effectively dead. Pulled the full list of audiences, which pixel each used, and whether it was active, before building anything new.

The GTM block

Tracking I'd set up wasn't firing on the pop-up-clinic page. GTM simply wasn't loading. I traced it to their WordPress origin filter mangling newlines into a literal _NL_ inside inline scripts, which breaks the GTM snippet. Ruled out the caching plugin and the consent plugin one at a time — including purging Breeze cache and checking the GDPR plugin version — and required source links and exact citations before sending the diagnosis, because a wrong call would have cost another week. Their dev fixed it and tracking now works.

Offline conversion import

Built and shipped the Google Ads offline import for qualified leads, live as a secondary conversion. Flagged that some GCLIDs arrive truncated and therefore can't be matched, with an example.

Iteration: ran across four weeks with repeated rounds against Cai and the client on what was legally acceptable to send. I wrote to the client's team directly, confirmed GTM had been reconfigured to send numeric values only, and got their explicit sign-off on removing the Initiate Checkout event. Their team corrected one of our assumptions about the hero-arm form being static — it is dynamic and does collect limb data — which I took on board and rebuilt the value mapping around.

Meta lead numbers that did not agree, 27 August

Meta reported 142 leads for the account while the client's own figure was 25, and the question landed as "which of you is wrong". Neither: they were different metrics over different windows. Traced their number to Landing Form Fill Roots, a Custom Conversion created in October 2025, before our rebuild - not a tag, no code on the site, just a filter Meta applies on top of pixel events, and its rule is PageView AND URL contains landing-thank-you. The site has roughly fifteen thank-you pages and that rule watches exactly one of them, so leads converting on the Find a Clinic page we built - thank-you URL /find-a-clinic/thank-you - can never match it. That single fact is the whole gap.

Then went and got independent evidence instead of arguing from the tag setup. Pulled the Gravity Forms entries out of their WordPress: 157 entries in August, 121 carrying an fbclid, 109 of them unique people. Checked the export properly after spotting July rows sitting below the first August entry, and re-ran the count from the correct row rather than reporting the inflated figure. Noted the tag does not deduplicate, so a repeat submitter counts twice.

Explained why the standard Lead event is the right one to stay on: Meta optimises natively on standard events, and the custom conversion runs at about six a week against the roughly fifty per ad set per week Meta needs to leave the learning phase - optimising to it would starve every ad set. Defended the leadSubmitted GTM trigger as deliberate, since a visitor can land on the LP and submit any form on the site, and confirmed the old per-limb tags are paused so nothing double-fires.

Finally reconciled Meta against GA4 rather than declaring one of them broken: of 115 leads on the US prospecting campaign, 109 are 7-day click and only 6 view-through, and 7-day click is not same-visit - a phone click on Monday and a laptop submission on Thursday is one person to Meta and two unrelated sessions to GA4. For scale, the pixel recorded 472 Lead events in August across all sources and Meta claims 160 of them. Also grammar-checked the client-facing version the strategist rewrote, and handed it back as a txt file after the chat copy-paste mangled it.

FSS ZoneFumigants · new WordPress site + Shopify store

19hStarted 10 Jul
Major Pools added, call assets flagged 10 Jul – 3 Sep
What I did

CallRail restructure. Two sites shared one number, so reporting was unusable. I laid out two options with the cost implication of each, and built the chosen one: a second CallRail company plus a new website pool, so each site keeps its own number at no extra cost, since CallRail bills per number not per company. Linked Google Ads to both companies and showed the team where per-company reporting lives. Later found the pool numbers were swapping out too quickly and gave two fixes — add numbers at $5 each, or exclude direct and organic traffic from swapping.

The GTM find. Their new WordPress container was never announced to us. I discovered myself that they had created it on the Friday and shared it with our account — it wasn't in the admin inbox and the strategist hadn't passed it on. I picked it up, installed the CallRail code into it, confirmed numbers were swapping, and then went through all their WordPress sites to establish what was actually deployed where.

Conversion architecture. Reviewed the new site — 94 pages, though the sitemap listed only 6 — and proposed splitting conversions by buyer intent rather than one generic form event: RUP Purchase Request, Lab Pest ID Request, and Contact, plus tracking redirects to the Shopify store and email clicks. Reusing their existing GA4 property rather than starting fresh. Built the new container with GA4 and form-submission conversions, set up per-form UPD tags for Enhanced Conversions with trigger sequencing, and tested the RUP form live.

Raised commercially: the Ads account was spending roughly $2,248 per 30 days against zero recorded conversions, and the top form's calculator CTA is a dead button.

Conversions live, and the multi-number question answered. Built and shipped the five conversion goals from that architecture and added the GA4 tracking for them in GTM. Set up the CallRail form tags against CallRail's own instructions and tested the RUP form live, then worked through the trigger sequencing so one Enhanced Conversions user-data tag fires ahead of each of the three separate form-submission tags rather than all of them sharing one event. Set up link click tracking for the Shopify redirects and email clicks as its own thing rather than folding it into a dataLayer variable.

Their Contact page lists 10 offices with 10 different numbers, so I priced out four ways to handle it and gave the pros and cons of each: all 10 as swap targets on the existing pool at no extra cost but every office showing the same number; Local Swap at 18 numbers and $54/mo, noting it matches the visitor's IP rather than the page so an Ohio page won't show an Ohio number to a Texas visitor, and that it locks permanently once activated; a pool per office at 36 numbers and $108/mo, the only option that gives both Ads attribution and per-office reporting; and static numbers per office at $30/mo, which is cheap but loses Google Ads data on every branch call.

Eight pools built, 14 August

The client picked the pool-per-location option, so I built it through the CallRail API rather than clicking through eight setups, with a separate website pool per number. Before building I went through the whole site page by page to inventory every number and every page it appears on, twice, because the first pass missed numbers that only appear on location pages.

That surfaced a data problem on their side rather than ours: on the Contact page the Cedar Rapids and Des Moines numbers are identical to the main site number that already swaps, while the Iowa page shows two different numbers for the same two offices. Put that back to the strategist for the client to confirm before adding the last one or two pools, instead of guessing which set is correct and building pools against wrong numbers.

Call pools and call assets, 3 September

Added two more website pools in CallRail for the confirmed Des Moines and Cedar Rapids numbers. Then checked the Google Ads call assets and told Joey what the check showed: most Google Ads leads are still calling the untracked 833-221-2979. Recommended switching all campaigns to the CallRail WordPress ads asset number, or the Shopify ads asset number that we did not create and that I could not find in the Ads assets at all, or creating a new call asset.

Vantage Elite Fitness — main website trackingDallas PT · existing site, separate from the landing page

2hStarted 9 Jul
Quick Live 9 Jul – 5 Aug
What I did

Their main site had Google Ads and GA4 wired through Site Kit plus loose HFCM snippets, all predating the landing page. Disconnected both from Site Kit to stop double counting once the new container went live, removed the stray snippets, and worked through LiteSpeed's JS deferral and cache settings so nothing was being suppressed. Caught that the main-site contact form had shown inactive since 18 July and fixed it.

Bradfords BakersMagento · Meta purchase tracking research

1hStarted 9 Jul
Quick Delivered 9 Jul
What I did

A platform I hadn't set up before, so I said so internally rather than bluffing, then did the research properly — articles, forums and the Adobe Commerce marketplace — and compared the realistic integration routes specifically on whether each actually supports purchase tracking. Delivered a ranked recommendation with Meta's own free extension as the starting point.

Patterson's Water — trackingMarketing 360 site + new LP · CallRail

8hStarted 6 Jul
Complex Live 6 – 28 Jul
What I did

Built container GTM-TSBFB483 covering both the main site and the new landing page, while leaving their two legacy containers intact so nothing broke mid-migration. Discovered the GTM code was present on the main site but not actually executing because of how it had been added, and produced a copy-paste install for Marketing 360 formatted to be usable by a non-technical person. New conversion actions for both the main site and the LP, both primary, with separate labels so LP leads stay distinguishable.

Marketing 360 CRM. Wired submissions into contacts, worked through the API to get the source IDs right — including tracking down a stale source ID left behind after a deletion — and was straight with the team that contacts rather than leads is genuinely the most the CRM allows, since its lead flow only accepts their own native forms. Ran a real test submission with tagged UTMs to confirm gclid arrives, and confirmed gbraid and wbraid record too.

CallRail. A long-running mess I chased to the end: the client believed her account was renewed, but CallRail support confirmed it was a disabled trial. I got that in writing, relayed it, then when the account came back found CallRail had deleted all previous numbers and had to create a new website pool. When they proposed another number at $3/month, I proposed excluding direct and organic traffic from swapping instead, so the client pays nothing extra.

RubberTrackBigCommerce · GA4 recording no purchases

10hStarted 3 Jul
Complex Fixed 3 – 7 Jul
What I did

GA4 was recording no purchases at all. Worked through the BigCommerce Script Manager setup, taking care not to disturb the Twitter and affiliate conversion tracking sharing the same block, and shipped a fix into the affiliate section with Enhanced Conversions corrected for Ads.

Then the harder half: I couldn't run a test purchase, so I had to verify against real orders as they came in over several days. That surfaced two further problems the first fix didn't cover. The recorded value was the pre-discount subtotal, so I traced how BigCommerce exposes order amount and offered the client the choice of pre- or post-discount to stay consistent with Ads. And purchases were still intermittently missing — which turned out to be the cookie-consent banner blocking Analytics until a shopper clicks Accept, which most never do. I checked current US privacy law before recommending they switch it off, and kept the recommendation short and free of unproven claims.

Iteration: took most of a week and several dead ends. I said so to the strategist rather than presenting it as clean.

Sewing Machines PlusCallRail swap verification

2.5hStarted 3 Jul
Quick Live 3 Jul – 11 Aug
What I did

Confirmed GTM was present in the theme so the CallRail swap would work, got numbers swapping, and added the GA4 integration. Found the Contact and About pages use a different number that isn't a swap target, and — before recommending anything — established exactly what adding it would cost and whether it would swap to one tracking number or two, because the client would be paying for it.

11 August: added a purchase conversion through a Shopify Customer Pixel alongside the existing setup, so the two can be compared on real data instead of picking one on theory. To close it out we need a discount code or a $1 test product from the client, which I asked for rather than putting a real order through.

Proline Range HoodsMoving offline conversion import off Zapier

1hStarted 3 Jul
Quick Pool expansion flagged to the strategist 3 Jul – 14 Sep
What I did

Set up the access request to migrate their offline conversion import from Zapier onto the newer, more reliable engine — recorded a Loom walking the client through granting Shopify app developer permissions rather than sending written steps. Chased twice.

9 September: closed the request out in ClickUp. Two chases and the Shopify app developer permission never came.

14 September. CallRail flagged that the site's number pool is too small for its traffic, so I passed the recommendation to Joey with the context rather than leaving it in the CallRail dashboard where nobody would see it.

Exquisite TimepiecesLuxury watches · Ecwid → Shopify migration

64hStarted 2 Jul
Major Pixels rebuilt and verified live 2 Jul – 21 Sep

The largest project of the period: rebuilding an entire ecommerce measurement stack so it survives a platform migration without losing a day of conversion data.

Ecommerce tracking

Built Purchase and Add to Cart into a Shopify customer pixel with conversion labels matched to the old Ecwid site so historical reporting stays comparable, and verified the value field against what the old site recorded rather than assuming. Added GA4 into the pixel with a switchable test mode so it couldn't pollute live data, anchored the GA4 client ID to Shopify's Web Pixels API client ID, and excluded my own IP as internal traffic.

The product ID problem

The hardest single problem I solved this period. Dynamic remarketing and purchase reporting both need product IDs that match Merchant Center — but Merchant Center holds legacy Ecwid IDs while the Shopify storefront exposes Shopify IDs. I spent days on it: checked the theme liquid, inspected the Add to Cart button markup, read the network requests, and found the Ecwid IDs sitting in Shopify product metafields — by browsing Shopify myself rather than waiting on a developer. I then established exactly where the developer must surface them, and wrote that as a dev-facing instruction including how they can verify it from their side. I demanded exact citations for the claims in that instruction and rejected two rounds of sources that didn't actually support the point.

Along the way I found the reason product view and add-to-cart events appeared to fire nothing: the store wasn't publicly live yet. I checked that with a senior tracking specialist, then summarised her call for the client document.

GTM in theme, forms and chat

Worked out where GTM belongs in the theme liquid and got it installed and confirmed live. Mapped every form on the site — Contact, Trade-in/Sell, Request More Information, Notify Me When Available, Affiliate, Careers, Newsletter, Credit — and gave a recommendation per form on whether to track it in Ads, GA4, or not at all, rather than tracking everything by default. Set up Enhanced Conversions per form and tested submissions live in GTM preview, catching that the UPD tag was firing after the conversion tag and correcting the sequencing. Investigated LiveChat and established its native GA4 app already covers chat events, so no duplicate GTM setup was needed.

Go-live

Wrote the cutover procedure — connect pixels and pause GTM at the same moment — so the migration wouldn't double-count, and gave the dev the exact clicks. Verified all tracking after they went live, then investigated a GA4 transaction arriving from something other than our pixel.

Iteration: the client document went through six versions, with formatting and wording reworked repeatedly for a non-technical reader, and the GTM container import rebuilt after I found it contained duplicated and auto-paused tags.

Working with their web agency: I corresponded directly with the client's developers throughout — confirming Ecwid IDs were available, flagging clearly that form submission tracking was not ready while ecommerce was, and putting specific questions to them about how each form behaves rather than guessing. On launch day, 2 August, I monitored delivery across the switch to catch anything breaking in the first hours.

Recovering the browser-switch purchases: their agency sent a video and script for draft order tracking. I watched it, decided a call wasn't needed and said so rather than taking the meeting, and set the direction: configure the CTM export for contacts carrying a gclid so buyers who complete payment in a different browser can still be matched. Recorded a Loom and wrote up the extra Shopify access needed to automate the draft order exports; the client had deliberately restricted that permission, so it was granted temporarily and will be reduced again afterwards.

Offline conversion pipeline, 10 to 13 August

Turned the draft order direction into a working pipeline, and it took three separate systems. Built the CallTrackingMetrics webhook into an Apps Script endpoint writing every call with its click ID to a sheet, and wrote the click-by-click setup for the CTM webhook screen rather than describing it. Cleared two false starts of my own: the Apps Script editor's Run button doesn't exercise doPost at all, and CTM's Test button sends the most recent call immediately, so no real call had to be waited on. Caught that the account ID in the code still pointed at a different client after CTM was repointed to Exquisite, and added a helper that prints the correct account ID rather than leaving it to be hunted.

Shopify access the current way. Shopify has killed the old static Admin API token flow, so I moved it to a client-credentials app in their Dev Dashboard - the script mints its own token each run, so there is no credential to copy or expire. Specified the three read scopes and the custom-distribution install, and worked out that email and phone stay null until Level 2 protected customer data access is enabled and the install link is reopened.

Where the click ID actually lives. The client sent a CSV of matches they had recovered from NetSuite, with real gclids and the campaign names to match. I first assumed Shopify held the same values and was wrong, so I stopped guessing and wrote a probe that dumps every place attribution could hide on an order - customer journey summary, all metafields, note and custom attributes - and ran it across the completed orders. Extended the journey scan from first and last visit to every visit, so a click ID sitting in a middle visit is caught, and kept the query under Shopify's cost ceiling by paging smaller.

The result was a negative finding worth having: Shopify genuinely does not hold the gclid - NetSuite does, and Shopify only carries the campaign and source of the same visit. Shopify does expose NetSuite customer and sales order IDs on every order, so there is a clean bridge. Wrote the client the ask with a concrete matched example - one order where NetSuite has the gclid and Shopify demonstrably does not - rather than a general request, and set out the two ways forward: NetSuite API access, or writing the gclid onto the Shopify order as a metafield from their side.

Asked the strategist to confirm in the client email thread that we want 90 days of GCLIDs, so the request goes to the client as a specific number rather than an open-ended data ask.

27 August. Chased the outstanding question with the strategist: whether the client's developer came back on importing GCLIDs from their CRM into Shopify, which is the piece the offline side still depends on. Nothing back yet.

2 September

Draft order import ready to go into Google Ads. Asked Joey to decide whether the conversion should be primary or secondary before turning it on.

Post-launch conversion audit, 14 September

Six weeks after the store went live, audited every conversion action against live data rather than against the migration plan. Every "misconfigured" or "awaiting activity" flag in the account traced back to three causes. Draft orders are 45% of orders and 67% of revenue, and because they are typed in the admin rather than bought through the storefront they carry no feed id, so only 31% of purchased items matched Merchant Center. One watch reached Google under twelve identities in 30 days. The migration had also silently killed the old chat and phone conversions, and Submit Notify me had never fired once - proved at code level, the label was declared but no handler referenced it. Found the two lead actions are crossed: the one named for the contact form actually receives trade-in submissions and vice versa.

Five pixel versions, two independent reviewers each

Put every version through a Claude agent and a Codex agent working blind to each other, and they found real bugs I had shipped. Phone-click dedupe keyed the raw tel: href, so one number written four ways counted four times. Setting user data only when it existed meant a conversion with no email inherited the previous visitor's identity. Dropping items with no id destroyed GA4 item revenue, so free-text lines are kept as name-only items instead.

Withdrew my own proposal rather than defend it. I had floated a Cloudflare Worker serving a product-id map as one option and then started writing about it as agreed work; the client's rule is that the only thing we change is the Shopify pixel. Before dropping it I measured what it would have been worth across 1,248 draft-order line items: it fixes at most 23.4%, because 64.4% are free text typed by staff and unreachable from any pixel. So the blank item id goes away but the Merchant Center match rate cannot be materially improved from the pixel, and I said that plainly rather than implying the audit had solved it. Also dropped a deposit-and-balance filter after review, because across a deposit and its balance the total value is already correct and filtering would have deleted real revenue to fix the smaller problem.

Shipped the final pixel comment-free on request, stripped with a JS-aware pass rather than a naive one because a plain // strip corrupts the regular expressions in the file, then re-checked and re-ran the tests after stripping.

GA4 changes and the chat event, 14 September

Made the GA4 changes myself rather than handing over instructions: registered lead_type and form_id as custom dimensions so leads can finally be split by form, and rebuilt chat_started as an event-create rule. Disproved the assumption we were both working from - chat_started was never LiveChat's own integration, it was a custom tag on the old site - and proved mechanically why three other events died: they are all rules keyed on a /thanks page that does not exist on Shopify. Did not delete them, since nobody asked and it is destructive.

Dynamic remarketing pixel, 15 September

Audited the separate remarketing pixel and found its add to cart handler has never fired once since launch. It reads line-item properties, and Shopify's cart line object has no properties field at all. Both reviewers caught it independently. Rebuilt it around a variant-to-feed-id cache seeded from the theme's own product-view event, and the reviewer then caught the bug that would have repeated the same failure: the cache was keyed on a bare numeric id but looked up with a value Shopify may deliver in a prefixed form, which would have missed 100%, silently, forever, and been undetectable from the account because there is no historical data to compare against.

Accepted a correction rather than keeping the tidier claim: I had written that omitting the items key "satisfies both reviewers", and it does not - it is the right fail-safe, but it still does not meet Google's rule that the event carry an item. Also fixed pricing to use the post-discount line value instead of list price.

Verified live, 16 September

Checked two days later instead of calling it done. Notify me recorded its first ever conversions. chat_started came back, 17 events on the first day against zero since 1 August, and it needed no pixel paste at all - the GA4 rule did it alone, exactly as predicted. Phone conversions went from a blog-only trickle to 8 a day. Trade-in submissions went to zero as designed. Leads now break down by form for the first time.

Nearly drew the wrong conclusion and caught it: almost every conversion looked down on the two days after the change. It was reporting lag, not breakage, and I proved it three ways before reporting anything - GA4 sessions for those days were less than half normal and still processing, the last complete day was dead normal, and Google-hosted actions our pixel cannot touch fell too.

Offline conversion import errors, 18 to 21 September

The imported offline conversion was showing errors, mostly "event timestamp precedes the click". Worked out the share of matched orders that were recorded against those rejected, and corrected my own figures twice against what the Google Ads interface showed before reporting any of it. The main cause is gclids older than 90 days. Since Shopify has only been live about 50 days, those old clicks cannot come from the storefront, so they are most likely pulled from the CRM. Told Joey the conversion is in the account and working as it should on the current setup, then sent their developer a short message asking how the gclid is picked before an order is pushed to Shopify, without claiming anything was wrong.

Citadel PackagingOffline conversion import — scope check

1hStarted 2 Jul
Quick Delivered 2 Jul
What I did

Checked whether purchases can happen by phone or email after a form submission and whether those get logged in Shopify as draft orders — because if they do and we don't capture them, the import silently under-reports revenue.

GMA Low-Ticket funnel — Meta purchase attributionInternal · training.growmyads.com

13hStarted 1 Jul
Major Live 1 Jul – 5 Aug

Our own funnel went live while I was mid-setup, so this ran as live debugging against real money and real orders.

What I did

Ran a real end-to-end test order through the live funnel with a 100% discount code rather than trusting a test event. Then worked through why purchases weren't appearing in the campaign: I audited every real order against the Cloudflare Worker logs and Meta, established 15 real purchases with 13 attributed, and traced each miss individually — the first had no fbclid or UTMs at all (organic, forwarded link, or private browsing), and I was explicit that I couldn't fully verify the other because the log data had expired, rather than inventing an explanation.

Pushed hard on Meta's actual limits around custom events with dynamic values, refused several answers that didn't match what the interface showed me, and made the call to revert to the standard Meta Purchase event so Meta can optimise properly — reviewed with Anna first, then duplicated the campaign because the optimisation event can't be changed on a published one. Extended the Worker's logging window so this is diagnosable next time. Kept the Worker running in parallel as a cross-check on ThriveCart's own attribution.

Also fixed the Meta domain configuration, verified the training subdomain, checked the Meta Gateway test-period expiry risk and confirmed we were covered by Stape's tokens, and assessed whether the fbclid survives the advertorial hop in in-app browsers before a listicle campaign launched — including asking how common the failure case actually is before spending time on it.

Body Temple Spa — main website & account trackingNavigator client · existing pages and Google Ads account

7hOngoing
Moderate Live Jul – 22 Sep
What I did

Tracking work on the pages and account that existed before the new landing page. Tweaked the tracking on their existing pages, and answered the client's conversion double-count question directly: yes, one person can be counted twice, once per goal, because a form fill and a booking are separate goals. Gave the real figure - 6 bookings from Ads in 90 days, so the overlap is negligible - plus the steps to verify any single case in GHL, and recommended setting counting to One on the lead-form actions.

Saved her money unprompted. She asked whether she still needed CallRail after being charged again. I pulled her actual usage, only 10 new-customer calls in 30 days, told her plainly she was overpaying, and cancelled it for her, confirming it stays live for the month already paid. Also chased down a campaign she thought had vanished from her Google Ads account.

Tracking for the new services, 31 August to 3 September

Lalita emailed me and Anna directly asking to set up tracking for the new services and campaigns she now has running. Sent her my audit booking link rather than trading times back and forth, ran the call on 3 September, and sent the recording back as a Loom the same evening, with a second Loom to follow covering the rest of the setup.

4 September. Sent the second Loom covering the rest of the setup, as promised on the call.

22 September. Lalita did not understand what she had to do with Claude to finish the tracking. Wrote back explaining what the call and the Loom cover together and what is left for her.

GMA attribution — Stape server-sideInternal · ad-blocker resilience across all GMA pages

5hStarted 1 Jul
Moderate Rollout coordinated 1 – 30 Jul
What I did

Got Own CDN live — walked through the Cloudflare DNS change to proxy the Stape subdomain and set SSL mode correctly, so our tags load first-party and survive tracking restrictions. Then prepared the Custom Loader rollout across every GMA page, which reloads the container if a blocker stops it.

The judgement call worth noting: Enhanced Ad Blocker Protection recovers more data but requires every platform to be updated simultaneously. Rather than push for the better option and risk a broken rollout across pages owned by different people, I supplied a version that can be deployed gradually, and set out clearly what would need to change for the stronger option. Wrote the instructions for whoever holds each platform, and chased repo access for the one funnel I couldn't reach.

Adamar IndustriesEcwid store · unattributed purchases and disapproved products

8hStarted 19 May
Complex Live 19 May – 22 Jun
Attribution

Purchases were arriving with no attribution, so Google Ads was being judged on a fraction of the sales it actually produced. Built a sheet that captures each purchase with its GCLID, then set up an offline conversion import on top of it. It recorded more purchases than the existing tag was catching, and the strategist switched the account's conversion over to it.

Later fixed a rejection where Google refused conversions from a customer's second purchase when it followed the first too closely.

Merchant Center

Products were disapproved and offline, which means they cannot be advertised at all. Traced it to a broken Clean URL implementation on their own backend: the crawler was hitting 404s and auto-flagging products as unavailable. Wrote the fix for the client, who is their own developer, then corrected it when it turned out they had built the integration on index.html rather than the shop page my first version assumed.

Note on scope: this predates the 1 July start of the tracking window in this log, and is included because the import is still running.

Landing pages

292.1 h Build, backend, deploy, DNS. Tracking for each page is counted above. Sorted by start date, newest first.
22pages builtevery landing page I worked on since January 2026
5paid builds$12,500 invoiced. Client bought the page, so a creative strategist drafted design and copy
13not paid forno page fee, so the whole build was mine end to end
3GMA internalour own funnels and review site
11built solono creative strategist involved at any stage
292.1htotalbuild, backend, tracking, deploy and DNS

Landing Pages 2.0 skill - Codex test buildsInternal · Luke's page and CRM builder, tested on Codex

9.5hStarted 18 Sep
Complex Test builds shared with Luke 18 Sep – 28 Sep
What I did

Carried on from the skillset review with Luke by testing his Landing-Pages-2.0 skill on a clean Codex account, so the results would not be helped by his own history. Updated the tracking part, the data layer and the GTM import container builder, then built test pages with it and went through the CRM build and recovery steps.

Reported what broke rather than only what worked: the brochure PDF was left out, the mobile menu did not return focus after Escape, phone text dropped to 13px on small screens, and form messages used technical wording. Added rules so these are caught next time. A UK accounting page for a business with no website came out in one run, images included, with no manual fixes.

Wrote the Google Sheets connection for form submissions and pushed it to a community branch, and said Formspree is not needed because we already connect forms to the client's CRM, a Google Sheet, or both. Shared six test pages and a live CRM demo on Cloudflare and GitHub on 22 September. Also renewed the expired zoomlink.cc domain, turned auto-renew on for all domains, and asked to use agencymetrics.com for test subdomains. On 24 September tested two more model settings and reported rule violations and missing images.

28 September. Reviewed two more runs for Luke. The research was much better than last time, but images still failed: one run refused to fetch any images, logos or brand colors, and the other skipped them and drew illustrations instead. Said running it in Codex, where it can download images, would likely fix it.

Prestige Botanicals — listicle pageFaux florals · prestigebotanical.pages.dev

19hStarted 17 Aug
Major Live at go.prestigebotanicals.com PPC Management Not paid for 17 Aug – 9 Sep

My partDeploy, DNS, tracking (page built by Valerie)

prestigebotanical.pages.dev

Getting it deployed

The client had not booked a deployment call, so nothing could move. Rather than wait, I pushed the reminder into the strategist channel with the booking link and it was on the calendar within days. Deployed live on the call itself: found the repo, created the Cloudflare project from their account token, and handed back the exact CNAME record to add, which turned out to be at Namecheap rather than Cloudflare. Verified the record myself afterwards instead of taking the client's word, and worked through a 522 and a coming-soon page before it resolved.

Held the page rather than declaring it done: flagged that the author has no profile picture, that the byline reads The Home Journal, and that Michael's own email is on a paid landing page. Recommended a dedicated address used only on paid pages so inquiries from ads can actually be attributed. Valerie then pushed visual changes, so I rebuilt the deployment on her newer version instead of leaving the live page behind the repo.

Tracking

They have no GTM, so the choice was to stand up a container or work in GA4 directly. Took it to the strategist with a recommendation rather than a menu: GA4, because these events import into Google Ads cleanly later, and a separate Ads setup only earns its keep if one of them is going to be a primary conversion driving bidding.

The page has 14 outbound links to the store and eight of them are the same button with the same copy, so a plain click event would say nothing. Specified shop_click carrying a section tag, so we learn which part of the article actually drives clicks, with carousel clicks passing the product name. On top of that, scroll depth pinned to real content boundaries rather than round numbers, a 120-second active-time event that excludes background tabs, and an engaged-reader event combining depth and time, filtered to exclude people who already clicked through, which gives a clean retargeting pool. Set the GA4 tracking up and tested it live.

Found while testing: several products are priced higher in Shopify than on the page. The Magnolia Leaf Branch is $26.39 on the page and $32.99 in the store. Prices were presumably correct when the page was written. Raised it with the strategist and Valerie before traffic goes to it, since that is the kind of gap that kills conversion rate quietly.

The design rework, 24 to 27 August

Luke saw the live page and called it "super AI-looking and generic", with the sans-serif hard to read, and asked for it to be improved before it went any further. The awkward part was that Valerie had built it directly with the client and the client had already approved it, so I put that on the table first and asked how we wanted to handle telling them, rather than quietly redesigning approved work. The answer was to build a better version and let the client choose. I took it to Valerie myself and told her I was reworking it instead of going around her.

Built the second version at prestige-listicle-v2.pages.dev and pushed it to the client's Cloudflare alongside the first. Pulled the real colours and fonts from the client's own site rather than inventing a palette, including the #353535 CTA colour, since the CTAs did not match their brand. Researched what actually makes an elite listicle page for home and floral retail rather than tweaking the existing layout, and pushed back on my own output twice when it was still recognisably the old page with adjustments.

Ran it as a documented process instead of taste: had Claude and Codex produce a written rationale for every section and design element - why it does not read as AI-generated and what creates the high-end feel - then reviewed the page against that document over several passes. The finding worth keeping: Claude is cautious about changing an existing design and needs concrete visual instruction, while GPT-5.6 is much better at improvising a new concept.

Detail work through the same loop: the comparison table reverted and rebuilt for mobile, the compared competitor's name shown in the table with a "click to compare" cue so the interaction is obvious, an image cropping a flower head at the top fixed, a hairline white gap at the right edge on mobile, image annotations moved off the images, and the editor byline moved under the headline. Recommended dropping the "The Home Journal" sponsored-content footer, since we publish on the client's own subdomain and not on a ranking site - Valerie confirmed the footer came from draft notes that assumed otherwise.

Sent v2 to Valerie and then to the strategist to put in front of the client. Also checked the GA4 setup on the page was correct and ready to import into Google Ads.

1 September

Confirmed to Ryan that everything is set up and we have full access, so going live should take up to 24 hours from the approval confirmation.

V2 approved and live, 8 to 9 September

Ryan confirmed the client approved v2, so I moved the tracking built for v1 onto v2 and published it over v1 on the same subdomain rather than leaving two versions live. Minted the Cloudflare token for the client's account from credentials already held, instead of going back to ask for access we had.

Fixed what real devices showed rather than what the desktop preview looked like: the hero image oversized on iPad Pro, a missing favicon, and fonts that had drifted off the client's brand set, which I checked back against their own site. Cut an invented headline that described something the video does not actually show, and moved the hero form and headline where the strategist wanted them. Confirmed the listicle should stay indexable and left robots.txt open accordingly, since this is not a paid-only page.

Checked the two things that decide whether the page earns anything: that cookies and UTMs carry across to the main Shopify store so a later purchase is still attributable to the ad, and which property the page_view conversion actually reports to. Weighed the injected banner against leaving the page alone before doing it, on the basis of what it costs the page rather than whether it was possible. Live at go.prestigebotanicals.com with GA4 tracking confirmed.

Home Reserve — listicle pageModular furniture · homereserve.com/pages/7-reasons

9hStarted 17 Aug
Complex Live PPC Management Not paid for 17 Aug – 31 Aug

My partDeployment to Shopify only - page built entirely by Valerie

homereserve.com/pages/7-reasons

What I did

A listicle page that had to go onto the client's own Shopify rather than a Cloudflare subdomain, which I had not done before. Said so and researched the options first, including whether any tool exists to push a static page into a theme, rather than experimenting on a live store. Established what access was actually needed, pulled Valerie's version from her repo, checked I had the final one after she pushed again, and found a dozen unused images sitting in the repo that did not need to ship.

Reviewed it in the browser before pushing anything, then deployed it into the theme and got it live. Pushed it to both the live theme file and the next one, and told the strategist to warn the client that the page lives on that theme version so their dev has to carry it over when they switch. Checked the URL parameters survive the redirect to the store, since that is the only thing linking a click on this page back to a paid session.

Mobile

Recorded a Loom walking through the layout problems on mobile and tablet, and showed Valerie how to check the same views from her own browser rather than just listing the faults. Desktop was fine throughout. Asked her to record back how she wanted the blocks restructured rather than guessing at her design intent, then applied the fixes and pushed once she confirmed.

On tracking, I would not build anything without knowing what it was for, so I put the question up in writing: which events, and on which platforms. The answer came back that this page needs none, so nothing was built and the test tracking I had set up was removed.

26 August. Valerie pushed further design changes, but to her own GitHub rather than the client's, and there is no Git connection between either repo and the client's Shopify theme. Re-authorised Shopify access and pushed her version into the theme by hand, then checked her changes had not undone the mobile fixes before calling it done. Told her plainly why this page cannot auto-update and that every change needs a manual authorise-and-push, so she does not expect her commits to appear live.

Footer added, 31 August

Added the footer the client asked for: logo plus links to the privacy policy and terms of use. Thought through what happens if someone follows one of those links and then browses on from the policy page, rather than just dropping the links in.

Watchmaker Genomics — cfDNA pageNavigator client · go.watchmakergenomics.com

20hStarted 3 Aug
Major Client review Navigator Not paid for 3 – 27 Aug

My partSolo build - no strategist

watchmakergenomics.pages.dev - live draft. The go. subdomain is not resolving yet, waiting on the client's IT team to finish the DNS change.

What I did

Ran the build. Product chosen from campaign data rather than preference. Headline built on their verified 9x yield at 1ng figure and their real BSI certification. When asked to confirm a claim wasn't already used elsewhere, I checked every landing page on the site and listed them all rather than answering from a spot check. Confirmed no testimonials exist anywhere for this company and used none.

Set up the client Cloudflare account and project, diagnosed the subdomain SSL error, and wrote a short DNS change request for their IT team — cut down twice because my first versions were too long for the audience. Checked their registrar and DNS are both on GoDaddy before writing it.

Page is up on a preview URL and working through the last visual fixes plus the hero image, which I'm generating rather than sourcing stock. Checked the go CNAME directly instead of taking the client's word that it was set. Held it back from the strategist until the tracking audit was out, since that was the higher priority for them this week.

Page build, 10 to 12 August

Generated the hero image rather than settling for stock, iterating the prompts until the composition worked, and built a standalone hero preview so it could be judged on its own before going into the page.

Ran a full critical review of every section through a second AI model as an independent check on my own work, then listed every proposed fix and got confirmation before changing anything, marking which were genuinely relevant. Landed on the V5 hero after comparing variants side by side in the browser instead of describing them.

Applied two client content rules carefully: the CTA became "free sample" wording, and no competitor is named anywhere on the page. Their supplied logos are partners, so those stay.

Sent to Luke for review on 11 August and chased twice; he picked it up on 19 August. Also shared it in the client chat in Metrics so the review sits with the account rather than in a DM.

Copy rewrite and a design pass, 25 to 27 August

Luke rewrote the page copy, so the first job was getting his version onto the page exactly rather than paraphrasing it, then opening the density out - his note was that it needed room to breathe. Varied the header lengths deliberately across the page instead of running nine identically shaped headers, which is what makes a page read as a template.

Then a long pass on the things that actually break trust on a genomics page: the sticky mobile CTA text, the CTA moved under the image on mobile, duplicate numbering in the proof section, competitor names dropped, the hero image no longer cropped at any width, headline and subheadline colour, and the CTA centred on the screen rather than on the headline - which I had to redo after getting it wrong from the screenshot the first time. Aligned the plasma headline's top edge with the top of the hero image.

Also caught that the old version was still serving on the pages.dev link after I had pushed changes, and redeployed to the current one, since a review against a stale URL is worse than no review.

Patterson's Water — landing pagego.pattersonsqualitywater.com

3hStarted 6 Jul
Moderate Live PPC Management Paid build · $2,500 · Jun 2026 6 – 20 Jul

My partBackend, deploy, DNS, tracking (design draft by Valerie)

go.pattersonsqualitywater.com

What I did

Took the page live and wired the backend. Form submissions flow into Marketing 360 contacts, the client gets an email for every submission, and everything also lands in our sheet as backup. Fixed a multi-step form bug where focusing the zip field pushed the last field onto the next page, and reworked a custom dropdown twice before concluding the native browser control was genuinely better and reverting — rather than defending my own work.

Ran a full PageSpeed and Lighthouse pass and applied the fixes. Merged Valerie's late change (adding Tim's photo) and verified it hadn't collided with mine before pushing.

Vantage Elite Fitness — landing page & trackingDallas PT · go.vantageelitefitness.com · WordPress + Cal.com

17.5hStarted 3 Jul
Major Live, sheet delivery re-verified PPC Management Not paid for 3 Jul – 30 Sep

My partBackend, deploy, DNS, tracking (design draft by Valerie)

What I did

go.vantageelitefitness.com  ·  mobile preview at vantage-elite-lp.pages.dev/mobile-preview

Built the page, the Apps Script backend into a shared sheet, and the thank-you page. Added a per-browser 15-minute resubmit lock after finding I could submit five times in a row — that's both spam protection and conversion-inflation protection. Fixed the phone field to reject letters as typed and corrected its formatting. Ran the page through a mobile pass and fixed the header phone number and footer service-area ordering.

Images. Migrated everything to the client's Cloudflare so nothing depended on their WordPress, then when images still vanished for some viewers, diagnosed it as browser cache holding the old WordPress URLs and re-uploaded every image under new filenames so even cached pages recover.

The calendar. Embedded Cal.com on the thank-you page and rebuilt the layout to match their main site — removed the stray Cal.com branding and link, dropped an empty photo block, tightened the spacing, and got the calendar visible without scrolling. Caught that booking redirected users off to the main site and reverted to the live version until it was fixed properly.

DNS. The client had moved DNS management from Squarespace to Hostinger mid-build. I established where DNS actually lived, wrote step-by-step instructions for the client, and rewrote them repeatedly — including redoing the PDF after checking how it actually looked — because the first versions weren't clear enough for a non-technical reader. Then I ran it directly by email with Zach and his assistant: when they couldn't find the option my document described, I read their screenshot, worked out the actual path on their account (Websites → the domain → Advanced → DNS Zone Editor), and walked them to it until the record was added and I could confirm it live on the Cloudflare side.

Tracking for this page. They had no GTM at all and a hardcoded gtag. Built a complete container from scratch, passing all 28 checks on our validator, using the four-component Enhanced Conversions pattern with the UPD tag firing before the conversion tag. Installed it on WordPress via GTM4WP, then tore out the old tracking cleanly — disconnected Google Ads and GA4 from Site Kit to stop double counting, found and removed the HFCM snippets, and worked through LiteSpeed's JS deferral and cache settings so nothing was being suppressed. Added a tracking template in Ads. Tested in GTM preview before publishing, caught the UPD tag not firing on the calendar submission, and fixed it. Pushed back on a page-view-based conversion in my own setup, since a reload would have counted again.

The Cal.com trigger. My booking listener pushes cal_booking_success, but the same event fires on both the main site and the Go subdomain, so a naive trigger would double-count. Split it by hostname to keep them separate and future-proof against someone changing the main site later.

Caught in testing: the main-site contact form showed as inactive since 18 July, and GTM debug wouldn't attach on the thank-you page. Both found by me while testing rather than reported by anyone else, and both fixed.

Iteration: a continuous loop with Valerie and Andrew over layout — how many results fit on one line in Kevin's story, how the certification badges should wrap — plus repointing submission emails to the client once testing finished.

Phone field bug, 13 August: reported that a visitor typing the leading country code lost a digit. The formatter stripped to digits then hard-cut to the first ten, so 12142530395 became a different, valid-looking ten-digit number - and it passed validation silently, which meant a wrong phone number went to the lead sheet and to Google Ads enhanced conversions. Fixed it to recognise a leading 1 as the country code and strip it from everything recorded, and had to raise the field's maxlength and pattern or the browser would have blocked the longer formatted value from validating at all.

Then I overreached: I also added area-code rules and made over-long input display back unformatted, which let fourteen digits sit in the field. Bohdan caught it, and I reverted everything except the leading-1 fix and re-verified against the live URL.

14 August: confirmed the fix to the strategist and clarified ownership: the page sits on the client's own Cloudflare, so their dev can edit it, and our access is limited to the API key they handed over on the deployment call.

26 to 27 August. The strategist asked to split the page into weight-loss and muscle-gain versions on a new URL, with the client making their own copy changes, and to embed a client video. Said what needed saying: this is out of scope for a page we did not charge for, I would fit it in around paying work, and it should be leveraged for a Clutch review rather than absorbed silently. Specified Wistia's free tier for the video rather than self-hosting, because it is the fastest option for page performance and costs the client nothing.

Their own developer turned out to have no access to edit the page, so rather than becoming the permanent bottleneck I offered two routes - add the dev to our repo so both sides can push and the live page auto-updates, or hand the page to their GitHub and Cloudflare and keep access - and sent the full zip with every asset so they are not blocked either way.

Variant page stalled, 2 September

The client's web developer came back saying they built the site in WordPress and Elementor, cannot use GitHub, but can produce the video embed code. Told Andrew clearly what that means: anyone tweaking the page needs to be able to work with GitHub, and if the design stays the same I can duplicate it and apply whatever copy they provide. Still waiting on the Wistia embed code.

Video section added, 8 to 9 September

The Wistia embed finally arrived from the client's developer through Andrew, six weeks after the first ask. Added a new section with the video and shipped it muted, working through our repo and the API connection to the client's Cloudflare rather than waiting on their developer again, and told Andrew it was done. Left tracking for the new section deliberately, since it measures nothing until ads point at it.

17 September. Andrew reported that leads had stopped reaching the Google Sheet and that a test submission of his never appeared. Submitted one myself before touching anything; it landed in the sheet. Rather than closing it as working, asked him how exactly he submitted his, since a submission that fails for him and not for me is a real difference worth finding.

24 September. Asked Daniela to check with the client whether they are still seeing submissions go missing from the sheet, and whether the plan to duplicate the page into separate weight loss and muscle gain offers is still on, with copy for both.

29 and 30 September. Booked an LP deployment call with Daniela and tagged her in the page thread so she could pick up the deployment side.

Body Temple SpaNavigator client · lymphatic massage

9hOngoing through window
Complex Live Navigator Not paid for Jul – 4 Sep

My partSolo build - no strategist

lymphatic.pages.dev

What I did

The broadest single client relationship in this period — page, tracking, backend and enablement. Tweaked tracking on the existing pages, built a new landing page and a new PDF brochure, and set up the tracking for the new page.

Beyond the build, I ran several calls with the client and her assistant: taught them how to use Claude to produce their own landing pages, using the page we'd built as the worked example, and walked them through creating and managing GHL webhooks themselves.

I was her direct contact - she emailed me rather than a strategist, and I handled the page end to end.

Tag firing outside its hostname, 4 September

A Google Ads lead form tag scoped to the go subdomain fired while I was testing a thank you page on the main site, which would have counted those leads twice. The preview summary showed it as fired and the event view showed it blocked, so I worked out which of the two is true for the live page instead of trusting the summary. It survived a fresh publish and a different browser and has only one trigger, so I traced the trigger and the conversion label back from the tag to find why a hostname-scoped tag was matching a hostname it excludes.

Seneca — cost segregation guide pageTax services · guide.senecacostseg.com · build + deploy

14hStarted 26 Jun
Complex Live PPC Management Not paid for 26 Jun – 20 Jul

My partSolo build - page not paid for, so no strategist

guide.senecacostseg.com

What I did

A nine-phase rebuild of their cost-segregation guide page under a verified-claims-only rule - no number goes on the page unless it is sourced, which matters on a tax page. Ran a real performance pass afterwards rather than assuming: the guide mockup went from 605KB to 38KB as WebP, fonts made non-blocking, LCP hero preloaded, low-contrast text fixed, phone paste unblocked.

Deployment

Took it from built to live on the client's own infrastructure. Recorded a Loom showing their developer how to create a Cloudflare API token, and made the point that he can revoke it once the page is live, plus offered the alternative where he imports the repo himself and we never hold a token at all. Diagnosed the CNAME pointing at a stale Workers hostname and gave the exact replacement value. Conversion set as secondary; raised whether it should carry a value (the contact form is $50) rather than deciding unilaterally.

Open Bionics — Find a Clinic pageProsthetics · openbionics.com/find-a-clinic

8hStarted 27 May
Complex Live PPC Management Not paid for 27 May – Aug

My partBuilt with Valerie - my part was the build, backend and all tracking

openbionics.com/find-a-clinic

What I did

Built with Valerie and shipped into their WordPress site rather than a subdomain, because the page had to sit inside the main clinic path. My part was the build, the backend and every piece of tracking on it.

The page is the reason several later findings exist: leads converting on its thank-you page could never match the custom conversion their Meta account had been counting since 2025, which is what explained a 142 versus 25 lead discrepancy.

Hours are an estimate and have not been reviewed.

Better Place Design Build — landing pageConstruction · go.betterplacedesignbuild.com

6hStarted 27 May
Moderate Live PPC Management Paid build · $2,500 · May 2026 27 May – 2 Jun

My partDeploy, DNS, form tracking, call tracking (design draft by Valerie)

go.betterplacedesignbuild.com

Deployment

Deployed onto the client's own Cloudflare account and wired the subdomain end to end, working around the domain being pointed at the registrar rather than through Cloudflare. Tightened the copy, including softening the thank-you wording.

Form tracking

Set up form submission tracking for the page and created the Google Ads goal "Submit lead form (go LP)", left on secondary so it could be validated before it influenced bidding.

Call tracking

Found the CallRail setup could not work as configured: the website pool was built around one swap target while the landing page and the main site both used a different number. Rather than guess, I laid out the three ways to fix it - repoint the swap number, create a second website pool, or run multiple swap targets - and got the client to confirm which number was correct. Once resolved, verified numbers were swapping on both the landing page and the main website.

Greenville CoinsCoin dealer · go.greenvillecoins.com

26.5hStarted 11 May
Major GHL automation built, awaiting a real deal to test PPC Management Paid build · $2,500 · Apr 2026 11 May – 1 Oct

My partBackend, deploy, DNS, video, tracking (design draft by Valerie)

go.greenvillecoins.com

Build and deployment

Valerie produced the design draft. Everything from there was mine. Accepted the repo invitation, created the Cloudflare project and wired it to GitHub so the page redeploys on push, and sent back full and mobile preview links.

The page then had to move off my account onto the client's own Cloudflare. I minted a scoped token from their token-creation token, migrated the project, and registered go.greenvillecoins.com against their GoDaddy CNAME. Deliberately kept the mobile preview on the pages.dev URL only rather than exposing it on the client's subdomain.

Embedded their Wistia hero video and restyled the player - nav bar and play button recoloured to the page palette rather than leaving Wistia's defaults.

Tracking

Set up landing page tracking and CallRail from scratch for the page.

Later changes

July: made the top-left logo link through to their main site, and rather than letting that traffic go dark, created a new Google Ads conversion for it so we can see how many LP visitors move on to the main site.

August: scoped offline conversion import for in-store sales - pull GCLID (or GBRAID/WBRAID) from CallRail, with name, phone, value and date from the client. Flagged the real limit honestly: if someone calls from one number and gives another in store, that sale cannot be matched unless their system links the two.

Built it, 20 August. The client sent their first call list with revenue back to 1 July and said they are happy to keep doing it, so I turned the scope into a working import. Pulled the CallRail side through the API, checked whether one API key covers every CallRail client under our management rather than assuming it does, and rebuilt the whole thing as a reusable offline-conversion skill so the next client is setup rather than rework: the CallRail company recorded in the script, correct sheet naming, hashing done in the sheet, and the sync interval dropped from every six hours to daily as the default with weekly for this client, because nothing here changes six times a day.

Caught a wrong claim in the skill's own notes rather than shipping it: it said gbraid must never be joined on because it is shared across many users. It is not. A gbraid can repeat across separate purchases by the same user, which is a different problem with a different fix, and the note was corrected.

Import automated and running, 24 to 25 August

Turned the manual import into an Apps Script that does the whole job in the client's spreadsheet: pull the CallRail call history through the API, match each purchase in Raw Purchases to the call that earned it, and write a Data Manager-ready upload sheet. Refused to let the script re-fetch purchase data that already sits in the sheet, and confirmed which sheets could be emptied and which the matching depends on before touching any of them, so renaming a tab could not silently break the match.

Pushed hard on the matching rule rather than accepting the first pass. Confirmed it takes the last GCLID before the purchase date, not simply the most recent click, and that a click landing after the sale is ignored. On a row reported unmatched I found older GCLIDs sitting under that caller's CallRail profile and had the script fall back to the earlier click instead of dropping the sale. Added exact-match fallbacks on email and name for customers who bought on one number and called from another, after checking against the real data first rather than building for a case that does not occur. Established that GBRAID and WBRAID are not available on this account, and that CallRail exposes click data only for calls, not for every click.

14 purchases matched and uploaded. Asked the strategist whether the action should be primary or secondary rather than deciding it myself; secondary for now, since the client has no CRM yet. Also asked how the client assembled the purchase data in the first place, because if it lives in a system we can reach, the whole run can be scheduled instead of pasted in by hand. Installed the trigger so it runs on its own.

Open: Data Manager accepted all 14 with no errors, but Google Ads recorded 6 and flags no enhanced-conversions data. Chased whether the phone hashing is the cause: whether the number needs the country code, in which form, and whether the email column was actually populated. Not resolved yet.

Import reconciled, 31 August to 1 September

The client's side had finished appending the GCLID from their CRM back into Shopify, so I matched the records and ran the import rather than waiting for certainty that the fix was complete. Cai flagged errors in the platform and only three conversions visible. Reran the import with zero errors and all 14 conversions accepted by Google, and told him straight that only 6 of the 14 are currently counted in Ads, that this is a common gap and not something we can fix.

Traced the earlier errors to missing emails on most orders, which is not a problem because phone numbers are still being sent, so I removed email from the import entirely and expect those errors to clear from the goal within one to two weeks. Also checked why some GCLIDs look like EAIaIQobChM... and others like CjwKCAjw... before treating them as a data fault, and reviewed how customer data is hashed in the import script.

3 September. Cai forwarded an updated call and transaction list from the client for the next upload. Queued, not imported yet.

GHL access and what it can actually do, 9 to 10 September

Chased the GHL invite through Cai when nothing arrived in the admin inbox, and asked for it to be resent to a dedicated alias rather than the shared admin address, which is already carrying five other logins. Confirmed access once it landed, tested the connection, and found a brand new account with the deals pipeline already in it.

Told Cai plainly that there is very little tracking to build in GHL here rather than inventing scope: no landing pages or forms in GHL, and no form on our page either, so CallRail already covers the Google Ads side. What is worth doing is an automation that pushes purchases from the deals pipeline into the offline conversion sheet, needing nothing manual from the client beyond moving the deal to the purchase stage. Checked whether a direct GHL to Google Ads import would be better and said it would not: GHL does not store GCLIDs and has no CallRail integration, a custom bridge would need me to fix every failure by hand, and the number of offline conversions recorded in Google Ads would not change, so the switch would be cosmetic. Also said up front that rebuilding a working import would be billed separately, and covered what GHL is genuinely worth to them, a CRM they need and email campaigns at usage rates rather than another subscription.

GHL purchase automation built, 15 to 16 September

Cai needed it before catching up with the client, so I built the automation that pushes won deals out of the GoHighLevel pipeline into the offline-conversion sheet. Kept it deliberately small rather than building the general case: deals land in Raw Purchases only, with email, and nothing else in the workbook changes, because the client will at most send one more purchase list and everything after that comes from GHL.

Deployed it and left the existing daily trigger alone rather than recreating it, since the trigger lives in the Apps Script UI and is not part of the code. Told Cai the one thing that can break it in practice: the automation fires on the stage move, so whatever value is on the deal at that exact moment is what reaches Google Ads, and the value has to be right before the deal is moved. Said plainly that it needs a real deal to reach that stage before it can be proved, and asked for a ping when that happens rather than declaring it tested.

29 September to 1 October. The client started moving deals into the purchase stage, so I checked and confirmed the automation was matching purchases into the same sheet. Cai asked whether all purchases could go back, not only gclid matches. Suggested uploading all of them to a separate Secondary conversion to see what Google can recover, and he agreed.

ServiceMaster RestoreRestoration franchise recruitment

25h7 May
Major Delivered PPC Management · past client Not paid for 7 May

My partSolo build - page not paid for, so no strategist

smr-franchise.pages.dev

What I did

Built in a single sustained day - 84 prompts - with repeated hero and structure reworks against a reference page and Luke's copy feedback. Rather than only fixing the page, I fed the feedback back into the skillset so the next build starts from corrected rules. Repo bohdanshev/servicemaster-restore-franchise, delivered as a handoff package.

Byrider FranchiseAutomotive franchise recruitment · go.byriderfranchise.com

18hStarted 8 Apr
Major Live PPC Management Not paid for 8 Apr – 4 Sep

My partSolo build - page not paid for, so no strategist

go.byriderfranchise.com

What I did

Full build from research through deployment. Two-step popup form with the country field locked to US because they only franchise there, an Apps Script backend emailing submissions into FranConnect, GTM-W774K2V8, and a packaged handoff zip for their developer.

Iteration: seven working sessions. Rebuilt more than once - the first version was too short and had no photos, then reworked toward a luxury franchise direction, then again against a reference page. Client feedback removed the Franchise Times ranking claim and changed the sticky header. Also drove a copywriting rules rewrite in our skillset after I found that giving the model worked examples made it copy them instead of applying the principle.

4 September. Told the strategist plainly that the change has to be made on the client's side: we have no access to the live page, and their own developer published it from the zip we handed over.

New Review GuideMulti-page review site

6.2hStarted 1 Apr
Moderate Live Internal GMA internal 1 Apr – 30 Jun

My partFull build

www.newreviewguide.com

What I did

Consolidated articles from two competing page variants into one site, then solved the real problem: GTM had to be present on every page including ones that do not exist yet. Rather than tagging pages one by one, added middleware so new pages inherit GTM-K3MH45T4 automatically. Repointed CTA redirects and tightened the "contains /reviews/" trigger so it stopped over-matching.

Also built the full GA4 tracking setup in GTM for the site, not just the container rollout - the events, the configuration and the conversions, so the review pages actually report rather than just carrying a tag.

Coastal Creationsgo.coastalcreationslps.com

5.7hStarted 27 Mar
Moderate Live PPC Management · past client Not paid for 27 Mar – 1 Apr

My partSolo build - page not paid for, so no strategist

go.coastalcreationslps.com

What I did

Hardened the live form's security and reworked the Apps Script backend after reviewing how it could be abused. Handled a mid-flight hosting move from Cloudflare to Hostinger, recovered the live version when the local copy had drifted from what was deployed, and reorganised the project into clean per-subdomain folders.

Caught: a form that redirected to the thank-you page while silently failing to write the lead. That is the failure mode that looks like success, and it is why I now test live submissions end to end before calling anything done.

Capital RoadFinance · go.capitalroad.net

7.7hStarted 26 Mar
Complex Live Navigator Paid build · $2,500 · Mar 2026 26 Mar – 12 May

My partBuild, backend, tracking (Valerie's repo)

go.capitalroad.net

Invoiced under their legal name, Pershall Group LLC, so it does not read as "Capital Road" on the billing export.

What I did

Ran the discovery phase and produced a client-ready brief, reworked several times until it read like something a human wants to read rather than a technical document. Then processed thirteen rounds of section-by-section PDF comments: extracted the sticky notes programmatically, recorded them per section first, and only then applied the copy changes so nothing got lost. Merged the design-improvements variant and unified fonts. Added a custom PDF-download event that fires on the actual file load rather than the click, so the GTM conversion means something. Debugged the go. subdomain failing to resolve on the client's Cloudflare.

GMA training funnel (training.growmyads.com)GMA internal · low-ticket funnel, opt-in through purchase

39.5hStarted 18 Mar
Major Live Internal GMA internal 18 Mar – 9 Sep

My partFull build, with Valerie on the opening NEPQ page

training.growmyads.com

Opening phase - NEPQ rebuild

The project started by rebuilding a reference funnel page block by block in GMA colours, keeping every asset and section rather than producing a loose approximation. Built with Valerie. Merged an eleven-commit proof-section restructure across 31 files into the v1 page. Also unpicked a repo-versus-Cloudflare sync problem that had her blocked, worked out exactly what she needed to push and where, and granted a new contributor access. Several rounds on the header logo alone - it kept coming back invisible or replaced rather than recoloured.

Our own paid funnel, and the largest single build of the year at 464 logged prompts.

What I did

Built the multi-page funnel (opt-in, order-confirmed, thank-you), embedded Wistia hero teasers, and restructured the copy to follow the copy document's section spec rather than approximating it. Wired the ThriveCart popup and Calendly booking, and rewrote the Loom embeds so learners cannot click through off the ThriveCart Learn platform.

For purchase tracking I skipped the fragile route and sent ThriveCart webhook to a Cloudflare Worker to Meta CAPI directly, then proved it with a real 100% discount test order rather than declaring it done. Reported that /book-the-call was 404ing.

Iteration: heaviest feedback loop of the year - repeated hero and structure rewrites against Luke's copy notes, plus a mid-project handover when a coworker had been holding the repo.

Video B live and the UTM loss, 7 September

A second page went live at /video-b ahead of ads being pointed at it, so I checked its whole tracking path against Video A rather than assuming a copy behaves like the original. Found the Video B form redirecting to the Video A thank you page and pointed it at its own, and confirmed no duplicate events.

The real problem was that some bookings reach OnceHub with no UTMs at all. Traced it to redirect timing instead of blaming aggressive adblockers, which was the easy answer sitting there. Fixed it on Video B first, tested it there, had Codex and an independent agent confirm the fix works and introduces nothing new, and only then pushed to Video A, which carries live traffic. Told Luke what the test submissions were when he noticed them, and wrote the client the short version of what was found, what was working and what was fixed, with nothing padded.

The campaign that looked dead, 8 September

Alex reported the Meta campaign had stopped producing since the tracking fix, which made the fix the obvious suspect. It was not. Lead events were recording correctly in Meta; the problem was that none of the previous seven days of prospects qualified, so none of them could book. In OnceHub a qualified booking carries a Schedule tag, and for a week that tag had appeared only on my own test submits, with every real Meta lead sitting at Completed. Counted it out for him: twelve real unqualified leads so far in September, a few missing UTMs from the redirect timing, and no Meta Schedule bookings lost to that this month. Worked the Meta side by hand first, reproducing the lead event in the browser network panel against a test event code rather than reading the Events Manager summary back.

Also pinned down what can and cannot be changed on the Google side, where the running campaign only carries Schedule in its settings and the purchase conversion comes from ThriveCart, and kept to verified answers on it.

Form broken and repaired, 9 September

The Video A form went slow and stopped advancing past the phone step, which is the worst outcome a tracking change can have on a live funnel. Found what had been added and where, and got the form working again. Also caught that the step order had changed so last name came after phone, which breaks the form's own logic, and established who changed it from the record instead of guessing at it. Fixed the step numbering while checking phone normalisation still holds for other countries, and dropped my own worry about the phone format once it turned out OnceHub normalises on its side anyway. Chased the UTMs still reaching the Apps Script sheet with an unbranded medium and no term or campaign, and did not book real times while testing.

go.growmyads.com landing pageGMA internal · our own lead page

7hStarted 20 Feb
Major Live Internal GMA internal 20 Feb – 22 Apr

My partFull build

What I did

Built the go.growmyads.com page from our master prompt, then ran it through several compliance passes against our own blueprint and fixed every violation I found, including a version that shipped with no images or video at all.

Not currently live. go.growmyads.com returns 404 today, so the page is either unpublished or has been replaced. Worth confirming what happened to it.

Buena Vista NY — landing pageHell's Kitchen restaurant · page hosted on New Review Guide

4hStarted 18 Feb
Moderate Live PPC Management Not paid for 18 Feb – 7 Apr

My partNot my build - Valerie built the page; I did the changes, backend and tracking

newreviewguide.com/reviews/buena-vista-nyc  ·  on www.newreviewguide.com

What I did

The page itself was Valerie's build, not mine. My part was the changes and the backend: I matched the restaurant's design language, colours and fonts from their main site, sourced better photography after rejecting the low-quality images in the draft, and connected the repo to Cloudflare so the page auto-updates on push.

Worth reading alongside New Review Guide above - that site was built to host this page, and the site itself was mine end to end.

VidaBoxLuxury home technology · 5-reasons advertorial

13.5hStarted 16 Feb
Major Delivered To confirm Not paid for 16 – 20 Feb

My partFull build

What I did

An advertorial rather than a standard landing page, so I ran it through a panel review framed around luxury-product advertorial craft before returning a version. Rebuilt the client logo wall after the first attempt looked poor, and colour-matched the footer and palette against the live vidabox.com rather than approximating. Footer set to the exact legal wording they required for the VidaMount brand under VidaBox LLC.

Iteration: I made the build screenshot both the original section and my version and compare them, because "close enough" kept passing when it should not have.

No live URL. Built as standalone HTML with no repo and no deployment, so there is nothing to link. Service tier still to confirm.

Lexani MotorcarsLuxury Sprinter conversions

13.5hStarted 26 Jan
Major Live PPC Management · past client Not paid for 26 Jan – 26 Mar

My partBuilt with Valerie - my part was build, tracking and backend

lexani-motorcars.pages.dev

What I did

Brand-matched to lexanimotorcars.com down to fonts and tone, with real vehicle photography pulled from their own site. Built a dedicated mobile layout after emulation kept failing - the phone number was cut off and iOS rendered content under the dynamic island. Verified every placeholder claim against real sources before it went out. GTM-TDQ2DG9L, form submissions into a two-tab sheet (Leads for the sales team, UTM Params for us).

Iteration: seven sessions, the most design back-and-forth of any client page. Later flagged that the agreed go.lexanimotorcars.com had been changed to /learn-more/ without telling us, which meant reconfiguring the tracking - raised rather than silently absorbed.

SAB Group — two pagesNegotiation training + Procurement

10.5hStarted 14 Jan
Major Live PPC Management · past client Paid build · $2,500 · Dec 2025 14 Jan – 26 Mar

My partFull build + tracking

Other

67 h Recurring internal work, team process, and environment. Sorted by start date, newest first.

GHL email exclusion for current clientsInternal · GoHighLevel campaigns

2.5hStarted 28 Sep
Moderate Done 28 Sep – 1 Oct
What I did

Luke asked to stop GHL email campaigns going to current clients. Before excluding anyone I asked Anna, Luke and Mash who runs the campaigns, because Navigator clients get their own emails there. Pulled the client emails from Pipedrive against the current client list and checked which were in active or recent campaigns.

On 30 September I turned on DND for the 119 current clients. Rikki saw it as blocking her campaigns, so I reverted the DND on 1 October and replaced it with a tag, client-exclusion-list, on the same 119 contacts, and told Mash to add "Tag is not client-exclusion-list" to every new campaign.

Meta partner access processInternal · client asset sharing

1.5h14 Sep
Quick In use 14 – 15 Sep
What I did

A client had sent a Meta invitation to our admin inbox and it could not be accepted, because nobody here logs in as that address. Rather than reply that it had not worked, I established what the correct route actually is - the client sends a partner request to our business portfolio - and wrote the step-by-step instructions for it, since I had only ever done this for Google Ads.

Wrote it as the access levels rather than a list of clicks, and said what each one costs them: full control on the ad account, because the partial option lets us run ads but not fix settings, billing or permissions, so every settings fix comes straight back to them; partial on the Page and Instagram with exactly two boxes ticked, so we are not reading their inbox or posting for them; full control on the pixel, because the view-only option means we could not fix their tracking; and the catalogue only if they actually run product ads.

Had it checked before it went anywhere near a client - first with Anna, who confirmed the invite route was wrong, then with Drew - and only then sent it on for the client who needed it. It is written to be reused rather than for one account.

Request intake automationInternal · Cloudflare Worker · Slack + inbox → ClickUp

5hStarted 11 Aug
Moderate Fixed and live 11 – 13 Aug
The symptom, and what it actually was

Tracking and landing page requests are supposed to become ClickUp tasks automatically, and new ones had stopped appearing. The worker looked alive, which is what made it misleading: the cron was firing daily, the email path was still creating tasks and the daily stale-task digest was still posting. Only the Slack read path was dead - no Slack-sourced task since 24 June.

Root cause was a revoked user token. I proved it rather than inferring it: forced the worker to rebuild its channel list so it had to call Slack with whatever credential it really holds, and watched the tick abort before writing anything, which rules out any mix-up between the token on disk and the one deployed. The stored keys showed the stop was genuine rather than expiry, and the cron turned out to have been created about an hour after the last clean scan - so it broke at the corporate account cutover and had never once completed a clean pass.

Corrected myself twice: I first said the worker had stopped working, and that was too broad - it kept creating tasks from email throughout. I also wrote that it failed on the first channel, when in fact it aborted before reaching any. Both narrowed once the evidence was in.

The fix

Rotated the Slack credentials and redeployed, verifying the deployed script hash matched the source and that all five secrets and the cron survived. The channel list rebuilt to 103 - up from 97, so new client channels had appeared during the outage. Seeded the duplicate guard so the catch-up run could not re-create tasks that already existed, then let it scan the whole 29 June to now gap silently, with no channel posts, so the team just sees the recovered cards. Added an alarm that posts if the Slack credential ever dies again, which is the thing that would have caught this in June.

Access: reinstalling the Slack app hit a wall - the admin scopes it asked for are Enterprise-only on this workspace - so the fix went through a user token instead. Cloudflare access turned out not to need a minted API token at all, just a login, which removes a recurring expiry from the setup.

Project work logInternal · gma-work-log.pages.dev

12hStarted 6 Aug
Complex Live 6 Aug – 18 Sep
What I did

There was no single place showing what tracking and landing page work had actually been done, so I built one. Pulled every project from my own session history, Slack, inbox and ClickUp, estimated the hours each had taken, and published it as a page the team can open rather than a document someone has to be sent.

Reviewed the estimates myself and corrected the ones that were too generous — a short audit plus a written finding is an hour, not three — and added an explanation of what each complexity band means, since the labels are useless without it. Set it up to be rebuilt from a single data file so new work gets added rather than the page being rewritten, and put it on a weekly refresh.

Landing pages breakout, 13 August

Extended it to answer a question the page couldn't: for every landing page of the last year, which service tier the client is on, whether they paid for the page separately and how much, and what my own part of the build was. Added a summary panel above the section - pages built, how many were paid, how many were built solo with no strategist involved - since the point is the split between paid builds where a strategist drafts design and copy and unpaid ones where the whole build is mine. Dropped a test project and one I couldn't identify rather than listing them, corrected a payment figure and a misattributed client, and removed a note about publishing a container to the wrong account.

21 August: the 14 August run had only Claude history to work from and its deploy failed on an auth error, so this run re-covered 11 August onward with Slack, Gmail and ClickUp as well and pushed the site live again.

4 September: the run published with Gmail unreachable and the notifier said so, so I re-covered 28 August onward once the connector was back - which is what surfaced the client email work that exists nowhere but the inbox. Also sorted out which Google account each source should use: bohdan@ for the work log's mail, admin@ for the ClickUp side.

10 to 11 September: the published site still showed 4 September, so I checked why the weekly run had not fired rather than just running it by hand, went through every connector, and tracked down which function is supposed to trigger the run in the first place.

Cut down for a call, 14 to 15 September

Anna asked for a shorter version of this for a call with Luke, so I reworked it into a single readable summary with charts rather than sending the full log. Most of the work was correcting it. The first pass led on the least valuable thing I had done for a client and had to be rewritten to lead on the tracking and landing-page work that actually mattered. The page count did not add up against the paid, free and internal split. It claimed twelve months of data when the log only goes back to July, so I recut it to the real window rather than leaving a number that flatters. Two projects were miscredited - one page I only deployed, another built by Valerie - and two more were listed as needing checks when they were finished, so they moved to completed and the rest were dropped.

Also rejected my own framing. Calling it a measurement page made it read as a scoreboard rather than an account of the work, so it was renamed. Fixed a chart nobody could read - the colours were too dark and the numbers did not sit under the segments they belonged to.

New client onboarding automationInternal · ChargeOver → Pipedrive, ClickUp, Slack

13hStarted 31 Jul
Complex Live, Zap retired 31 Jul – 30 Sep
What I did

A Zap failing its test with "cannot filter by _zap_static_hook_code" looked like dead authentication. It isn't — the connection is fine and other triggers work; it's a bug in ChargeOver's own app affecting the New Customer trigger, reproducible even in a clean Zap with no filters or steps. Gave the decision path so nobody rebuilds a working Zap for no reason.

The Zap never came back, so I replaced it, 14 to 15 September

Three months after the diagnosis the Zap had still not posted anything, so instead of chasing ChargeOver again I rebuilt the whole automation as a Cloudflare Worker. It polls ChargeOver every 15 minutes for new subscriptions, matches the customer in Pipedrive, and then writes the ClickUp fulfilment task, marks the deal won, and posts to Slack - in that order deliberately, so Slack only fires once everything else succeeded and a mid-run failure can never leave a won deal with no task behind it.

Refused to guess at the branches that decide what happens. A matched deal with no prior win is new; a prior win 60 days or more back is a returning client and says so in the message with the previous deal linked; a person with no deal, or nothing matched at all, posts an alert and writes nothing anywhere. That last part was a decision, not a default - a bad automatic match is worse than a human look, so unmatched cases go to the channel for review.

Built the safety in before the features. Idempotency keys on the subscription rather than the customer, because 17 emails in ChargeOver span two customer records and a customer-keyed check would be wrong in both directions. The first run seeds its position and processes nothing, so it can never onboard 537 historical customers into Slack. Batches are capped per tick and the mark advances, so no volume of new subscriptions can make a run fail. It shipped behind a dry-run flag with a one-line rollback, and the old Zap stayed switched on until the Worker had proved itself.

Put it through an independent Claude review and an independent Codex review before connecting it to anything, and worked through what they found rather than accepting the pass. Created the Slack app and its icon, drafted the message format and had it checked before it went near the channel - returning-client status in bold, the amount paid in bold, the supporting detail greyed down - and deliberately backfilled only the last seven days rather than every missed payment. Live and posting; the first real returning client came through it the same day.

Payment notifications, 29 and 30 September

Changed the billing notifications to the rules agreed with Anna: Navigator deposits and payments to the Navigator channel, management deposits to management, one-time payments to their own channel, nothing for renewals of existing subscriptions, and nothing for Copilot, which is billed elsewhere now. Backfilled the last ten days, posted the latest one-time payment to check the channel, set it to run automatically, and moved it to the company Cloudflare account rather than my personal one.

Deployment process documentationInternal · LP deployment and production manual

9.5hStarted 9 Jul
Complex In use 9 Jul – 20 Aug
What I did

Wrote the standing documentation for landing-page deployment so it isn't rebuilt from memory each time: a screenshot-by-screenshot guide to creating a Cloudflare account token, and the full project creation walkthrough for the case where a client shares or creates their Cloudflare account live on a call. Shared with Anna for the team.

Also set up a booking link so Valerie can route tracking, CRM integration and deployment requests to whoever has capacity, rather than every request landing on one person.

Finished the landing page build SOP — the full step list for a page from brief to live — and handed it to Anna, attached to the LP process review task so it sits with the process rather than in a chat.

The full production manual, 11 to 20 August

Anna asked for the SOP to become a real manual rather than a step list: tools, how to use them, the prompts, screenshots and Looms. I asked where it sits against everything else before starting, and got it confirmed as higher priority than internal and dev work but below live client tracking and LP requests, so it was written a part at a time instead of blocking a week.

Reviewed the 17-day LP task sequence Anna is turning into recurring tasks and gave three corrections from how the work actually runs: the Day 7 handoff should include the repo push of the draft page, thank-you page, brand assets, research, offer and brief, because without it the build gate has no context; the Day 14 mobile check can only be real on an iPhone since I have no Android or second physical screen size, so the rest is emulation and should be described as that; and Day 17 belongs to the Google strategist, not operations, since that is who already connects the page to Ads. Also defined who counts as an approver, which matters when the main contact is not the only decision-maker.

Produced the manual and published it into the Metrics wiki so it lives with the process. That took getting write access first: the connected wiki server was the read-only build with GET tools only, so I went to the developer, got the correct OAuth endpoint and reconnected against it. Converting the HTML to a wiki page stripped the inline links out of a long instruction where they carry most of the value, so that was reworked until the published page matched the source. Screenshots still to be added.

Working environment & toolingInternal

21hOngoing
Complex Ongoing 3 Jul – 30 Sep
What I did

Keeping the setup that runs everything else working. Connected the Meta MCP so I can query Meta directly instead of clicking through Events Manager. Audited what was running on the machine and stripped out unused integrations that were slowing it down, including removing Perplexity across all commands and skills. Recovered session context after crashes and restarts. Changed the build skill so it stops injecting its prompt into every unrelated request. Cleared a client VPN that had locked the machine without a passcode.

Connected Gmail and Google Drive so client threads can be read without leaving the terminal, then got GA4 connected as well — which took working through gcloud application-default login, the browser landing on the wrong profile, and finally an OAuth setup that will carry over to other client properties rather than being a one-off for this account. Checked what the Google Ads connection can and cannot reach, and established that purchase Match Rate for Shopify clients isn't exposed through it at all — it only exists in the Google Ads interface, so automating it means a browser extension, which I passed to the person who can build one.

Asked to pull the past-client roster with end dates into a sheet, I mapped what the connected servers can actually reach before starting an authorisation flow for the wrong one - and established that none of them return client records. The metrics server exposes wiki pages only, so even re-authorised it can only ever return documentation about the platform rather than rows out of it, and the ClickUp workspace has no client roster. Said that plainly instead of producing a partial export.

August. Reconnected the Metrics wiki server against its OAuth endpoint to get write access, after establishing the connected one was the read-only build rather than assuming the tools were missing. Swept the machine for local files already in GitHub and untouched for 30 days and cleared them. Killed a runaway terminal multiplexer that had taken 50GB and was opening Chrome windows on its own. Recovered the shared Upwork login without a phone code by routing it back through the browser profile that was already trusted.

24 to 27 August. The parallel review agents left dozens of Chrome instances and local servers running and the machine became unusable - at one point I could not open Google Ads. Found and killed them, repeatedly, across three days, and cleared out a stale local project directory and duplicate Playwright installs after confirming the content was already on YouTube and Google Drive rather than deleting on the assumption.

Turned the Prestige Botanicals design-improvement process into a reusable skill and published it to the skills repo, then shared the full page-builder skillset with Valerie on GitHub so pages she builds directly get the same design passes instead of arriving for rework. Wrote up what the process actually taught: Claude is cautious about modifying an existing design and needs concrete visual instruction, GPT-5.6 improvises new concepts better, and the skillset's Call Codex skill lets Codex run as an agent from inside Claude so both can be used on one page.

Late August into September

Kept killing the Chrome profiles that testing and parallel review agents leave open, and made it a standing rule for testing sessions so only real profiles survive a run. Debugged the MCP connectors after the Meta server started failing with no OAuth token found.

Helped Oleg get back into Upwork. He had it pinned on the proxy settings; it was the VPN language wrap, so we turned that off while keeping location and time wrap on to stay safe, and switched off the extra Windscribe privacy options. That fixed it.

9 September: folded the phone normalisation handling worked out on the funnel form into a skill so the next page does not relearn it, and kept clearing the Chrome processes and test profiles the review agents leave behind while leaving the real profiles alone.

Landing page skillset review with Luke, 16 to 17 September

Two sessions with Luke going through the page-builder skillset as something the rest of the team would use rather than just my own setup. Shared the repo and walked through pages built with it. Chased the result of his own Codex test build when it did not appear in the shared repo, instead of assuming it had gone nowhere, and a further session was booked to close it out.

Kept the machine usable alongside that: cleared the Chrome instances and background processes the review agents leave behind, pushed outstanding work to GitHub and accepted the pending repo invitations, and after a restart wiped every running session, wrote out the list of what needs to be running and a single command to bring each one back, so the next restart costs minutes rather than an afternoon.

22 September: two restarts wiped the running sessions, so I rebuilt the list with a one-line resume command for each, and closed the processes that were making the Mac lag.

25 to 30 September: turned the Merchant Center and tracking audit work into two reusable skills, with the audit template and instructions and with client details removed. Restored the running sessions after another restart and cleared stale test browsers that were slowing the Mac. Showed Anna and Alex how to switch between GHL client accounts on admin@growmyads.com.

Weekly lead reportingInternal · every Monday

2.5hRecurring
Recurring Ongoing Weekly
What I did

Every Monday: check Pipedrive for duplicate records and fill out the lead dashboard on Netlify. Roughly an hour a week across the period.

9 September: the Netlify dashboard had not been filled in for a week. Checked who owns it now before assuming it had been dropped, then asked Oleg to fill it and to reconcile it properly: filter Pipedrive to the last 30 days, delete duplicates, and check the numbers match the dashboard. There was in fact a duplicate being counted. The missing week was my own misread of the date, which I said so.