← back to Wallco Ai

data/yolo-overnight/bulk-ops-inventory-20260525-1232.md

229 lines

# Bulk-Ops Inventory — `data/bulk-ops/`

- **Generated:** 2026-05-25 12:32 PT
- **Walked dir:** `/root/public-projects/wallco-ai/data/bulk-ops/`
- **Working dir resolved from:** task spec's third candidate (`~/Projects/wallco-ai` and `/root/Projects/wallco-ai` are empty scaffolds — only `/root/public-projects/wallco-ai/` has real content)

## File inventory

| # | File | Size | Lines | Valid JSONL? | Unique ops |
|---|------|-----:|------:|:------------:|-----------:|
| 1 | `republish-orphans-2026-05-25-010833.jsonl` | 636,236 B (621 KB) | 4,258 | ✅ all 4,258 parse, 0 errors | 1 (`republish-orphan`) |

Only one file present in the directory. No partial writes, no empty lines, no malformed rows.

## File 1: `republish-orphans-2026-05-25-010833.jsonl`

### Record schema (consistent across all 4,258 rows)

```json
{
  "ts": "2026-05-25T08:08:33Z",
  "op": "republish-orphan",
  "id": <design_id>,
  "cat": "<category[ · colorway]>",
  "gen": "<generator>",
  "prev_pub": false
}
```

- All rows share the **same timestamp** (`2026-05-25T08:08:33Z`) → emitted in a single sweep, not an ongoing append log.
- `id` range: **11 → 41,560**, all **unique** (4,258 distinct design ids; no duplicates).
- `prev_pub`: **always `false`** for every row → none of these designs had previously been published to Shopify when the sweep flagged them. (Republish here means *first publish from orphan state*, not re-flip from unpublished after a prior publish.)

### ID distribution

| id bucket | count |
|----------:|------:|
| <10 k     |    65 |
| 10–20 k   |   516 |
| 20–30 k   |   626 |
| 30–40 k   | 2,418 |
| 40 k+     |   633 |

Skewed toward the newer (30 k+) end of `spoon_all_designs`, as expected for a recent-orphan sweep.

### Op breakdown

| op | count |
|---|---:|
| `republish-orphan` | 4,258 |

Single-op file. No mixed payloads.

### By generator (`gen`)

| generator | count | % |
|---|---:|---:|
| `replicate` | 2,334 | 54.8 |
| `gemini-2.5-flash-image-smart-fix` | 1,124 | 26.4 |
| `comfy` | 685 | 16.1 |
| `gemini-2.5-flash-image-edit` | 55 | 1.3 |
| `pil-fix-design` | 39 | 0.9 |
| `pil-opacity-snap (via smart-fix redirect)` | 9 | 0.2 |
| `gemini-2.5-flash-image-regen-reverse` | 5 | 0.1 |
| `dw-shopify` | 3 | 0.07 |
| `pil-fix` | 2 | 0.05 |
| `flux` | 1 | 0.02 |
| `stub` | 1 | 0.02 |
| **total** | **4,258** | 100 |

### By category (rolled up across `pattern · colorway` variants)

| base category | count |
|---|---:|
| damask | 1,715 |
| face-skull-damask | 292 |
| designer-zoo-calm | 292 |
| drunk-zoo-36 | 290 |
| drunk-monkeys-v2 | 261 |
| drunk-animals | 238 |
| throttled-plaster-roses | 237 |
| stripe | 217 |
| designer-scenic | 195 |
| muybridge-plate | 133 |
| cactus | 122 |
| chinoiserie | 113 |
| cactus-pine-scenic | 41 |
| colorways-imperial-garden-barone | 28 |
| drunk-monkeys-birds-subdued | 22 |
| floral | 17 |
| designer-bugs | 10 |
| desert-flora | 6 |
| monterey-mural | 5 |
| colorways-imperial-garden-barone-facesup-test | 5 |
| lips | 4 |
| archive | 3 |
| saguaro-arms | 3 |
| designer-flat-lips | 3 |
| recolor | 2 |
| arts and crafts | 1 |
| botanical-foliage | 1 |
| cactus-11ft-mural | 1 |
| tree-mural | 1 |

(166 distinct `cat` strings once colorway suffix is included — counts above roll them up to the base pattern.)

### Sample rows

```jsonl
{"ts":"2026-05-25T08:08:33Z","op":"republish-orphan","id":11,"cat":"floral","gen":"replicate","prev_pub":false}
{"ts":"2026-05-25T08:08:33Z","op":"republish-orphan","id":37982,"cat":"damask","gen":"replicate","prev_pub":false}
{"ts":"2026-05-25T08:08:33Z","op":"republish-orphan","id":41560,"cat":"damask","gen":"replicate","prev_pub":false}
```

---

## What it means (operational read)

This log is a single batch sweep at 2026-05-25 ~08:08 UTC (01:08 PT) that flagged **4,258 design rows in `spoon_all_designs`** as candidates for **republishing from orphan state** — i.e. designs that exist as generated assets but had never been pushed to the Shopify store. `prev_pub: false` on every row confirms none of these had ever been live before, so the action is a **first-publish**, not a flip from previously-unpublished.

No script in the repo currently writes to `data/bulk-ops/` (grepped — only this file references the path). The closest neighbour is `scripts/sweep_orphan_generated.js`, which sweeps PNGs on disk against `spoon_all_designs` — but that one is for *file-cleanup*, not Shopify publish. The writer of this JSONL is either an in-flight script not yet committed, or an ad-hoc one-shot run.

---

## Reversal procedure (how to undo each entry)

Each row records a single state transition: **`spoon_all_designs.published = false → true`** for `id`, with no Shopify side-effect prior to the act (`prev_pub: false`). Reversal options, in order of preference:

### Option A — soft revert in PG only (recommended, blast radius = 0 on Shopify)

If the sweep only updated the PG flag (no Shopify product created yet), one statement reverts the whole file:

```bash
psql dw_unified -At -q <<'SQL'
BEGIN;
WITH ids AS (
  SELECT (jsonb_array_elements(jsonb_agg(line::jsonb))->>'id')::int AS id
  FROM (
    SELECT regexp_replace(l, E'^\\s+|\\s+$', '', 'g') AS line
    FROM regexp_split_to_table(
      pg_read_file('/root/public-projects/wallco-ai/data/bulk-ops/republish-orphans-2026-05-25-010833.jsonl'),
      E'\n'
    ) AS l
    WHERE l <> ''
  ) t
)
UPDATE spoon_all_designs s
   SET published = false, updated_at = now()
  FROM ids
 WHERE s.id = ids.id;
SELECT count(*) AS reverted FROM spoon_all_designs WHERE id IN (SELECT id FROM ids) AND published = false;
COMMIT;
SQL
```

(Read the file via `pg_read_file` requires PG superuser; if not available, pipe `jq -r '.id' file.jsonl` → `\copy ids FROM STDIN` instead.)

Simpler version using `jq`:

```bash
jq -r '.id' data/bulk-ops/republish-orphans-2026-05-25-010833.jsonl \
  | psql dw_unified -At -q -c "CREATE TEMP TABLE revert_ids(id int);
                                COPY revert_ids FROM STDIN;
                                UPDATE spoon_all_designs s SET published=false, updated_at=now()
                                 FROM revert_ids r WHERE s.id = r.id;"
```

### Option B — Shopify unpublish (only if Shopify products were created downstream)

If the sweep cascaded to actually pushing products into Shopify:

```bash
# Dry-run first — see what would be touched
jq -r '.id' data/bulk-ops/republish-orphans-2026-05-25-010833.jsonl \
  | psql dw_unified -At -q -c "SELECT id, shopify_product_id, shopify_handle
                                  FROM spoon_all_designs
                                 WHERE id = ANY('{ \$(cat -)} '::int[])
                                   AND shopify_product_id IS NOT NULL;" \
  > /tmp/republish-orphans-shopify-targets.tsv

# Then for each shopify_product_id, set status='draft' via GraphQL productUpdate,
# batched 25-per-call per DW-Agents Shopify rules. Use Quinn (port 9670 worker).
```

### Option C — full audit-and-restore via paired log

Write a `data/bulk-ops/revert-republish-orphans-<ts>.jsonl` alongside this file capturing
`{ id, prev_published_state, prev_shopify_status, ts }` *before* flipping. Then reversal is
a row-by-row replay. (Not in place today — recommend adding this before the next sweep.)

### Per-row reverse spec (single row)

For one record `{"id": 41560, "cat": "damask", ...}`:

```sql
UPDATE spoon_all_designs SET published = false, updated_at = now() WHERE id = 41560;
-- + if a Shopify product was created downstream:
--   shopify productUpdate(id: <gid>, status: DRAFT) via Quinn worker
```

---

## Caveats Steve should know

1. **No paired pre-state log.** The JSONL records only the *intent* (republish, prev_pub=false), not the resulting Shopify product ids. If/when this sweep does flip products into Shopify, we'll need a `shopify_product_id` field captured per row to make reversal precise. **Recommend extending the writer to dual-log: one `…-intent.jsonl` and one `…-result.jsonl` with shopify gids.**
2. **No script in repo writes this file.** Whoever ran the sweep at 08:08 UTC did it from an uncommitted script or an ad-hoc one-liner. The producer should be checked in before next run.
3. **All 4,258 rows share a single timestamp** — this was a batch dump, not a streaming append. A re-run will overwrite or create a new dated file (filename includes hh:mm:ss).
4. **Heavy damask skew** — 1,715 of 4,258 (40%) are base `damask`. If the publish pipeline has any per-pattern QA gate (e.g. duplicate seam check, two-color fix), surge that bucket first.
5. **`prev_pub: false` universal** — confirmed no design in this batch was previously live, so unpublishing is safe in the sense that we're not stomping a customer-visible product that pre-existed.

---

## Quick recipes

```bash
# Re-validate the JSONL is well-formed:
jq -c . data/bulk-ops/republish-orphans-2026-05-25-010833.jsonl >/dev/null && echo OK

# Extract just the design ids:
jq -r '.id' data/bulk-ops/republish-orphans-2026-05-25-010833.jsonl > /tmp/republish-ids.txt

# Per-generator counts:
jq -r '.gen' data/bulk-ops/republish-orphans-2026-05-25-010833.jsonl | sort | uniq -c | sort -rn

# Per-base-category counts:
jq -r '.cat' data/bulk-ops/republish-orphans-2026-05-25-010833.jsonl \
  | awk -F' · ' '{print $1}' | sort | uniq -c | sort -rn
```