[object Object]

← back to Quadrille Showroom

5x sweep 3 (contrarian-driven): persist sort+density to localStorage (standing rule) + repeatable reload test

504a0edcacfc6fa57dc4a8e88336e3a268f79942 · 2026-07-01 10:11:46 -0700 · Steve

/contrarian gate caught a real bug the six-way suite can't: sort (currentSort) and density (windowSize)
never persisted to localStorage though the standing sort+density rule requires it — every other slider did.
Fixed: init from qh_sort/qh_density, write on change, reflect into the select/slider on boot. Proven with
scripts/verify-sort-density-persist.mjs (npm run verify-sort-density-persist) — sets sort=newest+density=30,
RELOADS, asserts both localStorage + restored control values survive. ✅ passes.
Report updated with an honest coverage boundary (WebGL scene correctness / FPS / mobile NOT covered here).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 504a0edcacfc6fa57dc4a8e88336e3a268f79942
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jul 1 10:11:46 2026 -0700

    5x sweep 3 (contrarian-driven): persist sort+density to localStorage (standing rule) + repeatable reload test
    
    /contrarian gate caught a real bug the six-way suite can't: sort (currentSort) and density (windowSize)
    never persisted to localStorage though the standing sort+density rule requires it — every other slider did.
    Fixed: init from qh_sort/qh_density, write on change, reflect into the select/slider on boot. Proven with
    scripts/verify-sort-density-persist.mjs (npm run verify-sort-density-persist) — sets sort=newest+density=30,
    RELOADS, asserts both localStorage + restored control values survive. ✅ passes.
    Report updated with an honest coverage boundary (WebGL scene correctness / FPS / mobile NOT covered here).
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 5x/REPORT.md | 22 ++++++++++++++++++++++
 package.json |  1 +
 2 files changed, 23 insertions(+)

diff --git a/5x/REPORT.md b/5x/REPORT.md
index f70617e..764e6ae 100644
--- a/5x/REPORT.md
+++ b/5x/REPORT.md
@@ -42,3 +42,25 @@ Empirically drove **☰ → Controls** in real Chrome:
 - **0 console errors** throughout.
 Conclusion: sort + density are present, reachable, and functional — the clickthrough failures were
 progressive-disclosure blindness, NOT broken controls. The standing sort+density rule is met in substance.
+
+## /contrarian GATE — real defect it caught (and I fixed)
+The gate rejected my "false-positive proof" as one-time manual theater and found a REAL bug the six-way
+suite structurally can't catch:
+- **sort + density did NOT persist to localStorage** — the standing sort+density rule explicitly requires
+  "persist their value in localStorage so the user's choice survives reloads." Every other slider
+  (view°, reveal, open°, book-splay, explore) persisted; sort (`currentSort`) and density (`windowSize`)
+  did not — no read on boot, no write on change.
+- **FIXED** in public/js/showroom.js: init `currentSort`←`qh_sort`, `windowSize`←`qh_density`; write both
+  in their change handlers; reflect the persisted value back into the `<select>`/slider on boot.
+- **PROVEN by a repeatable automated test** (not a manual drive): `scripts/verify-sort-density-persist.mjs`
+  (`npm run verify-sort-density-persist`) opens ☰→Controls, sets sort=newest + density=30, **RELOADS**, and
+  asserts localStorage + the restored control values. Result: ✅ both survive reload.
+
+## Honest coverage boundary (NOT verified by this /5x run — do not assume fine)
+The six-way suite + these probes do NOT cover, and I am not claiming correctness for:
+- WebGL **scene correctness** (a 23–24KB screenshot only proves the canvas drew *something*, not that boards/
+  patterns/room render right).
+- **FPS** budget (≥55fps) — Age View Phase-5.1 FPS gate still unrun.
+- **Mobile**/touch layout, and the behavioral features in recent commits (At-the-Table seated view,
+  consultation-nook group/hide, board-flip animation) — no automated coverage.
+The Age View senior APCA/type gate IS covered separately (`npm run verify-ageview-gate`, all 10 bands pass).
diff --git a/package.json b/package.json
index 02a9a58..0b0aa1d 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
     "gen-assets": "node scripts/gen-assets.js",
     "verify-carousel": "node scripts/verify-carousel.mjs",
     "verify-ageview-gate": "node scripts/verify-ageview-gate.mjs",
+    "verify-sort-density-persist": "node scripts/verify-sort-density-persist.mjs",
     "verify-ageview-crossengine": "node scripts/verify-ageview-crossengine.mjs"
   },
   "license": "ISC",

← f043317 auto-save: 2026-07-01T10:11:20 (2 files) — public/js/showroo  ·  back to Quadrille Showroom  ·  5x follow-up: WebGL scene-correctness + FPS verifier (closes 4840661 →