4280d5a2026-05-18sp: set_variants.js — flatten 72 products to 2 variants (Roll (with specs) / Sample), added missing sample to Dot All Over Pink; Boxwood Stripe skipped (multi-colorway)
62e1af12026-05-18sp: enrich_metafields v2 — fix dwc.content type to multi_line; 72/73 enriched with item_width/roll_size/repeats/match/country
6b8b0b82026-05-18sp: ran private_label — deleted 52 dupes, renumbered 73 keepers to DWPH-10001 (Saybrook House)
c283bfa2026-05-18sp: enrich_metafields.js — push DW spec metafields (item_width, roll_size, repeats, match, country) from PDP crawl, joined to live store by title
2570b302026-05-11tick 7: SP viewer × wallco PD bridge — 'PD inspirations →' button on every SP card opens modal with 3 nearest Lab-color PD matches; image proxy /pd-img/<source>/<file> reads from wallco-ai/data/images
134a4842026-05-11SP color v2: center-crop 80% before palette extraction — near-white dominants 7→4 · cross-match cleanup — Appleton Beige #e4d9c6 → Met 'Seaman's Wife's Reckoning' #e7dac7 (Lab dist 0.91, much improved over v1)
280a3a32026-05-11tick 5: Shopify still 0 · cross-match SP × PD in Lab space (219 matches, 73 × 3) · tileability score (11 seamless / 38 near / 24 photo)
1c085992026-05-11tick 4: Shopify still 0 SP products · recorded 10 Backend-C research link-outs (google+etsy) for 5 SKUs across price tiers; ToS-clean, no scrape
0956a192026-05-11schedule Shopify push for Wed 2am PT via launchd com.steve.sister-parish-push (idempotent, self-unloads at 73/73)
81602d32026-05-11tick 3: normalize curly quotes in specs · extract dominant_hex + 5-color palette (73/73) · wire color-wheel/light-dark sorts + color dot in viewer
17c85262026-05-11viewer: sister parish browse UI on :9790 (sort + density slider, pm2 supervised)
The inventory-stamp-guard.mjs shim now resolves via DW_SHARED_GUARDS env or
home-dir fallback instead of relative path. This enables the guard to work
on Kamatera (/root), Mac1, and any other machine regardless of repo location.
ESM consumers (import) work correctly. CJS consumers (require) fail safely
with ERR_REQUIRE_ASYNC_MODULE, preventing silent bad defaults on inventory
stamps.
Original vendored copy preserved as inventory-stamp-guard.mjs.pre-shared-lift.
The $0-orderable guard (TK-11357) now has ONE source of truth at
~/Projects/_shared/dw-guards/.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WoD95uATtwJXUZvQ7PNPsB
b126d74 · 2026-09-22 · Make SP guard shim path portable and skip $0-orderable variants in the inventory re-stamper
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DP24DdLpG6PHXgmjr47TVb
4322d1d · 2026-09-10 · governance(TK-11370): make live-by-default Shopify writers dry-run by default
Flip `DRY = argv.includes('--dry')` -> `DRY = !argv.includes('--apply')` so a
zero-argument run no longer fires customer-facing Shopify writes.
Backward compatible: `--dry` still means dry; `--apply` now required to write.
Only zero-arg invocations change behaviour, and every candidate was checked
against its launchd/cron/pm2/wrapper invocation sites first (4 scripts that a
cadence job runs flagless were EXCLUDED so this cannot silently disable them).
Verified: node --check/py_compile 87/87 with a positive control proving the
checker rejects an injected fault; argv truth-table negative test 5/5.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L53y4oP2itY3qeJ8WQgMzc
3e2c3fc · 2026-09-10 · guard TK-11357 Fix D: sister-parish push_shopify.js — don't mint/stock a $0 variant as CONTINUE
Found by widening the writer enumeration to REST inventory_levels endpoints (my first sweep was
GraphQL-mutation-only, the same blind spot this lineage has hit before).
PRE-EXISTING GUARD STATE: none. buildProductPayload() prices every variant `v.dw_retail.toFixed(2)`
straight from the input feed with no price check, sets inventory_policy 'continue', and the caller
then stamps a flat 2026 on every created variant via /inventory_levels/set.json. A 0/absent
vendor_retail (dw_retail = vendor_retail / 0.85) therefore mints a $0 variant that is CONTINUE --
orderable at ANY quantity INCLUDING ZERO, so the qty->0 remedy cannot fix it.
FIX: inventory_policy comes from the guard ('deny' when the safe quantity is 0, caller's 'continue'
otherwise), and the stock loop stamps the guard's per-variant safe quantity computed from the price
Shopify actually landed -- skipping $0 variants with a logged refusal instead of stocking them.
Priced variants keep 'continue' + 2026 exactly as before (Steve's 2026-06-20 rule intact).
Shared guard vendored to scripts/lib/. Proven: 4/4 + 3/3 + P8 policy 2/2.
SOURCE-ONLY. Reversible: git revert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
f1ec46d · 2026-05-19 · broaden .gitignore to exclude .bak/.pre-* snapshot files and .next/
Fleet-wide hygiene rule — snapshot files must never land in git so the
404-guard middleware never has anything stale to refuse. Mirrors the
.gitignore baseline used across the rest of the DW sister sites.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code-health fleet sweep pass: closes the reverse-tabnabbing vector on
the two external target=_blank anchors (vendor source PDP, PD-corpus
source link in the inspirations modal). Also adds an Express middleware
404-guard so .bak / .bak.* / .pre-* / .pre.* snapshot paths can never
be served via static even if one slips into the tree.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
b825dc7 · 2026-05-12 · sp: preflight.sh — single-shot health read for YOLO ticks
Replaces the curl+grep+dry-run dance future ticks were doing each time
with one O(1) call. Reports: live SP count (status=any), plist installed
& loaded, dry-run would-create count. Exit code: 0 GREEN, 1 mixed, 2 env fail.
Uses the same node-path fallback chain as scheduled_push.sh (homebrew →
/usr/local → which node) so it works on both Mac1 (homebrew) and Mac2
(/usr/local/bin/node).
File tree
36 files tracked. Click any to browse the source at HEAD.