Local Service Spotlight https://localservicespotlight.com Amplifying Local Service Professionals | Stories, Spotlights & Community by Dennis Yu Thu, 24 Sep 2026 19:08:31 +0000 en-US hourly 1 https://wordpress.org/?v=7.1.2 https://localservicespotlight.com/wp-content/uploads/2025/10/ChatGPT-Image-Sep-27-2025-08_04_30-PM-1-150x150.png Local Service Spotlight https://localservicespotlight.com 32 32 How We Use Descript in the Content Factory https://localservicespotlight.com/how-we-use-descript/ https://localservicespotlight.com/how-we-use-descript/#respond Thu, 24 Sep 2026 18:51:09 +0000 https://localservicespotlight.com/how-we-use-descript/ We use Descript as the edit desk inside the Content Factory. Raw phone video from a job site, a customer interview, or a podcast lands in Descript first. Transcription, filler-word cleanup, clips, captions, and a clean master come out. Then agents and humans turn that master into blogs, social posts, ads, and meta articles.

This page is how Local Service Spotlight actually runs that step — not a Descript product tour, and not instructions for logging into our shared team account. If you want the product overview, read Why I Call Descript the Swiss Army Knife of Video Editing. If you need the team login path, that stays on an internal page and is not a public SEO target.

Where Descript sits in the Content Factory

The Content Factory turns one piece of raw video into dozens of finished assets. Descript is Stage 2 tooling: Process. Collect happens on the phone or camera. Process happens in Descript (and adjacent AI). Publish and Promote happen on WordPress, social, and ads.

  • In: a job-site clip, testimonial, podcast take, or screen walkthrough
  • In Descript: transcript as the timeline, Studio Sound, remove filler words, cut speakers, export clips and a captioned master
  • Out: SRT/transcript, short clips, stills, and a clean master the Content Factory can repurpose without re-watching the raw file
Descript project timeline used for Content Factory video editing
Descript is where the transcript becomes the timeline — the same file feeds clips, captions, and the master we pass to the Content Factory.

What we actually do in Descript

1. Import and name the project after the person or job

Every project is named for the source — the customer, the contractor, the episode — not “Final_v3.” That name follows the transcript, the clips sheet, and the blog that comes later. Provenance is the point: a stranger should be able to trace a published quote back to the recording.

2. Edit on the transcript, not the waveform

Descript’s advantage for our shop is text-based editing. Delete a sentence in the transcript and the video follows. That is how we cut a 90-second customer thank-you or a one-minute “answer the question customers actually ask” clip without a traditional NLE.

3. Studio Sound, filler words, then speaker labels

Job-site audio is noisy. Studio Sound first. Then filler-word removal. Then rename “Speaker” to the real person when the recording supports it. Wrong speaker labels poison every downstream quote, so we treat naming as part of QA, not decoration.

4. Pull clips and captions before you leave the project

Short clips for social and ads come from the same composition as the master. Captions travel with the export (cc_load_policy=1 on every YouTube embed we publish). The Content Factory does not invent a transcript later if Descript already produced one.

5. Hand off a package, not a mystery file

What leaves Descript for the next agent or teammate: project link, duration, SRT or markdown transcript, clip list with timecodes, and the master export. That package is what “Process” means in the Content Factory — not “someone remembered what was said.”

Worked example: testimonial in, Content Factory out

A recent path looks like this: import a customer MOV into Descript → compose a “Full testimonial” timeline → export transcript with speaker changes and timecodes → cut short clips from the same composition → agents draft the blog and social from the transcript, not from memory. The Descript project stays the source of truth even after the article is live.

Same pattern on personal-brand builds: phone video of the owner answering real customer questions goes into Descript, then into the Content Factory receipts you see on pages like Phone Video to Personal Brand: Britain Eriksen.

Dennis on Descript as the edit layer — captions on by default in our embeds.

What this is not

  • Not a substitute for descript.com login or billing support
  • Not our internal shared-account login checklist (that page stays noindex on purpose)
  • Not “AI will edit your brand for you” without a real recording — we still start from something that happened

See it on your business

If you already shoot job video and nothing reusable comes out, start with a free Quick Audit. If you already know you want the full growth retainer — Maps, Proof & Content, Calls & Conversion — see home service marketing pricing.

Marker: LSS-HOW-WE-USE-DESCRIPT-2026-09-24

]]>
https://localservicespotlight.com/how-we-use-descript/feed/ 0 A Players Only: How Project Leads Serve Contractors Without a Founder Bottleneck https://localservicespotlight.com/a-player-project-leadership-for-contractors/ https://localservicespotlight.com/a-player-project-leadership-for-contractors/#respond Wed, 23 Sep 2026 16:59:09 +0000 https://localservicespotlight.com/a-player-project-leadership-for-contractors/ .apl{--navy:#102a43;--blue:#176b87;--green:#12715b;--orange:#df6b24;--ink:#172b3a;--muted:#526779;--line:#d5e1e8;--paper:#f4f8fa;max-width:880px;margin:0 auto;color:var(--ink);font-size:18px;line-height:1.62} .apl *{box-sizing:border-box}.apl p{margin:0 0 1em}.apl h2,.apl h3{color:var(--navy);line-height:1.22}.apl h2{margin:1.7em 0 .45em;padding-bottom:.22em;border-bottom:2px solid #e5edf2;font-size:1.5em}.apl h3{margin:1.3em 0 .3em;font-size:1.1em}.apl a{color:#075c86;text-decoration-thickness:1px;text-underline-offset:2px}.apl ul,.apl ol{padding-left:1.2em}.apl li{margin:.35em 0}.apl .apl-lede{font-size:1.12em;line-height:1.5;margin:0 0 14px}.apl .apl-lede strong{color:var(--navy)}.apl-video{margin:0 0 22px}.apl-video-box{position:relative;aspect-ratio:16/9;max-width:740px;margin:0 auto;overflow:hidden;border-radius:14px;background:#071a2b;box-shadow:0 8px 24px rgba(16,42,67,.14)}.apl-video iframe{display:block;width:100%;height:100%;border:0}.apl-video figcaption{max-width:740px;margin:8px auto 0;color:var(--muted);font-size:.78em;line-height:1.45}.apl-standard{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:18px 0 24px}.apl-standard div{padding:14px;border:1px solid var(--line);border-top:4px solid var(--green);border-radius:12px;background:#fff}.apl-standard b{display:block;color:var(--navy);margin-bottom:4px}.apl-standard span{display:block;color:var(--muted);font-size:.85em;line-height:1.45}.apl-callout{margin:1.35em 0;padding:16px 18px;border-radius:12px;background:var(--paper);border-left:5px solid var(--blue)}.apl-critical{background:#fff5ef;border-left-color:var(--orange)}.apl-route{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:14px 0 24px}.apl-route div{padding:13px 11px;border-radius:10px;background:#eef5f7;border:1px solid #cfe0e5;font-size:.84em;line-height:1.42}.apl-route b{display:block;color:var(--blue);margin-bottom:4px}.apl-route div:last-child{background:var(--navy);color:#fff;border-color:var(--navy)}.apl-route div:last-child b{color:#8fe1ca}.apl table{width:100%;border-collapse:collapse;margin:.8em 0 1.4em;font-size:.86em}.apl th{padding:9px 10px;background:var(--navy);color:#fff;text-align:left}.apl td{padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:top}.apl tr:nth-child(even) td{background:#f8fafb}.apl-proof{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:14px 0 24px}.apl-proof section{border:1px solid var(--line);border-radius:12px;padding:15px}.apl-proof h3{margin:0 0 8px}.apl-proof .pass{border-top:4px solid var(--green)}.apl-proof .miss{border-top:4px solid var(--orange)}.apl-check{margin:1.2em 0;padding:18px;border:2px solid var(--green);border-radius:14px;background:#f5fbf8}.apl-check h2{margin:0 0 .35em;border:0;padding:0}.apl-related{margin:1.5em 0;padding:16px 18px;border-radius:12px;background:var(--navy);color:#e9f1f6}.apl-related h2{color:#fff;border:0;margin:0 0 .35em;padding:0}.apl-related a{color:#aee9d9}.apl-related li{margin:.5em 0}.apl small{color:var(--muted)} @media(max-width:720px){.apl{font-size:17px}.apl-standard{grid-template-columns:1fr}.apl-route{grid-template-columns:1fr 1fr}.apl-proof{grid-template-columns:1fr}.apl table,.apl tbody,.apl tr,.apl td{display:block;width:100%}.apl thead{display:none}.apl tr{margin:0 0 12px;border:1px solid var(--line);border-radius:10px;overflow:hidden}.apl td{border:0!important;background:#fff!important}.apl td:before{content:attr(data-label);display:block;color:var(--green);font-size:.75em;font-weight:800;letter-spacing:.04em;text-transform:uppercase}} @media(max-width:430px){.apl-route{grid-template-columns:1fr}.apl-video-box{border-radius:10px}.apl h2{font-size:1.35em}}

Local Service Spotlight project leads serve contractors by owning a business outcome from source data to weekly action. An A player does not route every question or random item through Dennis; they use the team, name one Accountable owner, and bring Dennis only the bounded finance or judgment calls that require him.

Dennis Yu explains the A-player standard in 4 minutes 9 seconds. English captions are on by default; the video does not autoplay.
Own the outcomeKnow the contractor’s goal, the source of truth, and the number that must move.
Use the teamRoute work to the right owner in the shared project thread instead of creating a Dennis queue.
Prove the impactClose the loop with a live receipt and a weekly Metrics, Analysis, Action update.

A players only is an operating standard

“A players only” is not a motivational slogan and it is not a score for raw talent. It is a role-fit standard: can this person reduce the load on the team while helping a contractor get found, get chosen, and get booked?

An A player asks for the goal and the source of truth once, finds the relevant training and prior work, chooses the right teammate, and returns with a result someone else can verify. They surface a real blocker early. They do not wait to be chased, report activity as impact, or make one busy founder the default router for the whole company.

If these basics require repeated reminders after onboarding, the person is not operating as an A player in that seat. The right response is not endless explanation. Narrow the role, add a specific skill gap with a due date and acceptance test, or change the owner.

“Do not treat Dennis as your assistant” means use the team

The problem is larger than asking Dennis to paste a comment or find a link. It is routing every question, approval, and random item to him one-to-one because that feels easier than learning to work in a team. That creates a founder bottleneck and hides the fact that no one else has taken the Accountable seat.

Keep the work in the shared project thread. Search the documented process. Ask the person who owns that function. When a task crosses functions, name the one person who owns the result and the teammates who own the component work. Read Why People Shouldn’t Solo Message Me for the communication symptom and Basecamp Basics for the source-system mechanics.

1. SearchCheck the project, SOP, prior receipt, and source system.
2. RouteName the teammate who owns the function and use the shared thread.
3. OwnKeep one Accountable person responsible for the end result.
4. EscalateBring Dennis one bounded owner-only finance, authority, or judgment decision.

A good escalation is small enough to answer: “Approve up to $300 for this tested campaign by Thursday; the live dashboard and rollback plan are here.” A poor escalation is “What should we do?” followed by a pile of context the project lead has not analyzed.

RACI for a contractor account

RACI prevents a group of helpful people from becoming a group with no owner. The Accountable person is not the one who performs every task. They are the one who makes sure the right work happens, the evidence is checked, and the next action has one owner and one date.

Seat What it means on a contractor account Evidence
Accountable Owns the business outcome and the weekly decision. There is exactly one A. Current MAA, named owners, due dates, source links, and closed loops.
Responsible Executes a component: ads, site, content, analytics, sales follow-up, or client coordination. Published change, platform receipt, checked deliverable, or source-system update.
Consulted Supplies expertise before the decision: the contractor, finance owner, channel specialist, or subject expert. A bounded question and a recorded answer, not an open-ended handoff.
Informed Needs the result, not every intermediate message. Concise update with decision, impact, next owner, and next check.

Dennis may be Consulted for a strategic tradeoff, Informed on a material result, or Accountable where he is explicitly the finance source owner. His availability does not make him the A for every project.

The contractor outcome comes before channel activity

A contractor does not buy posts, ad clicks, schema, or reports. They buy profitable growth. The project lead has to connect diagnostic work to the contractor’s operating numbers without pretending attribution is cleaner than it is.

Business outcome Useful leading indicators Counterbalancing check
Collected revenue and contribution profit Booked jobs, sold estimates, qualified calls Refunds, discounts, ad spend, fulfillment cost, and jobs not yet collected
Profitable customer acquisition Cost per qualified lead, booking rate, answer rate Close rate, average job value, lead quality, seasonality, and service-area fit
More local demand Maps visibility, branded searches, direct traffic, video watch time Calls and booked jobs; visibility by itself is not profit
Stronger trust Reviews, proof-rich pages, case studies, response speed Conversion rate and sales feedback; content volume is not proof of persuasion

Label impact DIRECT only when the source system supports it. Use INFLUENCED when several channels contributed, and UNKNOWN when the plumbing is incomplete. Honest UNKNOWN is more useful than invented precision.

The weekly MAA is the proof of ownership

Every Accountable lead should produce one weekly Metrics → Analysis → Action tied to the contractor’s money path. It is not a dashboard dump or a list of completed tasks.

  1. Metrics: Compare the current period with a useful baseline. Lead with booked work, qualified opportunities, collected revenue, contribution profit, and spend when available.
  2. Analysis: Explain the non-obvious signal and its counterbalancing metric. Separate creative quality, audience fit, offer fit, sales follow-up, site conversion, and measurement gaps.
  3. Action: Make one or two changes with one owner, one due date, a spend or authority boundary, and the next measurement window.
Minimum weekly sentence: “Qualified calls rose from 8 to 12, but booked estimates stayed at 4 because three calls were outside the service area. Jack will tighten location exclusions by Thursday; Dylan will verify the next seven days in the call log and ad account.”

What A-player behavior looks like

Operating as an A player

  • Returns with the answer, source, and next action.
  • Uses shared threads so the team can see and help.
  • Names uncertainty and verifies public or financial effects.
  • Delegates components while retaining accountability.
  • Connects work to contractor revenue, profit, or a verified leading indicator.
  • Finds and develops other people who can own outcomes.

Not operating as an A player yet

  • Sends Dennis unsorted questions that another teammate or the source can answer.
  • Moves decisions into solo messages and leaves the team blind.
  • Calls drafts, optimistic UI, or activity “done.”
  • Reports views, traffic, or revenue without the cost and quality check.
  • Waits for reminders instead of maintaining the next checkpoint.
  • Says “I understand” without producing a verifiable result.

Verification, not acknowledgement

The 30-day proof test

Do not close onboarding because someone read this article or said they understand. Give the person one real contractor outcome and verify four artifacts:

  1. One-page charter: goal, baseline, source of truth, RACI, guardrails, and next checkpoint.
  2. Three weekly MAAs: each anchored to live sources, including one counterbalancing metric and one owned action.
  3. One clean team handoff: a component assigned to the right teammate in the shared thread, with acceptance test and read-back.
  4. One business-impact closeout: direct, influenced, and unknown impact separated; profit or the nearest honest proxy shown.

Pass: the contractor outcome moved or the lead produced a clear evidence-backed learning, the source systems match the report, and the team needed less founder intervention by the end of the month. Do not pass: attendance, effort, a quiz, a read receipt, or a polished report with no source receipts.

Questions new project leads ask

Should I never ask Dennis a question?

No. Ask when the decision truly needs his finance authority, access, relationship context, or judgment. First reduce it to one bounded decision and include the source, recommendation, downside, and deadline.

What if I am not skilled enough to do every component?

You do not have to be. The Accountable lead assembles the right Responsible people and verifies the combined result. Ownership is not solo execution.

What if the contractor’s revenue data is missing?

Mark it UNKNOWN, assign the measurement gap, and use the nearest honest operational proxy until finance or the CRM can supply the real number. Do not turn visibility metrics into invented revenue.

Does one mistake mean someone is not an A player?

No. A players surface mistakes early, correct them, and improve the system. Repeatedly outsourcing the same basics, hiding uncertainty, or requiring chase behavior after onboarding is the role-fit signal.

Where do agents fit?

Agents can gather evidence, execute bounded work, check deliverables, and keep recurring loops moving. They follow the same standard: use the canonical source, preserve authority boundaries, and return a verifiable receipt. Start with New Agents Start Here.

]]>
https://localservicespotlight.com/a-player-project-leadership-for-contractors/feed/ 0
How a Zero-Call Week Got Explained Instead of Escalated https://localservicespotlight.com/how-a-zero-call-week-got-explained-instead-of-escalated/ https://localservicespotlight.com/how-a-zero-call-week-got-explained-instead-of-escalated/#respond Tue, 15 Sep 2026 20:01:05 +0000 https://localservicespotlight.com/?p=77076 Every Friday an AI agent writes the Google Ads report for a local service company we manage. On September 11 the account had its worst week since reporting began: $239.59 spent, one lead, and no phone call that lasted a full minute. The campaign had bought its cheapest clicks on record, $7.05 each. On this account, cheap clicks call less often. The agent checked tracking, the holiday, and demand, and cleared all three.

The report said so, proposed no performance change, and went to the owner with one question instead of an alarm.

Daniel Goodrich reviews the work. The owner runs the crews. The agent does the middle part. We do not name the client here, and the numbers are real.

This was also the first scheduled run under the rewritten process, where a second agent reads the draft cold and tries to break it. It broke the first draft: a grade of F, fifteen wrong numbers, and five claims the data did not support. The version the owner will read is the one that survived that pass.

This is the meta article for that run. It documents what the agent did, the calls it made, what a human changed, and what is still unknown.

The zero-call week run through the five stages on September 11, 2026: read, pull, draft, harden with a grade of F and 15 numbers corrected, investigate and find that cheap clicks call less, stop with one question to the owner

The run at a glance. Red is where the hardener rejected the first draft. Gold is the investigation that explained the week.

The run in brief

The assignment was the scheduled weekly Google Ads MAA (Metrics, Analysis, Action) for the account. The report is a client deliverable for the owner. A human approves it, then posts it to the client’s project thread.

The source material was live account data pulled through the Google Ads API, read-only, for two windows: September 4 to 10, and August 12 to September 10. Before pulling a number, the agent read the client’s ledger. That file holds:

  • how a lead is defined ($50 to $80 per lead is the goal, and a call counts at 60 seconds)
  • every change made to the account and when
  • the items on watch
  • anything too new to judge

The goal was the same as every week: tell the owner plainly what the money did, and decide what, if anything, to change. This week the second half was the hard part. The obvious move on a one-lead week is to do something, and one conversion on 34 clicks is not enough evidence to do anything.

What the agent did, step by step

Stage 0: it read before it pulled

The agent read the ledger, all ten sections, then the metric spec, the shared data rules, and last week’s report. That is where it learned the counted-call unit, the target band, and the standing rule that this account’s reports leave out desktop. It also learned that a keyword re-enabled on August 28 could not yet take credit or blame for the week’s shift in queries. The two-cycle rule defers that read to September 18.

Stage 0b: it pulled the whole pack

The pack covered:

  • campaign summary and budgets
  • keywords with Quality Score components, across every status
  • search terms
  • ads with strength
  • conversions by action
  • network and device
  • searcher location
  • negatives at three levels
  • call detail
  • the change history

The change history returned rows for the first time after five failed attempts. The agent saved the raw pull and recorded every row count. One pull hit the tool’s output cap, so the agent replaced it with an explicit list query.

Stage 1: it drafted under the gates

The lead collapse went into Analysis and onto the watch list, not into Action. One conversion on 34 clicks does not clear the five-conversion bar. The week’s biggest-spending keyword, $65.61 on seven clicks with no lead, went to watch for the same reason.

The agent withdrew the Quality Score “reversal” that had led the previous report. Under the new two-cycle rule, a score that reads 7, then 5, then 7 while its two component directions never move is not a change. It also closed a negative-keyword gap carried for two cycles with a direct query showing all nine terms live.

Stage 2: the hardener graded it F

A second agent, in a fresh context with only the frozen draft, the raw pull, the ledger and the spec, re-derived the numbers. Fifteen did not match. One cause was self-inflicted. The first save of the raw pack carried a weekly call summary the drafter had typed by hand, and it did not sum to its own rows. Four sentences were wrong because of it.

The hardener dropped five claims outright, demoted one action to watch, and returned the draft with a punch list. One round, every verdict applied.

Stage 3: it reconciled

Every number tied to the pull. Every action either had two cycles of watch history or was a foundation break. Nothing inside the 14-day window took credit or blame. One account setting the change log could not explain went into the notes and the open questions rather than into the analysis.

Then Daniel asked the question the draft had not answered

The hardened draft said the agent could not explain the week. Daniel commissioned a same-day investigation to rule out a tracking break, a demand collapse, and noise. The investigation is its own file, and its answer changed the report.

  • Nothing was broken. GA4 recorded four tap-to-call events from paid visits and Google Ads recorded four, a match through the import. The call button served on all 468 impressions. The site booked three jobs that week, all from unpaid visits.
  • Labor Day was not the cause. Holidays do not suppress calls on this account. The July 4 week ran above the median on calls, and the Memorial Day week produced six tracked calls.
  • Demand did not collapse. It softened about 7% while the account’s impressions fell 20%, so most of the loss was auctions the campaign did not win.
  • The matching footprint was not to blame. Tightly and loosely matched traffic cost $79.37 and $79.89 a lead over seven weeks.

The finding: cheap clicks are quiet clicks. Across fourteen weeks, what the campaign paid per click predicted how often those clicks called (r = +0.65, and the relationship holds with any single week removed). This week’s $7.05 was the cheapest click price on record. Its 5.9% call rate, two calls on 34 clicks, came in slightly above what that relationship predicts. The volume matched the traffic the campaign bought, and the traffic was cheap.

Both calls were under a minute. Google counts an ad call at 30 seconds, so the account shows one conversion. We count a call at 60 seconds, so the report shows zero counted calls. That accounts for the gap between the two numbers.

Bar chart of tracked calls per click over 14 weeks. Three peak weeks at 26.4%, 27.9% and 23.1% in gold, the week of September 4 at 5.9% in red, 14-week median 10.4%

Tracked calls per click by week, from the account’s call records. The three gold weeks were the outliers. The red week sits with five other weeks under 7%.

Stage 4: it appended and stopped

The agent wrote the trend row and the weekly log into the ledger, plus seven new watch items with first-seen dates, eleven open questions, and six data faults. No client view, no charts, no post. Daniel approved the draft in chat. The agent then rendered the client view and staged it for him to paste.

The judgment calls

It held the collapse off the action list

The easy report says “pause the weak keyword” or “raise the bid.” The gates said one conversion on 34 clicks cannot carry either, and the account’s own history said four of the prior thirteen weeks had come in at three tracked calls or fewer. The draft said so and proposed nothing on performance.

It withdrew its own earlier framing in the open

Since August 28 the reports had described a run of 26%, 28%, and 23% calls per click as “an elevated call rate,” as though it were the new level. It was a peak, and those three weeks were the outliers. The report says that. It also says that last week’s “back inside target” line did not survive a week.

It proposed a watch trigger that would not cry wolf

The first draft proposed escalating if the next week produced fewer than three counted calls. Checked against history, that trigger would have fired on four of the last thirteen weeks. The proposed replacement sits in the ledger pending Daniel’s approval. It tests the mechanism instead of the symptom:

  • If click price recovers to $11 and the call rate stays under 10%, the relationship has broken and we escalate.
  • If price stays under $9 and calls stay low, the cheap-auction pocket is persisting and the bidding question opens.
  • If both recover, the item drops.

It narrowed the ask to the owner

The first draft asked the owner to help rule out a tracking break. After the investigation ruled it out from our side, the ask became a two-minute confirmation. The agent asked whether two short calls, one Saturday morning and one Wednesday afternoon, matched what the owner saw on the phones.

It logged an unexplained change as a question

Someone had changed one account setting with no record of who or when. The report records that as an unlogged change and an open question. It does not build a story on it.

What it cost

We did not measure this run. Our July run articles estimated about 14 agent-minutes and $2 to $4 per run, against an hour to an hour and a half of manual work for a draft with no hardener pass. This run did more, since the hardener pass and the investigation are new, and we record its time, tokens, and cost as UNKNOWN. The notes block now requires start and end timestamps, so the next cycle will carry numbers.

Where the humans were

The agent did these on its own:

  • read the ledger
  • pull and save the data
  • write the draft under the gates
  • dispatch the hardener and apply its verdicts
  • reconcile
  • append the ledger and trend file
  • render the client view once approved
  • write this meta article

Required a human this run:

  • commissioning the investigation, since the hardened draft had stopped at “we cannot explain it,” and the investigation changed its central finding
  • approving the draft
  • pasting the client view into the client’s project thread
  • approving the replacement watch trigger
  • the answer only the owner has

Two of those touched the report itself, and one of the two changed the analysis. The hardener handled every number correction. The back-test of the previous week, run through the same process a few days earlier, had needed zero. The gap between those two counts is what we work to close.

What this run changed in the recipe

  1. Compute derived blocks from rows. Never type them. A hand-typed weekly summary in the raw pack produced four wrong sentences. The rule is now in the analyzer, the reviewer’s re-derivation step, and the query pack.
  2. Paste the hardener’s output verbatim. This report described the verdicts in one sentence of counts. Only one of the four reports that cycle printed the verdict table, and none printed a grade after the round. The skill’s completion checklist now requires the table, the counts, and both grades.
  3. Test a watch trigger against history before proposing it. “Fewer than three calls” fires four times in thirteen weeks on this account. Check the false-positive rate on the series before writing the condition.
  4. Treat “we cannot explain it” as a prompt for a pull. The explanation was in data the standard pack already had: weekly cost per click and call rows. The next revision of the recipe should ask, before closing Analysis, whether the draft has tested any mechanism in the pack against the symptom.
  5. Name the levels when claiming nothing is disapproved. This account’s report did not make that error this week. The same cycle on another account said “nothing is disapproved” from an ad-level pull while two image assets sat disapproved. The rule now applies everywhere.

Run inventory:

  • Execution ID: GAA-2026-09-11-C1A
  • Recipe: google-ads-analyzer v1.5.0, before the house-format revision, hardened by google-ads-reviewer v1.5.0 in a fresh context, one round
  • Windows: 7D 2026-09-04 to 09-10, and 30D 2026-08-12 to 09-10
  • Hardener result: grade F on the first draft, 15 numbers corrected, 5 claims dropped, 1 action demoted to watch
  • Actions in the final report: 5 (2 for the owner, 3 for the agency), and nothing shipped to the account this cycle
  • Ledger appended: 1 weekly-log row, 7 watch items from this run, 11 open questions, 6 data faults, quarantine updated
  • Human interventions on the report: 2 (Daniel commissioned the investigation, and Daniel approved the draft with the reframed ask to the owner)
  • Time, tokens, cost: UNKNOWN
  • Evidence, in the private client folder: deliverables/2026-09-11-google-ads-maa.md (Generation notes block), deliverables/2026-09-11-call-volume-investigation.md, compiled/ledger.md rows dated 2026-09-11, and compiled/trend.csv last row

Run it on your own account

Install the Google Ads MAA skills from GitHub, onboard one account, and let the scheduled run fire on Friday. Read the hardener’s verdicts before you read the draft. The Google Ads MAA Agent recipe describes the five stages this run followed and the setup steps.

Two earlier runs under the previous process show what changed: the July review that fixed a blind spot and the July painting contractor run. Dennis Yu’s MAA framework is the discipline underneath all three.

This meta article documents one client’s Google Ads MAA run on 2026-09-11, execution GAA-2026-09-11-C1A. The client is anonymized, and the numbers are unchanged.

Agent receipt: localservicespotlight.com draft · Claude [claude-fable-5-1] · action: drafted · human review: Daniel Goodrich reviews before publishing

]]>
https://localservicespotlight.com/how-a-zero-call-week-got-explained-instead-of-escalated/feed/ 0
Dazos Review: Do Not Prepay 100% for a Custom eClinicalWorks Integration https://localservicespotlight.com/dazos-review/ https://localservicespotlight.com/dazos-review/#respond Mon, 14 Sep 2026 17:15:13 +0000 https://localservicespotlight.com/dazos-review/ Verdict: we would not buy Dazos again for an eClinicalWorks clinic that needs the integration before paying, and we would not prepay 100% of year one. Cardinal Treatment Center did.

If this article is still up, they have not addressed the situation.

eCW the clinic chart already in use the missing door custom eCW integration sold · prepaid · not delivered Dazos CRM login cut Sep 11, 2026 LOCKED Cardinal paid for the door. Dazos later wrote that the door still has to be built. Then they locked the CRM room.
Figure 1. Two rooms: eClinicalWorks and Dazos. The product was the custom door. Cardinal prepaid $65,200. The door was not built. Then Dazos locked the CRM.

This is an operator review, not a brochure. Sam Hessler was the salesperson who made the big promises. What we feared from a full prepay is exactly what happened. Dated facts: Dazos cut access after Cardinal prepaid $65,200. We are not linking to Dazos. A dofollow link is a living recommendation. The rule is when trust ends, the endorsement link ends.

Do not buy
for an eCW clinic that needs the custom door before a second invoice

$65,200
prepaid June 5, 2025, including the custom eCW integration

100%
year-one cash taken up front after we said a full prepay was the risk

Sep 11
2026: CRM login cut on disputed Year-2 invoice IN-4797 ($55,200)

Score the engagement, not the homepage

What we bought for What landed Operator score
Custom Dazos-to-eCW door Sold as bidirectional. A year of “released” and “working.” Then “does not integrate.” Then “still has to be created.” Fail
Sales honesty on prepay Sam Hessler and Kayla Nielsen pushed a same-month close for a Series A. The 30-day / no-payment paper died. Year one became non-refundable, 100% up front. Fail
Year-2 billing IN-4797 $55,200 while the sold door was still a roadmap item. Disputed. Unpaid. Do not pay it. Fail
Collections conduct Sarah Diegnan emailed the clinical team a “courtesy notice” that finance would suspend that afternoon. Marcel Scheurer wrote the account “is being suspended.” Fail
Would we refer them No. We keep the story. We do not send them a link. No
Figure 2. Review scores against the sold job, not against a marketing page. Sources and full names live on the facts file.

Name the salesperson who sold the prepay

Sam Hessler was the eager salesperson. He was on the Dazos | Cardinal Zooms. Calendar holds from February through April 2025 show he accepted — including February 14, 18, and 25, plus the March 21 and March 28 eClinicalWorks integration discussions and the April 28 sync. Kayla Nielsen, Regional Director, sent the paper and copied him.

On February 26, 2025, Kayla Nielsen wrote (copy: Sam Hessler) that she had spoken to David and Dazos could “commit to doing the bidirectional integration with eClinicalWorks for $10k on a 6 month timeline.” Push patients. Update them back. Push encounters. That was the product.

On February 27, 2025, after a late-night sales Zoom, Kayla Nielsen wrote (copy: Sam Hessler): “Appreciate the late night call.” Marketing Reports free. DocuSign resent. Sign this month.

That same night, at 3:14 a.m. Pacific, Dennis wrote Michael Maryash what the sales desk had just made plain:

  • The most important part was “the integration of ECW with Dazos — data going both ways” plus billing, so the clinic could judge marketing, clinicians, and profit.
  • “They are closing out this month for raising a Series A round, so they seem to have legitimate urgency to get an agreement.”
  • They wanted a signature that day, with a 30-day cancel and no payment until terms were finished. The reason, in that same-night mail: this is just to “book revenue” for their investors on paper.
  • “They are quite eager to do this deal today, of course.”

We said, on those calls and in the follow-up, that a 100% prepay was the risk. If the door never opened, Cardinal would already have handed over a full year of cash. Sam Hessler still pushed the close. He needed to book this revenue for their capital raise.

The 30-day, no-payment paper did not survive. By May 14, 2025 Dennis was writing Kayla Nielsen (copy: Sam Hessler): “I know we’re committing to $62,500 non-refundable, up-front.” On May 20 the year-one number was $65,200 prepaid, including the eCW integration, with no refunds for Year 1. On May 21 Dazos’s own mail was subject-lined “Dazos Raises $25M.” On June 5, 2025 Cardinal prepaid $65,200.

What we feared is exactly what happened. The money left first. The working eCW door did not. A year later Marcel Scheurer, CFO, billed Year 2 anyway. When Cardinal would not pay a second year for a door that still had to be built, Sarah Diegnan and Marcel Scheurer cut the CRM login.

Proof ledger: Series A / “book revenue” sentences are Dennis’s February 28, 2025 3:14 a.m. mail to Michael Maryash, the night of the sales call, forwarding Kayla Nielsen’s mail that copied Sam Hessler. The $10k / six-month bidirectional promise is Kayla Nielsen, February 26, 2025, copy Sam Hessler. Zoom’s 39-minute recap of the July 1, 2026 call with Sarah Diegnan says the profitability tracking had been discussed on earlier Zooms with Sam. This desk cannot log into Zoom’s recording locker, so those 2025 sales calls are cited from the calendar and from the same-night email, not from a pasted transcript. Full timeline: the Dazos facts file.

Put their own sentences in one row

When Who What they wrote
Feb 26, 2025 Kayla Nielsen, copy Sam Hessler “we can commit to doing the bidirectional integration with eClinicalWorks for $10k on a 6 month timeline.”
Nov 7, 2025 David Farache Dazos had “released the integration.”
Nov 26, 2025 Kenny Correa “everything is now working as expected.”
Jan 15, 2026 Naomi Williams “we are at the tail end of finalizing the eClinicalWorks integration.”
Jul 15, 2026 Sarah Diegnan, SVP Customer Experience “Our product does not integrate with eClinicalWorks.”
Aug 21, 2026 Marcel Scheurer, CFO “The platform is performing as contracted.”
Sep 2, 2026 Marcel Scheurer, after Sarah Diegnan and David Farache looked “The next step is the custom development work to create the integration between eCW and Dazos.” Roadmap. Not in the next couple of weeks.

A fifth grader can check that table. Same company. Same account. Same integration. You do not need a lawyer to see that “released,” “working,” “tail end,” and “performing as contracted” cannot sit next to “does not integrate” and “still has to be created” — not after a $65,200 prepaid year whose central deliverable was that door.

Watch what the July 1 Zoom actually covered

The July 1, 2026 Zoom is in the mailbox as “Meeting assets for Dazos problem,” duration 00:39:42. Sarah Diegnan was on it. Zoom’s own recap (their AI summary, not a court transcript) matches the later mail:

  • Cardinal’s goal was marketing profitability by tying appointment revenue back to marketing. That had been discussed on multiple previous Zoom calls with Sam.
  • Sarah Diegnan split work into live / out of scope / third-party-dependent. The appointments module that would make the profit math work was, on her screen, out of scope.
  • Dennis said a CRM that cost about $65,000 a year had not been functional, and asked not to bill more before the sold door worked.
  • Sarah Diegnan would take the contract question to co-founders.

Two weeks later she put the product sentence in writing. That is the call, then the email. We are not embedding the recording and we are not publishing a Zoom passcode.

Use this file two ways

We can run the same money-versus-door check for you. You can run it yourself from the questions on this page. Both links return a live page.

Say who this review is for

If you run a treatment center, a behavioral-health group, or any clinic on eClinicalWorks, and a Dazos salesperson is pitching a custom integration plus a prepaid year so they can book the quarter, this file is for you.

Ask them, in writing, before anyone pays:

  1. Name the integration. Bidirectional, or read-only. Appointments, or not. Billing, or not.
  2. Put the go-live date and the six-month functional test in the same signed paper as the invoice.
  3. Refuse 100% prepay because someone has a raise to close. If they need to “book revenue” this month, that is their problem, not your risk.
  4. Keep every “it’s released” email. Those sentences are the file.
  5. If they threaten suspend on a disputed renewal, demand the data export first, on the thread, in ordinary machine-readable files.
  6. Do not let payment mail go to clinical staff. One owner. One thread.

That is the same method as a Quick Audit and a software subscription audit: money paid versus a working door, then one action. Here the action is refuse Year 2, keep the data, and write it where a stranger can read it.

Keep two facts apart

Dazos spent July and August 2026 saying they could not investigate until they had eCW logins. That access delay was real. Our project lead was injured. Laura Marants had to provision unique accounts. We did not hide that.

A few weeks of login coordination in summer 2026 does not erase the year before it. The FHIR ticket, the sandbox sign-off, the “released” mail, and Naomi Williams’s February admission that production EMR value had not been realized all happened before Sarah Diegnan asked for those four user accounts. On September 2, after the logins arrived, Marcel Scheurer’s finding was still “create the integration.”

Ask the review questions

Is Dazos a good fit for an eCW clinic?

Not on this file. Sarah Diegnan wrote that their product does not integrate with eClinicalWorks. Marcel Scheurer then wrote that the integration still had to be custom-built and parked on a roadmap — after Cardinal had already prepaid $65,200 for that door.

Who sold Cardinal the prepaid year?

Sam Hessler, with Kayla Nielsen sending the DocuSign and pricing. We told them a 100% prepay was the risk. On the February 2025 calls they needed a same-month signature to book revenue for a Series A. That is in the 3 a.m. mail to Michael Maryash the same night.

Did Cardinal get what it paid for?

Cardinal’s stated position: zero usable production value from the sold eCW door. The CRM login was later cut on a disputed second-year bill. That is not a working engagement.

Why is there no Dazos link on this page?

We do not pass juice to people who act badly or try to harm a client. Names stay. The endorsement link does not. Hub: Dazos eCW Cardinal facts.

THE RECORD
If this article is still up, they have not addressed the situation

Restore the instance, produce the Year-2 notice, or make the prepaid year whole, and this page will say so. Until then, the operator review stays public. No patient data. No card numbers. No link to Dazos.

Read the dated Dazos file →
Cardinal Treatment Center →

Parent method: how we write a sourced record. Writing rules: article guidelines. Related: software subscription audit, boil the ocean, client access checklist, when trust ends, the link ends.

Marker: DAZOS-REVIEW-2026-09-14 · DAZOS-GUIDELINES-SEO-2026-09-14. Operator review compiled September 14, 2026. Hub and full names: dennisyu.com/dazos-ecw-cardinal/. If a date or quote is wrong, the next edit is the email, not a memory.

]]>
https://localservicespotlight.com/dazos-review/feed/ 0
How We Monitor Uptime Across the Entire Fleet https://localservicespotlight.com/how-we-monitor-fleet-uptime/ https://localservicespotlight.com/how-we-monitor-fleet-uptime/#respond Wed, 09 Sep 2026 22:28:25 +0000 https://localservicespotlight.com/how-we-monitor-fleet-uptime/ Both. Not either/or. A cheap heartbeat service (UptimeRobot-class) watches money sites every few minutes. Agents run the deep daily sweep, cloak checks, registry hygiene, and triage. If you put every parked domain on a 1-minute SaaS check, or ask a model to be the ping loop, you burn money and train people to ignore alerts.

This page is the operating model Local Service Spotlight uses for the website fleet. Anyone standing up fleet management can copy the lanes. The runnable probe recipe lives on the parent skill: Fleet Uptime Monitor. The BlitzMetrics fleet-uptime-monitor page stays an SEO leaf. This article is the control plane: who does what, what overlaps, and what does not.

Layer map of fleet uptime control plane: GitHub registry feeding heartbeat SaaS, Fleet Uptime Monitor deep sweep, and Data consume desk
Layer map: one GitHub roster feeds heartbeat SaaS, one Codex deep sweep, and one Data consume desk.

GCT (Goals, Content, Targeting)

  • Goal: Publish one definitive public how-we page that answers “UptimeRobot or agents?” with the layered operating model, so ops and clients can trust green and copy the lanes.
  • Content: Verified registry facts (354 rows; monitoring_status breakdown), July 2026 outage lessons, skill hard rules, Data 7am PT consume + flake gate, and the honest UptimeRobot sync gap.
  • Targeting: Fleet operators, web function owners, and agency teams who manage dozens to hundreds of sites and need an honest uptime control plane.

The short answer

QuestionAnswer
UptimeRobot or agents?Both, different jobs — heartbeat SaaS + Codex deep sweep + Data consume
Overlap?Only if you run two full-fleet AI probes or put every domain on paid minute-checks
Who owns the list?GitHub fleet registry (sheets are views)
Who pings all night?Heartbeat SaaS on the ENABLED money cohort + 3 anchors
Who diagnoses cloak / 5xx layer / fleet-wide?Fleet Uptime Monitor (Codex scheduled sweep)
Who consumes receipts and decides chat vs quiet?Data desk (7:00 AM PT), with a flake gate
Who sends P1 email?Drafted to web@blitzmetrics.com — agents draft, humans send unless a separate send seat is approved
Auto-sync registry → UptimeRobot?No (as of 2026-09-09). Registry has monitoring_status; agent-runtime has no automated sync

Why one tool is not enough

July 21, 2026: ~150 client sites returned HTTP 500 with a fully rendered HTML body. A monitor that only asked “did a body come back?” would have stayed green. Status code and layer probes matter.

July 27, 2026: the credential cache was 111 days stale. Probes passed 18/18 while 18 live client sites were never on the list. Green is worthless if the roster is frozen.

May 2026 (BlitzMetrics alone): Search Console 5xx alerts arrived after the fact. A short-interval heartbeat on the money site closes that detection gap. Case study: How we set up uptime monitoring for BlitzMetrics.

September 2026 pattern: Codex ATTENTION on ENABLED sites often shows human Errno 51 / TimeoutError while Googlebot still gets 200, and an independent box check returns 200/200. That is transport flake, not an outage. Without a flake gate, chat and P1 email cry wolf.

Heartbeat SaaS does not see cloakers, soft-404 catch-alls, or “PHP dead but robots.txt still 200.” Agents do not replace a 5-minute ping on localservicespotlight.com.

Layer map (copy this)

GitHub fleet registry  (source of truth)
        |
        +---> Heartbeat SaaS (UptimeRobot-class)
        |       ENABLED money sites + 3 anchors
        |       minutes, email/SMS/webhook
        |
        +---> Codex / Fleet Uptime Monitor skill
        |       ~6:15 PT daily (or scheduled deep run)
        |       HTTP + Googlebot/canary + robots/shell
        |       receipt + agent-note in agent-runtime
        |
        +---> Data desk (consume only)
                7:00 AM PT routine
                flake gate on named Errno-51 / timeout rows
                quiet if nothing new; ATTENTION/P1 when real

Do not add a second AI full-fleet probe on Grok, Claude, or another seat. One deep sweeper. One consume desk. Heartbeat is not a third probe of the same recipe.

Layer 0 — Canonical roster (GitHub)

Authority: Local-Service-Spotlight/agent-runtime under fleet/website/ (fleet-registry.json / CSV + README). Updates go through update-fleet-record.mjs with evidence. Google Sheets and BlitzAdmin caches are human views or caches. They do not win fights with GitHub.

Canonical GitHub fleet registry path fleet/website with 354 rows and monitoring_status counts
Canonical registry path fleet/website/ — 354 rows; ENABLED 161, DISABLED 60, UNKNOWN 130.

Verified counts (fleet-registry.csv)

FieldCount
Total unique domain/hostname rows354
monitoring_status=ENABLED161
monitoring_status=DISABLED60
monitoring_status=UNKNOWN130
RETIRE_FROM_ACTIVE_MONITORING_AFTER_CONSUMER_READBACK2
PUBLIC_CHECK_PRESENT__CONFIG_UNKNOWN1

There is no money_site column in the registry. “Money sites” for the uptime lane are an operational cohort: ENABLED / retain / client-visible domains plus the three anchors — not a CSV flag.

What “money sites” means vs SEO “money pages”

Diagram of monitoring_status ENABLED DISABLED UNKNOWN counts and money site versus money page definition
monitoring_status breakdown and the money-site vs money-page distinction.
  • Money site (uptime lane): a domain the business still needs answering HTTPS — client-visible or retain. These are the seats that belong on short-interval heartbeat checks (the ENABLED money cohort) plus anchors.
  • Money page (SEO lane): a high-intent URL on a site that converts (service page, geo page, offer page). That is a content/SEO concept from the money tree. Putting every money *page* on a 1-minute SaaS monitor is the wrong unit and burns the bill.

Do-not-monitor (encoded, not tribal knowledge)

Mark exclusions in the registry, not in someone’s head:

  • coreyjacobs.com — prospect who never became a client → monitoring_status=DISABLED, leave alone unless Dennis Yu explicitly overrides.
  • parkernathans.com — burned relationship / ops do-not-touch → DISABLED, do not probe or give daily attention.

Also exclude RETIRED, Not Active, and other DISABLED backlog from ATTENTION noise unless status changed. Hub: Web Function.

Screenshot of Local Service Spotlight Web Function hub page
Web Function hub — parent home for fleet ops pages on Local Service Spotlight.

Rules that keep green trustworthy:

  • Union more than one roster when building a probe set (credential cache + publishing targets historically; registry is now canonical).
  • Report roster age on every healthy close-out. A roster that stopped updating is the incident.
  • Never silently fall back when a roster is missing.
  • Mark exclusions in the registry with evidence via update-fleet-record.mjs.

Layer 1 — Heartbeat (UptimeRobot-class)

Job: tell a human within minutes that a money site stopped answering HTTPS.

Scope: ENABLED / retain / client-visible money sites plus the three anchors: localservicespotlight.com, blitzmetrics.com, dennisyu.com. Do not put every parked, deferred, UNKNOWN, or do-not-monitor domain on a 1-minute plan.

Config pattern (from the May BlitzMetrics setup, scaled):

  • HTTPS check on homepage and one interior path that needs live PHP (CDN-cached home can lie).
  • Interval: short (minutes), not hours.
  • Alert channel: web@blitzmetrics.com or the ops channel that actually wakes someone.
  • Prefer “confirmed down” (2–3 fails) on the wide fleet to cut noise; keep aggressive alerting on the three anchors if you want.

What it does not do: cloak detection, robots shape, shell markers, shared-IP blast-radius diagnosis, registry writes, flake classification vs Googlebot.

Cost control: SaaS seat count tracks ENABLED money sites (~161 ceiling on status alone; operational money cohort is the retain/client-visible subset), not the full 354 inventory and not the 130 UNKNOWN rows.

Honest gap — no automated UptimeRobot sync

As of 2026-09-09, code search in Local-Service-Spotlight/agent-runtime for UptimeRobot sync / export-ENABLED / createMonitor returned 0 implementation hits. Mentions of UptimeRobot exist in outage notes and unrelated site-health modules; they are not a registry→SaaS sync.

Proposed sync (not built): export monitoring_status=ENABLED money cohort (+ anchors) → create/update SaaS monitors; remove monitors that flipped DISABLED / do-not-monitor. Until that ships, heartbeat seats are maintained by hand against the GitHub registry.

Layer 2 — Deep sweep (Fleet Uptime Monitor)

Job: catch what a status ping cannot: fleet-wide 5xx, cloaking, reinfection, parked/stub, soft-404 catch-alls, layer diagnosis.

Owner: scheduled Codex / Cowork job running the Fleet Uptime Monitor skill. Cadence has moved from every 3h toward a daily deep run ahead of the morning agent wave. Canary pass (3/3) gates trust in the receipt.

Screenshot of Local Service Spotlight Fleet Uptime Monitor skill page
Parent skill page: Fleet Uptime Monitor — probe recipe, hard rules, and cloak/canary checks.

Hard rules from the skill (do not weaken):

  • Read-only probes. Draft alerts; do not auto-send unless a separate send seat is approved.
  • Healthy = one line. Verbose only when something is broken.
  • Status code is the signal; body-present is not.
  • Cloak / canary / robots / shell checks are ungated (not only on already-down sites). A check that only runs on broken sites cannot catch a cloaker that returns 200.
  • Deep-probe non-healthy sites with controls (/wp-cron.php, nonexistent URL expects 404, static asset, dig for shared IP).
  • Force-verify known reinfection cohort every run until a human removes them.
  • Incident files get a UTC time in the filename so same-day runs do not overwrite each other.
  • Exactly one fleet-uptime draft per day when escalating.

Receipts and agent-notes land in Local-Service-Spotlight/agent-runtime. Marketplace security-audit remains the canonical verdict owner for infection-class findings; this monitor feeds it, it does not invent a second marketplace skill.

Probe internals and field lessons continue on the skill page and the BlitzMetrics definitive leaf.

Screenshot of BlitzMetrics fleet-uptime-monitor SEO leaf article
BlitzMetrics SEO leaf for the probe recipe — keep as leaf; do not promote BlitzMetrics as the brand home.

Layer 3 — Consume desk (Data)

Job: read today’s Codex receipt + registry, independent-check anchors, apply the flake gate, decide quiet vs chat vs P1 draft.

Schedule: 7:00 AM America/Los_Angeles (CRON_TZ=America/Los_Angeles 0 7 * * *).

Diagram of agent-runtime agent-notes and receipt path for fleet uptime consume desk
Receipts and agent-notes land under agent-runtime; Data consumes at 7:00 AM PT.

Does:

  • Consume the latest full receipt and canary. Does not run a second full-fleet probe.
  • Skip do-not-monitor and known DISABLED backlog noise unless status changed.
  • Independently HTTPS-check the three anchors (human + Googlebot when diagnosing).
  • Flake gate (2026-09-09): before chat ATTENTION on Errno 51 / TimeoutError / human-ERR+Googlebot-200, re-check only the named domains from this desk. If independent check is 200/200, record agent-note only — no chat ATTENTION, no P1.
  • Critical durable outages / INFECTED / cloak → draft to web@blitzmetrics.com. Route host/DNS work to IT (Austin). Registrar sessions stay with the owner of that registrar seat — not a paste-keys loop through Dennis.

Does not need Amazon keys. Public HTTPS and GitHub receipts are enough for the uptime lane. Host fixes use the shared AWS seat IT already runs.

Alert routing

FindingOwnerAction
Anchor or money site down on heartbeatOps / web@Investigate now
1 site 5xx on deep sweepWeb / ITSingle-site draft + watchlist
≥3 sites 5xx or shared-IP cohort down while control anchor 200WebFleet-wide outage playbook; expand sample
Cloak / canary fail / infection markersSecurity + webP1; outranks uptime; do not “clean” over REST
SUSPECT off-fleet A / wrong NSIT + registrar ownerDNS cutover with evidence; registry update
Errno 51 that clears on independent 200/200DataAgent-note only
Stale roster (>30d)Whoever owns roster refreshRoster itself is the incident

Agents draft; they rarely auto-send. One draft inbox (web@blitzmetrics.com). Never train the team with three contradictory drafts per day.

What counts as overlap (avoid these)

Bad patternWhy it hurts
Two AI full-fleet probes (Codex + Grok both sweeping 200+ sites)Double cost, conflicting receipts, nobody trusts either
UptimeRobot on every parked / do-not-monitor / UNKNOWN domainAlert fatigue + bill
Agent as the only 24/7 pingModels are expensive and slow for “is HTTPS up?”
Heartbeat aloneMisses cloakers and “200 that is spam”
Sheet as source of truthStale rows hide sites; GitHub wins
Clearing cloak on uptime aloneJuly 29 pattern: 200 with injector still live
Chat ATTENTION on every Errno 51 without flake gateTeam ignores the channel
Inventing a registry→UptimeRobot sync that does not existFalse confidence; seats drift from ENABLED

How to stand this up on another fleet (verification checklist)

  • Inventory domains into a versioned registry (GitHub JSON/CSV). Mark ENABLED, DISABLED, RETIRED, do-not-monitor with evidence.
  • Pick three anchors on different failure domains (different IPs if you can).
  • Heartbeat SaaS: import only ENABLED money sites + anchors. Homepage + one PHP interior page. Confirmed-down on wide fleet.
  • Install the Fleet Uptime Monitor skill (or equivalent) on one scheduled AI seat. Wire canary + receipt folder.
  • Assign one consume desk (person or agent) that reads receipts and never re-probes the whole fleet.
  • Write the flake gate into that desk’s standing orders (independent re-check named Errno-51 / timeout rows before chat/P1).
  • Alert path: one draft inbox (web@…). Humans send unless a send seat is approved.
  • Publish the skill page + this operating model. Link both from your web-function hub. Link UP to the skill; keep vendor brand pages as SEO leaves only.
  • Agent-note after every substantive run. No secrets in notes.
  • Verify: registry row count matches reality; ENABLED seats ≈ heartbeat monitors; deep receipt exists before 7am PT consume; independent anchor checks 200/200 on a healthy morning; no second AI full-fleet probe scheduled.

Pass / fail checks

CheckPass
Registry authorityGitHub fleet/website/ wins vs sheet
Heartbeat scopeENABLED money + 3 anchors only
Deep sweeper countExactly one scheduled AI seat
Consume deskReads receipt; does not re-sweep fleet
Flake gateErrno 51 → independent 200/200 → note only
Alert draftsLand at web@; no surprise auto-send
Sync honestyDocument whether SaaS is auto-synced (today: no)

Two doors (how-we)

Related reading

FAQ

Should we cancel UptimeRobot now that agents run?

No. Canceling the heartbeat puts detection back on a once-a-day model run and on Google finding 5xx first.

Should Data ping every site every morning?

No. That duplicates Codex and fights the “one deep sweeper” rule. Data consumes and flake-gates.

Can we use Pingdom / Better Stack / Checkly instead of UptimeRobot?

Yes. The brand does not matter. The lane does: short-interval HTTPS on the money cohort, separate from the deep AI sweep.

Is the Projection Google Sheet the monitor?

No. It is a human board. GitHub registry + receipts are authoritative.

What about sites we do not renew or burned relationships?

Registry do-not-monitor / DISABLED. Keep them off heartbeat and out of ATTENTION noise. Document why in the registry evidence, not in chat lore.

Does the registry auto-create UptimeRobot monitors?

No. Today monitoring_status is the signal humans (and future sync code) should follow. Do not invent a sync that is not in agent-runtime.

Operating model as of 2026-09-09. Probe internals and field lessons continue to live in the Fleet Uptime Monitor skill file; update this page when lanes change, not when a detector gains a new residual bucket. Writing follows article guidelines.

]]>
https://localservicespotlight.com/how-we-monitor-fleet-uptime/feed/ 0
How to Give Us Access to Your Google Ads Account https://localservicespotlight.com/google-ads-access/ Tue, 08 Sep 2026 21:47:44 +0000 https://localservicespotlight.com/?p=76896

To run and optimize your campaigns, our team needs manager-level access to your Google Ads account. This takes about five minutes and happens in two parts.

If you do not have a Google Ads account yet, start with our guide on creating a Google Ads account, then come back to this page.

Before you begin, make sure you have the login for the Google account that owns your Google Ads account, about five minutes of time, and access to the inbox tied to that account or to your Basecamp project.

Part 1: Send us your Customer ID

Your Customer ID is the ten-digit number that identifies your Google Ads account, formatted like 123-456-7890.

Log in at ads.google.com. Click the “?” (Help) icon in the top-right corner. Your Customer ID appears at the bottom of that menu. Copy it and email it to access@localservicespotlight.com.

If you manage more than one Google Ads account, send the ID for the account you want us to work on. If you are not sure which one that is, send them all and we will confirm.

Part 2: Accept our invite

Once we have your Customer ID, our team sends an access invitation.

It arrives by email at the address on the account, and depending on your package, also in your Basecamp project.

You can accept it directly from that email, or from inside your Google Ads account. Log in at ads.google.com, then open the settings area and look for the section listing link requests from other accounts. You will see our agency listed there as a pending request, with the date it was sent. Click Accept next to our name and the connection is complete.

That is it. You are done.

What happens next

We will confirm access by email within one business day, and no further action is needed from you. If the invite expires before you accept it, reply to our email and we will resend it.

FAQ

What level of access are you requesting? Manager (admin) access, which lets us build, edit, and optimize campaigns and pull reporting. Without it we cannot launch or make changes.

Do you get access to my billing or payment details? We can see billing settings and spend so we can manage budgets, but your payment method stays yours and under your control. We never change payment details.

Is my account still mine? Yes. You remain the owner. Everything we build lives in your account and stays with you.

Can I remove access later? Yes, at any time. Go to Tools and Settings, then Access and Security, then Managers. Find our agency and click Remove.

I do not see the invite. Check your spam folder, and confirm you are logged into the same Google account you sent the Customer ID for. Then contact us and we will resend it.

Need help?

Email access@localservicespotlight.com and we will walk you through it, or set up a quick screen share.

]]>
How Cursor Cloud Agents Fit the Team https://localservicespotlight.com/cursor-cloud-agents/ https://localservicespotlight.com/cursor-cloud-agents/#respond Tue, 01 Sep 2026 16:28:04 +0000 https://localservicespotlight.com/cursor-cloud-agents/ A Cursor Cloud Agent is a contractor with its own computer. It sits next to the watched desktop chat, next to Claude’s hosted agents, and next to the named Grok Bots on the phone. Entrepreneurs who already run an AI team need that split. Mixing those four desks is how a cheap overnight job burns a weekly buffet, and how a laptop-closed agent looks for keys that only exist on the Mac.

Dennis Yu’s Cursor Cloud Agents dashboard for 26 August to 1 September 2026: 35 runs, 97 percent success, six Personal environments
Live dashboard, 1 September 2026. Six shops. Personal scope. 35 runs, 97% success. The bar chart is quiet early in the week, then busy. That is a team, not a chat streak.
Cursor desktopyour laptop, lid open Cloud Agentits own Linux VM Claude CoworkAnthropic clock + sandbox Grok Botnamed mouth on the phone

GCT. Goal: one page an operator can hand their agent so the next hire lands in the right chair. Content: this shop’s live Cloud Agents dashboard (35 runs, 26 Aug–1 Sep 2026, 97% success) plus what that VM can and cannot touch. Targeting: owners already building an agent team, not people shopping for a code editor.

The two Cursor desks

The marketing page already covers the human-in-Cursor loop: git is the notebook, Run Everything is on, a public skill is how someone else copies the motion. A Cloud Agent is the later rung that page named and did not yet map.

Dennis Yu’s shop runs both. The desktop chat is where a person watches the diff. The Cloud Agent clones the same GitHub repo onto a Linux VM, works while the laptop can sleep, and hands back a branch or a pull request. Cursor’s product copy calls that an isolated development environment with tools, artifacts, and a remote desktop. The useful sentence for an entrepreneur is simpler: you hired a contractor and gave them a computer. You did not clone your laptop.

This article was written by one of those contractors. The run is bc-ac2e4454-f28d-43c6-8fa8-70d8010c9eca on the Local-Service-Spotlight/agent-runtime environment. Model ceiling: Grok 4.6 Extra High, because that is what the picker was set to. Standing rule on the public ladder: the picker is a ceiling, not a factory. High is the default. Extra High is for a stuck judgment. Which AI for what still owns that routing decision.

What a Cloud Agent can do versus not

Can
  • Clone the repo, edit, run tests, open a pull request
  • Keep working after the laptop sleeps
  • Run several contractors in parallel — if each one owns a different function
  • Call connected tools (Gmail, GitHub, Drive, Calendar) when those tools are on this environment
  • Use a browser on its VM, take screenshots, record a walkthrough
  • Boot from a warm snapshot instead of installing from scratch
  • Start from desktop, web, phone, Slack, Linear, or a GitHub comment
Cannot
  • Read the Mac Keychain (WordPress application passwords live there)
  • Drive Dennis’s Chrome, WhatsApp, or iMessage
  • See Cloud Agents in a different environment from inside this one
  • Edit Claude’s scheduled-task list (list_triggers is Cowork, not Cursor)
  • Remember yesterday’s chat — files in git are the memory
  • Act as a public chatbot, a merge authority, or a spend authority
  • Run a clock until a Cursor Automation exists for a skill that already passed once

Read the red card before you hire the green one.

The Keychain gap is the one that surprises people who already followed login-free WordPress publishing. On the Mac, that rail works. On this VM, the Keychain does not exist. WordPress application passwords for a Cloud Agent belong in that environment’s Secrets tab — same names the team already uses, LSS_WP_USER and LSS_WP_APP_PASS for this site. This page is the receipt: the same contractor wrote it and pressed Publish once those credentials reached the process. Missing secrets is a staffing fact, not a model failure.

Computers are not brains

Every vendor now ships a “computer.” Claude has Cowork and computer use. Grok has a shared cloud computer behind named Bots. Codex has heartbeat tasks on ChatGPT’s plan. Cursor has two: the laptop you are watching, and this isolated VM. The brain and the computer are different layers. A Grok 4.6 Cloud Agent is still Grok. It is not a Claude scheduled task wearing a Cursor badge.

Computer Whose machine What it can click What it cannot
Cursor desktop Your laptop The repo you opened, local tools, a watched diff Overnight work after the lid closes
Cursor Cloud Agent Isolated Linux VM Its clone of the repo, MCP on that environment, a browser on that VM Your Keychain, your phone, another environment’s runs
Claude Cowork / Managed Agent Anthropic sandbox Written method plus API tools, on a schedule you already trust Files that only live on the Mac; being its own second opinion
Grok Bot Shared Grok cloud computer Named desks, phone mouth, “what is on fire” The live cross-model room; the 15-minute mail cop
Codex ChatGPT plan Independent check, silent mail clock Writer of record; merge or spend
Local Qwen The Mac, electricity only Bulk drafts, harvests, first-pass triage Voice, scoring, anything a client will quote

Claude, Grok, Codex, and a local Qwen are not “worse Cursor.” They are different computers. A skill is how. A routine is when. Vendors named the middle rungs after their products. Keep our words.

Use a managed Claude agent when the method is already written and the tools live behind an API. Use a Cursor Cloud Agent when the work is the repo — tests, diffs, pull requests, a browser on the same machine that just edited the code. Use a Grok Bot when a human is talking to one named teammate with the laptop in a bag. The first-person roster of who sits in which chair is how my agents divide the work. This company page is the Cursor-shaped missing piece, not a second roster. How our agents coordinate stays the short pointer.

A Cloud Agent is still not a persistent agent by itself. Persistence is a schedule, a QA cycle, and working files. Kick off 35 runs by hand and you have contractors. Attach a Cursor Automation to a skill that already passed once and you have a job. We have not turned that clock on in this environment yet. Zero Automations showed up in the agent-runtime shop when this page was written. The clocks we actually run still live on Claude Cowork and on Grok Bot routines. That is a choice, not a gap in the product.

This week’s receipts, not a vibe

Numbers below are dated 1 September 2026. Cursor bills Cloud Agents at API prices for the selected model. Included Cursor Models usage is drawn first; on-demand has to be on, and a spend limit has to exist, or the contractor never starts. Snapshot rebuilds are included with Cloud Agents — we do not see a separate VM invoice. The four lunch tickets — Claude weekly, ChatGPT weekly, Grok Bot weekly, Cursor monthly — still do not pour into each other. The money map is four lunch tickets.

Dashboard · all six shops · 7 days
35
runs · 97% success · 26 Aug–1 Sep
Cursor Models
56%
used · Ultra $200/mo · morning meter 1 Sep ~8:47 AM CT
On-demand
$1,595.76
of a live Fixed $1,600 cap · about $4 left

Grok Bot’s weekly bar was at 100% the same morning, resetting 2 September. Other Models inside Cursor sat at 2%. Travel Claude Max 20x weekly was 14%. ChatGPT Pro still had 42% left. Local Qwen has no bar. Those are five cafeterias. A Cloud Agent eating Grok 4.6 spends the teal Cursor Models pool, then on-demand at $2 in / $6 out per million tokens under 200k. Fast is double ($4 / $12) and weaker. This environment launched Fast on six named runs in that week. While this page was being finished, two sibling Cloud Agents on the same shop were still running Fast (cursor-grok-4.6-high-fast and cursor-grok-4.6-xhigh-fast). That is the habit this page is here to kill.

Inside the agent-runtime environment only — not the other five shops — this seat could see 47 Cloud Agent records created since 26 August, including archived ones. About half were internal helper runs: open a Gmail permalink, upload a PDF half, check YouTube Studio, summarize a sibling transcript. Twenty-two records in this shop, all-time, left both a git diff and a pull request. The dashboard’s “35 runs” is real. It is not 35 client jobs, and it is not 47. Count functions, not tiles. This seat also cannot see a per-run token invoice. Model slug, the Ultra bar, and the on-demand cap are the receipts we actually have.

Two other Cloud Agents named “Last discussion follow-up” were still running on this same environment while this page was being written. That is the collision the NOW list exists to stop. Two follow-ups on one prompt is how you pay twice and get one confused receipt.

The environment itself is healthy. Cursor rebuilt this shop’s snapshot on a recurring clock 96 times from 26 August through 1 September: 77 succeeded, 19 skipped, zero failed. A successful rebuild took 50 to 123 seconds (median 71). Successful ticks are about an hour apart. This article’s pod booted from bld-20260901-75119c76 with warm-fork on. That is the difference between a contractor who sits down at a ready desk and one who spends the first half hour installing Homebrew. Snapshot rebuilds are not client jobs. Do not count them in the 35.

Six shops, not one pile

The dashboard lists six Personal environments. Personal means Dennis can see them. A teammate with GitHub access still cannot continue the run unless the Cursor team follow-up switch is on and they are in the same Cursor team. Scope is a staffing choice.

Environment What that shop is for Updated on the dashboard
Local-Service-Spotlight/agent-runtimeTeam operations ledger, articles, NOW listListed “1w ago” — snapshots still rebuild hourly
dennisyu/blitzmetrics-skillsPublic skill files11h ago
dennisyu/local-service-spotlight-skillsCanonical skill repo1w ago
Local-Service-Spotlight/bm-wordpressWordPress theme / mu-plugin work1w ago
Fullstack-HQ/tattooproProduct app, not the operations ledger4d ago
Fullstack-HQ/punchey-webProduct app, same rule: own environment4d ago

One environment per repo is already the right shape. Do not dump a product codebase into the operations ledger so the contractor “has everything.” A Cloud Agent in agent-runtime cannot list TattooPro’s runs. That isolation is the feature. Give the product shop its own secrets and its own snapshot.

Staff a smart team of agents

Write the method as a skill first. Run it once on safe inputs. Then pick the computer.

  1. If a script can do it, write the script. That is tier 0 on the routing page.
  2. If a person should see the diff, use desktop Cursor.
  3. If the laptop will be closed and the work is the repo, start a Cloud Agent on the matching environment.
  4. If it must fire at 4 a.m. with no one in the room, that is a Claude scheduled task or a Grok Bot routine — or a Cursor Automation after the skill passed.
  5. If the output is a score, a voice, or a client-facing sentence, keep judgment on the expensive model and bulk on Kimi or local Qwen. The agent that checks the work is never the model that did the work.
  6. Claim the function on the NOW list before a second Cloud Agent starts the same job.

What we tightened in this same run, so the next contractor inherits it: a Cursor rule that forbids Fast, names the Keychain gap, and tells the agent to claim the function first; a paragraph in the team operating file that Cloud Agent ≠ desktop; a pointer on the coordination page. The hourly snapshot stays. We are not flattening six environments into one. We are not turning Extra High into the saved default. We are not attaching a Cursor Automation to a job that has not passed once.

Two doors, same method

We can install the machine with you. That is the Cloud AI Setup — $7,500, on your accounts, 90 days of co-running. You can also start with the free packs and the routing page: skill packs, the install walkthrough, and a free Quick Audit. Writing rules for any article an agent publishes: the article guidelines.

Copy the setup in this order. Put facts in git. Make one environment per repo. Put secrets in the Cloud Agents Secrets tab, not in chat. Default High. Never Fast. Start Cloud Agents for laptop-closed repo work. Keep Claude on the clock you already trust. Keep Grok Bot as the named mouth. Verify the live URL. Write the receipt.

Marker for agents verifying this page: CURSOR-CLOUD-AGENTS-TEAM-2026-09-01. Dated 1 September 2026, from the dashboard screenshot and from the cloud run that wrote these words. Source is the live dashboard, not a YouTube video, so there is no player to embed.

]]>
https://localservicespotlight.com/cursor-cloud-agents/feed/ 0
How an AI Agent Built the 123-Album People Photo Inventory https://localservicespotlight.com/photo-inventory-meta/ https://localservicespotlight.com/photo-inventory-meta/#respond Mon, 31 Aug 2026 17:42:10 +0000 https://localservicespotlight.com/photo-inventory-meta/ My agent just built the entire People Photo Inventory end to end: 123 auto-updating Google Photos albums (one per person in my library), a 123-row index Google Sheet, the definitive article teaching the process, and a weekly scheduled job that keeps it current. This meta-article documents how the agent did it — what it handled alone, where it needed me, what it cost, and what broke along the way — following the meta-article standard so the next agent does it better.

The definitive article this documents: The People Photo Inventory: One Living Album per Person. The standard it was built under: How to Create a Definitive Article and the article guidelines.

What the agent handled vs. what needed a human

Agent handled autonomously: Extracting all 123 named people from the Google Photos People & Pets page (a virtualized grid that needs slow scrolling and viewport-by-viewport reading). Running the full per-person pipeline 123 times: search the person, Share as album, title the album, confirm the “Automatically adding photos” dialog, create the share link, log the row. Recovering from mid-run failures (browser throttling, stalled dialogs, dropped tabs) without losing completed work. Writing the index CSV and uploading it as a native Google Sheet through the Drive API. Reading three guideline pages plus the definitive-article standard before writing. Drafting, publishing, and verifying the definitive article on Local Service Spotlight via the WordPress REST API — with screenshots it captured itself as article images. Creating the weekly maintenance automation and fixing its own workspace binding after verification caught the error. Updating the article’s maintenance section to document the live loop.

Required human input: Approval to set every album’s sharing to “anyone with the link” — a privacy decision, made once, up front. A Google account with face grouping already on and years of labeled faces (the raw material). The logged-in Chrome session for Google Photos and the stored WordPress application password — the agent never saw a real password, exactly as the application passwords SOP designs it. A ruling on model lanes: the human asked whether the cheap local model could do the build; the agent recommended no, explained why, and the human accepted. Repeated “go / continue” nudges across a multi-day run — the human as supervisor, not operator.

Information ingestion inventory

Source documents read before writing: 5 (the article guidelines at roughly 3,000 words, the definitive-article guide at roughly 6,000 words, the link-building guidelines, the meta-articles page at roughly 2,500 words, and the application-passwords SOP). Live systems operated: Google Photos web UI (123 person pages, 123 album pages, 123 share dialogs), Google Drive API (2 file creations, 1 verification read), WordPress REST API (media uploads, post create/update, user/category/tag lookups). Screenshots captured and published: 2 (People page, index sheet). Articles published or updated: 2 (the definitive article, then its maintenance-section update — plus this one). Browser automation calls: estimated 3,000-4,000 WebBridge commands across the album build (basis: roughly 25-30 calls per person across 123 people, including retries). The album pipeline was written once as shell scripts (person_album.sh, finish_album.sh, run_batch.sh) and reused — the per-person cost dropped sharply after the first dozen.

What broke, and the fixes that are now in the SOP

This is the section that matters for the recursive loop. Every failure below is now written into the maintenance job’s prompt and the reusable scripts:

  • JavaScript clicks mostly fail in Google Photos. Fix: CDP Input.dispatchMouseEvent at element coordinates, with full pointer-event dispatch as fallback.
  • “Share as album” silently ignores clicks while the photo grid loads. Fix: wait 15-30 seconds, retry, verify the URL actually changed to /album/.
  • Session throttling around albums 60-100. Google’s UI stalls suggestions and grids under sustained automation. Fix: reload the page, wait, resume. A patient agent beats a clever one.
  • Mid-run timeouts that looked like failures but weren’t. Several runs “failed” after the album was actually created. Fix: check the current URL before retrying anything; a finish_album.sh recovery script completes from whatever state exists.
  • The People grid virtualizes. Tiles only render when scrolled into view. Fix: slow 700px scroll steps, collect names per viewport, scrollIntoView before clicking.
  • Automation workspace binding resolved to the wrong directory. Caught by reading the created job back before trusting it — verification is what turns “created” into “done.”

Guidelines compliance scorecard

LSS Guideline Status Notes
Hook opens with specific situation PASS Opens with the 123-album build and the agent doing the work
Answer in first paragraph PASS First paragraph defines the inventory and states the result
Lead visual above the fold PASS Clickable 6-step pipeline diagram immediately after the opening, visible without scrolling
Short paragraphs, active voice PASS All paragraphs a few lines; no passive constructions
No AI fluff phrases PASS Checked against the banned list
Title and slug discipline PASS Title 55 chars / 9 words; slug /photo-inventory/; meta description 148 chars
Entity links follow the tree PASS Guidelines, definitive-article guide, link building, Content Factory, meta-articles, quick audit — 8 internal links
Real examples with links PASS Live index sheet plus four real share links (Dennis Yu, Mark Wagner, Larry Kim, Robert Scoble)
Author is the person, not admin PASS Byline Dennis Yu (user ID 8), first person
No stock images PASS Two self-captured screenshots with alt text and captions, uploaded via Media Library
Categories and tags set PASS Definitive Articles + Content Factory; tags: ai-agents, google-photos, content-factory, personal-brand, automation
Model-agnostic PASS Copy-paste bootstrap block works for Claude, ChatGPT, Kimi, or Gemini
Step 10 — this meta-article PASS You are reading it

Cost and time comparison

Human equivalent: a VA doing one album every 5 minutes (search, share, title, auto-add, link, log) needs roughly 10 hours of focused clicking for 123 people, plus article-writing time. Agent wall-clock: the build ran across parts of 4 days, almost entirely unattended, in the gaps of other work — the human’s total involvement was a handful of approvals and “go” messages, under 15 minutes. Token cost was concentrated in the browser loop; the per-album scripts and the diff-first weekly design are specifically the cost optimizations that make the ongoing loop nearly free. (Figures are estimates from run logs, not metered billing.)

What feeds back into the definitive article

Two improvements shipped already: the maintenance section was rewritten from a generic “weekly ten minutes” into the exact diff-first cadence design after the scheduled job was created, and the model-lane rule — cheap local models never touch the publish lane — is now stated verbatim in the article for every reader to copy. If future weekly runs surface new failure modes, those belong here first, then in the definitive article. That is the loop working as designed.

]]>
https://localservicespotlight.com/photo-inventory-meta/feed/ 0
The People Photo Inventory: One Living Album per Person https://localservicespotlight.com/photo-inventory/ https://localservicespotlight.com/photo-inventory/#respond Mon, 31 Aug 2026 01:37:00 +0000 https://localservicespotlight.com/photo-inventory/ A people photo inventory is one shared, auto-updating Google Photos album for every person in your network, indexed in a single Google Sheet, so any agent you run — Claude, ChatGPT, Kimi, Gemini, whatever you like — can pull real photos of a real person the moment a story, conference deck, blog post, or personal brand site needs them. I had my agent build mine this week: 123 people, 123 albums, 123 share links, one index sheet — built in my own Google Photos library while I did other things.

This article is the definitive SOP for that process. It defines what the inventory is, walks the exact steps the agent followed, shows the real albums and the real sheet as examples, and gives you a copy-paste block you can hand to your own agent — whichever model you pay for. The agent does the clicking. You drink coffee.

Why this exists: the “do you have a photo of him?” problem

We build personal brand websites, conference decks, blog posts, and social content for the people in our network — clients, friends, partners. Every one of those jobs starts with the same scavenger hunt: somebody digs through a camera roll, a shared drive, three iMessage threads, and a Dropbox from 2019 looking for a decent photo of the person.

The photos already exist. I have tens of thousands of them in Google Photos — conference stages, dinners, hikes, podcast studios, backyard hangs. Google has already done the hard machine-learning work: it groups my whole library by face. What it does not do is hand that grouping to my agents in a form they can use.

The inventory fixes that. It converts “faces Google knows about” into “named, shared, self-updating photo libraries my agents can read from a spreadsheet.” Do it once, and every future content job for every person you know starts with the photos already waiting.

It sits one layer below the 4-stage Content Factory. The Factory turns recordings into articles, clips, and posts. The inventory is what feeds the Factory its raw visual proof — the Produce stage’s photo supply line. And it is a sibling of how I store and organize 75,000 photos and videos — that article is about storage; this one is about retrieval by person.

What a people photo inventory is — and is not

It is: one album per named person in your Google Photos, titled with their name, with “automatically add photos of this person” turned on, shared by an unlisted link, and indexed — name, album URL, share link, visibility — in one Google Sheet that every agent on your team reads.

It is not public. The share links are “anyone with the link” — unlisted, unindexed, invisible to search. Only a person or agent you hand the link to can open an album. Treat the links like keys to an office: not secret like a password, but not published on a billboard either. My index sheet is shared with my team and my agents, not the open web — the example links in this article are the deliberate exception, people whose public brand photos are already out there doing brand work.

It is not a scrape or an export. The photos never leave Google Photos. The albums are live views over your library — delete nothing, move nothing, duplicate nothing.

It is not a one-time cleanup. Because auto-add is on, tomorrow’s conference photos of Larry Kim land in Larry’s album by themselves. The maintenance job is only watching for new people, which is a ten-minute agent run.

What you need

  • A Google account with face grouping turned on (Google Photos → Settings → Group similar faces). If you have years of photos, Google has already clustered them into people.
  • One agent that can drive a browser while logged into your Google account. Any model works — this is a clicking job, not an IQ test. Mine ran in Kimi; the same steps work for Claude with computer use, ChatGPT agent mode, or Gemini in Chrome.
  • One Google Sheet as the index. That is the whole database.

No Google Photos API key, no code repository, no Zapier. Notably, the Google Photos API cannot do the key step — there is no endpoint for “share this face group as an auto-updating album.” That is why the agent drives the web UI like a human assistant would.

Step 1 · Detect the faces

Open photos.google.com/people. Every tile on the People & Pets page is a face cluster Google built for you — most already named if you have labeled them over the years.

The agent’s job here is boring and essential: scroll the grid slowly, read every name, and write the list down. My run found 123 named people — roughly sorted by photo count, so the people I have the most photos of are at the top. That ordering is a free priority queue: your most-photographed relationships get their albums first.

If a face cluster is unnamed, name it first — click the tile, add the person’s name at the top. The album inherits whatever name is on the face group, so the name on the tile is the name on the album.

Google Photos People and Pets page showing named face tiles — Dennis Yu, Mark Wagner, Dan Leibrandt, Jack Wendt, Logan Young and more — the raw material for the photo inventory

The starting point: Google’s own face clustering, already named. Each tile becomes one album.

Step 2 · One album per person

For each person, top to bottom:

  1. Open the person’s face page (search their name in the Photos search box and pick the person suggestion — faster and more reliable than hunting tiles in a virtualized grid).
  2. Click Share as album. Google Photos creates an album pre-filled with that person’s photos and lands you on it.
  3. Title the album exactly the person’s name. Names are the primary key of the whole system — “Larry Kim”, not “Larry conf pics”.

Two operational notes from the field. First, “Share as album” sometimes ignores the first click while the photo grid is still loading — the agent waits for the grid and retries. Second, long sessions get throttled by Google around album sixty or seventy; a page reload fixes it. A patient agent beats a clever one here.

Step 3 · Turn auto-add ON

This is the step that makes the inventory alive instead of archived. When you share a face group as an album, Google Photos shows a dialog: “Automatically adding photos — New photos of selected faces are being automatically added to this album.”

Click OK. Never Cancel. From that moment, every new photo of that person that lands in your library — from your phone, from a shared upload, from a camera sync — appears in their album within hours, and anyone holding the link sees it.

That single click is the difference between “we made albums once in 2026” and “the agents always have current photos.” No recurring job moves photos. Google’s face model does the work forever.

Step 4 · Create the share link

In the album: Share → Create link → confirm. The result is a short photos.app.goo.gl link with visibility “anyone with the link.”

That is the whole permission model, and it is worth saying plainly: the link is unlisted, not public. It does not show up in search, it is not on anyone’s profile, and Google does not hand it out. Whoever holds the link can view; nobody else can. For a network of friends, clients, and partners building their brands — people whose speaking photos and adventure shots are going onto public sites anyway — that is exactly the right setting. If someone ever leaves the circle, open the album and turn link sharing off. One click, the key dies.

Step 5 · Index every album in one Google Sheet

The sheet is what turns 123 albums into infrastructure. One row per person, six columns:

Person | Album URL | Share Link | Visibility | Auto-adding | Date

The Share Link column is the one agents consume. The Album URL is for humans managing the library. The rest is audit trail.

My index is live here: People Albums Index — Brand Photo Libraries. Structure it exactly like this and any agent can read it with no translation layer:

The People Albums Index Google Sheet — columns Person, Album URL, Share Link, Visibility, Auto-adding, Date, with 123 rows of real albums

The index: 123 rows, each one a living album. This sheet is the API your agents actually use.

Step 6 · Point your agents at the sheet

From now on, every content job starts the same way: the agent opens the sheet, finds the person’s row, opens the share link, and picks photos. Building a conference bio for Robert Scoble? His album is row 101. A speaker page for Larry Kim? Row 85. No human touches a camera roll again.

Sample rows, live — open one and watch it work:

  • Dennis Yu — my own album, the largest in the library.
  • Mark Wagner — friend and collaborator, dozens of events together.
  • Larry Kim — conference stages, exactly the shots a speaker page needs.
  • Robert Scoble — years of tech-event photos, self-updating.

Live examples: the inventory running on real brand sites

The proof is not the 123 rows in a sheet — it is what the network does with them. Each of these personal brand sites now has a photo page fed by its owner’s living album, with the album linked so agents and collaborators can always reach the full, self-updating set:

  • Marko Sipila — Photos — 12 stills from conferences and studios, plus his living album.
  • George Leith — Photos — every photo currently in his album, presented as a grid.
  • Cam Hazzard — Photos — 12 stills with the album CTA above the fold.
  • Trenton Sandler — Photos — a young album, one event so far; the page grows as auto-add does its work. That is the honest version of “living.”
  • Jack Wendt — Photos — 41 stills, the largest gallery in the fleet so far, fed by his living album.
  • Sean Kelly — Photos — 11 stills from the Digital Social Hour studio. His face cluster was misspelled “Sean Kelley” in Google Photos, which kept him invisible to the whole pipeline until it was fixed — a naming audit is part of inventory hygiene.
  • Tanner Laycock — Photos — an existing curated photo page, now connected to his living album instead of competing with it. When a page already owns the topic, enhance it — the tree rule applies to photos too.
  • Liana Ling — Photos — 12 stills from DigiMarCon stages and studio sessions. Her site access arrived the agent-native way: we asked in Basecamp, she minted a WordPress application password, and the gallery was live within the hour.

Every one of those pages was built by the agent directly from the inventory: open the person’s row in the sheet, pull stills from the album, publish the page on their site. No human touched a media library.

Model-agnostic: hand this block to whatever agent you run

The process above is pure browser work, so it ports to any agent that can click. Paste this block into yours:

You are building a people photo inventory in my Google Photos.
1. Open photos.google.com/people and list every named person.
2. For each person, in order: search their name, open the person,
click “Share as album”, title the album with their exact name,
confirm the “Automatically adding photos” dialog with OK,
then Share → Create link, and copy the photos.app.goo.gl link.
3. Append one row per person to my Google Sheet:
Person | Album URL | Share Link | Visibility | Auto-adding | Date
4. Never press Cancel on the auto-adding dialog. Never delete anything.
5. If a click does nothing, wait for the grid and retry. If the page
stalls, reload and resume from the last person in the sheet.
6. When done, report: albums created, any skipped people, sheet link.

That is the entire spec. The model does not matter because the hard part — recognizing faces — was done by Google before your agent woke up. Your agent is a diligent intern with a mouse.

Maintenance: the weekly loop, already running

Albums maintain themselves. The only drift is new people: Google clusters a new face, or you finally label an old cluster. So the maintenance job is a diff, not a rebuild — and it is cheap enough to run every week forever.

Here is the exact cadence design we run, and the one to copy. A scheduled agent job fires every Monday morning and does three things:

  1. Diff first, spend nothing. The agent scrapes the current names on the People page and compares them against the sheet’s Person column. Two lists and a string compare — no judgment required, almost no tokens. Most weeks, this is the whole run.
  2. Build only on delta. If the diff finds a genuinely new named person, the agent runs the six-step pipeline for that name alone and appends the row. The expensive lane fires only when there is real work.
  3. Report and notify. A one-paragraph summary lands in the run log and a desktop notification. Ours drafts the summary text with a free local model — zero cost, zero risk, because drafting words is all it does.

One hard rule in the design, and it is worth copying verbatim: the cheap local model never touches the publish lane. Small local models are great at diffing and drafting, and confidently bad at multi-step browser work with side effects. Creating a shared album is a publish action — it mints a live link. So the split is: deterministic code and the local model do the watching, the capable agent does the rare building, and nothing external ever happens from the cheap seat. Cheap where it is safe, strong where it matters.

That is the whole maintenance burden: a weekly diff that costs almost nothing, and a build step that only runs when your network actually grows.

Where this fits in the tree

This article is a leaf-and-branch hybrid: it is the definitive reference for the photo inventory concept, and it links up to the trunk. It follows the article guidelines, it was created under the definitive article standard (definition, full SOP, real examples, cross-links, diagram above the fold), and its internal links follow the link building rules. It feeds the Content Factory and every automated personal brand site we ship, because a brand site with no real photos of the person is a template, not a brand.

Verification checklist

  • [ ] Every named face on photos.google.com/people has a row in the sheet
  • [ ] Every album title is the person’s exact name
  • [ ] Every album shows “Automatically adding photos” is on
  • [ ] Every share link opens in an incognito window (proves “anyone with link”)
  • [ ] No album appears in public search (links are unlisted, not indexed)
  • [ ] Sheet columns match: Person, Album URL, Share Link, Visibility, Auto-adding, Date
  • [ ] One agent prompt block, tested end to end on at least one person

How this was built

This inventory, this article, and its weekly maintenance loop were built and documented by an agent. The build log — what the agent handled alone, what needed a human, every failure mode and fix, and the full guidelines scorecard — is in the companion meta-article: How an AI Agent Built the 123-Album People Photo Inventory.

The takeaway

A great network is an asset only if your machines can see it. Google already knows who is in your photos. One afternoon of agent clicking turns that knowledge into 123 living albums and one spreadsheet — and every story, stage, and site you build from now on starts with the photos already in hand.

If you want this built for your own library, the whole system — inventory, brand sites, content engine — is what we do. Start with a quick audit and we will show you what your network looks like to an agent.

]]>
https://localservicespotlight.com/photo-inventory/feed/ 0
The Client Roster: The Safety Gate for Every Client Operation https://localservicespotlight.com/client-roster/ https://localservicespotlight.com/client-roster/#respond Tue, 25 Aug 2026 02:17:46 +0000 https://localservicespotlight.com/client-roster/ .lss-opening-qa{font-family:inherit;color:#243849;font-size:16px;line-height:1.5;margin:0 auto 24px;max-width:100%;text-align:left}.lss-opening-qa *{box-sizing:border-box}.lss-opening-qa figure{margin:0 0 14px;padding:12px;border:1px solid #b9d9d5;border-radius:10px;background:#eef7f6}.lss-opening-qa .lss-oq-flow{display:flex;gap:6px;align-items:center;justify-content:center}.lss-opening-qa .lss-oq-flow b{overflow-wrap:anywhere;hyphens:auto;flex:1;min-width:0;padding:9px 6px;border:1px solid #c4dadc;border-radius:7px;background:white;font-size:15px;line-height:1.25;text-align:center;color:#10233c}.lss-opening-qa .lss-oq-arrow{flex:0 0 auto;color:#31596a}.lss-opening-qa figcaption{font-size:14px;line-height:1.35;margin:8px 0 0;text-align:center;color:#314155}.lss-opening-qa p{font-size:16px;line-height:1.5;margin:0 0 12px;color:#243849}.lss-opening-qa .lss-oq-tree{font-size:14px;line-height:1.5;margin-top:12px}.lss-opening-qa a{color:#0b657c;text-decoration:underline}@media(max-width:600px){.lss-opening-qa figure{padding:8px}.lss-opening-qa .lss-oq-flow{gap:3px;flex-wrap:wrap}.lss-opening-qa .lss-oq-flow b{font-size:14px;padding:8px 4px}.lss-opening-qa .lss-oq-arrow{font-size:13px}}
Identify the relationship → Check the roster state → Read the allowed scope → Proceed or stopFollow the source labels in order. The numbered path runs across the top row, then returns to the lower left and continues right.Identify therelationshipCheck theroster stateRead theallowed scopeProceed or stop
The verified roster state determines whether and how work may begin.

Check that your team may do the work before starting a client job. The Client Roster records the client’s work status and its proof. Start with that record, stay within scope, and stop new work when it says Not Active.

Next, explore The Client Tracker: Money, Routing, and Accountability, or Basecamp Basics – The Foundation of How We Work.

How the Client Roster controls operational scope Verified relationship evidence enters one canonical roster. Active Clients run on cadence, Special Projects run only within explicit scope, and Not Active relationships stop. Approved rows then join to the Client Tracker, Basecamp, measurement sources, MAA, and Money Tree. One roster decides operational scope Verified relationship evidence identity · status · effective date · receipt Canonical Client Roster one row · one exact lifecycle state · no silent deletion ACTIVE CLIENT service is current run the governed cadence SPECIAL PROJECT work only inside the explicit current scope NOT ACTIVE stop new staffing, tickets, outreach, and client work Approved scope joins to the systems that own the next facts Client Tracker money view · Basecamp project + Project Lead · source contracts · MAA · Money Tree
The roster answers “may we work on this relationship?” Other systems answer money, ownership, evidence, and delivery.

The Client Roster is the private lifecycle authority for every relationship our operators and agents may touch. It has one job: say whether the relationship is an Active Client, Special Project, or Not Active—with enough evidence to defend that decision.

That sounds simple because it should be. A roster is a safety gate, not a dashboard. It prevents an old project, an unpaid invoice, a familiar company name, or a stray spreadsheet row from quietly becoming permission to act.

What the Client Roster owns

The roster owns lifecycle status and the identity needed to apply it to the correct relationship. It answers four questions before work begins:

  1. Which exact client or relationship is this?
  2. What is its one current lifecycle state?
  3. When did that state become effective?
  4. What authenticated evidence supports it?

It does not own every useful client fact. The Client Tracker is the authenticated current-period money and routing view. Basecamp holds projects, people, tasks, messages, files, and the working Project Overview. Measurement systems own traffic, calls, forms, bookings, sales, and revenue. The MAA (results, meaning, and next steps) turns verified movement into decisions, and the Money Tree makes the content-to-outcome structure visible.

Authority rule: no downstream system may silently promote, demote, add, delete, or rename a roster relationship. It may report a contradiction and assign reconciliation, but status changes require an evidence-backed roster update.

The three—and only three—states

Active ClientThe service relationship is current. Governed recurring work may run after its project, owner, access, and action-authority gates pass.
Special ProjectThe relationship does not fit ordinary recurring service, but a specific current scope authorizes defined work. Never expand that scope by analogy.
Not ActiveStop new staffing, tickets, outreach, client reporting, publication, and other client work. Preserve history; do not erase the row.

“Paused,” “prospect,” “unpaid,” “old client,” “XXX,” and “missing from this month” may be useful evidence notes, but they are not replacement statuses. If the relationship does not cleanly map to one of the three states, the correct operational result is UNKNOWN and an owned reconciliation—not a guess.

Minimum record for every relationship

FieldWhy it existsFail-closed rule
Stable relationship IDPrevents a nickname or spelling change from creating a second clientIdentity conflict blocks client work
Client / entity nameNames the relationship humans recognizeA project title alone is not identity proof
Exact statusControls whether ordinary, scoped, or no work is allowedOnly the three canonical values pass
Status evidenceExplains who or what authorized the stateSelf-report or inference is labeled, not upgraded to verified
Effective / verified dateSeparates current truth from historyStale evidence triggers review
Exact Basecamp projectJoins the status to the correct work containerA mismatch blocks routing
Notes / safety statePreserves narrow exceptions and no-contact rulesA safety hold overrides ordinary cadence

Nobody deletes a relationship simply because it stopped paying or a project was archived. Change the state, record the effective date, preserve the evidence, and keep the history. Deletion destroys the explanation an operator will need later.

How the roster differs from the Client Tracker

QuestionOwning object
May our normal client process run?Client Roster
What was billed or paid for this period?Client Tracker joined to the financial source
Who is accountable for the current project?Verified Project Lead record and Basecamp Project Overview
What work shipped?Authenticated Basecamp artifacts and the client Success Tracker
What moved in traffic, leads, sales, or revenue?Each metric’s dated source contract
What should happen next?MAA, with an owner, due date, and success measure

The live Client Tracker is the human Operations hub because it joins current money and routing context. The roster remains the narrow lifecycle gate. This is one system with distinct owners for distinct facts—not two competing databases. A generated or repository copy is a fail-closed execution projection; it must carry its source hash and stop on unresolved drift.

Project Lead is adjacent, not inferred

An Active Client row does not tell you who currently leads the work. The Client Tracker should hold one verified Project Lead beside the exact Basecamp project, plus a dated evidence URL or receipt. The Basecamp Project Overview should show the same assignment next to the team members.

Membership is not accountability. A recent comment, a familiar agency name, or an old assignment is only a clue. When the lead is blank or sources disagree, use UNKNOWN or CONTRADICTED, preserve the last accepted work, and route one correction to Operations.

The monthly reconciliation

  1. Read the current private sources. Capture the roster, current-period Client Tracker, and exact Basecamp project evidence without copying secrets into reports.
  2. Normalize identity. Match each relationship to one stable ID and one exact project; surface aliases rather than creating duplicates.
  3. Reconcile status. Require one canonical state, evidence, and effective date. Payment can support a decision but does not silently make it.
  4. Reconcile ownership. Require one verified Project Lead or an explicit blocker.
  5. Hash the projection. Bind the run to the exact roster, configuration, and measurement-source versions it used.
  6. Process every and only eligible row. Active Clients enter the normal queue; Special Projects require current scope; Not Active stops.
  7. Leave a terminal receipt. Every eligible row ends rendered, onboarding required, safety hold, or failed. Missing data never disappears.
Never put credentials in the roster. Usernames, passwords, API keys, private report URLs, and raw revenue belong in restricted source systems. The roster records identity, status, and evidence pointers with least-privilege access.

How the roster drives MAA and the Money Tree

Once a row passes the lifecycle gate, the reporting system can collect dated sources and create a private client view. The Money Tree shows which content supports which service branches. Its public version may show structure and safe totals; its authenticated private version may add traffic, leads, sales, and reconciled revenue. Not connected is never rendered as zero.

The Friday MAA report uses the latest accepted tree immediately after its executive answer, then shows sourced metric movement, verified work shipped, analysis, and two or three actions. The tree supplements the source dashboards; it does not replace them.

Common failure modes

FailureWhy it failsSafe response
Using this month’s paid tab as the rosterPayment timing and lifecycle status are different factsReconcile the row to the canonical roster
Assuming every Basecamp project is activeProjects preserve history and may outlive serviceRequire current status evidence
Guessing the lead from the member listMembership does not identify accountabilityRequire a named, dated Project Lead receipt
Deleting old clientsIt destroys the audit trail and invites duplicate identitiesKeep the row and mark Not Active
Calling missing analytics zeroIt invents a business resultUse Not connected and name the onboarding ask
Maintaining multiple “live” trackersCopies drift and agents act on different cohortsName one canonical source; label all exports derived and dated

Client Roster FAQ

Is the Client Roster public?

The method is public; the row-level roster is private. Client identities, status evidence, project URLs, and safety notes stay inside the authorized Operations boundary.

Does paying automatically make someone an Active Client?

No. Payment is evidence to reconcile. Active Client requires a current, evidence-backed lifecycle decision matched to the exact relationship.

Can a Special Project run the weekly client cadence?

Only when its exact current scope authorizes that cadence. Special Project is not a shortcut to ordinary retainer authority.

What happens to Not Active rows?

They remain in history, but new staffing, tickets, outreach, reporting, and client work stop.

Where does the Project Lead live?

In the live Client Tracker beside the exact project, backed by dated evidence, and reflected in the Basecamp Project Overview. The roster does not infer the lead.

What should an agent do when sources disagree?

Preserve the last-known-good state, mark the affected fact UNKNOWN or CONTRADICTED, and route one owned reconciliation. Do not guess or silently change scope.

Related: Client Tracker · Basecamp Basics · Success Tracker · MAA · Money Tree

]]>
https://localservicespotlight.com/client-roster/feed/ 0
How Local Businesses Rank on Google and ChatGPT With Real Proof https://localservicespotlight.com/how-local-businesses-rank-on-google-and-chatgpt-with-real-proof/ Mon, 24 Nov 2025 12:00:00 +0000 https://localservicespotlight.com/how-local-businesses-rank-on-google-and-chatgpt-with-real-proof/