[object Object]

← back to Designerwallcoverings

TK-11357 action C: 15-min zero-price-orderable OUTCOME tripwire (wrapper + plist template) — auto-rezero any $0 quote-only sellable variant that becomes orderable; reuses guarded stopgap enumerate+apply, restore-mapped, install stays gated

094abee2415950abd85b7c97d79bdbe3c7012861 · 2026-09-10 11:21:01 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MAcoZUWRsEY6F1nNYyfzQi

Files touched

Diff

commit 094abee2415950abd85b7c97d79bdbe3c7012861
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu Sep 10 11:21:01 2026 -0700

    TK-11357 action C: 15-min zero-price-orderable OUTCOME tripwire (wrapper + plist template) — auto-rezero any $0 quote-only sellable variant that becomes orderable; reuses guarded stopgap enumerate+apply, restore-mapped, install stays gated
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01MAcoZUWRsEY6F1nNYyfzQi
---
 .../com.steve.zero-price-orderable-tripwire.plist  | 21 +++++++++++
 scripts/tk11357-zero-price-stopgap/tripwire.sh     | 43 ++++++++++++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/scripts/tk11357-zero-price-stopgap/com.steve.zero-price-orderable-tripwire.plist b/scripts/tk11357-zero-price-stopgap/com.steve.zero-price-orderable-tripwire.plist
new file mode 100644
index 0000000..ffe4281
--- /dev/null
+++ b/scripts/tk11357-zero-price-stopgap/com.steve.zero-price-orderable-tripwire.plist
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>Label</key>
+  <string>com.steve.zero-price-orderable-tripwire</string>
+  <key>ProgramArguments</key>
+  <array>
+    <string>/bin/bash</string>
+    <string>/Users/macstudio3/Projects/designerwallcoverings/scripts/tk11357-zero-price-stopgap/tripwire.sh</string>
+  </array>
+  <key>StartInterval</key>
+  <integer>900</integer>
+  <key>RunAtLoad</key>
+  <true/>
+  <key>StandardOutPath</key>
+  <string>/tmp/zero-price-tripwire.stdout.log</string>
+  <key>StandardErrorPath</key>
+  <string>/tmp/zero-price-tripwire.stderr.log</string>
+</dict>
+</plist>
diff --git a/scripts/tk11357-zero-price-stopgap/tripwire.sh b/scripts/tk11357-zero-price-stopgap/tripwire.sh
new file mode 100755
index 0000000..83005a9
--- /dev/null
+++ b/scripts/tk11357-zero-price-stopgap/tripwire.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+# TK-11357 action C — OUTCOME tripwire. Every 15 min: detect any ACTIVE $0 quote-only
+# sellable variant that is orderable (on_hand>0, DENY, tracked, price==0) and set it back
+# to on_hand=0. Guards the OUTCOME so any future ad-hoc/hand-run store-wide restock
+# self-heals before a 7th recurrence. NEVER writes a price (the $0 is the quote-only sentinel).
+# Reuses the guarded, restore-mapped stopgap tooling (enumerate.mjs → apply.mjs --apply).
+# Reversible: launchctl bootout gui/$(id -u)/com.steve.zero-price-orderable-tripwire
+set -u
+export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
+HERE="$HOME/Projects/designerwallcoverings/scripts/tk11357-zero-price-stopgap"
+LOG="/tmp/zero-price-tripwire.log"
+LEDGER="$HOME/.claude/yolo-queue/executed-reversible/ledger.jsonl"
+TS="$(date -u +%FT%TZ)"
+cd "$HERE" || { echo "$TS FATAL: no $HERE" >>"$LOG"; exit 1; }
+
+# 1) enumerate (read-only) — refreshes targets.json with the current $0-orderable cohort
+node enumerate.mjs >/tmp/zero-price-tripwire-enum.out 2>&1 || { echo "$TS enumerate FAILED" >>"$LOG"; exit 2; }
+N=$(python3 -c 'import json;print(len(json.load(open("targets.json")).get("targets",[])))' 2>/dev/null || echo 0)
+
+if [ "${N:-0}" -eq 0 ]; then
+  echo "$TS OK — 0 zero-price-orderable variants, no write" >>"$LOG"
+  exit 0
+fi
+
+# 2) a cohort exists → re-zero it (guarded apply; records restore-map before each write)
+echo "$TS TRIPWIRE FIRED — $N zero-price-orderable variants detected, re-zeroing" >>"$LOG"
+node apply.mjs --apply >>/tmp/zero-price-tripwire-apply.out 2>&1
+RC=$?
+echo "$TS apply.mjs --apply exit=$RC" >>"$LOG"
+
+# 3) ledger the reversible write
+python3 - "$N" "$RC" >>"$LEDGER" 2>/dev/null <<'PY'
+import json,sys,datetime
+n,rc=sys.argv[1],sys.argv[2]
+print(json.dumps({
+ "ts":datetime.datetime.now(datetime.UTC).isoformat().replace("+00:00","Z"),
+ "agent":"zero-price-orderable-tripwire (launchd, TK-11357 action C)","ticket":"TK-11357",
+ "action":f"OUTCOME tripwire fired: re-zeroed {n} ACTIVE $0 quote-only sellable variants that became orderable (ad-hoc/hand-run restock self-heal)",
+ "blast_radius":int(n),"store":"designer-laboratory-sandbox.myshopify.com",
+ "undo_cmd":"node ~/Projects/designerwallcoverings/scripts/tk11357-zero-price-stopgap/rollback.mjs --apply",
+ "verify":"node ~/.claude/skills/zero-price-orderable-canary/check.mjs  # expect 0","errors":0 if rc=="0" else 1}))
+PY
+exit 0

← a48f912 TK-10895: post-verify must read the STOREFRONT, not the Admi  ·  back to Designerwallcoverings  ·  TK-10933: sniff image type from magic bytes instead of trust 5c48cd7 →