Creative ideas + design notes
Commits with substantial prose (≥120 chars) — the rationale behind each move.
f46edb3 · 2026-09-22 · Fix: replace hardcoded-path shim with portable resolution (TK-11786)
The inventory-stamp-guard.mjs shim now resolves via DW_SHARED_GUARDS env or
home-dir fallback instead of hardcoded /Users/macstudio3 path. This enables
the guard to work on Kamatera (/root), Mac1, and any other machine.
ESM consumers (import) work correctly. CJS consumers (require) fail safely
with ERR_REQUIRE_ASYNC_MODULE, preventing silent bad defaults on inventory
stamps. CJS call sites should use dynamic import() instead.
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
68b2721 · 2026-09-10 · guard TK-11357 Fix D: rebel-walls push.js — refuse to MINT a $0 mural, and never CONTINUE it
SCHEDULED: reached from run-cadence-hourly.sh:117 via cadence-daily-step.sh behind an $RW_MARK
marker, i.e. effectively daily. Behind a multi-hop .sh chain, which is why plist greps missed it.
PRE-EXISTING GUARD STATE (whole path read, not assumed): NO price gate anywhere. fetchRows()
filters only on `(shopify_product_id IS NULL OR = '') AND dedup_skip IS NOT TRUE`; there is no
price_retail condition in the SQL and none in JS. buildInput() then prices the main mural variant
`String(row.price_retail)` with inventoryPolicy CONTINUE and tracked:true.
Why CONTINUE is the dangerous part: CONTINUE (oversell) makes a variant orderable at ANY quantity
INCLUDING ZERO. So a $0 variant minted here is orderable AND the established qty->0 stopgap for
this defect class is a NO-OP against it. Guarding only the quantity would have been decorative.
THREE fixes:
(a) pushRow() refuses to create when !(Number(row.price_retail) > 0). Safe + idempotent: this is
a create-only MINTING path (hard-coded VENDOR 'Rebel Walls'), it cannot revert an existing
cohort, and the row keeps shopify_product_id NULL so it is re-picked when a real price lands.
The caller reports it as HELD, not FAILED, and logs it to the progress log.
(b) inventoryPolicy comes from the guard: CONTINUE only for a genuinely priced mural, 'deny'
otherwise (uppercased for the productSet enum). Priced murals keep CONTINUE unchanged.
(c) publishAndStock()'s flat QTY_2026 stamp is guarded too. HONEST NOTE: that path is currently
unreachable for new rows — buildInput() mints DRAFT/ARCHIVED and the call is gated on
status === 'ACTIVE' despite the comment above it claiming ACTIVE. Guarded anyway so flipping
that decision back cannot silently reopen the hole. The mutation already returned each
variant's price; it now returns `title` too, for guard accuracy.
Shared guard vendored to scripts/lib/. Proven by the Designer-Wallcoverings harness:
4/4 required + 3/3 regression + P8 policy 2/2 ($0->deny, priced->continue).
SOURCE-ONLY: nothing run, no Shopify write. Reversible: git revert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
359cbbf · 2026-09-04 · TK-10405 full-fix EXECUTED: reordered Mural(per m²)->pos1 + Sample->pos2, DELETED the 2 Default-Title orphans on dwrw-76016 + dwrw-76264
Supersedes the A' mitigation. End state verified live (Admin API + storefront):
both PDPs now read offers[0]=$117.47, Default-Title absent. Reversible via
scripts/TK-10405-fullfix-undo.mjs (recreates orphan from captured pre-state).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8debf6b · 2026-09-04 · TK-11248 EXECUTED: Aries title fixed live; guard held 2 position-1 RW products; 10 deletes done concurrently
- TK-11238: productUpdate fired -> 'Aries - Akoya Type II Vinyl Wallcovering | Hollywood Wallcoverings' (verified live ACTIVE, ledgered, undo=TK-11238-restore.json).
- TK-10405: hardened executor with DTD-verdict guard (position-1/default-served + dw_unified mirror id-reference). Guard correctly HELD 2 position-1 products (6679729078323 $80.48 anomaly, 6679739629619 A Priori) for A' follow-up. The other 10 (position-3) were deleted by a concurrent batch agent; this run detected drift (dt=0) and refused to double-write. Live verify: 10/10 deleted-clean (Mural+Sample), 2/2 held intact, 0 anomalies.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HzpfrKkjFqGRUrMEQGhFFW
ff9dbfb · 2026-09-04 · TK-11248 action G: read-only revalidation confirms 6 cleared descriptions already live (no write needed)
All 6 settlement-CLEARED Rebel Walls murals carry authorized descriptionHtml,
all DRAFT, 0 activated. 4 from TK-11192 (9/3); 2 refreshed in the 9/4 18:26 wave
(word-identical, curly-vs-straight apostrophe only). Holds intact: R20805 blocked,
5 counsel untouched (len=0). Stopped on the (benign) drift per instruction — no
customer-facing write fired.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFJimFhUJowuXnXtjNTLEC
3111ca5 · 2026-09-04 · TK-11248 prep: revalidate + gated executor + rollback for TK-11238 (Aries title) + TK-10405 (12 RW Default-Title deletes)
Read-only revalidation confirms both live targets exactly match characterization
(Aries ACTIVE, old title verbatim; 12 products each 3 variants -> 1 Default-Title
+ distinct Mural + Sample survivors). Executor is DRY-RUN by default and hard-gated:
--apply requires --approval=TK-11248 + a sentinel token file written only after
Steve's explicit approval on TK-11248 (proven: premature --apply exits 3, no write).
Restore maps written for one-command rollback. NO Shopify writes fired.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HzpfrKkjFqGRUrMEQGhFFW
12856c3 · 2026-09-03 · TK-10029: runnable Scope-B rollback (reverse 1220 relabels from durable map)
Reads the committed B rollback map and renames each touched option value from
'Mural (per m²)' back to its recorded old_value. Dry-run default; --apply reverts.
Idempotent; never touches the 280 held roll/bolt or originally-canonical products.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c93997d · 2026-09-03 · TK-10029: retry gql() on transient Shopify upstream errors (backoff)
A non-JSON 'upstream connect error' gateway blip was crashing long --apply
runs mid-flight (JSON.parse throw, no retry). Split into gqlOnce + a 6-attempt
exponential-backoff gql wrapper. Transport-only; rename set/hold logic unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dd06ad8 · 2026-09-03 · TK-10029: durable scope-B rollback map (1220 rows) + generator
Captures old->new for exactly the 1220 per-m² FIX rows the
--apply --hold-rollbolt run touches (1144 Sold Per Square Meter +
76 Complete Mural, zero held roll/bolt). Deterministic non-destructive
reverse documented in the map.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZBUFotX5YXv7nUtTtAa2r
72b8edd · 2026-09-03 · TK-10029: one-command rollback executor (reads durable ledger, reverts canonical->old_value)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VA9ekkiMa6vAC2RaDP11zU
789f983 · 2026-09-03 · TK-10029: fresh complete pre-apply rollback ledger (1500 renames + 12 orphans, current live state)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VA9ekkiMa6vAC2RaDP11zU
080e96f · 2026-09-03 · TK-10029: add --hold-rollbolt flag (scope B) to relabel-units.js
Subtractive flag that excises the roll/bolt unit-of-sale cohort
(roll / single roll / sold per roll / sold per bolt (20.5in x 33ft))
from the wrong-label set entirely, so those variants are neither FIXed
nor REVIEWed. Scope-A behavior unchanged when the flag is absent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZBUFotX5YXv7nUtTtAa2r
be208a1 · 2026-08-10 · TK-10029: retarget relabel to canonical 'Mural (per m²)' (DTD Option A, 7/7)
- CORRECT_LABEL now 'Mural (per m²)' — the label the live importer push.js already mints
- converge legacy roll/bolt/complete-mural + interim 'Sold Per Square Meter' + mojibake onto it
- robust matcher isWrongMuralLabel() catches corrupted 'Mural (per m<?>)'
- NON-DESTRUCTIVE: renames only, never deletes a variant, never creates a duplicate canonical
- collision/orphan cases (canonical already present + Default Title) FLAGGED for manual review, not auto-modified
- dry-run: 1467 renames, 0 deletes, 12 review; still --apply-gated (live customer-facing write)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
09027cf · 2026-07-30 · relabel-units: skip sample products from Roll→SqMeter relabel
84 'Memo Sample' products were wrongly included in the fix set because
'Default Title' matched WRONG_MURAL_LABELS. Added isSampleProduct() guard
that checks title for 'memo sample' / ' sample' / ends-with 'sample'.
Dry-run now shows 370 true mural products needing relabel (was 454).
Co-author: steve@designerwallcoverings.com
e6677f9 · 2026-07-08 · GMC re-gate: exclude Google & YouTube publication (29646651457) from push + activate
Both run on a daily cron and re-leaked the $4.25 sample price to the Google channel.
Filter Google out of loadPublications() in each. Google is fed by the controlled TSV
feed only. Inline + reversible.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
a3c8752 · 2026-06-30 · Add RW cadence daily step — 5 murals/day, budget-coordinated, DRY by default
Steve 2026-06-30: '5 new SKUs a day, focusing on murals' (RW is 100% murals). Budget-coordinated
via the shared variant ledger (take 'rebel' N) so it never races the hourly uploader. DRY by default;
--commit creates live. NOTE: push.js dry flag is --dry-run (an initial --dry typo created 5 live
products DWRW-361150..361154 = today's authorized batch; flag corrected, true-dry now verified 0 writes).
1e70258 · 2026-06-09 · dedup-guard push: skip 759 patterns already live under older Rebel Walls SKUs (DTD verdict A)
- dedup-flag.js: tightened pattern+exact-color match vs older live cohort (DWRW-72201..451820);
flags 759 true dups, leaves 2,874 net-new pushable via reversible dedup_skip column
- push.js fetchRows: AND dedup_skip IS NOT TRUE (null-safe) so resume pushes only net-new
- verify-live.js / reconcile-from-shopify.js: read-only Shopify count + sku->id helpers
c54afd5 · 2026-06-04 · Rebel Walls: bake live-on-create (ACTIVE + all channels + inventory 2026) into pusher; add activation pass for already-pushed products
push.js now creates non-discontinued products as ACTIVE with tracked variants,
publishes to all 13 publications, and sets available=2026 on both variants after
each productSet. New activate.js does the same for the ~500 already-pushed DRAFT
products (idempotent, resumable via activated_at checkpoint). _shop.js shared
GraphQL/psql helper with 429/throttle backoff.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>