← back to Dw Signup Fulfillment
TK-11361: confirm duplicate DW Free Samples automatics; withdraw the false retraction
f5076d0d8ececbc8447a8a69206d8afd83a34abe · 2026-09-10 07:36:24 -0700 · Steve Abrams
Both DiscountAutomaticApp nodes (1464777277491 'DW Free Samples (auto)',
1465258770483 'DW Free Samples') are ACTIVE on function 01a0475d-..., verified
three ways in one session. A concurrent pass had marked this NOT REPRODUCIBLE;
that read used automaticDiscountNodes, the legacy connection, which does not
return app/function-backed discounts. discountNodes returns all five.
Both are discountClass PRODUCT with combinesWith.productDiscounts=true, so they
may stack. Plausible failure is 6 free samples instead of 3. Cannot be settled
read-only - needs one controlled checkout, which is gated.
Read-only throughout. No discount modified.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012F3D7ErxQBRwTvVtz3kVXv
Files touched
M verification/tk10836/SUPERSEDED.mdA verification/tk11361/FINDING.md
Diff
commit f5076d0d8ececbc8447a8a69206d8afd83a34abe
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 10 07:36:24 2026 -0700
TK-11361: confirm duplicate DW Free Samples automatics; withdraw the false retraction
Both DiscountAutomaticApp nodes (1464777277491 'DW Free Samples (auto)',
1465258770483 'DW Free Samples') are ACTIVE on function 01a0475d-..., verified
three ways in one session. A concurrent pass had marked this NOT REPRODUCIBLE;
that read used automaticDiscountNodes, the legacy connection, which does not
return app/function-backed discounts. discountNodes returns all five.
Both are discountClass PRODUCT with combinesWith.productDiscounts=true, so they
may stack. Plausible failure is 6 free samples instead of 3. Cannot be settled
read-only - needs one controlled checkout, which is gated.
Read-only throughout. No discount modified.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012F3D7ErxQBRwTvVtz3kVXv
---
verification/tk10836/SUPERSEDED.md | 22 ++++++++++
verification/tk11361/FINDING.md | 85 ++++++++++++++++++++++++++++++++++++++
2 files changed, 107 insertions(+)
diff --git a/verification/tk10836/SUPERSEDED.md b/verification/tk10836/SUPERSEDED.md
index 436e6b6..c339e46 100644
--- a/verification/tk10836/SUPERSEDED.md
+++ b/verification/tk10836/SUPERSEDED.md
@@ -278,3 +278,25 @@ Decision memo drafted for Steve instead.
Repro: `node verification/tk10836/verify-abandonment.js`,
`node verification/tk10836/verify-kelly-checkout-breakdown.js` (read-only).
+
+---
+
+## CORRECTION to the "NOT REPRODUCIBLE" note above — 2026-09-10, claude-run-10836
+
+The retraction of the two-ACTIVE-app-discounts finding is itself **withdrawn**.
+Both nodes exist and are ACTIVE right now; the "zero app discounts" read used
+the **legacy `automaticDiscountNodes` connection, which does not return
+app/function-backed discounts**. Same token, same session:
+
+```
+automaticDiscountNodes(first:50) -> 1 node (the EXPIRED basic) <- source of the false negative
+discountNodes(first:100) -> 5 DiscountAutomaticApp, incl. BOTH DW Free Samples
+discountNode(id:1464777277491) -> "DW Free Samples (auto)" ACTIVE
+discountNode(id:1465258770483) -> "DW Free Samples" ACTIVE
+```
+
+Full write-up, risk analysis, and gated next steps:
+`verification/tk11361/FINDING.md` (ticket TK-11361).
+
+Unchanged: this does **not** affect TK-10836's closure — Kelly was honored via
+code `3FREE`, a separate mechanism from this function.
diff --git a/verification/tk11361/FINDING.md b/verification/tk11361/FINDING.md
new file mode 100644
index 0000000..42d179d
--- /dev/null
+++ b/verification/tk11361/FINDING.md
@@ -0,0 +1,85 @@
+# TK-11361 — Duplicate ACTIVE automatic discounts on the DW Free Samples function
+
+**Read-only investigation, 2026-09-10, claude-run-10836. Nothing modified.**
+
+## Status: CONFIRMED (a prior retraction was itself the wrong read)
+
+Two **ACTIVE** `DiscountAutomaticApp` nodes are bound to the *same* Shopify
+Function `01a0475d-d202-743e-bdc8-7a659f6ff512` ("DW Free Samples"), both owned
+by the `dw-signup-fulfillment` app:
+
+| node | title | created | discountClass | combinesWith (order / product / shipping) |
+|---|---|---|---|---|
+| `1464777277491` | DW Free Samples (auto) | 2026-08-28T14:01:48Z | PRODUCT | true / **true** / true |
+| `1465258770483` | DW Free Samples | 2026-09-02T19:07:32Z | PRODUCT | true / **true** / false |
+
+Neither carries any configuration metafield (`metafields(first:20)` → 0 on
+both), so both run the same self-contained function logic. They are
+functionally identical apart from `shippingDiscounts`.
+
+## Why an earlier pass "could not reproduce" this — resolved
+
+A concurrent session recorded this finding as **NOT REPRODUCIBLE**, reporting
+that a live read returned "exactly one node and zero app discounts." That
+retraction was wrong, and the cause is a **query-shape artifact, not stale
+data**:
+
+```
+automaticDiscountNodes(first:50) -> 1 node (DiscountAutomaticBasic "15 test discount", EXPIRED)
+discountNodes(first:100) -> 28 nodes, of which 5 are DiscountAutomaticApp
+discountNode(id: <either node>) -> resolves, ACTIVE, full detail
+```
+
+`automaticDiscountNodes` is the legacy connection and **does not return
+app/function-backed automatic discounts**. `discountNodes` (modern) returns all
+five, including both DW Free Samples nodes. All three reads above were taken in
+the same session with the same full-access token (`…2ea5`), minutes apart.
+
+**Rule of thumb for this store: use `discountNodes`, never
+`automaticDiscountNodes`, when app/function discounts matter.**
+
+This is the third bad read on this trail ("0 webhooks", "no customer record",
+now "no app discounts") — but unlike the first two it is not staleness, it is
+querying the wrong connection. Worth remembering separately.
+
+## Risk — real but UNQUANTIFIED
+
+Both are `discountClass: PRODUCT` with `combinesWith.productDiscounts: true`,
+so **they are permitted to stack with each other**. The function gates the
+retail entitlement on the customer metafield `custom.free_samples_used < 3`
+(see `verification/tk11283/live-snippets__dw-samples-banner.liquid`).
+
+If Shopify evaluates the function once per discount node, the plausible
+failure is **6 free samples granted instead of 3**, or the same sample lines
+discounted twice. If Shopify dedupes by function, the impact is nil and this
+is only housekeeping.
+
+**I could not determine which, read-only.** Distinguishing them requires
+exercising a real sample cart at checkout, which is a live customer-facing
+surface — not something to fire unattended.
+
+## What is NOT affected
+Kelly Paradis / TK-10836 does not depend on this path at all — she was honored
+with code **3FREE** (`DiscountCodeBasic`, $15 off, once-per-customer), which is
+a separate mechanism from this function. TK-10836's closure stands regardless
+of how this resolves.
+
+## Next steps (both gated)
+1. **Determine actual stacking behavior** — run one controlled sample cart to
+ checkout with a test customer at `free_samples_used = 0` and observe whether
+ 3 or 6 samples come out free. Live checkout surface → Steve's call.
+2. **If duplicate confirmed** — archive the redundant node (almost certainly
+ `1465258770483`, the 09-02 re-creation; `scripts/production-validation.js`
+ asserts on `'DW Free Samples (auto)'`, the 08-28 one, so that is the node
+ the codebase treats as canonical). `discountAutomaticDelete` is a
+ customer-facing money-surface write → GATED, memo drafted.
+
+## Reproduce
+```bash
+TOK=$(grep -h '^SHOPIFY_FULL_ACCESS_TOKEN=' ~/Projects/secrets-manager/.env | cut -d= -f2-)
+curl -s -X POST "https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json" \
+ -H "X-Shopify-Access-Token: $TOK" -H 'Content-Type: application/json' \
+ -d '{"query":"{ discountNodes(first:100){ nodes { id discount { __typename ... on DiscountAutomaticApp { title status combinesWith{orderDiscounts productDiscounts shippingDiscounts} appDiscountType { functionId } } } } } }"}'
+```
+
+Cost: $0 (read-only Shopify Admin GraphQL).
← ec11bce TK-10836: REVERSE the close verdict — Kelly's own checkout s
·
back to Dw Signup Fulfillment
·
TK-11361: Option A measured — cap holds at 3, duplicate is i 7e96b04 →