← back to Dw Sku Integrity

RUNBOOK.md

68 lines

# TK-10896 — gated dw_sku self-copy firing runbook

Turnkey, per-vendor execution of the ledger-verified self-copy plan. Every write
here is **canonical Kamatera dw_unified = HARD-GATED**: Steve runs each step; agents
never fire it. Recovers an existing code (no mint). Full closed loop:
**preflight (read-only) → apply (gated write) → verify (read-only) → rollback if needed.**

## Prerequisites (Steve, once)
1. **Confirm the ledger's chain of custody.** The plan's provenance rests on
   `/tmp/TK-10896-phase4-ledger.jsonl` being the authorized export of Kamatera's
   `sku_repair_p4_20260826` undo table. Integrity is verified (SHA-256 + row-count +
   internal consistency); confirm it's the real export before proceeding.
2. **Set the canonical target** for the read-only checks (same wrapper the scanner uses):
   ```bash
   export DWSKU_PSQL='ssh <kamatera-host> psql'      # points read-only checks at Kamatera
   cd ~/Projects/dw-sku-integrity
   ```
3. **(Optional) regenerate the plan on canonical.** The committed apply-plans were built
   from the Mac2 mirror. shopify_id is stable cross-machine, so they port directly — but
   to be exact you may re-run the scan+join+gen against Kamatera first.

## Per-vendor cycle (start with the smallest vendor as a canary)
Order by size ascending; `apply-plans/SUMMARY.json` → `per_vendor` has the counts.

```bash
V=<vendor-slug>      # e.g. a-s-cr-ation (small) before carnegie (10,707)

# 1. PREFLIGHT (read-only) — must print "verdict": "GO"
node preflight-check.mjs --vendor "$V" --out /tmp/pf-$V.json
#    GO   = every row exists + still blank on Kamatera -> safe to apply
#    NO_GO= inspect flags: MISSING (row not on target / drift) or
#           ALREADY_OTHER (row holds a different code — do NOT overwrite). STOP, investigate.

# 2. APPLY (GATED WRITE — Steve fires). Every UPDATE is blank-guarded + shopify_id-keyed.
ssh <kamatera-host> "psql dw_unified" < apply-plans/$V/apply.sql
#    (or run apply.sql however Steve normally applies a canonical migration)

# 3. VERIFY (read-only) — must print "verdict": "GO"
node preflight-check.mjs --vendor "$V" --mode verify --out /tmp/vf-$V.json
#    GO   = every planned row now equals its candidate (applied cleanly)
#    NO_GO= NOT_APPLIED rows (write didn't land) or ALREADY_OTHER — inspect + reconcile.

# 4. ROLLBACK (only if a problem is found) — reverses exactly what apply set.
ssh <kamatera-host> "psql dw_unified" < apply-plans/$V/undo.sql
#    undo.sql sets dw_sku=NULL WHERE shopify_id=... AND dw_sku='<candidate>' (targeted).
#    restore-map.json is the human-readable record of every (shopify_id -> candidate).
```

## Scope reminder (what this plan does / does NOT touch)
- **Applies (self-copy, 33,762 rows / ~38,712 statements across 93 vendors):** recovers the
  existing DW/source/Cork code already sitting in each row's `sku`. No mint.
- **Does NOT apply — routed elsewhere:**
  - **~837 rescrape** (Knoll 492 + Hollywood 266 confirmed reverted-mint residue, Pixels 52,
    Steve Abrams 13, Jeffrey Stevens 12, PR 2, + 65 truly bare) → the re-scrape program
    (TK-10900/10901), owned by each vendor's scraper-manager. NEVER self-copied (would re-mint).
  - **9 collisions** → dedup (TK-10649).
  - **2 shape-rejected** garbage candidates (a leaked title + a "Sold Per Bolt" suffix) →
    manual/rescrape, excluded from apply.

## Safety properties (independently verified)
- Every apply UPDATE keyed on `shopify_id` (stable cross-machine), NOT the local serial `id`.
- Every apply UPDATE carries the blank-guard `(dw_sku IS NULL OR btrim(dw_sku)='')` — idempotent.
- 0 reverted-mint ledger codes appear in any apply.sql (verified across all assigned codes).
- undo.sql reverses apply.sql exactly; restore-map.json records every mapping.
- 45 tests green. `preflight-check.mjs` is SELECT-only.

Parent ticket: **TK-10896**.