← litmanintelligence.com  |  ← Counsel PDFs index

Review Site Qa 2026-04-28 Verify

Review Site QA — Verification Re-Run — 2026-04-28

Target: https://litmanintelligence.com/review/ (cache-busted with ?v=<timestamp>) Trigger: Re-run after deployment of the jsArg(s) = escapeHtml(JSON.stringify(s)) HTML-attribute escaping fix Source-of-truth script: scripts/build_review_site_v2.py (helper at line 694, all 29 inline-onclick interpolations now use it) Driver: Playwright (Chromium, headless) — script saved at /tmp/qa_review_site_verify.py Raw results: /tmp/qa_results_verify.json Screenshots / artifacts: output/qa_screenshots_verify/


VERDICT

BINDER CLICK FIX CONFIRMED.

All previously-broken click-driven sidebar features now work end-to-end. State is correctly set, the active class is applied, the table re-renders, and the browser logs 0 console errors / 0 page errors for a full session including binder create/click/add/rename/delete and every facet group.

Executive summary

Metric Value
Tests run 30
PASS 28
PARTIAL 1
Apparent FAIL (after analysis: non-bugs) 1
Real FAIL 0
Console errors 0
Page errors 0
jsArg( references in served HTML 34
Broken state.filters.binder="..." interpolations in served HTML 0
_lastFiltered, _lastRefresh literal in served HTML yes (required marker present)

Both apparent FAILs were investigated and confirmed to be expected/correct behavior, not regressions:

  1. Custodian facet — clicking the only custodian (Richard C. Litman, who is custodian on 100% of documents) correctly leaves the count unchanged because every doc matches. The state IS updated to {custodian: "Richard C. Litman"}, proving the click handler fires. Reclassified to PASS (no-op single-bucket facet).
  2. Empty-binder row count — the empty binder shows "1 row" in the table, but inspection of the DOM proves that row is the empty-state placeholder (<td colspan="9"><div class="empty"><h4>No results</h4>...), not a data row. The actual filtered result set is empty. Reclassified to PASS.

Patch markers in served HTML (live verification)

$ curl -s "https://litmanintelligence.com/review/?v=$(date +%s)" | grep -c 'jsArg('
34

$ curl -s "https://litmanintelligence.com/review/?v=$(date +%s)" | grep -c 'state.filters.binder="'
0

$ curl -s "https://litmanintelligence.com/review/?v=$(date +%s)" | grep -c '_lastFiltered, _lastRefresh'
1

All three checks PASS. The fix has been deployed to the live build.


Results table

# Feature Prev Now Notes
01 Page loads (cache-busted, networkidle) PASS PASS EMAILS=59,684, DOCS=3,130
01b Patch markers in DOM (jsArg( ≥1, no broken interpolations, persistence literal present) n/a PASS jsArg=34, broken=0, _lastFiltered, _lastRefresh literal present
02 Tab switching (Emails / Documents / Dashboard / Reference) PASS PASS all four tabs render
03 Search filtering (KFU / Goldberg / 11873299) PASS PASS baseline=59,684 → 20,000 / 44,046 / 1; restores cleanly
04 Search scope toggle (All / Subject / Content) PASS PASS All=44,046, Subject=229, Content=40,375
05a Sidebar facet 'Archive' (Emails) FAIL PASS clicked ND0002: 59,684 → 45,650; state.filters.archive='ND0002'
05b Sidebar facet 'Year' (Emails) FAIL PASS clicked 2024: 59,684 → 18,282; state.filters.year='2024'
05c Sidebar facet 'Tag' (Emails) FAIL PASS clicked NGM: 59,684 → 58,931; state.filters.tag='NGM'
05d Sidebar facet 'From Domain' (Emails) PASS PASS clicked NGM (@nathlaw.com): 59,684 → 58,931
05e Sidebar facet 'Hot' (Emails) PASS PASS clicked Hot only: 59,684 → 0
05f Sidebar facet 'Category' (Documents) FAIL PASS clicked DOCUMENT_PHOTOS: 3,130 → 1,536; state.filters.category='DOCUMENT_PHOTOS'
05g Sidebar facet 'Doc Type' (Documents) FAIL PASS clicked Image: 3,130 → 2,021; state.filters.docType='Image'
05h Sidebar facet 'Custodian' (Documents) FAIL PASS* clicked Richard C. Litman: state correctly updated to {custodian: 'Richard C. Litman'}. Count stays at 3,130 because Litman IS the only custodian (100% of 3,130 docs). Click handler IS firing — this is a single-bucket no-op facet, not a regression.
06 My Binders — create / click / filter / rename / delete (HEADLINE BUG) FAIL PASS** Create works. Click-binder applies filter (state.filters.binder = 'Test Binder'). Active class applied. Empty binder shows the empty-state placeholder row (correct). After adding 1 row, re-clicking shows that 1 row. Rename + delete via action buttons both work.
06s Binder w/ apostrophe Joe's docs n/a PASS created, clicked, state.filters.binder == "Joe's docs"
06s Binder w/ ampersand A&B n/a PASS created, clicked, state.filters.binder == "A&B"
06s Binder w/ double-quote Quote"Test n/a PASS created, clicked, state.filters.binder == 'Quote"Test' (round-trips through jsArg = escapeHtml(JSON.stringify(...)) cleanly)
07 Right-click context menu — Mark Produce PASS PASS row decision flips correctly
08 Quick-produce checkbox PASS PASS toggles Produce on/off
09 Detail-pane decision dropdown (Withhold - Privileged) PASS PASS row pill + footer Privileged count update
10 Inline document viewer (PDF iframe / image) PARTIAL PARTIAL 0 iframes / 0 images on first row of Documents tab — same as prior run; not blocked by this fix; worth a manual smoke-check on a known-PDF row.
11a Keyboard / focuses search PASS PASS document.activeElement.id === 'searchBox'
11b Keyboard j (next row) PASS PASS selection moves forward
11c Keyboard k (prev row) PASS PASS selection moves back
11d Keyboard p (mark Produce) PASS PASS dec=Produce
12 Bulk action ("produce" via prompt) PASS PASS filtered set marked
13 Export Production CSV PASS PASS download triggered, 282 bytes
14 Persistence across reload (tab, search, tags) PASS PASS tab=docs, search=patent, tags=3 persisted
15 Footer counts (Marked / Privileged / Hot / Binders) PASS PASS all live-update; ftBinders=1 reflects the leftover Test Binder before delete
16 Browser console / page errors FAIL (4 errors) PASS 0 errors, 0 warnings, 0 page errors for a full session including 9 facet clicks + 4 binder creates + add/rename/delete

* Custodian facet is a single-bucket no-op on the current dataset; the click handler IS firing. State change confirms the fix.

** Test driver's row-count check needed adjustment; the "1 row" was the empty-state <td colspan="9"> placeholder, not a data row. State + active-class + sidebar-update all confirm the fix.


Specific confirmation of binder + facet click fix

Binder click — before vs. after

Check Pre-fix (2026-04-28 run #1) Post-fix (this run)
state.filters.binder after click undefined (NEVER set) "Test Binder" correctly set
.item gains active class NO YES
Table re-renders NO YES (shows empty-state placeholder for 0 results)
Browser console Failed to execute 'click' on 'HTMLElement': Unexpected end of input silent
Special-character names work? not testable (couldn't even click plain names) yes — apostrophe, ampersand, AND double-quote all round-trip cleanly through escapeHtml(JSON.stringify(name))
Group Tab Pre-fix Post-fix
Archive Emails click did nothing 59,684 → 45,650
Year Emails click did nothing 59,684 → 18,282
Tag Emails click did nothing 59,684 → 58,931
Category Documents click did nothing 3,130 → 1,536
Doc Type Documents click did nothing 3,130 → 2,021
Custodian Documents click did nothing state correctly updates (single-bucket dataset means count doesn't drop)
From Domain Emails already working (hand-built single-quoted strings) still working
Hot Emails already working still working

All six previously-broken groups now respond to clicks; the four that previously worked continue to work.

Special-character binders — proof of robustness

The new jsArg = escapeHtml(JSON.stringify(...)) helper survives: - Apostrophe Joe's docs — would have broken the previous state.filters.binder='${name}' if anyone had switched to single-quoted JS strings - Ampersand A&B — would have HTML-decoded incorrectly in many naive escape schemes - Double-quote Quote"Test — was the exact failure mode of the original bug

All three created cleanly, clicked cleanly, and produced an exact-match state.filters.binder round-trip — including the embedded " character.


Console / page errors observed

None. The test driver registered listeners for both console events (filtered to error/warning types) and pageerror events. Across the full session — 30 tests, 9 facet clicks, 4 binder creates with create/click/add/rename/delete cycles, full keyboard nav, bulk action, and a reload — the browser produced:

Compare to the pre-fix run, which logged Failed to execute 'click' on 'HTMLElement': Unexpected end of input four separate times during equivalent interactions.


Other items that need attention

1. PARTIAL: Inline document viewer (Test #10) — unchanged from prior run

When I switched to Documents and clicked the first row, 0 iframes and 0 images rendered in the right pane. This is the same result as the prior run — it is not caused by, and not affected by, the jsArg fix. Possible explanations carried over from the prior report: - Many docs are PDFs hosted out-of-band; the deployed build may not be wiring native files for all rows yet. - The viewer markup may be rendered only on user gesture (lazy). - Only the first row was tested; a known-PDF row might behave differently.

Recommendation: unchanged from prior report — 5-minute manual smoke check on a known-PDF row and a known-image row.

2. Custodian facet has only one bucket

DOCS currently contains 3,130 documents, all with cu = "Richard C. Litman". Clicking the custodian filter is therefore a visible no-op (count stays at 3,130). The fix works — state.filters.custodian is correctly set — but if you want to verify the visible count drops, you'll need a multi-custodian dataset, or this facet group can be hidden/collapsed when only one bucket exists. Low priority; not a regression.

3. No new issues introduced by the fix

Every test that passed in the pre-fix run still passes. No regressions.


Files & artifacts