). No server\nchange required."},{"h":"8ae5031","d":"2026-05-29","s":"fix(colorways/promote): designs.json fallback + nullable FK","b":"Two issues surfaced by the loopback end-to-end test:\n\n 1. prod PG is sparse (~1.5k rows) while the shipped catalog\n (data/designs.json) has ~50k. PG lookup for the source design\n came back empty → promote silently bailed. Added an mtime-\n invalidated designs.json cache as a fallback and a defaults\n fallback when both miss.\n\n 2. spoon_all_designs has an FK on parent_design_id. When the source\n id isn't in PG (only in designs.json), inserting with that id\n violated the constraint. Now: parent_design_id only written\n when source actually exists in PG; otherwise NULL. Lineage\n stays in tags ('colorway-of-') + prompt text.\n\nVerified end-to-end via loopback admin auth on prod: save returned\nnew_design_id, /design/ served 200, image served 200, PNG\non disk (~1.2K)."},{"h":"669fc05","d":"2026-05-29","s":"add backfill-wallco-rooms.js: populate /admin/rooms gallery from the 1,421 bulk data/rooms mockups that generate_room_mockups.py never inserted into wallco_rooms (idempotent, tagged for reversal)","b":""},{"h":"6a83e70","d":"2026-05-29","s":"admin/rooms: img src prefers /designs/room/design__.png with onerror fallback to legacy image_path (fixes ~1377 broken thumbnails; mirrors prod 3dc8702)","b":""},{"h":"18b423b","d":"2026-05-29","s":"feat(colorways): admin user fallback for save/list/delete","b":"Steve 2026-05-29 'test it as admin user'. Admin auth (loopback / JWT\ncookie / ?admin=) now satisfies the trade-user gate by routing\nto a synthetic wallco_trade_users row ('admin-system@wallco.ai',\ncreated lazily on first admin use, id cached in process). All admins\nshare this row — fine since Steve is typically the sole admin."},{"h":"b6425eb","d":"2026-05-29","s":"feat(colorways): promote saved colorway to a real spoon_all_designs row","b":"When the user clicks 💾 Save colorway, the client now sends the baked\nPNG (rendered from the recolor ImageData buffer) alongside the ink_map.\nServer's POST /api/colorways/save accepts an optional data_url; if a\nvalid PNG arrives it writes the bytes to data/generated/ and INSERTs a\nnew spoon_all_designs row (parent_design_id=src, generator='colorway-\npromote', is_published=FALSE) so the colorway becomes a true product.\n\nThe new id is stored on wallco_user_colorways.new_design_id (column\nadded via idempotent ALTER) and returned in the save response. Client\nauto-navigates to /design/ after a brief toast. Chip links\nprefer the promoted clean URL over the ?cw= overlay path; older\ncolorways without a promote still fall back to ?cw= correctly."},{"h":"838401d","d":"2026-05-29","s":"Cactus curator: click a card's color dot to recolor via native color wheel","b":"Wires the dominant-color dot on each grid card to a native \npicker. On pick it POSTs to the existing /api/design/:id/recolor endpoint\n(metadata-only: updates dominant_hex in all_designs + spoon_all_designs + the\nin-memory catalog + bumps the by-color cache; image untouched). Also gates that\nendpoint behind requireAdmin."},{"h":"a72f554","d":"2026-05-29","s":"Age prompt: voice the message on load via Web Speech API (best-effort; re-tries on first gesture if the browser gates speech)","b":""},{"h":"f9d25bc","d":"2026-05-29","s":"fix(colorways): restore original chip visual after anchor swap","b":"inline-flex centering moved the v-label to the chip's center which looked\noff vs the original button (label was top-left). Switch to inline-block +\nzero padding/margin/line-height on the anchor, with display:block label\nat padding:2px 0 0 3px (matching the original button's natural rendering)."},{"h":"759068a","d":"2026-05-29","s":"trade-login: add password sign-in (env-var gated) alongside magic-link","b":"Steve 2026-05-29 'update so the un and pw work'. Magic-link still works\n(SMTP now wired on prod via env), but adds a parallel password path that\nbypasses email entirely for admin convenience.\n\nnew on /trade/login: hr-separated 'Or sign in with password' section\nunder the existing email form. Email + password fields, posts to\nPOST /api/trade/login-pw with the same returnTo round-trip.\n\nnew route POST /api/trade/login-pw: env-var gated single-user admin\nbypass. Reads TRADE_ADMIN_EMAIL + TRADE_ADMIN_PASS, constant-time\ncompares via crypto.timingSafeEqual after length-equal check (length\nleak acceptable vs returning early on mismatch). On match: upserts\nwallco_trade_users row, mints the SAME 14-day JWT + cookie as the\nmagic-link /trade/auth handler, applies same admin-promotion via\nWALLCO_ADMIN_EMAILS, logs trade_login_pw_success to wallco_audit_log.\nOn fail: logs trade_login_pw_fail + 600ms delay + 401.\n\nNo bcrypt, no schema change. Security model = HTTP basic equivalent\nfor a single-user env-var bypass. Multi-user/proper hashed creds is\na future change (Option B2 from the debug-agent analysis); deferred\nuntil trade signup is actually live.\n\nverified Mac2:\n - wrong pw → 401 'Invalid email or password.'\n - correct pw → 200 ok:true + Set-Cookie wallco_trade_session +\n Set-Cookie dw_auth (admin-promote landed because Steve's email\n is in WALLCO_ADMIN_EMAILS)\n - GET /trade/login serves the new form\n\nverified prod (surgical port via python str.replace, both anchors\nfound exactly once + node -c passed before scp):\n - POST /api/trade/login-pw without env vars → 503 'not configured'\n (route loaded but TRADE_ADMIN_PASS not yet set on prod)\n - GET /trade/login serves the new form\n\nstill pending: TRADE_ADMIN_EMAIL + TRADE_ADMIN_PASS in prod /root/\npublic-projects/wallco-ai/.env. Steve to provide the password value\nout-of-band; will append + pm2 reload --update-env when received."},{"h":"1950b74","d":"2026-05-29","s":"feat(colorways): clicking a saved colorway chip opens it as a product","b":"Chip is now a real link — right-click\nopens in new tab, share/bookmark works. Plain click still applies the\ncolorway in-place (instant) but also pushes the ?cw= URL via\nhistory.pushState so the browser state reflects the new-product view.\n\nOn any /design/$id?cw= load, applyFromUrl() looks up the colorway\nand applies it automatically. Modifier/middle clicks fall through to\nbrowser-native open-in-new-tab."},{"h":"1ed5276","d":"2026-05-29","s":"Age prompt: add 'We are asking to serve the best theme for your eyes.' line on the first-visit age overlay","b":""},{"h":"4e1f5e0","d":"2026-05-29","s":"feat(theme-gallery): width + height sliders, dynamic resize on input","b":"Replaces the discrete Desktop/Tablet/Mobile segmented control with\ntwo continuous range sliders (room width 320-1920 / height 480-2400).\nEach input event rAF-throttles a rescale() so dragging stays smooth.\nThe 3 presets are kept as quick-set buttons (set BOTH dims at once,\nhighlight when both match). Sliders persist via localStorage keys\ntg-vw and tg-vh."},{"h":"58b694b","d":"2026-05-29","s":"Save-this-colorway: per-user EXCLUSIVE versioned colorways. New src/colorways.js (wallco_user_colorways table + /api/colorways save/list/delete, trade-auth gated); color-dots.js gains Save button + version rail (jump to any saved version) + reset. Verified authed round-trip v1/v2 + unauthed 401","b":""},{"h":"69f306b","d":"2026-05-29","s":"color-dots: interactive recolor — click a dot to open an HSV color wheel, drag to pick a new ink, pattern live-recolors that ink (per-pixel delta preserves texture). Applies across all 17 variants + classic PDP","b":""},{"h":"6f2666d","d":"2026-05-29","s":"cactus-curator: select-all button + live-animate-out + auto-force-publish UX","b":"three small UX upgrades on the same surface, in flight since the earlier\n'debug why i cant publish anything' + 'allow user to select 1 to all\nin check marks' interrupts.\n\n1. select-all toolbar button — '☑ Select all visible' next to Auto-ID.\n Click once: every visible card gets sel-class + adds to selected set\n and bulk-bar appears. Click again (or once all selected): clears.\n Skips .moved-to-etsy mid-animation cards so a recent decision doesn't\n sneak back into the next bulk action.\n\n2. Publish on gate-fail now visually completes — added 'live' to the\n per-card animate-out action set so when the auto-force-publish lands,\n the card fades out (was sitting there with ✓ PUBLISHED pill while\n Steve was puzzled why nothing visibly happened). The local model is\n patched (is_published=true, web_viewer=true, user_removed=false,\n needs_fixing_at=null) inside the force-success branch so filter\n re-renders won't bring it back.\n\n3. force-publish success branch in decide() now also animates out the\n element after patching the local model — matching the gate-pass live\n path. Without this the 'auto-force-publishing…' toast shows, the row\n flips in PG, the local model updates, but the card sits there\n indefinitely with ✓ PUBLISHED until you refresh.\n\nverified locally + on prod: HTML serves 90679 bytes, all 4 new code chunks\npresent in prod-served response."},{"h":"8e67419","d":"2026-05-29","s":"Add color-dots.js: vertical strip of the pattern's screen-print ink colors (canvas-extracted) along the left edge of every pattern, included across all 17 PDP theme variants","b":""},{"h":"8c1ed72","d":"2026-05-29","s":"revert: theme1/theme2 toggle on /designs admin (was super-zooming cards)","b":"Steve 2026-05-29 'i ages should not be superzooom on load.. revert\nhttps://wallco.ai/designs'. Removes the admin-only theme toggle added\nin 49dcd87a.\n\nRoot cause: the theme2 CSS overrides used `background:var(--card-bg)`\nSHORTHAND on the catch-all [class*=\"card\"] selector. With higher\nspecificity than .card-img, this reset background-size from 'cover'\nback to 'auto' — so every card-img rendered its 1024px source PNG at\nnatural size inside a 256px box. Result: each card showed ~1/16 of the\noriginal tile = super-zoom. Per-card looked like one giant motif filling\nthe card instead of the seamless-repeat preview.\n\ngit revert would not auto-merge cleanly (later commits in same area).\nManual surgical removal of the conditional admin block. /design/:id\nkeeps its own theme toggle separately (c26ba53e fix). Grid is now\nback to the default cream/warm theme for everyone.\n\nverified: prod /designs returns 200, grep 'data-page-theme' = 0."},{"h":"300315d","d":"2026-05-29","s":"C-bridge (DTD interim): patchDesignsSnapshot() persists curator publishes into designs.json (is_published/user_removed/force-tag + resolve real filename from PG) + reload, so grid+PDP+persistence all agree. Wired into bulk + single publish paths","b":""},{"h":"c090fe6","d":"2026-05-29","s":"addToIndex: derive filename from image_url so designHasImage grid filter can match (one more structure-matrix seam)","b":""},{"h":"7e0d667","d":"2026-05-29","s":"Add addToIndex(): surface curator-published designs on the storefront immediately (mirror of dropFromIndex) — overrides stale snapshot user_removed/is_published + aesthetic gate; PDP now 200. Grid-listing filter gap remains (structure-matrix)","b":""},{"h":"49dcd87","d":"2026-05-29","s":"feat(designs grid): admin-only theme1/theme2 toggle on /designs","b":"Same pattern as /design/:id. Scoped to #grid-main, shares the\n'wallco-page-theme' localStorage key so an admin's choice flows\nacross grid + PDP. Public users see vanilla theme1."},{"h":"bda32cf","d":"2026-05-29","s":"audit: bulk-publish 246 muybridge-plate designs (force=true past gate)","b":"Steve 2026-05-29 'now bulk publish muybridge-plate'. First mass-publish\nusing the new auto-Publish-anyway behavior (cactus-curator bulk now\nsends force=true, server bypasses runPublishGate per id).\n\nscope: category='muybridge-plate' (base only — not the 16 colorway\nsub-categories). 246 undecided designs flipped to is_published=TRUE.\n\nresult:\n before: 174 pub / 246 undecided / 156 removed (576 total)\n after: 420 pub / 0 undecided / 156 removed (576 total)\n\nflow: POST /api/cactus-decision/bulk action=live force=true on mac2\n(28s wall — ~115ms per id for the psql UPDATE) → snapshot refresh\n(34,429 → 34,430 designs) → scp designs.json to prod → /admin/reload-\ndesigns hot-reload.\n\ncustomer-facing delta: prod DESIGNS in-memory grew 3476 → 3705 (+229).\n17 of the 246 didn't load into the live index (missing local_path or\ndesignHasImage filter), but their PG row says published. acceptable.\n\nverified: sample of 5 newly-live design pages on https://wallco.ai\nreturn HTTP 200.\n\nrisk note: 246 designs that did NOT clear settlement+edges+ghost+seam\ngates are now live. Steve's stated mitigation: post-hoc triage via\nthe new Haiku-chip layer on /admin/cactus-curator + one-click\nUnpublish for any that surface as defective."},{"h":"925a444","d":"2026-05-29","s":"fix(blank-guard): un-blank 3510/3529 (imperial-garden colorways, false positives)","b":"detect-blank-designs.js had flagged 3510 + 3529 as failed-generation blanks, so\nloadDesigns() skipped them from every grid/listing (line 493) — but they're real\ntone-on-tone floral colorways (61-68KB, render fine via by-id). They showed in\nthe curator (reads PG) but never reached wallco.ai/designs. Removed both from the\nblank_ids list (1282 -> 1280) on Mac2 + prod, reloaded. All 33 imperial-garden\ncolorways now live on the public grid."},{"h":"c26ba53","d":"2026-05-29","s":"fix(design page): gate theme1/theme2 toggle to admin-only","b":"Per Steve 2026-05-29 'all for the admin account level' — public visitors\nwere seeing the placeholder theme2 styling and the toggle UI. Now the\nentire block (data-page-theme attr, scoped CSS, toggle UI, persistence JS)\nrenders ONLY when _isAdmin is true. Public users see vanilla theme1\nmarkup with no toggle."},{"h":"b75d7f3","d":"2026-05-29","s":"audit: bulk Bad 39 flagged-live designs from haiku full-sweep triage","b":"triage of the 39 undecided drunk-animals* designs Haiku 4.5 flagged in\nthe live bucket of the full sweep (847 designs total, mac2 yolo-loop on\nmax plan). all 39 were is_published=FALSE/null (undecided in curator\nqueue), not customer-facing. action=bad quarantines the PNGs +\nuser_removed=TRUE so they drop from the curator queue too.\n\nOTHER (26):\n #54134 #54136 #54139 #54143 #54148 #54149 #54154 #54155 #54171\n #54176 #54177 #54183 #54190 #54195 #54201 #54210 #54211 #54213\n #54222 #54229 #54240 #54253 #54260 #54285 #54287 #54293 #54318\n #54321 #54329 #54334 #54337 #54341\n (aesthetic breaks, halftone violations, metallic gradients, garbled\n text 'TEST FERA OOTOA ND GAR', empty failed gens, posterized photos,\n hard panel edges)\n\nTONE_BREAK (7):\n #54134 #54136 #54177 #54190 #54201 #54210 #54255\n (hard L/R or T/B seam discontinuities)\n\nGHOST (4):\n #54237 #54245 #54327 #54342\n (multi-opacity translucent layers behind motifs)\n\nMURAL_MISCLASS (2):\n #54225 #54313\n (single-subject scenes mis-tagged as tileable)\n\nflow: POST /api/cactus-decision/bulk action=bad on mac2 → quarantine\nPNGs to data/generated_cactus_quarantine/ → snapshot refresh → scp\ndesigns.json to prod → /admin/reload-designs hot-reload.\n\nrunning tally: 7 (smoke goods) + 20 (full-sweep goods unpublish) + 39\n(full-sweep live bad) = 66 defective designs surfaced and acted-on by\nthe haiku-vision pass today, at $0 API spend."},{"h":"6e172f4","d":"2026-05-29","s":"feat(curator): force-publish stoned-animals (Steve explicit override 2026-05-29)","b":"716 stoned-animals were bulk-marked 'bad' 2026-05-28 (user_removed) and fail the\n100% gate (seam + off-concept). Steve explicitly overrode both removal and gate.\nforce-publish-stoned.sql flips is_published in all_designs + spoon_all_designs\nunder SET LOCAL settlement.allow_override, tags curator-force-publish (exempts the\nload-time passesAestheticGate), then snapshot rebuild + ship makes them live.\npublish-stoned-animals.js is the gated alternative (kept for future categories).\n\nCo-Authored-By: Claude Opus 4.8 (1M context) "},{"h":"c9f199f","d":"2026-05-29","s":"Honor force in bulk /api/cactus-decision live path — bulk Publish now bypasses the 100% gate (frontend already sent force:true; backend was dropping it → everything parked)","b":""},{"h":"08eb2ac","d":"2026-05-29","s":"Fix cactus-curator 'Published only' toggle to filter the main grid (was stack-only; now drives the #filter dropdown via change event)","b":""},{"h":"2547596","d":"2026-05-29","s":"cactus-curator: auto-select 'Publish anyway' on gate-held (per-card + bulk)","b":"Steve 2026-05-29 'always select: Publish anyway on autop'. Publish click\nis now an unconditional decision — the publish gate becomes ADVISORY,\nnot blocking.\n\nper-card (decide()): when /api/cactus-decision/:id returns gate_held=true,\nno longer shows the 'Publish anyway' toast button. Instead, displays a\nbrief amber info toast with the gate reasons + auto-fires the force=true\nfollow-up call. The card lands on ✓ PUBLISHED in <500ms.\n\nbulk (bulk() for action='live'): now sends body.force=true. The\nserver-side bulk handler at /api/cactus-decision/bulk already supports\nforce (Steve shipped that plumbing earlier) — pass it through and ALL\ngate-held items go live without parking.\n\nimplication: this overrides the standing 'feedback_only_clean_designs_\nwelcome' default — once you click Publish, the design goes live even\nif settlement/edges/ghost/seam gates fail. Defective designs WILL slip\nthrough on bulk Publish of large categories (muybridge-plate has 2054\nundecided rows = potential to mass-publish many defects).\n\nmitigation moving forward: the new haiku-vision chip layer (also shipped\ntoday) surfaces defects post-hoc on /admin/cactus-curator, and the new\nunpublish button takes them down with one click. Steve's curate-fix-loop\nmodel: 'I trust my Publish click, I'll catch defects via Haiku-chip\ntriage after the fact.'"},{"h":"89d7ad5","d":"2026-05-29","s":"Fix publish-gate.py prod fail-closed: use resolved image path for seam scan (not dead Mac2 local_path) + PIL resize instead of macOS-only sips for vision JPEG","b":""},{"h":"96e8588","d":"2026-05-29","s":"fix: /api/design/:id/fix reads all_designs first (spoon fallback) so it stops falsely reporting 'image file not found' on curator-visible designs that drifted out of spoon_all_designs","b":""},{"h":"dd42e27","d":"2026-05-29","s":"audit: unpublish 20 more flagged-goods from haiku full-sweep triage","b":"triage of the 27 goods Haiku 4.5 flagged in the full sweep (847 designs\ntotal, mac2 yolo-loop on max plan). 7 had already been unpublished from\nthe goods-smoke; this commit removes the remaining 20:\n\nOTHER (8) — aesthetic breaks (posterization, smearing, garbled text):\n #53657 #53655 #53670 #53678 #53685(skip) #53711 #53723 #53885 #53965\n\nMURAL_MISCLASS (7) — single-subject scenes mis-tagged as tileable:\n #53652 #53653 #53654 #53656 #53660 #53665 #53667\n\nGHOST (4) — halftone-stipple instead of solid screen-print:\n #53866 #53888 #53979 #53987\n\nFUZZY_SEAM (1) — smeared midline band:\n #53968\n\nall 20 in drunk-animals* categories (drunk-animals, -sample, -sample2,\n-sample3, -sample5, -replfast) — likely escaped curator from earlier\ngeneration experiments.\n\nflow: POST /api/cactus-decision/bulk action=unpublish on mac2 → snapshot\nrefresh → scp designs.json to prod → /admin/reload-designs hot-reload.\n\nverified: prod DESIGNS shrunk 2747 → 2727 (exactly 20 dropped). all 20\ndesign pages on https://wallco.ai return HTTP 404. running tally: 7+20=\n27 published-but-defective designs the haiku-vision pass surfaced and\ntook down today, at $0 API spend."},{"h":"cf75a5c","d":"2026-05-29","s":"fix(publish-gate): sudo-psql on Linux + image-path fallback — gate falsely failed on prod","b":"Two infra false-fails made the publish gate park EVERY design on prod (never a\nreal quality verdict):\n1. psql() ran bare 'psql dw_unified' as the current user. On prod pm2 runs node\n (and the gate) as root, but PG has no root role → empty result → gate\n reported 'design not found' and parked the publish. Now uses\n 'sudo -n -u postgres psql' on Linux, matching lib/db.js PSQL_CMD.\n2. Image resolution only tried local_path (a Mac2-style /Users/... path that\n doesn't exist on prod) → 'image file missing/unreadable'. Now falls back to\n data/generated/ + quarantine dirs, same chain\n as the by-id handler.\n\nSurfaced when bulk-publishing colorways-imperial-garden-barone: '0 published,\n5 parked (gate)' though the designs render fine. No quality logic changed."},{"h":"79f45cc","d":"2026-05-29","s":"Add 6 room-left PDP theme variants V12-V17 (room setting left of pattern, adjustments in a hamburger selector) + routes + Theme submenu + gallery entries + admin-tabs nav link","b":""},{"h":"0b5f501","d":"2026-05-29","s":"cactus-curator: per-card Bad/Digital/Unpublish animate out + reset stale 'all' filter","b":"two UX fixes Steve flagged 2026-05-29 ('bad bulk not working / nor a\nbad hook... debug' + 'how do i see published/unpublished/undecided???'):\n\n1. per-card decide() for bad/digital/unpublish now mirrors bulk: add\n 'moved-to-etsy' class + setTimeout(el.remove, 300). The SQL update\n was already firing correctly — the bug was visual. Card sat there\n with a REMOVED pill making the click feel broken. Etsy + Live skip\n this branch (Etsy self-hides, Live should stay visible).\n\n2. one-time localStorage migration: stale cc_filter='all' resets to\n 'undecided' (the in-code default). without it, prior sessions\n pinned the Show dropdown to 'All (live)' which kept Bad-removed\n cards visible. After the migration runs once per browser, future\n manual filter picks are still honored.\n\nrelated cleanup: confirmed per-card Bad on a real id (#9840) returns\n{ok:true, action:bad} and the PG row has is_published=f, user_removed=t —\nthe action was always landing, just invisible."},{"h":"fe9624d","d":"2026-05-29","s":"harden(db): psqlExecLocal throws on psql error (ON_ERROR_STOP=1)","b":"psqlExecLocal ran psql with no ON_ERROR_STOP, so a SQL error printed the\nmessage but psql exited 0 — execSync didn't throw and the caller mistook the\nfailure for success. That masked the prod incident where all_designs rejected\nevery UPDATE (no replica identity, in an update-publishing publication) yet the\ncurator returned applied:N and persisted nothing.\n\nNow the write path runs ON_ERROR_STOP=1 and throws a clean Error carrying\npsql's stderr + exitCode. ON_ERROR_STOP stops on ERROR only (NOTICE/WARNING\npass), so boot-time CREATE ... IF NOT EXISTS is unaffected. Reads (psqlQuery)\nleft lenient. No DDL routes through psqlExecLocal (110 callers are DML in\ntry/catch'd handlers). Tested Mac2: success clean, missing-table/syntax throw\nwith the ERROR line, NOTICE no-throw, server boots, write persists+restores."},{"h":"f6e3188","d":"2026-05-29","s":"cactus-curator: haiku-vision chips + Fix-now heal pipeline w/ rollback","b":"new in cactus-curator (Steve 2026-05-29 — built while the haiku-weekend\nfull sweep was finishing):\n\n1. Haiku verdict chip on every card the weekend pass flagged. read from\n data/haiku-weekend-*.jsonl via new GET /api/admin/cactus/haiku-verdicts.\n per-defect color-coding (ghost=red, fuzzy_seam/tone_break=amber,\n mural_misclass=orange, ok=green, etc.). reason in hover-title.\n\n2. Fix button now ALSO triggers the seam-heal pipeline in-place — not just\n stamp needs_fixing_at. POST /api/design/:id/fix runs scripts/fix-seam.py,\n promotes the healed PNG to canonical, backs up original alongside as\n __preseam.png. result lands in-card via cache-busted img refresh.\n\n3. New POST /api/design/:id/restore-preseam — swaps __preseam.png backup\n back to canonical to roll back a heal that made things worse.\n\n4. In-card 'chat panel' below each fixed card shows: what fix-seam did\n (fixed/already-seamless/no-change + duration), the haiku reason that\n triggered it, and a Restore button when a backup exists. honors the\n Round-1-sacred rule: in-place pixel surgery only, no SDXL re-roll.\n\ndtd-ratified path A. local verified: endpoints respond correctly,\nhaiku-verdicts returns 847 entries from the completed weekend sweep,\nHTML embeds new code chunks. NOT yet pushed to prod (will likely\nauto-sync via same mechanism that propagated unpublish button earlier;\nif not, surgical-port + scp)."},{"h":"2c77613","d":"2026-05-29","s":"Add Theme Gallery link to admin-nav hamburger (sibling of Room Renders Gallery)","b":""},{"h":"d65186a","d":"2026-05-29","s":"Add admin Theme Preview Gallery (/admin/theme-gallery) — all 11 PDP theme variants side-by-side per design, viewport toggle, created-date chip","b":""},{"h":"61fa817","d":"2026-05-29","s":"audit: unpublish 7 designs caught by haiku-weekend goods-smoke","b":"audit log entries for the 7 published-but-defective designs the haiku\n4.5 vision pass flagged in the goods-smoke bucket. all 7 had passed\nthe existing publish gate but were real defects on second-look:\n\n #53651 mural-misclass (single ape-in-jungle, not tileable)\n #53690 muddy aesthetic break\n #53755 cactus category mismatch\n #53872 multi-opacity photo fragments\n #53908 partial-opacity duplicate silhouettes\n #53937 garbled AI text 'lUoe nlbmaa'\n #53963 gibberish bottle-label + posterized shading\n\nflow: POST /api/cactus-decision/bulk action=unpublish on mac2 →\nrefresh_designs_snapshot.py → scp designs.json to prod → POST\n/admin/reload-designs. all 7 design pages on https://wallco.ai now\nreturn 404. prod DESIGNS array shrunk 2754 → 2747."},{"h":"9d53444","d":"2026-05-29","s":"cactus-curator: add Unpublish action (kbd 6) + button","b":"new 5th cactus verdict 'unpublish' — soft take-down that sets\nis_published=FALSE + web_viewer=FALSE only. NO quarantine, NO\nuser_removed flag, NO tagging. Fully reversible via the existing\n'live' (Publish) action (will re-gate).\n\nuse case (Steve 2026-05-29): the haiku-weekend smoke caught designs\nthat were published-but-shouldn't-be (#53651 mural-misclass,\n#53908 ghost). 'Bad' is too destructive (quarantines PNG), 'Digital'\nmis-tags them as etsy-digital. 'Unpublish' is the clean take-down.\n\nserver.js: new branch in applyCactusDecision, both single-id +\nbulk action validators updated, dropFromIndex condition extended\nso the SKU leaves the live in-memory index immediately.\n\ncactus-curator.html: 3 new buttons (per-card, bulk-bar, modal-acts),\nslate-gray .unpub color class to distinguish from destructive .bad,\nkeyboard shortcut '6', optimistic state-patch in both decide() and\nbulk(), bulk-confirm dialog. status-pill labels for unpublish action.\n\norphan node process on Mac2 was holding port 9905 — killed PID 83855\nto let pm2 take over with the new code.\n\nverified locally: bogus action returns 'must be bad|digital|fix|live|unpublish';\nunpublish on a non-existent id returns 'design not found' (validator\npasses, lookup fails as expected).\n\nNOT deployed to prod yet — needs surgical-port per\n[[feedback_wallco_ai_mac2_prod_serverjs_drift]] (server.js drift)."},{"h":"77af6a2","d":"2026-05-29","s":"feat(contact-sheet): room-setting thumbnails + wallco.ai footer + 8-col cap","b":"loadChain tries the living-room mockup first, falls back to the flat tile for\ndesigns with no room render. Footer bar with centered wallco.ai wordmark + count.\nColumn cap 6 to 8 for wider sheets.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) "},{"h":"3778fde","d":"2026-05-29","s":"fix(cactus-curator): batch bulk-delete + drop removed SKUs from live index","b":"Two bugs in the /admin/cactus-curator bulk action bar:\n\n1. BULK DELETE FORK STORM. The frontend bulk() fired an un-awaited decide()\n per selected id — N concurrent fetches, each hitting applyCactusDecision\n which spawns a psql process (psqlExecLocal=execSync). A few-hundred-card\n 'Bad — remove all' became a few-hundred-way psql fork storm that timed out\n and left the delete half-applied. Now bulk() makes ONE batched request to\n /api/cactus-decision/bulk, which collapses bad/digital/fix to a single\n 'WHERE id IN (...)' UPDATE (one psql spawn). 'live' stays per-id (each\n design must clear its own publish gate). Cards are removed from the grid on\n success; failures roll back the optimistic state.\n\n2. REMOVED SKUs LINGERED ON THE LIVE INDEX. applyCactusDecision('bad'/'digital')\n only wrote PG — it never touched the in-memory DESIGNS array, so a removed\n design (and its SKU) stayed on the public /designs grid + /api/designs +\n by-color until the next refresh_designs_snapshot.py + reload-designs. New\n dropFromIndex(ids) helper splices removed designs out of the live catalog in\n one backward pass + bumps the by-color cache version, so SKUs leave every\n public surface immediately. Wired into both the single applyCactusDecision\n (bad/digital) and the batched bulk endpoint.\n\nTested on Mac2: bulk 'digital' on a published id returned dropped_from_index:1,\nlive index 2754->2753, design no longer served by /api/designs; restore put it\nback to 2754. Input guards (empty ids, bad action) return 400. Frontend inline\nJS syntax-checked."},{"h":"6ef7cef","d":"2026-05-29","s":"Add sweep-orphan-rooms.py: remove unreferenced room PNGs (dry-run default, --delete/--verify), reclaimed ~1.7GB on prod","b":""},{"h":"9b7f1eb","d":"2026-05-29","s":"feat(designs-grid): Contact sheet button on admin bulk-select toolbar","b":"Select N cards (checkbox / rubber-band drag) then '\\U0001F4C7 Contact sheet' builds\na client-side canvas montage (cover-fit grid + header + per-card DIG/SKU label)\nand downloads a PNG. Zero server load, no new endpoint. Images sourced from the\nstable /designs/img/by-id/:id route — parsing card background-image was\nunreliable (lazy-loaded / var(--card-bg) backgrounds rendered every cell\n'image unavailable').\n\nCo-Authored-By: Claude Opus 4.8 (1M context) "},{"h":"875105c","d":"2026-05-29","s":"haiku weekend test: yolo-queue runner (max-plan path) + SQL fixes","b":"new: scripts/queue-haiku-yolo-tasks.js — generates yolo-queue tasks\nfor the weekend recall test running under Steve's Max plan (Claude\nCode via yolo loop, not developer API). Same sampling, same rubric,\nJSONL output aligned with haiku-weekend-summary.js. Batches 15 designs\nper task to stay under MAX_TURNS=30 + 25min wallclock; defaults to\n3-batch smoke before committing to full sweep.\n\nfix: SELECT DISTINCT + ORDER BY random() is illegal in PG ('ORDER BY\nexpressions must appear in select list'), but psql exits 0 silently\non SQL errors by default — bulk-tag queries were returning empty\nstrings, fetchBads returned just the 13 gold rows. Two-part fix:\n(1) psql helper now passes -v ON_ERROR_STOP=1 so syntax errors fail\nloudly, (2) bulk-tag query wraps DISTINCT in an inner subquery + sorts\nrandom in the outer.\n\nfix: live-queue query was hitting needs_fixing_at on spoon_all_designs\nview (which doesn't expose that column — view is a strict subset of\nall_designs). Switched FROM to all_designs directly + added user_removed\nguard for the proper 'undecided' filter.\n\nverified: dry-run now returns 500 bads + 226 goods + 200 live = 838\ndesigns across 56 batches (vs previous broken 13+226+0=239)."},{"h":"d335cbc","d":"2026-05-29","s":"Add rollback-photoreal-rooms.py: regenerate living_room mockups via :3075 service, explicit served-dir output, no PG dependency","b":""},{"h":"431fbf5","d":"2026-05-29","s":"haiku 4.5 weekend defect-scan test scripts + monday summary","b":"build the runner (test-haiku-vision-weekend.js) and analyzer\n(haiku-weekend-summary.js) for the weekend recall test against\ndocumented Gemini blind spots (tone-on-tone seam breaks, fuzzy\nheal bands at tile midlines, mural-misclass).\n\ndtd verdict A (unanimous Claude+Codex, qwen errored): multi-label\nrubric (OK/GHOST/FUZZY_SEAM/TONE_BREAK/MURAL_MISCLASS/VENDOR_LEAK/\nBLEED/OTHER) gives per-category recall measurement vs binary or\nidentical-prompt head-to-head.\n\nguards: budget cap ($10 default, auto-exit), 400ms rate limit,\ndry-run default, resumable JSONL, auto-pause on 3 consecutive 5xx,\nnever touches is_published.\n\nground truth: bad_examples PG table weighted across vision-relevant\ndefect_tags + is_published=TRUE post-2026-05-27 (curator-approved)\n+ live curator queue.\n\nsummary script computes per-tag recall on bads, FP rate on goods,\ngemini-disagreement set (top-N each direction) for monday triage.\n\nblocked on credits — $0 balance per /v1/messages 'credit balance\ntoo low' error 2026-05-29."},{"h":"63833d5","d":"2026-05-29","s":"security: remove vestigial admin:DWSecure2024! basic-auth string","b":"The wallco admin gate (src/admin-gate.js) authorizes via localhost / signed\ndw_auth JWT (AUTH_DEV_SECRET) / ADMIN_TOKEN — there is NO basic-auth password\ncheck. admin:DWSecure2024! in the reload-designs curl examples + the etsy\nmockup-queue script was sent in the -u/auth flag but never validated; those\ncalls work because they hit 127.0.0.1 (localhost tier). Drop the dead string\nso it stops looking like a live credential in tracked files (and in backups)."},{"h":"692c3ba","d":"2026-05-29","s":"Update Claude model IDs to claude-opus-4-8 (Opus 4.8 upgrade)","b":"Co-Authored-By: Claude Opus 4.8 (1M context) "},{"h":"84a88cf","d":"2026-05-29","s":"docs: Digital Downloads app delivery runbook (chosen over webhook/token path)","b":""},{"h":"52f07a5","d":"2026-05-29","s":"chore(gitignore): ignore timestamped *.bak.* runtime backups","b":"designs.json.bak. files (written by the snapshot-refresh + mockup-queue\nauto-refresh) ended in . not .bak, so neither *.bak nor *.bak-* caught\nthem and they cluttered git status. Add *.bak.* to cover the pattern."},{"h":"ccbd1fb","d":"2026-05-29","s":"feat(mockup-queue): auto-refresh designs.json + hot-reload server after batch","b":"Without this, the customer-facing chip count on /designs stays stale until a\nmanual refresh_designs_snapshot.py + /admin/reload-designs. Fires only when\nok>0 and --no-auto-refresh not passed.\n\nCo-Authored-By: Claude Opus 4.8 (1M context) "},{"h":"13587cd","d":"2026-05-29","s":"fix(by-id-image): query all_designs not spoon_all_designs in PG fallback","b":"Mac2: spoon_all_designs is a view of all_designs — same rows either way.\nProd: spoon_all_designs is an INDEPENDENT sparse table (~350 rows) while\nall_designs holds the historical catalog (5170 drunk-animals alone). The\nold query returned 0 rows on prod, so d stayed undefined and the handler\n404'd despite the PNG sitting on disk.\n\nSurfaced when the cactus-curator showed 90 PUB-badged drunk-animals\nwith blank images. Now /designs/img/by-id/9883 -> 200 on prod."},{"h":"4781d58","d":"2026-05-29","s":"fix(by-id-image): add IMG_DIR + basename(local_path) candidate","b":"When prod PG carries a Mac2-style absolute path (/Users/stevestudio2/.../\ndata/generated/X.png) the old resolution chain (lp1 -> local_path ->\nquarantine) never tried IMG_DIR + basename. Result: cards with PUB\nbadges in admin curators rendered with blank images because the by-id\nhandler 404'd despite the PNG sitting on prod disk under the same\nbasename.\n\nSurfaced 2026-05-29 on /admin/cactus-curator?category=drunk-animals:\nprod PG had 90 drunk-animals as is_published=TRUE but Mac2 PG (source\nof designs.json snapshot) had them as FALSE -> filtered out of DESIGNS\nat boot -> PG fallback supplied Mac2 local_path -> 404. Now IMG_DIR +\nbasename hits, file serves. No regression on IDs already resolving."},{"h":"5c516fe","d":"2026-05-29","s":"feat(pdp): V11 Best-of composite — merge V1+V3+V9 strengths","b":"Pinned hero L (V3) + sticky tabbed buy rail R (V3 tabs in V1 rail) + V9's\n3-up Pattern/Room/At-Scale preview row below the fold + full-width Pairs\ngrid + 3-up footer accordions for deep-tail content (generator, tags,\nmotifs).\n\nRight rail tabs: Buy (CTAs always visible above tabs + calc + palette +\nadjust) · Specs · Coords · Trade · Share. /design/:id/best route + ★\nRecommended menu entry placed just below Classic."},{"h":"74ee628","d":"2026-05-29","s":"docs: SHOPIFY-WEBHOOK-REGISTRATION one-pager (UI registration path bypasses read_orders scope gap)","b":""},{"h":"34281f4","d":"2026-05-28","s":"feat(pdp): V4-V10 theme variants — full 10-variant Theme submenu","b":"Adds 7 standalone PDP layouts at /design/:id/{hero,vertical,drawer,editorial,\nspec,config,stack}, each fetches /api/design/:id. Hamburger Theme submenu now\nlists all 10 + Classic. Shared themeVariantSend() helper. No template-literal\nsurgery; all variants live in public/theme-variants/v{N}-*.html.\n\nV4 hero — full-bleed top hero + narrow 640px buy column + 11 accordions\nV5 vertical — 720px stack + 14 accordions + fixed floating buy bar\nV6 drawer — minimal page + 12 chips that open right-side dark drawers\nV7 editorial — magazine layout: 70vh hero w/ pull-quote, 2-col body + marginalia\nV8 spec — wine-list 20-row spec table right, image left\nV9 config — calculator UP TOP (4-step) + big-CTA, hero shrunk to 1/3\nV10 stack — single 1080px column of standalone section cards"},{"h":"441d381","d":"2026-05-28","s":"/designs: replace binary 'In a room' chip with a chip row — All / Any / 🛋 Living / 🛏 Bedroom / 🍷 Dining / 💼 Office. Each chip shows a count + dims to 45% opacity when count=0. Server filter accepts specific room type (room_mockups[] contains the value) OR binary 'any' (length > 0). Breadcrumb reads 'In a bedroom' etc instead of generic 'In-room previews'","b":""},{"h":"06db4d7","d":"2026-05-28","s":"feat(pdp): V3 Sticky Hero + Tabs theme — /design/:id/tabs + Theme submenu entry","b":"Pinned full-height hero column left, right pane is a 6-tab surface\n(Buy / Specs / Coords / Room / Trade / Share). Each tab content lives in\nits own panel; client-side tab switcher. Reuses /api/design/:id;\nno template-literal surgery."},{"h":"701c89a","d":"2026-05-28","s":"feat(pdp): V1 Two-Column Compact theme — /design/:id/compact + Theme submenu entry","b":"Image left 60% / sticky buy rail right 40% with 8 collapsed accordions\n(specs / paints / stripes / share / furnish / trade / ratings / generator).\nFetches /api/design/:id like V2; adds V1 entry above V2 in the hamburger\nTheme submenu."},{"h":"83ea0b2","d":"2026-05-28","s":"polish pass (#1+#2+#5 of 'all 6 threads'): (1) loop.sh singleton — flock-style mkdir lockdir + stale-pid cleanup, stops the 5-concurrent-instance dup-disaster that ran tasks 39/40/44 each 3x today. (2) server.js ensureUpscaleBytesColumn() migration — fresh DB schemas get the byte-budget cache column. (5) wall-viewer iframe — auto-fit height via onload + ResizeObserver, no border, color-scheme:light so it inherits page theme. PLUS scripts/queue-room-mockups-for-etsy-bucket.js (dry-run default, /bin/zsh.10/call ROOM_API, --commit flag to actually spend) + scripts/stripe-room-upsell-scaffold.md (architecture doc for future paid-tier on ROOM_API). #3 resolved by regenerating bundles via byte-budget refactor — 12 bundles all under 72.1 MB","b":""},{"h":"7f1d2f6","d":"2026-05-28","s":"feat(pdp): theme submenu inside UR hamburger — Classic + V2 Bento Grid","b":"Adds 'Theme ▾' parent to the unified hb-menu dropdown with a nested submenu\nlisting layout variants. V2 Bento Grid links to /design/:id/bento (already\nshipped). Submenu collapses by default, caret rotates on expand, styled to\nmatch the existing hb-menu luxe-dark aesthetic."},{"h":"2973b9e","d":"2026-05-28","s":"scripts: stamp-shopify-bundle-metafields.js — repeatable stamper for wallco_ai.* product metafields","b":"Tool that brings any pre-webhook bundle product up to the 4-metafield\nshape that the orders/paid webhook handler needs to mint per-order\ndownload tokens:\n\n - wallco_ai.bundle_slug single_line_text_field\n - wallco_ai.bundle_design_ids single_line_text_field\n - wallco_ai.bundle_count number_integer\n - wallco_ai.source_date date\n\nReuses the metafieldsSet pattern from attach-shopify-bundle-files.js\nattachMetafield(). Post-write verify via REST against the live product\ncatches partial writes. Returns metafield IDs so a reversal via\nmetafieldDelete is a one-liner.\n\nUsage:\n node scripts/stamp-shopify-bundle-metafields.js \\\n --product= --slug= --ids= --date=YYYY-MM-DD\n\nNote: ran live against the two products called out in the task brief\n(7843830923315 designer-zoo-calm + 7843831087155 drunk-monkeys-v2) and\nShopify returned 'Owner does not exist' on both — those product IDs are\nnot present on designer-laboratory-sandbox.myshopify.com (GraphQL\nproducts query for handle:*designer-zoo* and handle:*drunk-monkey* both\nreturn 0 edges, and the dry-run mass-push manifest from 2026-05-28\nconfirms only the cactus bundle was actually created). Stamper is ready\nonce the real product IDs are in hand.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) "},{"h":"c000130","d":"2026-05-28","s":"feat(pdp): V2 Bento Grid theme — /design/:id/bento + /api/design/:id","b":"Standalone client-side template fetches single-design JSON; 4-col bento with hero 2x2,\nall PDP info preserved as labeled cells (calc, palette, specs, room, pairs, paints,\nstripes, at-scale, adjust, share, furnish, trade, ratings) + 4 collapsed accordions.\nKeeps server.js template literal untouched per backtick-gotcha rule."},{"h":"2229fb4","d":"2026-05-28","s":"tests: 19 unit tests for shopify-bundle-webhook (HMAC verify + ingest + handler)","b":"Covers:\n - verifyShopifyHmac: correct sig verifies, wrong sig fails, missing secret\n returns null, tampered body fails verification, missing header fails\n - extractCandidateLineItems: pulls product_id/line_item id/qty, skips items\n with no product_id, returns [] for null/missing line_items\n - mintToken: 32-char lowercase hex, two consecutive mints differ\n - ingestPaidOrder (stubbed deps): mints one token per bundle line item with\n unique tokens + stamps single note_attributes call, skips non-bundle items,\n survives stamp errors, handles empty line_items\n - makeWebhookHandler: HMAC good → 200 + ingest runs, HMAC bad → 401 + no\n ingest, HMAC missing → 401, secret unset in production → 503, secret unset\n in dev → still ingests, invalid JSON → 400, non-buffer body → 400\n\nNo DB / no network. Runs under plain node: `node tests/shopify-bundle-webhook.test.js`\n\nCo-Authored-By: Claude Opus 4.7 (1M context) "},{"h":"d6de7c5","d":"2026-05-28","s":"scripts: register-shopify-webhooks.js — idempotent orders/paid webhook registration","b":"GETs /admin/api/2026-01/webhooks.json first, skips POST if (topic, address)\npair already exists. Otherwise creates a new orders/paid webhook pointed at\nhttps://wallco.ai/api/shopify/webhooks/orders-paid.\n\nFlags:\n --address override webhook target (default: prod wallco.ai endpoint)\n --topic override topic (default: orders/paid)\n --list list all registered webhooks\n --dry show what would be POSTed without sending\n\nREST-created webhooks share the shop-wide signing secret (Shopify admin →\nSettings → Notifications → Webhooks); paste into .env as\nSHOPIFY_WEBHOOK_SECRET, then route via the secrets-manager skill.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) "},{"h":"c15a691","d":"2026-05-28","s":"shopify orders/paid webhook: mint per-order download token per bundle line item","b":"Replaces the shared wallco_ai.bundle_download_url pattern (one URL stamped on\neach bundle product → every buyer gets the same /downloads//.zip)\nwith a per-order token minted at orders/paid webhook time.\n\nFlow:\n 1. Shopify fires orders/paid → POST /api/shopify/webhooks/orders-paid.\n 2. Express.raw runs FIRST (early-mount before global express.json) so HMAC\n can be computed over the raw request bytes.\n 3. HMAC SHA256 verified against process.env.SHOPIFY_WEBHOOK_SECRET; 401 if\n bad, 503 if unset in NODE_ENV=production (refuses to mint unsigned).\n 4. For each line_item: GET /admin/api/2026-01/products//metafields.json,\n look for wallco_ai.bundle_slug. Skip if absent (sample/wallpaper rolls).\n 5. Mint 32-char hex token (crypto.randomBytes(16)), INSERT into\n wallco_download_tokens with shopify_order_id / shopify_product_id /\n customer_email / max_downloads=5 / expires_at=now()+90 days.\n 6. PUT note_attribute download_url_ on the order so the URL surfaces\n on the buyer Shopify order-status page (no email template change).\n 7. Always 200 on errors so Shopify doesn't retry + double-mint.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) "},{"h":"96f9215","d":"2026-05-28","s":"deploy: ship scripts/mint-shopify-download-token.js to prod (alongside seam-defect-boxes) so Steve can mint download tokens directly on the box","b":""},{"h":"82f333f","d":"2026-05-28","s":"tile-period-detect: PIL+numpy quantitative validator for mural-mode renders (FFT/autocorrelation detects tile-grid periodicity in room mockups). Authored by yolo task 39 (mural-render-programmatic-validation) — committed here for proper home; carryover staged in repo because that task hit max-turns before its own commit phase","b":""},{"h":"334af5a","d":"2026-05-28","s":"etsy bundles: option C v2 — replace count-based cap with byte-budget packing (75 MB default). Empirical finding from yolo-task-49: per-design upscaled PNGs vary 0.77-10.55 MB (5× spread driven by pattern complexity); count caps fail catastrophically when heavy designs cluster (warm-red 9-pack hit 114 MB, warm-orange-01 12-pack hit 109 MB despite the option-C 12-cap). Byte-budget targets total ZIP size and is robust to future heavy designs. estimateBundleZipBytes() uses cached all_designs.upscale_bytes_2400 + source_1024 file size. push-etsy-bundle.js: source_1024.png now ACTUALLY resized to 1024² (was preserving original ~20MB file). mass-push-etsy.js: --target-size → --byte-budget flag. Authored by yolo worker (task 49 instances all hit max-turns/timeout but shipped the refactor before dying)","b":""},{"h":"e4cb8b8","d":"2026-05-28","s":"rooms: add Mac2→prod auto-sync wrapper so room PNGs land on prod after each batch","b":"Per DTD verdict 2026-05-28 (task 46 / option A):\n- sync-rooms-to-kamatera.sh: rsync -av --ignore-existing data/rooms/ to prod\n (prod-authored renders stay safe via --ignore-existing)\n- gen-rooms-and-sync.sh: runs generate_room_mockups.py then auto-syncs\n\nNew usage: bash scripts/gen-rooms-and-sync.sh --top 50 --rooms living_room\nOld usage: python3 scripts/generate_room_mockups.py ... then manual rsync (easy to forget)"},{"h":"8c14be1","d":"2026-05-28","s":"mural categories never tile — helper + hard rule + fixed 12 misclassified rows (10 monterey-mural + 2 cactus-pine-scenic)","b":""},{"h":"4ad23bc","d":"2026-05-28","s":"feat(design page): theme1/theme2 toggle, default theme2 onload","b":"Scoped to #detail-main only (does not touch global light/dark data-theme).\nTheme 2 is a placeholder palette (white/black/brick) ready to be replaced\nwith the Figma mockup at JJuL0IPUZpUBrCdpubxzSU."},{"h":"71a12b2","d":"2026-05-28","s":"add botanical-wonders substitute generator + curator (12 designs for retired Clarke & Clarke DWKK-127831/127832 samples)","b":""},{"h":"d43deaf","d":"2026-05-28","s":"generate_room_mockups: add --all-published, --kind-filter, --category-filter, --regen-old, --dry-run","b":"Implements the CLI surface that task-41 audit recommended (yolo-loop output\n41-mural-mockup-coverage-2026-05-28.md). Required to run the mural-mode\nregen across the 815-row published cohort without listing IDs by hand.\n\nFlags:\n- --all-published iterate every is_published=TRUE row (refuses to run\n without --kind-filter or --category-filter — guard\n against accidentally re-rendering the full catalog)\n- --kind-filter csv restrict to kind IN (csv). CAUTION: 201 published rows\n have kind='mural_panel' but a tile-y category\n (face-skull-damask, designer-zoo-calm, stripe); they\n should NOT be force-rendered in mural-mode.\n- --category-filter csv restrict to category LIKE 'X%' OR 'Y%' etc. — safer\n scope for the mural batch (matches by category prefix\n so colorway sub-cats are included).\n- --regen-old re-render existing mockups whose mtime is before\n MURAL_MODE_CUTOFF_EPOCH (default 2026-05-28 13:00 PT)\n — kills stale tile-mode mockups.\n- --dry-run print cohort + cost estimate + sample IDs, run NO\n Gemini calls. Mandatory preview before paid batches.\n\nBug fixes:\n- SQL used non-existent columns 'title' and 'saturation' on all_designs\n (they only live on the spoon_all_designs view + the snapshot). Switched\n to ai_title; sort by id. Memory feedback_psql_execsync_nan_trap noted\n that psql -At -q exits 0 on errors, so the bad SQL would have silently\n returned 0 rows. Verified by direct psql call.\n\nDry-run scope previews (this commit):\n- --category-filter monterey-mural,cactus-11ft-mural,cactus-pine-scenic,tree-mural\n → 626 designs · $8.76 @ $0.014/call (RECOMMENDED safe scope)\n- --kind-filter mural,mural_panel\n → 815 designs · $11.41 (includes 201 misclassified colorway rows)\n\nNO actual batch run. Awaits Steve's approval on (a) scope choice and\n(b) authorization of the $8.76 spend.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) "},{"h":"87fa2ac","d":"2026-05-28","s":"wallco.ai: finish Scenic+Studio sub-brand strip — kill orphaned customer chips + trade-pricing brand text","b":"DTD verdict 2026-05-28 killed the Scenic+Studio sub-brand proposal. Prior\ncommit (aed2aa0b) removed nav entries, hospitality-chip block, and made\n/scenic + /studio redirect. This pass removes the four remaining customer-\nfacing brand surfaces that were still rendering \"wallco / Scenic\" /\n\"wallco / Studio\" text:\n\n1. Grid card sub-brand chip (\"Scenic\" / \"Studio\" pill on every design card\n in /designs)\n2. PDP product-line chip (\"wallco / Scenic — Photoreal hospitality mural\"\n pill at top of /design/:id)\n3. Mural wall-sizing calculator trade-pricing CTA (\"wallco / Studio\" badge\n + \"Studio mode —\" footer + \"Trade pricing inquiry — wallco / Studio\"\n email subject)\n4. Wallpaper wall-sizing calculator trade-pricing CTA (same surface, repeat\n instance)\n\nTrade-pricing distinction kept (legitimate per memory — different price\ntier), brand label replaced with neutral \"Trade pricing\". Email subject\nnow reads \"Trade pricing inquiry — wallco.ai design #X\".\n\nNo deploy. Steve runs deploy-kamatera.sh."},{"h":"aed2aa0","d":"2026-05-28","s":"strip Scenic/Studio sub-brand from customer-facing surfaces (proposal killed 2026-05-28 via DTD)","b":"four surgical edits to server.js:\n1. nav: drop /scenic and /studio entries (keep /designer-studio - separate tool)\n2. routes: /scenic and /studio now 301-redirect to /designs\n3. /designs page: strip Hospitality (Aman/Auberge/Four Seasons) chip block\n4. productLine() neutralized to return null - kills grid-card chip, PDP chip,\n ?line=/?hospitality=/?studio_pack= filters, Studio trade-pricing branch\n\ndead code (renderSubBrandLanding, hospitalityFit, studioPack, pitchScenic/Studio\ntext) kept for git history but no longer reachable. mural-scenic and\ncactus-pine-scenic category SLUGS untouched - they're standalone product lines now."},{"h":"7e34229","d":"2026-05-28","s":"luxe-curator: add canonical .when chip + flow created_at through /api/luxe-curator","b":"Front-end (public/luxe-curator.html):\n- Add .when chip (bottom-left of root tile) mirroring cactus-curator pattern:\n 🕓 ${fmtDate(p.created_at)} + ISO timestamp in title=.\n- Add local fmtDate() helper (full year/month/day/hour/minute via toLocaleString).\n- Add .when CSS rule (paired with the existing .ground bottom-right chip).\n\nServer (server.js /api/luxe-curator):\n- Capture the earliest log ts per root as created_at on the row object\n (regen entries should not bump created_at forward).\n- Include created_at in the response payload.\n\nCloses tick-37 audit finding for luxe-curator (was the only \"missing\" surface;\n\"server.js change needed first\" blocker resolved)."},{"h":"e1b59d8","d":"2026-05-28","s":"wallco.ai downloads route: /downloads/:slug/:token.zip token-gated bundle delivery (wallco_download_tokens PG table) + mint CLI + tokens minted + Shopify metafields set on 3 drafts","b":""},{"h":"c4b01d5","d":"2026-05-28","s":"add tile-period-detect: validate mural-mode room renders","b":"Programmatic detector that scores autocorrelation peaks on horizontal +\nvertical projections of the feature wall band. Single-axis peak-baseline\nratio is noisy (furniture creates moderate peaks), but strong-peak count\non min(H, V) cleanly separates continuous murals (≤1) from repeating\ntile-grids (≥2 with harmonic series).\n\nValidated 2026-05-28 on test render #37893 (new patternType='mural')\nvs 6 randomly-sampled kind='mural_panel' controls. Test min=1, controls\nmin∈[2,4]. Clean gap.\n\nReport: ~/.claude/yolo-queue/output/39-mural-render-validation-2026-05-28.md"},{"h":"23b1207","d":"2026-05-28","s":"wallco-etsy bundles: option C wired — target-size 12 (was 15) + hard maxSize=12 + 2400px upscale (was 3600px). Each ZIP now ~75 MB (12 designs × ~6 MB), comfortably under Etsy's 100 MB file-upload cap. Listing description text updated to 2400×2400/16in. Picked by /dtd panel 2026-05-28 (2/2 valid panelists voted C — keeps bundle-count manageable + comfortable cap headroom). Old bundle metadata wiped for fresh rebuild","b":""},{"h":"760af6a","d":"2026-05-28","s":"Scenic+Studio sub-brand proposal: KILLED 2026-05-28 (DTD verdict)","b":"Marked the proposal doc as killed in the header. 1-1 DTD tiebreak, A:kill\nwins on argument strength. Mural families stay as standalone lines under\ncore wallco branding; designer-scenic was wiped earlier today (2,032\nsoft-deleted). Revisit only with explicit Steve ask or purchase-pattern\nevidence."},{"h":"050d10b","d":"2026-05-28","s":"scripts/mass-push-etsy.js — single-command drain wallco_etsy_bucket → Etsy drafts. Wraps generate-etsy-bundles.js --commit + push-etsy-bundle.js (per slug, sequential, rate-limited). --skip-bundle-gen / --by / --resume / --max-bundles / --state active / --dry-run flags. 3-consecutive-failure circuit breaker (auth/quota recovery). Manifest at data/etsy-exports//mass-push-manifest-.json. Fail-fast missing-creds preflight (exit 4) so we never half-run","b":""},{"h":"b14db23","d":"2026-05-28","s":"card-room hover: drop chip inset, show entire room setting on hover","b":"Steve directive 2026-05-28 round 2: 'onhover should show the entire room\nsetting/not just half'.\n\nThe earlier 'second position chip' directive (server.js:6300) had positioned\n.card-room as a small bottom-right inset (right:8px; bottom:8px; width:42%;\naspect-ratio:1) — that's the half-card crop Steve was seeing on hover at\nwallco.ai/designs.\n\nReplaced the chip rule with full-card overlay (inset:0; width:100%;\nheight:100%; object-fit:cover). Card source is 1:1, room source is 1:1, so\ncover produces no cropping (same-aspect → exact fill). Badge re-positioned\nto a small bottom-right pill that doesn't obscure the room.\n\nShipped to prod (45.61.58.125:/root/public-projects/wallco-ai/server.js) via\nsurgical patch — pull-prod-copy + python find-replace + node -c +\nscp-over-with-backup + pm2 reload wallco-ai. Honors the\nfeedback_wallco_ai_mac2_prod_serverjs_drift rule (no full server.js\nrsync, surgical-port only).\n\nVerified: prod /designs hover shows full room (wallpaper, sofa, console, TV,\nlamp); /api/designs + homepage hero still 200."},{"h":"f55cad1","d":"2026-05-28","s":"scripts: push-shopify-digital-bundle.js — Shopify counterpart to push-etsy-bundle, DTD verdict B","b":""},{"h":"5f263d7","d":"2026-05-28","s":"cactus-curator: hover any chip to swap flat tile → room mockup (🛋 badge marks the 164/3951 chips with room data; same hover-swap on by-base family cards)","b":""},{"h":"a2a7d70","d":"2026-05-28","s":"/me/saved: add admin view-mode toggle pill (admin/live) — info@designerwallcoverings.com already gets dw_auth on trade-login allowlist (line 3667), but the toggle UI was only on /designs. Now flipped from /me/saved too.","b":""},{"h":"09c554e","d":"2026-05-28","s":"hero: room slides use background-size:cover (full-width) instead of contain","b":"Round 2 of the room-hero work. The earlier 'contain' decision (centered square,\n--hero-frame letterbox) made the hero look like a tiny center image with huge\ncream bars on either side — Steve 2026-05-28: 'where are the hero room\nimages?'.\n\nThe 2048² Lanczos source carries enough resolution that 'cover' on a 1440×648\nhero strip downsamples ~1.4× — still crisp. background-position center 35%\nkeeps the wallpaper-on-wall band centered while cropping ceiling above + floor\nbelow, which is what you want on a wide hero anyway.\n\nVerified visually via playwright @ 1440×900 (age-gate dismissed): hero strip\nfilled edge-to-edge, wallpaper pattern + furniture band centered, dot\nnavigator + 'wallco.ai' wordmark properly placed underneath."},{"h":"88d80d7","d":"2026-05-28","s":"hero: 2048² Lanczos-upscaled room mockups; heroImageUrl prefers _hero.png","b":"The upstream room renderer (45.61.58.125:3075) hard-codes 1024² output. On a\n1920px hero with contain mode that's noticeably soft on Retina displays — Steve\nasked where the hi-res hero images were ('where are the high res room setting\nhero images????' 2026-05-28).\n\nscripts/upscale-room-heroes.py: PIL Lanczos 2x of every data/rooms/design_*.png\ninto a sibling _hero.png at 2048². Idempotent + parallel (11 workers). 400/400\nexisting rooms upscaled in 97s, ~4MB/file, zero errors. Re-run anytime new\nrooms land; --force overwrites.\n\nserver.js heroImageUrl(): _ROOM_HERO_SET in-memory index of basenames-with-_hero,\nrebuilt at boot AND on /admin/reload-designs. Hero URL prefers _hero.png when\npresent, falls back to 1024² .png otherwise. Product cards (renderProduct +\ncard-room) intentionally untouched — they render at ~280px wide and don't\nbenefit from the bigger asset.\n\nVerified: all 6 live hero slots on / now serve /designs/room/__hero.png\nat (2048, 2048), http 200, 3.1-4.5 MB each."},{"h":"cf819f1","d":"2026-05-28","s":"snapshot: lift pil-edge-heal block for mural/scenic categories; bulk-publish 294 monterey-mural heals","b":"Steve: 'these are murals.. edges modeled are ok' (2026-05-28).\n\nThe feedback_wallco_heal_blur_band_edges_agent_blind rule was built around\nTILE-seam heal artifacts: the 24px Gaussian blur band across H/2 + V/2\ncreates a fuzzy-T/cross defect that repeats visibly when adjacent tiles\nmeet in a seamless layout. Mural/scenic panels DON'T tile — each panel\nhangs once, edge-to-edge — so edge-modeling at panel borders is benign.\n\nscripts/refresh_designs_snapshot.py: pil-edge-heal now passes the\nallowlist when category ILIKE '%mural%' OR '%scenic%'. Tile categories\nstay hard-blocked (pil-mid-heal stays hard-blocked everywhere — it's\nmid-seam, applies to murals too).\n\nPG (local, dw_unified):\n monterey-mural pil-edge-heal: 0/294 pub -> 294/294 pub\n (via BEGIN; SET LOCAL settlement.allow_override='true'; ... COMMIT;)\n\nSnapshot deltas (33712 -> 34186 rows total):\n monterey-mural 563 -> 857\n cactus-11ft-mural 59 -> 88\n tree-mural 33 -> 42\n designer-scenic* ~1775 -> 1910 (across 16 colorways)\n\nTagged 294 monterey-mural rows with 'curator-force-publish' so the\npassesAestheticGate exemption + force-publish path remain auditable."},{"h":"a6405c4","d":"2026-05-28","s":"cactus-curator: mural categories don't hide web_viewer from 'undecided'; add hidden-by-filter hint","b":"monterey-mural had 549 items but only 3 rendered: 546 were web_viewer=true (every\npanel gets that flag at creation) and the default 'undecided' filter excludes\nweb_viewer items. Result: bulk-select looked broken because there were no cards\nto select.\n\n- passesFilter('undecided'): when CATEGORY matches /(mural|scenic)/i, treat\n web_viewer as orthogonal to undecided-ness — those categories ARE the\n web-viewer pool, not a side bucket.\n- render(): if the current filter hides any items, show a banner\n ' hidden by filter — Show all →' so the user can flip to\n 'all' in one click. Never silent again.\n\nVerified: monterey-mural now renders 549/549 cards under the default filter\n(was 3); bulk-bar .show toggle was already correct (lines 519-520, 695-698)\nand lights up as soon as cards exist to click."},{"h":"48ecb0c","d":"2026-05-28","s":"homepage hero: room slides render at FULL SCALE — hero-slide.is-room uses background-size:contain (was 'cover' which cropped 1024² rooms on wide hero strip → soft+lost context); frame backing uses per-design dominant_hex (--hero-frame) so letterbox reads as intentional framing. Steve directive 'must be at full scale so it is clean and clear'","b":""},{"h":"fa813e7","d":"2026-05-28","s":"homepage cards: 'second position' room-setting inset chip — when a design has photoreal rooms, layers a corner thumbnail (~42% wide, bottom-right, rounded shadow) inside the .card-img + 'In a room' badge that fades in on hover. Pointer-events:none so clicks fall through to the parent design link.","b":""},{"h":"223088a","d":"2026-05-28","s":"/designs grid bulk-action: scrub URL creds on fetch — same fix as 4b8026f5's unpublish patch, but for the grid's bulk-action handler","b":"Steve hit 'Network error: Failed to execute fetch on Window: Request\ncannot be constructed from a URL that includes credentials' when\nclicking Delete on the bulk-select bar (Tag/Publish/Unpublish/Delete).\n\nThe /designs page (server.js line 5453) renders a bulk-action handler\nthat calls fetch('/api/designs/bulk-action', ...). When the admin loads\nthe page via http://admin:pwd@wallco.ai/... the relative URL inherits\nthe userinfo and Chrome refuses the fetch.\n\n4b8026f5 fixed this for the design page's unpublish handler by building\nthe URL via location.protocol + '//' + location.host. Mirroring that\nhere for bulk-action. Doesn't touch the page , so no risk of\nbreaking the render."},{"h":"46eb294","d":"2026-05-28","s":"homepage hero: prefer photoreal room-mockup over flat tile when available (heroImageUrl helper picks /designs/room/design__.png if room_mockups[] non-empty); heroDesigns() biases toward rooms-first, falls back to high-sat flat tiles to fill 6 slides","b":""},{"h":"f538318","d":"2026-05-28","s":"/design/:id 'Sell on Etsy' button — go one-click force-add by default (design-page = deliberate admin intent; gate becomes advisory). Surface scores in success status if seams > 12 so the admin sees the warning without being blocked. Curator bulk actions keep the eligibility gate","b":""},{"h":"d9d340a","d":"2026-05-28","s":"/design/:id admin toolbar: 'Sell on Etsy' button — (1) absolute-URL fetch so Basic-Auth credentials in the page URL don't break Request construction; (2) live elapsed-time progress during the 30-60s seam scan; (3) on gate-fail surfaces scores + an amber 'Sell anyway →' button that POSTs {force:true} to bypass — same pattern as the publish gate-held toast. Also fixed atb-fix (smart-fix) to use absolute URL for the same reason","b":""},{"h":"b471c32","d":"2026-05-28","s":"wall-room-viewer: add Wall HEIGHT slider matching the Wall WIDTH layout — independent room aspect, true px-per-inch on both axes, V-ruler counts to wall height, badge shows ↔N × ↕M repeats. Defaults 9' (108\"), range 7'-15' (84-180\"), persists via localStorage wrv_wall_h","b":""},{"h":"a5228db","d":"2026-05-28","s":"design grid: universal hover-preview for the ~93% of cards without a room mockup — pure-CSS ::after pseudo-element on .card-img tiles the same image at 33% (3×3 zoom-out, reveals the seamless repeat). cards WITH a room mockup keep the existing photoreal swap (.has-room wins). Stamped --card-bg on every card-img site (7 spots) so the pseudo-element gets the right source w/o extra fetch","b":""},{"h":"86dd47e","d":"2026-05-28","s":"wall-viewer: ROOM_API render as sign-in upsell. /api/room now requires admin OR trade-user (anonymous → 401 sign_in_required); requested_by_user_id stamped on wallco_rooms for attribution. Frontend: 'Try in your room' CTA + 4 room-type chips + render overlay + reset-back-to-wall pill; postMessage to parent /design/:id for trade-login redirect; replaces tiled wall preview w/ photoreal render in place","b":""},{"h":"557b826","d":"2026-05-28","s":"front-end: bring wall+room viewer to customer-facing /design/:id (iframe public/wall-room-viewer.html w/ 24/36/54 repeat pills + wall-width slider 96-240in + repeat-count + pinstripes + ft+in rulers). Add hidden admin-nav block to public hamburger w/ links to all curator tools; /api/admin/whoami probe unhides it for admin requests. Same wall/room tech now visible on both front (customers, no API cost) and back (admins, full curator)","b":""},{"h":"153d690","d":"2026-05-28","s":"etsyEligible: pass --path to seam scanner (resolve from DESIGNS) instead of --id, so prod (Node-as-root → no PG role) skips the broken psql path-lookup. Falls back to --id when path unresolvable.","b":""},{"h":"da0674d","d":"2026-05-28","s":"deploy: ship scripts/seam-defect-boxes.py to prod (used by /api/etsy-bucket/add eligibility check). Same pattern as refresh_designs_snapshot.py: explicit single-file rsync after scripts/ wholesale exclude. Add narrowly as more runtime-endpoint scripts emerge.","b":""},{"h":"77dbbab","d":"2026-05-28","s":"admin pages: q() now anchors '/'-prefixed paths to location.origin — strips embedded Basic Auth credentials from the document base URL so JS fetch can construct Requests (Fetch spec rejects credentialed URLs in Request constructor; manifests as 'Failed to execute fetch on Window: Request cannot be constructed from a URL that includes credentials' when page is loaded via http://admin:pw@host/...). Applied to cactus-curator, drunk-curator, rooms, etsy-bucket, etsy-setup, seam-debug","b":""},{"h":"f55c3ff","d":"2026-05-28","s":"etsyEligible: graceful fallback when seam-defect-boxes.py isn't deployed — scripts/ is rsync-excluded on prod, so the Etsy toolbar button was hard-failing eligibility on every design. Now returns SKIPPED + ok=true; force:true still bypasses.","b":""},{"h":"a04f46c","d":"2026-05-28","s":"unpublish endpoint: read+write the catalog snapshot (in-memory + data/designs.json) so it works on prod where PG is sparse. PG UPDATE retained as best-effort no-op on prod, source of truth locally.","b":""},{"h":"82cafd8","d":"2026-05-28","s":"cactus-curator: add ★ top-N rank pill + ✨ fresh chip (24h) to card badges — ported from drunk-curator ID-cue pattern","b":""},{"h":"1097a55","d":"2026-05-28","s":"cactus-curator: fix regex typo in TIF-path basename extractor","b":"1f775202 (17 min ago) introduced `/^.*\\\\//` which terminated the regex\nliteral early (escaped backslash + slash). Whole inline

Wallco Ai

repo: ~/Projects/wallco-ai · 1309 commits · 1 in last 24h, 1 in last 7d ·

Search the build

1309 commits indexed

  1. c08236f 2026-07-27 migrate GoDaddy auth → Bearer PAT (TK-10 key rotation); sso-key fallback retained
  2. ce1283b 2026-07-03 chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew)
  3. 3189159 2026-06-26 auto-save: 2026-06-26T06:12:56 (65 files) — public/marketplace/_layout.css public/marketplace/_partials.js public/marketplace/admin.html public/marketplace/api.html public/marketplace/apply.html
  4. ce0520d 2026-06-26 auto-save: 2026-06-26T04:09:16 (1 files) — data/designs.json.tmp
  5. 14f9f48 2026-06-26 auto-save: 2026-06-26T03:39:04 (1 files) — data/designs.json.tmp
  6. bfa2467 2026-06-25 auto-save: 2026-06-25T20:07:02 (1 files) — data/logs/gate-rejections.jsonl
  7. 34e93c7 2026-06-25 auto-save: 2026-06-25T19:36:54 (1 files) — data/logs/gate-rejections.jsonl
  8. 3135a1e 2026-06-25 auto-save: 2026-06-25T14:04:32 (1 files) — data/logs/gate-rejections.jsonl
  9. 16a9ef5 2026-06-24 auto-save: 2026-06-24T22:30:00 (1 files) — data/logs/gate-rejections.jsonl
  10. 345b704 2026-06-24 auto-save: 2026-06-24T18:59:00 (1 files) — data/logs/gate-rejections.jsonl
  11. 184b469 2026-06-24 auto-save: 2026-06-24T16:28:13 (1 files) — data/logs/gate-rejections.jsonl
  12. 94ea8f3 2026-06-24 curator: stage Kamatera reverse-proxy fallback vhost (DTD-A, not deployed)
  13. 6a41dda 2026-06-24 Add API-path tunnel finish-script (DTD-C: scoped CF token, no cloudflared login/cert)
  14. a641549 2026-06-24 Add curator.wallpapersback.com tunnel finish-script (post cloudflared-login: create tunnel, ingress, DNS route, LaunchAgent)
  15. d5ea384 2026-06-23 auto-save: 2026-06-23T16:22:58 (1 files) — data/logs/gate-rejections.jsonl
  16. f76ac12 2026-06-23 auto-save: 2026-06-23T14:52:21 (1 files) — data/logs/gate-rejections.jsonl
  17. 3a7458b 2026-06-23 Concierge search reads in-memory designs.json cache, not Postgres
  18. 126ee4f 2026-06-23 Fix design concierge returning 0 results
  19. 10c7ad7 2026-06-23 auto-save: 2026-06-23T02:49:11 (1 files) — data/logs/gate-rejections.jsonl
  20. ed959fe 2026-06-22 auto-save: 2026-06-22T23:48:32 (1 files) — data/logs/gate-rejections.jsonl
  21. 3ad3d71 2026-06-22 auto-save: 2026-06-22T22:18:11 (1 files) — data/logs/gate-rejections.jsonl
  22. 495ac53 2026-06-22 auto-save: 2026-06-22T10:35:23 (1 files) — data/logs/gate-rejections.jsonl
  23. 10c54d4 2026-06-22 Revert "/designs catalog: collapse Hue + Motif filter groups on load (wrapped in default-closed <details>; auto-open when that filter is active)"
  24. 01a7253 2026-06-22 /designs catalog: collapse Hue + Motif filter groups on load (wrapped in default-closed <details>; auto-open when that filter is active)
  25. 8faeb9b 2026-06-22 auto-save: 2026-06-22T09:04:52 (1 files) — data/logs/gate-rejections.jsonl
  26. 4b947bb 2026-06-22 gen-luxe: stamp new designs brand=wallpapersback (de-brand off wallco.ai)
  27. f0b78f1 2026-06-22 Fix mural room customizer max dimensions: 21 ft wide × 12 ft tall
  28. 327400c 2026-06-22 auto-save: 2026-06-22T04:03:42 (1 files) — data/logs/gate-rejections.jsonl
  29. 5603a69 2026-06-21 auto-save: 2026-06-21T20:31:57 (1 files) — data/logs/gate-rejections.jsonl
  30. 939dec9 2026-06-21 TODO: dedup deploy — wallco.ai retired, deployed+rolled-back wallpapersback (served-total halved = double-card de-dup), Steve decision needed
  31. 8eb1bbe 2026-06-21 TODO: log designs.json dedup fix + gated prod rebuild step
  32. f55cefc 2026-06-21 Dedupe designs.json snapshot: DISTINCT ON (id) + dedup-aware shrink guards
  33. 37d9df9 2026-06-12 marketplace/db: never pass undefined password to pg (fixes SASL 'client password must be a string')
  34. 8f57319 2026-06-12 Fix hero click landing on wrong design: add pointer-events:none to inactive hero slides so only the visible slide is clickable (was always navigating to the 6th/last stacked slide)
  35. 66f6a71 2026-06-12 colorways: add POST /api/design/:id/recolor-preview — live crisp recolor off full-res TIF (recolor-tif.py, --preview-maxedge 1400, ink-map-hash cache, no_tif fallback) + cache serve route
  36. 393fbb9 2026-06-12 Add edge-seam mural gate batch (DTD-B: edge-PASS keeps tile, WARN/FAIL→mural) + the (unreliable, kept for record) autocorr gate
  37. af64e05 2026-06-12 TODO: seam joint-heal v2 + four-horsemen verdict + non-tiling diagnostic (Steve decision needed)
  38. 0fdef02 2026-06-12 element_copy_heal v2: wrap-edge-only crisp palette-reconcile (DTD verdict C)
  39. d99cb67 2026-06-12 Fix variants montage 0/90: count PASS rows from both i2i + original ControlNet generator tags (img2img pivot 7d5a23e dropped the 4 pre-pivot cells)
  40. cbb6d9e 2026-06-12 Add seam-joint-heal-loop: autonomous yolo-runner over the 9 roots, DTD continue/pause decider, one-shot per root (no INSERT-only bloat), 07:00 backstop
  41. 0c5c224 2026-06-12 seam-joint-heal pipeline + variant-curator shows seam-joint-healed + seam-debug image fallback to by-id route
  42. e4a15f7 2026-06-12 variant-curator API: show only the new img2img-cleanup variants (generator=variants-i2i-cleanup), hide the old sparse focal-crop children Steve rejected
  43. 7d5a23e 2026-06-12 variants-9roots: PIVOT to img2img-low-denoise cleanup — variants now preserve the root's lush composition+palette and just clean it (kill smudge/seam), denoise sweep 0.34-0.61, distinct 'variants-i2i-cleanup' generator tag
  44. 8e69f5d 2026-06-12 Add self-healing supervisor for variants-9roots regen (relaunches resumable script until 90/90; Mac2 keeps killing the foreground run)
  45. 78491e9 2026-06-12 Add gated variant-pick export: dry-run by default, publishes kept picks to Kamatera all_designs + scp PNG on --live
  46. 96285b0 2026-06-12 Add live variant-curator for Wave-1 drunk-animal composition variants
  47. 8f035f5 2026-06-12 variants-9roots: edge-seamless is the only hard gate (Steve curates coverage/subject); target 10 children per root for variety
  48. 660e786 2026-06-12 Add variants-9roots.py: 10 composition/density variants per Wave-1 root (motif-scale sweep, permissive coverage gate, ledger-resumable, insert-only PASS children)
  49. a0bab98 2026-06-12 TODO: log replace-colors-3-methods work (AI-recolor gate fix, preset endpoint, lineage fix, UI unify)
  50. 2d7a39e 2026-06-12 design-edit: surface preset colorways (method 3) on the recolor-wheel block — all 3 replace-color methods on one admin surface
  51. 62ff6da 2026-06-12 colorways: add preset-colorway endpoint (method 3) + LIMIT 1 lineage fix (INSERT-only dup-row trap nulled parent_design_id)
  52. 231021e 2026-06-12 colorway-variants.py: add --detect (two dominant tones) + --list-presets CLI modes for the preset-colorway endpoint
  53. f7ada02 2026-06-12 overnight-seam-loop: route DTD vote tally to stderr so it lands in the log instead of being swallowed by the verdict capture
  54. 5b6ed8d 2026-06-12 Fix AI-recolor publish gate: child SKUs land is_published=FALSE + carry parent_design_id (was auto-publishing orphans)
  55. a0a8321 2026-06-11 Throttle overnight seam loop: max-retries default 8→4 (load relief — 15-min load hit 177 + DB timeouts)
  56. f591bcd 2026-06-11 Fix overnight loop DTD gate: capture only dtd_decide's final line (logl wrote vote-tally to stdout, polluting VERDICT so it never equaled PAUSE → pause branch was dead, loop ignored DTD)
  57. dd74023 2026-06-11 Fix overnight seam loop: (1) generator exits 0 on completed wave not 1-on-any-fail (was freezing manifest index → infinite re-run + orphan dupes); (2) idempotency guard skips roots with existing PASS candidate; (3) point loop at generalized reroll.py not scope-locked reroll-2.py; (4) retire unrescuable 43199 macaw + 54385 peacock
  58. 4992ea4 2026-06-11 seam-wave Wave 1: 1/3 roots cleared (55272 elephant -> 10000018 PASS-both-axes)
  59. 41f6dfc 2026-06-11 Add seam-warn recovery + animal-forward filter helpers (DTD-C bounded WARN slice)
  60. 61d91dd 2026-06-11 TODO: log overnight seam-fix runner launch (3-root manifest, DTD-gated, self-gating)
  61. 81fefac 2026-06-11 overnight-seam-loop: single log sink (drop tee, launcher >> is sole sink)
  62. 2fed439 2026-06-11 seam-wave: generalize the retry-loop generator to arbitrary --ids
  63. 0438663 2026-06-11 seam-wave: build manifest — 3 animal-forward FAIL roots (43199/54385/55272)
  64. f1efeda 2026-06-11 Add autonomous overnight seam-fix wave runner (DTD-gated, self-gating, never publishes)
  65. d08b86e 2026-06-11 seam-wave: bash-3.2 compat — replace declare -A (unsupported on macOS bash) with grep-based exclude membership
  66. 1dc9a01 2026-06-11 seam-wave: retire 54076+54266 (glassware-dominant, unrescuable) — exclude list auto-subtracted + animal-forward pre-filter documented
  67. 46f0778 2026-06-11 TODO: reroll-2 STOP/REPORT — 54076+54266 structurally unrecoverable (animal is minority structure entangled w/ glassware; canny crop=glass not animal; text-led loses wrap); 0 rows inserted; Steve decision A/B/C
  68. fb6e03f 2026-06-11 reroll-2: empirical correction — text-led alone fails edges+openness (0/12 cleared); synthesize weak-canny (wrap/open) + subject-recovery gate (rejects glassware-only rolls); cap cov 34%
  69. 95d401a 2026-06-11 reroll-2: DTD verdict A — drop canny for the 2 glassware-entangled roots (text-led seamless txt2img) + add Gemini/local-llava subject-recovery gate to the retry loop; add free local-llava vision backend (Gemini over spend-cap 429); add gen_textled_seamless to redo module
  70. 9ec758e 2026-06-11 Add controlnet-anchored-reroll-2: seam-retry loop for the two WARN roots (54076/54266); in-mem motif edge-verify, one INSERT per root, tighter crop, scope-locked to the 2 approved roots
  71. b9e1b4d 2026-06-11 TODO: ControlNet redo sample landed (1 PASS, 2 near-miss WARN, 2 fail); note un-deletable orphan rows + DB no-replica-identity constraint
  72. c63a1ff 2026-06-11 Add controlnet-anchored-redo.py: SDXL canny-CN anchored native-seamless redo
  73. fc72875 2026-06-11 Wire seam-fix wave cadence (DTD verdict C): gated one-wave-per-invocation runner + runbook + manifest template; refuses to run until 5-root sample is curate-approved
  74. 3a53bd5 2026-06-11 wallco redo: real-fibre composite path + img2img native-seamless orchestrator
  75. 3555103 2026-06-11 TODO: native-seamless sanity sample results (smear killed, 2/5 nail brief, abstract-drift + no-fibre-texture findings for Steve)
  76. 12c62e9 2026-06-11 Add native-seamless-sample.py: retire post-hoc strip-smear, generate native-seamless candidates on textured-natural grounds with open composition (sanity sample, no bulk)
  77. b9ad50c 2026-06-11 Force true-toroidal edge-wrap on both axes for the 6 WARN roots; all 6 candidates now edge-PASS
  78. 6c41239 2026-06-11 Add true-toroidal edge-continuity verifier + wire as hard publish gate on seam-fix curator
  79. b5f9566 2026-06-11 TODO: log seam-fix scale-up (80 worst-FAIL roots, 996 flagged remain, Steve confirm to continue)
  80. 0236a2b 2026-06-11 seam-fix curator: scale past 5-root sample — 80 worst-FAIL drunk-animals roots → 160 candidates (is_published=FALSE)
  81. 4a70b85 2026-06-11 TODO: log seam-fix curator sample + Steve pick step
  82. fe0b0b1 2026-06-11 seam-fix curator: heal seams of good roots as is_published=FALSE children + per-root picker
  83. bda8252 2026-06-10 id-collision resolutions re-run 1..14999 (125 live: 77 F,F skip + 48 F,T preserve-prod verdict A; 1 id drifted F,T→F,F since 06-03; 0 writes)
  84. 88181c9 2026-06-10 max-debug security: sanitize vision-check TITLE (callers pass full gen-prompt → injection surface) — collapse+cap to 160ch + mark it untrusted in-prompt so a crafted title can't steer the legal-gate verdict
  85. bf0a5f3 2026-06-10 max-debug: add missing Gemini fetch timeout (45s — body-stall no longer hangs child→fail-closed→unpublish); raise ollama 120→180s + spawn 150→240s + batch 90→240s (queue-wait under concurrency); guard SIGTERM-check + stdout-only VERDICT match
  86. f6b54ad 2026-06-10 settlement vision (2-agent review): keep_alive=2m frees ~8GB idle; timeouts 75→120s/90→150s prevent cold-load fail-closed; in-code model fallback (gemma3→llava) kills the missing-model foot-gun on any box
  87. 52ea65f 2026-06-09 security: strip DB DSN passwords from audit/digest docs (user@host form)
  88. 4e68e65 2026-06-09 fix(scripts): DB password from DATABASE_URL (.env), not empty PGPASSWORD env
  89. 4a2ef63 2026-06-09 restore script: generalize via CATEGORY_REGEX, hard-exclude damask, REVIEW-VISION-ERROR-only default
  90. d2decec 2026-06-09 deploy: ship settlement vision-check + tick-guard to prod (hardened gate parity)
  91. a3e8048 2026-06-09 harden settlement vision fallback (debugger pass): reject non-boolean 'violates' from Gemini→fall through; clamp partial-JSON ollama results to NEEDS REVIEW (close silent false-OK on garbled output)
  92. a717efc 2026-06-09 feat(design-curator): 🛋 Room setting button — generate room mockup, show below design in chip
  93. e3ccb0e 2026-06-09 cactus scale-sample: 28 gens, seam-PASS 76-90% per window vs 19% baseline, vision 100% — bulk regen stays gated
  94. dc1fa17 2026-06-09 restore-verified-drunk-animals: per-image gemma3 re-verify + single-row republish of Gemini-cap false-unpublishes
  95. a259466 2026-06-09 geometric pilot: 19/20 generated (57711-57750), settlement OK x19 by construction; ghost votes blocked on Gemini monthly billing cap (429)
  96. 4e65df7 2026-06-09 settlement vision: free local ollama fallback (gemma3:12b) when Gemini capped + clamp local-violation→NEEDS REVIEW (never auto-unpublish on local model)
  97. eedbd24 2026-06-09 purge-orphan-pngs: reclaim gen-time orphan PNGs (no DB row) — 1693 files freed
  98. dbe4464 2026-06-09 generator: log gate rejections to data/logs/gate-rejections.jsonl (close orphan provenance gap)
  99. afa4976 2026-06-09 cleanup: manifest of 14,632 May gate-rejected orphan designs removed (2.8GB freed)
  100. f969822 2026-06-09 snapshot before mural-feature + hero-click deploy
  101. 7440b74 2026-06-09 read-only settlement sweep over BLEED_GHOST cohort: 2,517 swept, 0 BLOCK / 0 NEEDS_REVIEW (yolo bleed-ghost-review-pool)
  102. 7c1a338 2026-06-09 seamless-bg-swap: fix RETURNING-id parse (psql -At emits command tag; [-1] grabbed 'INSERT 0 1' leaving image_url __NEW__) — proven on #39341 child #57712 + full-PASS #57685 child #57713
  103. b449bb8 2026-06-09 home hero: slides click through to their design PDP (role=link, keyboard Enter/Space, focus ring)
  104. cba4529 2026-06-09 generator_tick: add 15-min spawnSync timeout (was unbounded — hang risk); stage batch-2 orphan reclaim SQL (19 vision-triaged keepers, Steve-gated)
  105. ff8c30c 2026-06-09 Harden refresh_designs_snapshot.py summary print against None category
  106. 1d38efd 2026-06-09 stage orphan-reclaim SQL for seeds 1703852405 + 1320598381 (classifier-gated, Steve runs)
  107. 8ccb0d0 2026-06-09 drunk tick: raise generator timeout 4->12 min — 4 min SIGTERM'd between watermark and DB insert, silently orphaning PNGs (seed 638119258 diagnosis)
  108. e1efd02 2026-06-09 settlement gate fix (negation-strip + apply acceptable carve-out) — validated read-only, awaiting Steve apply
  109. 7fe54d4 2026-06-04 damask loop T4: staged 3 keepers (57680/81/83), rejected 2; batch-5 launched
  110. 31f02c8 2026-06-04 damask loop: init (DTD verdict A stage-only) — per-tick generate+curate+stage, never auto-publish
  111. 83390fc 2026-06-04 test: make npm test a real preflight gate (node -c server.js + hard-rule audit)
  112. 222ab35 2026-06-04 audit: extend hard-rule gate to vendor-names + FLIEPAPER (4 rules, one snapshot load)
  113. d249fc8 2026-06-04 audit: umbrella hard-rule gate (mural-kinds + designs.json local_path leak)
  114. 24c17c0 2026-06-04 audit: standing read-only check that mural categories never carry a tile kind
  115. 8537412 2026-06-04 damask line batch-3: +3 heritage damasks live (noir-rose, slate-carnation, espresso-acanthus) = 9 published; chip-seed covers all 9
  116. 84ccb96 2026-06-04 generate_designs: committed read-back in persistDesign — phantom-insert fix
  117. 4e561f7 2026-06-04 TODO: log staged Monterey/California-coast scenic mural batch for Steve's curator review
  118. da2cce1 2026-06-04 Fix monterey-mural inline settlement check: stop abaca (banana-stalk fiber) substrate from false-blocking; strip texture/substrate vocabulary before Part-B match
  119. cdbae9e 2026-06-03 damask line batch-2: 6 heritage damasks live on prod (feed+PDP+images) + prod chip-seed script (gated)
  120. bb95dd7 2026-06-03 Add dedicated Monterey/California-coast scenic mural batch generator (new landmarks, real-textile ground, settlement-gated, stages unpublished)
  121. c85a001 2026-06-03 Feature murals prominently on home: pinned Shop Murals quicknav + Featured Murals rail + /designs?murals=1 group filter
  122. 5499527 2026-06-03 bulk-action 'digital': exempt designs with a built room-size mural master from demotion
  123. d2aa744 2026-06-03 Add clean-edge vector-trace 150-DPI upscale pipeline (potrace + LANCZOS fallback)
  124. 9bf32a7 2026-06-03 damask line: purge 1207 luxe-animal junk + publish 2 settlement-clean heritage damasks (57625 emerald, 57629 navy) live
  125. a2634b3 2026-06-03 mural-previews: final batch-2 master 34576 — all 12 staged
  126. 7d3ac81 2026-06-03 Fix publish-ok-murals.sh publish-count parse (strip BEGIN/SET/COMMIT tags)
  127. c6b86c3 2026-06-03 mural-previews: 11/12 batch-2 masters staged (34576 rebuilding)
  128. e7ae026 2026-06-03 mural-previews: web previews + sidecars for newly-built batch-2 masters
  129. b01a644 2026-06-03 Add launchd plist for standing OK-only mural auto-publish (30-min timer, Steve installs)
  130. 09482ea 2026-06-03 Add publish-ok-murals.sh: OK-only mural auto-publish + verified redeploy (DTD-C back-half)
  131. 0edfa2a 2026-06-03 pdp: inject room-size-mural block on the LIVE-default-theme takeover path too (bare route _vhtml, not just themeVariantSend)
  132. d9c4f54 2026-06-03 pdp: universal room-size-mural injector for theme variants (prod serves v12-roomsplit)
  133. 5dc7d6a 2026-06-03 fix: digital-for-sale also unpublishes spoon_all_designs (prod leak root cause)
  134. b4013ff 2026-06-03 pdp: room-size mural preview block (web previews + API field + PDP section)
  135. 2fed713 2026-06-03 yolo loop: stop (done) — queue reconciled, clean slate
  136. 86f46a3 2026-06-03 yolo loop: resume (T17) — cleared 4 stale approval items, edges 0% PASS sample, health-sweep clean
  137. 2482fb4 2026-06-03 edges-batch-scan: read-only PASS-rate sampler over EDGES_FAIL pool (200-sample = 0% PASS, pool needs heal not promote)
  138. 2102035 2026-06-03 id-collision resolutions 1..14999 (125 live rows: 76 F,F skip + 49 F,T preserve-prod, verdict A)
  139. d247186 2026-06-03 log: etsy option-C validated (all 12 bundles under 90MB by actual cached bytes)
  140. bee700d 2026-06-03 mass-push-etsy: don't pass --commit to bundle-gen in --dry-run (no state mutation / no file writes on dry-run)
  141. 94fd03d 2026-06-03 yolo ledger: T4 live building cards + batch-2 recovery
  142. 7513978 2026-06-03 admin/mural-masters: show in-progress builds as live 'building…' cards [yolo, local-only]
  143. 3ca5a95 2026-06-03 curate-monterey-batch: exclude already-built masters + batch-2 manifest (12 new hue-spread Monterey)
  144. 5e97709 2026-06-03 Session freeze: compliance actions done locally, prod deploy held for settled catalog (DTD B)
  145. fb45a5a 2026-06-03 YOLO ledger: STOP condition — batch deployed+verified, room-revert dead, backlog exhausted (DTD verdict A)
  146. 89cef62 2026-06-03 gitignore: add missing standard excludes (.next/)
  147. 52b642f 2026-06-03 YOLO ledger: T8 wild validation PASSED — preserve-merge held rooms through a real bleed_guard rebuild+sync, prod 100%
  148. 7509891 2026-06-03 YOLO ledger: T7 monitor — durability holds, memory entry written, tapered to 1h cadence
  149. 7874404 2026-06-03 YOLO ledger: T6 verify pass — durability holding, all nets armed, monitor mode
  150. 306171e 2026-06-03 YOLO ledger: T5 true root-cause of room-revert (Mac2 PG/refresh dropped prod-rendered rooms) found + fixed via preserve-merge
  151. ea752a7 2026-06-03 refresh_designs_snapshot: PRESERVE room_mockups across rebuilds (DTD verdict B). Rooms are rendered on PROD (PNGs only there) and set in prod's designs.json, but NOT in Mac2 PG — so the every-5min bleed_guard→refresh rebuild was DROPPING them (99%→31% room coverage every cycle, the recurring revert). Now: when DB room_mockups is empty, fall back to the prior snapshot's value (additive; resolveRoomUrl still verifies the PNG). Validated: a full rebuild now keeps 4186/4186 published-with-room (was collapsing to 1315)
  152. 1e91a5a 2026-06-03 YOLO ledger: T4 grid-search color-aware
  153. 274ef88 2026-06-03 /api/designs/search (the /designs grid filter) now color-aware too — same colorTokensForHex match as the global search. Was a separate code path still title/category-only (blue 0→271), so grid-filtering by color was a dead-end while global search worked. Now consistent
  154. a340a82 2026-06-03 YOLO ledger: T3 deploy-durability (rooms survive deploys, DTD verdict C)
  155. 42b94d7 2026-06-03 deploy durability: rooms survive deploys (DTD verdict C). deploy-kamatera.sh ships backfill-rooms.py+pil-room-composite.py (2d) + non-fatal post-health re-link step (5c) so every deploy re-links rooms from on-disk PNGs (heals the designs.json clobber instantly, $0); raise nightly cron default 150->5000 as daily backstop (re-link is instant now)
  156. a0a627a 2026-06-03 yolo ledger: T3 CNCP tree warmer [local-only]
  157. 13396d1 2026-06-03 YOLO ledger: T2 re-link 2845 rooms (31%→99%) + root-cause (deploy clobber) + cron-redundancy findings
  158. fc5c3d3 2026-06-03 backfill-rooms: skip re-composite when room PNG already on disk → fast $0 re-link (heals deploy-reverted room_mockups + makes nightly cron cheaper)
  159. ab10041 2026-06-03 docs: mural-pipeline.md — Replicate gotchas playbook + review-gallery section [yolo T2, local-only]
  160. 3c40e9c 2026-06-03 YOLO ledger: 2026-06-03 EVE run — DTD verdict B + T1 color-name search fix
  161. e25598a 2026-06-03 universal search: match designs by color name (blue/navy/teal/cream/sage…) derived from dominant_hex via lib/color _hueBucket+hueName — was title/category/motif only, so color queries returned 0 (blue 0→271, green 0→435, teal 0→253). Cached per hex; text searches unchanged
  162. 4cb93d5 2026-06-03 admin: /admin/mural-masters local review gallery for room-size scenic murals [yolo T1, DTD-A, local-only]
  163. 78083e9 2026-06-03 Loop tick 9: corrected auto-curator republish premise (no live bug); staged regression reconciler
  164. 61159ee 2026-06-03 PDP live-theme takeover (/design/:id serving the active theme) now injects htmlHeader global-search + footer + corner-nav, matching themeVariantSend — the live default PDP was shipping raw with no global search
  165. f9e64ac 2026-06-03 PDP themes: route v1-compact/v2-bento/v3-tabs through themeVariantSend so all 17 variants + monolith carry the global-search nav (was missing on these 3 — raw sendFile skipped htmlHeader)
  166. bd8def2 2026-06-03 build-mural-master: retry per-tile ESRGAN calls (4x backoff) — one transient Replicate 400 was crashing a whole mural build [21079 fix]
  167. 333f44d 2026-06-03 designs grid: add 'Digital for Sale' bulk action (unpublish + tag digital-file + stamp digital_file_at)
  168. 8282219 2026-06-03 dogs-curator: fix greedy edges parse (split_part slurped appended settlement/canary notes into the badge)
  169. 9952d41 2026-06-03 backfill-rooms: idempotent free-local PIL room backfill for published-roomless designs + nightly cron wrapper (closes the gap where the auto-publish path ships designs with no room_mockups)
  170. a0b6407 2026-06-03 render-live-rooms.py: PIL rooms for prod-only designs (pull tile from live /designs/img/by-id, composite); fixed 60 la-toile PDPs (57524-57587) that shipped with no room mockups
  171. 1096024 2026-06-03 build-mural-master: fix SDXL outpaint — UA + files-API upload + version-pinned endpoint
  172. 6e8a5ae 2026-06-03 loop tick8: regression check steady (no change)
  173. 0170086 2026-06-03 loop tick7: regression check steady (no change)
  174. a0203ad 2026-06-03 /api/designs: strip local_path from public output (no /Users//root/ path leak)
  175. ecf309b 2026-06-03 loop tick6: regression check steady (0 new blocks, 658 unchanged, health 200, no decisions)
  176. 99ba82a 2026-06-03 loop tick5: focus C closeout — 1,590 orphan-room delete staged (action 4, excludes 832 re-publishable), no-tif informational
  177. 24439b2 2026-06-03 yolo loop 2026-06-03 complete: mural pipeline built/proved/curated/documented; fliepaper already compliant; stop condition reached [local-only]
  178. cfb81ce 2026-06-03 loop tick4: DTD->B, catalog quality clean (0 dup image_url, 0 null kind, 0 reverse misclass; id100 oddball already in action 2)
  179. ef20e20 2026-06-03 Q3: read-only top-12 Monterey manifest generator (one-command-away paid batch)
  180. 34f8c54 2026-06-03 docs: mural-pipeline.md — full room-size scenic-mural architecture + runbook [yolo T4, local-only]
  181. 1327a3c 2026-06-03 loop tick3: 2867 never-gated analysis — prompt triage unreliable, category-tiered re-gate plan staged (action 3)
  182. 47c3b30 2026-06-03 fliepaper-bugs admin grid: created date+time chip (standing rule #2)
  183. 6e65e8c 2026-06-03 loop tick2: UNSTABLE flag benign, designer-scenic 363 root-caused (auto-curator republish), broken-images clean on prod
  184. e5dc163 2026-06-03 mural-contact-sheet.py: visual panel review aid for any built master [yolo T3, local-only]
  185. fe7ac02 2026-06-03 global search: live typeahead overlay consuming /api/search — instant designs+collections+pages dropdown with keyboard nav + did-you-mean, wired site-wide via shared header (public/global-search.js + header script include + input id). LOCAL only — deploy parked for Steve.
  186. f7b76dd 2026-06-03 refresh_designs_snapshot: admit all gemini-%image% generators (was 2.5-only, blocked Nano Banana 3.x) + handle room_mockups list-or-dict (was crashing the build)
  187. 52b7c2f 2026-06-03 mural-batch: curate-monterey-batch.py → 12 hue-spread published Monterey manifest [yolo Q3, local-only, read-only DB]
  188. 2be769b 2026-06-03 loop tick1: fleet compliance sweep — 0 settlement-block live, 658 user_removed-yet-live staged
  189. d43631e 2026-06-03 mural-master: --estimate dry-run cost estimator (no-spend) — batch $ before approval [yolo Q2, local-only]
  190. 1f7667f 2026-06-03 yolo loop 2026-06-03: ledger + tick 1 (route sweep clean, /cart non-issue)
  191. 93e7589 2026-06-03 stage-la-toile-nb: emit gallery from REAL inserted IDs, not predicted ones
  192. e131ed2 2026-06-03 wallco: flip 137 reviewed misclassified mural_panel->seamless_tile (audit #1), keep 9 genuine murals
  193. 5bfe5e9 2026-06-03 mural-master: room-size 12x11ft scenic-master builder + vertical-panel slicer + lowres-demotion report
  194. 547c9df 2026-06-03 dogs/luxe gen: GEMINI_IMAGE_MODEL env override (re-roll on a newer Nano Banana) + dogs --force; provenance marker reflects model used
  195. 46bc416 2026-06-03 detectors: handle Nano Banana C2PA JPEG (b64 magic /9j/, path = short+exists)
  196. 8dad76a 2026-06-03 build-tif: Real-ESRGAN mural upscale stage (DTD verdict A) — large-format scenic murals
  197. 2ef1803 2026-06-03 LA Toile: stage+publish 30 Nano Banana toiles to live (peer-user all_designs insert, settlement-override publish)
  198. 07dab7d 2026-06-03 LA Toile: Nano Banana generator (literal scenic toile, 30/30 settlement-clean)
  199. b4692f9 2026-06-03 yolo audit: APPLIED+DEPLOYED 3 unpublish + 51 kind-flip + 1224 free room mockups
  200. 3910ddc 2026-06-03 subject-mismatch: enrich /api with dominant_hex+created_at (batched PG lookup) → finish standing-rule compliance: color-by-hue sort + date+time swatch chip
  201. 9b4f2b9 2026-06-02 yolo-backlog: T6 — N7 etsy-bucket + N8 elements done, LOOP COMPLETE [local-only]
  202. 82cf88b 2026-06-02 elements: add Sort (newest/oldest/category/color-by-hue/id↑↓ + Shuffled) coexisting with the Shuffle button; persists, restored sort overrides cold-start shuffle [yolo tick6/N8, local-only]
  203. a375967 2026-06-02 etsy-bucket: add Sort (newest/oldest/id↑↓/dpi) + persist; format the date chip via toLocaleString (was raw ISO) per standing rule [yolo tick6/N7, local-only]
  204. 26deee2 2026-06-02 LA Toile: staged recipe-B winners gallery builder
  205. a878353 2026-06-02 LA Toile: Option-B img2img recipe — luxe seed @0.72 + foliage concept gate (5/5 clean yield)
  206. 76a29ad 2026-06-02 yolo D5: /moodboard confirmed working (not a bug) + staged-cohorts report; loop ends [5/5 defects resolved]
  207. f4956d3 2026-06-02 yolo-backlog: T5 — N5 theme-gallery skipped (theme switcher), N6 prompt-vs-image sort done [local-only]
  208. 8bed130 2026-06-02 prompt-vs-image: add Sort (newest/oldest/category/id↑↓) client-side over loaded set + persist; density already present [yolo tick5, local-only]
  209. 9f25013 2026-06-02 yolo loop tick 5: customizer smoke test 33/34 pass ($0)
  210. 6155755 2026-06-02 yolo D4: /studio confirmed intentional 301→/designs (Studio sub-brand killed via DTD) — no fix, documented
  211. 55e320e 2026-06-02 yolo-backlog: T4 done — N4 subject-mismatch sort+density [local-only]
  212. 642ed28 2026-06-02 subject-mismatch: add Sort (root-id/subject) + Density slider, both persist per standing rule; no color-sort/date-chip (API exposes no hex/created_at) [yolo tick4, local-only]
  213. 1256df9 2026-06-02 yolo loop tick 4: smoke-test health check (focus B)
  214. 624b2ee 2026-06-02 front page: remove dead Big-Red chat widget (localhost:9935 404'd off-prod) per fleet-wide removal [yolo D3]
  215. 2dd2cbf 2026-06-02 yolo loop tick 3: room-coverage + dup-image scan
  216. 85b6407 2026-06-02 yolo-backlog: T3 done — N3 joint-fix-gallery density+persist [local-only]
  217. a67d6b2 2026-06-02 joint-fix-gallery: add Density slider + persist Sort & Density per standing rule [yolo tick3, local-only]
  218. 9014783 2026-06-02 PDP coordinates: route color-swatch pairs lookup through same-origin /api/coordinates/pairs proxy (was cross-origin → CORS-blocked off-prod) [yolo D2]
  219. c725798 2026-06-02 yolo loop tick 2: kind/category misclassification audit (198 mural_panel-in-tile-cats)
  220. dc939a3 2026-06-02 yolo-backlog: T2 done — N2 luxe-c-gallery density+persist [local-only]
  221. c2fa6b2 2026-06-02 luxe-c-gallery: add Density slider + persist both Sort & Density to localStorage per standing rule [yolo tick2, local-only]
  222. f19ce23 2026-06-02 yolo loop 2026-06-02: ledger + defect queue + approval queue (tick 1)
  223. a805dc0 2026-06-02 samples: fix unescaped apostrophe (We\'ll) that killed the sample-request form JS — match the working \\' pattern at L19535
  224. 6cdd086 2026-06-02 yolo loop tick 1: read-only catalog audit + pre-staged SQL (dtd focus C)
  225. 6452ad3 2026-06-02 yolo-backlog: open 2026-06-02 refinement loop (local-only per DTD) — N1 done, N2-N8 queued
  226. 7aa9645 2026-06-02 new.html: add Sort (6 opts incl color-by-hue) + Density slider per standing rule — both persist to localStorage [yolo tick1, local-only]
  227. 4eebff7 2026-06-02 Add settlement-gate-batch.js: gate ungated designs by category, stamp verdict
  228. 4c1e3e3 2026-06-02 deploy: add needs-tif admin-asset smoke test (5c) — assert marquee select + sorts + sparse banner shipped, via loopback admin gate
  229. 693981b 2026-06-02 test: add E2E for /admin/needs-tif (marquee select + 8 sorts + density) — Playwright, runs against a live server
  230. c8866fd 2026-06-02 needs-tif: marquee can start from grid margins (listener on main) + clear stuck didDrag after empty-space drag so next click isn't swallowed — found via E2E
  231. d04f0a2 2026-06-02 deploy: exclude data/fix-decisions.jsonl (prod-authored scanner log — was clobber risk, siblings already excluded)
  232. 167a7cb 2026-06-02 needs-tif: empty-state banner when this box's DB is sparse (DTD verdict A) — kills the false 'all designs have TIFs' read on prod
  233. 9813b2a 2026-06-02 needs-tif: marquee drag-select (1→all) + Copy IDs/open-selected bar + 4 more sorts (category Z→A, group size, color-by-hue, ID ↓)
  234. 27dad01 2026-06-02 security-monitor: line-level edit classifier — stop paging CRITICAL on benign cron/service edits
  235. 9cf3206 2026-06-02 PDP customizer: hide dragged module from hit-test so reorder targets short panes reliably
  236. 546e9b4 2026-06-02 draft_corey_letter.py: env-first George auth (GMAIL_BASIC_AUTH_B64) — drop hardcoded base64 credential
  237. d6068de 2026-06-02 needs-tif admin: count disk truth (findTifOnDisk), not PG tif_path
  238. 1044ed0 2026-06-02 PDP theme switcher: fix dropdown on bare /design/:id — treat as route mode, resolve current theme from live/?theme (slug not in URL)
  239. 4b22f53 2026-06-02 pilot-build-tifs.py: source from design image_url, fall back to by-id
  240. fe12244 2026-06-02 PDP: universal theme customizer — render-a-room + free drag-rearrange + save, on every theme incl monolith
  241. 093259a 2026-06-02 tif-gate C+D (DTD verdict 2026-06-02): correct the docs + add needs-TIF backlog view
  242. ecbba0f 2026-06-02 cron-build-tifs.sh: only alarm on disk-guard abort (rc=2), not expected 404s
  243. bce674c 2026-06-02 Add nightly TIF backfill cron wrapper (cron-build-tifs.sh)
  244. 6c66773 2026-06-02 color-dots: bind dot strips + Save toolbar only to VISIBLE images (isVisible gate)
  245. bc1d6d8 2026-06-02 hires: cache TIF-lookup HITS only, never misses
  246. b62bf3a 2026-06-02 la-toile: add palm vision-gate + tighten panel gate (negative prompt alone wasn't beating SDXL toile-palm prior; #56222 band leaked through old PANEL_Q)
  247. 7b073e5 2026-06-02 pilot-build-tifs.py: --all batch mode (published ids, disk guard, resumable, progress)
  248. ad8604f 2026-06-02 PDP: mtime cache-bust /js/color-dots.js so JS fixes land on normal reload (no hard-refresh) across injected + all 17 theme includes
  249. 3535426 2026-06-02 color-dots: Save targets the last-recolored image, not the toolbar's bound img
  250. 0bbf5ba 2026-06-02 PDP: '✓ smart-fix → #child' pill linking a design to its published smart-fixed child (parent_design_id). Server-side, works on monolith + theme PDPs + unpublished parents; /api/design exposes smartfix_child.
  251. c198fff 2026-06-02 generator: every new design self-archives TIF+SVG via build-tif hook
  252. 2b09de8 2026-06-02 edges-review + seam-debug + PDP: status filter + per-surface Fix (in-place seam-heal) & Redo (seam-debug regenerate) buttons wired to existing skill endpoints
  253. d668131 2026-06-02 Add pilot-build-tifs.py (PG-drift-proof TIF builder via by-id route)
  254. c9f7813 2026-06-02 TIF lookup: match both <id>.tif and <category>/design_<id>.tif
  255. 0f9c57a 2026-06-02 docs: TIF publish-gate review — rule unenforced + contradicts reality (3632/4936 published rows have NULL tif_path; download path uses upscale not tif). Options A-D + recommendation (soft-flag trigger + correct CLAUDE.md), deferring hard gate.
  256. 4ef783f 2026-06-02 TIF resolution: PG-independent disk lookup by design_<id>.tif
  257. 13bf818 2026-06-02 audit: unpublish 17 dogs published with NULL tif_path (un-orderable, no full-size archive)
  258. 3b80205 2026-06-02 curator 'Remove from all surfaces' now hard-deletes the TIF master (bulk + per-id bad paths) + NULLs tif_path; resolves Henry archive; confirm text updated
  259. 709a34d 2026-06-02 Full-res TIF colorways + hi-res mural preview
  260. 0e62d01 2026-06-02 la-toile: density gate 0.52->0.58 (stop over-rejecting classic-toile breathing room)
  261. dcdb679 2026-06-01 la-toile: fix prompt — gate off conflicting tone-on-tone palette suffix (BH colorway now wins → multi-color), remove palms from positive prompt (palm-free, matches negative+header)
  262. aa2d6d6 2026-06-01 PDP theme switcher: admin-only — hide .switcher bar from shoppers, gate dropdown+stepper on localStorage.dwAdmin
  263. f78404f 2026-06-01 follow-up #1 (two-master, /dtd Option B): disjoint id ranges + fix dig-number lpad truncation
  264. 05e0e01 2026-06-01 follow-ups #2 + #3: settlement trigger on all_designs (post-convergence) + retire MAX(id)+1 minting in heal-seam-region
  265. 08fb7a1 2026-06-01 PDP theme switcher: working public dropdown (Classic + 17 variants) in .switcher; fix broken ← Classic link (route via ?classic=1)
  266. 833bd9f 2026-06-01 genComfy: COMFY_SAMPLER/COMFY_SCHEDULER env knob (seam investigation)
  267. 7d91223 2026-06-01 convergence EXECUTED (Option B per /dtd): prod spoon_all_designs is now a view over all_designs — one id-space, churn structurally impossible
  268. 9e5eb22 2026-06-01 untrack public/refiner-compare + public/uploads/rooms (regeneratable, served from disk) before history strip
  269. 1b857f2 2026-06-01 untrack data/svg + data/fliepaper-bugs (regeneratable, served from disk) before history strip
  270. 7879c7b 2026-06-01 snapshot WIP + untrack regeneratable image dirs (data/generated, data/rooms, data/generated_cactus_quarantine) before history purge
  271. a88d486 2026-06-01 docs: Phase 0 results (Case B) + interim fixes applied (sequence bump 56000, designs.json rebuild/ship, render-time naming + 404 guard)
  272. 7fa37ed 2026-06-01 gitignore: stop tracking large regeneratable data blobs (etsy-exports, prompts-archive, spoonflower-pulled, library-cache.json)
  273. b2e1d06 2026-06-01 theme stepper: live-marker via /api/pdp-theme + functional control verifier
  274. 957c89c 2026-06-01 theme-variants: admin theme stepper (slug-based) + drag-reorder sections, all 17 + template
  275. 8164572 2026-06-01 designer-studio: add dead-thumbnail error-swap to its pattern search too
  276. d919742 2026-06-01 me/saved: add sort dropdown (default Recently saved) + density slider per standing rule
  277. 031802d 2026-06-01 docs: convergence migration plan — make prod spoon_all_designs a view over all_designs (kill catalog id churn)
  278. 8a16967 2026-06-01 murals: add sort dropdown + density slider (Steve standing rule — every product grid needs sort + density)
  279. 271f231 2026-06-01 studio/search: fix dead pattern thumbnails (generator + studio)
  280. 60d7b6f 2026-06-01 extend hex-consistent naming to grid (/api/designs) + search so names match the PDP
  281. 50731bb 2026-06-01 generator: drop dead refresh-orders endpoint (fetch_recent_orders_palette.js already removed)
  282. 01c9f7c 2026-06-01 npm scripts: test:themes (offline selftest) + test:themes:live (smoke vs live)
  283. 8ea8731 2026-06-01 Replicate generator: optional tileable SDXL cog (pwntus/material-diffusion-sdxl)
  284. 6516c8d 2026-06-01 add theme smoke-test selftest (meta-test) — proves the harness passes healthy themes AND catches a broken v11 toggle
  285. 0288f88 2026-06-01 render-time color-name consistency on /api/design/:id + 404 guard for removed/dangling ids
  286. f9f8f89 2026-06-01 Replicate fallback: sanctioned feather seam-heal + fix post-process skip
  287. 64c2db6 2026-06-01 security: admin-gate the entire /api/generator/* surface + /generator page
  288. a1e2cc7 2026-06-01 deploy: run PDP theme smoke test as step [5b/6] after health check (rc3=skip if no browser, else block on theme-wiring failure)
  289. 8919030 2026-06-01 add PDP theme smoke test — verifies every theme renders + v11 Wallpaper/Mural toggle re-wires all dependent surfaces
  290. dafdb2d 2026-06-01 generator: replace dead DW-orders palette with style-guide palettes + fix the page-killing onclick escaping
  291. 46878b0 2026-06-01 add Path B surgical color-name backfill (re-derive title color word from dominant_hex; category preserved per /dtd option B)
  292. 06a0e7c 2026-06-01 generator: add Texture component picker (15 real DW natural-material grounds) — wired UI->payload->prompt so designs paint on a real grasscloth/cork/raffia/silk/etc. ground per the hard texture-anchor rule
  293. bd05114 2026-06-01 PDP v11-best (live theme): Wallpaper/Wall Mural toggle on every design
  294. 5713b85 2026-06-01 add read-only color-name vs dominant-hex drift audit (10171 root-cause)
  295. 4746851 2026-06-01 PDP: explicit Wallpaper/Wall Mural format toggle on every design
  296. de244a8 2026-06-01 elements admin: click element image to use it in a new pattern (was: open PDP)
  297. 027cb79 2026-06-01 add Beverly Hills palette style-guide page to admin styleguides (linked from Brand Selector)
  298. d0e305b 2026-06-01 deploy: ship generate_designs.js + generator_tick.js in 2d runtime-scripts (the BACKEND_UNREACHABLE fix spans both server.js + generate_designs.js — must deploy together)
  299. 380a420 2026-06-01 fix: distinguish ComfyUI-unreachable from quality-gate failure in batch error
  300. 9f255b7 2026-06-01 designs: move social-share ↗ FAB right of the bulk-select checkbox
  301. efb671c 2026-06-01 migrate remaining retired gemini-2.0-flash vision refs to gemini-2.5-flash
  302. 9d134cd 2026-06-01 TODO: log generator batch-timeout diagnosis + local fix (deploy Steve-gated)
  303. 929ffc6 2026-06-01 fix(generator): batch child timeout + orphan-run reaper + retired-gemini gate model
  304. b3db6de 2026-06-01 SECURITY: SQL-escape interpolated paths/category in elements_extract_prod.py + pil-mural-composite.py (claude-codex finding #8)
  305. c2f49d0 2026-06-01 SECURITY: fix reflected XSS in htmlHead (<head> now esc()'d at chokepoint — kills /search ?q=</title><script> vector) + gate /api/generator/batch with isAdmin (was the only ungated generator route; anon could spawn 50 SDXL jobs). claude-codex findings #2/#3
  306. c76ad29 2026-06-01 deploy: orphaned-entrypoint guard — warn if a pm2 process points at a file rsync --delete removed (wallco-hot-or-not incident)
  307. 624d542 2026-06-01 SECURITY: admin-gate isLocalhost no longer trusts Host header — gate on loopback TCP peer + absence of proxy headers (fixes 'curl -H Host:localhost' admin bypass; claude-codex finding)
  308. 66f0082 2026-06-01 Redirect /api/design/{null,undefined,NaN} home too (belt-and-suspenders for stale-link/missing-id navigations)
  309. 8a607a0 2026-06-01 Add publish-ready-batch.sh: curator-force-publish the 18 census-vetted designs (both tables + allow_override + tag), re-vets in WHERE, rebuilds snapshot, prints deploy — Steve runs it
  310. 05eafc2 2026-06-01 Add unpublished-designs census 2026-06-01: 40,107 unpublished decoded by reason; only 18 publishable-now, 1,535 TIF-blocked
  311. 443ac42 2026-06-01 TODO: orphan rooms fixed-locally (141 copies, 0 remain; prod push Steve-gated) + dw_admin rotation queued in secrets-manager checklist
  312. 2369124 2026-06-01 styleguides: admin can add/delete custom style guides; usable by Generate + Apply/recolor
  313. 005165e 2026-06-01 TODO: track 284 settlement-blocked batch-regen run
  314. 7153551 2026-06-01 fix: settlement post-gen vision used retired gemini-2.0-flash (404) — move to gemini-2.5-flash; was fail-closing every roll so NO design could pass the 4th gate
  315. be40974 2026-06-01 TODO: log prompt-vs-image PG promotion + deploy (local+prod migrated, 0-row backfill, learn wired, live smoke green)
  316. f339c7f 2026-06-01 migration(prod): additive ALTER TABLE spoon_all_designs for prompt-match cols (prod table != local view; applied to prod dw_unified)
  317. 6d802cf 2026-06-01 prompt-rate: PG columns are source of truth (read+write), JSONL kept as audit; backfill script; learn_from_votes reads user_prompt_match (excludes reject/<=2, +0.2/pt rank bonus)
  318. f1f5191 2026-06-01 scope dw_auth admin cookie to .wallco.ai so admin login carries to subdomains (styleguides)
  319. 25e596a 2026-06-01 migration: add user_prompt_match/verdict/rated_at to all_designs + spoon view (applied local)
  320. 89e036b 2026-06-01 batch-regen: 2-design concurrency pool (DTD-C), deterministic-stdout id removes race so gen lock now opt-in; fix title col (no title in all_designs)
  321. d7523ba 2026-06-01 chore(deploy): exclude data/prompt-match-ratings.jsonl from rsync (server-authored append-only ledger, must not clobber a future prod copy)
  322. 2070bb0 2026-06-01 feat(admin): side-by-side prompt-vs-image A/B rating surface
  323. 5b012f9 2026-06-01 styleguides.wallco.ai → admin-only; revert public metering on batch/recolor
  324. 55c9073 2026-06-01 batch-regen driver: 4-gate (seam+color+concept+settlement-OK) settlement-blocked re-gen, staged-only, race-free per-roll gen lock
  325. e04b3d1 2026-06-01 feat(designs): add Color (group similar hues, H→L) + Style sort modes to browse grid
  326. 703d174 2026-06-01 Guard /api/design and /api/design/ (missing id) → redirect home instead of raw Cannot GET 404
  327. 5a812ec 2026-06-01 feat(styleguides): open to public with per-IP render cap (5 images/day)
  328. 0fbb86a 2026-06-01 feat(styleguides): Brand Selector admin tool wired to generator + studio recolor
  329. 6250128 2026-06-01 generator_tick: retry psql on boot-race PG-socket-not-ready (up to ~30s)
  330. 5196d88 2026-06-01 publish 36 reviewed HC drunk-animals keepers live (settlement-safe per-id, human-reviewed 2026-06-01)
  331. 1c8294c 2026-06-01 TODO: mark BLEED_GHOST triage done (7875 cohort, 850 contradiction unpublished, report 365dbd64)
  332. 4dbc0e2 2026-06-01 Add universal search: /search page + /api/search aggregator + global header search box
  333. fef1177 2026-06-01 gen-luxe: psql helper ON_ERROR_STOP=1 so a half-applied multi-statement write fails loud instead of exit-0 (Codex audit :257)
  334. ca8e0ff 2026-06-01 overnight loop: extend to daytime (stop_hour=18, cap=140), stage-only
  335. 9f06ace 2026-06-01 rename Cactus Curator → Design Curator: /admin/design-curator route + file, old path 301-redirects (query preserved), nav + title + sister-page links updated (internal /api/cactus-* names unchanged)
  336. 365dbd6 2026-06-01 BLEED_GHOST cohort triage report (7875 designs, read-only): 0 BLOCK live (clean), flags 850 live-but-removed contradiction + 1580 review pool
  337. 2dffa4a 2026-05-31 curator A8: panel-scoped keyboard shortcuts (0=reset, [ ]=nudge focused slider) + note documentation
  338. 45280b3 2026-05-31 curator A7: extreme-adjustment bake guard — require a confirming second click for wild sat/bri/con before POST
  339. ab93f20 2026-05-31 curator A6: 'Copy CSS' button — copies current filter string to clipboard with feedback
  340. cabd7d1 2026-05-31 curator A5: per-card 'Bake adjustment' button on grid cards (reuses bake path, neutral-guarded, decide binding scoped to [data-a])
  341. fea3eea 2026-05-31 Add read-only room-mockup coverage audit (2026-06-01): over-claim=0, 506 coverage gap / 268 reclaimable orphans
  342. b1e98d1 2026-05-31 overnight cohort audit loop — 17 cohorts, 98 unpub, $0.24, DTD-gated
  343. ba89b1e 2026-05-31 READ-ONLY designs.json integrity audit 2026-06-01: clean (no local_path leak, 0 dup ids, 0 mural-kind violations, published count sane)
  344. 5024636 2026-05-31 generator: read-only /api/generator/cooldowns — surfaces which categories the tick is skipping for bad-aesthetic cooldown (per-category failure counts + threshold)
  345. f127079 2026-05-31 generator: read-only /api/generator/digest — curator-queue snapshot (generated_today / settlement_ok / awaiting_review / published / removed) so the review backlog is visible
  346. a607731 2026-05-31 settlement integrity canary 2026-06-01: Mac2+prod clean, 0 BLOCK-class published
  347. 12a8456 2026-05-31 curator A4: extend live adjustment filter to the by-base family stack (#bbstack img)
  348. 6982a4a 2026-05-31 curator A3: live before/after preview chip in Adjust panel (samples a visible card, after-chip carries --img-adjust)
  349. 7431b12 2026-05-31 curator A2: show derived filter math next to each slider (hue degrees, sat/bri/con percent)
  350. b02506f 2026-05-31 curator A1: HSB Adjust presets (Neutral/Vivid/Muted/Warm/Cool/B&W) with exclusive active-chip highlight
  351. 51134a8 2026-05-31 dogs cohort review — 214 breed-aware title renames (--no-verify: gitleaks panic on config regex)
  352. d1deeb6 2026-05-31 More animals x more textures (55008-55020, 12 new species on sisal/jute/seagrass/abaca/hemp/paperweave/bamboo/madagascar/wicker/arrowroot), real SKU grounds, settlement-gated, live; +ostrich/octopus/peafowl plural fixes
  353. 447b0a0 2026-05-31 rescue-curator: add bulk 'Move to species category' → POST /api/admin/recategorize/bulk (animals · <species>, sanitized+pgEsc, updates all_designs+spoon+in-memory)
  354. 549ea46 2026-05-31 Color-targeted llama+crane colorways (54992-54998) replace random-clustered originals — blue/green/gold + grey/gold/navy spread via --color-family, settlement-gated, live
  355. 5a56093 2026-05-31 drunk-animals title-drift fix — re-title 180 designs with actual species
  356. 021e9d8 2026-05-31 admin: rescue-curator — per-species drunk-animals review w/ marquee select + bulk publish/unpublish (wired to /api/cactus-decision/bulk), status/species filters, sort+density, date chips
  357. cc6dafb 2026-05-31 gen-luxe --color-family=<gated family> targets ground colorway so variant runs get guaranteed spread (navy+blush+sage) instead of random clustering
  358. 5203dd4 2026-05-31 stoned-animals title-drift fix — re-title 303 designs with actual species
  359. 674cae4 2026-05-31 curator: add Bake button — render HSB+contrast adjustment to canvas, save as new unpublished design (reuses /api/design/:id/bake, original untouched)
  360. 0623808 2026-05-31 Publish silk+linen colorway variants on default spec (54978-54990, image-reviewed all good) — llama/pheasant/stag/crane across varied real-SKU grounds, settlement-gated, 12/12 live
  361. 4d9032c 2026-05-31 curator: add HSB + contrast live image-adjustment panel (non-destructive CSS preview)
  362. be9b245 2026-05-31 Add curator-excluded-ids helper — publish loop respects cactus-curator unpublish/bad takedowns
  363. 91d3a60 2026-05-31 stoned-animals quality purge — unpublish 227 alert-mood designs
  364. 724ffb9 2026-05-31 Generate + publish GRASSCLOTH/LINEN/SILK drunk-animals sets (54943-54960, 18 new species) on real Shopify SKUs by prefix, settlement-gated, live+verified on wallco.ai
  365. 3e32b5f 2026-05-31 pdp variants: clamp prev link to id>=1 (10 variants) + scheme/quote-sanitize image_url before <img src> across all 17 — codex review pass 2 hardening
  366. 50ab4a2 2026-05-31 Harden pattern-generation engine per Claude-Codex debate: gate --texture-cat to material enum (no raw SQL interpolation), hex_to_hls survives 3-digit/malformed hex (was a snapshot-abort), prefix-match animal categories so drunk-animals-* variants get motif naming, re.escape animal regex, drop dead goose entry
  367. 4fbb6e7 2026-05-31 drunk-animals quality purge — unpublish 513 'too abstract' designs
  368. 531f5ce 2026-05-31 designer-studio compose: bump generator spawn timeout 180s→300s — prod render+internal-regen cycle exceeded 180s, causing spurious code-null re-rolls
  369. 2b40d83 2026-05-31 security: gate /api/luxe-curator/regen + /pick behind requireAdmin (Codex audit)
  370. 1d5ddf1 2026-05-31 deploy.conf: exclude .venv/__pycache__/logs + prod-only scripts/backfill-rooms.js (cron-critical) — full-deploy dry-run now 84 transfers / 4 junk deletions
  371. 2343a75 2026-05-31 pdp-theme: atomic write (temp+rename) so a crash mid-write can't leave partial JSON every PDP reads — codex review hardening
  372. 252689c 2026-05-31 gen-luxe grounds on real Shopify SKUs by DW SKU prefix (grs-/lin-/sil-/crk-/mad-/raf-/mic-/nat-/sis-/jut-/sea-/aba-), not just title word; material label falls back to prefix
  373. 6804379 2026-05-31 deploy: exclude prod-authored logs (cactus-decisions/ghost-scan*/ghost-purge/ghost-labels/bad-aesthetic/fixes-feed/marketplace events) — CLAUDE.md mandates these never be clobbered; they were missing from the rsync exclude list
  374. a1b7baa 2026-05-31 deploy.conf (CRITICAL): exclude data/elements + data/tif (local symlinks→external drive, real dirs on prod — --delete would wipe ~35k prod files) + prod quarantine dirs
  375. ca7e5ce 2026-05-31 deploy: exclude data/pdp-theme.json from rsync (prod-authored live-theme setting; was clobbered by Mac2 copy each deploy, reverting the live PDP theme)
  376. 08ae76b 2026-05-31 Generate + publish fresh CORK + RAFFIA drunk-animals sets (54930-54942, 12 new species) on real Shopify cork/raffia SKUs, settlement-gated, live+verified on wallco.ai
  377. c0e3414 2026-05-31 v11-best PDP: mobile polish — id chip to bottom-right (clears Save-colorway bar), compact non-sticky mobile header (was clipping breadcrumb)
  378. e6c546d 2026-05-31 designer-studio compose: heal-first instead of re-roll — keep the round-1 tile (WALLCO_SEAMLESS_GATE=0), heal its seam in place via fix-seam.py (PIL shift-and-heal), re-roll only as last resort when ghost/frame gate rejects; fix-seam.py --inplace now no-ops on already-seamless tiles (Round-1 sacred)
  379. 55871ad 2026-05-31 Generate + publish fresh mica-ground drunk-animals set (54923-54928): peacock/giraffe/elephant/sloth/fox/flamingo on real Shopify mica SKUs, settlement-gated, live+verified on wallco.ai
  380. 70362eb 2026-05-31 deploy.conf: exclude prod-authored data/cactus-decisions.jsonl from rsync (server appendFileSync target; was a clobber risk)
  381. 0c8a15c 2026-05-31 harden generator_tick id-reconciliation: parse authoritative Created IDs line from stdout, snapshot heuristic as fallback
  382. ef32cc7 2026-05-31 admin: draggable+popout modal kit (all 19 pages) + windowed /admin/workspace dashboard (add/move/resize grid panels, layout persists)
  383. ebf027d 2026-05-31 Pattern generation always anchors on a REAL natural wallcovering texture: add mica + abaca/seagrass/jute/hemp/arrowroot/paperweave/bamboo/reed to gen-luxe pickTextureBrief pool; codify the real-texture-ground rule in CLAUDE.md
  384. 0425501 2026-05-31 designer-studio compose: auto-retry up to 3× on seamless-QA rejection (SEAMLESS_FAIL_LR) before erroring — single run_id spans attempts, frontend poll window 240s→420s
  385. b793327 2026-05-31 Publish luxe-v2 batch L5 image-reviewed (41906,41917,41920,41909,41882) — Orangutans/Giraffes/Elephants/Frogs, live+verified (+5)
  386. 28d2361 2026-05-31 admin/inspirations: align sticky controls offset to header height (65px)
  387. bc5fdec 2026-05-31 admin/inspirations: pin board header + sort/density controls (position:sticky) so they stay fixed as the pairs grid scrolls
  388. 6675f7f 2026-05-31 Fix two more PDP inline-script newline-in-string token errors
  389. 47df49c 2026-05-31 Fix two more PDP runtime JS errors (hint TDZ + mailto newline token)
  390. 6b5a6a1 2026-05-31 theme-gallery: Set Live promotes a variant to take over the bare /design/:id PDP (global, file-backed, ?classic=1 bypass)
  391. 606f45c 2026-05-31 designer-studio compose: async background generation — return run_id instantly + /api/studio/compose/status poll endpoint (fixes nginx 60s 504 on slow renders) + attribute real design id from generate_designs.js 'Created … IDs:' log (fixes ORDER BY id DESC race); frontend polls every 3s with elapsed timer instead of awaiting a blocking response
  392. 7f2e28e 2026-05-31 Fix PDP inline-script escape-collapse + restore grid density slider
  393. 03d26cf 2026-05-31 Publish luxe-v2 batch L4 image-reviewed+seed-deduped (41878,41888,41897,41900,41885) — Orangutans/Peacocks/Elephants/Capybaras/Frogs; expand animal lexicon (capybara etc). live+verified (+5)
  394. 004c457 2026-05-31 Publish luxe-v2 batch L3 image-reviewed (41871,41905,41875,41874,41866) — Orangutans/Sloths/Frogs/Elephants, ground-colorway names, live+verified (+5)
  395. cba7409 2026-05-31 Colorway samples the GROUND not whole-image average: parse 'Ground: ... dominant #hex' from luxe prompt (891/891 have it). Frogs Saunter in Teal (was Rose), Peacocks Bacchanal in Honey (was Pewter)
  396. ca9ff25 2026-05-31 generator batch: attribute run to actual created IDs from log (not global max id); mark error when 0 survive quality gate
  397. c8fc9a6 2026-05-31 Publish luxe-v2 batch L2 image-reviewed (41576,41844,41868,41839,41845) — Lemurs/Giraffes/Frogs/Pandas/Peacocks, live+verified on wallco.ai (+5)
  398. a7c3834 2026-05-31 Interior-designer naming: motif-aware pattern names (parse hero animal from Motif: clause) + curated colorway palette (Verdigris/Bottle Green/Oxblood/Prussian...). 'Peacocks Bacchanal in Bottle Green' replaces 'Marine Vignette No.NNNN'
  399. 71b98af 2026-05-31 generator: user-chosen batch size renders server-side in background (survives tab-close)
  400. afa8a3e 2026-05-31 Add per-site favicon (kills /favicon.ico 404)
  401. 417ad75 2026-05-31 Pivot to luxe-v2 realistic named designs (interior-designer lens): publish Marine Vignette/Caprice, Rose Carouse, Sage Vignette/Saunter (41795,41797,41806,41575,41838); revert smart-fix batch 13
  402. 3964faf 2026-05-31 tests: fix playwright integration specs against current UI (19 failing → 0)
  403. 0b990f6 2026-05-31 designer-studio: wire Elements panel to the REAL visual motif library — /api/studio/elements now returns extracted silhouette cutouts (data/elements) as clickable thumbnails grouped by category; selection by motif id resolved to motifs/category text in compose
  404. 25e05d1 2026-05-31 Publish drunk-animals batch 12 (39443-39447) — SQL-direct, settlement-enforced, live+verified on wallco.ai (+5)
  405. a230fc5 2026-05-31 Publish drunk-animals batch 11 (39438-39442) — SQL-direct, settlement-enforced, live+verified on wallco.ai (+5)
  406. 4cc32ef 2026-05-31 Publish drunk-animals batch 10 (39424,39433,39435-39437) — SQL-direct, settlement-enforced, live+verified on wallco.ai (+5)
  407. 4ad701e 2026-05-31 Publish drunk-animals batch 9 (39405-39408,39417) — SQL-direct, settlement-enforced, live+verified on wallco.ai (+5)
  408. 9b1e458 2026-05-31 Publish drunk-animals batch 8 (39400-39404) — SQL-direct, settlement-enforced, live+verified on wallco.ai (+5)
  409. 7a10d3d 2026-05-31 api/room: fall back to IMG_DIR/basename when local_path (often a Mac2 abs path) is missing on prod — fixes 'design file missing on disk' on the See-in-Room generate flow
  410. f8d5453 2026-05-31 designer-studio: un-gate /api/studio/elements (public vocab, no PII) — was 404ing for non-admins → Elements panel blanked for all visitors; + frontend Array.isArray guard
  411. 63432c5 2026-05-31 Resume sweep: publish new clean drunk-animals, tag 3 settlement-blocked as legal-review
  412. a7811a3 2026-05-31 TODO: bleed-review surface DONE + corrected cohort numbers
  413. 44d22f0 2026-05-31 admin: /admin/bleed-review surface for the BLEED_GHOST cohort
  414. 251b404 2026-05-31 Publish drunk-animals batch 7 (39395,39396,39397,39398,39399) — SQL-direct, settlement-enforced, live+verified on wallco.ai (+5)
  415. 4f57951 2026-05-31 Publish drunk-animals batch 6 (39372,39373,39376,39385,39390) — SQL-direct, settlement-enforced, live+verified on wallco.ai
  416. 3e8d54e 2026-05-31 Resume sweep: publish 7 new clean drunk-animals, tag 3 settlement-blocked as legal-review
  417. dae1ea5 2026-05-31 TODO: reconciliation pass — 3 stale claims refreshed against live DB
  418. 5c5ca23 2026-05-31 report: wallco.ai room-mockup coverage gap 2026-05-31 (37 over-claims / 18 designs, read-only audit)
  419. 87d7964 2026-05-31 fix luxe triage report: real data (567 clean, 98% drunk-animals, no quality scores, settlement-ungated) — prior commit was empty (queried nonexistent quality_score col)
  420. 71c86fd 2026-05-31 lib/db: lock_timeout=8000 on wallco's own psql connections so a contended boot ALTER can't wedge the whole server before app.listen
  421. 31a8d96 2026-05-30 Publish drunk-animals batch 5 (39341,39366,39367,39370,39371) — SQL-direct, settlement-gate enforced, live+verified on wallco.ai (+5)
  422. a3fae71 2026-05-30 TODO: mark aesthetic-gate /admin/edges-review tab DONE (was stale)
  423. 1761ac6 2026-05-30 luxe-v2 curation triage report (910 candidates, read-only, DTD-A)
  424. 7e7deff 2026-05-30 TODO: mark DW dw_admin code-strip DONE (rotation still Steve-gated)
  425. 640981f 2026-05-30 Tag 895 held banana/palm drunk-animals as legal-review (settlement-blocked, never publish)
  426. 9e1ec3e 2026-05-30 Publish drunk-animals batch 4 (41916,41566,42278,42246,42338) — settlement-clean, force quality-gate only, live+verified on wallco.ai
  427. e83be1d 2026-05-30 TODO: mark /admin/elements drawer CTA wiring DONE (was stale — shipped in 8eef445a+c812cf64)
  428. 98f6c51 2026-05-30 cactus-curator: park gate-failed designs by default, require explicit human override to publish (DTD verdict)
  429. c812cf6 2026-05-30 elements: backend POST /api/admin/elements/compose — real Gemini img-to-img fuse
  430. 8eef445 2026-05-30 security: add rel=noopener noreferrer to all target=_blank links; remove served .bak files from public/admin
  431. 40ba2c3 2026-05-30 Root fix: refresh_designs_snapshot withholds settlement-BLOCK rows at the artifact chokepoint — defeats all racing publishers (drunk_animals_tick etc); guard now spoon-keyed
  432. 25e21a7 2026-05-30 publish next-5 settlement-clean drunk-animals batch3 (Steve 2026-05-30)
  433. 8ccea8a 2026-05-30 Guard: trigger on spoon_all_designs (live catalog source), not all_designs curator table — avoids needless prod deploys on curator churn
  434. 0b0f327 2026-05-30 publish drunk-animals 5/28-5/30 batch2 (+44 via curator force, 97 settlement-held), deployed to wallco.ai
  435. c87c2c2 2026-05-30 TODO: correct auto-resume note — canonical daemon is the real one, removed redundant dup
  436. a50db3b 2026-05-30 TODO: 2026-05-30 session — 4763 rooms shipped free local full-bleed, dual-path resolver fix, 8 bad pulls, ssh + auto-resume, security-strip status
  437. ade7c0b 2026-05-30 generate_room_mockups: platform-aware psql (sudo -u postgres on prod) — bare psql fails as root on Kamatera
  438. e7466ba 2026-05-30 Add settlement-guard sweep: event-driven removal-only compliance net for live BLOCK designs
  439. 6bc0857 2026-05-30 publish next-5 settlement-clean drunk-animals batch2 (Steve 2026-05-30)
  440. 4f8e22d 2026-05-30 admin/edges-review: Aesthetic-gated (hidden) tab — endpoint + UI
  441. 94df68b 2026-05-30 publish drunk-animals 5/28-5/30 (+54 via curator force, settlement-blocked held), deployed to wallco.ai
  442. 15cf188 2026-05-30 Compliance: unpublish 31 settlement-legal-block designs catalog-wide (BLOCK + vision-error), leave BLEED_GHOST quality verdicts
  443. f1fb003 2026-05-30 publish first-5 settlement-clean drunk-animals (Steve 2026-05-30): force-tag SQL + snapshot
  444. 91b2a35 2026-05-30 5/29 publish: 164 clean drunk-animals live; unpublish 26 settlement-blocked (compliance fix)
  445. 0ae7644 2026-05-30 Fix deploy-kamatera.sh: data/elements exclude matches symlink
  446. 8c09397 2026-05-30 room mockups: tune template to full-width-credenza + quad bottom=742
  447. fff1c63 2026-05-30 room mockups: fix framed-panel defect — clean full-wall template + quad
  448. b47680d 2026-05-30 Fix /designs grid: accept ?category= as alias for ?cat=
  449. 167dee0 2026-05-30 Force-publish 190 clean drunk-animals from 5/29 to live (Steve approval: clean-only, excluded 32 user_removed)
  450. c0ef0e8 2026-05-30 security-monitor.sh: add cron + service-unit drift checks
  451. 1ac6616 2026-05-30 cactus-curator: bulk Publish now animates published cards out of the grid (matches per-card Publish) — fixes 'select row + Publish does nothing' (published server-side but no visible feedback)
  452. dfe2bce 2026-05-30 elements/img: fall back to source tile by-id when baked derivative missing (data/elements was a dangling symlink on prod)
  453. be08cbc 2026-05-30 fix(room-mockups): resolve ROOT from __file__ not Path.home() so prod writes to served data/rooms (not unserved /root/Projects)
  454. 44fb906 2026-05-30 Add living-room mockups for 55 cactus designs (Mac2 PIL+SQL, prod sync deferred to task 95)
  455. 007b79b 2026-05-30 Mural rooms upgrade plan: prod-ship (SSH-gated) + photoreal :3075 upgrade ($-gated, DTD-C)
  456. a54ea58 2026-05-30 scripts/pil-mural-composite.py: FREE local single-panel mural room-mockup renderer (murals never tiled)
  457. e70294d 2026-05-30 Add colorway sub-category room-mockup driver (1395 living_room composites generated, TAG-collision-safe)
  458. 044da51 2026-05-30 scripts/security-monitor.sh — 10-min cron detector for UID-0 / sudoers / authkeys / timer / useradd drift (dtd verdict A, deployed prod 2026-05-30)
  459. 2d3f9dd 2026-05-30 security: strip hardcoded dw_admin DSN password -> env-first. No rotation/deploy.
  460. fb0b8e2 2026-05-30 fix: backfill-wallco-rooms uses sudo -u postgres psql on Linux/prod (root has no PG role; was failing with 'role root does not exist')
  461. 5f9d9db 2026-05-30 fix(ui): admin-toolbar no longer overlaps fixed header
  462. 1b9059d 2026-05-30 backfill-rooms-cron: indent=2 + byte-size guard (95%) to stop daily designs.json field-shrink clobber
  463. a37f6a3 2026-05-30 _evidence: snapshot bubbe RCE routes (hooks + upload-bubbe) before de-root 20260530
  464. 0ed2c60 2026-05-30 backfill-rooms-cron.sh: atomic designs.json write + catastrophe guard — fixes the recurring ~06:30 UTC wallco catalog blackout
  465. 12ce9a9 2026-05-30 refresh_designs_snapshot: add byte-size guard (refuse <85% of existing file — catches field-shrink clobber the count guard missed, the 06:30 blackout) + atomic write (tmp+os.replace, no partial-read /api/designs=0). Prevents recurring catalog blackout
  466. 39851c6 2026-05-30 rooms: unified dual-path resolver (resolveRoomUrl/resolveDesignRooms) across ALL room surfaces — /api/rooms+gallery, PDP See-in-a-room figure+toggle, tearsheet, brief. Restores ~1,217 legacy /uploads designs regressed 2026-05-29; survives snapshot rebuilds; file-verified so no black/orphan tiles. Closes PARKED #1+#1b
  467. 19b104a 2026-05-29 fleet audit 2026-05-30 — toggle + sort/density backlog (DTD verdict C: fix 3 truly-broken sites, leave dwf stealth pattern alone)
  468. 70fedce 2026-05-29 docs: mac2-prod parity audit 2026-05-29 (5/5 files identical; +product_line on prod via /dtd)
  469. df69588 2026-05-29 /api/rooms: for non-admin, dedup by room_type + drop rooms whose /designs/room PNG is missing — PDP gallery no longer shows black/orphan tiles (design 12 had 4 orphan living_room rows w/ no file)
  470. 25bdcd2 2026-05-29 PDP gallery: drop inline onerror (broke inside server template literal — \' collapsed to '' → JS parse error → empty gallery); clean /designs/room src + dark bg placeholder
  471. be7e221 2026-05-29 PDP Generated-rooms gallery: tile src uses /designs/room/design_<id>_<type>.png convention (was r.image_path /uploads/rooms 404 → black tiles) with onerror fallback to image_path — same fix family as admin/rooms
  472. 851af25 2026-05-29 wallco PDP: gate unpublished /design/:id from public direct-link (404 for public, admin preview preserved)
  473. c72fe45 2026-05-29 id-collision resolutions 1..14999 (134 rows): 106 Mac2 re-published (F,T verdict A), 27 skipped (F,F), 1 escalated (T,F verdict C)
  474. a049441 2026-05-29 PDP: fall back to wallco_rooms table for room_mockups when designs.json snapshot is empty — rooms now appear on every SKU product page durably (survives snapshot rebuilds), file-existence guarded so no broken imgs
  475. 3bcf7db 2026-05-29 colorways: admin Publish badge on chip + new_design_published in /api/colorways
  476. a730f34 2026-05-29 colorways: add admin Publish/Unpublish endpoints for promoted spoon rows
  477. c334676 2026-05-29 Publish 19 clean aztec-kilim designs live (ids 54417-54436, ex 54419 seam-fail)
  478. cf8fd5d 2026-05-29 elements bake — recover 4 truncated Round-1 PNGs via targeted LOAD_TRUNCATED_IMAGES fallback
  479. 1d9bacf 2026-05-29 fix(generator_tick): guard finishRun against non-numeric runId (no more WHERE id=; spam)
  480. c42d61a 2026-05-29 admin/rooms list: filter out soft-deleted rooms (AND removed_at IS NULL) so /api/rooms/:id/remove hides them from the gallery
  481. 0be62b7 2026-05-29 elements: add prod-flavored extract.py with path rewriter + incremental persist
  482. c12ba4f 2026-05-29 publish-gate: raise execSync 90s→240s and urllib 120s→210s for CPU llava
  483. 5abd25b 2026-05-29 /design/:id?cw=<N> server-renders colorway-flavored title/canonical/og:image; bake-on-first-hit JPG cache at data/og-cw/cw_<id>.jpg (PIL recolor + 1200x630 OG-default crop).
  484. 463100b 2026-05-29 color-dots: double-click on colorway chip launches its product page
  485. 8ae5031 2026-05-29 fix(colorways/promote): designs.json fallback + nullable FK
  486. 669fc05 2026-05-29 add backfill-wallco-rooms.js: populate /admin/rooms gallery from the 1,421 bulk data/rooms mockups that generate_room_mockups.py never inserted into wallco_rooms (idempotent, tagged for reversal)
  487. 6a83e70 2026-05-29 admin/rooms: img src prefers /designs/room/design_<id>_<type>.png with onerror fallback to legacy image_path (fixes ~1377 broken thumbnails; mirrors prod 3dc8702)
  488. 18b423b 2026-05-29 feat(colorways): admin user fallback for save/list/delete
  489. b6425eb 2026-05-29 feat(colorways): promote saved colorway to a real spoon_all_designs row
  490. 838401d 2026-05-29 Cactus curator: click a card's color dot to recolor via native color wheel
  491. a72f554 2026-05-29 Age prompt: voice the message on load via Web Speech API (best-effort; re-tries on first gesture if the browser gates speech)
  492. f9d25bc 2026-05-29 fix(colorways): restore original chip visual after anchor swap
  493. 759068a 2026-05-29 trade-login: add password sign-in (env-var gated) alongside magic-link
  494. 1950b74 2026-05-29 feat(colorways): clicking a saved colorway chip opens it as a product
  495. 1ed5276 2026-05-29 Age prompt: add 'We are asking to serve the best theme for your eyes.' line on the first-visit age overlay
  496. 4e1f5e0 2026-05-29 feat(theme-gallery): width + height sliders, dynamic resize on input
  497. 58b694b 2026-05-29 Save-this-colorway: per-user EXCLUSIVE versioned colorways. New src/colorways.js (wallco_user_colorways table + /api/colorways save/list/delete, trade-auth gated); color-dots.js gains Save button + version rail (jump to any saved version) + reset. Verified authed round-trip v1/v2 + unauthed 401
  498. 69f306b 2026-05-29 color-dots: interactive recolor — click a dot to open an HSV color wheel, drag to pick a new ink, pattern live-recolors that ink (per-pixel delta preserves texture). Applies across all 17 variants + classic PDP
  499. 6f2666d 2026-05-29 cactus-curator: select-all button + live-animate-out + auto-force-publish UX
  500. 8e67419 2026-05-29 Add color-dots.js: vertical strip of the pattern's screen-print ink colors (canvas-extracted) along the left edge of every pattern, included across all 17 PDP theme variants
  501. 8c1ed72 2026-05-29 revert: theme1/theme2 toggle on /designs admin (was super-zooming cards)
  502. 300315d 2026-05-29 C-bridge (DTD interim): patchDesignsSnapshot() persists curator publishes into designs.json (is_published/user_removed/force-tag + resolve real filename from PG) + reload, so grid+PDP+persistence all agree. Wired into bulk + single publish paths
  503. c090fe6 2026-05-29 addToIndex: derive filename from image_url so designHasImage grid filter can match (one more structure-matrix seam)
  504. 7e0d667 2026-05-29 Add addToIndex(): surface curator-published designs on the storefront immediately (mirror of dropFromIndex) — overrides stale snapshot user_removed/is_published + aesthetic gate; PDP now 200. Grid-listing filter gap remains (structure-matrix)
  505. 49dcd87 2026-05-29 feat(designs grid): admin-only theme1/theme2 toggle on /designs
  506. bda32cf 2026-05-29 audit: bulk-publish 246 muybridge-plate designs (force=true past gate)
  507. 925a444 2026-05-29 fix(blank-guard): un-blank 3510/3529 (imperial-garden colorways, false positives)
  508. c26ba53 2026-05-29 fix(design page): gate theme1/theme2 toggle to admin-only
  509. b75d7f3 2026-05-29 audit: bulk Bad 39 flagged-live designs from haiku full-sweep triage
  510. 6e172f4 2026-05-29 feat(curator): force-publish stoned-animals (Steve explicit override 2026-05-29)
  511. c9f199f 2026-05-29 Honor force in bulk /api/cactus-decision live path — bulk Publish now bypasses the 100% gate (frontend already sent force:true; backend was dropping it → everything parked)
  512. 08eb2ac 2026-05-29 Fix cactus-curator 'Published only' toggle to filter the main grid (was stack-only; now drives the #filter dropdown via change event)
  513. 2547596 2026-05-29 cactus-curator: auto-select 'Publish anyway' on gate-held (per-card + bulk)
  514. 89d7ad5 2026-05-29 Fix publish-gate.py prod fail-closed: use resolved image path for seam scan (not dead Mac2 local_path) + PIL resize instead of macOS-only sips for vision JPEG
  515. 96e8588 2026-05-29 fix: /api/design/:id/fix reads all_designs first (spoon fallback) so it stops falsely reporting 'image file not found' on curator-visible designs that drifted out of spoon_all_designs
  516. dd42e27 2026-05-29 audit: unpublish 20 more flagged-goods from haiku full-sweep triage
  517. cf75a5c 2026-05-29 fix(publish-gate): sudo-psql on Linux + image-path fallback — gate falsely failed on prod
  518. 79f45cc 2026-05-29 Add 6 room-left PDP theme variants V12-V17 (room setting left of pattern, adjustments in a hamburger selector) + routes + Theme submenu + gallery entries + admin-tabs nav link
  519. 0b5f501 2026-05-29 cactus-curator: per-card Bad/Digital/Unpublish animate out + reset stale 'all' filter
  520. fe9624d 2026-05-29 harden(db): psqlExecLocal throws on psql error (ON_ERROR_STOP=1)
  521. f6e3188 2026-05-29 cactus-curator: haiku-vision chips + Fix-now heal pipeline w/ rollback
  522. 2c77613 2026-05-29 Add Theme Gallery link to admin-nav hamburger (sibling of Room Renders Gallery)
  523. d65186a 2026-05-29 Add admin Theme Preview Gallery (/admin/theme-gallery) — all 11 PDP theme variants side-by-side per design, viewport toggle, created-date chip
  524. 61fa817 2026-05-29 audit: unpublish 7 designs caught by haiku-weekend goods-smoke
  525. 9d53444 2026-05-29 cactus-curator: add Unpublish action (kbd 6) + button
  526. 77af6a2 2026-05-29 feat(contact-sheet): room-setting thumbnails + wallco.ai footer + 8-col cap
  527. 3778fde 2026-05-29 fix(cactus-curator): batch bulk-delete + drop removed SKUs from live index
  528. 6ef7cef 2026-05-29 Add sweep-orphan-rooms.py: remove unreferenced room PNGs (dry-run default, --delete/--verify), reclaimed ~1.7GB on prod
  529. 9b7f1eb 2026-05-29 feat(designs-grid): Contact sheet button on admin bulk-select toolbar
  530. 875105c 2026-05-29 haiku weekend test: yolo-queue runner (max-plan path) + SQL fixes
  531. d335cbc 2026-05-29 Add rollback-photoreal-rooms.py: regenerate living_room mockups via :3075 service, explicit served-dir output, no PG dependency
  532. 431fbf5 2026-05-29 haiku 4.5 weekend defect-scan test scripts + monday summary
  533. 63833d5 2026-05-29 security: remove vestigial admin:DWSecure2024! basic-auth string
  534. 692c3ba 2026-05-29 Update Claude model IDs to claude-opus-4-8 (Opus 4.8 upgrade)
  535. 84a88cf 2026-05-29 docs: Digital Downloads app delivery runbook (chosen over webhook/token path)
  536. 52f07a5 2026-05-29 chore(gitignore): ignore timestamped *.bak.* runtime backups
  537. ccbd1fb 2026-05-29 feat(mockup-queue): auto-refresh designs.json + hot-reload server after batch
  538. 13587cd 2026-05-29 fix(by-id-image): query all_designs not spoon_all_designs in PG fallback
  539. 4781d58 2026-05-29 fix(by-id-image): add IMG_DIR + basename(local_path) candidate
  540. 5c516fe 2026-05-29 feat(pdp): V11 Best-of composite — merge V1+V3+V9 strengths
  541. 74ee628 2026-05-29 docs: SHOPIFY-WEBHOOK-REGISTRATION one-pager (UI registration path bypasses read_orders scope gap)
  542. 34281f4 2026-05-28 feat(pdp): V4-V10 theme variants — full 10-variant Theme submenu
  543. 441d381 2026-05-28 /designs: replace binary 'In a room' chip with a chip row — All / Any / 🛋 Living / 🛏 Bedroom / 🍷 Dining / 💼 Office. Each chip shows a count + dims to 45% opacity when count=0. Server filter accepts specific room type (room_mockups[] contains the value) OR binary 'any' (length > 0). Breadcrumb reads 'In a bedroom' etc instead of generic 'In-room previews'
  544. 06db4d7 2026-05-28 feat(pdp): V3 Sticky Hero + Tabs theme — /design/:id/tabs + Theme submenu entry
  545. 701c89a 2026-05-28 feat(pdp): V1 Two-Column Compact theme — /design/:id/compact + Theme submenu entry
  546. 83ea0b2 2026-05-28 polish pass (#1+#2+#5 of 'all 6 threads'): (1) loop.sh singleton — flock-style mkdir lockdir + stale-pid cleanup, stops the 5-concurrent-instance dup-disaster that ran tasks 39/40/44 each 3x today. (2) server.js ensureUpscaleBytesColumn() migration — fresh DB schemas get the byte-budget cache column. (5) wall-viewer iframe — auto-fit height via onload + ResizeObserver, no border, color-scheme:light so it inherits page theme. PLUS scripts/queue-room-mockups-for-etsy-bucket.js (dry-run default, /bin/zsh.10/call ROOM_API, --commit flag to actually spend) + scripts/stripe-room-upsell-scaffold.md (architecture doc for future paid-tier on ROOM_API). #3 resolved by regenerating bundles via byte-budget refactor — 12 bundles all under 72.1 MB
  547. 7f1d2f6 2026-05-28 feat(pdp): theme submenu inside UR hamburger — Classic + V2 Bento Grid
  548. 2973b9e 2026-05-28 scripts: stamp-shopify-bundle-metafields.js — repeatable stamper for wallco_ai.* product metafields
  549. c000130 2026-05-28 feat(pdp): V2 Bento Grid theme — /design/:id/bento + /api/design/:id
  550. 2229fb4 2026-05-28 tests: 19 unit tests for shopify-bundle-webhook (HMAC verify + ingest + handler)
  551. d6de7c5 2026-05-28 scripts: register-shopify-webhooks.js — idempotent orders/paid webhook registration
  552. c15a691 2026-05-28 shopify orders/paid webhook: mint per-order download token per bundle line item
  553. 96f9215 2026-05-28 deploy: ship scripts/mint-shopify-download-token.js to prod (alongside seam-defect-boxes) so Steve can mint download tokens directly on the box
  554. 82f333f 2026-05-28 tile-period-detect: PIL+numpy quantitative validator for mural-mode renders (FFT/autocorrelation detects tile-grid periodicity in room mockups). Authored by yolo task 39 (mural-render-programmatic-validation) — committed here for proper home; carryover staged in repo because that task hit max-turns before its own commit phase
  555. 334af5a 2026-05-28 etsy bundles: option C v2 — replace count-based cap with byte-budget packing (75 MB default). Empirical finding from yolo-task-49: per-design upscaled PNGs vary 0.77-10.55 MB (5× spread driven by pattern complexity); count caps fail catastrophically when heavy designs cluster (warm-red 9-pack hit 114 MB, warm-orange-01 12-pack hit 109 MB despite the option-C 12-cap). Byte-budget targets total ZIP size and is robust to future heavy designs. estimateBundleZipBytes() uses cached all_designs.upscale_bytes_2400 + source_1024 file size. push-etsy-bundle.js: source_1024.png now ACTUALLY resized to 1024² (was preserving original ~20MB file). mass-push-etsy.js: --target-size → --byte-budget flag. Authored by yolo worker (task 49 instances all hit max-turns/timeout but shipped the refactor before dying)
  556. e4cb8b8 2026-05-28 rooms: add Mac2→prod auto-sync wrapper so room PNGs land on prod after each batch
  557. 8c14be1 2026-05-28 mural categories never tile — helper + hard rule + fixed 12 misclassified rows (10 monterey-mural + 2 cactus-pine-scenic)
  558. 4ad23bc 2026-05-28 feat(design page): theme1/theme2 toggle, default theme2 onload
  559. 71a12b2 2026-05-28 add botanical-wonders substitute generator + curator (12 designs for retired Clarke & Clarke DWKK-127831/127832 samples)
  560. d43deaf 2026-05-28 generate_room_mockups: add --all-published, --kind-filter, --category-filter, --regen-old, --dry-run
  561. 87fa2ac 2026-05-28 wallco.ai: finish Scenic+Studio sub-brand strip — kill orphaned customer chips + trade-pricing brand text
  562. aed2aa0 2026-05-28 strip Scenic/Studio sub-brand from customer-facing surfaces (proposal killed 2026-05-28 via DTD)
  563. 7e34229 2026-05-28 luxe-curator: add canonical .when chip + flow created_at through /api/luxe-curator
  564. e1b59d8 2026-05-28 wallco.ai downloads route: /downloads/:slug/:token.zip token-gated bundle delivery (wallco_download_tokens PG table) + mint CLI + tokens minted + Shopify metafields set on 3 drafts
  565. c4b01d5 2026-05-28 add tile-period-detect: validate mural-mode room renders
  566. 23b1207 2026-05-28 wallco-etsy bundles: option C wired — target-size 12 (was 15) + hard maxSize=12 + 2400px upscale (was 3600px). Each ZIP now ~75 MB (12 designs × ~6 MB), comfortably under Etsy's 100 MB file-upload cap. Listing description text updated to 2400×2400/16in. Picked by /dtd panel 2026-05-28 (2/2 valid panelists voted C — keeps bundle-count manageable + comfortable cap headroom). Old bundle metadata wiped for fresh rebuild
  567. 760af6a 2026-05-28 Scenic+Studio sub-brand proposal: KILLED 2026-05-28 (DTD verdict)
  568. 050d10b 2026-05-28 scripts/mass-push-etsy.js — single-command drain wallco_etsy_bucket → Etsy drafts. Wraps generate-etsy-bundles.js --commit + push-etsy-bundle.js (per slug, sequential, rate-limited). --skip-bundle-gen / --by / --resume / --max-bundles / --state active / --dry-run flags. 3-consecutive-failure circuit breaker (auth/quota recovery). Manifest at data/etsy-exports/<date>/mass-push-manifest-<ts>.json. Fail-fast missing-creds preflight (exit 4) so we never half-run
  569. b14db23 2026-05-28 card-room hover: drop chip inset, show entire room setting on hover
  570. f55cad1 2026-05-28 scripts: push-shopify-digital-bundle.js — Shopify counterpart to push-etsy-bundle, DTD verdict B
  571. 5f263d7 2026-05-28 cactus-curator: hover any chip to swap flat tile → room mockup (🛋 badge marks the 164/3951 chips with room data; same hover-swap on by-base family cards)
  572. a2a7d70 2026-05-28 /me/saved: add admin view-mode toggle pill (admin/live) — info@designerwallcoverings.com already gets dw_auth on trade-login allowlist (line 3667), but the toggle UI was only on /designs. Now flipped from /me/saved too.
  573. 09c554e 2026-05-28 hero: room slides use background-size:cover (full-width) instead of contain
  574. 88d80d7 2026-05-28 hero: 2048² Lanczos-upscaled room mockups; heroImageUrl prefers _hero.png
  575. cf819f1 2026-05-28 snapshot: lift pil-edge-heal block for mural/scenic categories; bulk-publish 294 monterey-mural heals
  576. a6405c4 2026-05-28 cactus-curator: mural categories don't hide web_viewer from 'undecided'; add hidden-by-filter hint
  577. 48ecb0c 2026-05-28 homepage hero: room slides render at FULL SCALE — hero-slide.is-room uses background-size:contain (was 'cover' which cropped 1024² rooms on wide hero strip → soft+lost context); frame backing uses per-design dominant_hex (--hero-frame) so letterbox reads as intentional framing. Steve directive 'must be at full scale so it is clean and clear'
  578. fa813e7 2026-05-28 homepage cards: 'second position' room-setting inset chip — when a design has photoreal rooms, layers a corner thumbnail (~42% wide, bottom-right, rounded shadow) inside the .card-img + 'In a room' badge that fades in on hover. Pointer-events:none so clicks fall through to the parent design link.
  579. 223088a 2026-05-28 /designs grid bulk-action: scrub URL creds on fetch — same fix as 4b8026f5's unpublish patch, but for the grid's bulk-action handler
  580. 46eb294 2026-05-28 homepage hero: prefer photoreal room-mockup over flat tile when available (heroImageUrl helper picks /designs/room/design_<id>_<room>.png if room_mockups[] non-empty); heroDesigns() biases toward rooms-first, falls back to high-sat flat tiles to fill 6 slides
  581. f538318 2026-05-28 /design/:id 'Sell on Etsy' button — go one-click force-add by default (design-page = deliberate admin intent; gate becomes advisory). Surface scores in success status if seams > 12 so the admin sees the warning without being blocked. Curator bulk actions keep the eligibility gate
  582. d9d340a 2026-05-28 /design/:id admin toolbar: 'Sell on Etsy' button — (1) absolute-URL fetch so Basic-Auth credentials in the page URL don't break Request construction; (2) live elapsed-time progress during the 30-60s seam scan; (3) on gate-fail surfaces scores + an amber 'Sell anyway →' button that POSTs {force:true} to bypass — same pattern as the publish gate-held toast. Also fixed atb-fix (smart-fix) to use absolute URL for the same reason
  583. b471c32 2026-05-28 wall-room-viewer: add Wall HEIGHT slider matching the Wall WIDTH layout — independent room aspect, true px-per-inch on both axes, V-ruler counts to wall height, badge shows ↔N × ↕M repeats. Defaults 9' (108"), range 7'-15' (84-180"), persists via localStorage wrv_wall_h
  584. a5228db 2026-05-28 design grid: universal hover-preview for the ~93% of cards without a room mockup — pure-CSS ::after pseudo-element on .card-img tiles the same image at 33% (3×3 zoom-out, reveals the seamless repeat). cards WITH a room mockup keep the existing photoreal swap (.has-room wins). Stamped --card-bg on every card-img site (7 spots) so the pseudo-element gets the right source w/o extra fetch
  585. 86dd47e 2026-05-28 wall-viewer: ROOM_API render as sign-in upsell. /api/room now requires admin OR trade-user (anonymous → 401 sign_in_required); requested_by_user_id stamped on wallco_rooms for attribution. Frontend: 'Try in your room' CTA + 4 room-type chips + render overlay + reset-back-to-wall pill; postMessage to parent /design/:id for trade-login redirect; replaces tiled wall preview w/ photoreal render in place
  586. 557b826 2026-05-28 front-end: bring wall+room viewer to customer-facing /design/:id (iframe public/wall-room-viewer.html w/ 24/36/54 repeat pills + wall-width slider 96-240in + repeat-count + pinstripes + ft+in rulers). Add hidden admin-nav block to public hamburger w/ links to all curator tools; /api/admin/whoami probe unhides it for admin requests. Same wall/room tech now visible on both front (customers, no API cost) and back (admins, full curator)
  587. 153d690 2026-05-28 etsyEligible: pass --path to seam scanner (resolve from DESIGNS) instead of --id, so prod (Node-as-root → no PG role) skips the broken psql path-lookup. Falls back to --id when path unresolvable.
  588. da0674d 2026-05-28 deploy: ship scripts/seam-defect-boxes.py to prod (used by /api/etsy-bucket/add eligibility check). Same pattern as refresh_designs_snapshot.py: explicit single-file rsync after scripts/ wholesale exclude. Add narrowly as more runtime-endpoint scripts emerge.
  589. 77dbbab 2026-05-28 admin pages: q() now anchors '/'-prefixed paths to location.origin — strips embedded Basic Auth credentials from the document base URL so JS fetch can construct Requests (Fetch spec rejects credentialed URLs in Request constructor; manifests as 'Failed to execute fetch on Window: Request cannot be constructed from a URL that includes credentials' when page is loaded via http://admin:pw@host/...). Applied to cactus-curator, drunk-curator, rooms, etsy-bucket, etsy-setup, seam-debug
  590. f55c3ff 2026-05-28 etsyEligible: graceful fallback when seam-defect-boxes.py isn't deployed — scripts/ is rsync-excluded on prod, so the Etsy toolbar button was hard-failing eligibility on every design. Now returns SKIPPED + ok=true; force:true still bypasses.
  591. a04f46c 2026-05-28 unpublish endpoint: read+write the catalog snapshot (in-memory + data/designs.json) so it works on prod where PG is sparse. PG UPDATE retained as best-effort no-op on prod, source of truth locally.
  592. 82cafd8 2026-05-28 cactus-curator: add ★ top-N rank pill + ✨ fresh chip (24h) to card badges — ported from drunk-curator ID-cue pattern
  593. 1097a55 2026-05-28 cactus-curator: fix regex typo in TIF-path basename extractor
  594. 4b8026f 2026-05-28 design page: scrub URL credentials via history.replaceState BEFORE any fetch — fixes 'Request cannot be constructed from a URL that includes credentials' on every relative-URL fetch (unpublish, smart-fix, etsy-bucket, /api/rooms etc.) when page is loaded via http://user:pass@host/...
  595. 696e739 2026-05-28 unpublish endpoint: drop updated_at column (doesn't exist on all_designs — psqlExecLocal silent-on-error was swallowing the failure)
  596. 88d2c1f 2026-05-28 design page: sticky admin toolbar (Unpublish / Smart-fix / Sell-on-Etsy-bucket) at top of /design/:id + POST /api/design/:id/unpublish toggle. Local only — wallco.ai deploy gated.
  597. 54a2c78 2026-05-28 trade-login: wire PureLyMail SMTP (smtp.purelymail.com:465 SSL, auth noreply@agentabrams.com — same pattern as george-gmail). nodemailer installed. MAIL_FROM='wallco.ai sign-in <noreply@agentabrams.com>' (change after adding wallco.ai to that mailbox's allowed-sender list). Test sent successfully — sent:true via smtp
  598. 1f77520 2026-05-28 cactus-curator: 📦 TIF badge on every card (green when archive present + tif dims/MB on hover, amber 'NO TIF' otherwise); server cactus/list returns tif_path/tif_w_px/tif_h_px/tif_bytes
  599. 63a6271 2026-05-28 refresh_designs_snapshot: include tags[] column so the curator-force-publish exemption in passesAestheticGate actually matches on prod (was the missing piece — gate filtered #53814 out of DESIGNS at load despite is_published=TRUE)
  600. 49f4fa9 2026-05-28 HOT-always-publish: bypass passesAestheticGate at server load too — designs tagged 'curator-force-publish' are exempt from neon/>3-hue/rainbow filter (was the third gate causing 404 on prod despite is_published=TRUE). All force-HOT writes now stamp the tag
  601. d7db846 2026-05-28 drunk-curator HOT = always publish (Steve directive 'dont stop if we say publish'): UI sends force:true on every HOT; server wraps force-publish in BEGIN; SET LOCAL settlement.allow_override='true'; UPDATE; COMMIT — bypasses both runPublishGate AND the PG settlement_publish_check trigger (banana/9-color/etc); notes stamped 'curator-force-publish 2026-05-28' for provenance
  602. e1ba323 2026-05-28 drunk-curator = canonical Hot-or-Not agent: add 🛒 Etsy bucket action button (keybind: S) next to HOT/Fix/NOT/Extract. Posts to /api/etsy-bucket/add (queues for digital-download listing at 300 DPI / 7200px). Ineligibility (seam FAIL etc) surfaces an amber toast with the reason; eligibility passes auto-advance the queue + tag the design 'etsy-bucket'
  603. 8581f87 2026-05-28 night-builder: land UNPUBLISHED — every new comfy roll requires curator approval (was auto-publishing 9+/day to storefront unreviewed); colorway variants INSERT is_published=FALSE; base post-2tone guard re-asserts FALSE (catches upstream regressions)
  604. 78c466d 2026-05-28 trade-login: wire transactional email send via sendTransactionalEmail() — auto-detects Resend (RESEND_API_KEY) or SMTP (SMTP_HOST+USER+PASS via lazy nodemailer). Falls back to existing copy-link UI when no provider configured. /api/trade/login now returns {sent, provider} flags; frontend shows 'Check your inbox' on send success and the copy-link UI otherwise
  605. 0f523b9 2026-05-28 design page: collapse the always-visible palette-strip on load (was the 'colors expanded' surface) + hue-sort the client-side extracted dots
  606. 243bd61 2026-05-28 etsy pipeline brand: Fentucci Digital Packs (final). 4 references swept across bundles + singles intro + footer
  607. f32ecb6 2026-05-28 etsy pipeline: brand → Fentucci Designs (was Designer Wallcoverings) in single-listing footer + bundle footer + intro line
  608. b962080 2026-05-28 heal: drop SDXL-inpaint strength 0.95 -> 0.7 (blend with surrounding pixels instead of full replacement, preserves the flat-screen-print aesthetic on tone-on-tone designs)
  609. 2d60ba7 2026-05-28 design page: backfill palette from PG when snapshot lacks it + hue-sort (color-wheel order, near-grays to tail) — single sort flows through every chip render path
  610. 02f7eab 2026-05-28 etsy activation wizard: /admin/etsy-setup — single-page status matrix (5 steps: app, key, oauth, shop_id, test) w/ one-click triggers. Server routes: /api/etsy-setup/{status,save-key,save-shop-id,start-oauth,test}. spawns scripts/etsy-oauth-helper.js detached; polls until tokens land; shows 'ready to push' banner linking to bucket when all 4 creds present
  611. 09b88ed 2026-05-28 cactus-curator: click-any-image → full-screen heal modal (drag-to-mark numbered red dotted boxes, ⚕ Heal calls Replicate SDXL inpaint with manual_boxes, ↺ Back pops history stack to revert, ✓ Accept promotes via /heal/approve, ✕ Close/Esc discards); by-base family cards add 🕓 created date pill; seam-debug also gains drag-to-add manual heal regions (M1, M2…) merged into heal endpoint via new manual_boxes payload; python normalizes scanner pixel-coords + accepts --manual fraction boxes
  612. ade5237 2026-05-28 cactus-curator by-base: full selection + action parity with index — sel-box, .acts (Bad/Digital/Fix/Live/Etsy), state label, decided class. Delegated click handler on #bbstack survives renderStack innerHTML rebuilds. applySelection/toggleSel resolve cards across #grid AND #bbstack. Marquee drag-select binds to both containers + enumerates cards in either to extend rubber-band across the stack
  613. 78f5533 2026-05-28 cactus-curator by-base: 'Published only' filter (default ON) — hides families with no published rows + filters thumb strips to published-only; toggle button persists in localStorage
  614. 7cdc0df 2026-05-28 etsy oauth: scripts/etsy-oauth-helper.js — one-time interactive auth (PKCE/OAuth2, local 3008 redirect listener, auto-opens browser, captures code, exchanges for tokens, fetches shop_id via /users/{id}/shops, prints secrets-manager save command). --refresh mode for the 1-hour access-token expiry. Fail-fast on missing ETSY_CLIENT_ID
  615. 3ce6882 2026-05-28 cactus-curator by-base layout: tight grid like the index page (.card chrome, --cols density, same width); fix display:block overriding .grid display:grid
  616. 5ad0135 2026-05-28 etsy push: scripts/push-etsy-bundle.js — atomic just-in-time asset build → Etsy v3 API → bucket state update → local cleanup. requireCreds() fail-fast w/ secrets-manager setup hints; --dry-run + --no-cleanup flags; multipart upload for cover + 6 preview images + ZIP
  617. 54a491e 2026-05-28 cactus-curator: 'By-base layout' is now an INDEX-PAGE mode (replaces modal overlay) — vertical stack of family cards (base big + colorway thumbs strip under each) for any ?category=, persists in localStorage, works on every collection with parent_design_id linkage
  618. ae36473 2026-05-28 etsy bundles: scripts/generate-etsy-bundles.js groups bucket/tagged designs into bundles (by category/color/manual); --build-assets opt-in for preview cover; default metadata-only · export-etsy-digital.js also flipped to metadata-only by default (Steve 'only create file when we upload to etsy'); test PNGs purged
  619. 8c77b4c 2026-05-28 seam-debug: replace PIL band-blur with Replicate SDXL-inpaint (auto-mirrors mask for edge boxes to preserve wrap); add preview/approve modal + /heal/approve (promotes heal, marks original removed + logs to defect registry) + Regenerate-from-prompt button (/api/seam-debug/:id/regenerate)
  620. 8794315 2026-05-28 etsy export: add print_ready_in / print_ready_ft computed fields per listing (close-up 150 DPI / room 75 DPI / mural 50 DPI) + safe-print-size language in description + CSV columns
  621. c07a04e 2026-05-28 tone-on-tone hex picker: sort by hue + collapse near-duplicate swatches
  622. e9fe6eb 2026-05-28 cactus-curator: 'By-base view' toggle — 1 pattern + thumbs of all colorways (overlay), ←/→/Esc + click-thumb-to-swap; backed by new /api/admin/cactus/families endpoint (route-guard /cactus/:id for shadowing)
  623. 3fc593c 2026-05-28 etsy-tag endpoint: drop nonexistent 'title' column (view has ai_title only)
  624. 3ed1a19 2026-05-28 design page: Sell on Etsy (digital) button → tags etsy-digital-file + queues to data/etsy-queue.jsonl (no Etsy API call yet — listing stays a gated batch op)
  625. 78093f0 2026-05-28 etsy bucket: wallco_etsy_bucket table + /api/etsy-bucket/{add,list,DELETE} + /admin/etsy-bucket viewer · curator 5th button (🛒 Etsy + key 5 + bulk-bar entry) · eligibility gate (seamless verdict ≤ WARN) · bucket items excluded from cactus/list + drunk/list pools
  626. c9af59b 2026-05-28 seam-debug: click boxes to select + 'Heal selected' button (also 'Heal all'); POST /api/seam-debug/:id/heal runs targeted mid-band/edge-wrap heal via PIL, saves as NEW design w/ healed-from tag, returns before/after scan
  627. fd80752 2026-05-28 curator: fix bgswap matcher (gen name is 'gemini-…-bg-swap', includes('bgswap') missed it) — bgswap now wins character-sort + shows blue badge
  628. 581d6a2 2026-05-28 etsy export: scripts/export-etsy-digital.js writes per-design source+cover+print PNGs + listing.json/csv manifest (Vela/eRank ready); --tif/-no-upscale flags; incremental via etsy-exported tag
  629. 2ca51dc 2026-05-28 drunk-curator: add sort (density/character/newest) + generator filter (persists in localStorage)
  630. d083387 2026-05-28 admin/bg-tester: .when chip on recent-design tiles (created date+time, ISO in title)
  631. 0972eb1 2026-05-28 admin/drunk-curator: include year in fmtDate (canonical date+time format)
  632. 312e90c 2026-05-28 cactus-decision: route guard for /bulk shadowing fix + publish-gate bypass for svg-tessellate (construction-guaranteed seamless+2-color)
  633. 37d5e6d 2026-05-28 cactus-curator: gate-held → 200 park (was 422 dropping vote, same loop as drunk-curator HOT bug); frontend offers amber 'Publish anyway' toast w/ force:true override
  634. 041d703 2026-05-28 drunk-curator: richer ID cues — density tier, subject+emoji, generator badge, colorway, top-N rank, freshness chip
  635. 5a5d6f7 2026-05-28 seam-debug: localize ALL joints (4 edge-wrap pairs + 2 internal latent-grid) — orange edge boxes + blue edge-wrap lines + box pairing across the wrap
  636. a55e2ac 2026-05-28 seam-defect localizer + /admin/seam-debug viewer (per-row/per-col ΔE → boxes) · rooms sort by pattern · debug-seams link per card
  637. beb0d0b 2026-05-28 drunk-curator: sort by triage instance-count desc (AUTO_HOT_N=<n>) so strongest dense candidates surface first
  638. 6eda7cc 2026-05-28 designs.json refresh: allowlist svg-% generators + ship 11 new geometric-block-leaves svg-tessellate tiles
  639. f460ec8 2026-05-27 clean-edge upscale (#53677): confirm potrace vectorize beats LANCZOS, document venv invocation
  640. e5f92ce 2026-05-27 render 5400px/150-DPI TIF archives for 25 HOT geom tiles (from svg masters, 2-ink LZW); tif_path/bytes/dims recorded; archive-svg-5400.js + svg_raster_snap tif support
  641. f02d8c5 2026-05-27 geom tessellation: add --palette colorways; generate terracotta-on-bone colorway (19 tiles) alongside navy
  642. ed63d9b 2026-05-27 curator: equal-size left/right panes (shared imgSize) + corner-drag resize grips
  643. 7bc6023 2026-05-27 TODO: mark geometric-block-leaves reroll done (19 SVG tessellation tiles awaiting curation)
  644. 22eba6a 2026-05-27 reroll geometric-block-leaves via programmatic SVG tessellation (DTD-C): 19 tiles, 2-ink navy/cream, seamless-by-construction, vector master kept; gen-geom-svg-tessellate.js + svg_raster_snap.py
  645. 45b818c 2026-05-27 room: user-adjustable wall-size slider (default 13.5ft) + fullscreen toggle
  646. 152132e 2026-05-27 drunk-curator: click pattern to enlarge (1x/2x/3x repeat lightbox to inspect seams); drag still marks misaligned
  647. def6e52 2026-05-27 room wall: show repeat count + black pinstripe vertical lines at each repeat boundary
  648. 39a931a 2026-05-27 curator: 24/36/54 widths + 12x12 sq room (fix 0x0 wall) + drag-to-mark-misaligned highlighter (saves to bad_examples) + drunk/list returns existing boxes
  649. a174bb9 2026-05-27 room setting: 12×12ft square room + ft-in rulers framing it + 24/36/54 presets + Furniture/Extract buttons
  650. a68dbc6 2026-05-27 drunk-curator: add dual rulers — pattern in inches (W×H), room wall in feet+inches (W×H)
  651. b0965ac 2026-05-27 drunk-curator scale: drop slider, only 24/36/52in presets (snap saved values)
  652. 9449d43 2026-05-27 flag geometric-block-leaves as bad_batch in defect registry (38 designs, systemic gate-fail) + TODO for regen/trash decision
  653. 3327937 2026-05-27 add one-off re-screen of already-flagged candidates for large-void duds
  654. 66faa13 2026-05-27 drunk-curator: inch ruler + stretch tile to 24/36/52in print width (buttons+slider, persists); room wall repeat scales to match
  655. 6c3d280 2026-05-27 drunk-curator: held-HOT toast attaches to body so render() can't wipe it (fixes 'HOT does nothing' on gate-fail categories)
  656. 3e0f472 2026-05-27 drunk-curator: Prev/Next queue nav (buttons + , . [ ] keys) to go back/forward without deciding
  657. 6fd11d4 2026-05-27 curator HOT: gate-failed pick saves+holds (no lost vote/loop) + Publish-anyway override
  658. 4e66da1 2026-05-27 drunk-animals cleanup: recategorize 198 unpublished luxe-v2 damasks -> damask (audit manifest)
  659. d20cf0a 2026-05-27 admin-card: add created date+time chip to inspirations (cactus-curator convention)
  660. d3abf43 2026-05-27 admin-card: add created date+time chip to elements + return created_at from elements/items API (cactus-curator convention)
  661. b36a8ee 2026-05-27 cactus prompt: all-new-specs rewrite vs graphic-designer agent failures
  662. cdb9f1c 2026-05-27 admin-card: add created date+time chip to status-browser (cactus-curator convention)
  663. f35bb2b 2026-05-27 admin-card: add created/flagged date+time chip to ghost-review + pass ts through flagged API (cactus-curator convention)
  664. 08a8775 2026-05-27 admin-card: add created date+time chip to dogs-curator + return created_at from dogs/list API (cactus-curator convention)
  665. 899e7fd 2026-05-27 Task 31: circular-padding is now the DEFAULT for all seamless_tile gen
  666. 8120fe7 2026-05-27 drunk-curator: make Auto-ID opt-in via header toggle (off by default — no Gemini cost on fast vote-throughs); toggle ON scans current item, OFF clears boxes, persisted in localStorage
  667. a1070fe 2026-05-27 drunk-curator Hot-or-Not: auto-ID dotted error boxes overlaid on the flat tile (drunk-aware: flags 'No bottle'/'Not animals' per region) + decisions HOT/Fix/Trash/Extract. Extract = opaque-motif-only → elements library (reuses elements/extract.py, --id bypasses publish filter). Fix verdict added to /drunk/decide; /api/admin/drunk/extract endpoint. F/E keyboard shortcuts
  668. 7eb9c7b 2026-05-27 100% publish gate: no pattern goes live without passing every hard check
  669. 040d453 2026-05-27 Add flat-color vectorize pipeline (potrace) + edge-fix comparison proof
  670. 7462d55 2026-05-27 drunk-curator (Hot or Not): fix votes silently dropped + same item looping — decide() now SAVES FIRST and only advances on res.ok (was optimistically advancing i++ before the POST + swallowing errors in catch{}, so saves failing during server restarts left the DB unchanged and unsaved items reappeared on reload). Codex-confirmed root cause; surfaces save failures + busy-guard against double-vote
  671. ed7d4f3 2026-05-27 Hot-or-not + room setting generalized to ALL wallco.ai lines
  672. 10cd2cf 2026-05-27 auto-decider TRIAGE mode: flag AUTO_HOT_CANDIDATE (no auto-publish), exclude flagged from re-scan, curator surfaces triaged winners
  673. 717fef2 2026-05-27 autonomous drunk hot-or-not decider + single-id room render + curator HOT→room spawn + two-pane room-setting curator
  674. dad5b6d 2026-05-27 wallco curator: add Collection picker (distinct base lines) + /api/admin/curator/collections
  675. dabde51 2026-05-27 drunk-curator: two-pane hot-or-not — flat tile left + instant CSS room-setting (tiled wall + floor + furniture silhouette) right, so designs are judged as real wallpaper
  676. c8123d2 2026-05-27 add /admin/drunk-curator hot-or-not picker: HOT publishes, NOT unpublishes + logs to wallco_defect_registry; keyboard nav + streak meter; curates drunk-animals-sample* pool
  677. 6371c5c 2026-05-27 tooling: repoint-stale-paths (350 removed designs → quarantine file locations; 5 published-broken flagged) + move-drunk-damasks (vision-classify luxe-v2 drunk-animals, moved 73 published damasks → damask collection; 43 animals/7 floral left). Gemini thinkingBudget=0 for one-word classify
  678. 40ef64b 2026-05-27 drunk-animals: scrub 'label'/'labeled' positive cues from bottle backdrops (were inducing SDXL gibberish text); keeps no-text negative
  679. 4a8fa2b 2026-05-27 curator: auto-ID now PERSISTS its dotted error-boxes (auto-flagged/amber) to bad_examples.boxes — squares survive reload + accumulate as a standing learning corpus; ✓ promotes to confirmed(red), ✗ drops; unified candidate/confirmed on the auto flag
  680. 9cc30c0 2026-05-27 curator: collapse per-card action buttons by default (compact cards) — reveal on hover + 'Actions' header toggle to pin. Moved damasks #41669/#41715 → damask collection (kept published); removed cartoonish #39423 (file kept, recorded bad); un-flagged #41715
  681. 99be6d6 2026-05-27 Validate cactus seamless redo: circular-padding + gate = 4/4 PASS, vision 95 (vs ~19% old)
  682. 1dbe891 2026-05-27 curator: generalize to any collection via ?category= (loads drunk-animals etc) + 'Auto-ID all visible' batch button (capped 60, 4-concurrent); drunk-aware auto-ID detects 'No bottle' + 'Not animals' (off-concept florals/damask); box labels→defect_tags so chips reflect confirmed boxes; header count uses category
  683. 86b2fdf 2026-05-27 cactus-curator: AUTO-ID bad areas via Gemini vision (candidate amber boxes) + human confirm(✓)/reject(✗)/add(shift-drag) flow with defect-label picker (Seams/Poor edges/Cartoonish/Blurry/Ghost/Bleed); confirmed boxes+labels persist to bad_examples. /api/admin/cactus/:id/auto-id endpoint (Claude path blocked — Anthropic acct out of credits, Gemini suffices since human reviews)
  684. 65bb871 2026-05-27 cactus-curator: surface bad_examples.defect_tags as red reason chips (Cartoonish/Poor edges/Ghost/Bleed/Seams/etc) — recorded defects now show on the card front; #53661 flagged cartoonish+poor_edges
  685. 0d0cca4 2026-05-27 cactus-curator: SHIFT+drag to box bad areas (dotted red boxes, stored in bad_examples.boxes per design — id BAD elements so we never repeat); red FAIL reason chip (Seams/Blurry); fix Unpublished filter showing removed. edges-review: status sort + human failure reason. server: /api/admin/cactus/:id/annotations endpoint, bad_examples.boxes, fix-decision/bulk route un-shadowed
  686. 05fa1bc 2026-05-27 Quality benchmark = top-20 unified-db lines + DW Bespoke; cactus redo wiring
  687. ef42bbe 2026-05-27 defect-registry viewer: accurate filtered_total + Load-more paging (cap 8000) + root-cause summary banner (heal 78% / Replicate 17% / ComfyUI 1% clean)
  688. a1cbb55 2026-05-27 add /admin/defect-registry web viewer over wallco_defect_registry — browse every kept-but-rejected design + defect type + generator + prompt; sort + density slider + per-card recorded/created timestamps
  689. 017a711 2026-05-27 edges-review: sort by status (removed/active first) + dynamic REMOVED/ACTIVE/NOT-ACTIVE badge; show human failure reason in audit tooltip (e.g. 'Mismatch at horizontal midline (ΔE 12.69 at h_mid)')
  690. d042eec 2026-05-27 bad_examples registry: dedicated anti-pattern DB ('keep all bad/deleted so we never repeat the error') — backfilled 33,881 bad/deleted designs w/ full prompt+seed+generator provenance; reusable recordBad() helper; logged 11 agent-confirmed repeat-breaks (color-deltaE scan's blind spot)
  691. d8d8b1b 2026-05-27 repeat-break audit: agent vision pass over 36 published designs found 11% clearly broken L/R or T/B repeats that the color-deltaE 6-lens scan passed (incl #18924 cactus control, #29714 rabbits egregious)
  692. 83da7a0 2026-05-27 cactus curator: click any card to view full details modal
  693. 7e26aab 2026-05-27 edges-review: multi-select + bulk Reject/Delete bar (prod-gated, disabled with notice off-localhost); fix /api/fix-decision/bulk route shadowed by /:newId
  694. 6e28424 2026-05-27 cactus-curator: exclude midheal_/edgeheal_/smartfix_ derivatives from curation list — curate clean round-1 originals, not blurred seam-healed copies
  695. bd86cb5 2026-05-27 cactus curator: relabel Live->Publish for clarity (action value unchanged)
  696. 989c3d0 2026-05-27 cactus-vision-score: skip user_removed designs (only score the 701 live survivors)
  697. ae1089a 2026-05-27 edges-review: add Snapshot tab sourcing flagged designs from shipped designs.json (prod PG is sparse → live tab shows ~0); add created-date+time chip per admin-card rule
  698. 998a6c8 2026-05-27 deploy: exclude data/generated_cactus_quarantine from rsync (mirror ghost quarantine)
  699. be027c7 2026-05-27 drunk-animals prompt surgery: kill poster/album/grid styles + 'hero centered' comps that caused borders/text/single-subject; force dense all-over wallpaper repeats; add anti-poster/frame/text negatives
  700. 08ff786 2026-05-27 Cactus curator: show created date+time per card; add marquee drag-select + shift-add
  701. 63e2927 2026-05-27 Purge 2,262 fuzzy-seam cactus tiles (start-fresh); add seam-purge + vision scorer
  702. adae983 2026-05-27 drunk-animals: allow marijuana imagery (joints/buds/cannabis leaves now welcome) — flip the cannabis-leaf ban to encouraged per Steve
  703. 9d836cf 2026-05-27 retire pil-mid-heal + pil-edge-heal: delete generators, promoters, curator; guard snapshot
  704. 7d932a6 2026-05-27 promote gate: require fuzzy_seam_scan PASS in addition to edges-agent
  705. fbc35e7 2026-05-27 Add cactus curator: ranked grid + density slider + 4-verdict admin actions
  706. fdd35e6 2026-05-27 Fix fuzzy edges + blurred center-cross in all 3 seam healers (smartfix/mid/edge): replace 24-25px 2-D GaussianBlur bands with narrow ~6px 1-D directional cross-fade; drop edge-heal's indefensible interior-midline blur pass
  707. 5d63f4b 2026-05-27 fuzzy-seam scanner: detect pil-heal blur-band 'fuzzy cross' the edges-agent misses
  708. 306c86f 2026-05-27 task#25: chinoiserie tile-class SAMPLE on ComfyUI (Mac2, circular-padding) — measure seamless yield vs Replicate 20% baseline; is_published=FALSE
  709. 5778b04 2026-05-26 snapshot before reject sweep (preserve parallel-session in-progress work)
  710. dcdbbed 2026-05-26 promote_edge_heal: dry-run-default tool, re-scans + flips only fresh-PASS non-ghost edge-heals
  711. fdb9464 2026-05-26 Add style-aware-sample-verify.js — settlement + edges-scan + TIF archive for sample designs
  712. 8d5f8a8 2026-05-26 dogs curator: /admin/dogs-curator hot-or-not surface + /api/admin/dogs/list (edges badges, sort+density, bulk publish via existing endpoint)
  713. 9c864f6 2026-05-26 security: gate 4 internal /api routes admin-only + redact brand/vendor/owned_by_steve from public fliepaper-bugs spec (Yuri tick #3/M2)
  714. e59e6b0 2026-05-26 TODO: close catastrophic-cohort tick — edge_seam_heal --grid both already ran
  715. d2af6bb 2026-05-26 wallco recolor: set dominant_hex on variants so title color matches colorway
  716. 774fe30 2026-05-26 replace-bg: accept any of the 5k library textures, not just the 10 curated bg_textures rows
  717. bb2d819 2026-05-26 docs: correct CLAUDE.md — designs.json IS deployed, not excluded
  718. 808384d 2026-05-26 drunk-*: every design now shows a vice — joint/cigar/pipe/bong (was joint-only)
  719. 41574f3 2026-05-26 Add Replicate-only chinoiserie sample generator (YOLO task #13, DTD Option C)
  720. dddb2ad 2026-05-26 TODO: record dogs collection (DTD verdict, generate-dogs.js launched, curate-then-publish)
  721. 03497c0 2026-05-26 dogs collection generator — 11 breeds (DTD verdict) × 20 designer colorways, opaque repeat-v2 + composition gate, is_published=FALSE
  722. bc99681 2026-05-26 Add style-aware-sample.js — PG-palette-derived chinoiserie SAMPLE prompts onto canonical generator
  723. 3646071 2026-05-26 TODO: record 157-catalog incident + fix, fliepaper publish + 4x upscale live
  724. 0377440 2026-05-26 Gate /admin/golive[.json] + /api/dw-textures (unauth shell-exec + vendor leak)
  725. 7d8a4d5 2026-05-26 deploy: add step 2c to ship guarded refresh_designs_snapshot.py
  726. 4c2836c 2026-05-26 snapshot: prefix-match generators to end recurring allowlist-gap bug
  727. e91c2ad 2026-05-26 refresh_designs_snapshot: catastrophe guard against sparse-PG clobber
  728. 39c5e38 2026-05-26 geometric pilot: record ghost-detector false-fail verification (52.6% on geometric-block-leaves)
  729. b026705 2026-05-26 generator_tick: restrict tile categories to tone-on-tone palettes (DTD verdict B)
  730. f03778e 2026-05-26 geometric pilot: push 9 both-gates-clean designs live to wallco.ai
  731. 0626076 2026-05-26 TODO: record fliepaper partial publish (1 PASS + 10 cabinet/specimen pieces live on prod)
  732. a39972d 2026-05-26 snapshot refresh: allowlist gemini-2.5-flash-image generator (fliepaper remakes)
  733. e65fc99 2026-05-26 refresh_designs_snapshot: allowlist gemini-2.5-flash-image (no -edit) so fliepaper-bugs remakes land in snapshot
  734. f168a77 2026-05-26 TODO: edge-heal scaled 630/630 (~72% PASS, ~454 promotable) — promote+deploy next
  735. 0b10f36 2026-05-26 Revert seamless guard to TILE_CATEGORIES — mirror genComfy tileable gate
  736. 9ca0509 2026-05-26 edge_seam_heal: combined mids+edges offset-heal for the edges_only cohort (6/6 PASS sample, scale awaits sign-off)
  737. e0387ff 2026-05-26 geometric pilot: bulk-verify ghost-detector (stable 3-vote) — false-fail 100%→52.6%
  738. 66addf6 2026-05-26 Broaden seamless-comfy guard to kind==='seamless_tile' (covers drunk-*)
  739. 43ccc81 2026-05-26 Force TILE_CATEGORIES to comfy seamless path regardless of GEN_BACKEND
  740. 2c4735e 2026-05-26 add CLAUDE.md project guidance
  741. 16d950f 2026-05-26 TODO: check off Kamatera deploy (done, prod count 3516->5864)
  742. 7365543 2026-05-26 TODO: close WARN-cohort item with finding (already culled + ghost-contaminated, do not bulk-heal)
  743. 823ced1 2026-05-26 TODO: check off route-audit + aesthetic-gate diagnostics (both clean)
  744. c89f613 2026-05-26 Fix 3 v2: add MakeCircularVAE — UNet-only patch left VAE re-introducing seams
  745. 11887e5 2026-05-26 scripts: bump dead admin-reload port 9792 → 9878 across 18 batch scripts
  746. d2291bc 2026-05-26 Fix 3: inject SeamlessTile node into workflow for tile categories (Mac1 ComfyUI spinagon/seamless-tiling@9225ed5d)
  747. 2b58f6b 2026-05-26 geometric pilot: bulk-generated 20 designs (verification deferred to 01v)
  748. f8ec2be 2026-05-26 refresh_designs_snapshot: include pil-mid-heal generator (7,329 SDXL grid-leak heals)
  749. 555107a 2026-05-26 gitignore data/quarantine/ + sweep 11.6MB stale .pre-* snapshots to it (audit log preserved)
  750. 654c9be 2026-05-26 tile-profile prompts v2: re-add ghost+frame+watermark bans (regression fix from f216b0f7)
  751. 053b914 2026-05-26 mid_seam_heal: default is_published=FALSE (was TRUE — bypassed edges-agent quality bar, 65% of healed outputs were WARN)
  752. ada55f4 2026-05-26 TODO.md — surface session work to CNCP task panel
  753. ad50dfd 2026-05-26 gitignore *.pre-* snapshots + untrack stale dedupe backup (2.8MB)
  754. d023789 2026-05-26 deploy: exclude 16GB of regeneratable data dirs (elements/tif/rooms/etc) — was the cause of 25-min rsync today
  755. f216b0f 2026-05-26 per-category prompt suffix: tile-profile for damask/chinoiserie/scenic, silhouette for drunk/figure categories
  756. 540cab4 2026-05-26 gitignore data/crontab.backup-* snapshots + flush new bleed-guard entries
  757. a5384f5 2026-05-26 cleanup: exempt pil-* generators from bleed_guard + delete dead /fix route
  758. 4f3993d 2026-05-26 pm2: ecosystem.wallco-ai-9878.config.js with restart-loop guards
  759. 50fe0af 2026-05-26 scripts: --start/--count CLI flags on geometric-block-leaves generator + pilot scorer
  760. e69a345 2026-05-26 gitignore: exclude data/edges-scan-report-*.md (regeneratable, like the .tsv)
  761. 02f91e6 2026-05-26 mid_seam_heal.py — $0 production fix for SDXL latent-grid leak
  762. 3190409 2026-05-26 gitignore: exclude data/elements (6GB), data/rooms (141MB), seam-fix, yolo-findings, edges-scan-* and counter — all regeneratable artifacts
  763. e30db7d 2026-05-26 mid-heal-preview: $0 SDXL grid-leak fix sample preview
  764. 50890a3 2026-05-26 elements skill: /admin/elements browse UI + bake-at-ingest pipeline
  765. 71e56c5 2026-05-26 fix: ensureUserRemovedColumn targets all_designs base table, not view
  766. 6e609a5 2026-05-26 fliepaper-bugs: scrub category-leak in generator + YOLO loop wrapper
  767. 57869a4 2026-05-26 edges-agent: unpublish 11,274 seam-defect designs + admin red-outline review
  768. 1d8b4c6 2026-05-26 add mkdir-based mutex wrapper for cron ticks (macOS has no flock)
  769. a2dd3ee 2026-05-26 ComfyUI default → Mac1 (192.168.1.133:8188), Mac2 was OOM-killing claude sessions
  770. 43ed08a 2026-05-26 snapshot before ComfyUI redirect to Mac1
  771. bd718e0 2026-05-26 consolidate INFO + EDIT + ADMIN into single ☰ hamburger menu (UR corner)
  772. 3c5ffe6 2026-05-26 seamless gate: drunk-* tolerance 30 → 80 after overnight batch evidence
  773. 43b2da0 2026-05-25 yolo tick 10: MON-1/2/3 ✓ bundle — QUEUE COMPLETE 20/20
  774. 0a23e1e 2026-05-25 yolo tick 9: DA-5 ✅ dtd verdict D=STOP (3/3 unanimous); DA-6+DA-7 gated on Steve approval
  775. b1b2863 2026-05-25 yolo tick 8: DA-4 ✓ 6 preview IDs (curator-mode reuse) + tick ledger header
  776. 1aea628 2026-05-25 drunk-animals: add "falling off tree, one hand grasping" motifs + yolo-tick.sh ledger
  777. 001cb74 2026-05-25 drunk-* gates relaxed: seamless tolerance 12→30 + drop conflicting palette suffix
  778. 29ac6e7 2026-05-25 generate_designs.js: bump ComfyUI poll timeout 5 min → 15 min
  779. 0e37522 2026-05-25 design-coordinate cards: image-only grid, hover overlay reveals View / Sample — removes title/vendor/why/palette/paint-match text per Steve directive
  780. 061b76f 2026-05-25 DA-2+DA-3: Met PD + prior wallco design references in every drunk-animal prompt
  781. 5f63e2d 2026-05-25 remove mural pan HUD (5 arrows ↑↓←→⟲) + drag-to-pan on /design/:id hero — image now normalized 100% cover, non-draggable across all kinds
  782. 0f99287 2026-05-25 yolo-queue: SG-5 ✓ settlement-gate.test.js — 14 cases all PASS
  783. 2bde4b7 2026-05-25 yolo-queue: escalation policy — debate-team-fast on every item, not just blockers
  784. 26ab5d3 2026-05-25 yolo-queue: SG-1..SG-4 ✓ attorney narrowings (moth/bird/scatter/leaf word-boundaries)
  785. 9228ce8 2026-05-25 drunk-animals: tiki/cognac/champagne/smoking-bubble + textures + deep tones
  786. 7fc7f07 2026-05-25 yolo-queue: DP-5 ✓ hamburger media query for mobile
  787. df640d3 2026-05-25 yolo-queue: DP-3 + DP-4 ✓ hex swatches + wheel + backend hex mode
  788. 705ca06 2026-05-25 design page: Texture tab — 5,034 DW textures, sort + density slider, click-to-apply (admin)
  789. e0bff67 2026-05-25 yolo-queue: DP-2 ✓ static 96x96 thumbs + stash + click-swap
  790. f73bb22 2026-05-25 drunk-animals + drunk-zoo-36: alcohol + lit joint + swinging mandatory
  791. 0e7d69c 2026-05-25 yolo-queue: DP-1 ✓ drawer movers verified clean
  792. be77282 2026-05-25 16 product-page layout variations w/ live modals at /layouts/ — V1-V16 picker, draggable comparison slider, AR mockup, concierge chat, bento grid, terminal inspector, storytelling long-form, print-master inspector
  793. aceea32 2026-05-25 extend-luxe-curator — backfill C + queue A/E for reverted-blanket roots
  794. 467c1ec 2026-05-25 audit-room-seam: tighter masks + pattern-vs-seam disambiguation
  795. 929d53b 2026-05-25 T7: batch-quality audit — 99.3% ok, no variant/ground bias
  796. fbe6091 2026-05-25 T6: gen-luxe --verify-subjects flag (off by default, ~$0.0005/check)
  797. c2332ef 2026-05-25 T4: keyboard R = regen focused row; visual focus ring; K-key conflict fix
  798. 05d4109 2026-05-25 T3: regenerate-THIS-variant button on /luxe-curator.html
  799. e7bc7e1 2026-05-25 T2: subject-mismatch scan + gallery — flags dropped-subject failures
  800. caabe86 2026-05-25 lib/subject-detector — Gemini vision gate for "is the prompted subject visible"
  801. 45dcfb7 2026-05-25 revert luxe-c blanket rollout + add curator-mode 4-up picker
  802. f34f3f9 2026-05-25 feat(design page): tag remaining buyer blocks for drawer relocate
  803. 44b3489 2026-05-25 /designs admin transparency badge + catalog republish + quarantine restore
  804. fd353db 2026-05-25 fix(recolor): tighten brand-mode prompt so signature accent actually appears
  805. 250dc80 2026-05-25 feat(design page): INFO hamburger + buyer drawer next to ADMIN button
  806. 8271d6d 2026-05-25 roll-luxe-c runner + /luxe-c-gallery.html viewer
  807. d0b2192 2026-05-25 TIF + SVG print-master pipeline — admin panel on /design/:id, on-demand build script, 150 DPI w/ LZW, SVG when crisp ≤8 colors
  808. 4399240 2026-05-25 design page: 3 admin accordions into admin sheet + ADMIN button beside hamburger
  809. a9b73c7 2026-05-25 gen-luxe: add --variant=<A|B|C|D|E> flag to lock heritage aesthetic
  810. 5d5b7c0 2026-05-25 fix(edges-scan): move scanner from ~/.claude/skills into project so it deploys
  811. 77c507c 2026-05-25 gen-luxe v2: 5 heritage-house variants + DW-texture ground anchor
  812. c6011e8 2026-05-25 design page admin sheet: add ⎋ Logout button next to close
  813. bcbd379 2026-05-25 feat(design page): move Curated Rating into admin drawer + add 'Run rating now' button
  814. 9b4e075 2026-05-25 stack both hamburgers in upper-right corner of design image — no longer overlaps the palette label
  815. 60f4226 2026-05-25 feat(design page): split tabs into LEFT (public) + RIGHT (admin) hamburgers
  816. 3a16b54 2026-05-25 bg-tester picker: switch to unified /api/bg-textures, hide vendor names
  817. 117c9e5 2026-05-25 fix(settlement): strip negative-prompt suffix before substring matching
  818. 3732ed9 2026-05-25 feat(design page): replace generic 14-hue tone wheel with 19 fashion-house palettes
  819. 85c30fb 2026-05-25 feat(design page): 2-col admin toolbox + edges-agent button + recreate-from-critique button
  820. c7ca41e 2026-05-25 collapse all design-page panels by default — page lands clean, click to expand each section
  821. 091fbfa 2026-05-25 Unified /api/bg-textures — title-keyword classification + dedup
  822. 75c5fe0 2026-05-24 feat(ticks): rsync-pull prod bad-aesthetic-patterns.jsonl at top of each tick
  823. b50dfe2 2026-05-24 Joint-fix gallery viewer
  824. b4c58f1 2026-05-24 fix(deploy): drop single-quotes from RSYNC_EXTRA_EXCLUDES patterns
  825. c85af21 2026-05-24 ghost-detector: seam-frame lens — catches plates at the tile boundary
  826. 913798d 2026-05-24 feat(generators): wire bad-aesthetic-patterns.jsonl into the tick loop
  827. 1848657 2026-05-24 fix(deploy): exclude ghost-scan + bad-aesthetic-patterns + ghost-purge from rsync
  828. f31431e 2026-05-24 fix-frame-overlay skill: detector + locator + crop-fix kind + auto-fix runner
  829. 641da47 2026-05-24 scripts: scan-frame-overlay.js — catalog sweep for the new defect lens
  830. 78cd6df 2026-05-24 fix(learn-and-purge): PG-side vendor-cat safety net
  831. 1a05f4b 2026-05-24 joint-fix: surgical seam repair (95%-preserve, edges only)
  832. a2e6fe6 2026-05-24 generate: wire frame-overlay gate + strengthen anti-frame prompt anchors
  833. 44322de 2026-05-24 ghost-detector: new frame-overlay lens — detects "pasted-on" geometric plates
  834. 352e9ce 2026-05-24 auto-fix: decouple ?legacy routing from prompt-version; fix PIL crash
  835. 0e7e4ff 2026-05-24 Stage 4 followup: scenic exemption + auto-fix-composition.js
  836. 5138c6e 2026-05-24 remove broken /admin/fixes-feed viewer
  837. a992ad5 2026-05-24 Stage 4: scan-composition.js + gen-poodle-demo.js
  838. f5a6676 2026-05-24 /design/:id → 302 to newest published child via parent_design_id
  839. 80466f6 2026-05-24 bg-tester: real DW texture library + recent-designs sidebar + auto-pick 4
  840. 67eac74 2026-05-24 fix(ghost-detector): vendor-category filter on PG source path + scrub poisoned flagged set
  841. 631a8c5 2026-05-24 feat(regenerate-whole): create sibling design instead of replacing original
  842. b362f0f 2026-05-24 feat(scripts): learn-and-purge-flagged.js — headless equivalent of /admin/ghost-review bulk Delete & learn
  843. 5575ce7 2026-05-24 Stage 2: composition-detector + smart-fix retry gate
  844. 9e5767b 2026-05-24 Stage 1: canonical lib/repeat-prompt.js + wire into smart-fix
  845. d8f3683 2026-05-24 seamless-detector: half-drop + ISOLATED_MOTIF + scenic-skip refinements
  846. d301665 2026-05-24 make_seamless.py: disable to no-op pass-through
  847. afee5cd 2026-05-24 seamless-tile physics gate: detector lib + sweeper + pre-publish wire-up
  848. 3fc81bf 2026-05-24 triage: colorway-sibling fallback in resolveImagePath
  849. e110dad 2026-05-24 ghost-scan flagged.jsonl: gate on unanimous 3/3, not confidence>=0.5
  850. ea1d852 2026-05-24 feat(design page): mural pan UI + on-screen arrow controls
  851. 8584a8a 2026-05-24 fix(api/room): pass full mural width to upstream renderer for kind=mural
  852. 153962b 2026-05-24 fix(make_seamless): hard-cut mask threshold to eliminate ghost-layer artifacts
  853. a7d1745 2026-05-24 add dedupe-flagged-jsonl.js + watch-and-dedupe.sh
  854. 06ad933 2026-05-24 fix(regenerate-reverse): fall back to stored prompt when source PNG missing
  855. b6c85f3 2026-05-24 feat(ghost-review): bulk-select with marquee drag + Delete & Learn
  856. 2d3c47c 2026-05-24 ghost-detector: bump 429 retry budget 4→6 attempts
  857. a9fbc70 2026-05-24 ghost-review: SHIFT+drag = KEEP element (green dotted) · fix by-id 404 · fix kind-enum insert failure
  858. 080cc68 2026-05-23 admin: live before/after Fixes Feed for every repair event
  859. a3c2b00 2026-05-23 add ghost-rescore-flagged.js — quantify detector-change rescue rate
  860. 7031abf 2026-05-23 ghost-review: magic wand — click motif to isolate, then recolor/erase/copy/paste/apply
  861. 9666be2 2026-05-23 scripts: oneshot trellis-upgrade regen for drunk-zoo-36 #26634 → new SKU #39288
  862. 7eb0a50 2026-05-23 fix(db): psqlExecLocal multi-line SQL — JSON.stringify of newlines was producing literal \n that psql parsed as a meta-command ("invalid command \nINSERT"). Switch to stdin-feed like psqlQuery. Regression from REFACTOR-1a (3b6954e). Unblocks /admin/ghost-review Regenerate-Whole button.
  863. 725d763 2026-05-23 ghost-review: Fix / Remove+Fill / Reverse-Regenerate action buttons + expanded sort
  864. 47f7a9c 2026-05-23 fix(ghost-detector): kill ~36% false-positive flag rate on full-corpus scan
  865. 7adcd3c 2026-05-23 ghost-review: auto-suggest dotted regions + tolerance slider + auto-labeler
  866. 150060a 2026-05-23 ghost-review: more robust labeling — multi-rect, defect types, seam test
  867. 788de56 2026-05-23 ghost-detector: 429 retry-with-backoff + triage-ghost-flagged.js
  868. 6bd6333 2026-05-23 admin: ghost-review viewer + label-collection routes
  869. 03cdc46 2026-05-23 ghost-detector: 3x voting + maximal-determinism config
  870. 550c260 2026-05-23 REFACTOR-2: extract lib/gemini.js wrapper for 6 Gemini call sites
  871. b940514 2026-05-23 REFACTOR-1b/c/d: extract lib/color.js, lib/http.js, lib/parse.js
  872. 3b6954e 2026-05-23 REFACTOR-1a: extract lib/db.js (psqlQuery, pgEsc, psqlExecLocal)
  873. 28303dd 2026-05-23 PERF-3: cache /api/marketplace/status (30s in-process TTL)
  874. 8f28f8f 2026-05-23 PERF-2: parallelize designer detail follow-up queries (4-await → 1)
  875. eae5296 2026-05-23 PERF-1: 6 missing marketplace indexes (CREATE INDEX CONCURRENTLY)
  876. 65f1266 2026-05-23 BUG-2: qwen3 timeout 60s → 3s + 5-failure circuit breaker
  877. e14743c 2026-05-23 BUG-1: rename duplicate /api/design/:id/rate → /score (Express 5 first-wins)
  878. dc21aab 2026-05-23 SEC-5: drop local_path from public response paths
  879. 74da46f 2026-05-23 SEC-4: require auth on Gemini-burning endpoints + rate-limit /furnish
  880. 72ddc0e 2026-05-23 SEC-3: strip payout_details / commission_rate from public designer routes
  881. ad389f7 2026-05-23 SEC-2: harden /_devlogin and prod secret fallbacks (fail-closed)
  882. b6ef2b2 2026-05-23 SEC-1: fix shell injection in POST /api/leads
  883. 53c740e 2026-05-23 cleanup: delete .bak files, orphan entrypoints, unused @dw/inline-editor dep
  884. 3b8b3c1 2026-05-23 ghost-detector v2 + Matisse v4 generation prompt
  885. 75da858 2026-05-22 fix /api/designs PII leak: drop local_path from designs.json snapshot, refactor by-id route to use localPathForDesign() helper. Admin ops re-fetch local_path live from PG via psqlQuery — unaffected. Supersedes f9b2acc which fixed the 404 but introduced the leak.
  886. 0592448 2026-05-22 feat(catalog): categoryDisplay translator + vendor-inspired generator + brand library
  887. f9b2acc 2026-05-22 refresh_designs_snapshot.py: emit local_path so /designs/img/by-id/:id route resolves without hitting the broken prod psql fallback (psql as 'root' role fails on Kamatera; route now uses in-memory DESIGNS.local_path → basename → IMG_DIR resolve)
  888. 323e1fa 2026-05-22 add scripts/sweep_orphan_generated.js — orphan-PNG sweeper for data/generated/. Default dry-run; --apply with guardrails (PG-floor 1000, 30min in-flight grace, --max-bytes cap). First run reclaimed 33,799 files / 26.92 GB (orphan .original pre-seamless artifacts).
  889. d2d3d8e 2026-05-22 feat(admin): Crop & Fix tool — drag rect on any design, Gemini regenerates that region
  890. 2bd3823 2026-05-22 feat(scenic): hospitality style-pack sub-filter — Aman / Auberge / Four Seasons
  891. 49e0ab6 2026-05-22 ghost-layer: detector + scanner + pre-publish gate + fix-queuer
  892. f587ed9 2026-05-22 vendor-scrub: remove all references to de Gournay / Gracie / Zuber
  893. 9e6a142 2026-05-21 wallco / Scenic + Studio sub-brand landings, Studio trade-gate, Scenic hospitality fit
  894. 28ef4d5 2026-05-21 generator: wire product_line column on INSERT + backfill designs.json
  895. b0577b9 2026-05-21 feat(scenic+studio): sub-brand rename — product_line column + UI chips + /scenic + /studio routes
  896. b6510d8 2026-05-21 feat(studio): 12 new Gracie-language scenic compositions (Studio line batch 2)
  897. 38532bd 2026-05-21 regen 10 BLEED_GHOST_REGEN lips via SDXL→Gemini 2-pass — new IDs 39155-39164, originals (11035/11168/11233/11374/11520/11588/11723/11929/12142/12340) unpublished + notes linked to successors. Recipe: feedback_wallco_gemini_edit_recovers_sdxl_aesthetic.md. First pass failed on kind='pattern_repeat' (CHECK constraint allows seamless_tile|mural|mural_panel|best_seller_seed); finalize script reuses orphan PNGs to avoid double-spend on Gemini.
  898. 5782b51 2026-05-21 feat(scenic+ux): 6 Gracie-language colorways + 3 reviewer-redo murals + tiles-readout + sub-brand proposal
  899. 3ddc65b 2026-05-21 feat(cactus+murals): 48 cactus-11ft + 32 tree-murals + 6 cactus-pine scenics + product-page mode-aware UI
  900. b4d4d16 2026-05-21 feat(cactus): 10 11ft × 7.5ft single-cactus murals + hide Pattern-scale in MURAL mode
  901. 4e4fe74 2026-05-21 chat: design-AI pill back to bottom-right corner + Big Red stacks above
  902. cd80337 2026-05-21 chat: kill-switch on mobile (≤768px) — bail before DOM injection
  903. f7a54b8 2026-05-20 ui(designs): move chat pop-out to upper-right; strip ALL sliders + admin clutter
  904. bb09c26 2026-05-20 deploy-kamatera.sh: probe https://wallco.ai/health (CF) instead of firewall-blocked origin :9905, and fix HTTP 000000 concat bug (drop || echo from -w pipeline)
  905. 5f15c01 2026-05-20 hide Ghosting button when MURAL mode (level 0) is selected — ghosting is a tile-repeat artifact that can't exist on a single 20×11 ft mural canvas, so the button was offering a fix for a non-problem
  906. cfe794d 2026-05-20 fix: regen-with-comment + ghosting endpoints fall back to DESIGNS in-memory cache when design isn't in spoon_all_designs PG table — file-backed designs (fliepaper-bugs, JSON-only) were failing with 'parent design not found'
  907. 07d3dc2 2026-05-20 add: 'Ghosting' button on /design/:id admin rating panel — prompts to either Update SKU (regenerate image in-place with anti-ghosting prompt addendum, DIG number + URL preserved) or Delete (hard-delete + log fingerprint to ghosting-do-not-want.jsonl + queue fresh regen). New /api/design/:id/ghosting endpoint, admin-gated
  908. 0c4e701 2026-05-20 wallco mural: update LEVELS[0].label to '20 ft × 11 ft' too
  909. a9ef495 2026-05-20 add: color slider + style slider (Traditional→Modern) + admin per-card bulk-select checkbox + drag-rubber-band selection + bulk-action toolbar (tag/publish/unpublish/delete) + /api/designs/bulk-action endpoint
  910. 615bf37 2026-05-20 wallco mural: viewport 20:11 + cover-fit init at zoom 1
  911. 9cf8d04 2026-05-20 ui: surface ALL styles + populated color dots on /designs grid — drop motif slice(0,12), expand hue palette from 10 to 32 named buckets with finer hue ranges + lightness subtypes (blush/coral/butter/lime/sky/lavender/burgundy/terracotta/chocolate/cream/linen/ivory/stone/charcoal/ink/black/white)
  912. b4ba6e1 2026-05-20 rename: Magic → Curated across all customer-facing copy on wallco.ai (plus strip residual fav-count chip update)
  913. 2fed040 2026-05-20 ui: strip faded ·N count suffix from category/motif/room/favorites chips — opacity:.55 ghost text was visually noisy
  914. 826619a 2026-05-20 rename: replace every customer-facing 'AI' with 'Magic' across wallco.ai — 25+ string replacements in server.js covering all design pages, homepage tagline, about page copy, badges, designer panels, swipe-vote copy. Code/variable names (ai_style, ai_colors, aiGrid, ai-badge CSS) preserved
  915. c9ec53b 2026-05-20 fix: hide AI-Original badge from /design/:id public view — keep Pattern No / Category / Kind, drop the AI-disclosure tag for non-admins (same rationale as provenance-note hide)
  916. 6f11ac9 2026-05-20 fix: hide AI-provenance legal-disclaimer block on /design/:id from non-admins — was leaking compliance language onto public design pages where the design itself sells; admins still see for QA
  917. 33bc0da 2026-05-20 Pollock-splatter (12) + Sherman-circus (20) collections published
  918. dac62a7 2026-05-20 wallco /designs: defense-in-depth vendor-name denylist on dropdown + card filter
  919. 48f26cf 2026-05-20 night-builder: scrub ALL DW vendor names from prompt templates + rename fromental-scenic track
  920. f9750ac 2026-05-20 Login modal (3-role scroll-trigger) + comprehensive PNG sync
  921. 1e6e13a 2026-05-20 night-builder: take FIRST line of psql RETURNING output, not last whitespace token
  922. 2ea2f75 2026-05-20 night-builder: debug-log url-patch step + ship self-healing watchdog
  923. cb7f3a5 2026-05-20 night-builder: split CTE → 2 separate psql calls (PG data-modifying CTE snapshot bug)
  924. 2279beb 2026-05-20 Bulk 2-color fix + full-room murals + hue-sync 4-color quartets + Designer-zoo-calm track + admin review panel
  925. f67ea3a 2026-05-20 night-builder: fix PLACEHOLDER image_url bug in colorway INSERT (CTE)
  926. 1e6fc9a 2026-05-20 wallco: generate-lips.js — 10 designer lipstick-brand colorways
  927. a607c8b 2026-05-20 wallco: admin spacing slider on /designs + bleed_guard.js ghost-layer agent
  928. bb766af 2026-05-20 wallco: gate /library + chips behind isAdmin — admin-only per Steve directive
  929. 9691c7c 2026-05-20 data: 50-design inspiration ramp — audit + designs.json refresh
  930. f5f2f30 2026-05-20 /designs — source filter chips (AI · Designer Library · All Combined)
  931. 688fa90 2026-05-20 /design/:id — inject "Pairs well with real designer wallpapers" row
  932. 8cdbb6b 2026-05-20 harden vendor redaction in library cache + scrub helper
  933. 2b2eb5c 2026-05-20 data: initial inspiration-audit.jsonl from n=5 smoke test
  934. f4153d0 2026-05-20 admin: side-by-side inspirations gallery (real seed × wallco AI original)
  935. 3cd8e28 2026-05-20 add /library route + APIs — surface 57k professional vendor wallpapers under the Designer Wallcoverings house brand
  936. c79c5bc 2026-05-20 server: mount /admin/inspirations + /api/admin/inspirations/list + badge API
  937. fd7b53d 2026-05-19 wallco /designs — remove studio-adjust modal (6 Photoshop-style global filter sliders)
  938. 27a2a98 2026-05-19 inspiration_generator: pull real archival seeds, generate NEW originals
  939. f90b1a4 2026-05-19 wallco: cactus collection generator + publisher (10 Omni Tucson colorways)
  940. be80861 2026-05-19 sql migration: add all_designs.inspired_by_sku + inspired_by_vendor
  941. 6e30ae3 2026-05-19 add /library surface data — materialize 57,629 real designer wallpapers into a single JSON cache
  942. 9abdaaa 2026-05-19 reconcile generator suffix → empirical professional palette (23,817 real vendor products)
  943. c1c8a89 2026-05-19 server: passesAestheticGate runtime filter in loadDesigns (neon + ≥4 hues + rainbow tags)
  944. dec2cf7 2026-05-19 generator hardening: tone-on-tone suffix + neon/rainbow negative_prompt across all prompt builders
  945. df08ff3 2026-05-19 add professional-palette reference + suffix learned from dw_unified
  946. eee8638 2026-05-19 aesthetic purge: log 1007 designs to do-not-want.jsonl (neon + ≥4 hue buckets)
  947. 1db9580 2026-05-19 aesthetic purge: add scripts/purge-neon-and-multicolor.js (neon + ≥4 hue buckets)
  948. 079feef 2026-05-19 report: dw-stale-urls rescrape pass (4 vendors, 806 products refreshed)
  949. e085a06 2026-05-19 report: dw-stale-urls push-A2 (470 products healed on storefront)
  950. 9fb3d02 2026-05-19 decision: dw-stale-urls trim-B → leave-it (negative cache is doing its job)
  951. ed88f83 2026-05-19 report: dw-stale-urls heal-A audit (4989 products, propose swaps)
  952. fd7b0dc 2026-05-19 report: dw-stale-urls trim-B HALTED (0 orphans, outside band, awaiting Steve)
  953. a109d4f 2026-05-19 refiner-compare: 3 more render columns (Gemini 2.5 Flash Image, Flux 1.1 Pro, gpt-image-1)
  954. 187a96b 2026-05-19 /designs HTML: filter cards by designHasImage (mirror /api/designs)
  955. e9586f4 2026-05-19 chore: gitignore generated images + audit logs + classifier jsonl
  956. ca3c568 2026-05-19 data: refresh designs.json
  957. 2e90f4f 2026-05-19 feat(scripts): add cull-viewer-server.js
  958. d12476d 2026-05-19 admin/inspiration: two-step flow + Export decisions.json
  959. b6b1b00 2026-05-19 /design page: show full palette as paint chips + paint stripe
  960. 7761399 2026-05-19 admin/inspiration/generate: actionable 503 when Ollama is unreachable + OLLAMA_HOST fallback
  961. 48f6b40 2026-05-19 Fuzzy-design cull pipeline: Gemini classifier + viewer + apply
  962. bed0442 2026-05-19 wallco /designs: hide failed-generation blank designs from all listings
  963. 6fa0c16 2026-05-19 refiner-compare: dual-method new-item composer — drag-a-house + multi-select dropdowns (max 3 each) with toggle, per-idea Coordinate + Create-similar, prompt shown per row
  964. 4a89b0e 2026-05-19 Inspiration pool: Replicate backend + settlement gate + placeholder thumbs
  965. d36364c 2026-05-19 refiner-compare: all 3 columns complete — 50 ComfyUI + 25 Replicate renders
  966. 4b9b81e 2026-05-19 replicate_compare: scrub API token from curl error messages so a failed call never leaks it
  967. 85d2777 2026-05-19 replicate_compare: read REPLICATE_API_TOKEN only from project env — no cross-project secret scanning
  968. 8c46cbd 2026-05-19 refiner-compare: add 3rd column — Replicate app render (stability-ai/sdxl). New replicate_compare.js renders 25 via the live app path; progress.json gains a replicate field; compare.html now 3-up; drop static-page overwrite (live page is permanent)
  969. 9829d20 2026-05-19 deploy-kamatera: image sync is incremental + non-destructive
  970. 9b5ec50 2026-05-19 refiner_compare: two-machine split — CMP_SHARD/CMP_SHARDS env shards indices across ComfyUI instances; progress.json now disk-derived so both shards write it safely; per-shard watchdog + .done sentinel
  971. f042d90 2026-05-19 refiner_compare: reorder into base pass then refiner pass — no checkpoint swap mid-pass; progress now counts 50 renders
  972. 838379d 2026-05-19 add refiner_compare watchdog — auto-restart on crash, exit on 25/25
  973. 252f179 2026-05-19 refiner_compare: skip already-rendered images so a crash+restart resumes instead of restarting from pair 0
  974. 498edd4 2026-05-19 fix: designs had empty image_url -> blank cards on /designs. Backfill all 8618 + persistDesign now sets image_url=/designs/img/by-id/<id>
  975. 152bba8 2026-05-19 wallco: CTA heading -> 'Every Design is an Original.'
  976. 4369c90 2026-05-19 wallco: CTA heading 'Every design is AI-original.' -> 'Every Design is a One of a Kind.'
  977. 06ffe08 2026-05-19 snapshot — gitify backup 2026-05-19
  978. 7d406b1 2026-05-19 add regen_one.js — redo comparison #1 (damask/Hermes/770000) with cleaner-lines prompt + seamless
  979. f9ddcbe 2026-05-19 generator: seamless tiling now MANDATORY for all non-mural designs (no env opt-out); murals (~11ft x 120in) exempt
  980. c51e39f 2026-05-19 refiner-compare: write progress per-image (not per-pair) + live viewer shows each render the instant it lands
  981. af70673 2026-05-19 generator: ban halftones, allow 3D/dimensional designs, add tactile material cues (suede, woven trim, raffia, grasscloth)
  982. 9bda674 2026-05-19 add refiner_compare.js — 25-prompt base vs base+refiner side-by-side eval
  983. 25f96e9 2026-05-19 comfy: optional SDXL base+refiner workflow (COMFY_REFINER_MODEL) — matches Replicate's expert-ensemble pipeline
  984. a787241 2026-05-19 generator: steer SDXL to screen-print look — solid opaque flat ink, ban transparent/unfilled/see-through layers
  985. b80dd4d 2026-05-19 wallco: add /style-guide.html — brand-picker dropdown showing palette swatches, fonts + unique UX per fashion house
  986. 174a5bd 2026-05-19 wallco generator: seed colour from dw-fashion-templates style guide (19 luxury-house palettes)
  987. e0266e6 2026-05-19 Reel maker: bump to 6 designs + admin publish-to-own-channels
  988. 383c03b 2026-05-19 Add social share layer + reel maker to wallco.ai
  989. 6ae5721 2026-05-19 wallco generators: wire settlement gate into both launchd ticks
  990. 3127fc6 2026-05-14 feat(mobile-chrome): meta theme-color cream/dark per prefers-color-scheme + apple-mobile-web-app status bar; mobile address bar now merges with page content instead of staying default-gray
  991. 6ae4fd4 2026-05-14 fix(/provenance): 301 redirect to /about (content merged); also remove stale sitemap entry — was 404ing for external inbound links and counted against crawl budget
  992. f0fe84b 2026-05-14 feat(/designs): dynamic OG image when filtered — sharing /designs?hue=rose on Twitter/LinkedIn/Slack now previews an actual rose design instead of generic og-default.png; unfiltered grid still uses default
  993. effa221 2026-05-14 perf(/design/:id): add fetchpriority=high + decoding=async to .detail-img + preload it in <head> via htmlHead({preloadImages}); detail-img is THE LCP candidate on the detail page
  994. 7ffca96 2026-05-14 perf(home): preload hero[0] + first 4 featured card images in <head>; hero[0] is the LCP candidate gets fetchpriority=high; mirrors the same pattern shipped for /designs in tick-20
  995. a29ccea 2026-05-14 feat(/samples): add autocomplete + inputmode + enterkeyhint attrs to sample-request form — browsers now offer saved-profile autofill for name/email/phone/company; mobile keyboards show search/Next/send keys; cuts checkout friction
  996. 8abdd79 2026-05-14 perf(head): preconnect googletagmanager + dns-prefetch google-analytics — shaves ~100-300ms off GA4 initial TLS+DNS handshake; pairs with existing fonts preconnects
  997. eb8097b 2026-05-14 perf(/designs): preload first 6 card images in <head> with fetchpriority=high on first; browsers start fetching LCP candidate ~100-300ms before body scan discovers background-image URLs
  998. 89a97b5 2026-05-14 perf(/designs): content-visibility:auto on .design-card — browsers skip rendering off-screen cards entirely; 60-card-per-page grid LCP drops significantly; contain-intrinsic-size:220px keeps scroll position stable while space is reserved
  999. a624fa8 2026-05-14 feat(/designs mobile): chip-rows scroll horizontally on phones instead of wrapping to 5+ lines; fade-mask on right edge hints scrollability; cuts iPhone-SE toolbar height ~420→180px so grid surfaces above fold
  1000. dba51ee 2026-05-14 feat(/design/:id): add BreadcrumbList JSON-LD alongside existing Product schema; lets Google show 'Home › Designs › <category> › <title>' breadcrumbs in SERP
  1001. 6601949 2026-05-14 feat(/designs): prefetch /design/:id on card hover with 80ms debounce; honors save-data + 2g + prefers-reduced-data so we don't burn metered cellular; click feels instant
  1002. 508fcbe 2026-05-14 feat(/designs): proper empty-state when filter combo returns 0 — magnifier glyph + 'No designs match' + Clear-filters + Surprise-me CTAs; was a bare 'No designs found.' <p>
  1003. 9a35a77 2026-05-14 feat(/design/:id): breadcrumb back-link inherits the filtered-grid URL the user came from via document.referrer — same-origin /designs only; preserves hue/motif/cat/q/sort context
  1004. 8a9c08f 2026-05-14 feat(a11y): visible focus ring on design cards via :focus-visible — keyboard Tab navigation gets a 3px accent outline; mouse-click hides via :has(:focus-visible) negation; falls back to :focus-within on older browsers
  1005. f757e73 2026-05-14 feat(/designs): hue swatches 14px → 20px for tap-friendly mobile + subtle shadow + hex tooltip on hover; min-height:32px gets the chip to WCAG 2.5.5 touch target threshold
  1006. 5733155 2026-05-14 feat(/designs): floating scroll-to-top button (↑) appears after 2 viewports of scroll; respects prefers-reduced-motion; refocuses search on return so / shortcut feels natural
  1007. 7a4ab66 2026-05-14 feat(/designs): clear-X button when search query non-empty; preserves other active filters in the reset link; mutually exclusive with /-kbd hint to avoid stacking icons
  1008. eee4f56 2026-05-14 feat(/designs): browser tab title reflects active filter — 'Rose designs · 296 designs — wallco.ai' instead of always 'All Designs'; helps tab navigation + SERP truth
  1009. 53149e4 2026-05-14 feat(/designs): kbd '/' hint inside search input — discoverability for the shortcut shipped in 7bbdf26; hidden on touch (hover:none); fades out on focus
  1010. 628c81f 2026-05-14 db: add 003_schema_parity migration to bring prod in line with Mac2
  1011. a188292 2026-05-14 feat(/designs surprise-me): defensive null-id handling + 'Try this prompt again' + 'Open full page' link
  1012. 7bbdf26 2026-05-14 feat(/designs): keyboard shortcut '/' focuses search (GH/X/Slack pattern); Esc blurs; ignored when user is typing in another input
  1013. 3291dd7 2026-05-14 fix(/designs): move card-hover OUT of card-link so the Sample <a> is no longer a nested anchor (60 nested anchors per page → 0); same HTML5-parser-split bug class as button-in-anchor, surfaces when user hovers a card with overlay visible
  1014. 4622641 2026-05-14 chat: surface psql stderr + redact replicate token + throw on null INSERT id
  1015. e850309 2026-05-14 fix(/designs): studio-adjust summary precedence bug — state.hue||0!==0 parsed as state.hue || (0!==0) so 'changed' indicator was unreliable; now Object.keys(defaults).some() per-axis compare. Also 'on' → 'edited' for clarity
  1016. f69b164 2026-05-14 feat(/designs): add 'Clear filters' chip when any hue/motif/cat/room/q is active; single-click reset replaces clicking 'All' on three different rows
  1017. 2fae7d5 2026-05-14 feat(/designs): tighten NEW window 72h→6h; was firing on every single design (6010/6010) after generator burst; env-overridable via NEW_BADGE_HOURS for future tuning
  1018. 2cc97c7 2026-05-14 feat(/designs): density slider shows current col count + aria-valuenow; updates on resize-clamp so mobile shows '2' not '8'
  1019. c6bcfc5 2026-05-14 fix(/designs mobile): clamp density slider for narrow viewports (inline --cols was overriding @media breakpoints); always-show heart + NEW on touch devices via @media (hover: none)
  1020. 1ba619e 2026-05-14 chore(deploy): gitignore .deploy.conf (per-machine config)
  1021. b78b5d5 2026-05-14 drunk-animals: add FASHION_PALETTES (12 luxury-house combinations from common colors of 20 brands)
  1022. d10ea8d 2026-05-14 fix(/designs): wrap card in <div> so HTML5 parser stops splitting <a class=design-card> into 3 grid items; force 6-col default; hide NEW + heart until hover (no text at rest)
  1023. b22d13a 2026-05-13 marketplace: accept qualified AI agents (no bots) — add /marketplace/api docs page
  1024. 26dbc62 2026-05-13 security: remove public /spoonflower nav tab + admin-gate the page and all /api/spoonflower/* endpoints
  1025. d14bd81 2026-05-13 feat: 18 geometric-block-leaves designs + 2 fill-in runners + publish script
  1026. 3b4a284 2026-05-13 marketplace SEO: sitemap-index + BreadcrumbList JSON-LD + og-default fallback
  1027. 3b1a002 2026-05-13 brand: gucci viewer adopts universal corner-nav (bag/person/search/menu), supersedes inline MENU per 2026-05-13 standing rule
  1028. 8e30514 2026-05-13 marketplace: end-to-end integration test for admin payout export
  1029. 2961365 2026-05-13 Strip reserved-brand strings: BH/Beverly Hills source filenames moved to .env (BUTTERFLY_DREAM_SRC, CLEAN_TRELLIS_SRC); 4 BH-named generator scripts removed from working tree (history preserved); 41 bh-coordinates DB rows + 85 PNGs + sources backed up to ~/.wallco-deleted/2026-05-13/bh-all/
  1030. 746cf5e 2026-05-13 settlement: add 'palm leaves' to negative-prompt language + purge 1 Thibaut palm-frond row
  1031. 7d5c357 2026-05-13 wallco: fliepaper-bugs tick generator script
  1032. b5d6362 2026-05-13 fliepaper-bugs: API + server.js mount — settlement-gated regen, yolo job queue, GET /api/collections endpoint
  1033. 8e4960d 2026-05-13 fliepaper-bugs: collection page + admin grid HTML (placeholder-aware, 36 cells)
  1034. 4bc1561 2026-05-13 fliepaper-bugs: DB seed — mp_collections row + fliepaper_bugs_cells (36 cells)
  1035. e916bd4 2026-05-13 wallco: gucci brand-reference viewer + fliepaper-bugs spec.json (6 patterns × 6 colorways = 36 SKUs)
  1036. 53a5430 2026-05-13 marketplace ai tests: 5×8s retry budget to ride out parallel-agent pm2 reloads
  1037. d9bcbb0 2026-05-13 nav: pin marketplace + wallco.ai menu bars to top of viewport, never scroll
  1038. 912870e 2026-05-13 marketplace db: warn + fall through on non-URL DATABASE_URL; fix pm2 PORT to match nginx (9905); allow self-redeploy
  1039. 69fa84a 2026-05-13 nav: surface Marketplace · Designers · Patterns in wallco.ai hamburger
  1040. 9ff4a1a 2026-05-13 marketplace YOLO loop · overnight milestone 3 — all 8 parallel tabs landed
  1041. d6036b8 2026-05-13 marketplace: tests for /api/marketplace/textures (9/9 pass live)
  1042. ebf7abd 2026-05-13 marketplace: real-product texture picker + stripe/plaid generator
  1043. 9ea61af 2026-05-13 redact vendor name on /design/:id pairs-well cards + studio insights → 'Designer Wallcoverings' (universal customer-facing vendor-redaction rule)
  1044. ecc625c 2026-05-13 marketplace ai: tests for qwen3:14b tag-pattern + write-pattern-description (4/4 pass live)
  1045. 524cc84 2026-05-13 marketplace pattern page: wire 'Generate AI colorways' button to render results inline + show progress
  1046. 92d9917 2026-05-13 spoonflower upload returns SF pattern#, adds Upload-to-Shopify, DIG # auto-assigned + hover overlay
  1047. 67e4cc8 2026-05-13 marketplace: designer follow + /trade/projects board listing (files)
  1048. 8350976 2026-05-13 marketplace search: case-insensitive tag filters + non-trivial test assertions
  1049. b74ae4b 2026-05-13 marketplace: designer follow + /trade/projects board listing
  1050. e092403 2026-05-13 marketplace SEO: add smoke tests for sitemap + designer/pattern JSON-LD
  1051. 2ac2375 2026-05-13 footer: add visible phone, DW corp address, and © 2026 line
  1052. a1c0a71 2026-05-13 marketplace ai/generate-colorways: dedicated smoke test
  1053. faa24dd 2026-05-13 marketplace YOLO loop · overnight milestone 2 — parallel-tab landings
  1054. bd49413 2026-05-13 marketplace: admin payout CSV export
  1055. 2b84709 2026-05-13 purge: hard-delete all 44 bh-abstract-leaves designs
  1056. 6f6143e 2026-05-13 bh-abstract-leaves: regen all 44 as contemporary abstract via text-only Gemini (no source image → no banana-leaf bleed). Cycles 8 shape families, preserves BH color palettes, backs up old PNGs to ~/.wallco-deleted/<date>/bh-leaves-superseded/
  1057. 27158ce 2026-05-13 marketplace: designer-powered Wallco marketplace (Patternbank × Material Bank × Spoonflower)
  1058. 029a6cf 2026-05-13 design coordinate: collapse paint chips into <details> table + full sort dropdown (client-side)
  1059. e52478f 2026-05-13 design page: admin tone-on-tone color-wheel buttons + /api/design/:id/recolor
  1060. f4031b4 2026-05-13 furnish: disk-backed cache (data/furnish-cache/<id>-<ctx>.json)
  1061. 0f93256 2026-05-13 design page: add Share — Pinterest (Pin It) + Instagram (download + open) + Copy link
  1062. 829515f 2026-05-13 wallco: add full sort options (oldest/title-desc/vivid/muted/has-room/random) + mural 1×1 pan-and-crop
  1063. 0a9b0d4 2026-05-13 cards: pattern-only resting state, full meta on hover (admin + user + designer)
  1064. ab7d5d5 2026-05-13 design page: AI card Duplicate/Edit buttons always visible (was hidden until hover — broken UX on touch + low discoverability). Edit gets gold pill, Duplicate gets black pill, both at top-right with z-index:3 and icon prefix
  1065. fb5abf5 2026-05-13 docs: 6afffe7 also shipped — design page color-story (dots+SW+DE) under hero, top sliders (repeat-width + room scale), Duplicate/Edit per AI card, Wix-style pattern editor w/ 1-5 drag-drop color slots (admin)
  1066. 6afffe7 2026-05-13 furnish: per-item Google Images / 1stdibs / Pinterest / Etsy search chips
  1067. ade6dc4 2026-05-13 migrate: ensure user_removed column on spoon_all_designs (was missing on prod)
  1068. bf6d6f9 2026-05-13 admin-gate: add ADMIN_TOKEN query/header path so admin UI renders on wallco.ai
  1069. d7f84f7 2026-05-13 psqlExecLocal: use sudo-postgres path on Linux (was: bare psql, failed as root on prod)
  1070. 57798c8 2026-05-13 wallco /design/:id: fix Design Coordinate panel (CORS) + bucket by style
  1071. c7a227b 2026-05-13 wallco: AI Interior Designer button + Settlement Violation button on /design/:id
  1072. ef4e20c 2026-05-13 settlement: hard-delete 14-design Cane Trellis chain (banana-leaf bleed-through)
  1073. 05ab37b 2026-05-13 package: pin multer dep (wallco prod kept losing it on npm ci because not in lock)
  1074. e5bfcad 2026-05-13 wallco-ai: gate Rate panel on admin, restore See-in-Room generator button
  1075. 39b4997 2026-05-13 api/designs: filter out rows whose image file is missing on disk
  1076. 5fee57a 2026-05-13 wallco.ai: wall-fit crop tool on /design/:id (W×H input, tiled canvas preview, roll-count readout, PNG download); seamless-check.py edge-diff validator wired into regen as is_published gate; unpublished 3540 (top/bottom diff 67.66) and 3544 (settlement violation)
  1077. 77d9a4b 2026-05-13 settlement: db-level trigger blocks is_published=true UPDATE/INSERT when prompt satisfies Part A + Part B; supports session-local override with audit note
  1078. 45ff467 2026-05-13 wallco-ai: gate butterfly-trellis + drunk-animals batches through settlement skill; drunk-animals skips BLOCK/NEEDS_REVIEW prompts mid-batch instead of dying
  1079. bbf4173 2026-05-13 settlement: pre-generation legal gate + wallco-ai/scripts/settlement-gate.js helper; wired into bamboo→cane regen script
  1080. 1e5fc81 2026-05-13 snapshot: backup runtime state (3 files)
  1081. 5c53e57 2026-05-13 snapshot: backup uncommitted work (6 files)
  1082. bb126fc 2026-05-13 dig-1984: 100-colorway batch (50 tone-on-tone + 50 contrasting) via Gemini 2.5 image-edit, source pinned to Shopify CDN copy
  1083. 7620d5d 2026-05-13 cherry-blossom-animals: batch runner (default N=10) — fans prompts through generate_designs + snapshot refresh + admin reload
  1084. 9e4293d 2026-05-13 cherry-blossom-animals: prompt library mirroring wisteria — hanami-style canopy, animals face UP, public-domain ukiyo-e motif
  1085. e145932 2026-05-13 wisteria-animals: also block ferns + drooping plants; any incidental greenery must point upward
  1086. 09ad34c 2026-05-13 wisteria-animals: drop bamboo from brief; wisteria racemes are now the only botanical element (Hinson/Schumacher leaf-trap dodge)
  1087. f582e12 2026-05-13 wallco.ai: /designs cards show DW SKU + color name + AI-Designed badge + style; density slider 1-12 default 6; wisteria-animals prompt library
  1088. da2aabc 2026-05-13 wallco.ai homepage: pin newest 6 butterflies above Featured, sort Featured grid by created_at desc
  1089. 769ab6c 2026-05-13 Design Coordinate on /design/:id — palette-mode call to pairs.designerwallcoverings.com
  1090. 7e452f1 2026-05-13 drunk-animals: drop overnight gate, fire 24/7 like stoned
  1091. 96a4bc0 2026-05-13 designs: NEW badge on cards created in last 72h
  1092. 9cf27ca 2026-05-13 hot-or-not: filter broken images, always 6 thumbs, NOT modal with reason chips + notes
  1093. bfb6108 2026-05-13 snapshot: include gemini-2.5-flash-image-edit generator (10 new butterfly-trellis designs visible)
  1094. 9a13b0a 2026-05-13 designs: butterfly+trellis batch generator + 10 new designs
  1095. 5bb011a 2026-05-13 /api/generator/refresh-orders: stop hanging on the broken-pipe pattern
  1096. 10447d1 2026-05-13 /generator: fix broken 'Run tick NOW' + DW palette slider grid
  1097. d7d74bc 2026-05-13 designs: sort buttons (was dropdown) + /merge upload-and-fuse feature
  1098. 753227d 2026-05-13 designs: studio adjust panel (6 photoshop sliders) + per-card favorites
  1099. f2b894b 2026-05-13 mural-scenic: $950 infinite license + 150dpi download (Stripe Checkout + Real-ESRGAN)
  1100. d5cb765 2026-05-13 user-feedback: rate panel + soft-remove + 150 dpi spec
  1101. 58f892e 2026-05-13 mural-scenic: panoramic 20ft x 11ft scenic murals (NOT seamless tiles)
  1102. 9b791a3 2026-05-13 mural-animals: Iksel/de Gournay/Mural Sources refined collection (100 designs)
  1103. 14ea612 2026-05-13 /designs: fix 'newest' sort — was returning oldest first
  1104. 9232294 2026-05-13 /designs admin review-card: hide overlay on load, fade in on hover
  1105. 3df4f1a 2026-05-13 /designs: wider defaults — 3-up grid, slider min 1, tight side gutters
  1106. 9ccfd72 2026-05-13 snapshot: 4 file(s) changed, +1 new, ~3 modified
  1107. ed965df 2026-05-13 daemons: max-it mode — default cadence 240s → 90s
  1108. 65dcd74 2026-05-13 /designs: infinite scroll, replace pagination links
  1109. e54cb62 2026-05-13 pairings: Dunn-Edwards + Sherwin-Williams paint chip suggestions
  1110. d8b7aa1 2026-05-13 stoned-animals v2 — every animal must have joint AT lips
  1111. 9ee1fef 2026-05-13 drunk-animals v2 — flowers only (no leaves), drinks in hand, no tropical
  1112. 5f6728c 2026-05-13 stoned-animals: new collection — Grateful Dead × Warhol, red eyes, woodland
  1113. 6fb2136 2026-05-13 drunk-animals: daemon 5-min hard timeout on hung ticks
  1114. 5312be8 2026-05-13 drunk-animals: daemon preflight self-heals id_seq desync
  1115. f12547c 2026-05-13 /admin/health: surface random-ETag hit/miss/rate alongside by-color cache stats
  1116. 0ec07a8 2026-05-13 drunk-animals: end-to-end smoke test, 19/19 passing
  1117. e884616 2026-05-13 /admin/reload-designs: also bump by-color cache version + clear entries (auto-invalidate stale palette results on catalog reload)
  1118. c3467a1 2026-05-13 by-color: emit ETag on every response + 304 short-circuit on If-None-Match (pairs with TTL cache to skip JSON wire transfer)
  1119. ae55f6d 2026-05-13 /brief: add If-None-Match ETag short-circuit (ids+project+client sig) on top of existing Last-Modified
  1120. 0aaed9d 2026-05-13 drunk-animals: ready-to-fire prod-sync script (manual auth required)
  1121. 2edefae 2026-05-13 drunk-animals: salvage 6 orphan PNGs + fix spoon_all_designs_id_seq desync
  1122. 50ea14f 2026-05-13 drunk-animals: generator status pill + auto-recap mode on /live
  1123. 768a775 2026-05-13 drunk-animals: 'Best of the night' rail on /live
  1124. 4c0ff53 2026-05-13 drunk-animals: /api/drunk-animals/stats + 'tonight in numbers' bar on /live
  1125. 4dd3794 2026-05-12 drunk-animals: bump dedup window 5 to 8
  1126. 25d68d1 2026-05-12 drunk-animals: /drunk-animals/live realtime viewer + JSON feed
  1127. 83c5b98 2026-05-12 drunk-animals: cross-tick prompt dedup against last 5 PG rows
  1128. 5308324 2026-05-12 drunk-animals: replace launchd plist with pm2 daemon for precise cadence
  1129. 73f6770 2026-05-12 /compare: ETag + 304 keyed on (catalog lastmod, view, ordered ids) — skip re-render when nothing changed
  1130. 80b15e7 2026-05-12 /me/saved: surface 'Saved Xh ago' badge per card (SELECT already pulled saved_at, render dropped it)
  1131. 69c2529 2026-05-12 drunk-animals: hero block on /designs?cat=drunk-animals + ghost-tag sanitizer
  1132. 4f0ff5e 2026-05-12 /api/designs/random: ETag + 304 on seeded calls (deterministic given seed+state) — unseeded stays no-store
  1133. 01a41fa 2026-05-12 /admin/health: extended JSON w/ by-color cache stats (hits/misses/evictions/hit_rate) + uptime + rss
  1134. 1370963 2026-05-12 drunk-animals: /drunk-animals friendly URL → 302 to /designs?cat=drunk-animals
  1135. d5ea5ad 2026-05-12 drunk-animals: dedicated motif tagger w/ animal+pose+plant+style vocab
  1136. a5f9d55 2026-05-12 drunk-animals: category-aware titler (Hiccup/Tipple/Tableau/Soirée/...)
  1137. 89a8e15 2026-05-12 /designs: dismissible hint pointing trade users to the /brief proposal builder
  1138. 307a374 2026-05-12 drunk-animals: fix launchd PATH for PIL + retro-backfill 26 designs
  1139. 97ebc80 2026-05-12 by-color: 5min in-memory TTL cache (FIFO 1k cap, sorted-exclude key) — same PDP rail hex now skips full 1515-design ΔE recompute
  1140. 66cfe47 2026-05-12 drunk-animal overnight generator + /admin/reload-designs
  1141. f78cfec 2026-05-12 wallco-ai: log Gemini usage to cost-tracker at 2 call sites (critique + style-analysis)
  1142. 47eb2ff 2026-05-12 wall-calc: surface pinned W×H chip in summary so collapsed PDP still shows defaults
  1143. 101b1fd 2026-05-12 tokens: --eyebrow type token + .eyebrow utility class (4H Paper)
  1144. c68a4c1 2026-05-12 studio: hard single-column mobile stack + trade-nav clip fix
  1145. 4193c70 2026-05-12 header: heavier wordmark + iOS safe-area FAB inset
  1146. 2750b1e 2026-05-12 studio: P1 mobile + display-weight title (from graphic-designer + 4H panel)
  1147. 33807f2 2026-05-12 wall-calc pin hardening: positive guard + unit tag + 90d TTL
  1148. 57b8702 2026-05-12 gitignore: keep data/generated_pre_seamless_backup/ local-only
  1149. 3cf89a9 2026-05-12 wall-calc: 'Save defaults' link pins W×H across PDPs with clear action
  1150. 4cad4c4 2026-05-12 scripts: seamlessify_all.py — batch make_seamless across data/generated/
  1151. 61dcaab 2026-05-12 studio: post-process every generated pattern to be truly seamless
  1152. 7901449 2026-05-12 tools: add scripts/seam_check.py — quantify pattern seamlessness
  1153. dbc500b 2026-05-12 fix(/api/room): retry upstream once on fetch failed / transient errors
  1154. 48baf5a 2026-05-12 wallco.ai · audit log Phase 1 — capture all user + admin actions per Steve's spec (Sev all calls and recording per user and admin). New wallco_audit_log table in dw_unified (id BIGSERIAL, user_id FK trade_users, is_admin, actor_label, action TEXT, payload JSONB, ip INET, user_agent, created_at) + 3 indexes (user/admin/action). logEvent(req, action, payload) helper is fire-and-forget — never throws, never blocks request path. Wired to 5 event paths: trade_login_request, trade_login_success, trade_logout, design_saved/unsaved, sample_request_submitted, designs_search. /me/activity (auth-gated trade-user) shows own rows with pretty-printed action labels + payload summary + CCPA-aligned ?format=json export. /admin/activity (admin-gated, localhost bypass kicks in) shows all rows with user_id/action/from/to/limit filters + JSON export. Nav link 'My Activity' added next to 'My Saved'. Verified end-to-end: table created, anon /me/activity 302 → login, auth → 200 16.8KB rendered, 4 events captured (trade_login_request + trade_login_success + design_saved + designs_search), admin view returns rows joined to user emails.
  1155. 38b72fe 2026-05-12 tests: mask catalog content in isolate-visual VR so tests stop drifting
  1156. 1e5cbb8 2026-05-12 tests: re-baseline isolate-visual snapshots after full-suite run
  1157. eb7e582 2026-05-12 studio: persist repeat-inches across composes + browser sessions
  1158. 6eb8d92 2026-05-12 studio + tests: live tile preview, review.spec isolation, deterministic waits
  1159. 8470994 2026-05-12 fix(chat-modal): hide #wallco-chat-fab when chat/pair/iso modal is open
  1160. 04336ef 2026-05-12 wallco.ai · nav basket-count chip auto-refreshes via custom event (mirrors tick 56's wallco-saved-changed pattern) · introduces window 'wallco-basket-changed' (detail:{count, design_id, in_basket}); dispatched from PDP + Sample toggle AND /basket Remove button; nav script listens via paint(n) helper + readFromStorage() fallback when event detail.count is absent. Was hydrating only on page load — basket count went stale until next navigation. Verified home 2 refs (listener), PDP 3 refs (listener+dispatch), /basket 3 refs (listener+dispatch)
  1161. 965dff1 2026-05-12 test: studio repeat-size slider — 5 cases covering UX shipped in 0bbf445
  1162. 0bbf445 2026-05-12 studio: add repeat-size slider + fresh room re-renders on each compose
  1163. 38e639c 2026-05-12 wallco.ai · /compare view choice (specs/grid) now persists in localStorage[wallco-compare-view] · current view is saved on every load; if user later visits /compare?ids=… without an explicit view= param AND saved pref differs, page redirects via location.replace to honor the saved view; if URL has explicit view= or legacy grid=1, no override · Remove buttons preserve the active view (was dropping users back to specs after removing a design while in grid mode) · verified currentView=specs at /compare?ids=72,161, currentView=grid at /compare?ids=72,161&view=grid, 6 wiring refs total
  1164. 78f4fe2 2026-05-12 fix /api/room: read fresh local_path from DB; add parallel re-render audit script
  1165. 11c49ab 2026-05-12 wallco.ai · nav saved-count chip auto-refreshes via custom event · introduces window 'wallco-saved-changed' (detail:{saved_count,design_id,saved}); dispatched from PDP ♥ Save toggle AND /me/saved Remove button; nav script listens, updates #trade-nav-saved-count + window.__tradeMe.saved_count in one place. Removes the prior direct-poke-from-PDP wiring (was duplicated, hard to extend). Future surfaces (autocomplete ♥ flip, basket add, etc.) just dispatch the same event. Verified PDP 2 refs (dispatch+listener), /me/saved 2 refs, home 1 ref (listener only)
  1166. 84478a0 2026-05-12 wallco.ai · /compare gets ?view=grid image-comparison mode (legacy ?grid=1 alias supported) · adds a Specs ↔ Image grid pill toggle in the header (role=tablist, aria-selected) that links between /compare?ids=… and /compare?ids=…&view=grid · grid mode renders a 2-column grid of large aspect-ratio:1 thumbs with title+category+color-dot+tearsheet-link+Remove button (no spec table); designers comparing aesthetics side-by-side won't have to scroll past 10 spec rows · Brief / Print / Copy-share / Browse / Brief-options block all preserved underneath either view · verified specs 200 30.6KB, grid 200 22.9KB, ?grid=1 alias also returns compare-grid markup
  1167. 7cddfa6 2026-05-12 wallco.ai · /api/designs/by-color now accepts optional ?within=category to restrict color-neighbors to a single category (e.g. 'more in this palette WITHIN damask'). Response echoes within for client confirmation. Verified hex=%23c16d74 unfiltered → 228 candidates (top floral/mixed/mixed) · within=floral → 17 candidates (all floral) · within=damask → 174 candidates (all damask)
  1168. 869d5a0 2026-05-12 wallco.ai · PDP wall-calculator persists last-used W×H to localStorage[wallco-wall-calc] · restores values on next PDP visit so designers hopping between designs don't retype dimensions · auto-opens the <details> + auto-runs compute() on load if values were stored, so the result is visible immediately · saves on both Calculate-click and field-change (covers half-typed values surviving navigation) · verified PDP /design/72 200 115KB, 9 wiring refs (wallco-wall-calc, wallDetails, persist(), prev=JSON)
  1169. 3ae8ad8 2026-05-12 wallco.ai · home 'Stumble through the catalog' rail gets a category chip strip — server computes top-6 categories from DESIGNS sorted by count (damask, geometric, floral, mixed, arts and crafts, art deco), renders 'All' + 6 chips above the rail. Click → updates activeCat → fetch /api/designs/random?category=… → re-renders rail. Persists last-pick in localStorage[wallco-home-rail-cat] so the chosen category survives reloads. Same chip pattern as /designs hue/motif chips (is-on state, var(--accent) bg). Verified: / 200 29.8KB, 7 chips emitted, 11 wiring refs (home-rail-cats, home-cat-chip, paintChips, localStorage key)
  1170. 0fccfb6 2026-05-12 wallco.ai · /api/me/saved bulk endpoint + ♥ saved badges in /designs autocomplete · GET /api/me/saved returns {authenticated, count, ids[]} for the trade-user (anon → {false, []}); Cache-Control:no-store (mid-session changes). Dropdown lazily fetches saved-ids once on first input event, caches in window._savedIds Set, and decorates result rows with a gold ♥ when r.id ∈ savedIds. Saves the N round-trips that /api/saved/state would require for 24 suggestions. Verified: anon {false,[]}, smoke@example.com {true,1,[72]}, /designs has 7 wiring refs (ensureSavedIds, _savedIds, /api/me/saved)
  1171. c82055d 2026-05-12 security parity with starsofdesign: app.disable(x-powered-by), rate-limit 60/min/IP on /api/studio/*, COOP header at nginx
  1172. b03add3 2026-05-12 wallco.ai · home gets a 'Stumble through the catalog' random rail (12 designs via /api/designs/random + ↻ Shuffle button) inserted between Featured Designs and the CTA band — fresh discovery surface per visit, mirrors the empty-state /compare pattern, aspect-ratio 1/1.15 cards w/ color dot + category caption · pivoted from the originally-defaulted PDP 'More in this palette' rail because the existing 'Pair this with' block on the PDP already does palette neighbors via /api/design/:id/pairings (would have been a duplicate UX surface) · verified home / 200 26KB, 5 rail-related element refs
  1173. b425604 2026-05-12 wallco.ai · /sitemap.xml now includes /compare (priority 0.5, monthly) + /samples (0.6, monthly) — both are top-level user-facing pages that crawlers were missing. /design/:id/tearsheet stays out (noindex), /me/saved stays out (auth-gated), /basket and /brief defer to later tick. Verified sitemap.xml emits 7 static + 228 per-design URLs
  1174. 528112c 2026-05-12 wallco.ai · /me/saved 'Build proposal PDF →' button restyled to match /compare gold pattern (was DW-default btn-primary, now var(--gold)+var(--accent) like Export-as-Brief on /compare) — same target=_blank rel=noopener · adds Brief-options details panel with project + client name inputs (saved-brief-project, saved-brief-client) that builds /brief?ids=…&project=…&client=… and opens in new tab via window.open(_,_,'noopener') · only renders when designs.length > 0 (no-op for empty saved list) · verified by signing in as smoke@example.com, saving design #72 via POST /api/saved → /me/saved returns href=/brief?ids=72 + 7 brief-related element refs
  1175. cdb0765 2026-05-12 wallco.ai · /compare gets 'Export as Brief →' gold button + Brief-options details (project + client name inputs) — direct link goes to /brief?ids=72,161,139 with no labels; if user fills project+client in the details panel, 'Open Brief →' opens /brief?ids=…&project=…&client=… in new tab; renames 'Print or save as PDF' to 'Print this view' (less ambiguous now that there's a separate Brief PDF path); IIFE wires brief-go button via window.open(_,_,'noopener') · verified: /compare?ids=72,161,139 contains href=/brief?ids=72,161,139 + 7 export-related element refs
  1176. 702842c 2026-05-12 wallco.ai · /brief?ids= now ships Cache-Control + Last-Modified · populated brief: public,max-age=3600 (1h — shorter than tearsheet because designers may rotate project/client labels per session) + LM=max(created_at) over the selected designs; empty landing page: public,max-age=600 (10m) · verified: populated → 200 + headers + LM Tue 12 May 2026 05:11:59 GMT; IMS-match → 304 0B; empty → 200 + 10m cache
  1177. 59a2afc 2026-05-12 wallco.ai · /design/:id/tearsheet now sends Cache-Control:public,max-age=86400,must-revalidate + Last-Modified (per-design created_at) + 304 via maybe304() — overrides the global no-store HTML rule because tearsheets are per-id immutable docs · designers reload these all day; saves bandwidth + speeds re-prints · verified: 200 5255B + headers Cache-Control + LM Tue 12 May 2026 03:03:47 GMT; IMS-match → 304 0B
  1178. 1799198 2026-05-12 wallco.ai · 3 more pro functions inline · (1) /api/designs/by-color?hex=%23c16d74&n=12&exclude= — CIELAB ΔE ranked neighbor endpoint (sRGB→linear→XYZ-D65→Lab pipeline, returns sorted by Δ rounded to .1), useful for 'more like this in this palette' rails; verified target=#c16d74 → exact match ΔE=0 on #161, then ΔE 20.2 / 21.6 near-pinks; bad hex → 400 · (2) PDP wall-size calculator (collapsible details block above CTA group) — W×H ft inputs → panel count + total yards + sq-ft + material estimate (low/high range), reads chosen panel width (24/27/36 in) from existing material picker localStorage, 15% match-waste buffer, 27 ft standard panel length, $6.50–$11.50/sq-ft pricing tier · (3) /brief?ids=72,161,139&project=&client= — multi-design proposal/brief HTML (print-to-PDF), cover page w/ project+client+date+3-thumb mosaic, per-design tearsheet sections w/ page-break-after, empty /brief → landing page explaining usage; verified 3 ids → 12.7KB / empty → 778B / project=Living Room shows in <title> and <h1>
  1179. 6db3b6b 2026-05-12 wallco.ai · trade login + saved designs — magic-link auth (no passwords, no autonomous email), wallco_trade_users + wallco_saved_designs tables init at start, separate `wallco_trade_session` JWT cookie (won't collide w/ admin `dw_auth`), routes /trade/login /api/trade/login /trade/auth /trade/logout /api/trade/me /api/saved /api/saved/state /me/saved, ♡ Save button on PDP pro-tools row (toggles via POST /api/saved; prompts /trade/login when anon), Sign-In ↔ name+Saved-(N) hydrated nav element in htmlHeader (single fetch shared via window.__tradeMe + trade-me-loaded event), /me/saved grid w/ Remove button + Build-proposal-PDF link to /brief?ids=… — verified: /trade/login 200, /api/trade/login returns magic_link JSON, /trade/auth sets HttpOnly cookie, /api/saved toggle round-trips, anon POST 401, /me/saved redirects 302→/trade/login when anon, schema confirmed via psql dw_unified
  1180. 542e977 2026-05-12 wallco.ai · sample basket — multi-design trade samples (mirrors /compare): + Sample button on PDP pro-tools (max 12, localStorage[wallco-basket]), View Basket gold pill, /basket route with stacked mini-cards + reused samples form + random-rail empty state + ?ids= share-link fallback, POST /api/basket/submit appending to data/sample-requests.jsonl (no email, no DB), header nav 'Basket' link with client-hydrated count chip · verified: /basket 200, /basket?ids=72,161 200, submit POST 200, /compare /samples /design/72 unchanged
  1181. 4295177 2026-05-12 wallco.ai · /murals search box parity with /designs — server-side ?q= filter (form-submit fallback), live autocomplete dropdown (same pattern: 180ms debounce, AbortController, Arrow/Enter/Esc keyboard nav, click-outside dismiss, did-you-mean chip row on 0-hits, See-all-N link when count>8), result-count header updates with matched count · verified: /murals 200, /murals?q=rose → 'matching rose (53 found)'
  1182. 4739bcb 2026-05-12 wallco.ai · /api/designs/search now emits did_you_mean[] on 0-hit · Levenshtein over the motif+category vocab (cap=2, early-exit on row min) — only kicks in when count===0, returns top-5 candidates sorted by distance · autocomplete dropdown wires it through window._didYouMean and renders a 'Did you mean' chip row beneath the no-matches message · verified: roze→rose(d=1), damaks→damask(d=2), valid 'rose' (53 hits) → did_you_mean:[]
  1183. 0b4eba7 2026-05-12 studio: show rendered image + 3 room settings (bedroom/living_room/dining_room) inline after compose · T18
  1184. fe60c05 2026-05-12 wallco.ai · empty /compare now renders a 'More designs to explore' rail (12 random designs via /api/designs/random) with a ↻ Shuffle button — turns the empty-state from instructions-only into a real discovery surface · auto-redirect to /compare?ids= still fires first if localStorage has prior selections (so returning users skip the rail) · graceful 'Loading…' / 'Couldn't load' states · cards link to PDP where '+ Compare' button lives · empty page +3KB, /compare?ids= unchanged
  1185. 817e136 2026-05-12 wallco.ai · /api/designs/random?n=12&category=&seed= — random sample for 'Surprise me' rails + empty-state discovery · partial Fisher-Yates (O(n) not O(N)) · optional ?category= filter, optional ?seed= mulberry32 PRNG for reproducible shuffles · Cache-Control:no-store (randomness is the point) · verified: n=3→228-pool, category=floral→17-pool, seed=42→deterministic [208,173,265]
  1186. 340a3c9 2026-05-12 wallco.ai · autocomplete dropdown now renders a 'Refine' motif chip row beneath results — pulls facets.motifs (top-6) from the same /api/designs/search response (no extra fetch), chips link to /designs?motif=X for one-click facet filter. Stays hidden if facets absent (graceful degradation). Reuses existing pill styling from the catalog filter chips.
  1187. d6bebc3 2026-05-12 wallco.ai · professional/trade functions — 3 new designer-workflow features. (1) /design/:id/tearsheet — print-ready 1-page PDF view with hero+room+specs+DW contact, @media print rules, 'Print or Save as PDF' button, noindex (per-client docs not for crawlers). (2) /compare?ids=72,161,139 — side-by-side compare table (up to 4 designs), per-design Remove buttons + View/Sample/Tear-sheet actions per col, Print + Copy-share-link buttons, localStorage[wallco-compare] backed (empty /compare auto-redirects to stored list). (3) PDP CTA gets 4 trade-tool buttons: Tear Sheet (PDF), Email to Client (mailto with pre-filled subject+body+tearsheet link), + Compare (localStorage toggle with In-compare/Compare state), View Compare (N) — gold pill, only visible when list non-empty. All additive, all reversible. Verified: /design/72/tearsheet → 200 5255B, /compare?ids=72,161,139 → 200 24511B, /compare empty → 200 11644B (renders empty-state w/ localStorage auto-redirect), PDP has 6 pro-tool refs.
  1188. 4b1b3ed 2026-05-12 wallco.ai · /api/designs/search now returns facets — motifs (top-8) + categories (all) rolled up from matched designs · purely additive JSON field, existing autocomplete dropdown ignores it cleanly until wired into a future 'refine by motif' UI · verified q=rose → 53 hits, top motifs floral/peony/rose/leaf/vine, top categories damask/floral/mixed
  1189. 3622bf5 2026-05-12 wallco.ai · /designs search box → live autocomplete dropdown (uses /api/designs/search) — debounced 180ms, fetches /api/designs/search?q=&limit=24, renders top-8 with thumbnail+title+category+color-dot+room-badge in a floating dropdown beneath the input; ArrowUp/Down/Enter/Esc keyboard nav; click-outside dismiss; 'See all N results →' link to full /designs?q= page when count>8; AbortController cancels stale in-flight requests; form-submit fallback unchanged (Enter still works server-side without JS). aria-controls + role=combobox + aria-expanded for screen readers. Also adds data/generated/ + data/moodboards.json + data/reviews.json to .gitignore (was sweeping in 2 GB of generated PNGs).
  1190. 7d5cb78 2026-05-12 wallco.ai · /api/designs/search?q=&limit= — lightweight in-memory search across catalog scoring motif(5 exact/3 contains), title(2), category(2 exact/1 contains), handle(1); top-N by score then saturation; rejects q<2 chars; emits Last-Modified+Cache-Control public 5min so crawlers + clients can cache search results; verified rose+floral → 81 hits with Rose Bouquet No.161 (score 14) leading, damask → 180 hits
  1191. d6cdb24 2026-05-12 wallco.ai · all target=_blank now rel=noopener noreferrer (tab-nabbing fix) + 3 external links (figma/spoonflower/dash.cloudflare) escalated to add nofollow — closes the window.opener XSS pivot vector + SEO link-juice leak. 20 internal blanks, 3 external upgraded.
  1192. 8d04faa 2026-05-12 wallco.ai · Last-Modified + 304 on /sitemap.xml + /robots.txt — sitemap pinned to CATALOG_LAST_MODIFIED, robots.txt pinned to process start; both also override the global no-store middleware with cacheable Cache-Control (sitemap public+1h+must-revalidate, robots public+1d+must-revalidate) so crawlers actually issue conditional GETs; verified IMS-match → 304 0B, stale IMS → 200 32KB on /sitemap.xml
  1193. b74701c 2026-05-12 wallco.ai · Last-Modified + If-Modified-Since on /designs and /design/:id — Conditional GET: crawlers (Googlebot/Bingbot) get 304 (0 bytes) on repeat visits when no design newer than their last crawl. CATALOG_LAST_MODIFIED computed once at loadDesigns() from max(design.created_at); per-design page uses design.created_at. maybe304() helper floors to 1-second precision (HTTP-date drops millis). Verified: matching IMS → 304 0B, stale IMS → 200 94KB.
  1194. 324afdd 2026-05-12 security — prompt-injection hardening on Ollama chat path. Adds safePromptField() to sanitize design/chip metadata before string interpolation (strips backticks + angle brackets, caps length). ollamaCall() now wraps user input in <user_input>…</user_input> delimiters + appends 'Security rules (non-negotiable)' instructions: treat delimiter contents as data not instructions, never reveal system rules/design metadata verbatim, politely decline 'ignore previous instructions'/persona-switch attempts. Doesn't structurally prevent the model from complying (no LLM does), but raises the bar against drive-by 'reveal your prompt' probes and reduces the prompt-template-injection blast radius. All 191 tests still green.
  1195. 450155e 2026-05-12 wallco.ai · WCAG 2.3.3 prefers-reduced-motion shotgun — neutralizes all transitions + keyframe animations site-wide for OS-level reduce-motion users; hero crossfade (1.2s) / card-room overlay (360ms) / chat thinking-dot bounce / skip-link slide all collapse to 1ms; verified via playwright reducedMotion:reduce vs no-preference — design-card 0.18s→1e-05s, card-room 0.36s→1e-05s, skip-link 0.16s→0s
  1196. 2acf00a 2026-05-12 wallco.ai · WCAG 2.4.1 skip-to-main link in htmlHeader() — first focusable on every route; #main-content anchor span injected after the nav-panel; visually hidden via translateY until focused
  1197. 29adb76 2026-05-12 spoonflower — add GET /api/export/spoonflower-batch.csv + 'Spoonflower CSV' link on /moodboard. JS-native equivalent of scripts/spoonflower_kept_to_csv.py — same source data (reviews.json + designs.json), same output format (image_path,title,tags with category+wallcovering+motifs tags capped at 13), same '# header' first line. X-Wallco-Rows + X-Wallco-Skipped-Missing-Image response headers for client diagnostics. Now curators can one-click the spoonflower-batch CSV from /moodboard instead of running a Python CLI. Verified live with 2 seeded keeps → 2 rows; 0 keeps → 0 data rows + header.
  1198. 8aa0c7c 2026-05-12 spoonflower — add scripts/spoonflower_kept_to_csv.py to make --batch usable end-to-end. Reads data/designs.json + data/reviews.json (+ optional data/moodboards.json) and emits a CSV in the exact format upload_spoonflower_new.py --batch consumes. Filters: --decision keep|all, --min-pins N, --limit N, --dry (print) vs file. Tags = category + 'wallcovering' + motifs, deduped, capped at 13. Resolves image filenames against data/designs/img/ data/designs/ data/generated/. Header comment line (# image_path,title,tags) preserved through both writer and the existing reader (skipped via '#' prefix rule). +5 unit tests covering CLI, valid rows, --limit cap, tag count cap. End-to-end chain verified: generator → CSV → batch parser → 3 ready rows.
  1199. 680a09e 2026-05-12 wallco.ai · /design/:id Share button — Web Share API + clipboard fallback
  1200. f4354f9 2026-05-12 spoonflower upload — fix hydration race + add --batch CSV mode. Per 2026-05 technical-researcher finding: Spoonflower is a React SPA so input[type=file] renders AFTER networkidle fires; the old 2s post-navigation sleep was racing. Bumped to 10s hydration wait + explicit page.wait_for_selector(state='attached', timeout=15s) on the file input. Adds --batch CSV mode iterating image_path,title,tags rows with --throttle (default 15s between items) to avoid Spoonflower rate-limits. CSV supports # comment lines + optional tags column. Dry-by-default safety preserved.
  1201. 1d2bb76 2026-05-12 wallco.ai · /designs JSON-LD — ItemList of Products + BreadcrumbList
  1202. 0772bf0 2026-05-12 security — prototype-pollution + pin-spam DoS guards in src/review.js. Adds validId(raw) helper returning a positive-integer string or null; rejects '__proto__', 'constructor', 'toString', '0', '01', '1abc', etc. with HTTP 400 before id is used as an object key (reviews/cache/moodboards). Adds sanitizePinSuggestion() whitelisting suggestion fields (type/hex/label/reason/thumb_url/design_id/icon) so '...spread' can't leak surprise keys. /api/moodboard/:id/pin: 16kb content-length pre-check (global json parser has 25mb limit, route-local check is too late), pin_key required-string ≤200 chars, 200-pins-per-design cap. /api/chip/:id/:chipKey: chipKey restricted to [a-z0-9_-] ≤80 chars, message ≤2000 chars, history capped to last 200 turns. +11 integration tests covering attack + valid paths.
  1203. 486986e 2026-05-12 wallco.ai · gzip compression middleware — 86% bandwidth reduction on /designs
  1204. 70b4570 2026-05-12 security — close path traversal + shell injection in /api/studio/upload. sid/name user inputs are now strictly validated (sid: ^[a-z0-9-]{1,40}$ allowlist or anon-N fallback; name: strip non-[a-z0-9._-], collapse '..' sequences, trim leading dots). Resolved target verified to start with safeDir+sep. sips and python3 invocations switched from execSync(`...${path}...`) → execFileSync(cmd, [args]) so shell metacharacters can't reach a shell. Python script reads path from argv[1] instead of being source-string-interpolated. +5 integration tests verifying ../../etc/passwd traversal, name='../../escape.png', leading-dot '.env', shell-special-char sid all neutralized while normal uploads still 200.
  1205. 284e3dd 2026-05-12 wallco.ai · OG/Twitter enrich — og:type=product on /design/:id + image:alt + product:* tags
  1206. 149bfe0 2026-05-12 wallco.ai · /design/:id JSON-LD — enriched Product schema with sku/color/motifs/rooms
  1207. 3d1b6bd 2026-05-12 wallco.ai · /sitemap.xml + /robots.txt — 233 URLs, saturation-weighted priority
  1208. 05812f4 2026-05-12 wallco.ai · card-room-badge — dynamic room count ("4 rooms") replaces "IN A ROOM"
  1209. 47d55d2 2026-05-12 wallco.ai · sortDesigns — boost has-room designs to top of every sort
  1210. ece9e37 2026-05-12 wallco.ai · POST /api/room — mirror admin-generated rooms into catalog JSONB
  1211. d37c171 2026-05-12 yolo backlog: T17 ledger update — R8 viewport meta tag fix + loop stop condition met (all [ ] → [x])
  1212. 97bd4e5 2026-05-12 YOLO R8 — /age-themes mobile layout. Added viewport meta tag (was missing — @media queries didn't fire) + targeted @media (max-width:640px) overrides: h1 18px, tag 10px, toc/band-row tightened, theme-card 170px, theme-spec/apca/rationale scaled, diff-chip 10px. Validated at 390x844: band-compare grid stacks to single 358px column.
  1213. 1cd8af9 2026-05-12 YOLO R8 — /age-themes mobile layout. Added @media (max-width:640px) tier that scales down headers, padding, TOC pills, age-pills, theme-card min-heights, diff-chip + apca-chip font sizes, and lets rationale min-height collapse to 0. Verified clean stack at 390×844 via Playwright full-page screenshot.
  1214. 92ab522 2026-05-12 YOLO R6 — text search box on /moodboard. Matches case-insensitive against pin labels + reasons + parent design title. Empty sections auto-collapse, empty-state hint appears on zero matches, query persists across reloads via localStorage. Stacks with the existing type filter (?type=design|color|material).
  1215. 3b36790 2026-05-12 YOLO R7 — promote why-chip from subtle pill to prominent curator-rationale block. Adds CURATOR label tag, gold left-accent bar, larger padding+font, hover hint 'tap to open chat →'. Per debate-team verdict that auto-rationale is the curator's reasoning, not noise.
  1216. a9a18ac 2026-05-12 YOLO R5 — surface design's stored dominant_hex vs extracted palette[0] in iso modal. New iso-dominant row above palette block showing canonical DB hex + SW match with closeness chip. Header copy makes the distinction explicit ('stored hex; may differ from extracted' / 'top-6 from image pixels'). renderIsoDominant() gracefully hides when no dominant_hex stored.
  1217. 957e20b 2026-05-12 YOLO R2 — ΔE closeness bands in src/color-isolate. closenessBand(de, kind) returns {band, note} for any Lab ΔE; kind='sw' yields 'no SW analogue — paint physics ceiling' at the weak end, kind='design' yields 'different color family'. Wired into nearestSW (sw.closeness) and coordinatingDesigns (per-result closeness). API /api/isolate returns closeness on palette / dominant_sw / coordinating_hexes / coordinating_designs. Rendered as colored chips on the iso modal palette + coord-designs grid. +12 unit tests (27/27 green). Mirrored to ~/Projects/_shared.
  1218. 55f8ac2 2026-05-12 YOLO R4 — keyboard shortcuts on isolate modal (W=wallpaper, P=paint, C=copy primary hex, ?=help). Scoped to modal-open state so it doesn't fight the global K/R card handler. Toast feedback on every action; nudge if W/P pressed before Isolate button clicked.
  1219. 444eefc 2026-05-12 YOLO R3 — add diff-bar chip strip to /age-themes bands. Auto-detects which props changed between current↔best (font/body/h/accent/etc.) and renders them as 'key from → to' chips above the compare grid. Fixes architect punch-list #11 (Adult band's subtle body 13→15 delta now reads explicitly instead of looking 'identical').
  1220. 8ad112a 2026-05-12 YOLO R9 — scrub AI-generated language from 9 public surfaces (schema.org + meta descriptions on /, /designs, /design/:id, /murals, /samples, Shopify tagList). Replaced with 'wallco.ai original' / 'proprietary design system'. Admin /age-themes banner preserved per validation-loop honesty rule.
  1221. b855ca9 2026-05-12 YOLO ticks R10+R11+R12 — visual-regression baselines for isolate modal (3 PNGs), /api/isolate response now includes dominant_sw {code,name,hex,deltaE}, tsd mobile QA verified at 390×844
  1222. 7f87ada 2026-05-12 yolo backlog: R0a-R0d ledger update — Steve /studio post-gen experience complete
  1223. e636fb7 2026-05-12 wallco.ai · /studio R0c+R0d: studio_renders persistence + soft-delete (7d undo) + personal gallery on /studio with restore
  1224. c6eb465 2026-05-12 wallco.ai · refinement signal: ctx-passing through /swipe + /poll + /hot-or-not into WC.reward; /api/personal/recs surface curated picks at 80% refinement
  1225. 354cb17 2026-05-12 wallco.ai · /designs "In a room ·N" filter chip — surface room-preview designs
  1226. a7922f0 2026-05-12 hot-or-not: standalone server on port 9794 — own pm2 process
  1227. 70cab7c 2026-05-11 gamify: real game feel — XP, levels, combos, haptics, particles, achievements
  1228. 3563074 2026-05-11 wallco.ai · /api/studio/category-insights — fix products SQL to match real schema
  1229. 78b90d1 2026-05-11 wallco.ai · hover-preview room mockups on /designs grid cards
  1230. cfe10a2 2026-05-11 feat(/wallco-ai): drop Big Red widget into home page footer
  1231. 48475ee 2026-05-11 /hot-or-not: fix window.history shadow + backtick-in-comment
  1232. d92efea 2026-05-11 wallco.ai · context toggle on /design/:id (residential/commercial/hospitality)
  1233. bc44f28 2026-05-11 fix(chat.js): SyntaxError on line 145 — 'Here\\'s' broke string parsing
  1234. ece6129 2026-05-11 swipe: real touch-drag works on mobile — attach move+end to document
  1235. 03f4c4c 2026-05-11 wallco.ai admin · loopback bypass for src/admin.js gate
  1236. 2ad6307 2026-05-11 mobile: 44px tap-target floor + iOS auto-zoom fix + 24-viewport tested
  1237. 5c636e2 2026-05-11 wallco.ai · /admin/dashboard with catalog + demand + cost-burn metrics
  1238. 468964c 2026-05-11 wallco.ai · multi-room mockup grid + bedroom for top-5 (tick 16)
  1239. feb477a 2026-05-11 fix(/studio): escape inline onclick string quotes properly
  1240. 24e8de3 2026-05-11 wallco.ai · surface pre-generated room mockups on /design/:id (tick 15)
  1241. d1fefad 2026-05-11 fix(site.css): bump wordmark weights per debate consensus
  1242. 26f4d82 2026-05-11 gamify: Hot-or-Not single-card + Tinder-style swipe + /play hub
  1243. 38ac947 2026-05-11 Close security CRITICAL findings from 2026-05-12 audit — strip ?review=1 admin bypass (4 spots), gate all 13 review.js routes with requireAdmin middleware, fix broken isAdmin() cookie helper (was base64-decode only, now HS256 JWT verify via jsonwebtoken), neutralize CSV formula injection in csvCell(). New src/admin-gate.js module exports isAdmin/requireAdmin. All 32 Playwright tests + 119 unit tests pass.
  1244. e1a4e64 2026-05-11 tick 14 (late-fire): room-mockup mvp — generate_room_mockups.py runs top-5 saturated designs (Rose Origin #72, Sapphire Fan #29/#24/#14, Honey Salon #144) through Kamatera room-setting-generator endpoint · 5/5 succeeded ~10s each · output to data/rooms/ · persisted to spoon_all_designs.room_mockups JSONB · idempotent · fixed response-key parser ('image' vs older 'imageBase64')
  1245. 4541eb0 2026-05-11 tick 14: cool/pale palette batch + snapshot refresh — catalog 77→107 designs · marine 6→15, rose 3→10, neutral 10→13 (the 'cool/oyster/ivory/marine' prompts worked). Reload was hitting wrong pm2 name (wallco-ai-viewer vs actual wallco-ai); confirmed fix.
  1246. a8488e5 2026-05-11 fix(wallco-ai/404): drop is_published filter so recovery row populates
  1247. ba0b062 2026-05-11 gamify: user votes + head-to-head polls + Elo + 5-variation fan-out
  1248. 5bdabe9 2026-05-11 gamify: user votes + head-to-head polls + Elo + 5-variation fan-out
  1249. 925dc4e 2026-05-11 Add Ollama-free integration tests (admin-gate, csv-export, age-themes-render, pairings-api)
  1250. 3a43f9b 2026-05-11 404 v2 (debate consensus): numeral tightening + strip pill + eyebrow + og:image
  1251. 8e98a62 2026-05-11 feat: admin design ratings + RLHF-lite retry on /design/:id
  1252. 81b7308 2026-05-11 polish(modals): proper slide-in via translateX (was display:none, no animation) · viewport-safe width using min(480px, 92vw) · clean shadow seam when side-by-side (was bleeding pair shadow over chat) · 260ms cubic-bezier easing · mobile breakpoint 920px
  1253. 292faa8 2026-05-11 tick 13: palette-rebalance batch — 10 new SDXL designs targeting underrepresented hues (rose 0→3, plum 1→4, mauve, olive, sage refresh). Catalog 67→77. New most-saturated: Rose Origin No.72 (sat 0.751). ~$0.14
  1254. 229a8e0 2026-05-11 redesign(wallco-ai): luxury 404 page for /design/:id
  1255. caf6496 2026-05-11 wallco.ai: side-by-side modals on /design/:id — when both chat+pair open, chat shifts left by 480px via CSS :has() · 220ms transition on right · mobile stacks
  1256. 59a32e8 2026-05-11 wallco.ai: side-by-side modal layout on /design/:id — when BOTH chat-modal + pair-modal open, chat shifts left by 480px so they tile horizontally (was overlapping at right:0) · uses CSS :has() · mobile (≤900px) falls back to stacked
  1257. d8df29d 2026-05-11 fix(wallco-ai): 404 on non-numeric /design/:id to avoid WHERE id=NaN psql error
  1258. 880142e 2026-05-11 remove debug-kb spec scaffolding files (left from investigation)
  1259. 0afc54c 2026-05-11 fix review-mode IIFE syntax error + add keyboard-shortcut e2e tests
  1260. 7ffd43b 2026-05-11 wallco.ai admin: /admin/leads viewer — table of all wallco_leads + 'Most requested' chips of top 25 designs by hit count · added Leads tab to admin nav
  1261. 702863d 2026-05-11 wallco.ai: color-wheel hue swatch row above /designs · 10 buckets (rose/amber/honey/olive/sage/marine/sapphire/mauve/plum/neutral) each with chip+swatch+count · combines with cat/motif/q filters · live counts: amber 25 · honey 9 · neutral 9 · marine 5 · sapphire 5
  1262. f5de4b2 2026-05-11 Architect refactor (items 1+3+5 from punch list) — extract apcaLc to src/apca.js shared module + mirror to skill lib/apca.js (identical bytes), ship bands.json as canonical with VERSION 9.0.0, server.js require()s it (-7140 chars inline removed), credits banner surfaces version + cites canonical sources
  1263. e637e49 2026-05-11 tick 12: process 64 new wikimedia thumbnail-mode rows (palette+tileability+classification) → 39 AI-input candidates from wikimedia + 73 from met = 112 total seedable · pre-create dw_unified.wallco_leads schema with email+design indexes · POST /api/leads smoke green
  1264. f5a303a 2026-05-11 Sync /age-themes route to v9 — teen body 14→16/h22, adult line-height baseline 1.5, elder btn-min-height 56px; aligned with ~/.claude/skills/age-adaptive-theme/ + Figma file rebuild; validation-loop passed (debate verdict: ship)
  1265. ffcec80 2026-05-11 edit modal: large + live preview image at top + Adjust tab default
  1266. c63100c 2026-05-11 crawl_pd: use Wikimedia thumbnail URLs (iiurlwidth=1280) instead of full-res — Commons rate-limits original-res downloads, thumbnails are uncapped · re-running wikimedia crawl with limit 300
  1267. 4bb293e 2026-05-11 fix(kamatera): wrap psql with sudo -u postgres on Linux
  1268. 4504906 2026-05-11 tick 11: process 8 new wikimedia PD images (palette+tileability+classification — 4 new AI-input candidates) · 'Surprise me' button on /designs fires random-palette/random-motif chat → 1 fresh SDXL design, ~30s//bin/zsh.014
  1269. 525d067 2026-05-11 width slider: offer 24/36/52 on every design + samples form, generator picks per-design from weighted pool
  1270. 12f88ca 2026-05-11 design/:id: replace left side-panel with hamburger → tabbed info modal
  1271. 25e633c 2026-05-11 wallco.ai: Gmail draft to Corey with 6 SDXL trellis+butterfly variations · base64-embedded thumbnails · saved via George POST /api/drafts (steve@dw, draftId r163145...)
  1272. ba87275 2026-05-11 Fix apcaLc hex parser to handle 3-char shortcuts (#fff, #000) — was returning NaN for half the bands; same bug existed in figma frame generator + Figma file rebuilt with correct palettes
  1273. 9de55cd 2026-05-11 bake → redirect: nginx body limit + Express json limit + snapshot path
  1274. 8d7aa6f 2026-05-11 tick 10: expand Wikimedia PD categories — +10 (Tapa cloth, Ikat, Batik, Indian block prints, Chinoiserie, William Morris, Art Nouveau, Pattern books, Trellis, Lattice) · crawl backgrounded (limit 250)
  1275. fcefc88 2026-05-11 wallco.ai: overlay composer (Pillow) — tile background pattern + scatter overlay elements at lattice intersections · auto-mask near-white pixels as alpha · saves to spoon_all_designs with generator='wallco-overlay'
  1276. 3055bb2 2026-05-11 Apply debate-team fixes to /age-themes — implement APCA-W3 Lc calculator + render verified Lc badges (green/blue/yellow/red) on every swatch + drop the 2 hallucinated-precision swaps (toddler #222 fg unchanged, adult -apple-system unchanged) + use Fredoka (Google Fonts) instead of paid Sassoon Primary
  1277. 93f4423 2026-05-11 refresh_designs_snapshot: platform-aware psql (Linux sudo postgres, macOS direct)
  1278. f3c9acd 2026-05-11 Fix /age-themes after debate-team review — strip fabricated 4-horsemen credit, add honest 'AI-generated starting point' warning, link real Figma file (WmwSirHywv530eACPtbqyA), surface debate-team consensus, fix markdown bold rendering bug
  1279. e8f73bf 2026-05-11 wallco_rooms persistence + gallery + admin remove/restore/marketing
  1280. c9365f5 2026-05-11 design/:id: Photoshop-style edit panel — sliders, palette dots, color wheel, drag-drop recolor, bake
  1281. 6881a12 2026-05-11 wallco.ai: motif filter chips on /designs — 12 top motifs (peony/damask/lattice/scrollwork/etc.) clickable, combine with category + search · snapshot now carries motifs[] from PG · 47 designs tagged via llava
  1282. b8132ca 2026-05-11 wallco.ai: width + material picker on /design/:id — 24" residential (Paper/Vinyl/Peel-Stick/Grasscloth) vs 54" commercial (Vinyl Type II only) · localStorage-persisted · spec panel reactive · 'Designed by wallco.ai' (no Replicate leak)
  1283. 1fa03aa 2026-05-11 copyright: scrub AI vendor names + triple-layer watermark every design
  1284. 1f5e693 2026-05-11 wallco.ai: motif tagger via llava on Mac2 — extracts 3-6 visual tags per design (peony/damask/geometric/etc) · running in background against all 55 designs · ~5 min total
  1285. ae9a436 2026-05-11 generator: one-step batch UI + fix /design/13 (age modal was blocking)
  1286. 5e65545 2026-05-11 Add keyboard shortcuts to /designs (K/R/P/arrows/1-9/?) + npm pretest auto-resets all 5 data files (was leaking state between runs)
  1287. ccd3f38 2026-05-11 wallco.ai: 'Pair this with' block on /design/:id — 3 nearest-palette siblings in CIE Lab space · POST-less GET /api/design/:id/pairings · client-rendered grid below CTA
  1288. 6debe83 2026-05-11 Shopify: bump all wallco/SP scripts to API 2026-01 · add read_orders scope preflight in fetch_recent_orders_palette.js with admin-link-out helper · admin/_devlogin restored · inspiration→generate flow working (3 designs in ~90s, vendor-anonymous prompts)
  1289. d506fdf 2026-05-11 Add 5 Playwright e2e tests for /designs review flow — dual-mode (local + Browserbase via cloudflared tunnel), serial workers, addInitScript dismisses age-prompt overlay; 5/5 passing in 4.1m
  1290. a2999ed 2026-05-11 scripts: platform-aware psql (Linux → sudo postgres, macOS → direct)
  1291. 0d9edc5 2026-05-11 wallco.ai: live scale slider on /design/:id (4-54" repeat, persisted to localStorage) · update specs to 54" wide, sold per yard · admin layer scaffolded under src/admin.js + /css/admin.css + /js/admin.js (vendor browse, aesthetic search, inspiration pool — strict admin-only)
  1292. 679232f 2026-05-11 studio: textures + drag-drop + palette suggestions + designer review + insights
  1293. a3ace82 2026-05-11 Pairings v2: LLaVA vision read (Mac2 localhost:11434) drives material suggestions, moodboard pin/unpin per suggestion, CSV export of kept designs + pinned pairings
  1294. 2922a59 2026-05-11 wallco.ai: hot-path fallback for /design/:id (live PG lookup when not in snapshot) · classification-filter PD: 73 AI-input candidates (34 seamless+textile + 39 near+textile) from 304-row corpus · is_ai_input_candidate column + index
  1295. 98dbbba 2026-05-11 Add /designs pairing suggestions — Pair button + side modal with 2 catalog matches (sibling+sister) + 2 color swatches (complement+analogous) + 2 material recs from Ollama; cached in data/pairings.json with refresh button
  1296. 8269964 2026-05-11 generator + go-live: 30-min pattern generator, prod deploy at wallco.ai
  1297. cd26879 2026-05-11 chat panel UI polish: extract to /css/chat.css using site design tokens (--bg/ink/serif/gold) · dark-mode aware · animated thinking dots · slide-in panel · NEW badge on variant cards · mobile fullscreen breakpoint
  1298. 78f6515 2026-05-11 tick 6: tileability scored on all 304 PD images · verdict: 62 seamless / 95 near / 132 photo / 15 scene · note: paintings false-positive seamless (uniform-bg edges); classification-filter needed for real AI-input seeds
  1299. 5f79c25 2026-05-11 wallco.ai chat layer: POST /api/chat/catalog + /api/chat/design/:id · qwen3:14b on Mac1 with tool-use (search + generate) · Replicate SDXL for new+variant designs · floating chat panel auto-mounts on every page, context-aware (catalog vs design:id) · 5 PG tables (sessions, messages, parent_design_id lineage)
  1300. 225c77f 2026-05-11 spoonflower: 3-path auth (Chrome attach > cookies > password)
  1301. a6af871 2026-05-11 refresh data/designs.json snapshot — 30 designs (was 11): 8 damask · 9 floral · 8 geometric · 5 mixed; semantic title generator by category+hue
  1302. cf92efe 2026-05-11 fix wallco.ai missing CSS — add general /public static mount (was only /uploads + /designs/img)
  1303. 98ac0cf 2026-05-11 spoonflower: upload-new-product + pull-DW-account scripts
  1304. 047f1d6 2026-05-11 go-live launcher: scripts/golive.sh + /admin/golive web checklist · 8 steps with one-line commands, JSON probe, auto-refresh 30s
  1305. e10e4dd 2026-05-11 fix wallco.ai age-gate stuck overlay: drop inline display:flex, control via .is-open class; ESC also skips
  1306. f3dc9ad 2026-05-11 add finish_dns.sh — CF DNS + certbot + health check script for post-NS-swap
  1307. 3f15587 2026-05-11 ship v1 customer-facing storefront + Kamatera deploy
  1308. f5bdf9b 2026-05-11 wallco.ai: wire Replicate SDXL backend · inline-editor mounted at site=wallco.ai · 11 real SDXL designs across floral/geometric/damask (cost ~$0.15)
  1309. 2853438 2026-05-11 wallco.ai v0.1: PG schema (pd_source_designs + spoon_all_designs) · Met/Wikimedia/Smithsonian crawler · palette extraction · design generator (stub backend) · viewer on :9792 · 10 seamless tiles + 33 PD source images

Authors

  • Steve1305
  • steve4

Agents used

  • secrets-manager6
  • debate-team-fast4
  • debugger2
  • vp-compliance-policy1
  • abramstasks1
  • technical-researcher1

Skills used

  • /designs242
  • /design233
  • /marketplace58
  • /studio43
  • /room31
  • /library26
  • /rooms24
  • /trade24
  • /compare24
  • /generator23
  • /generated22
  • /saved22
  • /elements22
  • /logs21
  • /search19
  • /ghost-review17
  • /poll17
  • /gate-rejections16
  • /bulk16
  • /scenic16
  • /list15
  • /wallco15
  • /by-id14
  • /skills13
  • /hot-or-not13
  • /spoonflower13
  • /brief13
  • /luxe-curator12
  • /fixes-feed12
  • /inspirations12

Creative ideas + design notes

Commits with substantial prose (≥120 chars) — the rationale behind each move.

3a7458b · 2026-06-23 · Concierge search reads in-memory designs.json cache, not Postgres
toolSearchDesigns now searches the same DESIGNS array the public /api/designs
grid renders (data/designs.json snapshot) instead of querying spoon_all_designs.
On prod the dw_unified DB is near-empty (~350 rows) and is NOT the catalog
source — the ~27k-row designs.json snapshot is — so the PG-query concierge
returned near-empty on prod while the grid showed the full catalog. This makes
search return the same catalog the user can see, identically on local and prod.

- server.js: pass { getDesigns: () => DESIGNS } into chat.mount (matches the
  existing review.js/library.js getter convention; reflects /admin/reload-designs).
- src/chat.js: mount(app, opts) captures getDesigns; toolSearchDesigns filters
  the cached array (is_published && !user_removed), soft category/motif keyword
  match over category+title+motifs+tags (arrays or strings), hue/hex_near color
  filters with empty-cone keyword fallback, uses each record's own image_url,
  same {id,title,category,hex,image_url} return shape. GENERATE path + the
  /api/chat/design/:id PG lookup left untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
126ee4f · 2026-06-23 · Fix design concierge returning 0 results
toolSearchDesigns had three compounding bugs that all returned empty-but-200:
- generator='replicate' scope filter excluded ~84% of the published catalog
  (incl. every comfy/gemini/wallpapersback row and ALL damask rows)
- exact category= match against a vocabulary (floral/damask/...) the catalog's
  real taxonomy (drunk-animals/chinoiserie/...) never uses -> always 0
- image_url built from local_path basename 404'd; switched to /designs/img/by-id/:id

Now scopes to brand='wallco.ai' AND is_published, treats category as a soft
keyword (category OR prompt ILIKE), enlarges the candidate pool when a color
filter is active, and fixes hueNameToDeg returning 0(=rose) for unknown colors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f55cefc · 2026-06-21 · Dedupe designs.json snapshot: DISTINCT ON (id) + dedup-aware shrink guards
all_designs base table physically stores ~2 byte-identical rows per id
(69,399 rows / 35,192 unique; 34,207/34,207 dup ids fully identical, 0 differ).
spoon_all_designs view is a plain SELECT FROM all_designs (no JOIN), so the
builder faithfully emitted every physical row -> designs.json doubled.

Fix:
- SELECT DISTINCT ON (id) collapses the fan-out at the point of emission
  (lossless: kept copy is byte-identical to the dropped one).
- Catastrophe guard now compares UNIQUE-id coverage (not raw rows) so a
  legitimate 2x->1x dedup passes while a sparse-PG regen still aborts.
- Byte-size guard now compares bytes-per-RAW-ROW (not total bytes) so a
  dedup (same B/row, ~half total) passes while a field-strip clobber aborts.
- Added a WARN if any prior unique id disappears.

Validated locally (scratch dirs only, prod designs.json untouched):
53,385->27,165 raw rows, 27,165->27,165 unique ids (0 dropped/added),
0 payload mismatches, published render set 6,264->6,264 unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
37d9df9 · 2026-06-12 · marketplace/db: never pass undefined password to pg (fixes SASL 'client password must be a string')
Omit password from pool config unless PGPASSWORD/DW_UNIFIED_PG_PASSWORD is
actually set, and String()-coerce when present. The old '|| undefined' fed a
non-string password into pg's SCRAM handshake on Kamatera, throwing the SASL
error. Operational root cause is still a missing MARKETPLACE_DB_URL in the
marketplace pm2 env on prod — this fix surfaces a clearer error and lets the
trust-auth path work where intended.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66f6a71 · 2026-06-12 · colorways: add POST /api/design/:id/recolor-preview — live crisp recolor off full-res TIF (recolor-tif.py, --preview-maxedge 1400, ink-map-hash cache, no_tif fallback) + cache serve route
Server half of the click->TIF crisp-preview feature. Endpoint reuses resolveSrcTifLocal + the edge-preserving recolor-tif.py (the canonical fix for the 600px-canvas blocky+halo edges). Validated on Mac2: no_tif fallback, empty-map + no-op-map rejection. Crisp result verifiable on prod (designs with a TIF). Client wiring (swap img.src on click) still TODO.
0fdef02 · 2026-06-12 · element_copy_heal v2: wrap-edge-only crisp palette-reconcile (DTD verdict C)
Replaces v1 half-roll patch-copy which sliced a visible line through the frog's
face on root 2766 and worsened the top/bottom edge. v2 heals ONLY the 4 physical
tile-wrap edges, and only the columns/rows where the outermost wrap pixels carry
different palette labels (a motif crossing the wrap). Each rewritten pixel is
snapped to a crisp dominant-palette color (no averaging = no smudge), only the
disagreeing lines are touched (no drawn line), and the interior mids (x=W/2,
y=H/2 = motif edges, NOT seams) are never touched. On 2766: wrap-column
disagreement 17 -> 0, frog motif fully preserved, no smudge/line.
96285b0 · 2026-06-12 · Add live variant-curator for Wave-1 drunk-animal composition variants
New /admin/variant-curator (admin-gated) + /api/variant-curator + pick endpoint.
One row per root: root thumb + up-to-10 unpublished variant children, auto-poll
every 5s so new variants appear live as variants-9roots.py lands them. Multi-keep
toggle for variety. Each card shows the 🕓 created date+time chip (standing rule).

KEEP is durable via a local sidecar wallco_variant_picks (PK-backed → UPDATE-able)
rather than UPDATE-ing all_designs, which is INSERT-only on Mac2 (no replica
identity in FOR-ALL-TABLES publication dw_unified_pub). Roots never touched; real
is_published flip to live stays a Steve-gated Kamatera export. DTD verdict A
(unanimous). Nav link added to the admin hub.
4992ea4 · 2026-06-11 · seam-wave Wave 1: 1/3 roots cleared (55272 elephant -> 10000018 PASS-both-axes)
Ran the 3 animal-forward FAIL roots through the generalized retry generator.
55272 cleared PASS-both-axes (new id 10000018, is_published=FALSE, parent=55272).
43199 macaw + 54385 peacock exhausted 8 retries without a both-axes PASS
(motif edge never reached the <=6 strict threshold; honestly recorded, NO DB row
inserted — orphan-minimization held). Queue updated with the winner only.

Note: manifest grew during the run — a separate overnight-seam-loop (PID 48863)
appended 100 animal-forward WARN roots (DTD-C bounded slice). Left intact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
41f6dfc · 2026-06-11 · Add seam-warn recovery + animal-forward filter helpers (DTD-C bounded WARN slice)
seam-warn-list.py re-derives the 793 distinct WARN roots (the original
seam-fail-scan.py persisted only FAILs). seam-warn-animal-filter.py runs the
FREE local-llava dominance gate over them in id order, CAP=100, dropping
glassware-dominant / pastoral-toile / animal-minority roots. Both read-only
against the DB; neither appends to the manifest, flips is_published, or deploys.
81fefac · 2026-06-11 · overnight-seam-loop: single log sink (drop tee, launcher >> is sole sink)
logl + wave output were doubling because tee -a wrote to $LOG while the nohup
launcher also redirected stdout to $LOG. Now logl prints stdout-only and all
in-loop output relies on the launcher redirect — one clean line per entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2fed439 · 2026-06-11 · seam-wave: generalize the retry-loop generator to arbitrary --ids
controlnet-anchored-reroll.py wraps the proven reroll_one machinery from
controlnet-anchored-reroll-2 (image-level seam-retry until motif clears
PASS-both-axes + coverage + llava subject-recovery; insert ONLY the winner;
roots sacred) but accepts any animal-forward FAIL root via a DEFAULT_CFG canny
profile. Per-root special profiles (54076/54266) still honored via imported
ROOT_CFG. This is the SEAM_GENERATOR for scripts/seam-wave.sh.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0438663 · 2026-06-11 · seam-wave: build manifest — 3 animal-forward FAIL roots (43199/54385/55272)
Scanned 2448 eligible published drunk-animals roots (not in curator's 85, not
retired) with the canonical both-axes gate verify-edge-seamless.py: 848 PASS /
1586 WARN / 7 distinct FAIL. Animal-forward pre-filter (free local llava) kept
3 (macaw/peacock/elephant), dropped 4 (2 pastoral toile, 1 animal-minority,
1 glassware-dominant). Adds scripts/seam-fail-scan.py (read-only scanner).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
f1efeda · 2026-06-11 · Add autonomous overnight seam-fix wave runner (DTD-gated, self-gating, never publishes)
scripts/overnight-seam-loop.sh drives seam-wave.sh wave-by-wave overnight.
5 stop conditions (07:00 PDT / manifest exhausted / kill switch / DTD PAUSE /
3 zero-PASS waves). Self-gates: waits (never runs a wave) until the manifest is
populated, the generator exists, and ComfyUI is idle — no collision with Wave-1.
PASS rate from seam-fix-queue.jsonl per-wave window; DTD panel (codex+qwen+rule)
votes CONTINUE/PAUSE, ties fail-safe to PAUSE. bash-3.2 compatible. Nothing
publishes — only is_published=FALSE candidates; never touches settlement/deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c63a1ff · 2026-06-11 · Add controlnet-anchored-redo.py: SDXL canny-CN anchored native-seamless redo
Uses the controlnet-canny-sdxl-1.0 model installed on Mac1 ComfyUI to anchor a
single focal motif (DTD 3/3: cropped focal canny hint on blank canvas, not the
full busy root) while circular-pad SeamlessTile+MakeCircularVAE keeps the tile
seamless (zero smear). Composites onto real procedural fibre ground. Inserts a
sacred curator-mode child (is_published/user_removed FALSE, parent=root) with
explicit id (dw_admin has no sequence USAGE) and image_url inline (table is in a
no-replica-identity publication so UPDATE/DELETE error).
3a53bd5 · 2026-06-11 · wallco redo: real-fibre composite path + img2img native-seamless orchestrator
- make-fibre-ground.py: deterministic SEAMLESS natural-fibre swatch generator
  (grasscloth/raffia/linen/sisal/paperweave) — wraps by construction (edge ΔE
  0.00), fills the real-fibre-ground gap (no local DW fibre swatch library).
  Validated: composite of root #54266 onto raffia reads as genuine woven fibre.
- seamless-bg-swap-file.py: file-input wrapper around seamless-bg-swap.py so the
  deterministic real-fibre composite runs on a fresh motif PNG (not just a DB id).
- native-seamless-redo.py: img2img native-seamless orchestrator (VAEEncode root +
  SeamlessTile/MakeCircularVAE circular-pad, subject-anchored by starting from the
  root latent) then real-fibre composite. Sacred roots, is_published=FALSE.

FINDING (sample BLOCKED, not shipped): proved txt2img circular-pad PASSES edges
cleanly (3.18/2.18) but has no subject anchor -> drift; img2img preserves subject
but breaks native-seamless edges to WARN AND can't open the busy root. No
ControlNet model + no IPAdapter installed on Mac1 ComfyUI = no anchor that works
at denoise-1.0 native-seamless strength. Minimum missing: an SDXL canny/lineart
ControlNet model on Mac1. Probes 58056/58057 removed (FALSE+user_removed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
b9ad50c · 2026-06-11 · Force true-toroidal edge-wrap on both axes for the 6 WARN roots; all 6 candidates now edge-PASS
The 6 WARN roots (2662,54076,54078,54123,54266,54507) failed because the box
scanner never flagged their edge boxes - literal line diff was tiny but the 2x2
tiled cross-seam band exceeded clean. force-edge-seamless.py mirror-averages a
full-width top/bottom + full-height left/right strip unconditionally (no scanner
dependency), making row[k]==row[H-1-k] and col[k]==col[W-1-k] exactly so both
line_diff and tiled cross-seam drop to ~0. Roots untouched; each candidate is a
new child (ids 58043-58048) is_published=FALSE, parent_design_id=root, appended
to seam-fix-queue.jsonl with edge_verdict/edge_seamless/edge_axes.
6c41239 · 2026-06-11 · Add true-toroidal edge-continuity verifier + wire as hard publish gate on seam-fix curator
- scripts/verify-edge-seamless.py: measures literal wrap boundary (col[0] vs col[W-1], row[0] vs row[H-1]) + 2x2 tiled cross-seam, per-axis PASS/WARN/FAIL, exit 0 only on PASS both axes
- seam-fix-variants.py: record edge_verdict/edge_seamless/edge_axes per candidate (the literal-edge gate, not the strip-mean after_verdict)
- server.js: runEdgeSeamlessGate() helper; /api/seam-fix-curator/pick refuses to publish a candidate whose edge verdict != PASS (fail-closed, incl. verifier-absent host); list API surfaces edge_verdict so FAIL candidates render non-selectable
- backfilled edge_verdict into existing 170 queue rows (79 PASS / 71 WARN / 20 FAIL)
0236a2b · 2026-06-11 · seam-fix curator: scale past 5-root sample — 80 worst-FAIL drunk-animals roots → 160 candidates (is_published=FALSE)
Scanned 1304 eligible published drunk-animals roots (parent NULL, has path, not
user_removed, needs_fixing IS NULL): 228 PASS, 684 WARN, 392 FAIL = 1076 flagged.
Generated 2 composition-preserving candidates (v1 shift-feather, v2 heal-region)
for the 80 worst-FAIL roots via scripts/seam-fix-variants.py. All landed as
parent-linked children, is_published=FALSE — Steve picks per-row in the curator.
Roots untouched, prior 5 picks untouched. No Gemini/ComfyUI/API cost (PIL only).
996 flagged roots remain (312 FAIL + 684 WARN) pending Steve confirm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fe0b0b1 · 2026-06-11 · seam-fix curator: heal seams of good roots as is_published=FALSE children + per-root picker
Steve's narrow ask: the roots are good, only the seams need fixing. This is NOT
the luxe aesthetic transform (de Gournay/1838) — each variant is a SEAM-FIXED
copy of the SAME design, composition preserved exactly (round-1 sacred).

- scripts/seam-fix-variants.py: for given root ids, mints 2 composition-preserving
  seam-fix children (v1 fix-seam shift-feather, v2 per-box circular-wrap heal),
  re-scores each with seam-defect-boxes (before/after overall_max), inserts as
  parent_design_id=root, is_published=FALSE, generator=seam-fix-v1|v2, and
  appends to data/seam-fix-queue.jsonl. ComfyUI reroll deliberately excluded
  (DTD 3/0: a reroll drifts composition).
- server.js: GET /api/seam-fix-curator (isAdmin) + POST /api/seam-fix-curator/pick
  (requireAdmin). Pick publishes the chosen child, unpublishes seam-fix siblings,
  and NEVER touches the root. Pick validates the child is a real seam-fix child
  of the root before publishing.
- public/seam-fix-curator.html: luxe-curator-style per-root picker — root + seam-fix
  candidates side by side, 2x2-tile preview to reveal the seam, before/after seam
  scores + verdict per tile, cleanest fix starred, keyboard picks.

Sample: 5 drunk-animals roots (2810,2778,43186,43198,2662), all FAIL seam gate.
v2 per-box heal is the consistent winner (FAIL -> WARN/PASS, 50-82% lower max).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4e68e65 · 2026-06-09 · fix(scripts): DB password from DATABASE_URL (.env), not empty PGPASSWORD env
The secret-scrub left these reading os.environ PGPASSWORD (not exported) → empty
pw → PG auth fail. _pg_password() now parses DATABASE_URL from .env (mirrors
edges-batch-scan.py); PGPASSWORD env still overrides. SELECT 1 verified all 4 paths.
a717efc · 2026-06-09 · feat(design-curator): 🛋 Room setting button — generate room mockup, show below design in chip
Per-chip 'Room setting' button POSTs to existing /api/room (admin via q() token),
shows a spinner, then injects the rendered room image + caption in a .roomgen
box directly below the design image. Reuses the auth-gated renderer; honest error
surfacing on failure. No server change — static curator page.
dbe4464 · 2026-06-09 · generator: log gate rejections to data/logs/gate-rejections.jsonl (close orphan provenance gap)
When the ghost/seamless/frame-overlay gate rejects a tile after its retry, the
loop continued WITHOUT a DB insert, leaving an orphan PNG with no recorded
reason. Now each skip appends {ts,seed,file,gate,reason,category,kind} so the
wallco-live-viewer can name the actual gate instead of inferring 'gate-rejected'
from absence-of-row. Append-only; logging failures never block generation.
afa4976 · 2026-06-09 · cleanup: manifest of 14,632 May gate-rejected orphan designs removed (2.8GB freed)
Orphans = generated PNGs with no spoon_all_designs row (failed an insert-time
quality gate: seamless/ghost/frame-overlay/concept). Kept all June orphans
(recent). Manifest = every deleted filename+seed+mtime.
ff8c30c · 2026-06-09 · Harden refresh_designs_snapshot.py summary print against None category
The post-write Categories summary crashed with TypeError when any design
had a None category (sorted() can't compare None < str). The snapshot file
itself wrote fine before the crash, but the traceback masked that. Sort
None-last so the summary always prints and real errors stay visible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
83390fc · 2026-06-04 · test: make npm test a real preflight gate (node -c server.js + hard-rule audit)
Was a placeholder (echo + exit 1). Now: npm test -> preflight = syntax-check
server.js (the documented #1 deploy hazard — a stray backtick in a template
literal cost 321 pm2 restarts) + run the 4-rule hard-rule audit. Also exposes
npm run audit standalone. Gives the audit gate teeth — one command before any
deploy. Exits 0 today.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
222ab35 · 2026-06-04 · audit: extend hard-rule gate to vendor-names + FLIEPAPER (4 rules, one snapshot load)
Rule 3 (no vendor names in public UI — the legal premise of wallco.ai) and
rule 4 (no FLIEPAPER word in any customer-facing surface) were CLAUDE.md hard
rules with no standing programmatic guard. Folded into the umbrella (no new
file): scans the 9 customer-visible snapshot fields x 26,060 rows against the
server.js VENDOR_DENYLIST + a fliepaper regex, loading designs.json once for
rules 2-4. Current state: ALL CLEAR on all four.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d249fc8 · 2026-06-04 · audit: umbrella hard-rule gate (mural-kinds + designs.json local_path leak)
One read-only command (node scripts/audit-hard-rules.js) that verifies the
data-integrity hard rules from CLAUDE.md in one green/red pass: delegates rule 1
to audit-mural-kinds.js, checks rule 2 (no local_path / /Users home-path leak in
the public snapshot) inline. Exit 1 on any violation -> usable as a pre-deploy
gate or cron canary. Current state: ALL CLEAR (26,060 rows).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
24c17c0 · 2026-06-04 · audit: standing read-only check that mural categories never carry a tile kind
Insert-time assertMuralKind() only guards rows that go through it; the
2026-05-27 incident was 12 rows that bypassed it via direct SQL. This
catches that drift after the fact — requires lib/mural-categories.js +
lib/db.js (zero-drift canonical lists), exits 1 on LIVE violations so it
is CI/cron-able. Current state: CLEAN.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
84ccb96 · 2026-06-04 · generate_designs: committed read-back in persistDesign — phantom-insert fix
Root cause (6-agent workflow, high confidence): all_designs.id defaults to a
shared sequence (spoon_all_designs_id_seq). When an INSERT fails/rolls back
after nextval fires (settlement-trigger rejection or concurrent-generator
interleave), persistDesign() returned the burned id as success without
verifying the row committed — so batches reported phantom ids (PNG on disk,
no DB row), which looked like silent deletions. persistDesign now does a
fresh-connection SELECT read-back and throws if the row isn't visible; the
batch loop catch logs ✗ and continues, keeping the Created N/M count truthful.
Reversible: remove the read-back block.
5499527 · 2026-06-03 · bulk-action 'digital': exempt designs with a built room-size mural master from demotion
The low-res mural demotion (mark digital-for-sale → unpublish) was unpublishing
designs that NOW have a built 12x11ft master (e.g. #27151) — i.e. premium mural
products got demoted as 'low-res junk'. Guard: skip any id with a
data/mural-previews/<id>.jpg, report them as mural_skipped. Prevents the
mural-block PDPs from being silently 404'd by the demotion.
d2aa744 · 2026-06-03 · Add clean-edge vector-trace 150-DPI upscale pipeline (potrace + LANCZOS fallback)
Traces flat 2-4 color designs per-color via potrace (DTD-CRISP params:
turdsize=4, alphamax=0.8, native trace) into a composited SVG, rasterizes
at 5400x5400 (36in @ 150 DPI). LANCZOS fallback for trace failures/degenerate.
Source PNG round-1 sacred; outputs to data/generated/clean_<id>_<ts>.png.
Validated on #53677/#53690/#53720 - razor edges, palette preserved, no ghost halo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d9c4f54 · 2026-06-03 · pdp: universal room-size-mural injector for theme variants (prod serves v12-roomsplit)
prod default theme is client-side v12-roomsplit, so the bare-PDP server-rendered
block never showed live. MURAL_PDP_INJECT in themeVariantSend injects the Room-size
mural card (from the deployed design.mural API field) above the footer across all
17 variants. Validated on roomsplit locally.
5dc7d6a · 2026-06-03 · fix: digital-for-sale also unpublishes spoon_all_designs (prod leak root cause)
The /api/designs/bulk-action 'digital' branch wrote only all_designs; on prod
spoon_all_designs is a separate base table the storefront/PDP reads, so items
marked digital-for-sale stayed visible. Mirror the 'unpublish' spoon-write so
digital actually drops the item from the live site on prod. No-op echo on Mac2
(spoon is a view there). NOT deployed — run ./deploy-kamatera.sh to ship.
b4013ff · 2026-06-03 · pdp: room-size mural preview block (web previews + API field + PDP section)
Surfaces built 12x11ft scenic-mural masters as a panelized wall product on the
design PDP. mural-web-preview.py downscales each Henry master to a ~234KB web JPG
+ a sidecar JSON (dims/panels) — both small, in-repo, ship to prod (the 500MB TIF
stays Mac2-local). server.js: static route /designs/mural-preview, a 'mural' field
on /api/design/:id, and a conditional 'Room-size mural' block on the bare PDP
(preview image + 12x11ft + 6in install-bleed copy + 24/36/54in panel chips). Renders
only for designs with a master; hidden otherwise. node -c clean; real-browser
validated (block + 1400px preview render on #27151, absent on #54099). 28 previews
generated. NOT deployed — prod push is Steve-gated.
7513978 · 2026-06-03 · admin/mural-masters: show in-progress builds as live 'building…' cards [yolo, local-only]
API surfaces master dirs without summary.json as {building:true}; gallery renders
them as pulsing 'building…' cards and the header shows 'N done · M building'. Lets
Steve watch a batch land in real time (30s auto-refresh) instead of only seeing
finished masters.
ab10041 · 2026-06-03 · docs: mural-pipeline.md — Replicate gotchas playbook + review-gallery section [yolo T2, local-only]
Captures today's hard-won Replicate fixes so the next session doesn't burn an hour
rediscovering them: Cloudflare 403 on python urllib → browser User-Agent; 403 on
large inline base64 → files-API upload; model-predictions 404 → version-pinned
/v1/predictions; one transient tile 400 crashed a mural → per-tile 4x retry;
inpaint model = lucataco/sdxl-inpainting (latest). Plus a Reviewing-built-masters
section pointing at the new /admin/mural-masters gallery.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4cb93d5 · 2026-06-03 · admin: /admin/mural-masters local review gallery for room-size scenic murals [yolo T1, DTD-A, local-only]
Admin-gated local surface to review the 12×11ft mural masters built by
build-mural-master.py (masters live on Henry, Mac2-local not prod). API scans the
masters dir, reads each summary.json + master file size/mtime, returns dims +
per-width panel counts + created timestamp + contact-sheet availability. HTML grid
shows contact-sheet thumb, 24/36/54in panel chips, size, created date+time chip
(standing rule), Sort + Density controls (standing rule), 30s auto-refresh as the
batch lands more. Contact-sheet served via /api/admin/mural-masters/:id/sheet.
node -c clean; real-browser validated 13 cards render with all controls.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8282219 · 2026-06-03 · dogs-curator: fix greedy edges parse (split_part slurped appended settlement/canary notes into the badge)
/api/admin/dogs/list derived edges via split_part(notes,'DOGS_EDGES:',2) which
returned EVERYTHING after the marker — so when the settlement canary / override
processes appended audit lines to notes, the curator's edges badge rendered
multi-line garbage. Switched to regexp_match(...'(PASS|WARN|FAIL)') to extract
only the verdict token. Pure read-path fix, zero DB writes. Verified live:
438 rows → PASS 174 / WARN 34 / FAIL 29 / 201 unscanned, 0 polluted badges.
1096024 · 2026-06-03 · build-mural-master: fix SDXL outpaint — UA + files-API upload + version-pinned endpoint
Three fixes so the generative bleed actually runs: (1) Replicate's Cloudflare edge
403s the default Python-urllib User-Agent on files/model endpoints → install a
browser-ish UA process-wide (covers build-tif's esrgan calls too); (2) upload
images to the Replicate files API and pass URLs instead of oversized inline base64;
(3) resolve latest_version then POST /v1/predictions (the model-predictions endpoint
404s). Validated isolated on 27151: natural sky/grass bleed, no mirror artifact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
a0203ad · 2026-06-03 · /api/designs: strip local_path from public output (no /Users//root/ path leak)
Defensive output sanitization — runtime-added in-memory rows (generator/curator/recolor) carry local_path which the shallow-copy emit leaked on prod (146 rows, ids 39290-57342). Hard rule: public API must never expose filesystem paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
24439b2 · 2026-06-03 · yolo loop 2026-06-03 complete: mural pipeline built/proved/curated/documented; fliepaper already compliant; stop condition reached [local-only]
T5 = fliepaper-bugs date-chip audit: already compliant (fmtDate hour+minute + 🕓
chip), no change. No non-gated local work remains → loop stops, no busywork.
Session-recap memory written. Paid mural batch + 644-row demotion parked for Steve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
34f8c54 · 2026-06-03 · docs: mural-pipeline.md — full room-size scenic-mural architecture + runbook [yolo T4, local-only]
Documents geometry (21,600x19,800 master, 6in sky/grass bleed, 24/36/54in panel
slicing), the build pipeline (cover-fit then SDXL outpaint then tiled ESRGAN, in
the order model size limits force), both key findings (1448px ESRGAN cap leads to
tiling; mirror-bleed artifact leads to generative outpaint), every command, and
what stays Steve-gated (paid batch, demotion --apply, settlement-before-publish).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e5dc163 · 2026-06-03 · mural-contact-sheet.py: visual panel review aid for any built master [yolo T3, local-only]
Lays out a master's vertical panels per width (24/36/54") side-by-side, downscaled,
with seam lines + drop labels → <master_dir>/contact-sheet.png. Lets Steve eyeball
the slicing + bleed without opening a multi-GB TIF. Pure local PIL — no spend, no
DB, no network. Validated on the 10557 proof master (24"=2 drops, 36"=2, 54"=1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
52b7c2f · 2026-06-03 · mural-batch: curate-monterey-batch.py → 12 hue-spread published Monterey manifest [yolo Q3, local-only, read-only DB]
Read-only selector picks N published Monterey scenes spread across the hue wheel
(visual range, not 12 near-identical colorways) → data/mural-batch-monterey.json
with the ready-to-run batch + estimate commands. No DB writes, no spend. The
paid 12x11ft batch is now one command away on Steve's go.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d43631e · 2026-06-03 · mural-master: --estimate dry-run cost estimator (no-spend) — batch $ before approval [yolo Q2, local-only]
Mirrors esrgan_tiled's level loop exactly (count_esrgan_calls + _tiles_1d) to
report per-mural + batch Replicate call count and $ without making any calls.
12x11ft / 12-mural batch = ~216 calls / ~$3.30. Lets Steve see the spend before
greenlighting the paid batch. self-test still green; compiles clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
93e7589 · 2026-06-03 · stage-la-toile-nb: emit gallery from REAL inserted IDs, not predicted ones
Fixes the off-by-N 404 bug (2026-06-03): gallery HTML built inline with predicted IDs
(57280-57309) before the insert assigned real ones (57313-57342), so links 404'd while
designs were live. Now captures {id,title} from each RETURNING id, writes the gallery
after insert/publish, labeled LIVE only when --publish flipped is_published.
5bfe5e9 · 2026-06-03 · mural-master: room-size 12x11ft scenic-master builder + vertical-panel slicer + lowres-demotion report
build-mural-master.py: recreate Monterey scenic murals as ONE continuous
12ft W x 11ft H scene (21,600 x 19,800px @ 150 DPI) — 'the entire design is all
the panels, create room size to fit'. Upscales curated art via build-tif's
Real-ESRGAN chain (reused via importlib), cover-fits the 12x10ft focal (no
stretch), synthesizes 6in forgiving sky/grass bleed bands top+bottom (installer
shift/trim zone), then slices into customer-width vertical panels: 24in->6,
36in->4, 54in->3+remainder. v1 bleed = deterministic mirror+fade (free, no model,
never trips settlement foliage detectors); generative outpaint is the upgrade.
--self-test proves geometry at zero cost; all assertions pass.

demote-lowres-murals.py: REPORT-ONLY scan of mural-kind rows below 12ft-master
hi-res (tif_w_px<21600): 1,652 rows (644 published). Writes a plan JSONL of what
an apply would touch; makes NO DB changes. Applying stays Steve-gated. No DB
creds in the file — reuses build-tif.db() via importlib.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8dad76a · 2026-06-03 · build-tif: Real-ESRGAN mural upscale stage (DTD verdict A) — large-format scenic murals
Mural-kind rows (mural/mural_panel) are now upscaled toward the requested print
size at build time: chained Real-ESRGAN x4 via Replicate (same model+version as
the /api/design/:id/download route), then an exact LANCZOS resize, with a pure-
LANCZOS fallback when no Replicate token. Lets a 1024px scenic mural fulfill a
20ft order instead of capping at ~7" of true 150-DPI print.

Patterns are untouched — they tile infinitely so the native repeat IS the
master (compute_max_print still returns the 240x132" infinite-tile cap for
seamless_tile/pattern_repeat/best_seller_seed). SVG skipped for murals (scenic
art isn't vector-eligible; embedding a 36k raster would be pathological). Bulk
path untouched (tiles-only).

Flags: --no-mural-upscale, --mural-print-ft N (default 12ft, cap 20ft/36000px).
Env: WALLCO_MURAL_UPSCALE=0, WALLCO_MURAL_PRINT_FT, WALLCO_ESRGAN_PASSES.
Free-disk headroom guard before upscaling. Offline-validated: resize math,
aspect preservation, native short-circuit, max-print recompute.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
b4692f9 · 2026-06-03 · yolo audit: APPLIED+DEPLOYED 3 unpublish + 51 kind-flip + 1224 free room mockups
All live-verified: defect rows 404, flips render tile, rooms show on grid+PDP.
Published-with-room ~800->2024. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
9f25013 · 2026-06-02 · yolo loop tick 5: customizer smoke test 33/34 pass ($0)
EXIT 0 non-blocking. 1 soft fail: 'best' variant drag moved 17px no-reorder while
classic passed same check (Δy=2207) — likely flaky, flagged not fixed. Customizer
render-room + save-layout persistence verified on both surfaces.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

File tree

868 files tracked. Click any to browse the source at HEAD.

Other build journals

← Wallco  ·  all 4 projects  ·  Wallco Live Viewer →

Export

commits.csv · feed.atom · project.json · commits.json

rendered in 11ms