{"slug":"trending-dw","total":39,"limit":100,"offset":0,"since":null,"commits":[{"hash":"ae386f4","date":"2026-07-15 12:07:55 -0700","author":"Steve","subject":"chore: v0.3.0 (session close) — lint+refactor review clean, no fixes needed","body":""},{"hash":"45d6a46","date":"2026-07-15 11:46:47 -0700","author":"Steve","subject":"UX: tiered default sort — real product images lead, our-lane designs next, pending last","body":""},{"hash":"2374e12","date":"2026-07-15 11:41:39 -0700","author":"Steve","subject":"UX: dedupe our-lane fallback heroes (full-bleed once per design, repeats render as tinted inset) + attach first 16 real images","body":""},{"hash":"8f3f89d","date":"2026-07-15 11:36:23 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-15T11:36:14 (118 files) — data/real-images/ledger.json public/assets/real/01fed1ec969baa25.webp public/assets/real/06354f219cec20b7.webp public/assets/real/0ab7a0b22c9877fb.webp public/assets/real/1fcb172898433b84.webp","body":""},{"hash":"8ddd3d1","date":"2026-07-15 11:06:12 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-15T11:06:03 (3 files) — data/real-images/candidates/ data/real-images/ledger.json public/assets/real/","body":""},{"hash":"b3b4e49","date":"2026-07-15 10:59:12 -0700","author":"Steve Abrams","subject":"server+frontend: realImage support (signal default sort, meta coverage, Shopify staging guard) + UX overhaul (error/retry states, skeletons, provenance pill, OURS inset, date+time chip, alt text, 36-card first paint, detail modal w/ THEIRS-OURS)","body":""},{"hash":"c44ad99","date":"2026-07-15 10:42:29 -0700","author":"Steve Abrams","subject":"real-image pipeline scaffold: plan/download/qc/attach scripts + fingerprint-keyed ledger (internal-only marketplace images)","body":""},{"hash":"0968c22","date":"2026-07-08 08:29:13 -0700","author":"Steve Abrams","subject":"chore: v0.2.0 (session close) — 247-item multi-platform expansion + tz-pin + image localization (lint/refactor: clean)","body":""},{"hash":"eb73264","date":"2026-07-07 12:51:23 -0700","author":"Steve","subject":"chore: v0.1.3 (session close)","body":""},{"hash":"39b1dba","date":"2026-07-07 12:49:30 -0700","author":"Steve","subject":"gapgen: cost guard — refuse paid Replicate by default (Steve: use local models); Replicate now opt-in via GEN_BACKEND=replicate","body":""},{"hash":"8e9ac73","date":"2026-07-07 12:44:46 -0700","author":"Steve","subject":"chore: lint guards (colorGate NaN, --rolls, json.loads) + refactor (dead imports) + version bump (session close)","body":""},{"hash":"86ce32b","date":"2026-07-07 12:26:37 -0700","author":"Steve","subject":"trending: reship 10 vetted+deduped gap tiles (settlement-gated + QC'd) per Steve approval; drop 7 redundant","body":""},{"hash":"0ed523e","date":"2026-07-07 10:29:03 -0700","author":"Steve","subject":"trending: roll back 17 gap tiles per DTD verdict B — went live before formal settlement gate was run; reship only vetted+deduped survivors after gating","body":""},{"hash":"8e5b736","date":"2026-07-07 10:16:06 -0700","author":"Steve","subject":"trending: attach 17 AI-original texture tiles to gap lanes (seam-clean, settlement-safe) + Texture-Effect color cap 3->5","body":""},{"hash":"7991ccc","date":"2026-07-07 10:00:00 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-07T09:59:53 (1 files) — scripts/__pycache__/","body":""},{"hash":"52f5a8b","date":"2026-07-07 09:49:41 -0700","author":"Steve","subject":"gapgen: add file-based heal-tile.py (near-miss seam rescue, reuses wallco heal algo, no DB)","body":""},{"hash":"bedb55d","date":"2026-07-07 09:29:45 -0700","author":"Steve","subject":"gapgen: data-driven style-keyed briefs from live gap items (kill ID-drift landmine) + --dry-run","body":"Root cause of the 2026-07-07 misfire: briefs were hardcoded to TR-### ids, but\nthe feed rebuild reassigns ids, so all 16 briefs mis-targeted trends that had\nmoved. Now briefs are built from the live item's style/color/hex at run time and\nnon-gap ids are refused, so brief↔trend drift can't happen. --dry-run validates\ntargeting for $0 before any Replicate spend."},{"hash":"c96132f","date":"2026-07-07 08:42:36 -0700","author":"Steve","subject":"trending: fix infinite-scroll stall (fill while sentinel visible) + default sort to imaged-first","body":""},{"hash":"7ee3b0f","date":"2026-07-07 06:41:48 -0700","author":"Steve Abrams","subject":"trending: expand seed to ~50 bestsellers/trending PER PLATFORM (247 items, 5 platforms)","body":"Steve: 'add 50 from each platform.' Multi-platform Exa sweep (free-tier MCP, $0) →\nbuild-scout-feed.2026-07-07.js → 247 real named bestsellers/trend-directions across:\n  Etsy 50 · Spoonflower 49 · Patternbank 50 · Google/Retail 48 · Amazon/Big-box 50\nSources: Wallpaperdirect/Morris bestsellers (Pimpernel #1, Acanthus, Golden Lily...),\nWall Blush 1291-list (Copper Garden, Jagger, Bloom Wild 4.8*/640k), Tempaper trending +\ndesigner collabs, Amazon/big-box tested winners (Rifle Paper Co, RoomMates, NuWallpaper,\nYork, Wallshoppe), Etsy top shops (Livettes/MUSE/TimelessDecorations), Spoonflower\ntop-sellers + The Home Edit + artist bestsellers, Patternbank AW26-27/SS26/SS27/Resort/\ncatwalk trend directions. 123 matched to our-own images, 124 gaps on the pending affordance.\nsignalRank is editorial ordering within each platform (not a claimed exact sales rank)."},{"hash":"eec6dc5","date":"2026-07-07 05:57:53 -0700","author":"Steve Abrams","subject":"chore: lint, refactor, v0.1.1 (session close)","body":"Lint (code-reviewer): esc() applied to 3 unescaped href URLs (card tier link + 2 matchup\nmodal links); null-guards on titleAZ/company/marketplace localeCompare sort comparators\n(crash-safety if a legacy record lacks the field); removed dead 'Object.assign;' no-op in qs().\nRefactor (javascript-pro): MS_PER_DAY constant; staleDays IIFE → plain if-block; localize-images\nMap get-or-create de-cryptified; collapsed dead duplicate 'ok' branches in loadMeta tier.\nNo behavior changes — verified: node --check clean, mapper self-test PASS, page renders,\nconsole clean, source links intact.\n\nKnown/pre-existing (not this session): hardcoded admin:DW2024! default is the fleet-wide\n401-gate convention (env-overridable via BASIC_AUTH) — surfaced, not changed."},{"hash":"00c19c0","date":"2026-07-06 21:56:57 -0700","author":"Steve Abrams","subject":"trending: self-host all card images locally (scripts/localize-images.js)","body":"'show all images, download locally first' — download the 3 distinct remote wallpapersback.com\nby-id images into public/assets/wpb/ and rewrite bestsellers.json to serve them same-origin.\nNo more hotlinking (even our own WPB) → faster + resilient if the source host is down.\nWired into refresh.sh --scout so future refreshes self-host too. Idempotent, $0 (fetches\nour own public images). 22 imaged cards now 100% local; 27 gap cards stay on the pending\naffordance (no our-own design yet — awaits gated generation)."},{"hash":"c9753c2","date":"2026-07-06 21:40:47 -0700","author":"Steve Abrams","subject":"trending: pin staleness to Steve's TZ (America/Los_Angeles) so prod (UTC) and Mac2 agree","body":"Kamatera runs UTC, so the prior local-time staleDays showed 'as of Jul 6 · 1 day ago'\non prod while Mac2 showed 'today'. spottedAt is a bare date with no tz — pin the\nreference to PT + pure Date.UTC arithmetic on both endpoints. Verified staleDays=0\nunder PT, UTC, and Tokyo. Fixed in server.js loadMeta + tick.sh."},{"hash":"74b3db6","date":"2026-07-06 21:37:04 -0700","author":"Steve Abrams","subject":"trending: LIVE refresh — 49 current 2026 bestsellers via Exa scout + local-date staleDays fix","body":"- Ran the (approved, metered ~$0.05) design-trend-scout Exa sweep: 6 searches across\n  Etsy/Spoonflower/Patternbank/Google trend forecasts + mural sources. Built a fresh\n  per-item feed (data/scout-feed.json, builder saved as build-scout-feed.2026-07-06.js)\n  and mapped it → bestsellers.json now dated TODAY (49 items, was 50 @ 2026-07-02).\n  New signals: Art-Deco now #1 by sales volume, animal-print-with-a-twist = designers'\n  top pick, grasscloth+metallic/tweed/block-print texture surge, marble soft-futurism,\n  chinoiserie crane murals, Midnight Flora, Pantone Cloud Dancer warm-neutral texture.\n- FIX: staleDays computed local-date-to-date in both server.js loadMeta and tick.sh —\n  Date.parse('YYYY-MM-DD') is UTC midnight, so a today-local date read after 00:00 UTC\n  wrongly showed '1 day ago'. Now correctly shows 'today'.\n- The board is genuinely live-fresh; the honesty gap is closed in practice, not just in code."},{"hash":"6ab84ef","date":"2026-07-06 21:28:38 -0700","author":"Steve Abrams","subject":"trending: build live-refresh wiring — scout→bestsellers mapper (DTD verdict A)","body":"Closes the contrarian's core honesty gap (a 'trending' board whose data can't move)\nWITHOUT new credentials or unattended spend — Exa is reachable only via the sanctioned\ndesign-trend-scout agent, so the buildable-now $0 piece is the deterministic mapper:\n\n- scripts/scout-to-bestsellers.js: pure/offline mapper. Accepts the scout's per-item feed\n  OR its lane-level trend-board.json, validates required fields, stamps TODAY's spottedAt,\n  emits the exact board shape. --self-test proves it end-to-end with zero network. Unknown\n  colors get a deterministic (non-random) muted-hex fallback so every card renders.\n- refresh.sh: rewritten into explicit paths — '--scout <feed>' (LIVE, $0 map+attach+reload)\n  vs '--seed' (static dev re-bake); no-arg prints guidance and does NOTHING (can't silently\n  re-bake stale data). refresh.sh NEVER runs the metered Exa pull — that stays a separate\n  gated step.\n- tick.sh refresh memo: updated — wiring is now BUILT; only the metered design-trend-scout\n  pull remains gated (then $0 map, then deploy).\n\nDTD panel 3/3 verdict A. The metered scout pull + deploy stay Steve-gated."},{"hash":"955e9e4","date":"2026-07-06 21:18:40 -0700","author":"Steve Abrams","subject":"trending: fix contrarian-caught issues (onerror injection, header overflow, cron honesty)","body":"- CRIT: image-404 fallback was silently broken — the pending block was injected via an\n  inline onerror=\"...\" string, but pending's own class=\"...\" double-quotes terminated\n  the attribute early (only single quotes were escaped). Moved the handler to a JS closure\n  over `pending` (addEventListener) — zero escaping, unbreakable. Verified: forcing a\n  404 now renders the fallback.\n- header.top: added flex-wrap + gap row + tag min-width:0 — the nowrap freshness badge\n  caused horizontal scroll on <~1100px viewports (sticky header made it persist). Verified\n  no h-scroll at 1000px.\n- tick.sh: idempotency guard scoped to -maxdepth 1 (active queue only) so a resolved-but-\n  unfixed refresh memo RE-SURFACES instead of going permanently silent; refresh memo now\n  HONESTLY states refresh.sh re-bakes identical seed data and the real fix is building the\n  live-Exa wiring (code-only/$0) + running the metered pull (the gated spend)."},{"hash":"4fe938f","date":"2026-07-06 21:09:33 -0700","author":"Steve Abrams","subject":"trending: 10-min health+opportunity tick + launchd cron (DTD verdict A)","body":"- scripts/tick.sh: deterministic $0 watcher — probes live uptime, measures data\n  staleness, detects ComfyUI; drafts a GATED refresh memo when stale>threshold (7d)\n  and an image-gap opportunity memo when ComfyUI returns. Idempotent (find-based guard).\n  NEVER auto-deploys, NEVER auto-spends (metered Exa refresh stays Steve-gated).\n- ops/com.steve.trending-dw-tick.plist: StartInterval 600 (every 10 min), RunAtLoad.\n- resolves node absolutely (launchd minimal-PATH fix) + hardened PATH.\n- ledger at data/tick-ledger.jsonl (gitignored); state in data/tick-state/."},{"hash":"ab31ac0","date":"2026-07-06 21:06:06 -0700","author":"Steve Abrams","subject":"trending: data-freshness badge + per-card spotted timestamp + gap-image pending affordance + favicon","body":"- /api/meta endpoint surfaces generatedAt/asOf/staleDays/imageGap (freshness is the product for a trending board)\n- header badge: 'as of <date> · N days ago · N signals · N img-gap', amber>3d / red>7d staleness tiers\n- per-card '🕓 spotted <date>' chip (admin-card created-date standing rule)\n- 13 image-gap cards now show an intentional 'our-lane image pending' affordance instead of a bare gradient\n- inline SVG favicon kills the /favicon.ico 404"},{"hash":"baeb0bd","date":"2026-07-03 10:17:32 -0700","author":"Steve","subject":"trending: wire 3 generated GAP originals (TR-013/014/050 texture+abstract) into cards; 37/50 now real our-own images; 13 remain (ComfyUI-down seam-gate wall)","body":""},{"hash":"bf548c9","date":"2026-07-03 10:14:37 -0700","author":"steve","subject":"gap-lane generator: 3 seam-PASS settlement-OK tiles (TR-013/014/050) + gate driver","body":""},{"hash":"bd1056c","date":"2026-07-03 09:34:08 -0700","author":"Steve","subject":"trending: scripts/push-to-shopify.js — creates DW products from DWPV queue as DRAFT (safe: refuses w/o creds, never auto-publishes); ready for token","body":""},{"hash":"732d40d","date":"2026-07-03 09:24:54 -0700","author":"Steve","subject":"trending: 'Put on Shopify' button — stages our-own designs as DW products with sequential DWPV SKUs (one SKU per unique design, idempotent); queue viewer w/ staged date+time; queue file deploy-protected","body":""},{"hash":"de3b2ec","date":"2026-07-03 09:12:48 -0700","author":"Steve","subject":"deploy: trending-dw live with real our-own images; INSTALL_CMD=true for zero-dep server","body":""},{"hash":"3c73597","date":"2026-07-03 09:11:10 -0700","author":"Steve","subject":"trending: 'our lane' caption on our-own images (honesty label)","body":""},{"hash":"eeb5aaa","date":"2026-07-03 09:04:41 -0700","author":"Steve","subject":"trending: real our-own images on every covered card (WPB originals + self-hosted in-house webp); restore it.image overlay + /api/matchup lost in mac3 migration; GAP lanes flagged for gen","body":""},{"hash":"307d7e6","date":"2026-07-03 08:08:18 -0700","author":"Steve","subject":"chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew)","body":""},{"hash":"45f6d98","date":"2026-07-02 11:47:10 -0700","author":"Steve","subject":"deploy: live at https://trending.designerwallcoverings.com (public, CF-proxied, LE SSL); prod port 9954 (9951 taken on Kamatera)","body":""},{"hash":"14d87e4","date":"2026-07-02 11:35:11 -0700","author":"Steve","subject":"features: multi-select facets + filter chips, Gap-score badges vs pattern-vault catalog, gaps-first sort, Lanes rollup view, price->DW-tier mapper, ?view= param, staged weekly refresh job (fix: restore dropped closing tags)","body":""},{"hash":"9098c9e","date":"2026-07-02 11:26:51 -0700","author":"Steve","subject":"widen data: +Society6/Redbubble/Creative Market/Patternbank rows (50 items, 8 marketplaces, 27 styles) from AW26-27 + POD bestseller research","body":""},{"hash":"a0b0437","date":"2026-07-02 11:23:13 -0700","author":"Steve","subject":"trending-dw: bestseller-intelligence dashboard (Amazon facets + new-grid + sort/density/infinite-scroll), seeded from 2026-07-02 trend research","body":""}]}