Measurement & Analytics Agent

Skill packs › Skill

Measurement & Analytics AgentIN EVERY PACK

Read the source → Check the number → Choose the next stepFollow the source labels in order. The path runs from top to bottom.Read the sourceCheck the numberChoose thenext step
Every reported number links to its source, scope, and time period.

Find out which work brings leads and sales to your business. This guide helps your team check reports and use the real numbers to choose the next step. Start with the source for each number; keep missing data unknown.

Skill file measurement-analytics.md · last updated Aug 17, 2026

Start with one result. Read this guide or find it in the skill-pack directory. Give your AI app the guide and the source files it can read, then ask for one draft you can check. A ZIP holds instructions; it does not install a plugin or grant access. For reusable setup, follow the current installation guide and verify a fresh run. This one ships in every pack.

The rule this agent enforces: no number, no verdict. A healthy funnel passes a simple economic test — front-end sales pay for the ads, so leads are free. You cannot know that without measuring every stage, and “I think it’s working” is not a measurement. This agent switches the numbers on — and because it’s YOUR agent with YOUR access, you own the whole loop.

Read these first, every run: your links file (funnel page URLs), your offers + prices, your latest tracking sheet if one exists, and the benchmarks below. Numbers come ONLY from connected sources or files you provide — never estimated, never invented. A metric you can’t verify is reported as “not connected yet.”

The proof rule behind every report

Measurement Source Contract

A metric is reportable only when another operator can trace it to the same source, scope, definition, and time period. This contract is the boundary between a verified number and a guess. It governs the Client Tracker, the weekly MAA (results, meaning, and next steps), and each public or private Money Tree.

1. Identify the source
Name the system, account or property, client entity, domain, and authorized scope. “Google” or “the CRM” is not precise enough.
2. Define the metric
Record the event or field being counted, filters, attribution rule, source period, comparison period, and timezone.
3. Preserve the receipt
Keep a dated export, query definition, dashboard readback, checksum or immutable receipt, plus who collected it and when.

Not connected never means zero.
If access, identity, scope, freshness, or reconciliation fails, label that source Not connected or Failed. Do not estimate it, borrow another client’s number, or silently carry it forward. Preserve the last accepted artifact with its freshness date.

The seven outcome sources stay separate

Search Console measures search visibility and clicks. GA4 measures site behavior. Call tracking and form systems measure inquiries. The CRM measures qualified leads and pipeline movement. Booked-job records measure accepted work. Accounting or payment records measure collected or recognized revenue. A session is not a lead, a lead is not a booking, and a booking is not collected revenue.

GSC
GA4
Calls
Forms
CRM
Booked jobs
Collected revenue

Minimum receipt for every reported metric

  • Connection state: connected, not connected, failed, expired, or contradicted.
  • Identity and scope: client, entity, domain, source account/property, and permitted view.
  • Definition: metric name, event or field, filters, attribution rule, and any exclusions.
  • Time: source period, comparison period, timezone, collection timestamp, and freshness.
  • Provenance: query/export definition, receipt or artifact pointer, checksum where available, and collecting owner.
  • Comparability: reconciliation status and an explicit warning when two periods or systems cannot be compared.
Acceptance test
A reviewer can reopen the named source, reproduce the metric for the same period, explain any difference, and trace the number to the report branch it supports. If that test fails, the metric cannot support an earnings claim or a “top money branch” ranking.

What it connects to (each one is optional — more access = sharper verdicts)

  1. Your CRM / funnel platform (HighLevel, etc.) — page visits, form submissions, contacts, tags, email opens/clicks, payments. In HighLevel: Settings → Private Integrations → create one named my-agent, read-only scopes (contacts, funnels/pages stats, payments) → copy the token → tell Claude: “Add a custom connector: URL https://services.leadconnectorhq.com/mcp/ with my Private Integration Token.” Two minutes, revocable any time, scoped to YOUR account only.
  2. Meta Ads / Google Ads — spend, reach, clicks, cost per result. Easiest v1 path: export the campaign table (last 7/28 days) as CSV into your project folder; your agent reads it. The CSV takes 60 seconds and always works; API connection is a later upgrade.
  3. Google Analytics 4 — traffic sources and landing-page behavior. Same v1 path: the standard Traffic acquisition + Landing pages exports, or grant viewer access if your agent runs in a browser-capable setup.
  4. Your email platform (if separate) — subscriber count and growth. Local businesses: add your Google Business Profile insights export (calls, direction requests, bookings) — for many local funnels GBP is the real front door.

The weekly measurement (steps)

  1. Pull the stage numbers for the last 7 days (and the 7 before, for deltas): landing-page visits (organic page vs ads twin page — that split IS your attribution) · opt-ins → opt-in rate · low-ticket checkouts (or paid diagnostics / booked estimates) → take-rate · front-end revenue · ad spend (campaigns + boosts) · list size + growth · email opens/clicks if available.
  2. Compute the five verdicts:
  • Opt-in rate vs 25% target (35% excellent) — below target after 100+ visits → the landing page is the weakest stage.
  • Take-rate vs 3% target (10–15% possible) — below → the low-ticket offer/page is the weakest stage.
  • Cost per lead = spend ÷ ad-page opt-ins.
  • Self-liquidation = front-end revenue ÷ ad spend. ≥1.0 → “your leads are FREE — scale is allowed.” <1.0 → name the leaking stage; scaling is NOT allowed yet.
  • Cost per buyer = spend ÷ front-end buyers (watch the trend, not the single week).
  1. Respect data discipline: no verdict on any page with under 100 visits — flag “collecting data” instead. Compare like periods. One-line note when a number moved >30% week-over-week.
  2. Write the weekly report (format below) and hand off: the weakest-stage verdict goes to your sales-every-day agent (it becomes tomorrow’s action); the self-liquidation verdict goes to your dollar-a-day agent (scale / hold / fix first); the three headline numbers pre-fill your weekly MAA.
  3. Log the run. Never send anything anywhere — the report is a file (and a draft if your email is connected). You decide what travels.

The report (one page, every week)

` WEEK OF <date> — <your name>’s funnel TRAFFIC LP visits: organic ___ / ads ___ (Δ vs last week) LEADS opt-ins: ___ · opt-in rate: ___% [target 25%+] · cost/lead: $___ REVENUE front-end sales: ___ = $___ · take-rate: ___% [target 3%+] VERDICT self-liquidation: $___ revenue vs $___ spend = ___ → SCALE / HOLD / FIX <stage> WEAKEST STAGE: <stage> → handed to your Sales Every Day agent for tomorrow’s action NOT CONNECTED YET: <list — each one makes the next report sharper> `

Run it scheduled

“Create a scheduled task: every Friday at 6am, run my measurement-analytics skill and leave the weekly report in my Outputs folder.” You own the access, the tokens, and the report. The weekly MAA stops being an opinion the first Friday this runs.

Definition of done

  • Every number traces to a connected source or a named file; everything else says “not connected yet.”
  • The five verdicts are stated with benchmarks, and under-100-visit pages are never judged.
  • Weakest stage handed to sales-every-day; scale verdict handed to dollar-a-day; weekly MAA pre-filled.
  • Zero actions taken on ads or funnels — this agent measures; its siblings act; you approve.

Pairs with

→ sales-every-day (acts on the weakest stage) → dollar-a-day-strategist (scales only on a green verdict) → weekly-brand-maa (the report becomes the MAA) → content-agent (feeds the traffic) → recursive-self-improvement-qa


Built by Dennis Yu (BlitzMetrics / Local Service Spotlight). Measure every stage, so the daily selling is aimed — and the lead gen pays for itself.

Where this task fits in the Content Factory

This task supports work across the Content Factory (our four-stage process for using real content). Its inputs and next handoff determine which stage uses it.

1. ProduceCapture real work
2. ProcessTurn sources into useful assets
3. PostPublish and connect approved assets
4. PromoteShare proven work and measure results
Follow the numbered stages from Produce to Promote. Each stage links to its part of the Content Factory guide.

Start, finish, and next step

Start when
The agreed weekly measurement window closes for an authorized client or funnel.
Have ready
  • Connected source accounts or named exports
  • Accepted metric definitions, scope, timezone and period
  • The preceding comparison period
Follow the steps
  1. Identify each source and metric contract
  2. Pull the current and comparison windows
  3. Compute the source’s applicable stage verdicts
  4. Preserve missing connections and sample-size limits
  5. Write the weekly report and hand off the weakest stage

Use the detailed instructions in this article for each step.

Finish with
A sourced measurement report that can prefill MAA and inform the next authorized action.
Measure the result
  • Every number traces to the same source, definition and period
  • Missing sources are not reported as zero
  • Under-100-visit pages are not judged against the source’s rate thresholds
  • Measurement does not execute ads or funnel changes
Hand off next
Pass the weakest-stage evidence to sales-every-day, the scale verdict to Dollar-a-Day, and the report to weekly MAA.

Reference material for the inputs

Open this article’s tasks in the Task Library (our directory of tasks and recipes; see current Task Library). The library connects the current recipe, its smaller tasks, and the records of work performed.

Close the learning loop. Write a meta article: the record of this execution with the starting state, recipe version, result, checks, failures, and next owner. Link it back to this recipe and register the run under the same Task Library task. Reuse one execution ID for revisions and retries. A partial or failed run stays labeled that way. Public release follows the recorded publication authority; writing the run record is part of doing the task. Writing and revising that record belong to the original execution; they do not start another meta-article task. Use the findings to propose and verify a recipe improvement. See how recipes and execution records work together.

Learned in the field

Appended automatically by the self-improvement loop (Skill-Learnings/): dated lessons from real runs. Newest at the bottom.

<!– learning:2026-07-20-ahrefs-free-dr-endpoint-auth-deadline –> July 20, 2026 (from: anthony-hilb-seo-tracker (weekly-brand-maa) — refiled from a stray root note by skill-pack-propagation on July 21, 2026)

Ahrefs’ free Domain Rating endpoint stops accepting unauthenticated calls on August 1, 2026.

⚠ RESOLVED August 3, 2026 — read this first: use site-explorer-domain-rating, always.
Everything in this section down to “Rules for any skill that pulls Ahrefs Domain Rating” is
the historical record of a deprecation that no longer needs tracking. Do not act on the dates.

The public-domain-rating-free MCP call still returns the normal DR value today but now carries a deprecation warning: “Unauthenticated access to this endpoint will be removed on 2026-08-01. Requests will require a free API key.” Every weekly/monthly tracker that pulls DR (anthony-hilb, wtp, trenton-sandler, cxotalk, family-law, somba, and any future tracker) will start erroring from August if its call path is unauthenticated.

Rules for any skill that pulls Ahrefs Domain Rating:

RESOLVED — August 3, 2026. Use site-explorer-domain-rating. Always. There is no date left to track and no key to register. The three dated rules below are superseded, kept only as the record.

Why the free endpoint was retired from our skills rather than migrated:

  • We already hold the key. The workspace MCP authenticates with a paid Lite key

(subscription-info-limits-and-usage returns real workspace data, so auth demonstrably works). The “free API key” in Ahrefs’ warning is for callers who hold no key at all. Registering a second one would have added a credential to manage in exchange for nothing.

  • Identical numbers. Verified August 3, 2026 across two domains: anthonyhilb.com returned DR 10

from both endpoints, michaelkrigsman.com DR 1.0 from both.

  • The authenticated endpoint is MORE accurate. public-domain-rating-free lags the authenticated

series by about a day, which is exactly what put a wrong DR 11 into the anthony-hilb 2026-07-20 snapshot. Switching removes a known defect; it is not merely deprecation-proofing.

  • Cost is not a constraint. ~50 units per call against a 100,000/month Lite allowance. For many

domains at once, batch-analysis takes up to 100 targets in ONE call at ~18 units each, verified to return DR values identical to the single endpoint.

The meta-lesson, which is the part worth keeping. This block carried a hard-coded vendor date into six skill files, and only ONE of them ever received the July 27 correction from August 1 to August 10. The other five still read “Until August 1, 2026” on August 3 — a deadline that was both wrong and already expired, still instructing agents to prefer the dying endpoint. A conditional written around a vendor’s date has to be re-verified in every copy, forever; an unconditional instruction needs nothing. Prefer the instruction that cannot go stale over the one that is merely correct today — and when a correction lands, grep for the other copies in the same breath. Same shape as the “a standing contract recorded in one file is not a standing contract” rule in Skill-Learnings/README.md.

Superseded, retained as the record:

  1. ~~Until August 2026 keep using public-domain-rating-free first — it works and costs 0 units.~~
  2. ~~If it errors, fall back once to site-explorer-domain-rating and state the switch in the report.~~
  3. ~~Permanent fix: register a free API key (about a 5-minute setup).~~

Learned July 20, 2026. Resolved August 3, 2026.

<!– learning:ghl-mcp-truth-2026-07-27 –> July 27, 2026

HighLevel’s official MCP (https://services.leadconnectorhq.com/mcp/, Private Integration Token auth) exposes 36 tools — contacts, conversations, opportunities, payments, calendars, forms, social posts, blog posts, email templates. It does NOT expose funnels or landing pages, and the underlying REST Funnels API is read-only (list funnels / list pages / count pages only). There is no create or update endpoint in any version.

Consequence for every agent that touches a CRM: never promise to “build the funnel page.” Write the page to the client’s own WordPress site as a draft and hand over paste-ready copy for their page template. This is also the only route that works for clients not on the coach’s platform.

Send safety: conversations_send-a-new-message is a REAL send — never call it on a scheduled run. emails_create-template is the safe way to stage a daily email.

<!– learning:2026-08-03-a-compromised-site-must-not-outscore-a-clean-one –> August 3, 2026 (from: weekly-fleet-hub-audit v2, fleet-wide proof enrichment)

Rankings are evidence about someone’s work — check whose before you score them

The fleet scoreboard rates every site on PROVE: Domain Rating, organic traffic, and the breadth of keywords it ranks for. On August 3, 2026 the two sites whose keyword breadth looked strongest were philmershon.com (15 ranking keywords) and theathletespotlight.com (5). Both readings were the attacker’s, not the client’s.

Pulling the keywords themselves rather than the count showed philmershon.com — a speaker coach — ranking for hollymoviehd, borat thong, nintendo store, jupiter 125 black colour, silver aranjanam for baby boy. Fourteen of its fifteen keywords were junk. On theathletespotlight.com it was five of five: activa 6g best colour, bici decathlon, charola de unicel. Selecting best_position_url alongside the keyword named the cause — every junk term ranked on an injected path:

/product-similar-image/?<digits> /product/category/<digits> /shop/manufacturer-site?&transition=top<digits>

with a per-site numeric suffix (…1310 on one, …1760 on the other): one kit, two of our sites. Uncorrected, philmershon.com scored impact 40; netting the injected rankings out drops it to 21 — an eight-point BIS swing. A compromised site was being rewarded for being compromised, and would have been reported as a fleet-best performer.

Rules:

  1. Never score a ranking you have not attributed to a URL. org_keywords is a count of

things Google associates with the domain, not a count of the client’s wins. Select best_position_url and read the paths before any keyword number reaches a score or a report.

  1. Net hostile rankings out of the score and raise them as an action instead. Traffic

attributed to injected URLs gets discounted in the same proportion. Infection is a dispatch item, never a credit.

  1. Judge the keywords by fit with the person, not by how spammy they look. `nintendo

store` is a fine keyword — for a games retailer. The tell is a speaker coach ranking for it. The GCT (Goals, Content, Targeting: the goal, material, and audience) already states who each site is for; compare against that.

  1. A clean sitemap and a clean REST API do not mean a clean site. Both sites’ sitemaps

and post lists were entirely legitimate, and their real content is real. The injection lives beside WordPress, in URL space the CMS never enumerates — so any check that walks the sitemap or /wp-json/wp/v2/posts is structurally unable to find it. What Google has indexed is a separate source of truth from what the CMS will admit to.

  1. 404 today does not mean clean. These URLs now return 404 to human and Googlebot

alike from a datacenter IP, while still ranking. That is consistent with cleaned-but- still-indexed and with a cloak keyed to something the probe can’t reproduce. Say which of those you have ruled out; removal still has to be requested in Search Console either way, because the junk keeps ranking after the files are gone.

Companion to the same day’s classify-the-metric-dont-just-count-it (referring domains, same disease one metric over): fleet median referring domains is 368 against a median of 26 dofollow, because a .shop/.store link-spam blast hits every site daily. Report refdomains_dofollow; refdomains is noise. billybatt.com reads as 324 referring domains and is actually 2 dofollow, both of them ours — the authority problem the number appears to have solved is entirely intact. Ahrefs exposes an is_spam flag; use it.

Learned August 3, 2026.

<!– learning:2026-08-03-buckets-must-partition-the-thing-they-explain –> August 3, 2026 (from: weekly-fleet-hub-audit v2, phase 1 down-site triage)

If a report splits a set into buckets, assert that the buckets add up

The fleet audit deliberately splits unreachable sites two ways so a WAF block is never reported as an outage: genuinely_down (DNS/TLS/connection failure) and waf_suspect (403 from our crawler’s IP). The runbook says to read those two lists rather than the raw “Homepage NOT reachable” line, because the raw line conflates them.

On August 3, 2026 the raw line said 4 and the two buckets said 1 + 2.

The missing site was owenhemsath.com, returning a real HTTP 500 — a genuine outage on our own AWS fleet host, up and healthy the week before. The classifier had always produced a third kind, http_NNN, for real 4xx/5xx; nothing ever consumed it. So a site could be hard-down and appear in no dispatch list, while every summary line in the report stayed true. Following the runbook exactly would have made a live outage invisible for a week.

Fixed in audit_fleet.py and _combine_batches.py: an http_error bucket plus an explicit down_unclassified = down − (genuinely_down ∪ waf_suspect ∪ http_error) that prints a loud warning when non-empty. Proven able to fail before being trusted — injecting a bogus _home_kind into a scratch copy put the site in down_unclassified and printed the warning.

Rules:

  1. Every partition gets a residual bucket and an assertion. Whenever a report explains

a total by splitting it into categories, compute total − Σ(categories) and surface it loudly. Categories that came from an enum will silently drop members the day the enum grows a value.

  1. A value the producer emits and no consumer reads is a latent hole, not dead code.

Grep the consumer for every value the producer can return.

  1. The conflated line is the honest one. When a summary offers both a raw total and a

nicer breakdown, treat any disagreement between them as the finding.

  1. Read deltas for artifacts before narrating them. The same run’s needs_hub went

84 → 85 with “1 resolved: owenhemsath.com” — which reads as progress and was the outage: needs_hub requires homepage_up == yes, so a site leaves the list by going down. Any queue gated on reachability shrinks when sites break. State that in the report rather than counting it as work completed.

Learned August 3, 2026.

<!– learning:2026-08-03-prefer-the-instruction-that-cannot-go-stale –> August 3, 2026 (from: Ahrefs free-DR deprecation follow-up after the anthony-hilb-seo-tracker run)

A conditional built on a vendor’s date rots in every copy except the one you corrected

The anthony-hilb report flagged that Ahrefs’ public-domain-rating-free endpoint stops accepting unauthenticated calls on August 10, 2026 — seven days out, and the date of the tracker’s own next run — and recommended a “5-minute free API key registration.” Chasing that down produced two findings, and the second is the one that generalises.

1. The registration was never necessary, and checking took one call. The workspace MCP already authenticates with a paid Lite key. The “free API key” in Ahrefs’ warning is aimed at callers who hold no key at all. site-explorer-domain-rating returns the identical number on the key we already have — verified across two domains the same day (anthonyhilb.com DR 10 from both endpoints, michaelkrigsman.com DR 1.0 from both) — for ~50 units against a 100,000/month allowance. It is also more accurate: the free endpoint lags the authenticated series by about a day, which is precisely what wrote a wrong DR 11 into the 2026-07-20 snapshot. So the “deprecation fix” was really a defect fix that had been available all along.

Rule: before scheduling work to satisfy a vendor’s new requirement, check whether the credential you already hold satisfies it. A deprecation notice describes the vendor’s default caller, not your setup.

2. The instruction had already rotted in five of six copies. The block telling agents to prefer the free endpoint lived in six skill files. On July 27 the cutoff moved from August 1 to August 10, and exactly ONE file — weekly-brand-maa.md — received the correction. On August 3 the other five still read “Until August 1, 2026 keep using public-domain-rating-free first”: a deadline that was both wrong and two days expired, still actively instructing agents toward the dying endpoint. Nobody noticed, because each file was individually plausible and nothing compares them.

The fix was not to propagate the new date. It was to delete the date: the rule is now unconditional — use site-explorer-domain-rating, always — with the dated version struck through beneath it as the record, plus a pointer at the top of the section so an agent reading top-to-bottom cannot hit the stale narrative first.

Rules:

  1. Prefer the instruction that cannot go stale over the one that is merely correct today. “Use X”

survives indefinitely. “Use X until DATE, then Y” is a maintenance obligation in every copy, forever, and it fails silently and invisibly — an expired conditional reads exactly like a live one.

  1. **When a correction lands on a duplicated instruction, grep for the other copies in the same

breath.** This is the same shape as the standing rule in Skill-Learnings/README.md that “a standing contract recorded in one file is not a standing contract,” and the same shape as the July 29→31 gap between a rebuild gate being learned and the runner being changed. Three independent recurrences means the default is wrong: assume duplication until a grep proves otherwise.

  1. A date copied out of a vendor’s warning is the least durable thing in a skill file. Where one

must be written down, write it as “as of <Month D, YYYY> the API said X” so the staleness is visible on the page — and pair it with a dateless instruction that stays correct if nobody ever revisits it.

  1. Check the whole fleet of callers, not the one that surfaced the problem. Of 31 scheduled task

prompts, only two named the dying endpoint and two others were already on the authenticated one. Grepping the mirrored prompt set answered in one call what would otherwise have been six file reads and a guess.

Learned August 3, 2026.

<!– learning:2026-08-03-a-check-that-can-quietly-not-check-reports-green-either-way –> August 3, 2026 (from: skill-pack-propagation, August 3, 2026 — adding a concurrency gate exposed two ways a gate can disable itself)

A guard that can silently decline to run is worse than no guard, because it still prints the green line. Adding one concurrency gate to the daily runner on August 3, 2026 exposed two instances within ten minutes. First, the runner invoked it as [[ -x ./tools/x.sh ]] && run it — so a lost executable bit, from a zip round-trip or a clone or a copy that did not preserve mode, would skip the gate and say nothing. Gate on existence, invoke through the interpreter (zsh ./tools/x.sh), and make ABSENT a hard failure, not a skip. Second, the runtime-completeness test derived its required-file list by scanning the runner for python3 <path>.py invocations — correct, and blind to the ./tools/x.sh the runner had just gained. It printed “COMPLETE — all 31 referenced paths are present” while the new gate was absent from the cloud runtime entirely. A derivation that understands only one of the languages its source is written in is a hand-maintained list wearing a derivation’s clothes; it drifts exactly like one, but with more credibility.

The general form: for every automated check, ask what makes it a no-op — a missing file, a permission bit, a resource already held, an empty input, a regex that matches nothing — and make each of those loud and distinguishable from a pass. The self-test added that day correctly declines to run against a live lock, which is right; the runner then reported “guard OK ()” with an empty count, which was not. “NOT CHECKED” and “PASSED” must never render the same. When you extend a pipeline, extend the thing that verifies the pipeline in the same change, and confirm the verifier actually fails before you trust it passing.

<!– learning:2026-08-05-a-disabled-check-must-not-print-the-same-word-as-a-passing-one –> August 5, 2026 (from: skill-pack-propagation daily run)

“date OK” was printed by a check that had switched itself off — and the machine-readable twin certified the date the page did not show

blitzmetrics.com/task-library-dashboard served August 3, 2026 through a run whose own log said:

EDITED blitzmetrics.com/task-library-dashboard (id 104693): 1 url swap(s), dates -> August 5, 2026 VERIFY rendered (HTTP 200): urls OK, date OK

Both lines were true statements about what the code intended and false about the page. The mechanism was one line:

ok_d = (TODAY_HUMAN in hay) if dated else True

dated was bool(old_dates) — whether the date pattern had matched anything. The page’s badge phrasing was unrecognised, so nothing matched, so dated was False, so the check was skipped and printed the identical word it prints when it passes. A reader cannot tell the two apart, which means the green line is not weak evidence, it is manufactured evidence.

Rules:

  1. A check’s disabled state must never be spelled like its passing state. “OK”,

“not applicable”, and “NOT CHECKED” are three different facts and must read as three different facts. If a check can decline to run, its output has three values, not two.

  1. Prefer no gate to a conditional gate. The fix was to look every time and to describe

what was found — OK, OK (no badge pattern matched, but today's date is present), NOT STAMPED. The condition that used to skip the check now only changes the wording.

  1. Fixing a drift in one direction can create it in the other. On August 1, 2026

data-kept-current was found lagging a visible badge that was correct daily, and the fix made the attribute follow the badge. On this page there was no badge the code could see, so the attribute became the only thing that updated: it read 2026-08-05 while the human-readable page read August 3. The machine twin went from trailing the truth to asserting something the page visibly contradicted — strictly worse, because that attribute exists precisely to be trusted by machines that will never read the prose.

  1. Two representations of one fact need an equality assertion, not two writers. The

durable guard is: if the machine field says today and the human text never does, fail. It needs no knowledge of how the badge is worded, so it is the check that will still work on the surface nobody has thought about yet.

  1. **When two verifiers disagree about one page, the louder one is not automatically right —

but the disagreement is always a defect.** Here step 4 said OK and step 7 said MISSING on the same URL. Step 7 was correct. The fact that a later stage caught it is not a reason to leave the earlier stage lying: a lie at step 4 costs the diagnosis time of every future failure, and step 4 is the one that decides what gets published.

Diagnostic that settled it in one fetch: the same anonymous, cache-busted response contained the new zip filename and the old date. A stale cache cannot do that — it would have to miss both. One request separated “the page did not update” from “the page updated and the date logic never fired,” and pointed straight at the badge pattern.

Learned August 5, 2026.

<!– learning:2026-08-10-coverage-metric-from-a-frozen-file –> August 10, 2026 (from: weekly-fleet-hub-audit 2026-08-10)

A coverage number must be derived from the system it claims to describe, never from a file that only a human edits. If the source never changes, the metric cannot go up when the work lands and cannot go down when access is lost — it is a constant wearing a KPI’s clothes.

Found 2026-08-10: the fleet pulse reported “verified in Search Console: 9/92” every week from a CSV last written 2026-07-17. On 08-03 it printed 9 while gsc-enrichment.json did not exist at all — the number had zero live evidence behind it. When this run actually pulled Search Console, two of that CSV’s eleven VERIFIED rows (jasongamato.com, piotrzawislak.com) returned “you don’t have access” on every resource_id form. So the frozen source was not merely stale, it was wrong, and it was wrong in the flattering direction.

The fix is a resolution order that records HOW each fact is known, not just the fact:

  • live — we pulled real numbers for it this run. Proof of access.
  • lost — we tried this run and were refused. Proof of NO access, and it must outrank any stored claim.
  • claim — neither; fall back to the stored file, but label it, and report claims separately from proven coverage.

Report the three counts side by side. The moment claim is visible as its own number, nobody can mistake an assertion for a measurement, and a property that quietly falls out shows up as lost in the same week rather than being carried forward forever by a CSV.

Two collection gotchas worth carrying:

Search Console resource_id form. Our fleet properties are URL-prefix (resource_id=https%3A%2F%2F<domain>%2F), not domain properties. Querying one as sc-domain:<domain> returns Google’s “Oops, you don’t have access to this property” page — byte-identical to the response for a property you genuinely lost. Guessing the wrong form therefore manufactures a false regression. Try BOTH forms before recording any property as lost; only a domain that refuses every form is actually gone.

Vendor quota is a single point of failure for the whole proof layer. This run the Ahrefs workspace sat at 104,072 of 100,000 monthly units, nine days from reset, so every proof call returned “API units limit reached”. Do not paper over that by writing another vendor’s numbers into the same fields: DataForSEO’s backlink rank is 0–1000 and Ahrefs’ Domain Rating is 0–100, and DataForSEO’s referring-domain counts run roughly 10x lower on this fleet because it does not index the nofollow spam blast Ahrefs counts. Silently swapping them would have rendered as a fleet-wide authority collapse that never happened. Keep the second source in its own file with its scale documented, leave the primary values untouched and stamped with the date they were actually measured, and say plainly in the report that Proof contributed zero week-over-week delta this run.


Other skills: ai-search-visibility · boil-the-ocean · client-access-checklist · client-relationship-cadence · content-agent · content-factory

The full run order is on the skill-pack directory. Every skill here is one task from the Task Library — the library is the catalogue of what can be done; a pack is the subset you install; an agent is who runs it.

Where this sits in the system

A skill describes how to do a task. A pack groups skills. Work happens when an authorized agent runs a job with the agreed inputs, checks the result, and saves the work record. Installing a skill does not start an agent or create a schedule.

  1. Skill — the written method for a task; use the linked Task Library for its current tasks and state.
  2. PackYOU ARE HERE — a selection of skills; follow the current installation guide for setup and access.
  3. Agent — the person or AI worker carrying out an authorized task with the required access and tools.
  4. Job — an authorized execution with a trigger, inputs, checks, and a saved result; recurring work also needs an actual configured schedule.
  5. Proof — a written meta article (a record of one task run) for every execution, including partial or failed runs; public release follows recorded authority, and verified lessons improve the recipe.

The map: The System · every asset: Asset Tracker · next door: Asset Tracker.

Scroll to Top