[object Object]

← back to Gmc Titlefix

TK-11233 B3: Kravet-family hi-res re-fetch canary (read-only enumerate + gated reversible apply)

4e97f128f706fc3ed517e751697691463aa115c6 · 2026-09-04 11:04:23 -0700 · Steve

Measures served vs Brandfolder-original per item; only re-fetches when original >=1500px
(40-sample: 21 viable / 16 orig-also-small excluded / 3 already-ok). Apply is hard-gated
(--apply + TK11233_APPROVED=1), ADDS new primary media without deleting the original, and is
reversible via --rollback <run-log>. Nothing fired.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dj5vkpUp18yQkVZEYNdSCG

Files touched

Diff

commit 4e97f128f706fc3ed517e751697691463aa115c6
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri Sep 4 11:04:23 2026 -0700

    TK-11233 B3: Kravet-family hi-res re-fetch canary (read-only enumerate + gated reversible apply)
    
    Measures served vs Brandfolder-original per item; only re-fetches when original >=1500px
    (40-sample: 21 viable / 16 orig-also-small excluded / 3 already-ok). Apply is hard-gated
    (--apply + TK11233_APPROVED=1), ADDS new primary media without deleting the original, and is
    reversible via --rollback <run-log>. Nothing fired.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Dj5vkpUp18yQkVZEYNdSCG
---
 data/tk11233-kravet-hires-canary.json | 689 ++++++++++++++++++++++++++++++++++
 tk11233-kravet-hires-canary.mjs       | 170 +++++++++
 2 files changed, 859 insertions(+)

diff --git a/data/tk11233-kravet-hires-canary.json b/data/tk11233-kravet-hires-canary.json
new file mode 100644
index 0000000..99a5d37
--- /dev/null
+++ b/data/tk11233-kravet-hires-canary.json
@@ -0,0 +1,689 @@
+{
+  "ticket": "TK-11233",
+  "bucket": "B3-kravet-hires",
+  "checked_at": "2026-09-04T18:03:22.924Z",
+  "scope": "ACTIVE Kravet-family products in kravet_catalog with Brandfolder originals",
+  "thresholds": {
+    "served_ok_px": 1024,
+    "min_original_px": 1500
+  },
+  "sample": 40,
+  "counts": {
+    "needs_hires": 21,
+    "original_also_small_excluded": 16,
+    "already_ok": 3,
+    "errors": 0
+  },
+  "needs_hires": [
+    {
+      "pid": "7413673689139",
+      "gid": "gid://shopify/Product/7413673689139",
+      "vendor": "Brunschwig & Fils",
+      "sku": "33345.1121.0",
+      "orig": "2000x2000",
+      "title": "Martel Weave - Cream Ivory By Brunschwig & Fils | Vienne Silks | Geometric Multipurpose Silk",
+      "media_id": "gid://shopify/MediaImage/24121475334195",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 2000,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44fy3-a5yhmw-6g3pym/33345_1121.jpg"
+    },
+    {
+      "pid": "7413614346291",
+      "gid": "gid://shopify/Product/7413614346291",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2023109.353.0",
+      "orig": "3791x3792",
+      "title": "Cernay Moire - Blue Blue By Brunschwig & Fils | Alsace Weaves | Texture Upholstery Silk",
+      "media_id": "gid://shopify/MediaImage/24121346359347",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3792,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/rhjksgc989t3cgtn6br5xtv/2023109_353.jpg"
+    },
+    {
+      "pid": "7413590261811",
+      "gid": "gid://shopify/Product/7413590261811",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2020184.5.0",
+      "orig": "3226x3226",
+      "title": "Embrun Woven - Blue Blue By Brunschwig & Fils | Durance |Small Scale  Upholstery Weave",
+      "media_id": "gid://shopify/MediaImage/24121321226291",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3226,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/as/5n7g78wfjcbwkvkxbqhm36/2020184_5.jpg"
+    },
+    {
+      "pid": "7413717106739",
+      "gid": "gid://shopify/Product/7413717106739",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35515.35.0",
+      "orig": "4500x4500",
+      "title": "Seijun - Antique Gold By Brunschwig & Fils | Solid Texture Wallcovering Silk",
+      "media_id": "gid://shopify/MediaImage/24121578258483",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 4500,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44gbr-8z7gjk-bukd2f/35515_35.jpg"
+    },
+    {
+      "pid": "7413740503091",
+      "gid": "gid://shopify/Product/7413740503091",
+      "vendor": "Brunschwig & Fils",
+      "sku": "36095.3.0",
+      "orig": "3007x3008",
+      "title": "Loriyan Tape - Fiesta Green By Brunschwig & Fils | Treillis Passementerie |  Trim Braid / Tape",
+      "media_id": "gid://shopify/MediaImage/24121637142579",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3008,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/rf6b2hmkpm6c4cxh87wp6jcx/36095_3.jpg"
+    },
+    {
+      "pid": "7413692694579",
+      "gid": "gid://shopify/Product/7413692694579",
+      "vendor": "Brunschwig & Fils",
+      "sku": "34329.11.0",
+      "orig": "2048x2048",
+      "title": "Ninon Taffetas - Bleu Blue By Brunschwig & Fils | Solid Upholstery Silk",
+      "media_id": "gid://shopify/MediaImage/24121516785715",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 2048,
+      "orig_url": "https://cdn.brandfolder.io/GI4CWF96/at/q44g35-74q9g8-fgiv4i/34329_11.jpg"
+    },
+    {
+      "pid": "7413728149555",
+      "gid": "gid://shopify/Product/7413728149555",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35909.23.0",
+      "orig": "6000x6000",
+      "title": "Vernay - Red White By Brunschwig & Fils | Cadenet Wallcoverings | Botanical & Floral Wallcovering Print",
+      "media_id": "gid://shopify/MediaImage/24121607716915",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 6000,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/as/s6cbrxkcmvvhr8s7jtk6qs8/35909_23.jpg"
+    },
+    {
+      "pid": "7413685059635",
+      "gid": "gid://shopify/Product/7413685059635",
+      "vendor": "Brunschwig & Fils",
+      "sku": "34031.16.0",
+      "orig": "1500x1500",
+      "title": "Bird And Thistle - Gray Grey By Brunschwig & Fils | Volume 56 | Toile Wallcovering Print",
+      "media_id": "gid://shopify/MediaImage/24121501220915",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1500,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44g0z-2buay8-ezaapl/34031_16.jpg"
+    },
+    {
+      "pid": "7413747515443",
+      "gid": "gid://shopify/Product/7413747515443",
+      "vendor": "Brunschwig & Fils",
+      "sku": "36336.11.0",
+      "orig": "4334x4334",
+      "title": "Barodet Cord - Leaf Green By Brunschwig & Fils | Passementerie Volume I |  Trim Cord",
+      "media_id": "gid://shopify/MediaImage/24121655296051",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 4334,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/czkt4k6qfj8mfcw98qb86fs/36336_11.jpg"
+    },
+    {
+      "pid": "7413592916019",
+      "gid": "gid://shopify/Product/7413592916019",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2020198.357.0",
+      "orig": "3173x3173",
+      "title": "Adrien Cotton - Mahogany Chocolate By Brunschwig & Fils | Solid Texture Multipurpose",
+      "media_id": "gid://shopify/MediaImage/24121324109875",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3173,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/c937f7vfvg788n27p3jjtcf/2020198_357.jpg"
+    },
+    {
+      "pid": "7413537570867",
+      "gid": "gid://shopify/Product/7413537570867",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2018148.68.0",
+      "orig": "3374x3374",
+      "title": "Otes Solid - Pebble Light Grey By Brunschwig & Fils | L'Atelier Moderne |Solid Texture Multipurpose",
+      "media_id": "gid://shopify/MediaImage/24121298550835",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3374,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44etn-9akzlk-e6skup/2018148_68.jpg"
+    },
+    {
+      "pid": "7413723627571",
+      "gid": "gid://shopify/Product/7413723627571",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35520.511.0",
+      "orig": "3428x3428",
+      "title": "La Pagode - Teal By Brunschwig & Fils | Les Ensembliers Wallcoverings | Chinoiserie Wallcovering Embroidery",
+      "media_id": "gid://shopify/MediaImage/24121595494451",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3428,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44gby-e3ptjk-flu2y7/35520_511.jpg"
+    },
+    {
+      "pid": "7413594161203",
+      "gid": "gid://shopify/Product/7413594161203",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2020204.73.0",
+      "orig": "4480x4480",
+      "title": "Les Vagues Emb - Sky/Royal Dark Blue By Brunschwig & Fils | Les Ensembliers | Geometric Multipurpose Embroidery",
+      "media_id": "gid://shopify/MediaImage/24121325649971",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 4480,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/k4p2f4nc37nxgkjg32vc6/2020204_73.jpg"
+    },
+    {
+      "pid": "7413675032627",
+      "gid": "gid://shopify/Product/7413675032627",
+      "vendor": "Brunschwig & Fils",
+      "sku": "33353.106.0",
+      "orig": "2000x2000",
+      "title": "Arnaud Damask - Blue Light Blue By Brunschwig & Fils | Vienne Silks | Damask Multipurpose Silk",
+      "media_id": "gid://shopify/MediaImage/24121478512691",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 2000,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44fy3-5bfcqg-bgl4es/33345_106.jpg"
+    },
+    {
+      "pid": "7413715828787",
+      "gid": "gid://shopify/Product/7413715828787",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35495.15.0",
+      "orig": "3000x3000",
+      "title": "Kochi - Persimon Burgundy By Brunschwig & Fils | Solid Texture",
+      "media_id": "gid://shopify/MediaImage/24121574326323",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3000,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/as/739ppr8s46gsnv6ngv7n45tt/35495_15.jpg"
+    },
+    {
+      "pid": "7413535014963",
+      "gid": "gid://shopify/Product/7413535014963",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2018148.16.0",
+      "orig": "3471x3471",
+      "title": "Celestin - Paprika Rust By Brunschwig & Fils | L'Atelier Moderne | Texture Upholstery Chenille",
+      "media_id": "gid://shopify/MediaImage/24121297338419",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3471,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44etm-6yoqfk-b9x4bo/2018148_16.jpg"
+    },
+    {
+      "pid": "7413617557555",
+      "gid": "gid://shopify/Product/7413617557555",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2023122.24.0",
+      "orig": "3178x3178",
+      "title": "Nadari Print - Peach/Gold Multi By Brunschwig & Fils | Folio Francais | Global Multipurpose Print",
+      "media_id": "gid://shopify/MediaImage/24121351110707",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3178,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/bntn47xhncbbnrr4bncnx9wr/2023122_24.jpg"
+    },
+    {
+      "pid": "7413730410547",
+      "gid": "gid://shopify/Product/7413730410547",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35966.1635.0",
+      "orig": "4379x4379",
+      "title": "Tourbillon - Lapis Turquoise By Brunschwig & Fils | Celeste Wallcovering | Modern Wallcovering Print",
+      "media_id": "gid://shopify/MediaImage/24121613451315",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 4379,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/as/33fbq8bvk6v4fsfqnp2w7wp/35966_1635.jpg"
+    },
+    {
+      "pid": "7413607727155",
+      "gid": "gid://shopify/Product/7413607727155",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2022112.417.0",
+      "orig": "4480x4480",
+      "title": "Bird & Swing Hb - Aqua Turquoise By Brunschwig & Fils | Botanical & Floral Multipurpose Print",
+      "media_id": "gid://shopify/MediaImage/24121338200115",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 4480,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/6wm97ktcqhrzt7kwkwsnk/2022112_417.jpg"
+    },
+    {
+      "pid": "7413738831923",
+      "gid": "gid://shopify/Product/7413738831923",
+      "vendor": "Brunschwig & Fils",
+      "sku": "36086.31.0",
+      "orig": "3544x3544",
+      "title": "Sanchi Tape - Oyster Grey By Brunschwig & Fils | Treillis Passementerie |  Trim Braid / Tape",
+      "media_id": "gid://shopify/MediaImage/24121632653363",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3544,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/as/vm746897j3c474mrxpg3mcs/36086_31.jpg"
+    },
+    {
+      "pid": "7413590917171",
+      "gid": "gid://shopify/Product/7413590917171",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2020188.134.0",
+      "orig": "3226x3226",
+      "title": "Chamas Stripe - Indigo Indigo By Brunschwig & Fils | Durance | Stripes Upholstery",
+      "media_id": "gid://shopify/MediaImage/24121321979955",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 3226,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/as/qxvgw8jfx4jm4h8jfqr4nxz/2020188_134.jpg"
+    }
+  ],
+  "original_also_small_excluded": [
+    {
+      "pid": "7413635514419",
+      "gid": "gid://shopify/Product/7413635514419",
+      "vendor": "Brunschwig & Fils",
+      "sku": "30787.3.0",
+      "orig": "1024x1024",
+      "title": "De Blois Velvet - Leaf Green By Brunschwig & Fils | Chaumont Velvets |Dots Texture Upholstery Velvet",
+      "media_id": "gid://shopify/MediaImage/24121380864051",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44fg7-4usbx4-bjrs9q/30787_3.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413540028467",
+      "gid": "gid://shopify/Product/7413540028467",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2019102.147.0",
+      "orig": "1200x1200",
+      "title": "Le Zebre Emb - Leaf Green By Brunschwig & Fils | Cape Comorin | Animal Skins Multipurpose Embroidery",
+      "media_id": "gid://shopify/MediaImage/24121299828787",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1200,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q71mtc-chl5w8-g9ox8r/2019102_147.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413681324083",
+      "gid": "gid://shopify/Product/7413681324083",
+      "vendor": "Brunschwig & Fils",
+      "sku": "33851.515.0",
+      "orig": "1024x1024",
+      "title": "La Mer Weave - Teal Turquoise By Brunschwig & Fils | Les Ensembliers L'Eternel Ete |Abstract Texture Upholstery Indoor / Outdoor",
+      "media_id": "gid://shopify/MediaImage/24121491914803",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44fwj-gguw4w-5ldo94/33127_515.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413688336435",
+      "gid": "gid://shopify/Product/7413688336435",
+      "vendor": "Brunschwig & Fils",
+      "sku": "34258.116.0",
+      "orig": "1024x1024",
+      "title": "Fabriano Cotton And Linen Print - Grey Multi By Brunschwig & Fils | Cevennes | Botanical & Floral Multipurpose Print",
+      "media_id": "gid://shopify/MediaImage/24121505611827",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44gk8-4qxcu0-bvwfa/8014101_116.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413728739379",
+      "gid": "gid://shopify/Product/7413728739379",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35916.1.0",
+      "orig": "800x800",
+      "title": "Visan - Navy/Sky White By Brunschwig & Fils | Cadenet Wallcoverings | Paisley Wallcovering Print",
+      "media_id": "gid://shopify/MediaImage/24121608929331",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 800,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/as/qdmdaz-bnfd5s-3i5ya6/35916_1.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413518696499",
+      "gid": "gid://shopify/Product/7413518696499",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2016122.1611.0",
+      "orig": "1024x1024",
+      "title": "Bachelor Mohair - Mineral Grey By Brunschwig & Fils | Solid Texture Upholstery Mohair",
+      "media_id": "gid://shopify/MediaImage/24121265389619",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44g35-arhto8-ckqudj/34328_1611.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413729689651",
+      "gid": "gid://shopify/Product/7413729689651",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35916.323.0",
+      "orig": "800x800",
+      "title": "Petit Leopard - Rose Pink By Brunschwig & Fils | Madeleine Castaing Wallcoverings |Animal/Insects Animal Skins Wallcovering Print",
+      "media_id": "gid://shopify/MediaImage/24121611943987",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 800,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/as/qdmdaz-bnfd5s-7hlpmw/35916_323.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413513715763",
+      "gid": "gid://shopify/Product/7413513715763",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2012175.97.0",
+      "orig": "1024x1024",
+      "title": "Charmant Velvet - Hazelnut Brown By Brunschwig & Fils | Solid Texture Upholstery Velvet",
+      "media_id": "gid://shopify/MediaImage/24121252675635",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44fs2-b12bog-alur5t/32344_97.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413684207667",
+      "gid": "gid://shopify/Product/7413684207667",
+      "vendor": "Brunschwig & Fils",
+      "sku": "33886.111.0",
+      "orig": "1024x1024",
+      "title": "Talavera - Indigo By Brunschwig & Fils | Botanical & Floral Wallcovering Print",
+      "media_id": "gid://shopify/MediaImage/24121499222067",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44g0e-2i8kaw-21qeb6/33886_111.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413690171443",
+      "gid": "gid://shopify/Product/7413690171443",
+      "vendor": "Brunschwig & Fils",
+      "sku": "34259.012.0",
+      "orig": "1024x1024",
+      "title": "Barclay Texture - Terracotta Orange By Brunschwig & Fils | Texture Upholstery Chenille",
+      "media_id": "gid://shopify/MediaImage/24121509511219",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44gzr-367kz4-ag8ksc/BR-89778_012.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413643935795",
+      "gid": "gid://shopify/Product/7413643935795",
+      "vendor": "Brunschwig & Fils",
+      "sku": "31326.23.0",
+      "orig": "1024x1024",
+      "title": "Weymouth Print - Red Red By Brunschwig & Fils | Manoir | Botanical & Floral Multipurpose Print",
+      "media_id": "gid://shopify/MediaImage/24121396527155",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44fid-9j8ni8-89fr9p/31326_23.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413691646003",
+      "gid": "gid://shopify/Product/7413691646003",
+      "vendor": "Brunschwig & Fils",
+      "sku": "34328.135.0",
+      "orig": "1024x1024",
+      "title": "Satin La Tour - Champagne Beige By Brunschwig & Fils | Solid Texture Upholstery Silk",
+      "media_id": "gid://shopify/MediaImage/24121513607219",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44g33-7wpwww-emuife/34328_135.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413561524275",
+      "gid": "gid://shopify/Product/7413561524275",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2020129.136.0",
+      "orig": "886x886",
+      "title": "Tepey Chenille - Blue Blue By Brunschwig & Fils | Chambery Textures | Texture Upholstery Chenille",
+      "media_id": "gid://shopify/MediaImage/24121317457971",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 886,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/as/qd9h2f-dvcc5c-4s65za/2020129_136.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413519941683",
+      "gid": "gid://shopify/Product/7413519941683",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2016122.909.0",
+      "orig": "1024x1024",
+      "title": "Bachelor Mohair - Persimmon Rust By Brunschwig & Fils | Solid Texture Upholstery Mohair",
+      "media_id": "gid://shopify/MediaImage/24121268535347",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44g35-1b00t4-6x5bjv/34328_909.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413515419699",
+      "gid": "gid://shopify/Product/7413515419699",
+      "vendor": "Brunschwig & Fils",
+      "sku": "2012176.50.0",
+      "orig": "1024x1024",
+      "title": "Charmant Velvet - Chianti Purple By Brunschwig & Fils | Solid Texture Upholstery Velvet",
+      "media_id": "gid://shopify/MediaImage/24121256771635",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44fct-abs0ug-708khx/30421_50.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    },
+    {
+      "pid": "7413696299059",
+      "gid": "gid://shopify/Product/7413696299059",
+      "vendor": "Brunschwig & Fils",
+      "sku": "34397.1616.0",
+      "orig": "1024x1024",
+      "title": "Autun Mohair Velvet - Almond Beige By Brunschwig & Fils | Solid Texture Upholstery Mohair",
+      "media_id": "gid://shopify/MediaImage/24121523666995",
+      "served_long": 400,
+      "served": "400x400",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/q44g4r-ffqmfc-6txnip/34397_1616.jpg",
+      "note": "original-also-small → excluded (defer to upscale program)"
+    }
+  ],
+  "already_ok": [
+    {
+      "pid": "7821709967411",
+      "gid": "gid://shopify/Product/7821709967411",
+      "vendor": "Cole & Son",
+      "sku": "119/10045.CS.0",
+      "orig": "1319x1319",
+      "title": "Protea Garden Silk Olvgrn&Tngrn/Wht | Cole & Son",
+      "media_id": "gid://shopify/MediaImage/28084866056243",
+      "served_long": 1319,
+      "served": "1319x1319",
+      "orig_long": 1319,
+      "orig_url": "https://cdn.brandfolder.io/UT8SLOWQ/at/sspw6zkt3r87s9nqjsfb2b2p/119_10045_CS.jpg"
+    },
+    {
+      "pid": "7413664743475",
+      "gid": "gid://shopify/Product/7413664743475",
+      "vendor": "Brunschwig & Fils",
+      "sku": "32949.30.0",
+      "orig": "1024x1024",
+      "title": "Aurel Print - Gold/Red Yellow By Brunschwig & Fils | Cadenet | Flora & Fauna Multipurpose Print",
+      "media_id": "gid://shopify/MediaImage/24121442304051",
+      "served_long": 1200,
+      "served": "1200x1200",
+      "orig_long": 1024,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/at/q44fvp-2yx6zk-b9e919/32949_30.jpg"
+    },
+    {
+      "pid": "7413726445619",
+      "gid": "gid://shopify/Product/7413726445619",
+      "vendor": "Brunschwig & Fils",
+      "sku": "35766.1623.0",
+      "orig": "2764x2764",
+      "title": "Marindol - Canary Yellow By Brunschwig & Fils | Manoir Wallcoverings | Paisley Wallcovering Print",
+      "media_id": "gid://shopify/MediaImage/24121602474035",
+      "served_long": 1200,
+      "served": "1200x1200",
+      "orig_long": 2764,
+      "orig_url": "https://cdn.brandfolder.io/XSDLGRW8/as/n8kc77xsrn7rjqwk8ctgzn4/35766_1623.jpg"
+    }
+  ],
+  "errors": [],
+  "rollback_map": [
+    {
+      "gid": "gid://shopify/Product/7413673689139",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121475334195",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8023144_16_8efdeb09-eeb0-4980-b509-88004ca61e31.jpg?v=1725920701",
+      "old_media_count": 10
+    },
+    {
+      "gid": "gid://shopify/Product/7413614346291",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121346359347",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8019119_5_d5a5fde4-e9b7-4251-9d3e-4656c1577630.jpg?v=1725919232",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413590261811",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121321226291",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8017102_5_d2cf225e-dfed-41ef-a9b0-06ed2e40e58d.jpg?v=1725918858",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413717106739",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121578258483",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8015147_14_5696e7a7-2f01-43a2-bf26-1ac00e754ffb.jpg?v=1725922434",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413740503091",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121637142579",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/T8019104_37_149ba74c-ab7b-458a-8981-1919f50cb8ac.jpg?v=1725923422",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413692694579",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121516785715",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/BR-81081_PPO_b70d081d-083a-4e33-a87e-9e997b9b71bb.jpg?v=1725921379",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413728149555",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121607716915",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8023101_19_a6bb2a95-25c9-44b8-b2cb-d444cd2f1c90.jpg?v=1725922935",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413685059635",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121501220915",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/BR-69518_11_52b7714b-010b-4a04-a3fe-de88faccd010.jpg?v=1725921098",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413747515443",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121655296051",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/T8020106_3_aeb8dba0-76e0-4b51-9c82-12d9cced6dd7.jpg?v=1725923698",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413592916019",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121324109875",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8017121_6_6027aadb-e06c-44ff-b6b0-5b162881c6f1.jpg?v=1725918908",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413537570867",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121298550835",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8015167_21_1ddc6832-bad7-4053-936f-d7c0dcadc8a8.jpg?v=1725918557",
+      "old_media_count": 10
+    },
+    {
+      "gid": "gid://shopify/Product/7413723627571",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121595494451",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8020108_35_f3afd4ba-dbe6-4ac9-a195-b930f188a780.jpg?v=1725922727",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413594161203",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121325649971",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8017128_50_f950ea0c-14ca-4fcf-9886-6c52b009b3ad.jpg?v=1725918932",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413675032627",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121478512691",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8023150_5_ce893327-c3a9-4bf2-ac71-94adbdc5b22c.jpg?v=1725920768",
+      "old_media_count": 6
+    },
+    {
+      "gid": "gid://shopify/Product/7413715828787",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121574326323",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8015146_19_4f6a5b7a-da7e-4ae1-b9c8-a7311f939df5.jpg?v=1725922374",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413535014963",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121297338419",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8015160_12_e3b4e683-677b-4d1b-b1c3-bdbeb64e8edf.jpg?v=1725918543",
+      "old_media_count": 10
+    },
+    {
+      "gid": "gid://shopify/Product/7413617557555",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121351110707",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8019129_124_af2b32c2-7159-4a60-87bf-95dccb6c94be.jpg?v=1725919292",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413730410547",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121613451315",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/P8023111_355_cc6be34b-fcab-4450-a076-0342b49cb04c.jpg?v=1725923055",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413607727155",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121338200115",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8019100_13_dd17de81-f915-421f-bdc1-6083f57a32d4.jpg?v=1725919144",
+      "old_media_count": 1
+    },
+    {
+      "gid": "gid://shopify/Product/7413738831923",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121632653363",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/T8019100_11_3a8fcb7a-6a9d-461a-8186-b34ca9e3a4bd.jpg?v=1725923342",
+      "old_media_count": 2
+    },
+    {
+      "gid": "gid://shopify/Product/7413590917171",
+      "old_primary_media_id": "gid://shopify/MediaImage/24121321979955",
+      "old_primary_src": "https://cdn.shopify.com/s/files/1/0015/4117/7456/files/8017103_50_e838c916-f364-4e43-b17a-2206ed3eb96a.jpg?v=1725918873",
+      "old_media_count": 2
+    }
+  ],
+  "apply_gate": "HARD-GATED — requires --apply AND env TK11233_APPROVED=1; apply ADDS new media (never deletes the original); reversible via --rollback <run-log>."
+}
\ No newline at end of file
diff --git a/tk11233-kravet-hires-canary.mjs b/tk11233-kravet-hires-canary.mjs
new file mode 100644
index 0000000..55f192e
--- /dev/null
+++ b/tk11233-kravet-hires-canary.mjs
@@ -0,0 +1,170 @@
+#!/usr/bin/env node
+// TK-11233 Bucket-3 — Kravet-family HI-RES image re-fetch canary.
+//
+// PROBLEM: DW downsized Kravet-family masters to ~400px on ingest, so Google flags
+//   image_too_small_for_high_resolution (12,777 warns) → free/enhanced-listing demotion.
+//   The vendor originals live on Kravet's Brandfolder DAM (cdn.brandfolder.io) and are
+//   MOSTLY 2500–4361px — but NOT ALL (verified 1/5 sample was 427px). So we re-fetch the
+//   ORIGINAL and re-upload ONLY when the original actually clears the bar. This naturally
+//   excludes Phillipe Romano / Koroseal (different catalog tables, genuinely-capped originals).
+//
+// SAFETY / REVERSIBILITY:
+//   * DEFAULT = read-only enumerate. Measures served vs original, classifies, writes a
+//     candidate list + rollback map. Fires NOTHING.
+//   * --apply is HARD-GATED: refuses unless BOTH `--apply` AND env TK11233_APPROVED=1.
+//     Apply ADDS the hi-res image as new media and moves it to position 1 — it NEVER deletes
+//     the existing master. Rollback = delete the newly-added media + restore prior order,
+//     recorded per-product in the run-log. The original image is never destroyed.
+//
+// Usage:
+//   node tk11233-kravet-hires-canary.mjs                 # canary enumerate (default N=25), read-only
+//   node tk11233-kravet-hires-canary.mjs --limit 100     # bigger read-only enumeration
+//   node tk11233-kravet-hires-canary.mjs --apply         # REFUSES unless TK11233_APPROVED=1
+//   TK11233_APPROVED=1 node ... --apply --limit 25       # gated apply (do NOT run without approval)
+//   node tk11233-kravet-hires-canary.mjs --rollback <run-log.jsonl>   # undo an apply run
+
+import { execSync } from 'child_process';
+import fs from 'fs';
+import os from 'os';
+
+const SHOP = 'designer-laboratory-sandbox';
+const MIN_HIRES = 1500;          // require original ≥1500px on the long edge to bother (Google bar is 1024; headroom)
+const SERVED_MAX_OK = 1024;      // served ≥1024 = already fine, skip
+const LIMIT = parseInt((process.argv.find(a=>a==='--limit') ? process.argv[process.argv.indexOf('--limit')+1] : '25'), 10);
+const APPLY = process.argv.includes('--apply');
+const ROLLBACK = process.argv.includes('--rollback') ? process.argv[process.argv.indexOf('--rollback')+1] : null;
+const OUT = new URL('./data/tk11233-kravet-hires-canary.json', import.meta.url).pathname;
+const RUNLOG = new URL(`./data/tk11233-kravet-hires-apply-${new Date().toISOString().replace(/[:.]/g,'-')}.jsonl`, import.meta.url).pathname;
+
+const shopTok = (fs.readFileSync(process.env.HOME + '/Projects/secrets-manager/.env', 'utf8')
+  .match(/^SHOPIFY_FULL_ACCESS_TOKEN=(.+)$/m) || [])[1];
+if (!shopTok) { console.error('missing SHOPIFY_FULL_ACCESS_TOKEN'); process.exit(2); }
+
+async function shopify(query, variables) {
+  const r = await fetch(`https://${SHOP}.myshopify.com/admin/api/2024-10/graphql.json`, {
+    method: 'POST',
+    headers: { 'X-Shopify-Access-Token': shopTok, 'Content-Type': 'application/json' },
+    body: JSON.stringify({ query, variables }), signal: AbortSignal.timeout(60000) });
+  const j = await r.json();
+  if (j.errors) throw new Error('shopify gql: ' + JSON.stringify(j.errors));
+  return j.data;
+}
+
+// measure remote image on the long edge via curl + sips (local, $0)
+function dims(url) {
+  try {
+    const tmp = `${os.tmpdir()}/tk11233-${Math.random().toString(36).slice(2)}.img`;
+    execSync(`curl -s -m 30 -o ${tmp} ${JSON.stringify(url)}`, { stdio: 'ignore' });
+    const out = execSync(`sips -g pixelWidth -g pixelHeight ${tmp} 2>/dev/null || true`).toString();
+    fs.unlinkSync(tmp);
+    const w = +(out.match(/pixelWidth:\s*(\d+)/)||[])[1] || 0;
+    const h = +(out.match(/pixelHeight:\s*(\d+)/)||[])[1] || 0;
+    return { w, h, long: Math.max(w, h) };
+  } catch { return { w: 0, h: 0, long: 0 }; }
+}
+
+function pickCandidates(limit) {
+  // ACTIVE Kravet-family products joined to kravet_catalog (brandfolder originals only).
+  // kravet_catalog membership is what scopes this to the Kravet family — PR/Koroseal are other tables.
+  const sql = `SELECT sp.shopify_id, sp.vendor, c.mfr_sku, c.image_url AS orig_url FROM shopify_products sp JOIN kravet_catalog c ON c.shopify_product_id::text = sp.shopify_id::text WHERE sp.status='ACTIVE' AND c.image_url ~ 'brandfolder' AND sp.shopify_id IS NOT NULL ORDER BY random() LIMIT ${limit};`;
+  const raw = execSync(`psql "host=/tmp dbname=dw_unified" -tA -F'\t' -c ${JSON.stringify(sql)}`).toString().trim();
+  if (!raw) return [];
+  return raw.split('\n').map(l => { const [gid, vendor, sku, orig] = l.split('\t'); const pid = (gid.match(/(\d+)$/)||[])[1]; return { pid, gid, vendor, sku, orig }; });
+}
+
+async function primaryMedia(pid) {
+  const gid = `gid://shopify/Product/${pid}`;
+  const d = await shopify(`query($id:ID!){ product(id:$id){ id title
+      media(first:10){ nodes{ id mediaContentType
+        ... on MediaImage { image { url width height } } } } } }`, { id: gid });
+  const p = d.product; if (!p) return null;
+  const imgs = p.media.nodes.filter(n => n.mediaContentType === 'IMAGE');
+  return { gid, title: p.title, first: imgs[0] || null, mediaCount: imgs.length };
+}
+
+async function enumerate() {
+  const cands = pickCandidates(LIMIT);
+  const needs = [], origSmall = [], alreadyOk = [], errors = [];
+  const rollbackMap = [];
+  for (const c of cands) {
+    try {
+      const m = await primaryMedia(c.pid);
+      if (!m || !m.first) { errors.push({ ...c, why: 'no-media' }); continue; }
+      // served size Google sees = the master's Shopify image width/height (feed image_url)
+      const servedLong = Math.max(m.first.image.width || 0, m.first.image.height || 0);
+      const od = dims(c.orig);
+      const row = { ...c, gid: m.gid, title: m.title, media_id: m.first.id,
+        served_long: servedLong, served: `${m.first.image.width}x${m.first.image.height}`,
+        orig_long: od.long, orig: `${od.w}x${od.h}`, orig_url: c.orig };
+      if (servedLong >= SERVED_MAX_OK) { alreadyOk.push(row); }
+      else if (od.long >= MIN_HIRES) { needs.push(row);
+        rollbackMap.push({ gid: m.gid, old_primary_media_id: m.first.id, old_primary_src: m.first.image.url, old_media_count: m.mediaCount }); }
+      else { origSmall.push({ ...row, note: 'original-also-small → excluded (defer to upscale program)' }); }
+    } catch (e) { errors.push({ ...c, why: String(e).slice(0,120) }); }
+  }
+  const report = {
+    ticket: 'TK-11233', bucket: 'B3-kravet-hires', checked_at: new Date().toISOString(),
+    scope: 'ACTIVE Kravet-family products in kravet_catalog with Brandfolder originals',
+    thresholds: { served_ok_px: SERVED_MAX_OK, min_original_px: MIN_HIRES },
+    sample: cands.length,
+    counts: { needs_hires: needs.length, original_also_small_excluded: origSmall.length, already_ok: alreadyOk.length, errors: errors.length },
+    needs_hires: needs, original_also_small_excluded: origSmall, already_ok: alreadyOk, errors,
+    rollback_map: rollbackMap,
+    apply_gate: 'HARD-GATED — requires --apply AND env TK11233_APPROVED=1; apply ADDS new media (never deletes the original); reversible via --rollback <run-log>.'
+  };
+  fs.writeFileSync(OUT, JSON.stringify(report, null, 2));
+  console.log(`\n=== TK-11233 Kravet hi-res canary — sample ${cands.length} ===`);
+  console.log(`  NEEDS_HIRES (served<${SERVED_MAX_OK} & orig≥${MIN_HIRES}) : ${needs.length}`);
+  console.log(`  ORIG_ALSO_SMALL (excluded, defer)                        : ${origSmall.length}`);
+  console.log(`  ALREADY_OK (served≥${SERVED_MAX_OK})                          : ${alreadyOk.length}`);
+  console.log(`  ERRORS                                                   : ${errors.length}`);
+  console.log(`  → report: ${OUT}`);
+  needs.slice(0,8).forEach(r => console.log(`    + ${r.vendor} ${r.sku}  served=${r.served} orig=${r.orig}`));
+  origSmall.slice(0,5).forEach(r => console.log(`    - EXCLUDE ${r.vendor} ${r.sku}  orig=${r.orig}`));
+  console.log(`\ncost: $0 (Shopify reads + local sips). Nothing fired.`);
+  return report;
+}
+
+async function apply() {
+  if (!APPLY || process.env.TK11233_APPROVED !== '1') {
+    console.error('\n⛔ GATED: apply refused. Requires BOTH --apply AND env TK11233_APPROVED=1.');
+    console.error('   This writes customer-facing product media → must carry a logged TK-11248 approval first.');
+    process.exit(3);
+  }
+  const rpt = await enumerate();
+  console.log(`\n=== APPLY (gated, approved) — adding hi-res primary to ${rpt.needs_hires.length} products ===`);
+  for (const r of rpt.needs_hires) {
+    try {
+      const cm = await shopify(`mutation($pid:ID!,$media:[CreateMediaInput!]!){
+        productCreateMedia(productId:$pid, media:$media){ media{ id status } mediaUserErrors{ field message } } }`,
+        { pid: r.gid, media: [{ originalSource: r.orig_url, mediaContentType: 'IMAGE', alt: r.title }] });
+      const newId = cm.productCreateMedia.media?.[0]?.id;
+      const errs = cm.productCreateMedia.mediaUserErrors;
+      if (!newId || errs.length) { fs.appendFileSync(RUNLOG, JSON.stringify({ ...r, ok:false, errs })+'\n'); continue; }
+      // move new media to position 1 (primary) — reversible reorder
+      await shopify(`mutation($id:ID!,$moves:[MoveInput!]!){ productReorderMedia(id:$id, moves:$moves){ job{ id } userErrors{ message } } }`,
+        { id: r.gid, moves: [{ id: newId, newPosition: '0' }] });
+      fs.appendFileSync(RUNLOG, JSON.stringify({ gid:r.gid, sku:r.sku, ok:true,
+        added_media_id:newId, old_primary_media_id:r.media_id, old_primary_src:r.served,
+        undo:`delete media ${newId} + restore ${r.media_id} to position 0` })+'\n');
+      console.log(`  ✓ ${r.sku}  +hi-res ${r.orig}`);
+    } catch (e) { fs.appendFileSync(RUNLOG, JSON.stringify({ ...r, ok:false, err:String(e).slice(0,160) })+'\n'); }
+  }
+  console.log(`\nrun-log (rollback source): ${RUNLOG}`);
+}
+
+async function rollback(logPath) {
+  const lines = fs.readFileSync(logPath,'utf8').trim().split('\n').map(l=>JSON.parse(l)).filter(r=>r.ok && r.added_media_id);
+  console.log(`=== ROLLBACK ${lines.length} added media (deleting new, restoring original order) ===`);
+  for (const r of lines) {
+    try {
+      await shopify(`mutation($mediaIds:[ID!]!,$pid:ID!){ productDeleteMedia(mediaIds:$mediaIds, productId:$pid){ deletedMediaIds mediaUserErrors{ message } } }`,
+        { mediaIds:[r.added_media_id], pid:r.gid });
+      console.log(`  ↩ ${r.sku}  removed ${r.added_media_id}`);
+    } catch(e){ console.error(`  ✗ ${r.sku} ${String(e).slice(0,100)}`); }
+  }
+}
+
+if (ROLLBACK) rollback(ROLLBACK);
+else if (APPLY) apply();
+else enumerate();

← 9b6af59 TK-10993 Track G: read-only policy-disapproval enumerator  ·  back to Gmc Titlefix  ·  TK-11233 B3: --min/--cap args for approved canary run (thres 835144c →