Dw Unbuyable Recovery Pilot

repo: ~/Projects/dw-unbuyable-recovery-pilot · 70 commits · 0 in last 24h, 2 in last 7d · █

Search the build

70 commits indexed

  1. 9f30b37 2026-09-25 TK-11042: repair.mjs writes a reversible-ledger row (with exact undo) after any live run
  2. a9bc366 2026-09-25 auto-data-snapshot: 2026-09-25T11:23:40 (1 data files) — tk11042-quote-tag/data/plan.json
  3. 31a2a78 2026-09-17 auto-data-snapshot: 2026-09-17T19:01:39 (1 data files) — tk11042-quote-tag/data/plan.json
  4. e8277ec 2026-09-15 TK-11041 Innovations (Phillipe Romano) go-live: 39 repriced + made buyable + published; 18 width backfilled; Whistler dropped
  5. d4fae99 2026-09-15 TK-11041: Innovations reprice — LIST basis, decimal-safe /0.65/0.85 markup, Skylark by-roll, current 2026-09-15 terms + auto-exclude disco rule
  6. 18ec8a3 2026-09-14 TK-11252 fork-1: set 8 Hollywood/Versa dead-ends to DRAFT (Steve Option B), re-verify + undo scripts
  7. 0c20d0d 2026-09-14 auto-data-snapshot: 2026-09-14T00:22:42 (1 data files) — tk11252-hollywood/unbuyable-live.json
  8. 9deb622 2026-09-13 TK-11252: complete live re-measure — 27 unbuyable, only 8 are real dead ends
  9. 995b159 2026-09-12 TK-11041: stage shopify_product_id backfill dry-run (39/39 clean 1:1 match, gated write + undo)
  10. a561f20 2026-09-12 TK-11041: disambiguate the two reprice tools before the wrong one gets run
  11. 36062e5 2026-09-12 TK-11041: stage-reprice — 7 arriving numbers to a staged 39-SKU proposal in one command
  12. 330f399 2026-09-12 TK-11041: dry-run reprice plan for 39 live PR-Innovations items (parameterized on portal LIST)
  13. 334ea0d 2026-09-12 TK-11041: restore point before merging the 7-pattern price ask (merge done, NOT sent)
  14. 56bff11 2026-09-12 TK-11041: a 7-pattern price ask that could remove the portal blocker
  15. 9005ea5 2026-09-12 TK-11041: email price-list reconciliation for the 39 Innovations SKUs (read-only)
  16. 0e76f2d 2026-09-12 TK-11041: make the auth-proof failure self-diagnosing instead of silently fatal
  17. ecd3849 2026-09-11 TK-11041: the portal prices live per-colorway, not on the pattern page — add opt-in --deep
  18. ba3e4f9 2026-09-11 TK-11041: one-line discount+basis question, ready to merge into the unsent Whistler draft
  19. b756810 2026-09-11 TK-11041: settle Innovations (acct 58315) discount conflict at 10% via vendor Sales Order O-111475 + Currier correction + DB corroboration
  20. 00cbb25 2026-09-11 TK-11041: portal pull must capture WHICH price it read, not just the number
  21. 0e2141a 2026-09-11 TK-11041: portal-pull script written + self-tested (7/7), waiting only on the credential paste
  22. 6ca521c 2026-09-11 TK-11041: portal-pull runbook + second draft restore point (B done, A staged)
  23. 02a2486 2026-09-11 TK-11041: merge the Whistler/closeout paragraph into the vendor draft (approved; NOT sent)
  24. 02a570d 2026-09-10 Verify TK-11415 triage and resolve stale approval blocker
  25. f0fd04b 2026-09-10 auto-data-snapshot: 2026-09-10T18:07:04 (4 data files) — verification/TK-11415/README.md verification/TK-11415/client-tests.tap verification/TK-11415/dtd-verdict.md verification/TK-11415/e2e-proof.json
  26. b85e3f9 2026-09-10 snapshot before TK-11415 verification evidence
  27. 109edc2 2026-09-10 TK-11041: the exact paragraph the (new, clean) Innovations draft still needs
  28. 8fcad7e 2026-09-10 TK-11041: recover the full Whistler spec block from the 2025 Wayback snapshot
  29. 850e06a 2026-09-10 TK-11041: final amended vendor letter + two defects found in the live draft
  30. d609fc6 2026-09-10 auto-data-snapshot: 2026-09-10T08:48:14 (1 data files) — tk11042-quote-tag/data/plan.json
  31. ef59d38 2026-09-10 TK-11042: quote-CTA tag-normalization plan + gated executor + rollback
  32. cf73947 2026-09-10 TK-11041: Innovations re-scrape recovers 51/51 identities (0 mismatches); WHL=Whistler discontinued
  33. b5b3182 2026-09-04 auto-data-snapshot: 2026-09-04T14:52:10 (1 data files) — tk11252-hollywood/created-all.json
  34. cf93e58 2026-09-04 TK-11252 Tier 2: make 7 more unbuyable Hollywood products buyable
  35. dc82409 2026-09-04 auto-data-snapshot: 2026-09-04T12:10:54 (1 data files) — tk11252-hollywood/targets-tier2.tsv
  36. 109df2d 2026-09-04 TK-11252: add sellable Single Roll variants to 18 unbuyable Hollywood products
  37. 1313e2e 2026-09-02 Correct TK-11133 proof timestamp
  38. 50bf192 2026-09-02 Extend TK-11133 boundary proof
  39. e2d53f7 2026-09-02 Fail closed on Momentum search errors
  40. c3a2933 2026-09-02 Record E2E proof for credential containment
  41. e31ba08 2026-09-02 Remove hardcoded Meilisearch credential from Momentum audit
  42. defc1cb 2026-09-02 TK-10978: Rebel Walls RS-orphan archive complete — 455/455 (215 batch-2 + 240 batch-1), 0 failed
  43. 3c3e915 2026-09-02 auto-data-snapshot: 2026-09-02T15:21:07 (1 data files) — tk10978-rebelwalls/data/archive-prestate.jsonl
  44. 8085c23 2026-09-02 TK-11041: Innovations 51-cohort feed-first reconciliation — 0/51 locally recoverable + provenance guard
  45. e88e5d3 2026-09-02 TK-11124: add per-yard $359 sellable variant to 18 sample-only DWVE Velvet Walls (Phillipe Romano) — now buyable, samples intact
  46. 1af16b4 2026-09-02 auto-data-snapshot: 2026-09-02T12:46:36 (1 data files) — tk10978-rebelwalls/data/archive-prestate.jsonl
  47. fe0b011 2026-09-02 TK-10978 RebelWalls: one-command archive rollback (restore prior status from prestate)
  48. cdd5b64 2026-09-02 auto-data-snapshot: 2026-09-02T12:07:47 (8 data files) — tk10978-rebelwalls/data/archive-454-duplicates.csv tk10978-rebelwalls/data/archive-prestate.jsonl tk10978-rebelwalls/data/archive-skips.json tk10978-rebelwalls/data/investigate-39-no-twin.csv tk10978-rebelwalls/data/rescrape-39-summary.json
  49. 4101e6d 2026-09-02 TK-10978 RebelWalls: focused 39-no-twin re-scrape — 31/39 vendor-404, 0 recoverable -> defer
  50. ae3731d 2026-09-02 TK-10978 RebelWalls: read-only recon + reversible archive executor (scope-inversion evidence; nothing fired)
  51. 548c7af 2026-09-02 TK-10978 pre-approval audit: Coordonné 136 dry-run broken (dirty mfr_sku, join=0, content-match=0); Donghia moot (2 left); RW=280 only recoverable cohort. Read-only, no writes
  52. e1bec63 2026-09-02 TK-10978 Rebel Walls RW-494 CORRECTED dry-run: RS-series absent from catalog (not identity join); content-match yields 280 safe / 10 ambiguous / 204 need re-scrape; pilot-gated, no writes
  53. 9a9548c 2026-08-31 TK-10978 PR-Momentum recovery complete: 547 acted + 20 pilot = 567 buyable (Sold Per Yard @ hw_price), 0 fail, 567 ledgered
  54. 7e09367 2026-08-31 TK-10978 PR-Momentum add-yard recovery tooling: 567 clean (momentum_colorways hw_price per-yard join), dry-run 20/0/0; awaiting explicit pilot consent
  55. 6f992ff 2026-08-31 auto-data-snapshot: 2026-08-31T11:17:15 (4 data files) — tk10978-coordonne/data/prestate.jsonl tk10978-coordonne/data/skips.json tk10978-donghia/data/prestate.jsonl tk10978-donghia/data/skips.json
  56. e430ce2 2026-08-31 TK-10978 Coordonné add-roll recovery tooling: 136 clean (mfr_sku join, sell at MSRP=price_retail, empirically matches live $169), dry-run
  57. a12fffc 2026-08-31 TK-10978 Donghia add-roll recovery tooling: plan builder (152 clean, mfr_sku identity join, trade/0.65/0.85) + reused executor; dry-run 152/0/0 clean live-verified
  58. c686975 2026-08-30 chore: lint + light refactor (session close)
  59. 5a24ba1 2026-08-30 TK-10978: VERIFY correction — Track 0 quote-only 'free prize' is a phantom (5271/5474 already correctly quote-tagged; PF is do_not_price=false; real gap ~203)
  60. 47d9d7f 2026-08-30 auto-data-snapshot: 2026-08-30T23:23:51 (1 data files) — data/cost-sourcing-feasibility.md
  61. 7c8e401 2026-08-30 TK-10978 Scalamandre add-roll recovery complete: 124 acted + 20 skip + 0 fail, all buyable (inventory_policy=continue), sample $4.25 kept, 144 ledgered w/ undo
  62. b379051 2026-08-30 TK-10978 Scalamandre pilot: 20 add-roll live+verified buyable; caught+fixed deny/qty0 unbuyable defect, executor now creates continue
  63. 039b070 2026-08-30 TK-10978 Scalamandre add-roll: plan builder (144 clean, 6 conflicts excluded) + repair + rollback tooling, dry-run pilot clean
  64. 8408ecf 2026-08-30 auto-data-snapshot: 2026-08-30T17:49:20 (1 data files) — data/scalamandre-exact-recovery.csv
  65. c815a74 2026-08-30 TK-10978: Scalamandre content-match reconciliation — 133 recoverable (dry-run)
  66. 4f00877 2026-08-30 TK-10875: next-cohort scan — WG was the only bounded recoverable cohort
  67. 6ee445d 2026-08-30 TK-10875: regenerate artifacts + broaden live RR-defect verification (16 products)
  68. 8fb27f0 2026-08-30 TK-10875: EMPIRICAL correction — WG 224 are RR-defect, recoverable via restructure
  69. af9c3e5 2026-08-30 TK-10875: harden pilot after contrarian + Kimi red-team — stale-flag guard
  70. b634b70 2026-08-30 TK-10875: unbuyable classification + Wolf Gordon dry-run recovery pilot (read-only)

Authors

Agents used

  • none detected

Skills used

  • /claude19
  • /code19
  • /data14
  • /plan3
  • /item3
  • /closeout3
  • /archive-prestate3
  • /login2
  • /prestate2
  • /skips2
  • /unbuyable-live1
  • /list1
  • /trade1
  • /innov-price1
  • /costine1
  • /customer1
  • /account1
  • /draft-r-5469570474427181957-1
  • /client-tests1
  • /dtd-verdict1
  • /e2e-proof1
  • /undo1
  • /created-all1
  • /targets-tier21
  • /price1
  • /provenance1
  • /archive-454-duplicates1
  • /archive-skips1
  • /investigate-39-no-twin1
  • /rescrape-39-summary1

Creative ideas + design notes

Commits with substantial prose (≥120 chars) — the rationale behind each move.

9f30b37 · 2026-09-25 · TK-11042: repair.mjs writes a reversible-ledger row (with exact undo) after any live run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01784gJRp1Re5s8HHMK5a86e
e8277ec · 2026-09-15 · TK-11041 Innovations (Phillipe Romano) go-live: 39 repriced + made buyable + published; 18 width backfilled; Whistler dropped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EHBuQZQtbrc6yeNXFZfNLT
9deb622 · 2026-09-13 · TK-11252: complete live re-measure — 27 unbuyable, only 8 are real dead ends
Adds enumerate-unbuyable.mjs (complete 72-page GraphQL walk, cross-checked
against an independent REST count so a truncated walk cannot pass as complete;
keys on 'no NON-sample variant' rather than option1='Sample', which the original
53-scan was blind to for 3 'Default Title' members), tags-probe.mjs, and
verify-rendered.sh (fetches all 27 live PDPs following redirects and asserts
whether a customer actually gets a quote CTA).

Finding: 19 of 27 render a working 'Request a Quote' CTA; 8 render nothing.
The 8 are all Versa Designed Surfaces (7 Aura A166-*, 1 Kibesillah A125).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmWgsxVCLex9jdmmyzDTux
a561f20 · 2026-09-12 · TK-11041: disambiguate the two reprice tools before the wrong one gets run
Two sessions independently built a reprice planner here hours apart. Same verified
chain, but tk11041-dryrun-reprice-plan.mjs hardcodes basis=LIST (right for the portal,
which does show list). The draft I merged asks Hektor for NET. Feed a net price to the
LIST tool and it discounts an already-discounted number — ~10% under on 39
customer-facing products, silently, because the arithmetic succeeds.

The email route makes that the LIKELY pairing, not an exotic one. This names which
tool goes with which source, and records the Skylark MTO finding neither other path
surfaces.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
36062e5 · 2026-09-12 · TK-11041: stage-reprice — 7 arriving numbers to a staged 39-SKU proposal in one command
Formula VERIFIED, not assumed: across all 57 innovations_catalog rows carrying list,
trade and our_price together, trade/list = 0.9000 and our_price/trade = 1.8100
(= 1/0.65/0.85) to 4dp. So list x0.90 = net, net x1.81 = retail.

--basis is REQUIRED with no default. The vendor's own PDFs print LIST under a column
headed 'Net Price', so the label on the page cannot be trusted — a human says which
number it is. Defaulting either way is a silent 10% error into customer-facing retail.

Ships 12 self-tests, the meaningful ones negative: missing basis throws, unknown basis
throws, a $0 or negative price throws rather than becoming $0 retail, and a sanity band
against the Fall-2025 trend catches a quote that is 90% low (a wrong unit) instead of
pricing it. Unpriced SKUs are named, never silently dropped.

Found while parsing the terms: Skylark (SKL-001..004) is MADE TO ORDER — no stock, no
cut-fee code, MTO warehouse. My first parser silently dropped those 4 because its regex
expected 'Fee X'; fixed, and the tool now warns before they are made sellable.

Writes nothing to dw_unified or Shopify.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
330f399 · 2026-09-12 · TK-11041: dry-run reprice plan for 39 live PR-Innovations items (parameterized on portal LIST)
39 items / 7 pattern pages, 0 priced. Wires net_cost=LIST*0.90 -> retail=net/0.65/0.85,
rounded Math.round(x*100)/100 (matches stage-innov-reprice.mjs / cadence-import).
READ-ONLY: no dw_unified write, no Shopify write. Gated write fires only after portal
creds (acct 58315) land + per-pattern LIST verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzajqT19xhuZnfZBBgLDr3
334ea0d · 2026-09-12 · TK-11041: restore point before merging the 7-pattern price ask (merge done, NOT sent)
Third restore point on this draft, so every version is one call from recovery:
original letter, post-Whistler-merge, and now pre-price-ask.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
56bff11 · 2026-09-12 · TK-11041: a 7-pattern price ask that could remove the portal blocker
The email price lists showed Innovations prices at PATTERN level, so the 39 SKUs
need 7 numbers, not 39 — small enough to be answerable in one reply. A blanket
'send your price list' was refused twice in 2026, but a narrow named ask has
precedent in this mailbox. The Whistler email is already going to Hektor; adding
this paragraph costs nothing and, if answered, makes the credential paste unnecessary.

Not merged — the draft is agent_composed=false and Steve already chose send-as-is
before this finding existed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9005ea5 · 2026-09-12 · TK-11041: email price-list reconciliation for the 39 Innovations SKUs (read-only)
Checked the two named Gmail attachments (Oct-2025 "Fall 2025 Pricelist", Jan-2025
"Pricelist-US") plus widened search across info@ for fresher lists. Both PDFs cover
all 7 target patterns (39/39 SKUs, priced at pattern level) but the newest is 11
months stale (2025-10-01) and cross-pattern trend evidence proves it has since been
superseded. Innovations has twice (2026-06-17, 2026-09-02) refused a fresh price-list
request by email and redirected to the login-only portal, and DW's own reply
yesterday (2026-09-11) already accepted that. Verdict: PARTIALLY -- coverage is
complete but not current; portal remains the only channel with a live number.
No DB write, no Shopify write, no email sent.
0e76f2d · 2026-09-12 · TK-11041: make the auth-proof failure self-diagnosing instead of silently fatal
Nobody here has seen innovationsusa.com logged in. The June 2026 crawl saved only
cookies — no localStorage, no captured markup — so the 'Sign Out / My Account'
markers the auth proof keys off are an INFORMED GUESS. If they are wrong, every
page reports SESSION_FAILURE and the run looks exactly like bad credentials. That
ambiguity is the actual hazard, not the guess.

On auth-proof failure the script now dumps the identity-like lines the page really
carries, says plainly that this may be the marker guess rather than the login, and
prints the one-line re-run with INNOVATIONS_AUTH_POSITIVE set. Markers are env-
overridable so a fix needs no code edit. The diagnostic is also written into the
staged JSON.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ecd3849 · 2026-09-11 · TK-11041: the portal prices live per-colorway, not on the pattern page — add opt-in --deep
Found by chasing the discount forensics' own lead: DW already ran an AUTHENTICATED
Innovations crawl on 2026-06-17/18 (181 rows in innovations_catalog, price_source
'innovationsusa authed crawl 2026-06-18; list x0.90; per-yd'). Its crawler
(hollywood-import/innov-price.mjs) fetched /item/<pattern>/<sku> — per-COLORWAY URLs.
My script fetched only the 7 pattern pages, so a clean run could have returned
7x NOT_MEASURED and read as 'the vendor has no prices'.

--deep is opt-in, not a silent fallback, because robots Disallows /item/*/*. It prints
the conflict, throttles harder, and only fires for items whose pattern page had no price.
Default stays robots-clean.

Also settles the net-vs-list question with a hard artifact rather than the label heuristic:
the June crawl stored price_retail=134.95 (portal LIST) and price_trade=121.46 (list x 0.90),
so the portal shows LIST and the 10% applies on top.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGo6pAQho6w9xgqghMgNKh
ba3e4f9 · 2026-09-11 · TK-11041: one-line discount+basis question, ready to merge into the unsent Whistler draft
There is already an unsent email to the one person who can end the 10%-vs-20% argument.
Adding one sentence settles it for zero extra outbound, and also asks the net-vs-list
question the portal pull structurally cannot answer from a page that just prints a number.
Offered as a copy-paste block, NOT merged: the draft is agent_composed=false, so the next
action on it is Steve clicking send.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGo6pAQho6w9xgqghMgNKh
b756810 · 2026-09-11 · TK-11041: settle Innovations (acct 58315) discount conflict at 10% via vendor Sales Order O-111475 + Currier correction + DB corroboration
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGo6pAQho6w9xgqghMgNKh
00cbb25 · 2026-09-11 · TK-11041: portal pull must capture WHICH price it read, not just the number
A logged-in trade portal may show our NET price or the LIST price. Capturing the
number without the basis is the same error class as the 10%-vs-20% discount conflict
already blocking this ticket: the number is real, it is just a number about a
different thing. If the portal shows LIST the discount applies on top; if NET it
does not, and applying the wrong one is a silent cost-basis error that reaches
customers through cost/0.65/0.85.

extractPrice now reads the label around the number and records basis NET/LIST/UNKNOWN
plus 120 chars of verbatim context so a human adjudicates in one glance. UNKNOWN is a
legitimate answer and is never guessed into NET. Four new negative tests, 11/11 PASS.
Output carries basis_unknown and the innovations_catalog target columns.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGo6pAQho6w9xgqghMgNKh
0e2141a · 2026-09-11 · TK-11041: portal-pull script written + self-tested (7/7), waiting only on the credential paste
Converts the runbook from prose into a one-command run. Ships with negative tests:
the real captured logged-out /item/costine page must classify SESSION_FAILURE and yield
no price, and a $0.00 token must be rejected — a positive-only test on a detector
proves nothing. Credential-absent run exits 2 without opening a session ($0).

Corrects the runbook: Browserbase solves the reCAPTCHA natively (solveCaptchas:true),
no separate 2captcha call needed. 39 live items resolve to 7 pattern pages, one session.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGo6pAQho6w9xgqghMgNKh
6ca521c · 2026-09-11 · TK-11041: portal-pull runbook + second draft restore point (B done, A staged)
Steve chose A+B.

B (done): draft r-5469570474427181957 reduced to a short Whistler-only
follow-up, subject 'Re: Current trade price list request', opening by
acknowledging Hektor's Sep-2 answer so it does not read as ignoring his reply.
Verified: no provenance banner, no private-label names, labelIds=[DRAFT],
NOT SENT. Two restore points now exist (pre-merge, post-merge).

A (staged): the vendor told us pricing lives behind our own website login, so
the portal is the only path to net price. Registered INNOVATIONS_USERNAME /
_PASSWORD / _LOGIN_URL in secrets routes.json on the DEDAR_*/OSBORNE_*
trade-portal precedent, and verified the endpoint read-only: /login is 200
(stock Magento /customer/account/login/ 404s) and carries reCAPTCHA - so the
pull needs browserbase + 2captcha, not curl, with a cached session so we solve
one captcha rather than 39. Runbook includes the fail-loud rule: a logged-out
shell is a session failure, never a $0 price.

Also records the open discount conflict - registry 10% vs 'Net Less 20%' on
every sample request - which must be settled before any retail is computed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FXH75ac8BT9AFuzjiypPjU
02a2486 · 2026-09-11 · TK-11041: merge the Whistler/closeout paragraph into the vendor draft (approved; NOT sent)
Steve approved the merge directly. Captured a verbatim pre-edit restore point
first (undo/draft-r-5469570474427181957-PRESTATE.json) so a bad edit is a
one-call revert. Verified after the write: paragraph in the right position, no
'From job: node' provenance banner injected, no DW or private-label names,
signature intact, one draft (updated in place, no duplicate).

Draft remains UNSENT - awaiting_owner_send. The vendor has not been contacted,
so the ticket stays blocked on Steve's send, not on the vendor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FXH75ac8BT9AFuzjiypPjU
109edc2 · 2026-09-10 · TK-11041: the exact paragraph the (new, clean) Innovations draft still needs
The Sep-4 agent draft is gone; a clean human draft r-5469570474427181957 replaced
it today at 11:58 with the provenance banner and the bare signature both fixed.
It is still missing the one thing DTD verdict B required - naming Whistler and
asking about closeout - without which the vendor's reply cannot answer Decision 2.
Paragraph supplied as a copy-paste block (prose + HTML) rather than written into
the draft: the next action on that object is Steve clicking send, so an
agent-rewritten letter would read as unwitting approval.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FXH75ac8BT9AFuzjiypPjU
8fcad7e · 2026-09-10 · TK-11041: recover the full Whistler spec block from the 2025 Wayback snapshot
The prior lane read only the 2023-01-27 capture and concluded 'Wayback has no
spec block', leaving the 12 WHL/La Orvito rows identity-only. There are 7
Whistler snapshots; the newest (2025-10-17, HTTP 200) carries the complete
Specifications block. Recovered composition, backing, total weight, width,
repeat, full roll, fire rating and environmental, plus the full description.

Also sharpens the still-open Decision 2 on those 12 items with three new facts:
  - Whistler was live on the vendor site as recently as 2025-10-17, so the
    removal is RECENT (window 2025-10-17 .. 2026-09-10), not an old dead line
  - the 'renamed?' branch is ruled out: no cork/Portugal pattern exists in the
    live 371-page sitemap sweep (only VCO Vinyl Cork, a separate live pattern)
  - the page dates it to a Fall 2022 introduction (~3-year lifecycle)
A recent drop makes remaining/closeout stock MORE likely, which supports the
DTD verdict-B 'hold and ask about closeout' rather than the archive-now dissent.

Cohort spec coverage 39/51 -> 51/51. Staging-table UPDATE only (12 rows,
Mac2-canonical), prestate + exact keyed undo in rescrape/undo/, ledgered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FXH75ac8BT9AFuzjiypPjU
850e06a · 2026-09-10 · TK-11041: final amended vendor letter + two defects found in the live draft
Merged the Whistler/closeout paragraph into the REAL current draft body (read via
gmail_get_message, not reconstructed). Flags two defects in the draft sitting in
Drafts since Sep 4: a visible 'From job: node' provenance banner that would be sent
to the vendor, and an unfilled 'Scott' signature.

Not sent: George's externalSendGuard fail-closes on external recipients and requires
a human-approval token; did not self-approve past it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ef59d38 · 2026-09-10 · TK-11042: quote-CTA tag-normalization plan + gated executor + rollback
Live audit shows the Track-B blocker premise was wrong: Koroseal 2449 and Maya
620 are 100% correctly-configured quote-only (zero dead ends), while Marburg 112
and Phillipe Romano 4,096 render as customer-facing dead ends purely because they
carry quote intent under a tag name the theme does not trigger on. No vendor cost
data is required to fix any of it.

Read-only plan builder + verify-before-act executor + byte-for-byte rollback.
NOTHING FIRED — live execution is Steve-gated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RzTjJ25kmRFTvTjgA28Pwa
cf73947 · 2026-09-10 · TK-11041: Innovations re-scrape recovers 51/51 identities (0 mismatches); WHL=Whistler discontinued
Overturns the 2026-09-02 '0/51 recoverable' finding: CSO/ENS/FLN/PRO/SKL/TTM/VCO/WHL
are real Innovations item-number prefixes, not DW-internal codes. Feed-first $0
read-only sweep of innovationsusa.com sitemap (371 pattern pages, robots-compliant)
resolves every one of the 51 to pattern + colorway + specs + image.
43 exact colorway matches, 7 prefix, 1 DW-unnamed, 0 mismatches.
WHL (12 items) = Innovations Whistler, DISCONTINUED — recovered via Wayback; those
12 should be archived, not repriced. Price remains vendor-gated (no public prices).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M72uDgM1SgEh3Ma4QgcCw
cf93e58 · 2026-09-04 · TK-11252 Tier 2: make 7 more unbuyable Hollywood products buyable
5 Sold-Per-Yard (DUR/XWH/XWJ) + 2 Single-Roll (Senza A200). Price, option name,
inventory policy and tracked flag all read PER-LINE from live sellable siblings
rather than hardcoded — the canary caught a wrong option-name mapping, a value
not reaching the mutation, and a wrong tracked flag before the batch. 7/7 verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rLMRd91EREgUHbEMQDNiy
109df2d · 2026-09-04 · TK-11252: add sellable Single Roll variants to 18 unbuyable Hollywood products
18 ACTIVE Hollywood Wallcoverings products had only a $4.25 sample variant and
could not be bought. Price sourced per-product from its own pattern's live
sellable siblings (8-36 identically-priced siblings each). Canary-first, then 17.
Verified 18/18 live. Undo script + created.json variant ids included.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rLMRd91EREgUHbEMQDNiy
defc1cb · 2026-09-02 · TK-10978: Rebel Walls RS-orphan archive complete — 455/455 (215 batch-2 + 240 batch-1), 0 failed
Steve-approved archive of stale RS-series duplicate products whose R-series
twin is already ACTIVE+buyable. Verified live: 4-sample spot-check confirms
orphans archived, twins remain active with buyable Sold Per Square Meter
variant + Sample preserved. Reversible via archive-rollback.mjs (restore
prior status from prestate.jsonl).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019rsXQme52WNRYJAdh3MirZ
8085c23 · 2026-09-02 · TK-11041: Innovations 51-cohort feed-first reconciliation — 0/51 locally recoverable + provenance guard
Deterministic read-only recovery map for the 51 ACTIVE sample-only PR-Innovations
products. All local recovery keys yield 0 (sku/dw_sku/mfr_sku joins + feed-first
pattern-token match): the cohort carries only DW-internal collection codes with no
real Innovations item#/price, and innovations_catalog describes the Innovations USA
(DWIN-) line, not the PR private-label (236/341 no provenance URL, 81/341 fabricated
pattern-tail codes). Recovery correctly stays BLOCKED_ON_VENDOR_LINESHEET (gated email).

Ships lib/provenance.mjs guard (rejects no-URL / placeholder / lowercase-tail /
pattern-tail codes) encoding the TK-10981 fabrication caveat, with a 7/7 test incl. a
LIVE assertion that 0 fabricated catalog rows are wrongly trusted. No canonical/Shopify
writes; reads via BEGIN READ ONLY..ROLLBACK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GUmvA1WvsNnWhXfhLgz7q2
ae3731d · 2026-09-02 · TK-10978 RebelWalls: read-only recon + reversible archive executor (scope-inversion evidence; nothing fired)
454/494 unbuyable RS-orphans are stale duplicates of already-buyable R-twins; archive (not make-buyable). Dry-run proven on 5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c815a74 · 2026-08-30 · TK-10978: Scalamandre content-match reconciliation — 133 recoverable (dry-run)
Bridged the DWA↔DWSC SKU-identity gap via pattern+color content-match. 133/474 unique
high-precision matches (8/8 spot-verified exact); live-confirmed all sample-only =>
add-roll recovery. 38 ambiguous + 303 no-match held. Gated memo drafted to pending-approval.
Dry-run list: data/scalamandre-reconcile-dryrun.csv. No writes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4f00877 · 2026-08-30 · TK-10875: next-cohort scan — WG was the only bounded recoverable cohort
Tested corrected join + cost-population across 12 top unbuyable vendors. All others:
either empty staging cost columns (PR/China Seas/Arte/Malibu/PJ/Coordonné → cost-sourcing)
or cost present but keys diverge (Scalamandre: 4,877 costed rows, DWA vs DWSC + mismatched
mfr → identity-reconcile). No other quick-win cohort. Bounded recovery COMPLETE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6ee445d · 2026-08-30 · TK-10875: regenerate artifacts + broaden live RR-defect verification (16 products)
Mirror lock cleared; regenerated classify + pilot artifacts (25,214 unbuyable; WG
224 recoverable via restructure). Broadened live-Shopify verification to 12 more
distinct WG patterns ($54.75-$77.38) + the earlier 4 (up to $343.80) = 16 products,
ALL confirmed RR-defect (single option1=Sample variant @ roll retail). Evidence in
data/live-verification.txt. Still zero writes; restructure remains GATED.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8fb27f0 · 2026-08-30 · TK-10875: EMPIRICAL correction — WG 224 are RR-defect, recoverable via restructure
Empirical test gate (yoloforever) drove the claim against LIVE Shopify and reversed
the conclusion again — the decisive finding:
- The 224 WG 'unbuyable' products each have a SINGLE variant with option1='Sample'
  priced at ROLL RETAIL ($54.75..$343.80), not $4.25. Verified on 4 products across
  the price range. This is the RR-defect (TK-10875-130 class), NOT already-sellable
  and NOT clean sample-only — both prior conclusions were wrong.
- The mirror CANNOT classify this: it carries no variant option1 and is price-stale
  (one product read $180.90 mirror vs $343.80 live; sync 13 days dead).
- Recovery = variant restructure (relabel Sample->Sold Per Roll @ trade/0.65/0.85 +
  add $4.25 Sample), reversible+ledgered per TK-10875-130 — GATED customer-facing write.
- Fixed shopify_id vs internal-id bug; executor must read live + recompute from staging.

Artifacts marked REGEN_PENDING: a live mirror lock pileup (ALTER TABLE shopify_products
queued behind a 35-min analytical query) is blocking shopify_products reads. Code is
correct; regenerate data/ when the lock clears.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
af9c3e5 · 2026-08-30 · TK-10875: harden pilot after contrarian + Kimi red-team — stale-flag guard
Contrarian caught the decisive flaw: the 224 Wolf Gordon 'recoverable' products
already have a correctly-priced single roll variant in Shopify — has_product_variant
is a STALE mirror flag (dead sync job), so 'recovery' would double-add.

- Add stale-flag guard (variant_count=1 + non-null non-sample SKU + price>$4.50):
  classify + pilot now split already-sellable(224) vs genuinely-sample-only(24990)
- Pilot yields 0 truly-buildable; conclusion = fix sync + confirm live Shopify first
- Relabel the pricing cross-check honestly (tautological, not price validation)
- Note Coordonné DWCO2<->DWDC prefix reconcile path (not a dead end)
- db.mjs: ON_ERROR_STOP=1 so bad SQL fails loud instead of empty result

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
b634b70 · 2026-08-30 · TK-10875: unbuyable classification + Wolf Gordon dry-run recovery pilot (read-only)
- classify.mjs: 25,214 ACTIVE unbuyable; row-level cost drained; vendor breakdown
- pilot.mjs: Wolf Gordon 224/269 recoverable via corrected join, pricing 224/224 cross-checked
- Documents the join-key column-swap (shopify.sku = catalog.dw_sku) that made prior
  table-total estimates overcount ~10x
- lib/db.mjs: BEGIN READ ONLY via stdin (two psql traps found+fixed), zero writes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

File tree

205 files tracked. Click any to browse the source at HEAD.

Other build journals

← Dw Title Repair  ·  all 4 projects  ·  Dw Universe →

Export

commits.csv · feed.atom · project.json · commits.json

rendered in 2ms