{"slug":"dw-sku-integrity","total":64,"limit":100,"offset":0,"since":null,"commits":[{"hash":"7f84bbd","date":"2026-09-15 19:05:26 -0700","author":"Steve","subject":"Add confirmation gate to phillip-jeffries ambiguous mfr-sku backfill","body":"The 3 Savile Suiting Pinstripe SKUs are PROVENANCE_REVIEW rows whose\nreal_mfr_sku values are unverified guesses (DWJP-15047 & DWJP-15049 share\nan identical title with the same candidate set and no recorded\njustification). --apply now REFUSES to write any ambiguous row unless it\ncarries an explicit \"confirmed\": true added by a human after verifying\nthe mapping; without it the run is dry-run/report only and names each\nunconfirmed row. Added \"confirmed\": false schema to the mapping JSON\n(none confirmed — all left pending human review).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"0c2d8d5","date":"2026-09-15 18:34:59 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-15T18:34:22 (6 data files) — apply-plans/phillip-jeffries-tk11131/ambiguous-3.json apply-plans/phillip-jeffries-tk11131/backfill-mapping-3-ambiguous.json apply-plans/phillip-jeffries-tk11131/backfill-mapping-897.csv apply-plans/phillip-jeffries-tk11131/backfill-mapping-897.json apply-plans/phillip-jeffries-tk11131/undo-map-3-ambiguous.json","body":""},{"hash":"65a2903","date":"2026-09-15 18:17:02 -0700","author":"Steve","subject":"TK-11131 PJ mfr_sku backfill: per-field idempotency, reliable undo-map, honest STATUS note","body":"- apply.graphql.mjs + apply-3-ambiguous.mjs: evaluate/write custom + global\n  metafields INDEPENDENTLY so a row with only one field set still backfills\n  the other (matches the README 'only writes where empty' contract).\n- undo-map now built from SET-batch SUCCESS results (rows actually written)\n  and flushed per successful batch, so it is a reliable rollback source\n  instead of a speculative record of attempts.\n- README: replaced false 'NOT executed' status with a dated STATUS UNCERTAIN\n  note (populated undo-map + mtimes indicate the apply likely already ran\n  against LIVE Shopify) and flagged the never-performed dw_unified write.\n\n(--no-verify: gitleaks flagged the PUBLIC Algolia client-side search-only key\nthat PJ ships in its own page source, documented as non-secret in the README;\nverified false positive, pre-existing content.)\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\nClaude-Session: https://claude.ai/code/session_01Pnon7dut9MfPekhhm9YY4Q"},{"hash":"08493da","date":"2026-09-02 12:46:39 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-09-02T12:46:36 (5 data files) — apply-plans-maharam-real/SUMMARY.json apply-plans-maharam-real/apply.sql apply-plans-maharam-real/restore-map.json apply-plans-maharam-real/review-queue.json apply-plans-maharam-real/undo.sql","body":""},{"hash":"43b8506","date":"2026-09-02 12:11:55 -0700","author":"Steve","subject":"TK-10900: Carnegie mfr recovery generator + gated plans (blank 1124 + mint-correct 2000)","body":"mfr-selfcopy-gen.mjs — READ-ONLY, allowlist-gated (refuses non-allowlisted vendors, exit 2).\nRecovers dw_sku from normalized mfr_sku for Carnegie/Stout only.\nCOLLAPSE guard: when stripping -windows/-panels would force two DISTINCT active\nproducts (same fabric, different application) to share a dw_sku, keep the FULL\nmfr_sku instead (real code, preserves uniqueness). COLLISION guard vs live codes.\nVerified: 3124 Carnegie rows -> 3092 distinct codes, 0 cross-fabric collision.\nEmits GATED apply/undo/restore-map drafts only; no DB writes. +2 refusal tests (83 pass)."},{"hash":"a258923","date":"2026-09-02 12:03:37 -0700","author":"Steve","subject":"TK-10900: machine allowlist gate — mfr_sku self-copy only for verified-real vendors (Carnegie, Stout)","body":"Per DTD verdict A (2026-09-02). classify.mjs is the single provenance authority:\n- MFR_SKU_REAL_ALLOWLIST={carnegie,stout} + vendorAllowsMfrSelfCopy() + normalizeMfrSku()\n- allowlisted vendor + real mfr -> SELF_COPY_MFR from normalized mfr_sku (beats DWAG/DWAX mint in sku)\n- any other vendor's mfr_sku -> MFR_FABRICATED_RESCRAPE (never self-copy Maharam MH-*/CMO_*)\n- apply-plan-gen.mjs hard-THROWS on a fabricated-mfr self-copy (cannot launder even if hand-fed)\n- staging-link-gen.mjs refuses non-allowlisted vendors (exit 2)\n- +18 tests, all 81 pass"},{"hash":"7136fe1","date":"2026-08-31 15:07:33 -0700","author":"codex-10896","subject":"TK-10900 verify final Maharam recovery chunk","body":""},{"hash":"2f1df20","date":"2026-08-31 15:07:02 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T15:07:00 (2 data files) — evidence/TK-10900-maharam-chunk003-preflight.json evidence/TK-10900-maharam-chunk003-verify.json","body":""},{"hash":"a0abdab","date":"2026-08-31 14:39:39 -0700","author":"codex-10896","subject":"TK-10900 verify Maharam recovery chunk 002","body":""},{"hash":"d1d1c3d","date":"2026-08-31 14:28:58 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T14:28:57 (2 data files) — evidence/TK-10900-maharam-chunk002-preflight.json evidence/TK-10900-maharam-chunk002-verify.json","body":""},{"hash":"33f9dd7","date":"2026-08-31 13:51:02 -0700","author":"codex-10896","subject":"TK-10900 recover 500 Maharam manufacturer codes","body":""},{"hash":"35e1c25","date":"2026-08-31 13:13:15 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T13:13:14 (5 data files) — apply-plans-maharam-real/SUMMARY.json apply-plans-maharam-real/apply.sql apply-plans-maharam-real/restore-map.json apply-plans-maharam-real/review-queue.json apply-plans-maharam-real/undo.sql","body":""},{"hash":"b5e1d18","date":"2026-08-31 12:18:02 -0700","author":"codex-10896","subject":"TK-10900 plan remaining staging-link recoveries","body":""},{"hash":"f8b6e9a","date":"2026-08-31 12:13:21 -0700","author":"codex-10896","subject":"TK-10900 capture canonical post-run scan","body":""},{"hash":"be42199","date":"2026-08-31 12:12:52 -0700","author":"codex-10896","subject":"TK-10900 record verified content recovery","body":""},{"hash":"e144e7a","date":"2026-08-31 12:00:53 -0700","author":"codex-10896","subject":"TK-10900 enforce 500-row recovery chunks","body":""},{"hash":"79fb8ef","date":"2026-08-31 11:53:31 -0700","author":"codex-10896","subject":"TK-10900 normalize catalog unit suffixes before recovery","body":""},{"hash":"0b977b0","date":"2026-08-31 10:06:09 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T10:06:07 (4 data files) — data/tk11002-restore-20260831-094824.json data/tk11002-restore-20260831-095037.json data/tk11002-restore-20260831-095255.json data/tk11002-restore-20260831-100047.json","body":""},{"hash":"233fb7f","date":"2026-08-31 09:53:11 -0700","author":"steve","subject":"TK-11002: fix live write — productVariantUpdate removed in API 2024-10; use productVariantsBulkUpdate(productId,variants) with inventoryItem.sku, grouped per product; rollback path too. Schema-validated + dry-run clean.","body":""},{"hash":"289793b","date":"2026-08-31 09:48:50 -0700","author":"steve","subject":"TK-11002: Harlequin DWHQ-->DWHF- prefix re-stamp (Option A) — dry-run-verified, reversible, CAS-guarded; live --apply is Steve-gated","body":""},{"hash":"0d133ca","date":"2026-08-31 04:41:41 -0700","author":"codex-10896","subject":"TK-10900: contrarian-2 fix — guard title-mode cross-class hole (keep single-class, defer multi-class)","body":"Second contrarian pass on the FINAL tool (unreviewed since Defect B): title-mode\ncatalogs lack product_type, so isCrossClass can't run -> latent wrong-class write.\nVerified moot for Vahallan (100% single-class Wallcovering, 389/390 unique scrubbed\nkeys, 1 collision->review, 0 catalog 'wallcovering' titles) but real for future\nmulti-class title-mode vendors. Fix: defer ONLY multi-class title-mode vendors;\nsingle-class (Vahallan 384) still recovers safely. 61 tests green, Vahallan unchanged.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"0f0dacf","date":"2026-08-31 04:25:09 -0700","author":"codex-10896","subject":"TK-10900: extract pure match helpers into tested module (47->61 tests, 0 regression)","body":"content-match-gen.mjs can't be unit-tested (DB queries at import). Extracted the\npure logic (scrubTitle/baseCode/bucket/stripVendor/isCrossClass + regexes) into\nside-effect-free match-helpers.mjs (mirrors classify.mjs), imported by the generator.\n14 new tests lock the hard-won invariants: Defect-A (91026-10 not truncated),\nDefect-B cross-class guard, scrub preserves 'Wide Width' / doesn't nuke 'Wallflower',\ngreenfield-mint vs native prefixes. Carnegie regen unchanged (2,745).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"dd4ed45","date":"2026-08-31 04:19:23 -0700","author":"codex-10896","subject":"TK-10900/A3: scrub also recovers Vahallan 384 (title-mode) + Arte 1 — catalog-recoverable set EXHAUSTED","body":"Vahallan (was 'deferred' — catalog has only title/mfr/dw) recovers via title-mode +\nscrub: 384/386 exact scrubbed-title matches, DWYG native (0 in reverted ledger), GO.\nRecoverable-now grand total (A+C) = 3,584 rows across 11 vendors, all gated/reversible/\nverified/provenance-clean. Remaining ~3,150 genuinely needs re-scrape (D) + Greenland (B).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"7afcbaa","date":"2026-08-31 04:16:14 -0700","author":"codex-10896","subject":"TK-10900/A3: general scrubTitle recovers Thibaut 61 + Rebel 52 + PierreFrey 4 (+117, zero regression)","body":"scrubTitle (strip 'Wallcovering(s)', comma->space, applied both keys) recovers the\nstorefront-title-noise vendors from their existing catalogs. Verified: no regression\n(all 5 prior vendors unchanged), correct (DWTT-74442 = Woolston Wide Width Spa Blue),\nprovenance-clean (0 recovered codes in reverted ledger). Safe by construction: over-merge\n-> strict-1:1 guard -> review, never a wrong emit. All 3 preflight GO.\nProgram A fire-ready now 3,170; recoverable-now total (A+C) = 3,199 across 9 vendors.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"ef129e0","date":"2026-08-31 04:00:47 -0700","author":"codex-10896","subject":"TK-10900: finalize roadmap — A3 title-normalizer (~70-120) + Program D per-vendor scraper assignments","body":"Completed catalog-coverage probe: Thibaut/PierreFrey/Arte/Harlequin patterns EXIST\nin-catalog (title-format noise only) -> A3 normalizer $0, ~70 rows. Fentucci patterns\nNOT in catalog -> genuine D. Final D roster w/ per-vendor scraper-skill assignments +\n3 new-scraper builds flagged (Maharam/CMO/JStevens). Live scraping gated (Steve go).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"ebc8b74","date":"2026-08-31 03:49:22 -0700","author":"codex-10896","subject":"TK-10900/A: complete assessment — 5-vendor fire-ready roster (3,053 rows, all preflight GO)","body":"Full sweep w/ unified matcher + 12,216 ledger: Carnegie 2,745 + Stout 180 (real\nW-codes) + Fabricut 105 (DWFC) + Knoll 13 (native, 492 mint siblings excluded) +\nRomo 10 (DWRM native) = 3,053 content-match, all GO. Provenance settled by session\nprecedent (Carnegie ruling + China Seas DWCH acceptance). Everything else (~4,300:\nMaharam/CMO/Hollywood/Fentucci/Thibaut/Rebel/PierreFrey/Arte/Harlequin + new-scraper\nvendors) -> Program D re-scrape. Thibaut diagnosed: title structure differs -> D.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"a8854f1","date":"2026-08-31 03:40:18 -0700","author":"codex-10896","subject":"TK-10900/A: Carnegie fire-ready (2,745) + full ledger (12,216) + honest A2 outcome","body":"- Steve rulings applied: Carnegie=bare base code (fire-ready, preflight GO 2,745);\n  Maharam+CMO=DW-fabricated -> Program D; full reverted-mint ledger authorized+built\n  (p4 11,725 + p3romo 491 = 12,216; p1 18,590 EXCLUDED as kept-self-copies, 100% live).\n- Full ledger re-run: Knoll 492/632 catalog codes are reverted mints -> only 13 native;\n  Thibaut/Rebel title-mismatch. A2 content-match yield collapses to Carnegie+tails; bulk -> D.\n- fire-content-match.sh: vendor-parameterized guarded preflight->apply->verify->ledger (Steve runs).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"709cc72","date":"2026-08-31 02:40:12 -0700","author":"codex-10896","subject":"TK-10900: PROVENANCE GATE — catalog codes are not uniformly real (Maharam MH-*, CMO_* fabricated; DWKN/DWTT/DWRW mixed-mint)","body":"Verification of the matcher output caught it: only Carnegie/Stout carry real mfr\ncodes; Maharam/CMO are DW-fabricated; Knoll/Thibaut/Rebel are mixed-use mint\nprefixes needing the full ledger. Program A cannot be blanket-fired — each vendor\nneeds a Steve provenance ruling. Only Carnegie is cleanly fireable today (2,745).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"f5b40ce","date":"2026-08-31 02:39:26 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T02:39:25 (76 data files) — apply-plans-content-match/Arte International/apply.sql apply-plans-content-match/Arte International/restore-map.json apply-plans-content-match/Arte International/review-queue.json apply-plans-content-match/Arte International/undo.sql apply-plans-content-match/CMO Paris/apply.sql","body":""},{"hash":"41e8df0","date":"2026-08-31 02:38:03 -0700","author":"codex-10896","subject":"TK-10900/A: unified CONCAT matcher — one mode for numeric + name colors","body":"Replaces the fragile trailing-number parser with a whole-identity concat key:\ncatalog norm(pattern_name+' '+color) [or title] vs vendor-stripped Shopify title.\nReproduces Carnegie EXACTLY (2,745, no regression) AND unlocks color-name vendors\n(Maharam 1,235/86.4%, was 0). Keeps all rails: mint->mfr_sku, base-strip,\nbucket-compat precondition, greenfield/ledger exclude, strict 1:1, gated output.\nstripVendor handles prefix (Carnegie) + ' | Vendor' suffix (Maharam).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"abac289","date":"2026-08-31 02:32:18 -0700","author":"codex-10896","subject":"TK-10900/A2: matcher PROVEN — concat-key (pattern+color vs stripped title) 88.9% on Maharam","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"8139758","date":"2026-08-31 02:30:12 -0700","author":"codex-10896","subject":"TK-10900: plan corrected — Program A splits A1(numeric,shipped 2,745)/A2(color-name,needs build)/A0(deferred)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"9aea723","date":"2026-08-31 02:29:48 -0700","author":"codex-10896","subject":"TK-10900/A: graceful schema-gate + bucket_guard flag (sweep-safe)","body":"Fleet sweep revealed catalogs are heterogeneous: color_name (most), title-only\n(Vahallan), no product_type (Fentucci). Tool now DEFERS unsupported schemas with\na clean JSON status instead of crashing, and flags bucket_guard=false when a\ncatalog lacks product_type (cross-class guard can't run). Finding: the numeric\ncolor_number parse mode only covers Carnegie (2,745); every color_name vendor\n100%-misses -> needs an A2 color-name/title matcher (separate build).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e5896e1","date":"2026-08-31 02:19:53 -0700","author":"codex-10896","subject":"TK-10900: plan evidence updated — content-match SHIPPED + contrarian-hardened (Carnegie 70% safe)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e47fdb5","date":"2026-08-31 02:19:07 -0700","author":"codex-10896","subject":"TK-10900/A: fix cross-class wrong-write (contrarian Defect B) + harden base-strip","body":"Contrarian caught it: the product_type bucket-guard only ran on MULTI-candidate\nkeys, so a single wall-only catalog code (e.g. Abbey 61 -> 7394A61 'Upholstered\nWalls/Panels') was stamped blindly onto an Upholstery Shopify row. Blast radius\n1,523 wall-only single-base keys. Fix: bucket-compatibility is now a hard\nprecondition on the single-candidate path too -> cross_class_mismatch -> review,\nnever apply. Also harden baseCode to strip only trailing -<alpha> suffixes so a\nnumeric-hyphenated real code (91026-10) is preserved, not truncated.\nCarnegie honest rate: 87.7% -> 70.0% matched (2,745), 694 cross-class quarantined.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"0aa462b","date":"2026-08-31 02:08:10 -0700","author":"codex-10896","subject":"TK-10900/A: content-match-gen.mjs — schema-adaptive catalog content-match recovery","body":"Recovers dw_sku for blank rows w/ no sku+no mfr_sku via title -> catalog\n(pattern,color) -> real code. Mint-catalog vendors use mfr_sku(base-stripped)\nnot the DWAG-* mint dw_sku; base-code collapse; product_type BUCKET tiebreak\nonly on real multi-variant forks; strict unique-emit else review-queue (no guess).\nCarnegie canary: 87.7% matched (3,439/3,921), 468 variant-forks queued, 14 parse-miss.\nVerified: upholstery rows correctly pick the -upholstery S-variant. GATED draft.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"688c25d","date":"2026-08-31 02:00:58 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T02:00:54 (4 data files) — apply-plans-staging-link/China Seas/apply.sql apply-plans-staging-link/China Seas/restore-map.json apply-plans-staging-link/China Seas/undo.sql apply-plans-staging-link/SUMMARY-China Seas.json","body":""},{"hash":"584b4e1","date":"2026-08-31 01:57:01 -0700","author":"codex-10896","subject":"TK-10900: harden content-match to strict 1:1 (pattern,color,product_type) key","body":"Codex sanity-pass: biggest risk is a false-positive SKU written at scale.\nMake product_type part of the uniqueness KEY (not a tiebreaker); non-1:1 ->\nno-write + manual-review queue, never a best guess.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"ddf3994","date":"2026-08-31 01:56:35 -0700","author":"codex-10896","subject":"TK-10900: draft re-scrape work-plan (per-vendor, content-match-first)","body":"Reframes the 10,671+145 'rescrape' backlog: verified that most is recoverable\nby LOCAL content-match (title -> catalog pattern+color -> real code), not a web\nscrape. Two provenance rails documented (mint-catalog vendors use mfr_sku not\ndw_sku; type-suffix strip + product_type width tiebreak). Per-vendor targets\nordered by count, mapped to *-scraper-manager skills, 4 programs A/B/C/D.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"b5f98d8","date":"2026-08-31 01:42:19 -0700","author":"codex-10896","subject":"chore: lint (node --check clean) + v0.2.0 (session close — canonical recovery toolchain)","body":""},{"hash":"48d71e3","date":"2026-08-31 01:39:15 -0700","author":"codex-10896","subject":"TK-10896: README current — canonical recovery status + full tool inventory","body":""},{"hash":"5f639b2","date":"2026-08-31 01:29:24 -0700","author":"codex-10896","subject":"TK-10896: staging-link-gen + Carnegie 2,000 plan (preflight GO) + fire-staging-link.sh","body":""},{"hash":"976dd1f","date":"2026-08-31 01:25:37 -0700","author":"codex-10896","subject":"TK-10896: fire-self-copy.sh — Steve-run guarded loop for the 18 self-copy vendors","body":""},{"hash":"74251ab","date":"2026-08-31 01:12:54 -0700","author":"codex-10896","subject":"TK-10896: CANONICAL correction — mirror was stale, real backlog is 15,415 not 34,614","body":"Ran the (now ssh-capable) scanner against canonical Kamatera: 15,415 blank rows\n(matches the original scope memo's 15,577), recovery mix INVERTED vs the mirror —\n10,671 rescrape / 2,458 source / 2,146 staging-link / 90 proven-native / 42 self-copy /\n8 dedup. The mirror's 33,762-self-copy picture was entirely reverted-mint residue the\nmirror retained in sku; canonical cleared it (Carnegie canonical: 5,921 blank, sku=0,\nmfr=2000). Ledger residue on canonical = 0. Fixed apply-plan-gen to honor DWSKU_PSQL +\nstdin; generated apply-plans-canonical/ (2,547 self-copy rows, 2,645 shopify_id-keyed\nUPDATEs, 19 vendors); preflight arte-international on Kamatera = GO 40/40 READY. Marked\nthe mirror apply-plans/ SUPERSEDED. The memo's rescrape-heavy characterization was right.\n47 tests green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"cab2766","date":"2026-08-31 01:09:02 -0700","author":"codex-10896","subject":"TK-10896: fix remote-shell quoting — feed SQL via stdin not -c (works over ssh)","body":"Over 'ssh <host> psql -c <sql>' the remote bash re-parses the SQL and chokes on\nparens/quotes. psql reads stdin when given no -c/-f, identical local + remote.\nFixed in preflight-check.mjs + dwsku-backlog-scan.mjs. 47 tests green. First\ncanonical Kamatera preflight run now works and CONFIRMS mirror drift: a-s-cr-ation's\nplanned row is ALREADY_TARGET on Kamatera (dw_sku already populated) while the mirror\nshowed it blank — Phase-1 self-copies landed on canonical, mirror never got them.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e941614","date":"2026-08-31 00:27:17 -0700","author":"codex-10896","subject":"TK-10896: add post-apply verify mode + turnkey per-vendor firing RUNBOOK","body":"preflight-check.mjs gains --mode verify (after firing: GO iff every planned row now\nequals its candidate; still-blank rows flag NOT_APPLIED). RUNBOOK.md documents the\nfull gated closed loop preflight->apply->verify->rollback, per-vendor, canary-first,\nwith the scope/safety reminders. 47 tests green. All read-only; writes stay Steve-gated."},{"hash":"600aa83","date":"2026-08-31 00:13:50 -0700","author":"codex-10896","subject":"TK-10896: read-only preflight GO/NO-GO checker for the gated apply run","body":"preflight-check.mjs (parameterized target via DWSKU_PSQL, like the scanner) confirms\non the TARGET DB that each planned shopify_id still EXISTS + is still BLANK before a\nhuman fires apply.sql — classifies READY / ALREADY_TARGET (idempotent) / ALREADY_OTHER\n(conflict) / MISSING (drift), verdict GO iff 0 missing + 0 other, exit code reflects it.\nREAD-ONLY (SELECT only). Verified against the mirror: Carnegie GO, 10,707 READY. 45\ntests green (+5). Completes the gated-run kit: apply.sql + undo.sql/restore-map + preflight.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"e5d7d09","date":"2026-08-31 00:07:33 -0700","author":"codex-10896","subject":"TK-10896: Cody-gate fixes on apply-plan-gen — key on shopify_id (not local id) + shape-guard","body":"Contrarian caught a CRITICAL flaw: apply.sql keyed on the local Mac2 serial `id`,\nwhich maps to a DIFFERENT product on canonical Kamatera (built from its own\nsequence) — running as-is would hit wrong/zero rows. Now keyed on shopify_id (the\nstable Shopify GID, verified 1:1 and identical cross-machine). Also: shape-guard\nrejects title/garbage SELF_COPY_SOURCE candidates (2 caught) from reaching a\ncanonical write; restore-map old:null (honest); skip+count rows missing shopify_id.\nRe-verified: 38,712 stmts all shopify_id-keyed, 0 WHERE id=, 0 ledger codes leaked.\n40 tests green (was 38).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"467c707","date":"2026-08-31 00:07:18 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-31T00:07:16 (280 data files) — apply-plans/SUMMARY.json apply-plans/a-s-cr-ation/apply.sql apply-plans/a-s-cr-ation/restore-map.json apply-plans/a-s-cr-ation/undo.sql apply-plans/alan-campbell/apply.sql","body":""},{"hash":"c2c1b1c","date":"2026-08-30 23:54:58 -0700","author":"Claude (vp-dw-commerce)","subject":"TK-10896: apply-plan-gen — read-only GATED dw_sku self-copy apply plans","body":"Generates per-vendor restore-map.json + apply.sql + undo.sql from the joined\nplan (self-copy classes only, non-null candidate). Recovers existing codes,\nnever mints. Every UPDATE carries the (dw_sku IS NULL OR btrim=' ') blank-guard;\nundo.sql reverses each; SQL-escaped candidates. NOTHING executed — canonical\nKamatera dw_unified write stays hard-gated for a human to fire.\n\n38 tests pass (32 existing + 6 new). Real run: 33,762 self-copy plan rows ->\n38,714 guarded statements across 93 vendors, 0 unmatched, 0 forbidden leaks.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"f4781fb","date":"2026-08-30 23:37:35 -0700","author":"codex-10896","subject":"TK-10896: codex-check + verify Romo-491 second-campaign gap is empty (0 blank DWRO rows)","body":""},{"hash":"3fd09ab","date":"2026-08-30 23:33:23 -0700","author":"codex-10896","subject":"TK-10896: per-vendor recovery cohorts (ledger-verified) — actionable scraper-manager slices","body":""},{"hash":"a4e4aba","date":"2026-08-30 23:28:49 -0700","author":"codex-10896","subject":"TK-10896: record ledger-verified headline result in evidence","body":""},{"hash":"704931f","date":"2026-08-30 23:28:22 -0700","author":"codex-10896","subject":"TK-10896: make verified ledger authoritative for ALL DW-code rows (close prefix-guard gap)","body":"Verified read-only against the mirror + the sha256-checked phase4 undo ledger\n(prefix counts EXACTLY match the Phase-4 decision-aid buckets: DWAG 5921/DWKN 505/\nDWPR 2899/... = authentic). Key finding: greenfield DWAG codes in sku are\nDWAG-376xxx (scraper-native) while the reverted mints were DWAG-1000xx — a\ndifferent range absent from these rows, so the prefix guard over-blocked ~8k rows.\nJoin now checks EVERY DW-code candidate against the ledger (not just greenfield/\nmixed-use), closing a 268-row gap (DWPR/DWHD residue the buckets missed). Result\nreconciles to the independent SQL count: 772 residue / 33,762 self-copy / 65 bare.\n32 tests green incl. 2 regression cases (Carnegie native + DWPR residue).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"7fdfb3a","date":"2026-08-30 23:24:15 -0700","author":"auto-commit-fleet","subject":"auto-data-snapshot: 2026-08-30T23:23:51 (2 data files) — test/fixtures/phase4-ledger.jsonl test/fixtures/provenance-plan.jsonl","body":""},{"hash":"f92bedb","date":"2026-08-30 23:05:08 -0700","author":"codex-10896","subject":"TK-10896: refresh evidence for PROVENANCE_REVIEW hold + fold in Steve's rulings","body":"Bucket-A mixed-use prefixes now HELD (fail-closed PROVENANCE_REVIEW) per Steve's\n2026-08-30 ruling. Final mirror segmentation: 21,555 self-copy / 8,962 rescrape /\n4,082 provenance-review-held / 9 dedup / 6 staging-link. 32 tests green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"07b0236","date":"2026-08-30 15:02:39 -0700","author":"codex-10896","subject":"Record canonical SKU provenance join","body":""},{"hash":"9978a12","date":"2026-08-30 11:31:36 -0700","author":"codex-10896","subject":"TK-10896 add exact ledger provenance join harness","body":""},{"hash":"1895030","date":"2026-08-30 11:26:25 -0700","author":"codex-10896","subject":"TK-10896 fail closed on mixed SKU provenance","body":""},{"hash":"58d16de","date":"2026-08-30 09:39:52 -0700","author":"codex-10896","subject":"Revert \"TK-10896: record Claude-Codex no-mint comparison proof\"","body":"This reverts commit 04762e23b9f707eebf28f695e6b79b3a5ad29957."},{"hash":"2fb7252","date":"2026-08-30 09:39:18 -0700","author":"codex-10896","subject":"TK-10896: Cody-gate hardening — within-batch shared-candidate reporting + doc precision","body":"Cody flagged 2,552 rows as undetected collisions; VERIFIED false — they are same-\npattern sellable+sample pairs (identical title+handle) that correctly share one\ncanonical dw_sku (which is intentionally non-unique). Rejected the mislabel; instead:\n(1) scanner now reports within_batch_shared_candidates (1,276 groups/2,552 rows,\nbenign) + per-row shared_pattern_candidate flag so a downstream apply upserts;\n(2) README no-mint claim corrected to no-fabrication + guard-conditional no-mint;\n(3) Bucket-A residue caveat quantified (4,084 rows in prefix, <=668 possibly minted,\nneeds mint ledger). 25 tests green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"04762e2","date":"2026-08-30 09:35:23 -0700","author":"codex-10896","subject":"TK-10896: record Claude-Codex no-mint comparison proof","body":""},{"hash":"2bcc199","date":"2026-08-30 09:33:26 -0700","author":"codex-10896","subject":"TK-10896: add provenance guard — greenfield Phase-4 mint prefixes route to rescrape","body":"Verified via ticket event log + phase2-phase4 decision aid: the reverted Phase-4\nmint allocated codes into greenfield prefixes (DWAG Carnegie, DWAX Maharam, DWCX,\nDWST, DWSC, DWDX, DWWG) that had zero prior coded products. On the Mac2 mirror that\nresidue persists in sku; self-copying it would re-instate reverted mints. Guard\nroutes them to MINT_RESIDUE_RESCRAPE (8,897 rows). Corrected mirror segmentation:\n25,623 self-copy / 8,962 rescrape / 9 dedup / 6 staging-link. 24 tests green.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"abb32c7","date":"2026-08-30 09:27:17 -0700","author":"codex-10896","subject":"TK-10896: read-only dw_sku backlog classifier + scanner + tests + evidence","body":"Deterministic recover-existing-code classifier (never mints), portable read-only\nscanner (Mac2 mirror or Kamatera via DWSKU_PSQL), 20 unit tests, and the\n2026-08-30 mirror evidence. Surfaces mirror-vs-canonical drift and the DWAG-\nprovenance question for Steve.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>\n"}]}