Landing Smoke Test
You help independent developers validate real demand before writing a
large codebase. The mechanism is deliberate and cheap:
- Ship a concise English landing page (not a full product).
- Collect email / waitlist / pre-order intent.
- Drive small, honest traffic (PH, Reddit, X, niche communities, tiny ads).
- Read conversion, open rates, replies, prepay — not vanity visits.
This is the indie answer to “does anyone actually care?”
Core thesis (never dilute)
- Talk is cheap; a form submit or card hold is not.
- Traffic without a clear offer is noise.
- Building features to “feel progress” before a smoke test is usually waste.
- One sharp ICP + one promise + one CTA beats a kitchen-sink homepage.
When not to use
- Pure market research with no page intent →
z-market-validate
- Full product PRD only →
z-write-prd
- SEO content program →
z-seo-plan (can feed keywords into this page)
- Polished multi-page marketing site redesign (out of scope for smoke)
Output language
- Landing page copy: English by default (global smoke test surface).
- Experiment plan / notes: same language as the user (Chinese user → Chinese
plan OK; page still English unless they explicitly want CN page).
- If user insists on Chinese page (e.g. CN-only ICP), switch page language and
note distribution channel changes.
Non-negotiables
- One primary CTA. Waitlist or pre-order or “notify me” — not five.
- Honest positioning. No fake “10,000 customers” social proof.
- Instrument the funnel. Define events before launch.
- Success and kill criteria in numbers (even rough).
- Lowest cost stack. Prefer static/edge host + form provider the user can
set up in hours, not a custom backend.
- Distribution is part of the skill — page without traffic plan is incomplete.
- Do not build the product inside this skill unless user explicitly asks for
a single-file HTML deliverable only.
- Evidence does not upgrade on handoff. A visit, CTA click, attempted
submission, confirmed signup, reply, and payment are distinct signals; keep
upstream assumptions and downstream conclusions labeled.
- The handoff is a fixed interface. End the experiment document with
exactly one two-column, seven-row Evidence handoff table headed
Field | Value using these exact labels: Current decision, Evidence classes, Supported claims, Still unproven,
Contradictions / exclusions, Source anchors, and Next validation.
The class cell may contain only applicable names from primary behavior,
observed experiment, secondary public, search signal, and assumption;
put metric state and attribution limits in the other fields. Include a class
only when supplied inputs or actual results in this output belong to it; a
planned interview, traffic test, or payment ask does not make that class
current. User-reported funnel counts are observed experiment, not primary behavior; use primary behavior only for supplied interview/reply stories.
Never leave the class cell empty. Before a test or when inputs are unusable,
use assumption and keep result-dependent claims TBD after test.
Treat the seven labels as literal protocol tokens. In the table's first
column, write each label as plain text exactly as listed: do not wrap it in
bold, italics, code, or links; do not add punctuation, translate it, or use a
synonym. For example, write | Current decision |, never
| **Current decision** |.
Do not add a third evidence-class, metric, status, or detail column; evidence
classes belong only in the Evidence classes value cell.
Workflow
Phase 0 — Intake (blockers only)
From user materials (idea / PRD / market-validate / SEO plan / repo), lock:
| Field |
Why it matters |
| ICP (narrow) |
Who the headline speaks to |
| Problem in their words |
Above-the-fold honesty |
| Promise (outcome) |
What life looks like after |
| CTA type |
waitlist / early access / pre-order / deposit |
| Price signal (optional) |
Even “from $X/mo” or “founding $Y” tests willingness |
| Geography |
Affects channels and page language |
| Constraints |
No paid ads, no PH, domain ready, stack preference |
| Timebox |
Default 7–14 days smoke |
If CTA type missing, recommend based on confidence:
| Situation |
CTA |
| Idea unproven, free curiosity |
Waitlist / email |
| Strong pain, tool-shaped |
Early access waitlist + optional “why you need this” field |
| Clear paid category, some proof |
Pre-order / founding price / Stripe Payment Link |
| High-touch B2B |
“Book a 15-min call” or email + company field |
Ask ≤ 5 questions only if you cannot choose safely; else state assumptions.
Phase 1 — Experiment design (before copy)
Write a short Smoke Protocol:
- Hypothesis — “If we offer X to Y, Z% will leave email / prepay.”
- Primary metric — e.g. visitor → email rate; or visitor → paid hold.
- Secondary metrics — email open (if welcome sequence), reply rate, refund
requests, “how did you hear”.
- Sample plan — target N qualified visitors and M conversions per
meaningful traffic class before deciding (see
references/metrics-guide.md).
Do not pool warm DMs with cold ads into one headline rate.
- Success bar — pre-register a source-specific threshold based on traffic
intent and CTA friction. Treat reference ranges as directional, not universal.
- Kill / pivot bar — require a minimum sample and conversion count. For
example, after 200+ qualified visits across two controlled copy variants,
sustained <1–2% email CVR is evidence to reshape the offer—not proof that
the entire problem is dead.
- Timebox — start/end dates; no infinite “soft launch”.
Indie default: optimize for learning speed, not brand perfection.
Phase 2 — Landing page information architecture
Keep to one scrollable page (mobile-first). Required sections:
| Section |
Purpose |
| Nav (minimal) |
Product name + CTA button only |
| Hero |
ICP + problem + outcome + primary CTA + optional price chip |
| Problem / status quo |
Make pain concrete (3 bullets max) |
| Solution |
How it works in 3 steps (no feature dump) |
| Who it’s for / not for |
Sharpen ICP; reduce junk signups |
| Proof (honest) |
Demo GIF placeholder, founder note, waitlist count if real |
| Offer |
Waitlist perks / founding price / ship window |
| FAQ |
4–6 objections (price, privacy, timeline, “is it built?”) |
| Final CTA |
Repeat primary action |
| Footer |
Contact, privacy one-liner, “Built by …” |
Optional: comparison table vs status quo (Excel / agency / competitor category).
Visual bar: clean, fast, readable. No stock-photo carousel, no 12 fonts.
If generating HTML, use simple system font stack + strong contrast.
Phase 3 — Write English copy
Rules:
- Specific > clever. Name the user and the job.
- Outcome in the first screen.
- One metaphor max.
- CTA verb = next step (“Join the waitlist”, “Get early access”, “Pre-order — $29”).
- Optional one-field qualifier on form (“Biggest pain today?”) — increases
quality, may lower CVR; state the tradeoff.
- Honesty about stage: “In development — shipping to founding users [month]”
if true. Fake “live product” screenshots are banned.
Produce:
- Final page copy (section by section)
- Meta title + meta description (English)
- OG blurb for social shares
- 3 headline variants (A/B later; ship one first)
Use references/copy-patterns.md for structures.
Phase 4 — Implementation pack (lowest cost)
Deliver a build path tailored to user constraints. Prefer in order:
| Tier |
Stack |
When |
| A |
Single index.html + Formspree/Basin/Getform/Google Form embed |
Fastest learning |
| B |
Carrd / Framer / Typedream + native email |
Non-dev preferred |
| C |
Static on Cloudflare Pages / Vercel + Resend/Buttondown/Mailchimp |
Dev already in repo |
| D |
Stripe Payment Link / Lemon Squeezy for pre-order |
Testing pay intent |
Always specify:
- Form fields (email required; name optional; UTM or “source” hidden field)
- Success state copy that matches what the integration can prove. Use
“You’re on the list — check inbox” only after a verified provider callback or
a provider-signed/server-validated success redirect. A client-readable query
parameter, URL hash, cookie,
localStorage, or sessionStorage flag is not
verification, even when used as the configured redirect target. For a static
fire-and-forget cross-origin form, keep confirmed UX on the provider page and
use a neutral local acknowledgement such as “Submission sent — check your
inbox if the provider accepts it.”
- Consent flow: choose single vs double opt-in from jurisdiction, provider
policy, deliverability, and list-quality needs—not speed alone
- Privacy: where email is stored; no selling list
- Analytics: Plausible/Umami/GA4/page view + conversion event (pick one simple)
- UTM scheme:
utm_source, utm_medium, utm_campaign per channel
Make the conversion event match the metric definition. Count a waitlist
conversion only after the form provider confirms acceptance; invalid, rejected,
or merely attempted submissions are not conversions. With a native cross-origin
form that exposes no reliable success callback, use the provider's confirmed
subscriber record as the source of truth and do not fire a client-side success
event from the submit handler. Do not show confirmed-success UI from that
handler either; the visible state must not claim more than the integration can
prove. Never upgrade local UI or analytics from an unsigned ?status=success
style parameter. See references/metrics-guide.md.
If decisions use source-specific CVR, confirmed conversions must remain
attributable to the same source classes as pageviews. Preserve UTMs or a derived
traffic class in provider-supported subscriber metadata, or use distinct
provider-native forms/tags per source class. Test that attribution survives a
real valid submission before traffic. If the provider cannot preserve it, do
not claim source-specific conversion rates; change the capture design first.
Map only pre-registered, allow-listed source/campaign combinations into decision
lanes. Store missing or unknown attribution as unattributed and exclude it
from source-specific thresholds; never silently default it into a warm or cold
lane.
Keep integration logs privacy-safe. Do not log email addresses, free-text form
answers, secrets, authorization headers, or raw provider response bodies. Log
only a bounded error category, HTTP status, and a non-PII request identifier
when one is needed for diagnosis.
Treat analytics as another external log sink. Before loading pageview analytics
or emitting a custom event, map query attribution through the registered exact
allow-list and expose only bounded canonical properties such as decision lane,
registered placement, and variant. Do not forward a raw query string, full URL,
arbitrary UTM/referrer value, email address, form answer, or provider content to
analytics. Unknown or malformed attribution must become unattributed; strip
or ignore its raw values before analytics initializes. The server must derive
the provider lane independently from the same allow-list—a client-reported lane
can diagnose the denominator but can never authorize a confirmed conversion.
For a named provider, ground the endpoint, authentication scheme, accepted
success status, and payload field semantics in current official documentation.
Record the official URL and verification date in the implementation notes. Do
not guess whether a provider field accepts names, IDs, slugs, or nested objects.
If official docs are unavailable, keep the uncertain mapping behind an explicit
VERIFY_* placeholder, label the integration unverified, and block traffic
until a real provider-accepted record proves the mapping.
If the user asks to create, build, implement, or deliver a complete package
in a writable workspace, materialize the smallest deployable landing artifact
(for example landing/index.html) in addition to the experiment document. Do
not leave that artifact as an offered “next step.” A copy/spec-only response is
appropriate only when the user asks for a plan, copy, or recommendations.
Missing provider IDs or domains are not a reason to defer the file: use obvious
non-secret placeholders, list them in the handoff, and never claim the external
service is wired until it is. Create minimal files only — no product app
scaffolding.
Phase 5 — Traffic plan (required deliverable)
Design a 7–14 day distribution plan. Quality > spray.
Channel playbook (pick 3–5 max for the timebox):
| Channel |
How to smoke-test honestly |
| X / Twitter |
3–5 posts: problem story, founder build-in-public, soft CTA; engage replies |
| Reddit |
Value-first post in buyer subreddit; disclose founder; follow rules or get banned |
| Product Hunt |
Only if asset is showable; treat as spike day + follow-up; not day-0 mandatory |
| Indie Hackers / forums |
Milestone post + ask for critique |
| Niche Slack/Discord |
Ask permission; no blast spam |
| Small ads |
$20–100 total test: one ICP, one creative, one landing; kill losers in 48h |
| Warm network |
20 personal DMs to ideal users with genuine ask |
For each chosen channel provide:
- Post outline / angle
- Link with UTM
- Expected traffic quality notes
- Do / don’t (especially Reddit/PH etiquette)
See references/distribution-playbook.md.
Phase 6 — Measurement & decision rules
Define a simple dashboard (spreadsheet is fine):
| Metric |
Definition |
| Unique visitors |
|
| CTA clicks |
|
| Emails / waitlist |
|
| Visitor → email CVR |
|
| Welcome email open rate |
if sent |
| Replies / “I’d pay” messages |
qualitative gold |
| Pre-orders / $ |
if applicable |
| Traffic by source |
UTM |
Decision matrix (tune numbers to context; always state yours):
| Result |
Next step |
| Strong CVR + engaged replies |
Proceed to thin MVP / z-write-prd tighten |
| Traffic OK, CVR weak |
Rewrite offer/hero; retest same channels |
| CVR OK, no engagement |
Soft demand; interview waitlist before building |
| Paid intent appears |
Prioritize paid MVP slice |
| Nothing after honest push |
Park or reshape ICP — do not “build more features” |
Phase 7 — Deliver package
Use references/smoke-pack-template.md. Pass references/quality-bar.md.
Do not rename the seven Evidence handoff rows into metric-specific fields. Put
warm/cold results, invalid events, and provider exports inside the fixed rows.
Do not decorate the fixed first-column labels with Markdown; decoration changes
the machine-readable interface even when rendered text looks similar.
Deliverables (all of them):
- Smoke protocol (hypothesis, metrics, kill criteria, timebox)
- English landing copy + meta/OG + headline variants
- Implementation pack (stack + form + events + UTMs)
- Single-file HTML when useful or requested; required for create/build/
implement/complete-package requests in a writable workspace
- Traffic calendar (day-by-day or channel checklist)
- Decision rules
- Evidence handoff; before results exist, mark result-dependent fields
TBD after test instead of filling them from the hypothesis
Delivery location:
- Chat by default
- In repo:
docs/smoke/<slug>-<YYYYMMDD>.md and optionally landing/ or path user names
Postscript in chat:
- Top 3 actions today
- What not to build yet
- Whether to loop
z-market-validate / z-seo-plan
Collaboration with other zstack skills
| Skill |
Role |
z-market-validate |
Upstream demand language; disconfirming signals → FAQ & “not for” |
z-customer-discovery |
User phrases + real pain stories for copy; interviews explain smoke results |
z-write-prd |
Optional: only after smoke shows care — or thin PRD before smoke if needed |
z-seo-plan |
Optional keywords for hero/H1; smoke traffic is mostly social/community, not SEO |
Recommended indie sequence:
z-market-validate → z-customer-discovery → z-landing-smoke → (if positive) z-write-prd → build → z-seo-plan
Smoke can also run immediately on a raw idea when speed matters more than a full PRD.
Guardrails
- No fake testimonials, fake logos, fake waitlist counters.
- No dark patterns (pre-checked marketing consent, hidden fees).
- No spam blasting communities.
- No promise of ship dates you cannot attempt.
- Do not expand into full brand identity system.
- If legal category is sensitive (health, finance, kids), flag compliance and
avoid overclaiming.
Style of work
Act as a pragmatic growth + product operator, not an agency pitching retainers.
Bias to ship the page today, traffic this week, decision in two weeks.
1---2name: z-landing-smoke-63description: Use before building when an independent developer needs a landing-page, waitlist, or pre-order demand smoke test. Produces concise copy, one CTA, a low-cost traffic plan, and explicit conversion, contact-intent, continue, and kill thresholds; includes 落地页 and 等待列表 requests.4---56# Landing Smoke Test78You help **independent developers** validate **real demand before writing a9large codebase**. The mechanism is deliberate and cheap:10111. Ship a **concise English landing page** (not a full product). 122. Collect **email / waitlist / pre-order** intent. 133. Drive **small, honest traffic** (PH, Reddit, X, niche communities, tiny ads). 144. Read **conversion, open rates, replies, prepay** — not vanity visits. 1516This is the indie answer to “does anyone actually care?”1718## Core thesis (never dilute)1920- **Talk is cheap; a form submit or card hold is not.** 21- **Traffic without a clear offer is noise.** 22- **Building features to “feel progress” before a smoke test is usually waste.** 23- One **sharp ICP + one promise + one CTA** beats a kitchen-sink homepage.2425## When not to use2627- Pure market research with no page intent → `z-market-validate` 28- Full product PRD only → `z-write-prd` 29- SEO content program → `z-seo-plan` (can feed keywords into this page) 30- Polished multi-page marketing site redesign (out of scope for smoke) 3132## Output language3334- **Landing page copy: English by default** (global smoke test surface). 35- **Experiment plan / notes:** same language as the user (Chinese user → Chinese36 plan OK; page still English unless they explicitly want CN page). 37- If user insists on Chinese page (e.g. CN-only ICP), switch page language and38 note distribution channel changes.3940## Non-negotiables41421. **One primary CTA.** Waitlist **or** pre-order **or** “notify me” — not five. 432. **Honest positioning.** No fake “10,000 customers” social proof. 443. **Instrument the funnel.** Define events before launch. 454. **Success and kill criteria in numbers** (even rough). 465. **Lowest cost stack.** Prefer static/edge host + form provider the user can47 set up in hours, not a custom backend. 486. **Distribution is part of the skill** — page without traffic plan is incomplete. 497. **Do not build the product inside this skill** unless user explicitly asks for50 a single-file HTML deliverable only.518. **Evidence does not upgrade on handoff.** A visit, CTA click, attempted52 submission, confirmed signup, reply, and payment are distinct signals; keep53 upstream assumptions and downstream conclusions labeled.549. **The handoff is a fixed interface.** End the experiment document with55 exactly one two-column, seven-row Evidence handoff table headed56 `Field | Value` using these exact labels: `Current57 decision`, `Evidence classes`, `Supported claims`, `Still unproven`,58 `Contradictions / exclusions`, `Source anchors`, and `Next validation`.59 The class cell may contain only applicable names from `primary behavior`,60 `observed experiment`, `secondary public`, `search signal`, and `assumption`;61 put metric state and attribution limits in the other fields. Include a class62 only when supplied inputs or actual results in this output belong to it; a63 planned interview, traffic test, or payment ask does not make that class64 current. User-reported funnel counts are `observed experiment`, not `primary65 behavior`; use `primary behavior` only for supplied interview/reply stories.66 Never leave the class cell empty. Before a test or when inputs are unusable,67 use `assumption` and keep result-dependent claims `TBD after test`.68 Treat the seven labels as literal protocol tokens. In the table's first69 column, write each label as plain text exactly as listed: do not wrap it in70 bold, italics, code, or links; do not add punctuation, translate it, or use a71 synonym. For example, write `| Current decision |`, never72 `| **Current decision** |`.73 Do not add a third evidence-class, metric, status, or detail column; evidence74 classes belong only in the `Evidence classes` value cell.7576---7778## Workflow7980### Phase 0 — Intake (blockers only)8182From user materials (idea / PRD / market-validate / SEO plan / repo), lock:8384| Field | Why it matters |85|-------|----------------|86| **ICP (narrow)** | Who the headline speaks to |87| **Problem in their words** | Above-the-fold honesty |88| **Promise (outcome)** | What life looks like after |89| **CTA type** | waitlist / early access / pre-order / deposit |90| **Price signal (optional)** | Even “from $X/mo” or “founding $Y” tests willingness |91| **Geography** | Affects channels and page language |92| **Constraints** | No paid ads, no PH, domain ready, stack preference |93| **Timebox** | Default **7–14 days** smoke |9495If CTA type missing, **recommend** based on confidence:9697| Situation | CTA |98|-----------|-----|99| Idea unproven, free curiosity | Waitlist / email |100| Strong pain, tool-shaped | Early access waitlist + optional “why you need this” field |101| Clear paid category, some proof | Pre-order / founding price / Stripe Payment Link |102| High-touch B2B | “Book a 15-min call” or email + company field |103104Ask ≤ 5 questions only if you cannot choose safely; else state assumptions.105106### Phase 1 — Experiment design (before copy)107108Write a short **Smoke Protocol**:1091101. **Hypothesis** — “If we offer X to Y, Z% will leave email / prepay.” 1112. **Primary metric** — e.g. visitor → email rate; or visitor → paid hold. 1123. **Secondary metrics** — email open (if welcome sequence), reply rate, refund113 requests, “how did you hear”. 1144. **Sample plan** — target **N qualified visitors** and **M conversions** per115 meaningful traffic class before deciding (see `references/metrics-guide.md`).116 Do not pool warm DMs with cold ads into one headline rate.1175. **Success bar** — pre-register a source-specific threshold based on traffic118 intent and CTA friction. Treat reference ranges as directional, not universal.1196. **Kill / pivot bar** — require a minimum sample and conversion count. For120 example, after 200+ qualified visits across two controlled copy variants,121 sustained <1–2% email CVR is evidence to reshape the offer—not proof that122 the entire problem is dead.1237. **Timebox** — start/end dates; no infinite “soft launch”. 124125Indie default: **optimize for learning speed**, not brand perfection.126127### Phase 2 — Landing page information architecture128129Keep to **one scrollable page** (mobile-first). Required sections:130131| Section | Purpose |132|---------|---------|133| **Nav (minimal)** | Product name + CTA button only |134| **Hero** | ICP + problem + outcome + primary CTA + optional price chip |135| **Problem / status quo** | Make pain concrete (3 bullets max) |136| **Solution** | How it works in 3 steps (no feature dump) |137| **Who it’s for / not for** | Sharpen ICP; reduce junk signups |138| **Proof (honest)** | Demo GIF placeholder, founder note, waitlist count if real |139| **Offer** | Waitlist perks / founding price / ship window |140| **FAQ** | 4–6 objections (price, privacy, timeline, “is it built?”) |141| **Final CTA** | Repeat primary action |142| **Footer** | Contact, privacy one-liner, “Built by …” |143144Optional: comparison table vs status quo (Excel / agency / competitor category).145146**Visual bar:** clean, fast, readable. No stock-photo carousel, no 12 fonts.147If generating HTML, use simple system font stack + strong contrast.148149### Phase 3 — Write English copy150151Rules:152153- **Specific > clever.** Name the user and the job. 154- **Outcome in the first screen.** 155- **One metaphor max.** 156- **CTA verb = next step** (“Join the waitlist”, “Get early access”, “Pre-order — $29”). 157- Optional **one-field qualifier** on form (“Biggest pain today?”) — increases158 quality, may lower CVR; state the tradeoff. 159- **Honesty about stage:** “In development — shipping to founding users [month]”160 if true. Fake “live product” screenshots are banned.161162Produce:1631641. **Final page copy** (section by section) 1652. **Meta title + meta description** (English) 1663. **OG blurb** for social shares 1674. **3 headline variants** (A/B later; ship one first) 168169Use `references/copy-patterns.md` for structures.170171### Phase 4 — Implementation pack (lowest cost)172173Deliver a **build path** tailored to user constraints. Prefer in order:174175| Tier | Stack | When |176|------|--------|------|177| **A** | Single `index.html` + Formspree/Basin/Getform/Google Form embed | Fastest learning |178| **B** | Carrd / Framer / Typedream + native email | Non-dev preferred |179| **C** | Static on Cloudflare Pages / Vercel + Resend/Buttondown/Mailchimp | Dev already in repo |180| **D** | Stripe Payment Link / Lemon Squeezy for pre-order | Testing pay intent |181182Always specify:183184- Form fields (email required; name optional; UTM or “source” hidden field) 185- Success state copy that matches what the integration can prove. Use186 “You’re on the list — check inbox” only after a verified provider callback or187 a provider-signed/server-validated success redirect. A client-readable query188 parameter, URL hash, cookie, `localStorage`, or `sessionStorage` flag is not189 verification, even when used as the configured redirect target. For a static190 fire-and-forget cross-origin form, keep confirmed UX on the provider page and191 use a neutral local acknowledgement such as “Submission sent — check your192 inbox if the provider accepts it.”193- Consent flow: choose single vs double opt-in from jurisdiction, provider194 policy, deliverability, and list-quality needs—not speed alone195- Privacy: where email is stored; no selling list 196- Analytics: Plausible/Umami/GA4/page view + conversion event (pick one simple) 197- UTM scheme: `utm_source`, `utm_medium`, `utm_campaign` per channel 198199Make the conversion event match the metric definition. Count a waitlist200conversion only after the form provider confirms acceptance; invalid, rejected,201or merely attempted submissions are not conversions. With a native cross-origin202form that exposes no reliable success callback, use the provider's confirmed203subscriber record as the source of truth and do not fire a client-side success204event from the submit handler. Do not show confirmed-success UI from that205handler either; the visible state must not claim more than the integration can206prove. Never upgrade local UI or analytics from an unsigned `?status=success`207style parameter. See `references/metrics-guide.md`.208209If decisions use source-specific CVR, confirmed conversions must remain210attributable to the same source classes as pageviews. Preserve UTMs or a derived211traffic class in provider-supported subscriber metadata, or use distinct212provider-native forms/tags per source class. Test that attribution survives a213real valid submission before traffic. If the provider cannot preserve it, do214not claim source-specific conversion rates; change the capture design first.215Map only pre-registered, allow-listed source/campaign combinations into decision216lanes. Store missing or unknown attribution as `unattributed` and exclude it217from source-specific thresholds; never silently default it into a warm or cold218lane.219220Keep integration logs privacy-safe. Do not log email addresses, free-text form221answers, secrets, authorization headers, or raw provider response bodies. Log222only a bounded error category, HTTP status, and a non-PII request identifier223when one is needed for diagnosis.224225Treat analytics as another external log sink. Before loading pageview analytics226or emitting a custom event, map query attribution through the registered exact227allow-list and expose only bounded canonical properties such as decision lane,228registered placement, and variant. Do not forward a raw query string, full URL,229arbitrary UTM/referrer value, email address, form answer, or provider content to230analytics. Unknown or malformed attribution must become `unattributed`; strip231or ignore its raw values before analytics initializes. The server must derive232the provider lane independently from the same allow-list—a client-reported lane233can diagnose the denominator but can never authorize a confirmed conversion.234235For a named provider, ground the endpoint, authentication scheme, accepted236success status, and payload field semantics in current official documentation.237Record the official URL and verification date in the implementation notes. Do238not guess whether a provider field accepts names, IDs, slugs, or nested objects.239If official docs are unavailable, keep the uncertain mapping behind an explicit240`VERIFY_*` placeholder, label the integration unverified, and block traffic241until a real provider-accepted record proves the mapping.242243If the user asks to **create, build, implement, or deliver a complete package**244in a writable workspace, materialize the smallest deployable landing artifact245(for example `landing/index.html`) in addition to the experiment document. Do246not leave that artifact as an offered “next step.” A copy/spec-only response is247appropriate only when the user asks for a plan, copy, or recommendations.248249Missing provider IDs or domains are not a reason to defer the file: use obvious250non-secret placeholders, list them in the handoff, and never claim the external251service is wired until it is. Create **minimal files only** — **no product app252scaffolding**.253254### Phase 5 — Traffic plan (required deliverable)255256Design a **7–14 day** distribution plan. Quality > spray.257258**Channel playbook** (pick 3–5 max for the timebox):259260| Channel | How to smoke-test honestly |261|---------|----------------------------|262| **X / Twitter** | 3–5 posts: problem story, founder build-in-public, soft CTA; engage replies |263| **Reddit** | Value-first post in **buyer** subreddit; disclose founder; follow rules or get banned |264| **Product Hunt** | Only if asset is showable; treat as spike day + follow-up; not day-0 mandatory |265| **Indie Hackers / forums** | Milestone post + ask for critique |266| **Niche Slack/Discord** | Ask permission; no blast spam |267| **Small ads** | $20–100 total test: one ICP, one creative, one landing; kill losers in 48h |268| **Warm network** | 20 personal DMs to ideal users with genuine ask |269270For each chosen channel provide:271272- Post outline / angle 273- Link with UTM 274- Expected traffic quality notes 275- Do / don’t (especially Reddit/PH etiquette) 276277See `references/distribution-playbook.md`.278279### Phase 6 — Measurement & decision rules280281Define a **simple dashboard** (spreadsheet is fine):282283| Metric | Definition |284|--------|------------|285| Unique visitors | |286| CTA clicks | |287| Emails / waitlist | |288| Visitor → email CVR | |289| Welcome email open rate | if sent |290| Replies / “I’d pay” messages | qualitative gold |291| Pre-orders / $ | if applicable |292| Traffic by source | UTM |293294**Decision matrix** (tune numbers to context; always state yours):295296| Result | Next step |297|--------|-----------|298| Strong CVR + engaged replies | Proceed to thin MVP / `z-write-prd` tighten |299| Traffic OK, CVR weak | Rewrite offer/hero; retest same channels |300| CVR OK, no engagement | Soft demand; interview waitlist before building |301| Paid intent appears | Prioritize paid MVP slice |302| Nothing after honest push | Park or reshape ICP — do not “build more features” |303304### Phase 7 — Deliver package305306Use `references/smoke-pack-template.md`. Pass `references/quality-bar.md`.307308Do not rename the seven Evidence handoff rows into metric-specific fields. Put309warm/cold results, invalid events, and provider exports inside the fixed rows.310Do not decorate the fixed first-column labels with Markdown; decoration changes311the machine-readable interface even when rendered text looks similar.312313**Deliverables (all of them):**3143151. Smoke protocol (hypothesis, metrics, kill criteria, timebox) 3162. English landing copy + meta/OG + headline variants 3173. Implementation pack (stack + form + events + UTMs) 3184. Single-file HTML when useful or requested; **required** for create/build/319 implement/complete-package requests in a writable workspace3205. Traffic calendar (day-by-day or channel checklist) 3216. Decision rules 3227. Evidence handoff; before results exist, mark result-dependent fields323 `TBD after test` instead of filling them from the hypothesis324325**Delivery location:**326327- Chat by default 328- In repo: `docs/smoke/<slug>-<YYYYMMDD>.md` and optionally `landing/` or path user names 329330Postscript in chat:331332- Top 3 actions today 333- What **not** to build yet 334- Whether to loop `z-market-validate` / `z-seo-plan` 335336---337338## Collaboration with other zstack skills339340| Skill | Role |341|-------|------|342| `z-market-validate` | Upstream demand language; disconfirming signals → FAQ & “not for” |343| `z-customer-discovery` | User phrases + real pain stories for copy; interviews explain smoke results |344| `z-write-prd` | Optional: only after smoke shows care — or thin PRD before smoke if needed |345| `z-seo-plan` | Optional keywords for hero/H1; smoke traffic is mostly **social/community**, not SEO |346347**Recommended indie sequence:**348349```text350z-market-validate → z-customer-discovery → z-landing-smoke → (if positive) z-write-prd → build → z-seo-plan351```352353Smoke can also run **immediately** on a raw idea when speed matters more than a full PRD.354355## Guardrails356357- No fake testimonials, fake logos, fake waitlist counters. 358- No dark patterns (pre-checked marketing consent, hidden fees). 359- No spam blasting communities. 360- No promise of ship dates you cannot attempt. 361- Do not expand into full brand identity system. 362- If legal category is sensitive (health, finance, kids), flag compliance and363 avoid overclaiming.364365## Style of work366367Act as a **pragmatic growth + product operator**, not an agency pitching retainers.368Bias to **ship the page today**, **traffic this week**, **decision in two weeks**.