# Achievement activation: measurement plan

Version: 2026-10-21. Campaign: `achievement-activation-20261021`.

Use this plan to decide which published resources help a prospective buyer choose a useful first scope. This document is public. Store provider exports, lead records, booking records and weekly reports in the private reporting folder outside this site's `site/` and `content/` trees.

## Three independent proof layers

1. **Publication:** the source audit counts working resources and links against commit `34a420cbd78d22ab11ced014f0b4eaf104204875`. Optional live checks compare each deployed response with the local source. This establishes what a reader can open.
2. **Website actions:** Vercel Web Analytics records page views, fixed public-resource clicks, form steps and the existing lead/call/booking-link events. An event-handler test establishes the code path. A provider readback establishes a recorded action.
3. **Business outcomes:** a saved lead, completed calendar booking, qualified opportunity and agreed scope each need their own operational record. Count each stage separately. A resource or booking-link click does not establish completion.

Search Console query/page clicks and impressions describe Google Search exposure. They are independent of on-site actions. Keep page and query exports separate from property totals; row limits and anonymized queries can prevent their sums from matching. Compare like-for-like property, country/device filters, search type, aggregation and closed date windows.

## Fixed campaign links

Use lowercase tags on external distribution links only. Preserve each page's existing clean canonical URL; internal links remain untagged. Never put a name, email, prospect domain, contact message or private identifier into a campaign tag. No campaign parameters are copied into forms, contact payloads or calendar URLs by this implementation.

| Placement | utm_source | utm_medium | utm_campaign | utm_content |
| --- | --- | --- | --- | --- |
| LinkedIn profile Featured: qualifications | linkedin | profile | achievement-activation-20261021 | profile-qualifications |
| LinkedIn profile Featured: practice hub | linkedin | profile | achievement-activation-20261021 | profile-practice |
| LinkedIn profile Featured: expert kit | linkedin | profile | achievement-activation-20261021 | profile-expertise |
| Article distribution | linkedin | organic-social | achievement-activation-20261021 | One of the six article IDs below |
| Qualifications PDF shared externally | linkedin | document | achievement-activation-20261021 | qualifications-pdf |
| Proposal resource shared externally | linkedin | document | achievement-activation-20261021 | One of the three proposal IDs below |
| Expert kit shared externally | linkedin | document | achievement-activation-20261021 | expert-speaker-kit |

Example: `https://seo.suedeai.ai/practice?utm_source=linkedin&utm_medium=profile&utm_campaign=achievement-activation-20261021&utm_content=profile-practice`.

PDF/Markdown resource requests may bypass the HTML analytics loader. A tagged direct file request does not guarantee a Vercel Web Analytics event. Prefer a tagged HTML landing page with a measured file link when a counted visit is needed.

Article IDs: `mcp-tool-discovery`, `mcp-error-contracts`, `canonical-noindex-checks`, `source-live-evidence`, `evaluation-fixtures`, `credential-relationship-checks`.

Proposal IDs: `ai-workflow-proposal`, `search-audit-proposal`, `answer-evaluation-proposal`.

## Event contract

Markup uses `data-activation-artifact` and `data-activation-action`. The script checks the identifier against an exact public path, validates the destination origin and rejects mismatched or arbitrary destinations. The registry is in `site/assets/analytics.js`; the source audit has a matching registry guarded by a test.

| Event | Trigger | Properties | Meaning |
| --- | --- | --- | --- |
| `activation_evidence_click` | An allowlisted proof, article, case or kit page link | `artifact`, `page` | Reader chose to open a public resource |
| `activation_demo_click` | Allowlisted `/demonstrations` link | `artifact`, `page` | Reader chose a demonstration |
| `activation_qualification_click` | Allowlisted `/qualifications` link | `artifact`, `page` | Reader chose the qualifications page |
| `activation_proposal_click` | `/practice#proposals` link | `artifact`, `page` | Reader chose the proposal section |
| `activation_download_click` | Allowlisted PDF or Markdown link | `artifact`, `page` | Reader attempted to open the file |
| `Teardown click` | Existing `#scope`, `/#scope` or `#teardown-request` link | `page` | Scope/contact intent; one legacy event per click |
| `Booking click` | Existing Google Calendar link | `page` | Outbound booking intent |
| `Phone tap` | Existing telephone link | `page` | Call intent |
| `Lead` | Existing successful `suede:lead` signal | `form`, `page` | Form success signal; confirm delivery in operational records |
| `form_view`, `form_start`, `form_submit_attempt`, `form_error` | Existing website-review form lifecycle | `form`, `page`, fixed `reason` on errors | Form diagnostics, counted independently of `Lead` |

Resource-click properties never include the destination URL, query string, link text, visitor identifier, form content or client name. `page` is the current pathname. The existing URL filter removes non-UTM query parameters before page addresses reach Vercel. No identity stitching or new analytics vendor is introduced.

Each click produces at most one resource/legacy click event. Repeated loading of the analytics file does not bind another listener. Deliberate repeated clicks remain separate actions. `?qa=1` prevents the analytics loader and all its listeners from running. Preview/manual QA uses that parameter; it cannot validate receipt by the analytics provider because tracking is excluded.

## Baseline and weekly report

Capture the baseline before distribution, using the last seven complete days in `America/New_York`. Run weekly on the same day. Retain the absolute start/end dates, provider timezone, extraction timestamp, property/project, filters, row limits and provider freshness. Label any current-day extraction as partial. Keep known internal visits visible in methodology if they were not excluded at collection time.

Report this sequence as separate aggregate columns: referring source/campaign → resource page views and artifact clicks → scope clicks → `Lead` signals → operationally confirmed leads → completed bookings → qualified scopes. These are adjacent stage counts; cookieless aggregates do not prove that the same person moved between stages. Do not manufacture a joined user funnel or add conversions across sources.

Use `unavailable` for inaccessible data and `not_yet_observed` only when a successful, fully specified query found no records. A verified zero must name the queried scope and date window. Do not fill missing values with zero. Rates require a compatible denominator and the same window; do not divide Search Console clicks by website leads to assert an individual conversion rate.

Public-safe schema for a **private** weekly report:

```json
{
  "schema_version": 1,
  "campaign": "achievement-activation-20261021",
  "extracted_at": null,
  "window": { "start": null, "end": null, "timezone": "America/New_York", "complete_days_only": true },
  "search_console": {
    "status": "unavailable",
    "property": null,
    "filters": null,
    "property_totals": null,
    "page_rows": null,
    "query_rows": null,
    "row_limit": null,
    "freshness": null
  },
  "website": {
    "status": "unavailable",
    "project": null,
    "filters": null,
    "source_campaign_rows": null,
    "resource_pageviews": null,
    "artifact_clicks": null,
    "scope_clicks": null,
    "lead_signals": null,
    "booking_link_clicks": null,
    "internal_traffic_notes": null
  },
  "operations": {
    "confirmed_leads": { "status": "unavailable", "count": null, "evidence": null },
    "completed_bookings": { "status": "unavailable", "count": null, "evidence": null },
    "qualified_scopes": { "status": "unavailable", "count": null, "evidence": null }
  },
  "interpretation": { "observations": [], "hypotheses": [], "next_action": null, "causal_claim": false }
}
```

Source comparison and optional deployed readback:

```sh
node scripts/measure-achievement-activation.mjs --baseline 34a420c --out /private/tmp/achievement-source-report.json
node scripts/measure-achievement-activation.mjs --baseline 34a420c --out /private/tmp/achievement-live-report.json --live
node --test scripts/achievement-measurement.test.mjs
```

The audit records named units, source paths, input hashes, baseline commit, current HEAD and a working-tree digest. Its live mode fetches only the canonical Suede AI SEO host, makes no paid provider calls and never submits a form. A non-200, blocked request or source mismatch is recorded as incomplete. Provider settings, consent configuration and analytics retention are unchanged by this source implementation. Rollback is the repository's prior `analytics.js` plus the corresponding privacy wording and loader hash.
