{"slug":"consulting-designerwallcoverings-com","total":58,"limit":100,"offset":0,"since":null,"commits":[{"hash":"f4772ed","date":"2026-07-28 10:09:28 -0700","author":"Steve Abrams","subject":"TK-22 deploy-safety: exclude data/intakes.json from rsync so deploys never clobber live customer intake submissions (Cody gate)","body":"Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"c46dce5","date":"2026-07-27 21:15:16 -0700","author":"Steve Abrams","subject":"TK-22 signin: hydrate front door from /api/client (fixes stale empty tagline + dangling 'Reach ·')","body":"The signin page rendered hard-coded static HTML: an empty <p class=sub> tagline\nand a 'Reach: email · ' field with a trailing separator and no phone — even though\nclient.json now carries a tagline + phone and server.js already serves /api/client\nas the \"public-safe summary for signin page\" that the page never consumed. Wire the\npage to hydrate #tagline / #meta / #reach from /api/client (HTML-entity-decoded for\ntext), keeping the static markup as graceful fallback. Also drop the trailing ' · '\nfrom the static Reach so the no-JS state is clean too. Verified in headless Chrome:\ntagline + email·phone render, no double-escape, no console errors.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"4fcf330","date":"2026-07-27 21:08:46 -0700","author":"Steve Abrams","subject":"TK-22 admin-UX: add created date+time chip to Low Hanging Fruit cards","body":"Standing rule (global CLAUDE.md): every admin card/chip MUST show the\nrecord's created date AND time. The admin command-center's Low Hanging\nFruit cards showed none. Backfill created_at into suggestions.json\n(basis = file creation 2026-07-26) and render a 🕓 when-chip via\nfmtDate() (admin local tz, full ISO in title=), mirroring the\n/admin/design-curator reference impl. Verified headless: 8/8 chips,\n0 console errors, gating intact.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"b28b741","date":"2026-07-27 21:05:01 -0700","author":"Steve Abrams","subject":"TK-22 red-team FINDING 4: fix XFF-spoof rate-limit bypass on /api/intake","body":"The /api/intake rate limiter keyed off the raw, client-controllable\nX-Forwarded-For header, so rotating XFF per request bypassed the 5/IP/60s\ncap entirely (reproduced: 7 rotating-XFF POSTs all 200), defeating FINDING 1.\nNow: app.set('trust proxy','loopback') (nginx->Node over loopback on this host,\nenv-overridable via TRUST_PROXY) + key the limiter off Express's trusted req.ip\ninstead of the raw header. Verified: rotating attacker-XFF now trips 429 after 5\nwhile distinct real clients stay allowed; oversized still 413, boot/health OK.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"fdbc2a7","date":"2026-07-27 21:01:00 -0700","author":"Steve Abrams","subject":"TK-22 red-team FINDING 2: validate admin bucket writes + atomic write w/ .bak","body":"POST /api/admin/:bucket blind-wrote req.body, so one malformed/empty admin\nPOST (e.g. {} or a scalar) to 'client' corrupted the PUBLIC /api/client the\nsignin page reads. Now: require a JSON object|array, reject scalars/null (400),\ncap at 512KB (413), and refuse an empty payload that would wipe existing\nnon-empty content (409). writeJSON is now atomic (tmp+rename) and keeps a\nsingle-copy .bak so any accepted-but-wrong write is recoverable. .bak/.tmp\ngitignored. Verified 7 cases locally; deploy Steve-gated.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"3cc6bd7","date":"2026-07-27 20:56:09 -0700","author":"Steve Abrams","subject":"TK-22 red-team: harden ungated POST /api/intake (rate-limit + size cap + FIFO cap)","body":"FINDING 1 (HIGH, confirmed live): the only unauthenticated write had no\nrate-limit, no per-field size cap, and no stored-record cap. A single 400KB\nPOST grew intakes.json 2KB->402KB, and every POST rewrites the whole growing\nfile -> unbounded disk-fill DoS with quadratic CPU amplification on the public\ndw.agentabrams.com host.\n\nFix (reversible, local): validate body is an object, reject payloads >16KB\n(413), rate-limit to 5/IP/60s (429), and FIFO-cap retained records at 500 so\nthe file and every rewrite stay bounded. Verified: oversized->413, flood->429,\nvalid submission->200, file stays small.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"9d15ef6","date":"2026-07-27 20:52:09 -0700","author":"Steve Abrams","subject":"TK-21: honest fleet per-site depth — rank/report by crawled handleCount, drop aggregators (DTD verdict B)","body":"The all.dw /api/microsites feed exposes per-site productCount, but naively using\nit was dishonest: type=internal directory sites (all.dw reports productCount=201504\nwhile its OWN handleCount is 49 — it rolls up the whole fleet) and cf-zone mirrors\nreport inflated rolled-up figures. The old collector summed all productCounts into\nproducts_total=458655 (~123x inflation) and ranked 'Deepest sites by real catalog\ndepth' by productCount, so the aggregator + mirrors dishonestly topped the list.\n\nFix (DTD 5/5 Option B):\n- collect-dw.mjs: drop type=internal aggregator sites; per-site depth = crawled\n  handleCount (summing non-internal handleCounts ~= server total_handles=125624,\n  proving it's the faithful signal); retain productCount only as products_rollup\n  context; flag capped=200 (feed page-size) sites. Replace inflated products_total\n  with the server's honest total_handles + a transparent handles_sum.\n- build.mjs: page-capped sites render '200+' so the figure is not misread as exact.\n- Result: fleet count 280->271 (aggregators dropped), chips led by real crawled\n  depth (japan 29,073, astek 6,167) not the 201,504 aggregator; 0 pageerrors x7,\n  leak-scan clean.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"},{"hash":"afc0d96","date":"2026-07-27 20:24:26 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-27T20:24:23 (5 files) — build.mjs data/dw-analysis.json public/portal.html public/versions/gallery.html scripts/collect-dw.mjs","body":""},{"hash":"97105b7","date":"2026-07-27 16:21:11 -0700","author":"Steve Abrams","subject":"TK-17: generate read-only Batch A (9684) + Batch B (813) execution worklists","body":""},{"hash":"774241d","date":"2026-07-27 16:13:06 -0700","author":"Steve Abrams","subject":"TK-17: execution runbook + Batch B canary worklist (Steve-approved A+A′ quote-tags, B canary, C hold) — maps to canonical bucketA-add-roll-variants.js + tagsAdd; live --apply stays supervised","body":""},{"hash":"b206159","date":"2026-07-27 16:05:28 -0700","author":"Steve Abrams","subject":"TK-17: Phase-2 dry-run — batched, rule-enforced, contrarian-gated (813 Hollywood variant-eligible, 9,301 quote-tag, 12,397 HOLD; Batch C→0 GO after brand-integrity pulls)","body":""},{"hash":"0c7e77f","date":"2026-07-27 14:49:59 -0700","author":"steve@designerwallcoverings.com","subject":"Fix contrarian-caught join errors: Greenland already-buyable (0 in backlog, not a canary); Hollywood is the cost-ready canary (813/843 join via mfr_sku=alt_sku on hw_price)","body":""},{"hash":"4455119","date":"2026-07-27 14:40:33 -0700","author":"steve@designerwallcoverings.com","subject":"Correct Phase-1 cost-sourcing: momentum cost col is NULL (join hw_price); surface Greenland/Hollywood as cost-ready canary vs cost-blocked Osborne","body":""},{"hash":"9d147c4","date":"2026-07-27 14:35:41 -0700","author":"Steve Abrams","subject":"Phase-1 cost-sourcing plan for the 5 GO lines (read-only)","body":""},{"hash":"d4a3527","date":"2026-07-27 14:22:59 -0700","author":"steve@designerwallcoverings.com","subject":"Add Phase-0 go/no-go worksheet for sample-only backlog top lines (read-only)","body":""},{"hash":"6b2948a","date":"2026-07-27 14:21:18 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-27T14:21:14 (1 files) — data/media.json","body":""},{"hash":"ef33303","date":"2026-07-27 14:19:52 -0700","author":"steve@designerwallcoverings.com","subject":"Refresh sample-only backlog work orders (22,895 rows, 130 vendors, malformed 0)","body":""},{"hash":"7ca0f69","date":"2026-07-27 12:37:32 -0700","author":"Steve Abrams","subject":"TK-19: reconcile attribution docs to live GA4 measurement ID G-53F1QBZSG0 (property already existed; create-property memo void)","body":""},{"hash":"4bcdbe7","date":"2026-07-27 08:26:28 -0700","author":"Steve Abrams","subject":"TK-19 CLOSE: GA4 already live (G-53F1QBZSG0, $6.9k/7d revenue tracked) — brief finding corrected; Consent Mode v2 region-scoped installed on live theme + verified; theme.liquid backup + findings doc","body":""},{"hash":"befbf29","date":"2026-07-26 21:23:14 -0700","author":"Steve Abrams","subject":"TK-20 EXECUTED: collection FAQ metafields SET (versace/osborne/zuber) + dw-aeo-jsonld snippet & page.liquid hook live on theme 144396058675; LIVE-BACKUP preserved; portal deployed to dw.agentabrams.com","body":""},{"hash":"5f94a3d","date":"2026-07-26 21:13:19 -0700","author":"Steve Abrams","subject":"TK-20: apply vp-dw-commerce REVISE — collection JSON-LD branches emit FAQPage-only","body":"dw-collection-hero.liquid already emits CollectionPage+BreadcrumbList on collection\npages, so the snippet's versace-wallpaper + osborne-little branches now emit FAQPage\nonly (avoids duplicate same-URL CollectionPage entities). Page branch keeps WebPage+FAQPage\n(verified structured-data.liquid emits WebPage for ARTICLE templates only, never plain pages).\nDraft layer only; no theme write."},{"hash":"f2191dc","date":"2026-07-26 21:11:13 -0700","author":"Steve Abrams","subject":"TK-20: harden APPLY-page-jsonld.sh step[2] — fetch-live + abort-on-drift + append-one-line (vp-dw-commerce REVISE resolved); no blind PUT of stale .PROPOSED","body":"Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"d9016b7","date":"2026-07-26 21:09:17 -0700","author":"Steve Abrams","subject":"TK-20: AEO JSON-LD injector draft + read-only render-verify","body":"- docs/aeo-drafts/dw-aeo-jsonld.liquid: handle-keyed FAQPage/CollectionPage/WebPage\n  JSON-LD snippet (versace-wallpaper + osborne-little collections, wall-coverings page),\n  generated from the committed .jsonld graphs, mirrors visible body_html FAQ verbatim.\n  DTD verdict A (unanimous 5/5) — single snippet rendered from theme.liquid head.\n- scripts/aeo-render-verify.mjs: read-only Playwright render check (all 3 render body_html;\n  hasJsonLdFaq=false confirms the gap this snippet fills).\n- render-proof/: saved render-verify JSON.\nGated theme-write memo -> pending-approval/tk20-aeo-jsonld-snippet-and-nav.md. No theme write."},{"hash":"b5fc1de","date":"2026-07-26 21:02:37 -0700","author":"Steve Abrams","subject":"TK-20 verify: Playwright render-check (all 3 published, but 2 collection body_html blocks HIDDEN by Boost SD display:none); read-only theme investigation → dw-collection-hero SECTION is metafield-driven & already emits FAQPage; draft handle-keyed dw-aeo-jsonld.liquid snippet + page render-hook + collection custom.faq/category metafieldsSet payloads + gated APPLY scripts + findings doc","body":"Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"63824ff","date":"2026-07-26 20:49:19 -0700","author":"Steve Abrams","subject":"refine: fix 3 contrarian FIX-FIRST findings (DTD opt1, 5/5) — disjoint concept galleries (60-item collector, zero overlap), honest sorts (drop fabricated hue/tier -> Newest/Title/Vendor/Type), hero wordmark APCA clears Lc>=60 (dark-plateau gradient + text-shadow + hero-only champagne gold)","body":""},{"hash":"788d55d","date":"2026-07-26 20:47:46 -0700","author":"Steve Abrams","subject":"TK-20 PUBLISHED: AEO blocks live via Admin API (versace smart-collection 3688c, osborne 2681c, NEW page wall-coverings id 219525742643); aeo-render.mjs deterministic md→HTML; rollback baselines preserved","body":""},{"hash":"10291a7","date":"2026-07-26 20:45:53 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T20:45:50 (11 files) — build.mjs data/dw-analysis.json public/portal.html public/versions/atelier.html public/versions/gallery.html","body":""},{"hash":"ca97015","date":"2026-07-26 20:39:57 -0700","author":"Steve Abrams","subject":"weekly snapshot refresh: dw-analysis + build + work-orders (2026-07-26)","body":""},{"hash":"39e8e99","date":"2026-07-26 20:23:38 -0700","author":"Steve Abrams","subject":"refinement round: fresh collector snapshot (80,756 active / 174 vendors / 281 fleet) + rebuild","body":""},{"hash":"d94d732","date":"2026-07-26 20:19:38 -0700","author":"Steve Abrams","subject":"TK-20: README handle-verification note RESOLVED — bake in Admin-API-verified handles (versace-wallpaper, osborne-little, zuber-wallcoverings); wall coverings + designer wallpaper have no collection (NEW-page decision validated)","body":"Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"ca96290","date":"2026-07-26 20:18:39 -0700","author":"Steve Abrams","subject":"TK-20: compliance REVISE fix — drop implied-authorization adjacency from O&L FAQ (vp-compliance-policy sign-off)","body":""},{"hash":"30c247e","date":"2026-07-26 20:18:35 -0700","author":"Steve Abrams","subject":"TK-20: correct zuber AEO handle zuber -> zuber-wallcoverings (verified via Shopify Admin API; prevents 404 JSON-LD injection)","body":"Out-of-top-3 courtesy fix completing the handle-verification pass; same approved deliverable.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"99bcb11","date":"2026-07-26 20:15:06 -0700","author":"Steve Abrams","subject":"TK-20: verify live Shopify handles for top-3 AEO targets — correct versace-home→versace-wallpaper (543 products), confirm osborne-little (1041), wall-coverings page free","body":""},{"hash":"d98f901","date":"2026-07-26 20:09:33 -0700","author":"Steve Abrams","subject":"TK-21 P2 polish: hairline ring on doughnut legend markers so dark hues (Black rgb43) read on the #171310 panel (DTD verdict A, 5/5 unanimous)","body":"Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"601d121","date":"2026-07-26 20:07:40 -0700","author":"Steve Abrams","subject":"TK-20: AEO drafts for top-5 striking-distance queries (DTD-C hybrid, draft-only)","body":"5 Julian-Goldie-style AEO blocks (direct-answer + FAQ + JSON-LD + entity mentions):\n- versace/osborne/zuber -> AEO blocks appended to EXISTING vendor collection pages\n- wall coverings / designer wallpaper -> NEW head-term landing pages\nDTD verdict C (hybrid) unanimous 5/5. vp-dw-marketing sign-off REVISE (2 conditions\napplied at draft layer). No live theme write; publish memo gated to pending-approval.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"bd9f352","date":"2026-07-26 20:06:18 -0700","author":"Steve Abrams","subject":"portal P2 polish: gold-styled density slider (matches select) + count/% doughnut legends","body":"- versionPage: density input[type=range] now custom-styled to the gold system\n  (custom track w/ value-tracking --fill, gold thumb, focus-visible) so the\n  Sort+Density controls row reads as one designed system; caret hardened\n  (transform-origin centering, focus-visible). All 6 concept versions.\n- htmlLegend: doughnut legend rows now carry a right-aligned tabular\n  count + percentage (visible-only re-normalization on toggle); .hleg CSS\n  gains .lgvl (tabular-nums) + flexed .lgtx.\n- Rebuilt; Playwright: 0 pageerrors across portal + 6 concepts; leak-scan\n  (schumacher|momentum|wallquest|greenland|tokiwa|rigo)=0. TK-21."},{"hash":"95aeb4a","date":"2026-07-26 16:40:43 -0700","author":"Steve Abrams","subject":"chore: lint, refactor, v0.1.1 (session close)","body":""},{"hash":"f0b7063","date":"2026-07-26 16:00:44 -0700","author":"Steve Abrams","subject":"TK-17 Phase 0: per-line GO/NO-GO decision sheet for the 22,952 backlog (awaiting Steve rulings)","body":""},{"hash":"a4ad6c6","date":"2026-07-26 15:30:19 -0700","author":"Steve Abrams","subject":"attribution prep (DTD-A): per-channel UTM+coupon scheme (data/attribution-scheme.json), attribution-spec + gtag theme-install docs, inert G-XXXX gtag snippet; GA4 property + gtag-install gated to pending-approval","body":"Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"2a832f2","date":"2026-07-26 14:23:23 -0700","author":"Steve Abrams","subject":"Traffic & Search Reality section: GSC 28d totals, 51% organic-click decline flagged, striking-distance table, branded split, GA4 gap; sections renumbered","body":""},{"hash":"ec34562","date":"2026-07-26 09:34:19 -0700","author":"Steve Abrams","subject":"weekly-refresh.sh: harden with set -euo pipefail note; drop risky in-job log truncation (vp-operations APPROVE)","body":""},{"hash":"9568f61","date":"2026-07-26 09:31:10 -0700","author":"Steve Abrams","subject":"weekly snapshot refresh: dw-analysis + build + work-orders (2026-07-26)","body":""},{"hash":"4e62b5a","date":"2026-07-26 09:24:25 -0700","author":"Steve Abrams","subject":"sample-only backlog WORK ORDERS: per-vendor remediation CSVs (22,952 non-quote sample-only actives, 130 lines) + SUMMARY.md in /admin media bucket, gated /work-orders route; read-only from dw_unified mirror","body":""},{"hash":"27e394b","date":"2026-07-26 09:16:58 -0700","author":"Steve Abrams","subject":"designer LOW follow-ups: 2x16px line-marker HTML legends on the two doughnuts, styled select+caret chrome on concept sort controls, thin vertical-rule accent on section headers","body":""},{"hash":"26ca9ee","date":"2026-07-26 09:04:06 -0700","author":"Steve Abrams","subject":"Unlikely Revenue: quantify sample→roll funnel (Pool 2) from dw_unified mirror","body":"Collector: sample_roll block — funnel (78,244 sampleable → 66% buyable, 26,580 gap\nsplit 3,790 quote-only / 22,790 recoverable), per-vendor recoverable leak, and\norder-data provenance (no shopify_orders; mp_orders seed, digital_sample_orders thin).\nBrief: Pool 2 rewritten with measured figures, one stacked sample→roll chart by line,\nand a Tier A/B/C provenance box — upper-bound labeled, Tier-C names the instrumentation\ngap as the recommendation.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"},{"hash":"bf9f344","date":"2026-07-26 09:00:22 -0700","author":"Steve Abrams","subject":"preserve prior loop: GSC traffic-collector wired into snapshot (collector-side)","body":""},{"hash":"9b9d09a","date":"2026-07-26 08:33:26 -0700","author":"Steve Abrams","subject":"graphic-designer advisory pass: chart typography/gridlines, decisive rose accents, burger UR, hero overlay, metric labels","body":""},{"hash":"d75255d","date":"2026-07-26 08:29:29 -0700","author":"Steve Abrams","subject":"graphics+analysis pass: catalog DNA (style/color/needs-tags), 46x ramp chart, gradient fills, real product imagery in mosaic + concept grids/heroes, #all deep-link","body":""},{"hash":"d4a733e","date":"2026-07-26 08:18:43 -0700","author":"Steve Abrams","subject":"P2 fixes: honest null fleet counts, Gallery concept to light marketplace-luxe","body":""},{"hash":"2c9b6e0","date":"2026-07-26 08:14:01 -0700","author":"Steve Abrams","subject":"contrarian FIX-FIRST pass: data-layer forbidden-vendor filter + product-array coercion, snapshot sanity gate, roadmap KPIs","body":""},{"hash":"4c656f4","date":"2026-07-26 08:11:44 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T08:11:40 (1 files) — scripts/collect-dw.mjs","body":""},{"hash":"f141e57","date":"2026-07-26 08:06:35 -0700","author":"Steve Abrams","subject":"seed growth buckets with live channel state + $0 competitor pixel scan; bind ad-gap finding into brief","body":""},{"hash":"153dc6e","date":"2026-07-26 08:03:18 -0700","author":"Steve Abrams","subject":"flagship 14-section DW analysis app + 6 luxury-leader concepts, snapshot-bound","body":""},{"hash":"5f513da","date":"2026-07-26 07:51:52 -0700","author":"Steve Abrams","subject":"collector + /api/refresh + deploy conf; live at dw.agentabrams.com :9703","body":""},{"hash":"030bfa0","date":"2026-07-26 07:41:34 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-26T07:41:30 (1 files) — scripts/","body":""},{"hash":"65efc01","date":"2026-07-26 07:37:48 -0700","author":"Steve Abrams","subject":"enrich from live DW site: phone, tagline, linkedin","body":""},{"hash":"cb206b6","date":"2026-07-26 07:37:04 -0700","author":"Steve Abrams","subject":"DW intake scaffold on :9702 with verified auth gates","body":""},{"hash":"e4e5bef","date":"2026-07-26 07:36:27 -0700","author":"Steve","subject":"scaffold consulting portal for Designer Wallcoverings","body":""}]}