[object Object]

← back to Designer Wallcoverings

Add bucketB-land-175 one-shot lander (DW_ROLL_CAP=175, 00:01) for 175 priced Harlequin+MindTheGap rolls

d9ff0a7c7829ff07b70c1c80de57a237bb56618a · 2026-06-22 14:50:44 -0700 · Steve

Files touched

Diff

commit d9ff0a7c7829ff07b70c1c80de57a237bb56618a
Author: Steve <steve@designerwallcoverings.com>
Date:   Mon Jun 22 14:50:44 2026 -0700

    Add bucketB-land-175 one-shot lander (DW_ROLL_CAP=175, 00:01) for 175 priced Harlequin+MindTheGap rolls
---
 shopify/scripts/bucketB-land-175.sh | 78 +++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/shopify/scripts/bucketB-land-175.sh b/shopify/scripts/bucketB-land-175.sh
new file mode 100755
index 00000000..389a023c
--- /dev/null
+++ b/shopify/scripts/bucketB-land-175.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+# bucketB-land-175.sh  (2026-06-22)  — owner: vp-dw-commerce
+#
+# One-shot lander for the 175 priced Bucket-B roll variants (Harlequin 32 + Mind the Gap 143)
+# that were cap-blocked on 2026-06-22 (the shared 1000/day variant ledger was fully consumed by
+# upload 500 + osborne 20 + backlog 500, and the 'roll' category cap is throttled to 0).
+#
+# MECHANISM (DTD verdict A, 3/3, 2026-06-22): export DW_ROLL_CAP=175 for THIS run only, so 'roll'
+# becomes a first-class budget participant. budget.take('roll') is still clamped to remainingGlobal
+# (BUDGET_TOTAL - spentTotal), so a nonzero roll cap can NEVER push the combined daily total past
+# the 1000 ceiling — it only changes the priority order. Scheduled at 00:01 (after the midnight
+# ledger reset, before osborne 00:05 / fivefield-drain 00:10 / cadence-hourly 00:40), so roll
+# reserves its 175 from the fresh 1000 first and the others compete for the remaining ~825.
+#
+# Idempotent + draft-gated: each bucketB script skips products that already have a roll variant,
+# writes PG retail_price first (source of truth), never flips status, never touches title /
+# customer-facing vendor / display_variant. If a partial run leaves a remainder, re-running this
+# script on a later day drains it (DW_ROLL_CAP re-applied; already-landed products are skipped).
+#
+# After a clean full landing this job UNLOADS ITSELF (one-shot) so roll returns to 0 on subsequent
+# days. If a remainder remains (budget couldn't fit all 175 because a competitor raced in first),
+# it leaves the job loaded to retry the next night.
+
+set -uo pipefail
+export DW_ROLL_CAP=175
+
+SCRIPTS_DIR="$HOME/Projects/Designer-Wallcoverings/shopify/scripts"
+REPORT_DIR="$SCRIPTS_DIR/data/bucketB"
+LOG_DIR="$HOME/Projects/Designer-Wallcoverings/logs"
+TS="$(date +%Y%m%dT%H%M%S)"
+mkdir -p "$REPORT_DIR" "$LOG_DIR"
+LOG="$LOG_DIR/bucketB-land-175-$TS.log"
+
+# Locate node (launchd has a minimal PATH)
+NODE="$(command -v node || echo /opt/homebrew/bin/node)"
+export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
+
+{
+  echo "=== bucketB-land-175  $TS  (DW_ROLL_CAP=$DW_ROLL_CAP) ==="
+  echo "--- pre-run budget status ---"
+  "$NODE" "$HOME/Projects/designerwallcoverings/scripts/variant-budget/budget.cjs" status
+
+  echo ""
+  echo "=== Harlequin (32 priced rolls) ==="
+  "$NODE" "$SCRIPTS_DIR/bucketB-harlequin-roll-variants.js" --apply \
+    --report "$REPORT_DIR/harlequin-land-$TS.json"
+  HQ_RC=$?
+
+  echo ""
+  echo "=== Mind the Gap (143 priced rolls) ==="
+  "$NODE" "$SCRIPTS_DIR/bucketB-mindthegap-roll-variants.js" --apply \
+    --report "$REPORT_DIR/mindthegap-land-$TS.json"
+  MTG_RC=$?
+
+  echo ""
+  echo "--- post-run budget status ---"
+  "$NODE" "$HOME/Projects/designerwallcoverings/scripts/variant-budget/budget.cjs" status
+
+  # Decide whether to self-unload: only if BOTH scripts left ZERO staged/deferred priced rows.
+  HQ_STAGED=$("$NODE" -e "try{const r=require('$REPORT_DIR/harlequin-land-$TS.json');process.stdout.write(String((r.totals&&r.totals.stagedForNextWindow)||0))}catch(e){process.stdout.write('1')}")
+  MTG_STAGED=$("$NODE" -e "try{const r=require('$REPORT_DIR/mindthegap-land-$TS.json');process.stdout.write(String((r.totals&&r.totals.pricedBacklogStaged)||0))}catch(e){process.stdout.write('1')}")
+  echo "staged remaining: harlequin=$HQ_STAGED mindthegap=$MTG_STAGED  (rc: hq=$HQ_RC mtg=$MTG_RC)"
+
+  if [ "$HQ_STAGED" = "0" ] && [ "$MTG_STAGED" = "0" ]; then
+    echo "✅ all 175 landed — unloading one-shot job com.steve.dw-bucketB-land"
+    launchctl bootout "gui/$(id -u)/com.steve.dw-bucketB-land" 2>/dev/null || \
+      launchctl unload "$HOME/Library/LaunchAgents/com.steve.dw-bucketB-land.plist" 2>/dev/null
+  else
+    echo "↻ remainder staged — leaving job loaded to retry next night at 00:01"
+  fi
+
+  # Log the win to CNCP (local, best-effort)
+  curl -s -X POST http://127.0.0.1:3333/api/wins \
+    -H 'Content-Type: application/json' \
+    -d "{\"project\":\"dw-bucketB\",\"title\":\"Landed Bucket-B roll variants (Harlequin+MindTheGap)\",\"summary\":\"One-shot DW_ROLL_CAP=175 lander ran post-reset; hq_staged=$HQ_STAGED mtg_staged=$MTG_STAGED\"}" >/dev/null 2>&1 || true
+
+  echo "=== done  $(date +%Y%m%dT%H%M%S) ==="
+} >> "$LOG" 2>&1

← 627df739 auto-save: 2026-06-22T14:36:53 (2 files) — shopify/scripts/d  ·  back to Designer Wallcoverings  ·  PDP: wire REQUEST SAMPLE (add Sample variant to cart) + SPEC 7f21a275 →