Audrey Path Engine — Architecture Thinking
Status: Working doc — canonical architecture reference for the audrey workstream Date: 2026-05-13 Domain: audreyinc.com (Shopify scarf shop) Reader of derived dashboards: Dan (private) Horizon: Daily A/B testing through 31 Dec 2026
1. Context
- audreyinc.com: Shopify storefront, ~30k visits/day per Cloudflare Analytics.
- Revenue state: Flat. Daily A/B testing committed through 31 Dec 2026 (~230 days, realistically 100–150 distinct experiments).
- Existing pattern (precedent):
dashboard.dare.co.ukruns a GitHub Actions cron (06:00 + 18:00 UTC) that fetches Cloudflare Analytics GraphQL, builds a brief, asks Haiku 4.5 for 5 voice variants in a “dry-witty observer” register, picks one, renders static HTML, deploys to Cloudflare Pages. ~$0.04/mo, ~90s runtime. - Plumbing reuse:
dashboard.audreyinc.comis the second instance of the same engine shape; a portfolio health dashboard is queued as the third. Worth extracting before the third lands.
2. Mental model shift
audreyinc.com is not a static site. It is a parameterised path engine with Shopify as the checkout backend. Every visitor arrives via a distinct intent signal (ad source, agent recommendation, organic search, referral) and should land in a journey tuned to that intent. The site has surface area; the engine has logic.
This shift unlocks three things in parallel: - A/B testing as an everyday operation, not an occasional campaign. - Agentic discoverability (LLMs as a real traffic source). - Attribution down to “which path converted which segment.”
3. The Path Engine — four layers
3.1 Variant Library (pre-generated)
- Generation: GitHub Action runs the Claude API (probably Sonnet 4.6 for visitor-facing copy; Haiku 4.5 for brief generation). Weekly cadence by default; manual trigger on demand.
- Storage: JSON or HTML in Cloudflare KV or R2.
- Schema (proposed):
json { "slug": "gift-mum-summer-50s", "use_case": "gifts/mother-summer-birthday", "target_signal": ["utm:pinterest_gift_q3", "referrer:llm"], "voice_register": "warm_curator", "hero": { "headline": "...", "subhead": "...", "media": "..." }, "product_order": ["sku_a", "sku_b", "sku_c"], "copy_blocks": { ... }, "cta": { "label": "...", "destination": "..." }, "schema_org": { ... }, "generated_at": "...", "experiment_id": "..." } - Pre-generation = zero LLM cost at request time, full editorial review before anything ships.
3.2 Routing Worker
- Cloudflare Worker sits in front of audreyinc.com landing paths (or a dedicated subdomain / path prefix if Shopify routing is brittle).
- Reads: UTM params, referrer, geo, cookie, user-agent (detects LLM crawlers).
- Maps signal → variant slug via a routing config (probably KV-stored, hot-reloadable).
- Sets a
served_variant_idcookie so variant persists across the visitor’s session. - Fallback chain: matched signal → use-case default → site default.
3.3 Attribution Layer
- Worker writes
served_variant_idanddiscovery_channelinto the session. - Shopify checkout webhook fires on purchase → enrichment service joins purchase to served variant via session ID.
- Output: a clean event stream of (variant_id, segment, converted_yes/no, order_value).
- Feeds the daily brief.
3.4 Selector Intelligence (later)
- Once ~30 days of attribution data exists, weighting can shift toward winning variants per segment (Thompson sampling or epsilon-greedy).
- v1: round-robin or rule-based.
- Defer until v0 attribution is proven clean.
4. Top-of-funnel: 5 canonical use cases
These are stable, indexable, agent-citable URLs designed as the destination an LLM or search engine sends a buyer to. Each use case sits above the variant routing — i.e., a use case is the canonical URL, and variant routing happens within it based on traffic source.
Structure:
- Stable URL (never expires): audreyinc.com/<category>/<intent>
- Canonical schema.org markup describing recipient profile, occasion, price range.
- Dual-audience copy: human-readable AND answers the implicit agent retrieval query.
- 3–5 active variants per use case, refreshed weekly.
The 5 use cases themselves are the next decision to lock. They are load-bearing — URL taxonomy, schema, prompt design, and variant scope all flow from them. Proposed working session: 20-min divergence (12–15 candidates) → collapse to 5 covering real conversion potential.
5. Agentic discoverability
audreyinc.com should be findable and citable by LLM agents (Claude, Perplexity, ChatGPT, future native shopping agents).
Implementation surface:
/llms.txtat root. Emerging convention (cf. robots.txt). Declares taxonomy, recommended canonical pages, what each use case answers.- schema.org markup on every page:
Product,Offer,FAQPage,Recommendation. Use-case pages need custom additions describing recipient profile and occasion — not just product fields. - Dual-audience copy. Headings, alt text, meta descriptions written so the use-case page reads as a strong retrieval answer to the implicit query (“scarf gift for woman in her 50s, summer birthday”).
- MCP server (leading-edge). Cloudflare Workers MCP is first-class. Expose audrey’s catalog as an MCP server with structured queries:
recommend_gift(recipient_age, occasion, budget). When Claude (and others) gain native shopping intents, audrey is already wired in. Worth setting up early to learn the surface even before agent commerce is mainstream.
6. Daily dashboard companion
The dashboard at dashboard.audreyinc.com is the operational heartbeat of the engine.
6.1 Voice
- Register: “Growth partner over morning espresso.” Confident, slightly impatient, action-biased. Diagnoses fast, prescribes faster. Speaks in shopping-path language (paths, leaks, thresholds, friction).
- Distinct from dare’s voice (“dry-witty observer”): dare’s data has no action attached; audrey’s data demands a move. Voice must convert observation into a shippable test.
- Memory feel: Should sound like someone who has been watching the data for weeks and remembers what was tried last Tuesday.
6.2 Brief shape (5-part)
- Vital signs — revenue, sessions, conversion rate, AOV vs 7d/28d baseline.
- What shifted — one or two real anomalies in the shopping path.
- The opportunity — narrative thread, typically a leak or underexploited segment.
- Yesterday’s test verdict — ship / kill / extend.
- Today’s test — one concrete A/B hypothesis launchable in Shopify before next brief.
The last line is the lock. 06:00 prescribes; 18:00 reports early read; loop closes daily.
6.3 Cadence
- 06:00 + 18:00 UTC via GitHub Actions (same plumbing as dare).
- LLM step: Haiku 4.5, 5 voice variants, pick one.
- Output: static HTML on Cloudflare Pages.
7. Sequencing decision — what to build first
Three candidate first steps were considered: (a) brief template against real Shopify+CDN, security layer, and DNS provider sitting in front of dare.co.uk.">CF fields, (b) voice/system prompt, (c) experiment ledger schema.
Decision: Draft (a) and (b) as a single pass, not strict sequence.
- Brief template fields constrain what the voice can do; voice constraints determine which fields are worth querying. Drafting them separately produces either over-broad queries or ungrounded copy.
- Format: one artefact, two columns —
field → what the voice does with it. - (c) Experiment ledger schema: defer. Markdown file with 5 columns (hypothesis, variant, dates, sample, verdict) holds the line until ~10 tests have shipped and real patterns emerge.
Practical first task: 45-min spike to draft brief template against actual Shopify Admin GraphQL field names + voice prompt v0, side by side. Lands as a single tracked artefact in this repo. Unblocks the build. (Done — see audrey_dashboard_brief_template_2026-05-13.)
8. Cost reality
- Variant generation: Haiku at ~3k in / 1.5k out per variant ≈ £0.005–0.01. 100 variants < £1. 1,000 variants is trivial. Sonnet for visitor-facing copy costs more but still bounded.
- Daily brief generation: ~$0.04/mo pattern from dare extends.
- Real constraint: statistical power. 30k visits/day ÷ 100 variants = 300 hits/variant/day — enough for big effects (hero, CTA), not subtle ones.
- Implication: 100 variants is reasonable as a library; live config should have 5–15 variants active per use case at any time, refreshed weekly.
9. Attribution flow (closing the loop)
Visitor arrives (LLM agent / ad / referral / organic)
↓
Worker reads signal → selects variant slug
↓
Variant served → cookie set (served_variant_id, discovery_channel)
↓
Visitor browses → checkout (Shopify)
↓
Shopify webhook → enrichment service joins purchase to variant
↓
Event stream: (variant_id, segment, converted, AOV)
↓
Daily brief surfaces winners / losers / open tests
Within 60 days: empirical data on which discovery channels drive buyers vs browsers, surfaced in the morning brief.
10. Adjacent pattern (reusable plumbing)
Three instances now exist of the same engine shape:
| Instance | Status | Voice | Data sources |
|---|---|---|---|
dashboard.dare.co.uk |
Live | Dry-witty observer | Cloudflare Analytics |
dashboard.audreyinc.com |
In build (placeholder live) | Growth partner | Shopify Admin GraphQL + CDN, security layer, and DNS provider sitting in front of dare.co.uk.">CF Analytics |
| Portfolio health snapshot | Queued | TBD | TBD |
The spine: scheduled trigger → typed data fetcher(s) → brief builder → LLM variant generator → selector → renderer → deploy.
With instance #3 incoming, the cost of not extracting the spine into a template engine (drift between voices, divergent error handling, three places to update on model changes) starts to exceed the cost of extracting it. Recommend extraction work happens before portfolio health begins, not after.
11. Open questions / next decisions
- Lock the 5 use cases. Load-bearing. Nothing else proceeds cleanly without them.
- Draft brief template + voice prompt v0 as single tracked artefact (the 45-min spike). (Done — audrey_dashboard_brief_template_2026-05-13)
- Decide: Worker in front of full Shopify domain vs. dedicated landing subdomain vs. dedicated path prefix? Affects Shopify integration depth.
- MCP server timing: build now (learn the surface) or defer until agent commerce signals are clearer?
- Variant generation prompts: one master prompt + per-use-case modifiers, or fully separate prompts per use case?
- When to extract the shared engine spine into a template repo — before or after portfolio health begins?
12. Reference IDs and locations
- Shop domain:
audreyinc.com - Dashboard domain:
dashboard.audreyinc.com(placeholder live) - Repo:
xlab-co/audrey-dashboard(placeholder);xlab-co/audrey-pipeline(not yet created — daily brief GHA) - Data sources: Shopify Admin GraphQL, Cloudflare Analytics GraphQL
- LLM (brief): Claude Haiku 4.5
- LLM (variant copy): Claude Sonnet 4.6 (proposed)
- Hosting: Cloudflare Pages (dashboard) + Cloudflare Workers (routing engine)
- Cron: GitHub Actions, 06:00 + 18:00 UTC
- Companion instance:
dashboard.dare.co.uk(pattern source) - Sibling artefacts in catalog:
- audrey_dashboard_proposal_2026-05-13 — early strategic proposal (partially superseded by §3 here)
- audrey_dashboard_brief_template_2026-05-13 — field+voice contract for the dashboard layer