Compiled 2026-08-30 UTC / 2026-08-29 evening PDT.
Written to be picked up cold by someone with no context. Everything is here: identifiers, every
ad day to the hour, every object and its state, every decision and its reasoning, every fix, every
mistake, every tool, every open question.
Companion docs (all in repo):
ADS-PLAN.md · LEARNINGS.md · sources/competitive-research/competitor-audit-2026-08-28/ ·
output/ufo-banner-2026-08-27/RECUT-NOTES.md · docs/META-ADS-MCP.md
by an out-of-session MCP call — operator has not confirmed this was intentional).
(control), one pins it on screen from 0.0s (banner). This is a one-variable test.
pattern, but two things changed at once: the budget and it being the first weekend day.
They cannot be separated from history.
Do not try to read Sunday. Monday vs Thu/Fri is the clean comparison.
the budget change, and the go-forward budget.
| item | value |
|---|---|
| Ad account | 928489503435693 — "Brett Ads" |
| Page | 107954045643337 — Raw Chemistry |
| Instagram user | 17841477912140752 — @rawchemistryus |
| Pixel | 622400256897443 |
| Access route | mcp__claude_ai_Meta__* MCP tools |
| Timezone | America/Los_Angeles (PDT) — all "today" figures follow this, not UTC |
instagram_user_id is mandatory on video ads under an all-placements ad set. Without it Meta
rejects with error 1772103. Statics do not need it.
| item | value |
|---|---|
| Store | raw-chemistry-store.myshopify.com |
| Currency | USD |
| Markets | United States (primary, localCurrencies:false) · International (localCurrencies:true) |
| Admin token | permanent offline shpat_ from own custom app |
| Custom app | "Webbuildr 2", client ba66dfaf16713fd861fd4b70000ea92f |
| Credentials dir | ~/.config/admaker/credentials/ (mode 0600) |
| Health check | node tools/shopify-token-health.mjs → expect life OFFLINE |
CAD warning. The operator browses from Canada and is served converted prices by the
International market. A discount shown as −$334.28 is the −$236.85 USD discount
(rate ≈ 1.4114). Convert before diagnosing any pricing "discrepancy". Our own checks run from a
US-routed host and always return USD — which is what the campaign actually transacts, since the ad
set is geo-US only.
| item | value |
|---|---|
| Competitor research | Foreplay MCP (mcp__claude_ai_Foreplay__*) |
| Review host | http://15.204.83.60/ — static, read-only, mounts in /srv/www/_server/mounts.json |
| Repo | /home/ubuntu/Documents/AdMaker |
| Ledger | node tools/history.mjs record / validate |
| campaign | id | status | ||||
|---|---|---|---|---|---|---|
| **RAW \ | V81 Clean Test \ | UFO + LOOKUP + CUPID-R2 \ | save70 \ | Dark Posts** | 120249646488770611 | ACTIVE |
| RAW \ | V82 UFO Persistent-Offer \ | save70 \ | Dark Post | 120249669199670611 | PAUSED, never spent | |
| RAW \ | V80 Single Test \ | 3 Creatives \ | 70% Arm | 120249645525260611 | PAUSED | |
| RAW \ | V79 Video CBO \ | 8 Creatives | 120249625544390611 | PAUSED | ||
| RAW \ | V79 Video ABO \ | 4 Concepts x 2 Offers | 120249625270290611 | PAUSED | ||
| RAW \ | V77 ABO \ | 6 Ad Sets x $10 | 120249624812710611 | PAUSED | ||
| RAW \ | V77 Offer A/B \ | 3 Concepts x 2 Offers | 120249615068040611 | PAUSED | ||
| RAW \ | V76 DCO Test \ | 10 Concepts | 120249609686230611 | PAUSED | ||
| RAW \ | V76 Video \ | 4 Creatives | 120249608591340611 | PAUSED | ||
| RAW \ | V76 Launch \ | 6 Creatives | 120249599273780611 | PAUSED | ||
| RAW \ | Test | 120249424103750611 | PAUSED | |||
| RAW \ | Scale | 120249423872160611 | PAUSED | |||
| RAW \ | Prospecting \ | $100 Focused Test | 120249228401770611 | PAUSED | ||
| RAW \ | Prospecting \ | Main \ | 7-Creative Portfolio | 120248830225130611 | PAUSED |
120249646492400611Name: V81 | US 18-65 broad | FB+IG only | Purchase | no AN/WA/Threads
{"geo_locations": {"countries": ["US"], "location_types": ["frequently_in","home"]},
"age_min": 18, "age_max": 65,
"publisher_platforms": ["facebook","instagram"],
"facebook_positions": ["feed","video_feeds","marketplace","story","search","facebook_reels","profile_feed"],
"instagram_positions": ["stream","story","explore","reels","profile_feed","ig_search"],
"device_platforms": ["mobile","desktop"],
"targeting_automation": {"advantage_audience": 1}}
| setting | value |
|---|---|
| optimization_goal | OFFSITE_CONVERSIONS |
| billing_event | IMPRESSIONS |
| destination / conversion location | WEBSITE |
| promoted_object | {pixel_id: 622400256897443, custom_event_type: "PURCHASE"} |
| attribution | 7-day click + 1-day view |
| is_dynamic_creative | false |
| bid strategy | Highest volume (LOWEST_COST_WITHOUT_CAP), no cap |
Meta narrows this further on its own — effective_facebook_positions routinely drops
video_feeds, and effective_instagram_positions drops explore. That is Meta's choice, not a
failed write. Compare effective_* against requested and report the delta rather than retrying.
| ad | id | creative | status | spent |
|---|---|---|---|---|
| UFO control (end card) | 120249654283880611 | 1356499863310834 | ACTIVE | $220.48 |
| UFO banner (offer @0.0s) | 120249671503420611 | 1065147595893626 | ACTIVE | $63.43 |
| CUPID-R2 static save70 FINAL | 120249654289640611 | 2138899159993629 | PAUSED | $89.07 |
| LOOKUP static save70 FINAL | 120249654288290611 | 1068078835624142 | PAUSED | $19.11 |
| CUPID-R2 static save70 r2 | 120249648313090611 | 1602876511241208 | PAUSED | $0 |
| UFO video b2g1 | 120249646494080611 | 953501277773660 | PAUSED | $0 |
| UFO video save70 r4 | 120249648559340611 | 1570562491483849 | PAUSED | $0 |
| UFO video save70 | 120249648021960611 | 1095709386226097 | PAUSED | $0 |
| LOOKUP static save70 r2 | 120249648312470611 | 1389976239777840 | PAUSED | $0 |
| LOOKUP static save70 | 120249648022840611 | 949804804042637 | PAUSED | $0 |
| CUPID-R2 static save70 | 120249648023950611 | 1810337963460700 | PAUSED | $0 |
| CUPID-R2 static b2g1 | 120249647364390611 | 1783829736131871 | PAUSED | $0 |
| LOOKUP static b2g1 | 120249646495230611 | 1037709372360910 | PAUSED | $0 |
| V47-05 static b2g1 | 120249646496130611 | 1374909448090236 | PAUSED | $0 |
Deleted: 120249662229150611 — duplicate of the banner ad, removed Aug-27 21:28 PDT.
| object | id | state |
|---|---|---|
| campaign | 120249669199670611 | PAUSED, $100/day configured, never spent |
| ad set | 120249669203280611 | PAUSED, Advantage+ Audience ON, mirrors V81 targeting |
| ad | 120249669207010611 | PAUSED, creative 1065147595893626 (same banner creative) |
Built as a standalone home for the recut, then superseded by the decision to run the banner inside
V81 for a same-ad-set comparison. Retained as a spare.
Both live ads are the same 30.1s video: UFO-V34, a "leaked interview" concept. A hooded,
unidentified source in a dark room describes building a pheromone blend as a skin-chemistry test;
intercut with Venice Beach footage of women turning to look as a man passes. Ends on the product.
70% OFF + cream TODAY ONLY, **pinned from frame 0 toframe 767 (25.57s)**, then fades as the end card takes over. Offer therefore on screen for the
entire runtime.
Both ship native 4:5 (1080×1350) and 9:16 (1080×1920) masters — separately rendered, never
derived. adapt_to_placement is OPT_OUT so Meta performs no reformatting; supplying both natives is
mandatory, not optional.
Masters: brands/raw-chemistry/output/ufo-banner-2026-08-27/masters-{4x5,9x16}/
Uploaded video IDs: 2005163350167527 (4:5) · 2170230443928592 (9:16)
Verification: 30.100s, 30fps, faststart confirmed by atom order (ftyp moov free mdat),
−14.46 LUFS, and decoded audio PCM sha256 identical to the control — proving the edit is
video-overlay-only.
Primary text:
Most cologne is built to smell good for an hour and then quietly quit on you.
RAW 27™ is pheromone-infused — the formula behind 500,000+ bottles since 2016.
★★★★★ 4.8/5 · 12,400+ reviews · Free shipping · 60-day guarantee
Get 70% off — today only.
Headline: Your Cologne Quit Two Hours Ago
Description: 70% off today only. Free shipping.
CTA: SHOP_NOW · Display link: RAWCHEMISTRY.COM
Destination: https://rawchemistry.com/pages/raw-pheromone-cologne
Copy was recovered by fetching the live ad's own preview iframe and parsing its payload — not
reconstructed from documentation. Docs drift; the served ad does not.
OPT_OUT via degrees_of_freedom_spec sent alone asa JSON-encoded string: `image_touchups, text_optimizations, image_brightness_and_contrast,
image_templates, image_animation, image_uncrop, add_text_overlay, media_liquidity_animated_image,
adapt_to_placement, site_extensions, profile_card, enhance_cta, description_automation,
catalog_feed_tag, product_extensions, cv_transformation, inline_comment`
self_ai_disclosure omitted entirely — never OPT_IN, never OPT_OUT. Immutable after creation.object_story_spec — nothing reaches the page timeline.placement_videos: 4:5 as the unscoped fallback, 9:16 scoped to FB story/reels + IG story/reels.Exactly one unscoped entry is required by the API.
Traps: music is not a valid feature name and rejects the whole call. standard_enhancements
is deprecated. Validation stops at the first bad name, so the accepted 17 are expensive to
re-derive — reuse the list.
| day | dow | budget | spend | impr | reach | freq | CPM | CPC | ATC | $/ATC | IC | purch | revenue | ROAS | CAC |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Aug-27 | Thu | $100 | $134.48 | 957 | 723 | 1.32 | $141 | $3.36 | 22 | $6.11 | — | 3 | $218.90 | 1.63 | $44.83 |
| Aug-28 | Fri | $100 | $104.27 | 439 | 315 | 1.39 | $238 | $2.67 | 17 | $6.13 | — | 3 | $218.90 | 2.10 | $34.76 |
| Aug-29 | Sat | $175 | ~$151+ | 675+ | — | — | $266 | $3.06 | 13 | $11.60 | — | 1 | $99.00 | 0.66 | $150+ |
Aug-29 was still running at time of writing (18:35 PDT, 77% elapsed, $147.48 at ad level).
Campaign lifetime: $387.45 · 50 ATC @ $7.75 · 10 IC · 7 purchases · $536.80 · ROAS 1.39 · CAC $55.35.
| hr PDT | spend | impr | ATC | purch |
|---|---|---|---|---|
| 06 | $20.22 | 94 | 1 | — |
| 07 | $17.88 | 77 | 2 | — |
| 08 | $8.65 | 51 | 3 | 1 |
| 09 | $16.63 | 87 | 2 | — |
| 10 | $13.92 | 107 | 4 | 1 |
| 11 | $6.48 | 76 | 4 | 1 |
| 12 | $5.90 | 53 | 1 | — |
| 13 | $6.31 | 55 | — | — |
| 14 | $5.50 | 73 | 2 | — |
| 15 | $4.20 | 38 | — | — |
| 16 | $9.08 | 56 | 1 | — |
| 17 | $1.56 | 40 | — | — |
| 18 | $2.85 | 35 | — | — |
| 19 | $5.48 | 51 | 2 | — |
| 20 | $5.36 | 42 | — | — |
| 21 | $3.72 | 21 | — | — |
| 22 | $0.74 | 1 | — | — |
Delivery began ~06:00. All 3 purchases landed 08:00-11:59. Spend spread broadly.
| hr PDT | spend | impr | hr PDT | spend | impr | |
|---|---|---|---|---|---|---|
| 00 | $1.85 | 13 | 12 | $9.37 | 24 | |
| 01 | $1.88 | 2 | 13 | $3.51 | 22 | |
| 02 | $0.08 | 3 | 14 | $5.31 | 29 | |
| 03 | $0.06 | 2 | 15 | $6.83 | 23 | |
| 04 | $0.47 | 7 | 16 | $16.41 | 37 | |
| 05 | $2.39 | 14 | 17 | $6.63 | 40 | |
| 06 | $2.22 | 9 | 18 | $6.82 | 27 | |
| 07 | $7.77 | 15 | 19 | $7.28 | 20 | |
| 08 | $3.48 | 15 | 20 | $1.37 | 18 | |
| 09 | $0.76 | 10 | 21 | $6.13 | 33 | |
| 10 | $1.57 | 7 | 22 | $3.67 | 27 | |
| 11 | $4.90 | 16 | 23 | $3.51 | 26 |
Spend spread almost flat across 24h. Only $20.20 (19% of day) by 09:00.
Control-ad ATCs: 9 of 10 landed at or after 14:00. Biggest hour 16:00.
Why so slow in the morning: Aug-27 overdelivered to $134.48 (+34%). Meta balances across a
~weekly window, so Aug-28 was throttled early to repay it.
| hr PDT | ET | spend | CPM | LPV | ATC | purch |
|---|---|---|---|---|---|---|
| 00 | 03 | $3.56 | $237 | 2 | 1 | — |
| 01 | 04 | $1.65 | $183 | 2 | — | — |
| 02 | 05 | $1.72 | $156 | — | — | — |
| 03 | 06 | $5.43 | $319 | 2 | — | — |
| 04 | 07 | $9.96 | $255 | 1 | 1 | 1 |
| 05 | 08 | $9.62 | $196 | 2 | 1 | — |
| 06 | 09 | $21.62 | $305 | 6 | 1 | — |
| 07 | 10 | $15.04 | $301 | 4 | 2 | — |
| 08 | 11 | $11.50 | $359 | 2 | 1 | — |
| 09 | 12 | $6.45 | $195 | 3 | 1 | — |
| 10 | 13 | $8.57 | $245 | 1 | — | — |
| 11 | 14 | $3.16 | $316 | — | — | — |
| 12 | 15 | $6.61 | $264 | — | — | — |
| 13 | 16 | $2.30 | $121 | — | — | — |
| 14 | 17 | $2.70 | $159 | — | — | — |
00:00-09:59 = $86.55 → 24 LPV, 8 ATC, 1 purchase.
10:00-14:59 = $23.34 → 1 LPV, 0 ATC, 0 purchase.
The 06:00-07:00 block took 51% of the day's early budget at the highest CPMs of the day
($305/$301 vs $121-196 later). That was not irrational: those are 09:00-11:00 Eastern, and the
morning produced every conversion. Meta optimises for predicted purchasers, not cheap impressions,
and paid a premium for the hours that convert.
Caution recorded: the 13:00-16:00 stretch looked like a dead zone and was then followed by
2 more control ATCs by 16:42. Dayparting cannot be judged intraday.
| ad | status | spend | impr | CTR | $/LPV | LPV | $/ATC | ATC | purch | revenue |
|---|---|---|---|---|---|---|---|---|---|---|
| UFO control | ACTIVE | $220.48 | 934 | 7.39% | $3.80 | 58 | $8.48 | 26 | 5 | $377.85 |
| UFO banner | ACTIVE | $63.43 | 308 | 9.09% | $3.73 | 17 | $7.05 | 9 | 1 | $59.95 |
| CUPID-R2 static | PAUSED | $89.07 | 712 | 3.93% | $4.05 | 22 | $6.36 | 14 | 1 | $99.00 |
| LOOKUP static | PAUSED | $19.11 | 132 | 3.79% | $4.78 | 4 | $6.37 | 3 | 0 | — |
| ad | format | spend | impr | CPM | $/ATC |
|---|---|---|---|---|---|
| CUPID-R2 | static | $89.07 | 712 | $125 | $6.85 |
| LOOKUP | static | $19.11 | 132 | $145 | $6.37 |
| UFO | video | $25.20 | 110 | $229 | $4.20 |
Video costs ~1.8× static per impression. 84% of Aug-27's impressions came from statics, which
is why that day's blended CPM was $141 — the cheapest of the three despite the highest spend.
| order | timestamp PDT | amount | product | day |
|---|---|---|---|---|
| #164595 | Aug-27 08:18 | $59.95 | single | Thu |
| #164597 | Aug-27 10:06 | $99.00 | 3-pack | Thu |
| #164598 | Aug-27 11:05 | $59.95 | single | Thu |
| #164608 | Aug-28 15:23 | $59.95 | single | Fri |
| #164610 | Aug-28 18:22 | $99.00 | 3-pack | Fri |
| #164612 | Aug-28 22:34 | $59.95 | single | Fri |
| #164613 | Aug-29 04:52 | $99.00 | 3-pack | Sat |
| $536.80 |
10 consecutive exact reconciliations between Meta-reported revenue and paid Shopify orders.
Identify funnel orders by PRICE. Shopify reports **every one of these as `firstVisit: direct,
lastVisit: direct` with no UTM, because the funnel converts through shop.app / Shop Pay, which
strips the referrer**. Non-funnel orders on the same days ($71.00, $67.50, $36.50, $34.50, $36.75)
are other products/channels.
| FREE ads | honest-offer ads | |
|---|---|---|
| spend | $425.32 | $139.57 |
| impressions | 10,159 | 1,059 |
| CPM | $41.87 | $131.79 |
| cost/LPV | $1.49 | $4.65 |
| revenue | $73.00 | $218.90 |
| ROAS | 0.17 | 1.57 |
| revenue per LPV | $0.26 | $7.30 |
Honest offers cost 3.1× the CPM and returned 9.2× the revenue per dollar and **28× the
revenue per landing page view**.
Eleven campaigns had run (V76-V80, Prospecting, Test, Scale) on a funnel later proven broken.
Symptoms: cost per ATC $14-114, several days with zero purchases, and a Shopify attribution report
showing "Facebook/Instagram 0" in the last 16 orders — which was later shown to be **Shop Pay
stripping the referrer**, not an absence of ad-driven sales. Everything was paused to reach one
clean test.
| when | what | why |
|---|---|---|
| ~04:45 | V81 built: 3 ads (UFO video, LOOKUP static, CUPID-R2 static), CBO $100/day, save70 arm | Clean single-variable test after the funnel fixes |
| ~06:00 | Delivery begins | |
| 08:18 / 10:06 / 11:05 | Three purchases land — $59.95 / $99.00 / $59.95 | Reconciled exactly to Meta's $218.90 |
| 13:33 | Banner recut added to V81 ad set as 120249662229150611, paused | Operator: "add it to the campaign but keep it paused" |
| 19:27-19:28 | V82 campaign + ad set + ad created, all paused | Operator: "put it into its own campaign" |
| 19:49 | V82 ad set corrected: advantage_audience 0 → 1 | Operator corrected me — A+A must stay ON; "no AI flags" means creative AI |
| 21:28 | Duplicate ad 120249662229150611 deleted | Same creative existed twice after two instructions |
| 21:34 | CUPID-R2 and LOOKUP statics PAUSED | Cost-per-ATC: UFO $4.20 vs $6.85/$6.37. CUPID-R2 had taken 66% of spend on the worst CTR |
| 21:34 | Banner ad 120249671503420611 created in V81 ad set, activated 21:35 | To run banner vs control in the same ad set — one variable |
| 21:37 | Meta approves the banner ad | |
| day close | $134.48, 22 ATC @ $6.11, 3 purchases, ROAS 1.63 |
| when | what |
|---|---|
| all day | Two ads only: UFO control + UFO banner. Budget $100 |
| morning | Very slow — $20.20 by 09:00 (19% of day). Cause: repaying Aug-27's +34% overdelivery |
| 15:23 / 18:22 / 22:34 | Three purchases — $59.95 / $99.00 / $59.95 |
| — | 9 of the control's 10 ATCs landed at or after 14:00 |
| day close | $104.27, 17 ATC @ $6.13, 3 purchases, ROAS 2.10 — best day of the three |
| when | what |
|---|---|
| 02:20 | Campaign budget raised $100 → $175/day via ads MCP server, actor Brett Messinger. Not done in-session. Unconfirmed. |
| 04:52 | One purchase, $99.00 |
| 06:00-07:59 | 51% of early budget spent at the day's highest CPMs — but these hours produced the conversions |
| ~10:00 onward | Conversions stop; $23 spent 10:00-15:00 for 1 LPV |
| ~16:00-16:42 | Two more control ATCs land — the "dead afternoon" read was premature |
| 18:35 | $147.48 spent, 1 purchase, control ROAS 0.78 and falling |
| — | Operator identifies Aug-29 is a Saturday — a second variable |
| — | Operator rejects spending further to disambiguate; agreed to revert to $100 |
| what | when | reasoning at the time | retrospective |
|---|---|---|---|
| CUPID-R2 static | Aug-27 21:34 | $6.36/ATC vs UFO's $4.20; 66% of day-1 spend on the worst CTR (3.93%) | Defensible on the chosen metric. But it was buying impressions at $125 CPM and never got worse than $6.36/ATC — the control later hit $15.90 |
| LOOKUP static | Aug-27 21:34 | $6.37/ATC, worst CTR, 0 purchases on $19.11 | Had briefly shown the account's best $/LPV ($3.55) at ~$14 spend, which inverted as the sample grew — a small-sample mirage I initially reported as promising |
Duplicate banner ad 120249662229150611 | Aug-27 21:28 | Same creative in two places | Correct; my own sequencing error created it |
| b2g1 arm (4 ads) | pre-launch | Operator selected the save70 arm | Held as the week-2 arm test |
| r2/r4/superseded (6 ads) | pre-launch | Earlier renders replaced | — |
| 11 older campaigns | Aug-26/27 | Reduce to one clean test | — |
| V82 campaign | never activated | Banner ran inside V81 instead for a same-ad-set comparison | Correct — a separate campaign would have been a dirtier test and doubled spend |
The consequential one. Pausing both statics left the campaign with two cuts of one video.
Blended CPM went $141 → $238 → $266 and impressions fell 957 → 439 → 269. Statics were the
cheap-reach layer. This did not, however, explain the Aug-29 spend pattern — see Part 8.
| # | problem | detail | fix | verified |
|---|---|---|---|---|
| 1 | Checkout hid the offer | Shopify mobile renders the order summary collapsed — a cold buyer saw only "Order summary" and a number. No product, no quantity, no discount | Anchor prices + automatic discounts so the saving appears on the payment screen | Rendered checkout in a real mobile browser |
| 2 | Anchor pricing | — | 3-pack 67395347546416 $335.85 → $99.00 (−$236.85); single 67395347513648 $99.00 → $59.95 (−$39.05) | API readback + live checkout |
| 3 | Quantity overcharge | Discounts were fixed-amount with appliesOnEachItem:false — discount subtracted once per order while the anchor multiplied per unit. 3-pack ×2 charged $434.85 instead of $198.00 | Set appliesOnEachItem: true on both | 6 cart shapes re-tested: 3-pack ×1/×2/×3 = $99.00/$198.00/$297.00; single ×1/×2 = $59.95/$119.90; mixed = $158.95. No customer was ever affected — all funnel orders qty 1, no qty selector on the page |
| 4 | Internal name leaking to buyers | Checkout displayed RAW REVEAL V110 - 3 BOTTLES + FREE ROLL-ON (-$236.85) — Shopify prints the discount title verbatim | Renamed to 70% Off Today - 3 Bottles + Free Roll-On and Today's Price - Single Bottle; tools/raw-offer-pricing.mjs corrected so a revert can't reintroduce them | Order summary expanded in a real browser: v110/RAW Reveal absent |
| 5 | Shipping label contradiction | Drawer promised FREE EXPRESS; checkout said Economy | Delivery profile 132870603056, holding only the two funnel variants, rate named FREE Express Shipping (2–4 days) | node tools/raw-shipping-label.mjs verify |
| 6 | Stale offer badges | UP TO 70% OFF contradicted the flat 70% claim | Removed | 0 remaining; 8 CTAs read GET 70% OFF TODAY |
| 7 | Pixel fired too late | PageView only after 30s or interaction | sendBeacon PageView at a fixed 2,500ms, eid dedup key, _fbp/_fbc set incl. fbclid capture. Original 30s runtime loader left intact | Real headless browser: one PageView at 2.73s, no interaction, zero JS errors |
| 8 | Page speed regression | A 3-second tracking timer shipped and crashed live PSI to 71 / TBT 1,540ms | Reverted within minutes | PSI mobile 99/100/100/100, TBT 0ms; desktop 100/100/100/100; Core Web Vitals field data PASSED (LCP 2s, INP 162ms, CLS 0.02) |
Discount node IDs: 3-pack 1616747659568 · single 1616747692336. Both ACTIVE, no end date.
24 code discounts exist and do NOT stack on these automatics — verified.
Funnel state now: click → LP (PSI 99, pixel at 2.5s) → drawer (offer visible) → checkout
(discount visible, correct name, free express labelled) → Shop Pay.
Aug-29 broke a two-day pattern. $/ATC $6.11 → $6.13 → $11.60. ROAS 1.63 → 2.10 → 0.66.
Two variables changed simultaneously:
Purchase count proves nothing. At the Aug-27/28 rate (2.33/day), P(observing ≤1 purchase on a
given day) = 32%. One-versus-three is unremarkable.
Cost-per-ATC is the real signal — 13 events, not 1 — and it roughly doubled.
A single ad DOES absorb budget linearly. Hour-matched, the control ad only, hours 00:00-10:59
on both days:
| Aug-28 ($100) | Aug-29 ($175) | ratio | |
|---|---|---|---|
| spend | $8.98 | $85.49 | 9.5× |
| impressions | 32 | 310 | 9.7× |
| CPM | $281 | $276 | 0.98× — flat |
| ATC | 0 | 6 |
So budget does not inherently inflate cost. That kills the simplest explanation.
No weekend baseline exists. The account's only prior Saturday is Aug-08: $5.43 spend, 1 ATC.
Everything material changed since — creative, offer, checkout fix, pixel. Pre-Aug-27 days ran
different creative on a broken funnel ($/ATC $14-114). Nothing to compare against.
also halts remaining Saturday spend. Saves ~$40 tonight + ~$85 Sunday ≈ $125.
Rationale for not spending to disambiguate: the same answer is available later for the same money,
on a weekday, with better creative. Buying it now on a ROAS-0.66 day is paying a premium for a
tidier chart.
| control (end card) | banner (offer @ 0.0s) | |
|---|---|---|
| spend | $220.48 | $63.43 |
| impressions | 934 | 308 |
| CTR | 7.39% | 9.09% |
| $/LPV | $3.80 | $3.73 |
| $/ATC | $8.48 | $7.05 |
| ATC | 26 | 9 |
| initiated checkout | 7 | 1 |
| purchases | 5 | 1 |
| revenue | $377.85 | $59.95 |
Both cleared the 10-ATC gate cumulatively. The banner leads every cost metric; the control leads
purchases — but has had 3.5× the delivery, so the purchase gap partly reflects budget share.
Day by day the story flipped repeatedly:
| Aug-28 $/ATC | Aug-29 $/ATC | |
|---|---|---|
| control | $6.36 | $15.90 |
| banner | $6.98 | $6.77 |
Not resolvable while Aug-29 is confounded. Carry into the Monday read.
What the competitor evidence predicted: short ads (≤35s) place the offer at a median 0.0s,
5/5 within five seconds; GODA's longest-running live ad pins its offer and a Buy 2, Get 1 FREE
badge from frame 0 and never removes them. That predicted the banner should win. **Our own money has
not confirmed it.**
Four brands, 250-ad newest-first samples, all creatives opened and measured.
| brand | active | indexed | VIDEO | IMAGE | DCO | kill speed |
|---|---|---|---|---|---|---|
| Hypnosis by Cupids | 452 | 3,244 | 91% | 9% | 0% | 9.8h / 31h |
| Goda Perfume | 387 | 8,998 | 8% | 30% | 62% | mixed |
| IM8 | 232 | 14,494 | 10% | 90% | ~0% | slow |
| SALT & STONE | 825 | 12,440 | 14% | 23% | 62% | barely kills — 93% still live |
headline "Secret to Attention 👉" and are ten different files at **14.88, 38.19, 39.27, 39.83,
40.75, 46.53, 46.95, 60.67, 74.88, 91.9s. Live range spans 7.99s–93.18s**.
3/5/7-day tail. Survivors from the same day run 94h+.
"testing pheromone cologne on my sisters hot friend", club footage, a screenshot of a review
captioned "The 500,000+ positive reviews weren't LYING".
wordmark, LAST CHANCE, 50% OFF, two clipart alarm clocks. No product, no model. Attached to
~600 words of first-person advertorial signed "Michelle D."
crepey skin, smoothing over a day-1→60 arc. No model, no shoot, no likeness rights.
Oil / PLEASE HELP US EMPTY OUR WAREHOUSE" + "Buy 2, Get 1 FREE"*, both pinned from 0.0s, over a
spoken apology: "I told you that was the best price you'd ever get — and then we overproduced."
Ours asserts 70% OFF TODAY ONLY with nothing behind it.
"Do Not Try This IF you enjoy being the only one making an effort" — plus hard price anchoring
($78 → $14/bottle) and review badges.
scarcity ("Mini set. Big waitlist." / "SOLD OUT 3X").
| brand | model | pages |
|---|---|---|
| Cupids | fake editorial | Gents Secrets (categorised Magazine), Hypnosis by Cupids (categorised Musician/band, no website, 452 active vs main page's 199) |
| GODA | invented personas | Emily The Fragrance Girl, Steve The Perfumer, Over 40 & Fabulous |
| IM8 | real authorities | Dr. James DiNicolantonio, Tim Gray, David Beckham (blue-verified), New York Post, Athleats Nutrition — plus 4 legitimate own-brand pages |
| Salt & Stone | single page | — |
Satellite pages demonstrably outrun motherships. All three flavours are available options; the
choice is the operator's.
Foreplay's display_format: DCO means **any multi-asset creative, including plain placement
customization**. Proven symmetrically:
720×1280 and 720×900 at identical 30.164042s with identical audio sha256.
There is no DCO gap. We have shipped the mechanism since V76. Do not reopen without new
primary evidence.
Boards published:
http://15.204.83.60/raw-chemistry/competitor-creatives/ · /raw-chemistry/offer-timing/
Full text in LEARNINGS.md. Complete list, grouped.
warning, not a win — a proposed rule to kill ads above $120 CPM would have killed every
profitable ad and protected every unprofitable one.
business from CAC $20 against $30. But breakeven CAC is still unknown without COGS.
5.3%" comparison used a double-counted denominator — IC fired twice (drawer + Shopify).
Real Aug-24 funnel: 129 LPV → 9 buy-button clicks → 1 purchase. Direction holds, magnitude was
inflated.
hidden discounts — all fixable in an afternoon and worth more than a new creative.
interacting; parsing ev= from a query string when Meta posts URL-encoded bodies; comparing
against a non-deferred page.
profiles. No versions, run IDs or codenames.
"video beats statics" (wrong on the metric that matters: statics bought LPVs at $1.53 vs $2.91
over 90 days) and then the UFO video beat both statics in V81.
Being tested; our own money has not confirmed it.
banner's 29.6% CTR on 27 impressions; a "dead afternoon" that revived; a "$16.49/ATC" alarm that
was a partial-day artifact.
rate — impressions land before conversions.
expires_in, never shpat_.from it.
is a multi-day system.
updated_fields echoes the request.direct for everything.Creative mutates the ad — all 17 OPT_OUT.
degrees_of_freedom_spec is omitted.WhatsApp status, Threads, Messenger. Pin FB+IG explicitly.
advantage_audience: 1 demotes age limits to suggestions.self_ai_disclosure is immutable after creation.age_min: 25 was lifted from adoc describing a UI dropdown limitation and applied as strategy.
end = runtime foranything that reads persistent. One badge claimed 0.0→31.209s; pixels show it gone by 6.9s.
Recorded because the pattern repeats and recognising it early is worth more than any single finding.
| # | mistake | how it was caught | rule adopted |
|---|---|---|---|
| 1 | Claimed the LP had no tracking | Repo had already documented and corrected this once | Primary source before assertion |
| 2 | "Video beats statics 2:1" | Inherited from a handoff; 90-day data inverted it on cost/LPV | Never inherit an unmeasured claim |
| 3 | Picked the wrong static set from filenames | Operator: "that's the old run" | Folder names lie; sort by mtime |
| 4 | age_min: 25 from a UI-limitation doc | Operator: "18-65 is fine why did you do 25" | Read the surrounding sentence |
| 5 | AI enhancements left defaulted ON | Operator asked "no creative enhancements?" | Set every field explicitly |
| 6 | Swept advantage_audience to 0 | Operator corrected — A+A must stay on | "No AI flags" = creative AI |
| 7 | Proposed a CPM>$120 kill rule | Operator: "we aren't saying free anymore" | CPM describes who, not how well |
| 8 | Shipped a 3s tracking timer → PSI 71 | Live PSI re-measure | Dev-theme pass is not a live gate |
| 9 | Prevalence-as-proof on DCO — twice | Operator asked "is it genuinely more effective?" | Presence ≠ performance |
| 10 | Said shpat_ = permanent, "revoked not expired" | The exchange returned expires_in: 86353 | Trust expires_in, not the prefix |
| 11 | Blamed sandbox for exit 144 | It was pkill -f matching its own shell | Never pkill -f a pattern in your own argv |
| 12 | "The CLI hangs on auth" | app list doesn't exist in CLI 4.6.1 — subcommand error misread | Verify the command exists before diagnosing |
| 13 | Blamed campaign narrowing for front-loaded spend | Operator: "yesterday had no statics either" | Verify the cause actually changed |
| 14 | Blamed multi-day pacing for the same thing | Activity log showed the budget had been raised | Check the change log first |
| 15 | "CPM rises with budget" | Hour-matched data showed CPM flat at 9.5× spend | Never compare partial vs full day |
| 16 | Called the afternoon dead | Two ATCs landed an hour later | Dayparts can't be judged intraday |
| 17 | Wrote a decision rule ignoring the weekday | Operator: "it's also Saturday" | Enumerate variables before committing a rule |
| 18 | Proposed spending ~$85 to disambiguate | Operator: "so just waste money lol" | The same answer is often available later, cheaper |
**The dominant pattern: reaching for a plausible mechanism instead of checking whether the
suspected variable actually changed.** Items 13, 14, 15 and 17 are all the same error.
tools/, all runnable)| tool | what it does |
|---|---|
shopify-oauth-paste.mjs | PKCE paste-back OAuth for a headless host. Defaults to our own app; --cli falls back. Writes a .meta.json sidecar with real expires_in |
shopify-token-health.mjs | Structure + liveness + granted scopes; reports hours remaining, warns <6h. life OFFLINE = permanent |
shopify-token-receive.mjs | One-shot paste form for an Admin API token — random path, verifies before storing, exits after one success |
shopify-admin.mjs | Generic Admin GraphQL runner |
raw-offer-pricing.mjs | snapshot / apply / revert anchor prices + automatic discounts. Titles are customer-facing |
raw-shipping-label.mjs | Creates/verifies the surgical delivery profile |
raw-pixel-verify.mjs | Verifies the Meta event sequence through the funnel |
raw-funnel-walk.mjs · funnel-walk-audit.mjs | Full instrumented walk at iPhone viewport |
audit-page-tracking.mjs | Does the page actually fire tracking? Documents the 3 false-negative traps |
raw-trust-signal-audit.mjs | Where does a given string actually appear on the live page? |
shopify-theme-file.mjs | Read theme files into a local directory |
history.mjs | The append-only ledger — record / validate |
brands/raw-chemistry/scripts/analyze_competitor_offer_timing.py | Offer-timing analysis over Gemini breakdowns |
brands/raw-chemistry/scripts/render-ufo-banner-2026-08-27.sh | Renders a banner master through the house chain |
| skill | covers |
|---|---|
build-meta-ad-objects | Every campaign/ad set/ad/creative build. The Advantage+ split, broad targeting, placement lock, dark posts, self_ai_disclosure, plus scripts/verify-ad-objects.mjs which asserts the whole config from readback JSON and exits non-zero on failure |
connect-shopify-admin-api | Permanent tokens on a headless host: PKCE paste-back, why the CLI client gives 24h tokens, the empty redirect_urls trap, fixing app config via CLI deploy, plus references/traps.md indexed by error string |
At $72.97 AOV:
| contribution margin | breakeven CAC |
|---|---|
| 70% | $51.08 |
| 60% | $43.78 |
| 50% | $36.48 |
| 40% | $29.19 |
Measured CAC has run $34.76 → $150+. At 50% margin the account is roughly breakeven; at 40%
it is losing money; at 70% it has room. **This single number converts every scale decision from
opinion into arithmetic.**
launch inventory. Must be genuinely true; it is checkable by customers.
resolves the banner test.
ADS-PLAN.md Phase 1): UFO at 12s and 60s alongside 30s; revive a static.Target 5-8 distinct live ads before any further budget increase.
pain-first sharpening of the next static batch.
advantage_audience: 1). Advantage+ Creative OFF (17 × OPT_OUT).adapt_to_placement: OPT_OUT and native-master authoring.self_ai_disclosure omitted entirely, forever.node tools/history.mjs record --workstream ads.
node tools/shopify-token-health.mjs # expect: life OFFLINE
node tools/raw-shipping-label.mjs verify # delivery profile 132870603056
node tools/history.mjs validate # ledger integrity
node ~/.codex/skills/build-meta-ad-objects/scripts/verify-ad-objects.mjs < readback.json
node tools/shopify-admin.mjs '{ shop { name currencyCode } }'
Published copy: http://15.204.83.60/raw-chemistry/handoff/
Source of truth: this file, in the repo.