← back to Wallco Ai
output/designs-json-integrity-2026-06-01.md
104 lines
# wallco.ai `designs.json` integrity audit — 2026-06-01
**Scope:** READ-ONLY integrity check of the live prod catalog snapshot.
**Target file:** `root@45.61.58.125:/root/public-projects/wallco-ai/data/designs.json`
**File state:** `25,695,554 bytes`, owner `501:staff` (Mac2-built artifact), mtime `Jun 1 04:19` (fresh deploy).
**Authoritative DB cross-checked:** Mac2 `dw_unified.all_designs` (table underlying the `spoon_all_designs` view).
**Verdict: ✅ CLEAN on all three required checks. No misclassifications, no path leaks, no duplicate ids. No fixes applied (READ-ONLY by mandate; none were warranted anyway).**
---
## 1. `local_path` / `/Users/` path-leak check — ✅ PASS
| Check | Result |
|---|---|
| Records carrying a `local_path` key | **0** of 35,071 |
| `local_path` in the distinct-keys union | **absent** |
| Raw `grep -c "/Users/"` across whole file | **0 matches** |
The public `/api/designs` endpoint cannot leak `/Users/stevestudio2/…` paths from this snapshot. The `localPathForDesign()` basename-only convention (commit `6dbeb3b`) is holding — the snapshot exposes only `filename` + `image_url`, never an absolute local path.
**Distinct keys present (clean set):**
`category, created_at, dominant_hex, filename, generator, handle, id, image_url, is_published, kind, motifs, room_mockups, saturation, seed, tags, title, unpublish_reason, user_color_good, user_removed, user_scale_good, user_stars, user_style_good`
## 2. Duplicate `id` check — ✅ PASS
| Check | Result |
|---|---|
| Total records | 35,071 |
| Distinct ids appearing >1× | **0** |
Every record has a unique `id`.
## 3. Mural-kind misclassification check — ✅ PASS (zero violations)
Per `lib/mural-categories.js`, rows in `monterey-mural`, `cactus-pine-scenic`, `cactus-11ft-mural`, `cactus-accent-mural`, `tree-mural`, `mural-scenic` must be `kind='mural_panel'` (or `'mural'` for `cactus-11ft-mural`) — **never** a tile kind (`seamless_tile` / `tile` / `repeat_tile`).
**Mural-category rows present in snapshot, by category → kind:**
| category | kind | count |
|---|---|---|
| `monterey-mural` | `mural_panel` | 857 |
| `cactus-pine-scenic` | `mural_panel` | 73 |
| `cactus-11ft-mural` | `mural` | 87 |
| `cactus-11ft-mural` | `mural_panel` | 1 |
| `tree-mural` | `mural_panel` | 42 |
- **Tile-kind rows in any mural category: 0** (no `seamless_tile`/`tile`/`repeat_tile`).
- Cross-checked the authoritative Mac2 DB directly — **also 0** mural-category rows with a tile kind there. The 2026-05-27 fix (12 rows) is holding.
- `cactus-accent-mural` and `mural-scenic` have **0 rows** in this snapshot (categories defined in the guard but not yet populated — not an error).
**Informational only (not a violation):** the 1 `cactus-11ft-mural` row with `kind='mural_panel'` instead of the category's historical `'mural'`. `lib/mural-categories.js` explicitly accepts BOTH `mural` and `mural_panel` for all mural categories — the guard only refuses tile kinds. PDP/listing renderers handle both. No action needed.
**Global kind distribution:** `seamless_tile` 33,330 · `mural_panel` 1,649 · `mural` 92. (676 `mural_panel` + 5 `mural` rows live in non-mural categories — allowed; the rule is one-directional: mural categories must not be tile, not that mural kinds can't appear elsewhere.)
## 4. Published count sanity vs DB — ✅ SANE
| Source | Total rows | `is_published=true` |
|---|---|---|
| prod `designs.json` snapshot | 35,071 | **5,590** |
| Mac2 `all_designs` (authoritative) | 44,803 | **~5,673–5,687*** |
\* Live DB drifts a few rows between queries (concurrent generation/auto-commit agent active).
**Total delta (44,803 → 35,071, −9,732):** expected. The snapshot omits rows the rebuild filters out (no valid image, hard-removed state, etc.). Not all DB rows are snapshot rows.
**Published delta (~5,673 DB → 5,590 JSON, ≈ −83 to −97, ~1.7%):** sane. The snapshot drops a small number of published-in-DB rows during rebuild (quality/image-presence filtering) plus live drift. Within normal tolerance.
**Snapshot `is_published` × `user_removed` crosstab:**
| is_published | user_removed | count |
|---|---|---|
| false | false | 7,567 |
| false | true | 21,914 |
| true | false | **3,903** |
| true | true | **1,687** |
### Observation — published+removed rows in the snapshot are CARRIED but correctly SUPPRESSED at boot (not a leak)
1,687 snapshot rows are `is_published=true` AND `user_removed=true`. This is **not** a customer-visibility problem:
- `server.js:364 loadDesigns()` filters at boot: `const beforeGate = raw.filter(d => !d.user_removed && d.is_published !== false);` then applies `passesAestheticGate`. So `user_removed` rows are dropped from the in-memory `DESIGNS` index regardless of their `is_published` flag.
- The snapshot intentionally carries full row state (the `user_removed` flag travels with the row); the **server** is the visibility gate, not the raw snapshot.
- Effective customer-visible published floor = 3,903 (published & not-removed) minus aesthetic-gate drops (memory: ~28% historically filtered).
- **0** published rows are missing both `image_url` and `filename` (no broken cards).
This matches the authoritative DB (1,743 published-and-removed there) within live drift — the snapshot faithfully mirrors DB state.
---
## Summary table
| # | Check | Result |
|---|---|---|
| 1 | No `local_path` / `/Users/` leak | ✅ PASS (0/0/0) |
| 2 | No duplicate ids | ✅ PASS (0) |
| 3 | Mural categories never `seamless_tile` | ✅ PASS (0 violations; DB cross-check also 0) |
| 4 | Published count sane vs DB | ✅ SANE (5,590 vs ~5,673; ~1.7% gap explained) |
**Misclassifications found: 0. Path leaks found: 0. Duplicate ids: 0.**
Nothing to fix. The 2026-05-27 mural-kind fix and the `local_path` basename convention are both holding in the live snapshot. No `/dtd` convened — every check resolved cleanly with no decision fork (and the mandate is READ-ONLY).
*Generated 2026-06-01 (autonomous YOLO read-only audit).*