{"slug":"reid-witlin-onboarding","total":36,"limit":100,"offset":0,"since":null,"commits":[{"hash":"bb0a80a","date":"2026-09-24 11:33:51 -0700","author":"Steve Abrams","subject":"backfill-rwltd-mfr: namespace-scoped idempotency + HTTP status check & retry","body":"Two live-Shopify-path fixes on the 1,195-row backfill: (1) liveHasMfr now matches\nthe EXACT target metafield custom.manufacturer_sku (namespace + key), not any\nnamespace with that key — a same-keyed metafield elsewhere could previously mask a\ngenuinely-missing custom one and get counted \"already had\"; (2) added a fetchRetry\nwrapper (429/5xx backoff, 6 tries) and res.ok checks in gql() and liveHasMfr(), so\na transient throttle no longer kills the batch mid-run or makes liveHasMfr return\nfalse on an error body (which would trigger a needless write). Re-runs resume\nsafely via the live idempotency read.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"97382b2","date":"2026-09-04 11:42:30 -0700","author":"Steve Abrams","subject":"TK-11256: fix Reid Witlin/Architectural Fabrics onboarder dropping description on the floor","body":"Root cause of dw-five-field-canary cadence-regression FAIL (1005 recent products,\n2026-09-03 batch): build_batch2.py never SELECTed rwltd_catalog.description/\nai_description and never emitted a description field in the CSV; create2.py never\nsent descriptionHtml to Shopify at all. Also: activate_batch.py had no\ndescription-present gate before flipping DRAFT->ACTIVE, unlike every other DW\nonboarder's go-live.mjs (which holds as draft on empty descriptionHtml).\n\nFixes (code-only, no data/Shopify writes fired):\n- build_batch2.py: SELECT description, ai_description in both pool queries; rec_common()\n  now emits description (description || ai_description, may still be empty if the\n  scraper never captured either -- separate data gap, not this bug).\n- create2.py: sends descriptionHtml when row['description'] is non-empty.\n- activate_batch.py: holds any product with empty descriptionHtml as DRAFT (writes\n  held-no-description.json) instead of activating it -- protects future runs against\n  repeating this regression.\n\nNote: the single-Sample-variant/quote-only shape is NOT a bug -- Steve explicitly\napproved activating this batch in that shape (git a5b4a18), matching the precedent of\n190 prior same-shape ACTIVE Reid Witlin products. Not touched.\n\nAlready-live 1,005 products still missing descriptions is a Shopify write -- gated,\nsee pending-approval memo."},{"hash":"4d7b594","date":"2026-09-03 17:41:55 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T17:39:42 (1 data files) — rwltd-mfr-rollback-ledger.jsonl","body":""},{"hash":"47569c9","date":"2026-09-03 17:03:44 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T17:01:36 (1 data files) — rwltd-mfr-rollback-ledger.jsonl","body":""},{"hash":"b036eec","date":"2026-09-03 16:25:31 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T16:23:17 (2 data files) — backfill-rwltd-mfr.mjs.bak rwltd-mfr-mapping-clean.csv","body":""},{"hash":"761eab8","date":"2026-09-03 15:09:54 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T15:07:41 (1 data files) — rwltd-mfr-mapping.csv","body":""},{"hash":"ef19926","date":"2026-09-03 11:42:21 -0700","author":"Steve Abrams","subject":"Reid Witlin/Architectural Fabrics: rename titles to Pattern/Town - Colorway Fabric","body":"Steve approved live: title format \"{Pattern-or-Town} - {Colorway} Fabric\"\n(e.g. \"Ashburn Cassis\" -> \"Ashburn - Cassis Fabric\"). Rebuilt titles from\nstructured catalog data (pattern_name/virginia_town + mfr_sku-derived\ncolorway) rather than string-splitting rendered titles, with a casing\nfix for ALL-CAPS raw vendor pattern names (e.g. \"A ZILLION RUBS\" ->\n\"A Zillion Rubs\"). Scoped to ACTIVE products only (live status-checked\nper row) -- 16 archived/discontinued rows correctly skipped.\n\nDry-run verified clean, live run: 1179 renamed, 16 skipped (not active),\n0 errors.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>"},{"hash":"b4d14f1","date":"2026-09-03 11:13:19 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T11:10:51 (1 data files) — rename-titles-fabric-results.json","body":""},{"hash":"83290a6","date":"2026-09-03 10:27:09 -0700","author":"Steve Abrams","subject":"Reid Witlin/Architectural Fabrics: publish to 12 sales channels","body":"Steve approved live: \"post to all 13 channels\". Excluded \"Fabricut\" as\na documented vendor-dedicated channel (TK-10762: published via its own\nfull-pattern daily poster, never the shared rotation) -- publishing a\ndifferent vendor's line there would be a mismatch, flagged to Steve.\n\nTwo-step publish: first the 5 channels matching the existing 190 live\nproducts' pattern (Online Store, POS, Buy Button, FB&IG, Houzz), then\nthe remaining 7 (Google&YouTube, Pinterest, Rakuten, Shop, Inbox,\nTikTok, DWAutoPostBlog). Idempotent per-product missing-channel diff.\nVerified: 1005/1005 confirmed on exactly 12 channels each, 0 errors.\n\nInventory: confirmed with Steve these are correctly untracked\n(inventoryItem.tracked=false) -- always-purchasable by design, no\nchange needed.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>"},{"hash":"a401b87","date":"2026-09-03 09:55:54 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T09:53:05 (1 data files) — publish-results.json","body":""},{"hash":"a5b4a18","date":"2026-09-03 09:39:31 -0700","author":"Steve Abrams","subject":"Reid Witlin/Architectural Fabrics: activate all 1,005 DRAFT products live","body":"Steve approved live in conversation 2026-09-03: \"make them active with\nour pl - architectural fabrics line\". These are quote-only, single-\nSample-variant products (same shape as the original 190 already-ACTIVE\nproducts), structurally excluded from the automatic rotation-activator\ncadence (SKU matches SAMPLE_SKU_REGEX -(sample|s)$), so this was a\ndirect one-time scripted activation, not a cadence fix.\n\nFetched the live DRAFT set fresh via GraphQL (1,005, matching post\ncodex overnight race-twin cleanup) rather than any local file.\nDRY_RUN verified clean, live run: 1005/1005 activated, 0 errors.\nIndependently re-verified via GraphQL nodes() against the exact set:\nall 1005 confirmed ACTIVE.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>"},{"hash":"b205e69","date":"2026-09-03 07:08:51 -0700","author":"Steve Abrams","subject":"Verify Reid Witlin recovery end to end","body":""},{"hash":"a8724f1","date":"2026-09-03 06:41:25 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-03T06:39:23 (1 data files) — verification/tk10066-recovery-results.jsonl","body":""},{"hash":"6f38500","date":"2026-09-02 23:44:22 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-02T23:42:20 (1 data files) — verification/tk10066-recovery-results.jsonl","body":""},{"hash":"884a4e8","date":"2026-09-02 23:32:56 -0700","author":"Steve Abrams","subject":"Refresh retained canonical owners during recovery","body":""},{"hash":"039d074","date":"2026-09-02 23:31:20 -0700","author":"Steve Abrams","subject":"Add guarded Reid Witlin recovery executor","body":""},{"hash":"1541f4d","date":"2026-09-02 22:24:41 -0700","author":"Steve Abrams","subject":"Build immutable Reid Witlin recovery manifest","body":""},{"hash":"8d6bbce","date":"2026-09-02 16:27:31 -0700","author":"Steve Abrams","subject":"Reid Witlin v2 batch: execute Steve-approved 1,005-item onboarding","body":"Live create complete: rwltd_catalog live-pid count 190 -> 1193 (1003\nnet new DRAFT products across Pool A reconfirmed-old + Pool B new-gap).\nVerified 0 duplicate mfr_sku products despite a concurrent-write\noverlap with a sibling agent's process during the run -- Shopify's\nproductSet upsert-by-handle safely merged the races.\n\n2 residual handle-collision failures (DWKR-190830, DWKR-190420) from a\npre-existing vendor-data town-mislabeling issue, non-urgent fix-later.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>"},{"hash":"39ea379","date":"2026-09-02 16:20:58 -0700","author":"Steve Abrams","subject":"Record and gate Reid Witlin draft race recovery","body":""},{"hash":"de8a372","date":"2026-09-02 16:11:23 -0700","author":"Steve Abrams","subject":"Build deduplicated Reid Witlin onboarding batch","body":""},{"hash":"c95e6e2","date":"2026-09-02 16:08:40 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-02T16:03:42 (4 data files) — create-results.json summary_v2.json targets_image_held_v2.csv targets_ready_v2.csv","body":""},{"hash":"6f25029","date":"2026-09-02 15:52:44 -0700","author":"Steve Abrams","subject":"Reid Witlin v2 batch: corrected onboarding scope post re-scrape","body":"build_batch2.py + create2.py supersede the quarantined 2026-07-30 plan\n(stale DWDQ prefix, 1071-row catalog). Two verified pools reconfirmed\nlive by the 2026-09-01 re-scrape, neither overlapping the 190 already-\nlive products:\n\n- Pool A (623 ready / 779 total): original Feb-2026 full-detail rows,\n  already carry a minted DWKR-19xxxx dw_sku, reused as-is.\n- Pool B (382 ready): brand-new colorways from the re-scrape, minted\n  DWKR-191394..191775 continuing the live band.\n\nDRY_RUN verified clean (1005 would-create, 0 errors). No Shopify or\nDB writes fired. Live create stays Steve-gated.\n\nCo-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>"},{"hash":"7aca80f","date":"2026-07-30 16:43:37 -0700","author":"Steve","subject":"Cycle 3 log + loop PAUSE idle-on-gated (safe backlog exhausted, 5/5 SHIP)","body":""},{"hash":"9dd09fa","date":"2026-07-30 16:42:17 -0700","author":"Steve","subject":"Fix preview.py %-format crash (width:100% broke str%); token-replace; regen clean preview.html","body":""},{"hash":"72892c7","date":"2026-07-30 16:41:12 -0700","author":"Steve","subject":"Cody-gate cycle3: <img> lazy+onerror (404->red card, perf), real confidence-rank sort, search incl town/colorway; dropped phantom rwltd-403 (all imgs are cdn.shopify.com/200)","body":""},{"hash":"267c9f8","date":"2026-07-30 16:38:23 -0700","author":"Steve","subject":"Cycle 3: QA preview grid (preview.py -> preview.html) — 859 ready + 22 held, sort+density per standing rule","body":""},{"hash":"709bf28","date":"2026-07-30 16:16:35 -0700","author":"Steve","subject":"Cycle 2 log: ledger (spec enrichment + 3 Cody fixes, 5/5 SHIP)","body":""},{"hash":"e62d940","date":"2026-07-30 16:14:44 -0700","author":"Steve","subject":"Cody-gate cycle2: care->specs.care (custom.cleaning was a dead wire), drop specs.type/end_use noise, single-line newline guard; keys verified vs live read-chain","body":""},{"hash":"e59eb0f","date":"2026-07-30 16:11:17 -0700","author":"Steve","subject":"Cycle 2: enrich create.py spec metafields (verified types) + fix latent custom.content product_reference 422 bug; origin->tag","body":""},{"hash":"6aa815f","date":"2026-07-30 15:45:46 -0700","author":"Steve","subject":"Cycle 1 log: memo + ledger (ready 859 / held 22, 5/5 SHIP)","body":""},{"hash":"223c348","date":"2026-07-30 15:43:08 -0700","author":"Steve","subject":"Cody-gate fixes: create.py idempotent write-back; drop mis-keyed color_name tag; vendor-JS verify all fuzzy matches (curl fetch, 403-robust); authoritative summary","body":""},{"hash":"888650d","date":"2026-07-30 15:32:03 -0700","author":"Steve","subject":"recover_held.py: vendor-JS image recovery — 167 held -> 19 (recovered 156, ready now 862)","body":""},{"hash":"b05424c","date":"2026-07-30 15:27:37 -0700","author":"Steve","subject":"rename.py: also strip 'Reid Witlin' PL-leak tag (5 products) during unification","body":""},{"hash":"3736261","date":"2026-07-30 15:24:14 -0700","author":"Steve","subject":"Add gated rename.py: unify existing 312 live Reid Witlin DWRW-210xxx -> DWDQ-210xxx","body":""},{"hash":"b6f5dcd","date":"2026-07-30 15:16:43 -0700","author":"Steve","subject":"Switch new-product SKU prefix to DWDQ (dedicated Reid Witlin band, DWDQ-100001..100881)","body":""},{"hash":"87adb75","date":"2026-07-30 15:13:38 -0700","author":"Steve","subject":"Reid Witlin onboarding: dry-run batch (714 ready + 167 held), image recovery, gated create.py","body":""}]}