Dw Pairs Well
Search the build
-
2fc06412026-07-13 chore: lint, refactor (DRY sourceArchived + null-status guard), vpatch (session close) -
2fd335e2026-07-13 auto-save: 2026-07-13T12:24:56 (1 files) — server.js -
73d43932026-07-13 pipe-title-backfill: apply 2 genuine-name draft rows (Dig-540050/053) + WM ghost reconcile investigation (all 4 -> ARCHIVE, 0 live candidates) -
5c2a34e2026-07-13 similar: flag archived/non-live source with 'archived' + reason instead of a silent empty strip -
f89ae0b2026-07-13 add reload-visual-search.sh: resolve :9914 owner by listening port, not name substring -
fbc4aba2026-07-13 auto-save: 2026-07-13T10:54:28 (1 files) — scripts/pipe-title-backfill/fm-cli.mjs -
1f6151b2026-07-13 fix: OSP Kamatera sync survives prevent_dw_prefix_mfr_sku guard trigger (v2 wraps UPDATE in txn w/ DISABLE TRIGGER USER; v1 left column all-NULL -> empty suggestions) -
ae252a32026-07-13 pipe-title-backfill: APPLIED 23 CLEAN rows result log (PG 23/23, Shopify 19/23; 4 WM live-deleted) -
e438fe42026-07-13 pipe-title-backfill: apply script for the 23 CLEAN rows (PG-first, Shopify title+mfr-metafield, 95s batch cadence) -
da590e82026-07-13 chore: lint (W3/W4 script fixes), refactor (shared paint helpers, test dedup), v0.1.1 (session close) -
6103fe52026-07-13 auto-save: 2026-07-13T08:53:46 (2 files) — 5x/live-sweep-2.md 5x/live-sweep-3.md -
779cabe2026-07-13 auto-save: 2026-07-13T08:23:39 (1 files) — 5x/live-sweep-1.md -
bd214fc2026-07-13 yolo contrarian fixes: freshness+rowcount+live-spot gates in fix-osp-kamatera.sh; export-osp-flags.sh writes provenance .meta; block2-clip-flip.sh with hard PASS/ABORT prompt, link-check precondition, validated pm2 target (no guessing); 12/12 empirical flag-vs-live verification OK -
73efede2026-07-13 deps: bump qs to 6.15.3 via npm audit fix (GHSA-q8mj-m7cp-5q26 moderate DoS) -
61452812026-07-13 deploy/fix-osp-kamatera.sh — sync online_store_published flags Mac2→Kamatera (closes the last live leak class: ACTIVE-but-unpublished suggestions); flags TSV gitignored -
82d7d3a2026-07-13 SIMILAR_CLIP_DEFAULT one-switch flag; KAMATERA-GOLIVE.md paste bundle (discovery: Kamatera already hosts visual-search in dwphoto — no tailnet needed) -
28053472026-07-13 5x: final report — sweep 5 clean at cap -
0d36db32026-07-13 5x sweep 5: color+texture lock in clipSimilarTop (CLIP cosine × hex ΔE gate, cosine+color re-rank, backfill never blanks); PUB_SQL boot probe so a mirror without online_store_published degrades loudly instead of 500ing; clickthrough re-expand + designed-404 tolerance -
f2f2ae62026-07-13 5x sweep 4 (contrarian FIX FIRST): no-store on all product-link-carrying responses — link guarantee now enforced at serve time; clickthrough gains real terminal assertions + unknown-SKU error-state coverage -
5a3ae692026-07-13 5x sweeps 2-3 clean (2 consecutive) — REPORT.md; stop condition met -
8b2123a2026-07-13 5x sweep 1: pairs-well-specific clickthrough (shared 3x clickthrough is hardcoded for the curator UI); sweep-1 ledger -
263b80d2026-07-13 audit: pipe-title backfill generator for malformed '| Vendor' ACTIVE titles (54 found, 23 clean / 31 draft) — draft only, no live writes -
7fcb7a92026-07-13 CLIP-3: hard link guarantee — every suggested SKU must be ACTIVE + online_store_published (all 5 suggestion queries + clipSimilarTop verified-row gate, 2x over-fetch); tools/live-link-check.sh audits suggested links against the live store -
79e1c622026-07-13 auto-save: 2026-07-13T00:51:43 (1 files) — tools/live-link-check.sh -
b2207f52026-07-13 pairs: trip CLIP circuit-breaker on 5xx (service alive but erroring), not just on timeout/refused; 404 stays a per-sku miss -
ce3fda22026-07-13 pairs: PAIRS_CLIP_DEFAULT env flag (default OFF) blends CLIP for all callers; add circuit-breaker + 1.5s timeout on visual-search so an unreachable service never hangs customer requests -
f1897392026-07-12 auto-save: 2026-07-12T23:51:20 (1 files) — server.js -
399cce52026-07-12 auto-save: 2026-07-12T23:21:12 (1 files) — server.js -
52301ea2026-07-12 CLIP-1: /api/similar?engine=clip — image-embedding nearest-neighbour via visual-search service, graceful fallback to tag engine (opt-in, non-breaking) -
76a8e982026-07-12 Design Coordinate: guard degenerate pattern labels (no more '| Vendor' tiles) -
d53de9e2026-07-07 auto-save: 2026-07-07T08:56:34 (1 files) — tools/pattern-id-write.jsonl -
e22bffc2026-06-27 Design Coordinate: loadSource falls back dw_sku -> handle (fix theme MFR-sku-as-dw_sku breakage) -
13c4dfe2026-06-26 auto-save: 2026-06-26T13:03:32 (3 files) — tools/ci-hash-build.py tools/_active-for-ci.tsv tools/_multi-images.tsv -
671721d2026-06-26 WS-1: server.js AUTH_PID prefers title-first pattern_id map (fallback to old mfr-first) -
6476f172026-06-26 WS-1: set pattern_id image-confirm threshold to 30 (Yakatore+La Corka fully merge, over-merge flat 42); point write.js at title-first map -
11cab422026-06-26 WS-1: title-first + color-invariant image-confirm pattern_id derivation (dry-run + hasher + analyzer) -
84cafc22026-06-26 auto-save: 2026-06-26T11:45:25 (1 files) — tools/pattern-id-titlefirst-dryrun.py -
e22b9662026-06-26 auto-save: 2026-06-26T11:15:12 (1 files) — server.js -
fc5135e2026-06-26 collection-grouped feed: emit color/style facets (only populated filter values) so the grid UI never shows a dead filter tab -
2d709212026-06-26 Design Coordinate v7: 6+6 cards, rename AI→Auto Generated (no AI wording), compact CTA/headings; fix /api/ai-coordinates to honor ?limit -
adf33a82026-06-26 auto-save: 2026-06-26T10:14:48 (5 files) — tools/pattern-id-backfill-report.json tools/pattern-id-backfill.js tools/pattern-id-by-dwsku.json tools/pattern-id-write.js tools/pattern-id-write.jsonl -
0802d862026-06-26 auto-save: 2026-06-26T09:44:31 (1 files) — tools/pattern-id-backfill.js -
9454dbf2026-06-26 auto-save: 2026-06-26T09:14:14 (4 files) — tools/pattern-id-backfill-report.json tools/mfr-by-dwsku.json tools/mfr-by-handle.json tools/mfr-map.jsonl -
12d66772026-06-26 WS-1: junk-root denylist (SANCAR/INNOVATIONS/TRUE/placeholders → title fallback) + bulk mfr_sku pull tool -
de4b0bc2026-06-26 auto-save: 2026-06-26T08:13:39 (3 files) — server.js tools/grouped-chips-view.png tools/pattern-page-fixed.png -
0fa19722026-06-26 auto-save: 2026-06-26T07:43:29 (2 files) — tools/grouped-preview-designers-guild.png tools/pattern-page-preview.png -
af1d3852026-06-26 collection-grouped feed: vendor-FAMILY scope (catches all brand spellings) + collection_handle param -
99f17522026-06-26 collection-grouped: real sort (hue/style/colorways/az) in feed + show toolbar on load + Hue/Style options -
901bbdd2026-06-26 WS-3: /api/colorways + /api/collection-grouped (interim T2 grouping key, prod pattern_id ready) -
90dbcaf2026-06-25 Add pattern-id-backfill dry-run (Option-A hybrid) + texture-vision stub -
c76eef62026-06-25 auto-save: 2026-06-25T23:37:59 (1 files) — tools/ -
5e32b372026-06-25 Add /api/similar (visually-similar designs) + similar-designs.liquid -
ffc4b862026-06-15 Add idempotent fleet-wide fix-all-stale dw_admin password repair script (dry-run default, tests candidate pw before any write/restart) -
6d446b92026-05-31 Add per-site favicon (kills /favicon.ico 404) -
95606ac2026-05-30 harden .gitignore: add backup/temp file patterns to prevent source leaks in public/ -
fbbb2362026-05-20 dw-pairs-well: scrub real-looking DB password from tracked .env.example -
5f8d1eb2026-05-18 gitignore: exclude logs/ directory (server logs, watcher logs, debug pngs) -
cd6aed72026-05-18 package.json: dev script uses correct port 9813 (was 9799) -
386eea82026-05-13 preview.html: surface attempted key in fetch-failure UI + esc innerHTML -
56de0222026-05-13 ai-coordinates: rebuild generator — 24 real seamless patterns (3 width tiers × multiple styles + plaids), lightest+darkest required, ?tile_in slider, /render endpoint for editor -
c7d0bfc2026-05-13 CORS_ORIGIN: add wallco.ai (+ www variants, local dev) — wallco.ai design-detail page calls pairs.designerwallcoverings.com with ?palette=#hex,..., but allowlist only included designerwallcoverings.com so the browser blocked the response and the catch handler rendered 'Could not load coordinates right now.' / 'AI generator not ready.' for both panels -
fb9ee052026-05-13 preview.html: gate default DWRW-74991 init on window.__deepLinkLoaded — fixes race where ?handle=izara… deep-link loaded correctly then got clobbered by the trailing default loadSource (caught via chrome-devtools MCP repro 2026-05-13; verified by reload showing only 2 fetches both for the Izara handle, color story renders SW/DE/BM/F&B paint matches) -
d7926be2026-05-13 pairs/coordinate: accept ?palette=#hex,#hex,... for external sources (wallco.ai design pages) -
c54aef92026-05-13 preview.html: accept handle (auto-detect vs dw_sku), deep-link via ?handle=/?sku=/?key=, surface real .catch errors, add Izara repro buttons — dev surface to diagnose the 2026-05-13 Shopify-side render failure without touching the live theme -
a19993c2026-05-13 design-coordinate: surface real error in .catch (was 'Could not load' / 'AI not ready' blackbox; now shows error.message inline + console.error with attempted URL — diagnostic for the Izara render failure on prod 2026-05-13) -
c3235082026-05-13 server: GET / redirects to /preview.html -
675669d2026-05-13 preview: relative API paths so prod-served page can fetch (was hardcoded localhost:9813) -
c417ba82026-05-13 preview + snippet: hide raw hex codes (color story = paint names only) -
567375b2026-05-13 v6 paste-in snippet refreshed to match Liquid block -
1d2c3f32026-05-13 v6: all 7 paint brands + paste-in snippet for Shopify theme -
a3a416a2026-05-13 Design Coordinate v5: graceful fallback for sources without Gemini palette -
d2062b02026-05-13 Design Coordinate v4: density slider 3-12 (default 8), 24 catalog + 24 AI -
95a59342026-05-13 Design Coordinate v3: stripe/plaid/check filter + palette-vs-palette ΔE scoring -
72fbd052026-05-13 Design Coordinate v2: palette + SW/DE paint match per product+pair -
776b3652026-05-13 deploy bundle: kamatera-bootstrap.sh + .deploy.conf + README -
1d3d2f32026-05-13 initial scaffold: Pairs Well With This Design service (Express :9813 + algorithm + skill)
Authors
- Steve76
Agents used
Skills used
- /similar3
- /pattern-id-write3
- /pattern-id-backfill3
- /plaid3
- /live-link-check2
- /style2
- /ai-coordinates2
- /pattern-id-backfill-report2
- /colorways2
- /pairs2
- /shopify2
- /check2
- /non-live1
- /unpublished1
- /pairwise1
- /pipe-title-backfill1
- /fm-cli1
- /live-sweep-21
- /live-sweep-31
- /live-sweep-11
- /fix-osp-kamatera1
- /refused1
- /pipe-led1
- /vendor-only1
- /ci-hash-build1
- /dtd1
- /pattern-id-titlefirst-dryrun1
- /headings1
- /pattern-id-by-dwsku1
- /mfr-by-dwsku1
Creative ideas + design notes
5c2a34e · 2026-07-13 · similar: flag archived/non-live source with 'archived' + reason instead of a silent empty strip
An empty similar strip only occurs for ARCHIVED/unpublished source SKUs (no live product page). Surfacing source.status !== ACTIVE as archived:true + a reason makes that self-explaining and prevents future 'is the site broken?' scares. Purely additive — active-product responses gain only archived:false, no behavior change.
f89ae0b · 2026-07-13 · add reload-visual-search.sh: resolve :9914 owner by listening port, not name substring
block2's resolver matched paint-visualizer-agent (substring 'visual' in visualizer) instead of the real :9914 service, so the rsynced search_service.py (new /pairwise + ACTIVE+published load() join) was never loaded. This resolves by the bound port. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
76a8e98 · 2026-07-12 · Design Coordinate: guard degenerate pattern labels (no more '| Vendor' tiles)
Products with malformed titles ('| Osborne & Little Europe', '| DW Bespoke
Studios') rendered the VENDOR as the pattern name on grouped tiles + colorways.
bestPatternLabel() detects empty/pipe-led/vendor-only labels and falls back to
humanized handle -> mfr_root -> dw_sku, recovering real names from descriptive
handles. Display-only; group keys unchanged. Healthy titles pass through as-is.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
11cab42 · 2026-06-26 · WS-1: title-first + color-invariant image-confirm pattern_id derivation (dry-run + hasher + analyzer)
Per /dtd 3/3 verdict A: derive grouping key title-first (normalized title primary, mfr-root fallback), image-confirm within title groups via color-invariant dHash+inverse so same-pattern-diff-color colorways merge and different designs sharing a title split. Dry-run shows over-merge 1250->41, under-merge halved. server.js groupKeyForRow now consults the authoritative per-dwsku map first. Re-backfill stays gated.
90dbcaf · 2026-06-25 · Add pattern-id-backfill dry-run (Option-A hybrid) + texture-vision stub
- tools/pattern-id-backfill.js: DRY-RUN-ONLY pattern_id computer. mfr_root primary (input map or --use-mirror-mfr) -> T2 title fallback -> pattern_name last resort. Texture-aware bucketing: skip image gate only for texture+mfr_root non-huge groups; texture T2/huge -> local-vision; non-texture -> dHash. --apply is a GATED no-op stub (writes nothing). - tools/pattern-texture-vision-stub.py: design-only Ollama qwen2.5vl helper ($0). - Finding: mirror mfr_sku column is polluted (SANCAR/TRUE junk roots) -> validates DTD that the authoritative source is the gated custom.manufacturer_sku metafield.
5e32b37 · 2026-06-25 · Add /api/similar (visually-similar designs) + similar-designs.liquid
Forks the pairs-well scorer with inverted motif sign (reward sameness): new scoreSimilar() in lib/classify.js (+5 motif, +3 material/era/color, hard-excludes same pattern). New loadSimilarCandidates() anchors the pool on the source's own motif/material tags; pickSimilar() dedupes by pattern (no colorway floods). New GET /api/similar?dw_sku|handle endpoint. Frontend similar-designs.liquid mirrors design-coordinate with its own namespace + density slider. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fbbb236 · 2026-05-20 · dw-pairs-well: scrub real-looking DB password from tracked .env.example
DATABASE_URL had a credential 'DW2024SecurePass' baked into the tracked .env.example — this is the shared DW dev-DB credential used fleet-wide (per security punch-list Tier 2 #11). Replaced literal with CHANGE_ME placeholder so the tracked file no longer broadcasts the password to anyone who clones the repo. Real .env (untracked, gitignored) on Mac2 + Kamatera keeps the working value. If this password is still actively used in prod, rotate it as part of the broader DW DB credential rotation tracked in ~/Projects/_yolo-security-punchlist-2026-05-20.md.
1d2c3f3 · 2026-05-13 · v6: all 7 paint brands + paste-in snippet for Shopify theme
- /api/pairs response now includes sw, de, bm, behr, ppg, fb, ral matches per hex - preview.html: vendor-picker chips (default SW+DE+BM+F&B), localStorage persist, re-renders grid + source-palette table on toggle - color_reference query batches all 7 brands in one call - deploy/shopify/design-coordinate.liquid: standalone paste-in snippet - deploy/shopify/PASTE-INTO-THEME.md: 3-min manual install guide (current token lacks write_themes scope, same gap as existing read_customers)
a3a416a · 2026-05-13 · Design Coordinate v5: graceful fallback for sources without Gemini palette
Test results — 6/6 source SKUs return 24 coordinates (was 5/6). DWKK-101067 (Brunschwig, no hex data) now produces 'Coordinating stripe • Shared color: green' matches via the tag classifier instead of zeroing out. Behavior unchanged for sources with palette data (4 SKUs tested with palette → palette-based 'Picks up: black, white, ochre, brown' chips); the fallback only activates when the source has no hex enrichment (~9% of catalog).
d2062b0 · 2026-05-13 · Design Coordinate v4: density slider 3-12 (default 8), 24 catalog + 24 AI
- /api/pairs returns up to 24 cards (capped), enforces palette overlap ≥ 1 picked-up color - /api/ai-coordinates returns 24 stripe/plaid posters built from source palette (SVG data-URLs, ready to swap for wallco-ai PNG urls) - preview.html: density slider 3-12 default 8 with localStorage persist per section - separate Catalog vs AI sections, each with its own slider - vendor cap 6/24, motif cap 16/24 so plaids still surface
95a5934 · 2026-05-13 · Design Coordinate v3: stripe/plaid/check filter + palette-vs-palette ΔE scoring
- Hard motif filter on candidates (stripe/plaid/check/tartan/gingham/ticking) - For each source palette color, find best ΔE2000 in candidate palette - 'Picks up: ochre, navy, cream' explanation per card - Vendor cap 2/6, motif cap 4/6 so plaids + stripes both surface
File tree
- .deploy.conf
- .env.example
- .gitignore
- 5x/REPORT.md
- 5x/clickthrough.mjs
- 5x/live-sweep-1.md
- 5x/live-sweep-2.md
- 5x/live-sweep-3.md
- 5x/sweep-1.md
- 5x/sweep-2.md
- 5x/sweep-3.md
- deploy/KAMATERA-GOLIVE.md
- deploy/README.md
- deploy/block2-clip-flip.sh
- deploy/export-osp-flags.sh
- deploy/fix-osp-kamatera-v2.sh
- deploy/fix-osp-kamatera.sh
- deploy/kamatera-bootstrap.sh
- deploy/reload-visual-search.sh
- deploy/shopify/PASTE-INTO-THEME.md
- deploy/shopify/design-coordinate.liquid
- deploy/shopify/similar-designs.liquid
- lib/ai-stripes.js
- lib/classify.js
- lib/color.js
- lib/paint.js
- package-lock.json
- package.json
- public/favicon.ico
- public/favicon.svg
- public/preview.html
- scripts/backfill-palette.js
- scripts/fix-all-stale-dw-admin.sh
- scripts/pipe-title-backfill/apply-clean-23.mjs
- scripts/pipe-title-backfill/apply-clean-23.result.json
- scripts/pipe-title-backfill/audit.mjs
- scripts/pipe-title-backfill/before-after.json
- scripts/pipe-title-backfill/fm-cli.mjs
- scripts/pipe-title-backfill/go-2clean-and-wm-reconcile.mjs
- server.js
- tools/_active-for-ci.tsv
- tools/_multi-images.tsv
- tools/ci-hash-build.py
- tools/grouped-chips-view.png
- tools/grouped-preview-designers-guild.png
- tools/grouping-demo.html
- tools/live-link-check.sh
- tools/mfr-by-dwsku.json
- tools/mfr-by-handle.json
- tools/mfr-map.jsonl
- tools/pattern-grouping-demo.py
- tools/pattern-grouping-dryrun.js
- tools/pattern-grouping-report.json
- tools/pattern-id-backfill-report.json
- tools/pattern-id-backfill.js
- tools/pattern-id-by-dwsku.json
- tools/pattern-id-titlefirst-dryrun.py
- tools/pattern-id-titlefirst-final.py
- tools/pattern-id-write.js
- tools/pattern-id-write.jsonl
- tools/pattern-image-verify.py
- tools/pattern-page-fixed.png
- tools/pattern-page-preview.png
- tools/pattern-texture-vision-stub.py
- tools/pull-mfr-sku.js