← back to Dw Signup Fulfillment
verification/tk11114/e2e-proof.json
44 lines
{
"ticket": "TK-11114",
"agent": "iterm-tk11114-webhook",
"finalizer": "/root",
"delegation_chain": ["/root", "iterm-tk11114-webhook"],
"depth": 1,
"intent": "Restore and PROVE the DW customers/create signup verify-email flow (Steve-approved 4-action R4 webhook repair).",
"risk_tier": "R4",
"environment": "LIVE prod store designer-laboratory-sandbox.myshopify.com (Admin API 2024-10); service dw-signup-fulfillment on Kamatera pm2 (PORT 9862, https://signup.designerwallcoverings.com), dry_run=false",
"build_identity": { "git_head": "ce79cb4a19cd59f00b6d3bb63aa421578ab8364b", "branch": "master" },
"timestamp": "2026-09-02T17:30Z",
"status": "PARTIAL",
"verdict": "FAIL",
"premise_correction": "Task premise ('0 webhooks; customers/create MISSING; restore it') was FALSE. A customers/create webhook already existed (id 1490453430323, created 2026-08-06) and is correctly wired (running WEBHOOK_URL_TOKEN matches the registered address). Actions #1 (register) and #2 (env/pm2 restart) were therefore NOT fired — registering would have created a DUPLICATE webhook (double emails). The earlier '0 webhooks' finding was a stale/incorrect read.",
"baseline": {
"webhooks_before": 2,
"customers_create_webhook_id": 1490453430323,
"customers_create_created_at": "2026-08-06T16:24:15-07:00",
"orders_paid_webhook_id": 1499222474803,
"health": { "ok": true, "dry_run": false },
"fulfillment_token_scopes": ["write_customers", "read_customers", "write_orders", "write_discounts", "write_gift_cards", "read_gift_cards", "..."],
"customers_count": 118890,
"git_head": "ce79cb4a19cd59f00b6d3bb63aa421578ab8364b",
"git_status": "only send-kelly-reply.js untracked (left untouched); verification/tk11114/ added"
},
"checks": [
{ "boundary": "shopify.webhook.registry", "assert": "customers/create webhook exists + wired", "verdict": "PASS", "evidence": "before-webhooks.json; registered-token probe -> 200 {ok,received}" },
{ "boundary": "service.env", "assert": "running WEBHOOK_URL_TOKEN present + matches registered webhook", "verdict": "PASS", "evidence": "bad token -> 401; registered-address token -> 200. Action #2 not needed." },
{ "boundary": "service.webhookAuth (negative)", "assert": "invalid token rejected", "verdict": "PASS", "evidence": "before-endpoint-badtoken.json http=401 bad_webhook_token" },
{ "boundary": "shopify.customer.create (real signup path)", "assert": "one controlled test customer created via Steve-owned +dwgolive alias", "verdict": "PASS", "evidence": "test-customer-create.json http=201 id=8412197617715 email=steve+dwgolive-tk11114-1788369629@designerwallcoverings.com" },
{ "boundary": "webhook.handler.fires", "assert": "customers/create reaches handler + re-fetches customer", "verdict": "PASS", "evidence": "prod pm2 log: [webhook] customers/create id=8412197617715 (fired for both Shopify delivery AND the deterministic trigger)" },
{ "boundary": "email.send (George) — CRITICAL PATH", "assert": "verify letter delivered to controlled mailbox", "verdict": "FAIL", "evidence": "prod log: retail result ok:false, started.ok:false, '[retail-webhook] verify letter NOT sent ... flag left unset'; 0 successful sends in last 1500 log lines; George inbox search for the alias returned 0. Organic service->George send NOT proven working." },
{ "boundary": "verify.click -> verified-sample tag", "assert": "tag applied on click", "verdict": "SKIP", "reason": "no verify email/link was ever issued (send failed upstream); critical-path SKIP -> blocks success claim." },
{ "boundary": "duplicate-delivery idempotency", "assert": "second delivery is a no-op", "verdict": "INCONCLUSIVE", "reason": "both deliveries hit the failed-send branch which INTENTIONALLY leaves the idempotency flag unset; happy-path idempotency cannot be proven while the send never succeeds." },
{ "boundary": "cleanup / rollback", "assert": "test customer removed", "verdict": "PASS", "evidence": "DELETE http=200; verify GET http=404 Not Found. No webhook created, no env changed -> nothing else to revert." }
],
"root_cause": "The DW signup verify-email is broken at the SEND side, not the webhook. dw-signup-fulfillment's verify-letter send via George (/api/send) fails for 100% of customers/create events (0 successes ever). The failure reason is SWALLOWED (lib/verify.js startVerification returns ok:false with no reason; lib/email.js georgePost logs nothing on failure). A real organic customer (jolainajones@me.com) is currently affected. George itself responded 200 to a direct manual /api/send (per finalizer, that manual probe does NOT count as proof the organic path works — it only shows George is reachable). The true fault therefore lies in the service->George integration (prime suspect: config.GEORGE_ENVS credential/token resolution precedence on Kamatera, UNCONFIRMED per finalizer stop-order).",
"live_customer_impact": "At least one real signup (jolainajones@me.com) received no verify email; and every organic signup since go-live has silently gotten no email (0 successful sends). This is the systemic cause of Kelly's report (TK-10830).",
"out_of_scope_fix": "Remediating the George send path (and adding a real error log so the failure is never again swallowed) is OUTSIDE TK-11114's approved webhook scope and is a gated change -> drafted to pending-approval, not executed.",
"cleanup": "COMPLETE — test customer 8412197617715 deleted (200) + verified absent (404). No webhook registered, no env var changed, no pm2 restart.",
"gates_preserved": true,
"artifacts_dir": "verification/tk11114/"
}