[object Object]

← back to Wallco Ai

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

49f4fa91bafcca7934dbef4b95c12b3b158621ef · 2026-05-28 09:35:27 -0700 · Steve Abrams

Files touched

Diff

commit 49f4fa91bafcca7934dbef4b95c12b3b158621ef
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu May 28 09:35:27 2026 -0700

    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
---
 server.js | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/server.js b/server.js
index 95b5450..09d8bf5 100644
--- a/server.js
+++ b/server.js
@@ -263,6 +263,13 @@ const { _hexToHsl, _hueBucket, _isNeonHex, _hexToLab, _dE, hexToHSL, hexSaturati
 const _AESTHETIC_GATE_RE = /\b(neon|fluorescent|electric|rainbow|day[- ]?glo|highlighter|fluoro)\b/i;
 function passesAestheticGate(d) {
   if (!d) return false;
+  // Curator-force-publish exemption (Steve directive 2026-05-28: "always publish
+  // — dont stop if we say publish"). A design tagged 'curator-force-publish' has
+  // been seen + greenlit by the human curator and explicitly overrides every
+  // gate (runPublishGate, settlement trigger, AND this load-time aesthetic
+  // filter — otherwise the design loads but the /by-id route can't find it
+  // because passesAestheticGate dropped it from DESIGNS).
+  if (Array.isArray(d.tags) && d.tags.includes('curator-force-publish')) return true;
   // 1) palette pass (if present)
   const palette = Array.isArray(d.palette) ? d.palette : null;
   if (palette) {
@@ -1602,7 +1609,7 @@ app.post('/api/admin/drunk/decide', express.json({ limit: '4kb' }), (req, res) =
       // row stays is_published=FALSE. Wrapping in a tx + SET LOCAL fixes that.
       // Steve directive 2026-05-28: "always publish — dont stop if we say publish".
       const publishSql = force
-        ? `BEGIN; SET LOCAL settlement.allow_override = 'true'; UPDATE all_designs SET is_published=TRUE, user_removed=FALSE, needs_fixing_at=NULL, notes = COALESCE(notes,'') || ' | curator-force-publish 2026-05-28' WHERE id=${id}; COMMIT;`
+        ? `BEGIN; SET LOCAL settlement.allow_override = 'true'; UPDATE all_designs SET is_published=TRUE, user_removed=FALSE, needs_fixing_at=NULL, tags = (array_remove(COALESCE(tags, ARRAY[]::text[]), 'curator-force-publish')) || ARRAY['curator-force-publish']::text[], notes = COALESCE(notes,'') || ' | curator-force-publish 2026-05-28' WHERE id=${id}; COMMIT;`
         : `UPDATE all_designs SET is_published=TRUE, user_removed=FALSE, needs_fixing_at=NULL WHERE id=${id};`;
       psqlExecLocal(publishSql);
       // Auto-spawn a photoreal room render for the HOT pick — detached + non-blocking

← d7db846 drunk-curator HOT = always publish (Steve directive 'dont st  ·  back to Wallco Ai  ·  refresh_designs_snapshot: include tags[] column so the curat 63a6271 →