[object Object]

← back to Gmc Titlefix

TK-11448: prove vendor absence 3 ways, build archive plan (33) + dry-run-default archive executor

df158908aaa4b77fa7e0b7b31a3042432edc458b · 2026-09-11 11:57:45 -0700 · Steve

Steve: 'if not on mfr website. archive it'. Absence is PROVEN, not guessed —
the first probe used two hand-guessed URLs against a URL shape the vendor does
not use, and 404'd for the wrong reason.

Three independent tests, any single LIVE signal removes a product, UNKNOWN is
never archived: (1) absent from the vendor's own sitemap, (2) every plausible
product URL 404s on a live fetch, (3) no article asset on the vendor CDN.
The sitemap matcher ships a positive control — the 11 products known live at
the vendor must come back FOUND, and did, 11/11.

Two corrections the checks caught before anything fired: 4 of 5 sitemap
'FOUND' results were false matches on generic words (Garden, Structure,
Sample, Ribbon) and are absent; and 2 products previously proposed for a
FIX (Sandberg Oscar grey, Kimono green) are themselves gone from the vendor,
so they move to the archive set.

Result: 33 archive (30 Rebel Walls + 3 Sandberg), 17 fix, 1 live-but-unsourced.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JwXCqw4PdXfTY729wX8BFw

Files touched

Diff

commit df158908aaa4b77fa7e0b7b31a3042432edc458b
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Sep 11 11:57:45 2026 -0700

    TK-11448: prove vendor absence 3 ways, build archive plan (33) + dry-run-default archive executor
    
    Steve: 'if not on mfr website. archive it'. Absence is PROVEN, not guessed —
    the first probe used two hand-guessed URLs against a URL shape the vendor does
    not use, and 404'd for the wrong reason.
    
    Three independent tests, any single LIVE signal removes a product, UNKNOWN is
    never archived: (1) absent from the vendor's own sitemap, (2) every plausible
    product URL 404s on a live fetch, (3) no article asset on the vendor CDN.
    The sitemap matcher ships a positive control — the 11 products known live at
    the vendor must come back FOUND, and did, 11/11.
    
    Two corrections the checks caught before anything fired: 4 of 5 sitemap
    'FOUND' results were false matches on generic words (Garden, Structure,
    Sample, Ribbon) and are absent; and 2 products previously proposed for a
    FIX (Sandberg Oscar grey, Kimono green) are themselves gone from the vendor,
    so they move to the archive set.
    
    Result: 33 archive (30 Rebel Walls + 3 Sandberg), 17 fix, 1 live-but-unsourced.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01JwXCqw4PdXfTY729wX8BFw
---
 data/tk11448-archive-plan.json      | 348 ++++++++++++++++++++++++++
 data/tk11448-sandberg-presence.json | 190 +++++++++++++++
 data/tk11448-vendor-confirm.json    | 473 ++++++++++++++++++++++++++++++++++++
 data/tk11448-vendor-presence.json   | 306 +++++++++++++++++++++++
 tk11448-apply-archive.mjs           |  34 +++
 tk11448-archive-plan.mjs            |  48 ++++
 tk11448-sandberg-presence.mjs       |  42 ++++
 tk11448-vendor-confirm.mjs          |  42 ++++
 tk11448-vendor-presence.mjs         |  61 +++++
 9 files changed, 1544 insertions(+)

diff --git a/data/tk11448-archive-plan.json b/data/tk11448-archive-plan.json
new file mode 100644
index 0000000..a87ec96
--- /dev/null
+++ b/data/tk11448-archive-plan.json
@@ -0,0 +1,348 @@
+{
+  "ticket": "TK-11448",
+  "built_at": "2026-09-11T18:57:02.396Z",
+  "rule": "Steve 2026-09-11: if not on mfr website, archive it",
+  "method": "3 independent absence tests; any single LIVE signal removes the product; UNKNOWN never archived",
+  "population": 33,
+  "tally": {
+    "ARCHIVE": 33
+  },
+  "by_vendor": {
+    "Rebel Walls": 30,
+    "Sandberg": 3
+  },
+  "gated": true,
+  "fired": false,
+  "rows": [
+    {
+      "handle": "dwrw-75513",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50201",
+      "title": "Befoul",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75515",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50203",
+      "title": "Oops!",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75518",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50206",
+      "title": "Björnkram",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75520",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50402",
+      "title": "Concrete Jungle",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75522",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50404",
+      "title": "No sleep till Brooklyn",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75524",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50502",
+      "title": "Geometric Boundaries",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75525",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50503",
+      "title": "Isometric View",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75527",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50505",
+      "title": "Futuristic Flowers",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75528",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50506",
+      "title": "Tartan",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75530",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50601",
+      "title": "Colorbomb",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75531",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50602",
+      "title": "Sam F",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75533",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50604",
+      "title": "Tigermarble",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75534",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50701",
+      "title": "Tangram Puzzle",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75535",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50702",
+      "title": "Hyper Graphic",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75537",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50704",
+      "title": "Rusty X-Ray",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75551",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50904",
+      "title": "Dragonfruit",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75552",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R50905",
+      "title": "Garden",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75558",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R51003",
+      "title": "Natural Roof",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75562",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R51007",
+      "title": "Stairs",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75563",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R51008",
+      "title": "Structure",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75564",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R51101",
+      "title": "Winter Silence",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75565",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R51102",
+      "title": "Silent Lake",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75567",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R51201",
+      "title": "Hostal las Luces, black",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75568",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R51202",
+      "title": "Hostal las Luces, green",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75575",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "R95",
+      "title": "Sample",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75663",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "RS11061",
+      "title": "Letterpress, metal",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75777",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "RS12262",
+      "title": "Rubber Stamp",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75792",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "RS12353",
+      "title": "Ribbon, black&white",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75803",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "RS12431",
+      "title": "Roadways",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwrw-75804",
+      "vendor": "Rebel Walls",
+      "mfr_sku": "RS12432",
+      "title": "Roadways, black&white",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "ABSENT",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwss-71022",
+      "vendor": "Sandberg",
+      "mfr_sku": null,
+      "title": "Oscar grey Wallcovering",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "n/a (no article CDN for Sandberg)",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwss-71076",
+      "vendor": "Sandberg",
+      "mfr_sku": null,
+      "title": "Kimono green Wallcovering",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "n/a (no article CDN for Sandberg)",
+      "verdict": "ARCHIVE"
+    },
+    {
+      "handle": "dwss-72355",
+      "vendor": "Sandberg",
+      "mfr_sku": null,
+      "title": "Texture1 Wallcovering",
+      "test1_sitemap": "ABSENT",
+      "test2_url_probe": "404",
+      "test3_cdn_article": "n/a (no article CDN for Sandberg)",
+      "verdict": "ARCHIVE"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/data/tk11448-sandberg-presence.json b/data/tk11448-sandberg-presence.json
new file mode 100644
index 0000000..7bdbbe3
--- /dev/null
+++ b/data/tk11448-sandberg-presence.json
@@ -0,0 +1,190 @@
+{
+  "ticket": "TK-11448",
+  "checked_at": "2026-09-11T18:54:32.430Z",
+  "tally": {
+    "CONFIRMED_ABSENT": 3,
+    "LIVE_AT_VENDOR": 6
+  },
+  "rows": [
+    {
+      "handle": "dwss-71022",
+      "title": "Oscar grey Wallcovering",
+      "candidates": [
+        "oscar-grey"
+      ],
+      "sitemap": "ABSENT",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/oscar-grey",
+          "http": 404,
+          "is404": true
+        }
+      ],
+      "verdict": "CONFIRMED_ABSENT"
+    },
+    {
+      "handle": "dwss-71076",
+      "title": "Kimono green Wallcovering",
+      "candidates": [
+        "kimono-green"
+      ],
+      "sitemap": "ABSENT",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/kimono-green",
+          "http": 404,
+          "is404": true
+        }
+      ],
+      "verdict": "CONFIRMED_ABSENT"
+    },
+    {
+      "handle": "dwss-71269",
+      "title": "Marieberg - Blue Wallcoverings",
+      "candidates": [
+        "marieberg-blue",
+        "marieberg"
+      ],
+      "sitemap": "FOUND",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/marieberg-blue",
+          "http": 404,
+          "is404": true
+        },
+        {
+          "url": "https://sandbergwallpaper.com/marieberg",
+          "http": 200,
+          "is404": false
+        }
+      ],
+      "verdict": "LIVE_AT_VENDOR"
+    },
+    {
+      "handle": "dwss-71270",
+      "title": "Marieberg - Blue Wallcoverings",
+      "candidates": [
+        "marieberg-blue",
+        "marieberg"
+      ],
+      "sitemap": "FOUND",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/marieberg-blue",
+          "http": 404,
+          "is404": true
+        },
+        {
+          "url": "https://sandbergwallpaper.com/marieberg",
+          "http": 200,
+          "is404": false
+        }
+      ],
+      "verdict": "LIVE_AT_VENDOR"
+    },
+    {
+      "handle": "dwss-71290",
+      "title": "Oak View - Graphite Wallcoverings",
+      "candidates": [
+        "oak-view-graphite",
+        "oak-view"
+      ],
+      "sitemap": "FOUND",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/oak-view-graphite",
+          "http": 404,
+          "is404": true
+        },
+        {
+          "url": "https://sandbergwallpaper.com/oak-view",
+          "http": 200,
+          "is404": false
+        }
+      ],
+      "verdict": "LIVE_AT_VENDOR"
+    },
+    {
+      "handle": "dwss-71367",
+      "title": "Margareta - Garden Green Wallcovering",
+      "candidates": [
+        "margareta-garden-green",
+        "margareta"
+      ],
+      "sitemap": "FOUND",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/margareta-garden-green",
+          "http": 410,
+          "is404": false
+        },
+        {
+          "url": "https://sandbergwallpaper.com/margareta",
+          "http": 404,
+          "is404": true
+        }
+      ],
+      "verdict": "LIVE_AT_VENDOR"
+    },
+    {
+      "handle": "dwss-71394",
+      "title": "Otis - Coral Wallcovering",
+      "candidates": [
+        "otis-coral",
+        "otis"
+      ],
+      "sitemap": "FOUND",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/otis-coral",
+          "http": 410,
+          "is404": false
+        },
+        {
+          "url": "https://sandbergwallpaper.com/otis",
+          "http": 404,
+          "is404": true
+        }
+      ],
+      "verdict": "LIVE_AT_VENDOR"
+    },
+    {
+      "handle": "dwss-71420",
+      "title": "Ragnvi - Spring Green Wallcovering",
+      "candidates": [
+        "ragnvi-spring-green",
+        "ragnvi"
+      ],
+      "sitemap": "FOUND",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/ragnvi-spring-green",
+          "http": 410,
+          "is404": false
+        },
+        {
+          "url": "https://sandbergwallpaper.com/ragnvi",
+          "http": 404,
+          "is404": true
+        }
+      ],
+      "verdict": "LIVE_AT_VENDOR"
+    },
+    {
+      "handle": "dwss-72355",
+      "title": "Texture1 Wallcovering",
+      "candidates": [
+        "texture1"
+      ],
+      "sitemap": "ABSENT",
+      "probes": [
+        {
+          "url": "https://sandbergwallpaper.com/texture1",
+          "http": 404,
+          "is404": true
+        }
+      ],
+      "verdict": "CONFIRMED_ABSENT"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/data/tk11448-vendor-confirm.json b/data/tk11448-vendor-confirm.json
new file mode 100644
index 0000000..6f6fdc9
--- /dev/null
+++ b/data/tk11448-vendor-confirm.json
@@ -0,0 +1,473 @@
+{
+  "ticket": "TK-11448",
+  "checked_at": "2026-09-11T18:53:09.199Z",
+  "method": "sitemap-absent AND direct product-URL 404 on every candidate slug",
+  "population": 26,
+  "tally": {
+    "CONFIRMED_ABSENT": 26
+  },
+  "rows": [
+    {
+      "handle": "dwrw-75513",
+      "vendor": "Rebel Walls",
+      "title": "Befoul | Rebel Walls",
+      "mfr_sku": "R50201",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/befoul",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75515",
+      "vendor": "Rebel Walls",
+      "title": "Oops! | Rebel Walls",
+      "mfr_sku": "R50203",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/oops",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75518",
+      "vendor": "Rebel Walls",
+      "title": "Björnkram | Rebel Walls",
+      "mfr_sku": "R50206",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/bjornkram",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75520",
+      "vendor": "Rebel Walls",
+      "title": "Concrete Jungle | Rebel Walls",
+      "mfr_sku": "R50402",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/concrete-jungle",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75522",
+      "vendor": "Rebel Walls",
+      "title": "No sleep till Brooklyn | Rebel Walls",
+      "mfr_sku": "R50404",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/no-sleep-till-brooklyn",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75524",
+      "vendor": "Rebel Walls",
+      "title": "Geometric Boundaries | Rebel Walls",
+      "mfr_sku": "R50502",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/geometric-boundaries",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75525",
+      "vendor": "Rebel Walls",
+      "title": "Isometric View | Rebel Walls",
+      "mfr_sku": "R50503",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/isometric-view",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75527",
+      "vendor": "Rebel Walls",
+      "title": "Futuristic Flowers | Rebel Walls",
+      "mfr_sku": "R50505",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/futuristic-flowers",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75528",
+      "vendor": "Rebel Walls",
+      "title": "Tartan | Rebel Walls",
+      "mfr_sku": "R50506",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/tartan",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75530",
+      "vendor": "Rebel Walls",
+      "title": "Colorbomb | Rebel Walls",
+      "mfr_sku": "R50601",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/colorbomb",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75531",
+      "vendor": "Rebel Walls",
+      "title": "Sam F | Rebel Walls",
+      "mfr_sku": "R50602",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/sam-f",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75533",
+      "vendor": "Rebel Walls",
+      "title": "Tigermarble | Rebel Walls",
+      "mfr_sku": "R50604",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/tigermarble",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75534",
+      "vendor": "Rebel Walls",
+      "title": "Tangram Puzzle | Rebel Walls",
+      "mfr_sku": "R50701",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/tangram-puzzle",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75535",
+      "vendor": "Rebel Walls",
+      "title": "Hyper Graphic | Rebel Walls",
+      "mfr_sku": "R50702",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/hyper-graphic",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75537",
+      "vendor": "Rebel Walls",
+      "title": "Rusty X-Ray | Rebel Walls",
+      "mfr_sku": "R50704",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/rusty-x-ray",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75551",
+      "vendor": "Rebel Walls",
+      "title": "Dragonfruit | Rebel Walls",
+      "mfr_sku": "R50904",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/dragonfruit",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75558",
+      "vendor": "Rebel Walls",
+      "title": "Natural Roof | Rebel Walls",
+      "mfr_sku": "R51003",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/natural-roof",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75562",
+      "vendor": "Rebel Walls",
+      "title": "Stairs | Rebel Walls",
+      "mfr_sku": "R51007",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/stairs",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75564",
+      "vendor": "Rebel Walls",
+      "title": "Winter Silence | Rebel Walls",
+      "mfr_sku": "R51101",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/winter-silence",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75565",
+      "vendor": "Rebel Walls",
+      "title": "Silent Lake | Rebel Walls",
+      "mfr_sku": "R51102",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/silent-lake",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75567",
+      "vendor": "Rebel Walls",
+      "title": "Hostal las Luces, black | Rebel Walls",
+      "mfr_sku": "R51201",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/hostal-las-luces-black",
+          "http": 404,
+          "is404": true
+        },
+        {
+          "url": "https://rebelwalls.com/hostal-las-luces",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75568",
+      "vendor": "Rebel Walls",
+      "title": "Hostal las Luces, green | Rebel Walls",
+      "mfr_sku": "R51202",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/hostal-las-luces-green",
+          "http": 404,
+          "is404": true
+        },
+        {
+          "url": "https://rebelwalls.com/hostal-las-luces",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75663",
+      "vendor": "Rebel Walls",
+      "title": "Letterpress, metal | Rebel Walls",
+      "mfr_sku": "RS11061",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/letterpress-metal",
+          "http": 404,
+          "is404": true
+        },
+        {
+          "url": "https://rebelwalls.com/letterpress",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75777",
+      "vendor": "Rebel Walls",
+      "title": "Rubber Stamp | Rebel Walls",
+      "mfr_sku": "RS12262",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/rubber-stamp",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75803",
+      "vendor": "Rebel Walls",
+      "title": "Roadways | Rebel Walls",
+      "mfr_sku": "RS12431",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/roadways",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    },
+    {
+      "handle": "dwrw-75804",
+      "vendor": "Rebel Walls",
+      "title": "Roadways, black&white | Rebel Walls",
+      "mfr_sku": "RS12432",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null,
+      "confirm": "CONFIRMED_ABSENT",
+      "probes": [
+        {
+          "url": "https://rebelwalls.com/roadways-black-white",
+          "http": 404,
+          "is404": true
+        },
+        {
+          "url": "https://rebelwalls.com/roadways",
+          "http": 404,
+          "is404": true
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/data/tk11448-vendor-presence.json b/data/tk11448-vendor-presence.json
new file mode 100644
index 0000000..44cf4f2
--- /dev/null
+++ b/data/tk11448-vendor-presence.json
@@ -0,0 +1,306 @@
+{
+  "ticket": "TK-11448",
+  "checked_at": "2026-09-11T18:52:03.563Z",
+  "source": "rebelwalls.com/sitemap.xml",
+  "slug_universe": 4538,
+  "positive_control": {
+    "n": 11,
+    "found": 11
+  },
+  "population": 32,
+  "tally": {
+    "ABSENT": 26,
+    "FOUND": 5,
+    "NOT_MEASURED": 1
+  },
+  "rows": [
+    {
+      "handle": "dwrw-75513",
+      "vendor": "Rebel Walls",
+      "title": "Befoul | Rebel Walls",
+      "mfr_sku": "R50201",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75515",
+      "vendor": "Rebel Walls",
+      "title": "Oops! | Rebel Walls",
+      "mfr_sku": "R50203",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75518",
+      "vendor": "Rebel Walls",
+      "title": "Björnkram | Rebel Walls",
+      "mfr_sku": "R50206",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75520",
+      "vendor": "Rebel Walls",
+      "title": "Concrete Jungle | Rebel Walls",
+      "mfr_sku": "R50402",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75522",
+      "vendor": "Rebel Walls",
+      "title": "No sleep till Brooklyn | Rebel Walls",
+      "mfr_sku": "R50404",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75524",
+      "vendor": "Rebel Walls",
+      "title": "Geometric Boundaries | Rebel Walls",
+      "mfr_sku": "R50502",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75525",
+      "vendor": "Rebel Walls",
+      "title": "Isometric View | Rebel Walls",
+      "mfr_sku": "R50503",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75527",
+      "vendor": "Rebel Walls",
+      "title": "Futuristic Flowers | Rebel Walls",
+      "mfr_sku": "R50505",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75528",
+      "vendor": "Rebel Walls",
+      "title": "Tartan | Rebel Walls",
+      "mfr_sku": "R50506",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75530",
+      "vendor": "Rebel Walls",
+      "title": "Colorbomb | Rebel Walls",
+      "mfr_sku": "R50601",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75531",
+      "vendor": "Rebel Walls",
+      "title": "Sam F | Rebel Walls",
+      "mfr_sku": "R50602",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75533",
+      "vendor": "Rebel Walls",
+      "title": "Tigermarble | Rebel Walls",
+      "mfr_sku": "R50604",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75534",
+      "vendor": "Rebel Walls",
+      "title": "Tangram Puzzle | Rebel Walls",
+      "mfr_sku": "R50701",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75535",
+      "vendor": "Rebel Walls",
+      "title": "Hyper Graphic | Rebel Walls",
+      "mfr_sku": "R50702",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75537",
+      "vendor": "Rebel Walls",
+      "title": "Rusty X-Ray | Rebel Walls",
+      "mfr_sku": "R50704",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75551",
+      "vendor": "Rebel Walls",
+      "title": "Dragonfruit | Rebel Walls",
+      "mfr_sku": "R50904",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75552",
+      "vendor": "Rebel Walls",
+      "title": "Garden | Rebel Walls",
+      "mfr_sku": "R50905",
+      "state": "FOUND",
+      "how": "pattern slug + colour suffix",
+      "slug": "garden-charm-summer,garden-of-dreams,garden-of-dreams-black-white"
+    },
+    {
+      "handle": "dwrw-75558",
+      "vendor": "Rebel Walls",
+      "title": "Natural Roof | Rebel Walls",
+      "mfr_sku": "R51003",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75562",
+      "vendor": "Rebel Walls",
+      "title": "Stairs | Rebel Walls",
+      "mfr_sku": "R51007",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75563",
+      "vendor": "Rebel Walls",
+      "title": "Structure | Rebel Walls",
+      "mfr_sku": "R51008",
+      "state": "FOUND",
+      "how": "pattern slug + colour suffix",
+      "slug": "structure-graphite"
+    },
+    {
+      "handle": "dwrw-75564",
+      "vendor": "Rebel Walls",
+      "title": "Winter Silence | Rebel Walls",
+      "mfr_sku": "R51101",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75565",
+      "vendor": "Rebel Walls",
+      "title": "Silent Lake | Rebel Walls",
+      "mfr_sku": "R51102",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75567",
+      "vendor": "Rebel Walls",
+      "title": "Hostal las Luces, black | Rebel Walls",
+      "mfr_sku": "R51201",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75568",
+      "vendor": "Rebel Walls",
+      "title": "Hostal las Luces, green | Rebel Walls",
+      "mfr_sku": "R51202",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75575",
+      "vendor": "Rebel Walls",
+      "title": "Sample | Rebel Walls",
+      "mfr_sku": "R95",
+      "state": "FOUND",
+      "how": "pattern slug + colour suffix",
+      "slug": "sample-folder,sample-guide"
+    },
+    {
+      "handle": "dwrw-75663",
+      "vendor": "Rebel Walls",
+      "title": "Letterpress, metal | Rebel Walls",
+      "mfr_sku": "RS11061",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75777",
+      "vendor": "Rebel Walls",
+      "title": "Rubber Stamp | Rebel Walls",
+      "mfr_sku": "RS12262",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75792",
+      "vendor": "Rebel Walls",
+      "title": "Ribbon, black&white | Rebel Walls",
+      "mfr_sku": "RS12353",
+      "state": "FOUND",
+      "how": "pattern slug + colour suffix",
+      "slug": "ribbon-stripe-beige,ribbon-stripe-blue,ribbon-stripe-burgundy"
+    },
+    {
+      "handle": "dwrw-75803",
+      "vendor": "Rebel Walls",
+      "title": "Roadways | Rebel Walls",
+      "mfr_sku": "RS12431",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-75804",
+      "vendor": "Rebel Walls",
+      "title": "Roadways, black&white | Rebel Walls",
+      "mfr_sku": "RS12432",
+      "state": "ABSENT",
+      "how": "no slug contains the pattern name",
+      "slug": null
+    },
+    {
+      "handle": "dwrw-76636",
+      "vendor": "Rebel Walls",
+      "title": "Farmers Hill, Fall | Rebel Walls",
+      "mfr_sku": "RS18061",
+      "state": "FOUND",
+      "how": "exact pattern+colour slug",
+      "slug": "farmers-hill-fall"
+    },
+    {
+      "handle": "dwss-72355",
+      "vendor": "Sandberg",
+      "title": "Texture1 Wallcovering | Sandberg",
+      "mfr_sku": "222-WW",
+      "state": "NOT_MEASURED",
+      "how": "vendor not covered by this sitemap (Sandberg)",
+      "slug": null
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tk11448-apply-archive.mjs b/tk11448-apply-archive.mjs
new file mode 100644
index 0000000..46d325f
--- /dev/null
+++ b/tk11448-apply-archive.mjs
@@ -0,0 +1,34 @@
+#!/usr/bin/env node
+/** TK-11448 archive executor for data/tk11448-archive-plan.json.
+ *  DRY-RUN BY DEFAULT. --apply required. --canary N supported.
+ *  Records prior status per product to data/tk11448-archive-ledger.jsonl BEFORE each write.
+ *  Undo: productUpdate status back to the recorded prior value (ACTIVE). Fully reversible. */
+import fs from 'fs';
+const APPLY=process.argv.includes('--apply');
+const CAN=(()=>{const i=process.argv.indexOf('--canary');return i>0?+process.argv[i+1]:0;})();
+const SHOP='designer-laboratory-sandbox';
+const tok=(fs.readFileSync(process.env.HOME+'/Projects/secrets-manager/.env','utf8').match(/^SHOPIFY_FULL_ACCESS_TOKEN=(.+)$/m)||[])[1];
+async function gql(q,v){for(let a=0;a<6;a++){const r=await fetch(`https://${SHOP}.myshopify.com/admin/api/2024-10/graphql.json`,{method:'POST',headers:{'X-Shopify-Access-Token':tok,'Content-Type':'application/json'},body:JSON.stringify({query:q,variables:v}),signal:AbortSignal.timeout(60000)});const j=await r.json();if(j.errors){if(JSON.stringify(j.errors).includes('THROTTLED')&&a<5){await new Promise(z=>setTimeout(z,2500*(a+1)));continue;}throw new Error(JSON.stringify(j.errors).slice(0,300));}return j.data;}throw new Error('throttled');}
+const plan=JSON.parse(fs.readFileSync('data/tk11448-archive-plan.json','utf8'));
+let rows=plan.rows.filter(r=>r.verdict==='ARCHIVE'); if(CAN) rows=rows.slice(0,CAN);
+console.log(`${APPLY?'APPLY':'DRY-RUN'} | archive ${rows.length} products`);
+if(!APPLY){ for(const r of rows) console.log('  would ARCHIVE',r.handle,(r.mfr_sku||'').padEnd(8),r.title);
+  console.log('\nDRY-RUN ONLY. Nothing written. Re-run with --apply.'); process.exit(0); }
+const led=fs.createWriteStream('data/tk11448-archive-ledger.jsonl',{flags:'a'});
+let ok=0,skip=0;
+for(const r of rows){
+  const cur=await gql(`query($h:String!){productByHandle(handle:$h){id status title}}`,{h:r.handle});
+  const p=cur.productByHandle;
+  if(!p){console.log('  SKIP not found',r.handle);skip++;continue;}
+  if(p.status!=='ACTIVE'){console.log('  SKIP already',p.status,r.handle);skip++;continue;}
+  led.write(JSON.stringify({ts:new Date().toISOString(),handle:r.handle,productId:p.id,
+    prior_status:p.status,new_status:'ARCHIVED',
+    undo:`productUpdate(input:{id:"${p.id}",status:${p.status}})`})+'\n');
+  const res=await gql(`mutation($in:ProductInput!){productUpdate(input:$in){product{id status} userErrors{field message}}}`,
+    {in:{id:p.id,status:'ARCHIVED'}});
+  const ue=res.productUpdate.userErrors;
+  if(ue&&ue.length){console.log('  ERR',r.handle,JSON.stringify(ue));continue;}
+  console.log('  ARCHIVED',r.handle,res.productUpdate.product.status); ok++;
+  await new Promise(z=>setTimeout(z,700));
+}
+led.end(); console.log(`done: archived ${ok}, skipped ${skip} | ledger -> data/tk11448-archive-ledger.jsonl`);
diff --git a/tk11448-archive-plan.mjs b/tk11448-archive-plan.mjs
new file mode 100644
index 0000000..7a95668
--- /dev/null
+++ b/tk11448-archive-plan.mjs
@@ -0,0 +1,48 @@
+#!/usr/bin/env node
+/** TK-11448 — build the ARCHIVE plan from Steve's rule: "if not on mfr website, archive it".
+ * Absence must clear THREE independent tests before a live product is archived:
+ *   1. not in the vendor's own sitemap (its published list of what it sells)
+ *   2. every plausible product URL returns 404 on a live fetch
+ *   3. the vendor's CDN has no article asset for the SKU
+ * Any single test saying "live" removes the product from the set. UNKNOWN is never archived. */
+import fs from 'fs';
+const pres=JSON.parse(fs.readFileSync('data/tk11448-vendor-presence.json','utf8'));
+const conf=JSON.parse(fs.readFileSync('data/tk11448-vendor-confirm.json','utf8'));
+const sb=JSON.parse(fs.readFileSync('data/tk11448-sandberg-presence.json','utf8'));
+const confBy=new Map(conf.rows.map(r=>[r.handle,r.confirm]));
+// Rebel Walls: sitemap-ABSENT confirmed by URL probe, PLUS the 4 loose-matches re-probed absent.
+const LOOSE_ABSENT=new Set(['dwrw-75552','dwrw-75563','dwrw-75575','dwrw-75792']); // Garden, Structure, Sample, Ribbon
+const LIVE_KEEP=new Set(['dwrw-76636']);                                            // Farmers Hill, Fall — vendor page live
+const rw=pres.rows.filter(r=>r.vendor==='Rebel Walls' &&
+  ((confBy.get(r.handle)==='CONFIRMED_ABSENT')||LOOSE_ABSENT.has(r.handle)) && !LIVE_KEEP.has(r.handle));
+const out=[];
+for(const r of rw){
+  const sku=r.mfr_sku||''; const tries=[sku, sku.replace(/^RS/i,'R')].filter((v,i,a)=>v&&a.indexOf(v)===i);
+  let cdn='ABSENT';
+  for(const s of tries){
+    const u=`https://res.rebelwalls.com/gimmersta-wallpaper/image/upload/c_limit,w_1600,f_auto,q_auto/articles/${s}_interior1.jpg`;
+    try{ const resp=await fetch(u,{signal:AbortSignal.timeout(25000)}); if(resp.status===200){cdn='EXISTS';break;} }
+    catch(e){ cdn='UNKNOWN'; }
+    await new Promise(z=>setTimeout(z,700));
+  }
+  out.push({handle:r.handle,vendor:r.vendor,mfr_sku:sku,title:r.title.split('|')[0].trim(),
+    test1_sitemap:'ABSENT',test2_url_probe:'404',test3_cdn_article:cdn,
+    verdict: cdn==='EXISTS'?'KEEP_LIVE_AT_VENDOR' : cdn==='UNKNOWN'?'NOT_MEASURED':'ARCHIVE'});
+  process.stderr.write(`  rw ${out.length}/${rw.length}\r`);
+}
+for(const r of sb.rows.filter(r=>r.verdict==='CONFIRMED_ABSENT')){
+  out.push({handle:r.handle,vendor:'Sandberg',mfr_sku:null,title:r.title,
+    test1_sitemap:'ABSENT',test2_url_probe:'404',test3_cdn_article:'n/a (no article CDN for Sandberg)',verdict:'ARCHIVE'});
+}
+const t={}; for(const r of out) t[r.verdict]=(t[r.verdict]||0)+1;
+const arch=out.filter(r=>r.verdict==='ARCHIVE');
+console.log(`\n=== ARCHIVE PLAN === population ${out.length}`);
+for(const [k,v] of Object.entries(t).sort((a,b)=>b[1]-a[1])) console.log(String(v).padStart(4),k);
+const bv={}; for(const r of arch) bv[r.vendor]=(bv[r.vendor]||0)+1;
+console.log('by vendor:',JSON.stringify(bv));
+for(const r of arch) console.log('  ARCHIVE',r.handle,(r.mfr_sku||'').padEnd(8),r.title.slice(0,38));
+fs.writeFileSync('data/tk11448-archive-plan.json',JSON.stringify({ticket:'TK-11448',built_at:new Date().toISOString(),
+ rule:'Steve 2026-09-11: if not on mfr website, archive it',
+ method:'3 independent absence tests; any single LIVE signal removes the product; UNKNOWN never archived',
+ population:out.length,tally:t,by_vendor:bv,gated:true,fired:false,rows:out},null,2));
+console.log('-> data/tk11448-archive-plan.json  (PLAN ONLY — nothing fired)');
diff --git a/tk11448-sandberg-presence.mjs b/tk11448-sandberg-presence.mjs
new file mode 100644
index 0000000..312dfcc
--- /dev/null
+++ b/tk11448-sandberg-presence.mjs
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+/** TK-11448 READ-ONLY: Sandberg vendor presence for all 9 placeholder-featured Sandberg products
+ * (the 8 proposed for a reorder fix + the 1 unsourceable). Same two-method standard as Rebel Walls:
+ * vendor sitemap AND direct product-URL probe. If a product proposed for FIXING is gone from the
+ * vendor, it belongs in the ARCHIVE set instead — which is why the fix set is re-checked, not assumed. */
+import fs from 'fs';
+const slugs=fs.readFileSync('/private/tmp/claude-501/-Users-macstudio3-Projects-designerwallcoverings/8a713388-7ee5-4ca3-b604-696ecb26a42b/scratchpad/sb_all.txt','utf8')
+ .split('\n').filter(Boolean).map(u=>u.replace(/^https?:\/\/(www\.)?sandbergwallpaper\.com\/?/,''));
+const one=new Set(slugs.filter(s=>s&&!s.includes('/')));
+const norm=s=>s.normalize('NFD').replace(/[̀-ͯ]/g,'').toLowerCase()
+  .replace(/['’`]/g,'').replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');
+const sweep=JSON.parse(fs.readFileSync('data/tk11448-placeholder-sweep.json','utf8'));
+const rows=sweep.rows.filter(r=>(r.vendor||'')==='Sandberg');
+console.log('sandberg slug universe:',one.size,'| subjects:',rows.length);
+const out=[];
+for(const r of rows){
+  // "Oak View - Graphite Wallcoverings | Sandberg" -> pattern "Oak View", colour "Graphite"
+  const t=r.title.split('|')[0].replace(/\bWallcoverings?\b/ig,'').trim();
+  const pattern=t.split(/[-,]/)[0].trim();
+  const cands=[...new Set([norm(t.replace(/[-,]/g,' ')),norm(pattern)])];
+  const rec={handle:r.handle,title:r.title.split('|')[0].trim(),candidates:cands};
+  const inMap=cands.filter(c=>one.has(c)||slugs.some(s=>s===c||s.startsWith(c+'-')));
+  rec.sitemap = inMap.length?'FOUND':'ABSENT';
+  const probes=[];
+  for(const c of cands){
+    const u=`https://sandbergwallpaper.com/${c}`;
+    try{ const resp=await fetch(u,{redirect:'follow',headers:{'User-Agent':'Mozilla/5.0'},signal:AbortSignal.timeout(25000)});
+      const b=await resp.text(); probes.push({url:u,http:resp.status,is404:resp.status===404||/404 - Missing Page/i.test(b)});
+    }catch(e){ probes.push({url:u,http:null,is404:null,err:String(e).slice(0,60)}); }
+    await new Promise(z=>setTimeout(z,900));
+  }
+  rec.probes=probes;
+  const anyLive=probes.some(p=>p.is404===false)||rec.sitemap==='FOUND';
+  const anyUnknown=probes.some(p=>p.is404===null);
+  rec.verdict = anyLive?'LIVE_AT_VENDOR' : anyUnknown?'NOT_MEASURED':'CONFIRMED_ABSENT';
+  out.push(rec);
+  console.log(' ',rec.verdict.padEnd(16),rec.handle,rec.title.slice(0,32).padEnd(32),'sitemap='+rec.sitemap,'|',cands.join(' , '));
+}
+const t={};for(const r of out)t[r.verdict]=(t[r.verdict]||0)+1;
+console.log('\n',JSON.stringify(t));
+fs.writeFileSync('data/tk11448-sandberg-presence.json',JSON.stringify({ticket:'TK-11448',checked_at:new Date().toISOString(),tally:t,rows:out},null,2));
+console.log('-> data/tk11448-sandberg-presence.json');
diff --git a/tk11448-vendor-confirm.mjs b/tk11448-vendor-confirm.mjs
new file mode 100644
index 0000000..8b6c155
--- /dev/null
+++ b/tk11448-vendor-confirm.mjs
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+/** TK-11448 READ-ONLY second opinion on ABSENT. Sitemap-absence alone can be wrong (an unlisted
+ * but live page). For every product the sitemap called ABSENT, fetch its plausible product URLs
+ * directly and require a 404 on ALL of them. Any 200 => the product IS live at the vendor and is
+ * REMOVED from the archive set. Robots-clean: direct product paths only, no ?query crawling. */
+import fs from 'fs';
+const d=JSON.parse(fs.readFileSync('data/tk11448-vendor-presence.json','utf8'));
+const norm=s=>s.normalize('NFD').replace(/[̀-ͯ]/g,'').toLowerCase()
+  .replace(/['’`]/g,'').replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');
+const absent=d.rows.filter(r=>r.state==='ABSENT');
+console.log('confirming',absent.length,'ABSENT products against live vendor pages');
+const out=[];
+for(const r of absent){
+  const t=r.title.split('|')[0].trim();
+  const pattern=t.split(',')[0].trim();
+  const cands=[...new Set([norm(t.replace(/,/g,' ')),norm(pattern)])].map(s=>`https://rebelwalls.com/${s}`);
+  const probes=[];
+  for(const u of cands){
+    try{
+      const resp=await fetch(u,{redirect:'follow',headers:{'User-Agent':'Mozilla/5.0'},signal:AbortSignal.timeout(25000)});
+      const body=await resp.text();
+      const is404=resp.status===404 || /404 - Missing Page/i.test(body);
+      probes.push({url:u,http:resp.status,is404});
+    }catch(e){ probes.push({url:u,http:null,is404:null,err:String(e).slice(0,70)}); }
+    await new Promise(z=>setTimeout(z,900));
+  }
+  const anyLive=probes.some(p=>p.is404===false);
+  const anyUnknown=probes.some(p=>p.is404===null);
+  r.confirm = anyLive ? 'LIVE_AT_VENDOR' : anyUnknown ? 'NOT_MEASURED' : 'CONFIRMED_ABSENT';
+  r.probes=probes;
+  out.push(r);
+  process.stderr.write(`  ${out.length}/${absent.length}\r`);
+}
+const t={}; for(const r of out) t[r.confirm]=(t[r.confirm]||0)+1;
+console.log(`\n=== population ${absent.length} ===`);
+for(const [k,v] of Object.entries(t).sort((a,b)=>b[1]-a[1])) console.log(String(v).padStart(4),k);
+const live=out.filter(r=>r.confirm==='LIVE_AT_VENDOR');
+if(live.length){ console.log('\n*** SITEMAP WAS WRONG for these — they are LIVE at the vendor, do NOT archive ***');
+  for(const r of live) console.log('   ',r.handle,r.mfr_sku,r.title.split('|')[0].trim(),'->',r.probes.find(p=>p.is404===false).url); }
+fs.writeFileSync('data/tk11448-vendor-confirm.json',JSON.stringify({ticket:'TK-11448',checked_at:new Date().toISOString(),
+ method:'sitemap-absent AND direct product-URL 404 on every candidate slug',population:absent.length,tally:t,rows:out},null,2));
+console.log('\n-> data/tk11448-vendor-confirm.json');
diff --git a/tk11448-vendor-presence.mjs b/tk11448-vendor-presence.mjs
new file mode 100644
index 0000000..3994cf1
--- /dev/null
+++ b/tk11448-vendor-presence.mjs
@@ -0,0 +1,61 @@
+#!/usr/bin/env node
+/** TK-11448 READ-ONLY: is each placeholder product still on the MANUFACTURER's website?
+ * Steve: "if not on mfr website. archive it". Absence must be PROVEN, not guessed — my first
+ * probe used two hand-guessed URLs and 404'd on a URL shape the vendor does not use.
+ * Method: rebelwalls.com/sitemap.xml (4,541 live product slugs, the vendor's own list of what it
+ * sells) matched on normalised pattern name. Ships with a POSITIVE CONTROL: the 11 products we
+ * KNOW are still live at the vendor must come back FOUND, or the method is wrong and nothing is
+ * archived. Three states; NOT_MEASURED is never archived. */
+import fs from 'fs';
+const slugs=fs.readFileSync(process.argv[2]||'/private/tmp/claude-501/-Users-macstudio3-Projects-designerwallcoverings/8a713388-7ee5-4ca3-b604-696ecb26a42b/scratchpad/rw_urls.txt','utf8')
+  .split('\n').filter(Boolean).map(u=>u.replace(/^https?:\/\/rebelwalls\.com\/?/,'')).filter(s=>s&&!s.includes('/'));
+const slugSet=new Set(slugs);
+const norm=s=>s.normalize('NFD').replace(/[̀-ͯ]/g,'')      // Björnkram -> Bjornkram
+  .toLowerCase().replace(/['’`]/g,'').replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');
+const alt=json=>json;
+const sweep=JSON.parse(fs.readFileSync('data/tk11448-placeholder-sweep.json','utf8'));
+const altf=JSON.parse(fs.readFileSync('data/tk11448-placeholder-alternatives.json','utf8'));
+const cand=JSON.parse(fs.readFileSync('data/tk11448-real-image-candidates.json','utf8'));
+const candBy=new Map(cand.rows.map(r=>[r.handle,r]));
+const clsBy=new Map(altf.rows.map(r=>[r.handle,r.class]));
+
+function probe(title){
+  // Shopify title: "Befoul | Rebel Walls"  /  "Mischievous Monkeys, Sunshine | Rebel Walls"
+  const t=title.split('|')[0].trim();
+  const pattern=t.split(',')[0].trim();
+  const full=norm(t.replace(/,/g,' '));
+  const pat=norm(pattern);
+  if(slugSet.has(full)) return {state:'FOUND',how:'exact pattern+colour slug',slug:full};
+  if(slugSet.has(pat))  return {state:'FOUND',how:'exact pattern slug',slug:pat};
+  const pre=slugs.filter(s=>s===pat||s.startsWith(pat+'-'));
+  if(pre.length)        return {state:'FOUND',how:'pattern slug + colour suffix',slug:pre.slice(0,3).join(',')};
+  const loose=slugs.filter(s=>s.includes(pat)&&pat.length>=5);
+  if(loose.length)      return {state:'FOUND_LOOSE',how:'pattern appears inside a slug',slug:loose.slice(0,3).join(',')};
+  return {state:'ABSENT',how:'no slug contains the pattern name',slug:null};
+}
+console.log('vendor slug universe:',slugs.length);
+// ---- POSITIVE CONTROL ----
+const control=sweep.rows.filter(r=>candBy.get(r.handle)?.class==='REPLACEMENT_READY_ge500');
+let cFound=0; for(const r of control){ const p=probe(r.title); if(p.state.startsWith('FOUND')) cFound++; }
+console.log(`POSITIVE CONTROL (known-live-at-vendor): ${cFound}/${control.length} FOUND`);
+if(control.length && cFound/control.length < 0.8){
+  console.log('*** CONTROL FAILED — the matcher cannot find products we KNOW are live. Refusing to declare anything absent. ***');
+  process.exit(3);
+}
+// ---- SUBJECTS: the unsourceable ones ----
+const subj=sweep.rows.filter(r=>clsBy.get(r.handle)==='NEEDS_IMAGE_SOURCING' && candBy.get(r.handle)?.class!=='REPLACEMENT_READY_ge500');
+const out=[],t={};
+for(const r of subj){
+  const isRW=(r.vendor||'')==='Rebel Walls';
+  const p=isRW?probe(r.title):{state:'NOT_MEASURED',how:'vendor not covered by this sitemap (Sandberg)',slug:null};
+  const rec={handle:r.handle,vendor:r.vendor,title:r.title,mfr_sku:candBy.get(r.handle)?.parsed_mfr_sku||null,...p};
+  t[rec.state]=(t[rec.state]||0)+1; out.push(rec);
+}
+console.log(`\n=== population ${subj.length} | measured ${subj.length-(t.NOT_MEASURED||0)} ===`);
+for(const [k,v] of Object.entries(t).sort((a,b)=>b[1]-a[1])) console.log(String(v).padStart(4),k);
+console.log('\n--- per product ---');
+for(const r of out) console.log(' ',r.state.padEnd(12),r.handle,(r.mfr_sku||'').padEnd(8),r.title.split('|')[0].trim().slice(0,34).padEnd(34),r.how);
+fs.writeFileSync('data/tk11448-vendor-presence.json',JSON.stringify({ticket:'TK-11448',checked_at:new Date().toISOString(),
+ source:'rebelwalls.com/sitemap.xml', slug_universe:slugs.length,
+ positive_control:{n:control.length,found:cFound}, population:subj.length, tally:t, rows:out},null,2));
+console.log('\n-> data/tk11448-vendor-presence.json');

← 8246589 TK-11448: remediation plan for 19 placeholder-featured produ  ·  back to Gmc Titlefix  ·  auto-data-snapshot: 2026-09-11T12:03:30 (3 data files) — dat 3e98b29 →