[object Object]

← back to Sample Followup Sweep

auto-data-snapshot: 2026-09-23T13:45:21 (2 data files) — data/contacts.json.bak-20260923-131934-TK12085 scripts/send-reconciled.mjs.bak-20260923-131934-TK12085

20ca7a94d092536cb1fd506bd862e63cf781d2e4 · 2026-09-23 13:45:27 -0700 · auto-commit-fleet

Files touched

Diff

commit 20ca7a94d092536cb1fd506bd862e63cf781d2e4
Author: auto-commit-fleet <steve@designerwallcoverings.com>
Date:   Wed Sep 23 13:45:27 2026 -0700

    auto-data-snapshot: 2026-09-23T13:45:21 (2 data files) — data/contacts.json.bak-20260923-131934-TK12085 scripts/send-reconciled.mjs.bak-20260923-131934-TK12085
---
 data/contacts.json.bak-20260923-131934-TK12085     | 377 +++++++++++++++++++++
 ...send-reconciled.mjs.bak-20260923-131934-TK12085 |  99 ++++++
 2 files changed, 476 insertions(+)

diff --git a/data/contacts.json.bak-20260923-131934-TK12085 b/data/contacts.json.bak-20260923-131934-TK12085
new file mode 100644
index 0000000..6ef5aae
--- /dev/null
+++ b/data/contacts.json.bak-20260923-131934-TK12085
@@ -0,0 +1,377 @@
+{
+  "dgd": {
+    "name": "Designers Guild @ Osborne & Little",
+    "sample_email": "Polancol@oalusa.com",
+    "account_number": "1433803"
+  },
+  "osb": {
+    "name": "Osborne & Little",
+    "sample_email": "Polancol@oalusa.com",
+    "account_number": "1433803"
+  },
+  "wq": {
+    "name": "WallQuest / Malibu",
+    "sample_email": "orders@wallquest.com",
+    "account_number": "651317"
+  },
+  "thi": {
+    "name": "Thibaut",
+    "sample_email": "cathy.dy@thibautdesign.com",
+    "account_number": "0108751"
+  },
+  "thib": {
+    "name": "Thibaut",
+    "sample_email": "cathy.dy@thibautdesign.com",
+    "account_number": "0108751"
+  },
+  "pj": {
+    "name": "Phillip Jeffries",
+    "sample_email": "jballard@phillipjeffries.com",
+    "account_number": "On File"
+  },
+  "mor": {
+    "name": "Morris & Co",
+    "sample_email": "Sample@jaspershowroom.com",
+    "account_number": "On File"
+  },
+  "yor": {
+    "name": "York",
+    "sample_email": "RiveraH@yorkwall.com, orders@yorkwall.com",
+    "account_number": "34328"
+  },
+  "qua": {
+    "name": "Quadrille",
+    "sample_email": "Rhaiza@quadrilleinc.com",
+    "account_number": "37017"
+  },
+  "sca": {
+    "name": "Scalamandre",
+    "sample_email": "FLOVOS@scalamandre.com",
+    "account_number": "595234"
+  },
+  "kra": {
+    "name": "Kravet",
+    "sample_email": "matt.schoffman@kravet.com",
+    "account_number": "10087117"
+  },
+  "kor": {
+    "name": "Koroseal",
+    "sample_email": "samples@koroseal.com, sshortino@koroseal.com",
+    "account_number": "580270"
+  },
+  "bre": {
+    "name": "Brewster",
+    "sample_email": "brewsterorders@brewp.com",
+    "account_number": "6003784"
+  },
+  "brewster": {
+    "name": "Brewster",
+    "sample_email": "brewsterorders@brewp.com",
+    "account_number": "6003784"
+  },
+  "green": {
+    "name": "Greenland (bmwallpaper)",
+    "sample_email": "sales@bmwallpaper.com",
+    "account_number": "On File"
+  },
+  "astsand": {
+    "name": "Astek",
+    "sample_email": "amy.d@astek.com",
+    "account_number": "SAND001"
+  },
+  "arte-international": {
+    "name": "Arte (@ Egg & Dart)",
+    "sample_email": "Therese@egg-and-dart.com",
+    "account_number": "On File"
+  },
+  "pin": {
+    "name": "Pindler & Pindler",
+    "sample_email": "LosAngelesShowroom@pindlercorp.com",
+    "account_number": "696636"
+  },
+  "maya": {
+    "name": "Maya Romanoff",
+    "sample_email": "ari@quintushome.com",
+    "account_number": "On File"
+  },
+  "twi": {
+    "name": "twill (Karin Klein)",
+    "sample_email": "karinkleintextiles@gmail.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George: Karin Klein <karinkleintextiles@gmail.com> active sample-request replies 8/2026 (Steve screenshot: VID Twi, Karin Klein Textiles)"
+  },
+  "olp": {
+    "name": "Olivia & Poppy",
+    "sample_email": "info@oliviaandpoppy.com",
+    "account_number": "On File"
+  },
+  "san": {
+    "name": "Sancar (AS Cr\u00e9ation) \u2014 inferred",
+    "sample_email": "sales@sancarwallcovering.com",
+    "account_number": "1674444"
+  },
+  "chin": {
+    "name": "China Seas by Quadrille \u2014 inferred",
+    "sample_email": "Rhaiza@quadrilleinc.com",
+    "account_number": "37017"
+  },
+  "jofa": {
+    "name": "Lee Jofa (Kravet family) \u2014 inferred",
+    "sample_email": "matt.schoffman@kravet.com",
+    "account_number": "10087117"
+  },
+  "con": {
+    "name": "Concertex",
+    "sample_email": "info@concertex.com",
+    "account_number": "On File"
+  },
+  "sand": {
+    "name": "Sanderson Design Group \u2014 Zoffany/William Morris @ Jasper Showroom",
+    "sample_email": "Sample@jaspershowroom.com",
+    "account_number": "On File"
+  },
+  "sandb": {
+    "name": "Sandberg (via Gimmersta US)",
+    "sample_email": "support@gimmersta.com",
+    "account_number": "On File"
+  },
+  "rbl": {
+    "name": "Rebel Walls (via Gimmersta US)",
+    "sample_email": "support@gimmersta.com",
+    "account_number": "On File"
+  },
+  "spn": {
+    "name": "Spoonflower (online \u2014 no rep desk)",
+    "disposition": "no-chase",
+    "disposition_reason": "online print-on-demand \u2014 no sample-order desk to email (vendor type has no rep)",
+    "disposition_set": "2026-08-15"
+  },
+  "pf": {
+    "name": "Pierre Frey",
+    "sample_email": "hbarragan@kneedlerfauchere.com",
+    "account_number": "On File",
+    "contact_source": "DW Sent history \u2014 Kneedler Fauch\u00e8re (PF LA rep), order correspondence 2026-08-12; CONFIRM before send"
+  },
+  "rad": {
+    "disposition": "no-chase",
+    "disposition_reason": "item Dig-4350114V shares Spoonflower DIG- digital-print prefix \u2014 POD/no sample desk (INFERRED; reverse if RAD is a real chaseable vendor)",
+    "disposition_set": "2026-08-15",
+    "sample_email": "scott@radfordgraphics.com, jason@radfordgraphics.com"
+  },
+  "wol": {
+    "name": "Wolf Gordon",
+    "sample_email": "samples@wolfgordon.com",
+    "account_number": "149713",
+    "needs_confirm": true,
+    "contact_source": "George: dedicated sample desk samples@wolfgordon.com, sample-request confirmations Aug 2026"
+  },
+  "romo": {
+    "name": "Romo",
+    "sample_email": "fawn.bowen@romo.com",
+    "account_number": "223641",
+    "needs_confirm": true,
+    "contact_source": "George: Fawn Bowen, Sampling Coordinator, memo corr 8/17/2026"
+  },
+  "inn": {
+    "name": "Innovations",
+    "sample_email": "hmartinez@innovationsusa.com",
+    "account_number": "58315",
+    "needs_confirm": true,
+    "contact_source": "George: Hektor Martinez showroom, sample corr 8/17/2026 (acct Net Less 20%)"
+  },
+  "dtex": {
+    "name": "Designtex",
+    "sample_email": "samples@designtex.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George: Donna Dawson, Representative (LA), price-check corr 8/6/2026 \u2014 rep not sample desk, CONFIRM"
+  },
+  "mom": {
+    "name": "Momentum (\u2192Hollywood, INTERNAL chase only)",
+    "sample_email": "ddedic@momtex.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George: momtex sample-shipped notices Aug 2026; PRIVATE-LABEL, never customer-facing"
+  },
+  "ver": {
+    "name": "Versace (via Sancar)",
+    "sample_email": "sales@sancarwallcovering.com",
+    "account_number": "1674444",
+    "needs_confirm": true,
+    "contact_source": "George: 'sancar (VERSACE)' memo 8/17/2026 \u2014 Versace ordered through Sancar desk"
+  },
+  "sch": {
+    "name": "Schumacher (F. Schumacher)",
+    "disposition": "no-chase",
+    "disposition_reason": "self-service online sample ordering; only noreply@mailer.fschumacher.com exists \u2014 no rep desk to chase (George-verified 8/20)",
+    "disposition_set": "2026-08-20",
+    "sample_email": "la-samples@schumacher.com"
+  },
+  "sir": {
+    "name": "Sir Edward",
+    "sample_email": "sales@sir-edward.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): D\u00e9sir\u00e9e Ouweneel <sales@sir-edward.com>, active sample/sales corr; DWFM40xxx file-requested art items"
+  },
+  "cow": {
+    "name": "Cowtan & Tout / Colefax & Fowler / Jane Churchill",
+    "sample_email": "la_sample@cowtan.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): LA Sample <la_sample@cowtan.com> replies to New Sample Request; DWPD Cowtan/Colefax/JaneChurchill patterns"
+  },
+  "bm": {
+    "name": "B&M Wallpaper (Nora / Greenland factory)",
+    "sample_email": "sales@bmwallpaper.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): 'NORA & GREENLAND' <sales@bmwallpaper.com> already replies to our sample follow-ups; GRS/HLW woven-texture SKUs"
+  },
+  "amer": {
+    "name": "American Silk Mills (SolidSensuede)",
+    "sample_email": "crystal.guard@americansilk.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): Crystal Guard <crystal.guard@americansilk.com> replies to New Sample Request; SDP SolidSensuede SKUs"
+  },
+  "egg": {
+    "name": "Egg & Dart (Arte distributor)",
+    "sample_email": "therese@egg-and-dart.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): Therese Stachowiak <therese@egg-and-dart.com>, same desk as arte; BEC SKU"
+  },
+  "coor": {
+    "name": "Coordonn\u00e9 (via NewWall)",
+    "sample_email": "tricia@newwall.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): Tricia Robb <tricia@newwall.com> handles NWD/Coordonn\u00e9; DWDC 'Bike ride Fawn' A00907"
+  },
+  "christian-lacroix-europe": {
+    "name": "Christian Lacroix (via Osborne & Little / Designers Guild)",
+    "sample_email": "Polancol@oalusa.com",
+    "account_number": "1433803",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): CL is a Designers Guild/O&L brand; Leandra Polanco <Polancol@oalusa.com> is our O&L sample desk; PCL codes EUR prefix"
+  },
+  "hyg": {
+    "name": "Hygge & West",
+    "sample_email": "info@hyggeandwest.com",
+    "account_number": "On File",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): only Hygge & West address on file is support@hyggeandwest.com (marketing/support); DWHW2 'Be Good' SKU \u2014 CONFIRM it accepts trade sample requests"
+  },
+  "fol": {
+    "name": "Folia Fabrics (RETIRED)",
+    "disposition": "no-chase",
+    "disposition_reason": "Folia source decommissioned 2026-08-18 (folia-scraper retired); Ralph LWP items were Folia-distributed \u2014 no live desk to chase",
+    "disposition_set": "2026-08-20",
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns)",
+    "sample_email": "customerservice@folia-fabrics.com"
+  },
+  "phillipe-romano": {
+    "name": "Phillipe Romano (private label)",
+    "disposition": "no-chase",
+    "disposition_reason": "DW private label (Command54/RIGO/Justin David umbrella) \u2014 internal only, never chase a customer-facing vendor desk; PI-ACOUSTIC DWPN SKU",
+    "disposition_set": "2026-08-20",
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns)"
+  },
+  "carl": {
+    "name": "Carlsten / Desima (private label, archived)",
+    "disposition": "no-chase",
+    "disposition_reason": "Carlsten/Desima private-label line (Steve: Desima/Kravet); TTF Capitone items \u2014 archived line, no live sample desk",
+    "disposition_set": "2026-08-20",
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns)"
+  },
+  "ftr": {
+    "name": "(unresolved) metallic-leaf vendor \u2014 GLM/GLMG SL08/B20 gunmetal/bronze/copper codes",
+    "needs_confirm": true,
+    "unresolved_email": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): no vendor identity found in George; metallic/gilded-leaf line, distributor unknown",
+    "sample_email": "ftg1@futuretextiles.com"
+  },
+  "ulr": {
+    "name": "Ulrich Welter",
+    "needs_confirm": true,
+    "unresolved_email": false,
+    "sample_email": "info@welter-wandunikate.de",
+    "confidence": "HIGH",
+    "contact_source": "TK-11524 (worker-w03, 2026-09-12) George/Gmail resolution: Ulrich Welter = Welter Wandunikate (DW flock-velvet 'Austrian Prince' / glass-bead mfr). Address info@welter-wandunikate.de confirmed via Gmail msg 17e4fa0f0ecd5b7d \u2014 a two-way DW<->Ulrich order/cost/shipping thread (Ulrich emailed FROM this address to info@designerwallcoverings.com). Held needs_confirm:true pending Steve's confirm per the standing convention before it can draft."
+  },
+  "tbd": {
+    "name": "(placeholder — unidentified vendor)",
+    "disposition": "no-chase",
+    "disposition_reason": "TK-11524 (worker-w03, 2026-09-12): vid 'TBD' is a FileMaker data-entry placeholder, not a real vendor — there is no sample desk to chase. The durable fix is correcting the vid on the source memo in FileMaker (a canonical FM write, gated/out-of-scope for this data-hygiene pass). Dispositioned so the empty sample_email is EXPECTED, not a phantom gap.",
+    "disposition_set": "2026-09-12"
+  },
+  "1838-wallcoverings": {
+    "name": "1838 Wallcoverings",
+    "needs_confirm": true,
+    "unresolved_email": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): real line (1838-scraper-manager); likely distributed via Maxwell Fabrics (distribution@postmark.pdfsystems.com is order-only, not a sample desk) \u2014 no inbound sample-desk contact captured; CONFIRM the 1838/Maxwell sample email",
+    "sample_email": "scott.myer@gmail.com",
+    "account_number": "On File"
+  },
+  "bar": {
+    "name": "Barneby Gates",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail 2026-09-15: active DW vendor (live PO thread 101832; invoices SI-32897/SI-32880 in GBP). studio@=order/PO desk, alice@Gates=dispatch. Steve chose BOTH recipients 2026-09-15 (TK sample-followup vendor re-attribution). account On File; CONFIRM DW acct# + true sample desk.",
+    "sample_email": "studio@barnebygates.com, alice@barnebygates.com",
+    "account_number": "On File"
+  },
+  "poi": {
+    "name": "Pointe (via Justin David private label)",
+    "needs_confirm": true,
+    "unresolved_email": true,
+    "contact_source": "George/Gmail mining 2026-08-20 (grounded on live outstanding-memo Mfr Patterns): PI- codes DWPR/DWPN, 'from pointe'; Justin David desk jackie@justindavid.com is the likely source but POI may be an internal PR/JD private-label \u2014 CONFIRM whether to chase externally at all",
+    "sample_email": "samples@justindavid.com",
+    "account_number": "On File"
+  },
+  "paul": {
+    "name": "Paul Montgomery",
+    "sample_email": "info@paulmontgomery.com",
+    "account_number": "1045144",
+    "contact_source": "George/Gmail mining 2026-08-25 (grounded on live outstanding-memo Mfr Patterns + account#); confirmed 'New Sample Request for Designer Wallcoverings' thread"
+  },
+  "mdc": {
+    "name": "MDC Wallcoverings",
+    "sample_email": "sample@mdcwall.com",
+    "account_number": "1062427",
+    "note": "private-label as Phillipe Romano; chase real vendor MDC (internal)",
+    "contact_source": "George/Gmail mining 2026-08-25 (grounded on live outstanding-memo Mfr Patterns + account#); MDC Customer Service <cs@mdcwall.com>"
+  },
+  "eli": {
+    "name": "Elitis (USA \u2014 Annalisa Dominguez)",
+    "main_email": "ANNALISA@elitis.us",
+    "account_number": "1062120",
+    "needs_confirm": true,
+    "contact_source": "Steve-corrected 2026-08-25: sent to Elitis USA rep Annalisa <ANNALISA@elitis.us> (not France HQ contact@elitis.fr)",
+    "sample_email": "annalisa@elitis.us"
+  },
+  "lin": {
+    "name": "Lincrusta",
+    "main_email": "rebecca.cragg@lincrusta.com",
+    "account_number": "1062465",
+    "needs_confirm": true,
+    "contact_source": "George/Gmail mining 2026-08-25 (grounded on live outstanding-memo Mfr Patterns + account#); active rep Rebecca Cragg (corr. through 8/18/2026) \u2014 main/rep fallback per Steve 8/25",
+    "sample_email": "federico.contigiani@lincrusta.com"
+  },
+  "lbi": {
+    "name": "LBI Boyd (Jill Carol)",
+    "sample_email": "jill@lbiboyd.com",
+    "account_number": "On File"
+  },
+  "vah": {
+    "name": "Vahallan",
+    "sample_email": "info@vahallan.com",
+    "account_number": "On File"
+  },
+  "bru": {
+    "name": "Brunschwig & Fils (@ Kravet)",
+    "sample_email": "matt.schoffman@kravet.com",
+    "account_number": "10087117"
+  }
+}
\ No newline at end of file
diff --git a/scripts/send-reconciled.mjs.bak-20260923-131934-TK12085 b/scripts/send-reconciled.mjs.bak-20260923-131934-TK12085
new file mode 100644
index 0000000..3f6c293
--- /dev/null
+++ b/scripts/send-reconciled.mjs.bak-20260923-131934-TK12085
@@ -0,0 +1,99 @@
+#!/usr/bin/env node
+// Reconciled sample-follow-up DRAFTER (Steve 8/20).
+// Pulls outstanding memos in the "fill-in-since-last-send / 10-day-floor" window and DRAFTS one
+// letter per vendor into info@ Drafts (NEVER auto-sends). Steve reviews + sends from Drafts.
+// Letter = intro + "Attn / processed by: <vendor processor>" + Ref#·Date Ordered·Manufacturer# table.
+//   WIN env overrides the FileMaker date range (default = today's fill-in window).
+import { readFileSync, writeFileSync } from 'node:fs'; import { homedir } from 'node:os'; import { join } from 'node:path'; import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
+const ROOT = join(homedir(), 'Projects/sample-followup-sweep');
+const { georgeRequest } = require(join(ROOT, 'lib/george-transport.js'));
+// Rolling window: memos that crossed the 10-day follow-up floor within the last CATCHUP days (default 7),
+// so a daily scheduled run always covers any gap. Env WIN overrides for a manual one-off. (Draft-dedup
+// below stops the same memo being drafted twice across runs.)
+const _pad = (n) => String(n).padStart(2, '0');
+const _fmt = (d) => `${_pad(d.getMonth() + 1)}/${_pad(d.getDate())}/${d.getFullYear()}`;
+// Steve 2026-09-22 (TK-12013/TK-12014): full active window [today-MAX_AGE .. today-MIN_AGE] inclusive,
+// NOT a narrow rolling catch-up band — so no older still-outstanding memo is ever dropped. Draft-dedup
+// (reconciled-draft-ledger keyed by vendor+combo-sku) makes re-covering already-drafted memos a no-op.
+const _MIN_AGE = 10, _MAX_AGE = Number(process.env.MAX_AGE) || 60;
+const _hi = new Date(); _hi.setDate(_hi.getDate() - _MIN_AGE);   // includes exactly-10d cohort (inclusive range)
+const _lo = new Date(); _lo.setDate(_lo.getDate() - _MAX_AGE);   // 60-day dead-lead floor
+const WIN = process.env.WIN || `${_fmt(_lo)}...${_fmt(_hi)}`;
+
+// --- FileMaker: pull outstanding (Date WP Sample Sent empty) in WIN, group by vid ---
+const cfg = JSON.parse(readFileSync(join(homedir(), '.claude.json'), 'utf8'));
+const fenv = cfg?.mcpServers?.filemaker?.env || {};
+for (const k of ['FM_CLOUD_HOST', 'FM_CLARIS_EMAIL', 'FM_CLARIS_PASSWORD']) process.env[k] = fenv[k];
+process.env.FM_READONLY = '1';
+const fm = await import('/Users/macstudio3/Projects/filemaker-mcp/src/fm-client.js');
+const A = (await fm.findRecords('WALLPAPER', 'REPORT ON SAMPLES ORDERED',
+  { 'Date WP Sample Sent': '=', 'today for client': WIN }, { limit: 1200 }).catch(() => ({ records: [] }))).records;
+const snap = {};
+for (const r of A) { const d = r.fieldData; const v = String(d.vid || '').toUpperCase(); if (!v) continue;
+  (snap[v] = snap[v] || []).push({ mfr: (d['Mfr Pattern'] || '').trim(), sku: d['combo sku'] || '', req: d['today for client'] || '' }); }
+writeFileSync(join(ROOT, 'data/outstanding-snapshot.json'), JSON.stringify(snap, null, 2));
+
+const esc = s => String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
+const SHIP = { name: 'Designer Wallcoverings', line1: '15442 Ventura Blvd. #102', csz: 'Sherman Oaks, CA 91403', phone: '1-888-373-4564' };
+// Sent-verified addresses + processor (person at vendor who handled the order), per vendor
+const V = {
+  YOR:    { name: 'York', to: 'RiveraH@yorkwall.com, orders@yorkwall.com', acct: '34328', proc: 'York Sample Dept (order-thru-website desk)' },
+  BRE:    { name: 'Brewster', to: 'brewsterorders@brewp.com', acct: '6003784', proc: 'Brewster Orders desk' },
+  BMGREEN:{ name: 'Greenland / bmwallpaper', to: 'sales@bmwallpaper.com', acct: 'On File', proc: 'Nora (NORA & GREENLAND)' },
+  OSB:    { name: 'Osborne & Little', to: 'Polancol@oalusa.com', acct: '1433803', proc: 'Leandra Polanco' },
+  KRA:    { name: 'Kravet', to: 'matt.schoffman@kravet.com', acct: '10087117', proc: 'Matt Schoffman' },
+  ROMO:   { name: 'Romo', to: 'fawn.bowen@romo.com', acct: '223641', proc: 'Fawn Bowen (Sampling Coordinator)' },
+  SANDB:  { name: 'Sandberg (via Gimmersta)', to: 'support@gimmersta.com', acct: 'On File', proc: 'Alva' },
+  WQ:     { name: 'WallQuest / Malibu', to: 'orders@wallquest.com', acct: '651317', proc: 'WallQuest Orders desk' },
+  THIB:   { name: 'Thibaut', to: 'cathy.dy@thibautdesign.com', acct: '0108751', proc: 'Cathy Dy' },
+  ARTE:   { name: 'Arte (@ Egg & Dart)', to: 'Therese@egg-and-dart.com', acct: 'On File', proc: 'Therese Stachowiak' },
+};
+// merge BM + GREEN under one bmwallpaper letter
+const items = {};
+for (const [vid, arr] of Object.entries(snap)) { const key = (vid === 'BM' || vid === 'GREEN') ? 'BMGREEN' : vid; (items[key] = items[key] || []).push(...arr); }
+
+function letter(v, rows) {
+  // Steve 8/20: do NOT show our internal Ref # (DW SKU) to the vendor — Date Ordered + Mfr # only.
+  const tbl = rows.map(r => `<tr style="border-bottom:1px solid #eee"><td style="padding:5px 18px 5px 0;white-space:nowrap">${esc(r.req || '—')}</td><td style="padding:5px 0">${esc(r.mfr)}</td></tr>`).join('\n');
+  return `<div style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#222;line-height:1.5">
+<p>We are following up on memo samples we have not yet received (ordered ~10 days ago).</p>
+<p><strong>Our account number is ${esc(v.acct)}</strong></p>
+<p><strong>Attn / processed by:</strong> ${esc(v.proc)} — please route these to whoever handled the original order.</p>
+<table style="border-collapse:collapse;font-size:14px;margin:8px 0">
+<tr style="text-align:left;border-bottom:2px solid #333"><th style="padding:5px 18px 5px 0">Date Ordered</th><th style="padding:5px 0">Manufacturer #</th></tr>
+${tbl}
+</table>
+<p>Ship to:<br>${esc(SHIP.name)}<br>${esc(SHIP.line1)}<br>${esc(SHIP.csz)}<br>${esc(SHIP.phone)}</p>
+<p><strong>Sidemark: Samples ASAP</strong></p>
+<p>Thank you!<br>Showroom Manager</p>
+<p style="font-size:11px;color:#666">Designer Wallcoverings · 15442 Ventura Blvd. #102 · Sherman Oaks, CA 91403<br>
+To stop receiving sample follow-up emails, <a href="mailto:info@designerwallcoverings.com?subject=Unsubscribe%20from%20sample%20follow-ups">unsubscribe here</a>.</p></div>`;
+}
+// George draft (account=info, /api/drafts — no send-approval token)
+const genv = k => { for (const f of ['/Users/macstudio3/Projects/Designer-Wallcoverings/DW-MCP/.env', '/Users/macstudio3/Projects/george-gmail/.env']) { try { const m = readFileSync(f, 'utf8').match(new RegExp('^' + k + '=(.+)$', 'm')); if (m) return m[1].trim(); } catch {} } return ''; };
+let auth = genv('GEORGE_BASIC_AUTH'); if (!auth.includes(':')) auth = 'admin:' + genv('GEORGE_BASIC_AUTH_PASS');
+auth = 'Basic ' + Buffer.from(auth).toString('base64');
+async function draft(to, subject, body) {
+  const result = await georgeRequest({ path: '/api/drafts', payload: { account: 'info', to, subject, body }, headers: { Authorization: auth } });
+  try { const parsed = JSON.parse(result.body); return parsed.success ? 'ok' : result.body.slice(0, 80); } catch { return result.body.slice(0, 80); }
+}
+
+const DO = process.argv.includes('--draft');
+// Draft-dedup: never re-draft a memo (keyed by vendor+combo-sku) that a prior run already drafted,
+// so a daily scheduled run over a rolling window can't pile up duplicate drafts.
+const LEDGER = join(ROOT, 'data/reconciled-draft-ledger.json');
+let ledger = {}; try { ledger = JSON.parse(readFileSync(LEDGER, 'utf8')); } catch {}
+const stamp = _fmt(new Date());
+console.log(`Reconciled follow-up — window ${WIN} — ${DO ? 'DRAFT into info@' : 'DRY-RUN (add --draft to create)'}\n`);
+for (const [key, rows] of Object.entries(items)) {
+  const v = V[key]; if (!v) { console.log(`  ? no vendor map for ${key} (${rows.length})`); continue; }
+  const fresh = rows.filter(r => !ledger[`${key}:${r.sku}`]);
+  if (!fresh.length) { console.log(`  ⊘ ${v.name.padEnd(26)} — all ${rows.length} already drafted (skip)`); continue; }
+  const subj = `Sample Follow-Up — Outstanding Memos (Acct ${v.acct}) — Designer Wallcoverings`;
+  if (!DO) { console.log(`  · ${v.name.padEnd(26)} → ${v.to.padEnd(40)} (${fresh.length}) refs: ${fresh.map(r => r.sku).join(', ')}`); continue; }
+  const r = await draft(v.to, subj, letter(v, fresh));
+  console.log(`  ${r === 'ok' ? '✎' : '✗'} ${v.name.padEnd(26)} → ${v.to.padEnd(40)} (${fresh.length}) ${r === 'ok' ? '' : r}`);
+  if (r === 'ok') for (const row of fresh) ledger[`${key}:${row.sku}`] = stamp;
+}
+if (DO) writeFileSync(LEDGER, JSON.stringify(ledger, null, 2));

← 7394a41 sample-followup: resolve 68 blocked overdue rows (TK-12085)  ·  back to Sample Followup Sweep  ·  auto-data-snapshot: 2026-09-23T14:17:00 (2 data files) — dat 04e0986 →