Commit Graph
70 Commits
Author SHA1 Message Date
Alex-GilbertandClaude Opus 4.6 043aae5abb feat: add pixel-based font scoring function
Add _score_font_line_pixel() which renders candidate text and compares
pixels against the actual page image using Dice coefficient overlap.
This captures glyph shape differences that the old word-width MAE
approach cannot distinguish (e.g. serif vs sans-serif).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 11:16:20 -06:00
Alex-GilbertandClaude Opus 4.6 cb15bb068b docs: add pixel-based font detection implementation plan
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 11:11:53 -06:00
Alex-GilbertandClaude Opus 4.6 f4703285ed docs: add pixel-based font detection design
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 11:08:41 -06:00
Alex-GilbertandClaude Opus 4.6 8f432cc220 refactor: extract CSS custom properties for theme colors
Centralize 21 repeated color values into :root variables.
Makes theme changes trivial and improves readability.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 10:52:53 -06:00
Alex-GilbertandClaude Opus 4.6 bc65b82b26 feat: split app.js into ES modules with JSDoc types
Reorganize the monolithic 1,436-line frontend into 9 focused modules:
types, state, dom, canvas, viewport, associates, popover, solver, main.

No build step — browsers load ES modules natively. JSDoc @typedef
annotations provide type safety via @ts-check + jsconfig.json.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 10:42:11 -06:00
Alex-GilbertandClaude Opus 4.6 fd3617f98d docs: add frontend modularization implementation plan
Complete code for all 9 ES modules with JSDoc types.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 08:30:46 -06:00
Alex-GilbertandClaude Opus 4.6 7a8cda542c docs: add frontend modularization design
Split app.js into ES modules with JSDoc types, no build step.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 08:18:35 -06:00
Alex-GilbertandClaude Opus 4.6 6d4a91f7d0 fix: add viewer-section flex layout to fill viewport
Without flex properties, #viewer-section collapsed to content
height (just the controls bar), giving the workspace 0 height
and causing zoom to compute as 0%.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 18:17:07 -06:00
Alex-GilbertandClaude Opus 4.6 35b898af50 fix: remove unused import, add duplicate redaction detection
- Remove unused detect_redactions import from app.py
- Add de-duplication check in dblclick handler to prevent
  creating duplicate redaction entries for the same dark region

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 18:02:54 -06:00
Alex-GilbertandClaude Opus 4.6 6ca949b233 feat: remap shift+drag to gap width, remove manual marking
Shift+drag now adjusts gap width (was ctrl+shift+drag).
Manual redaction marking via shift+drag is removed;
users now double-click to spot-detect redactions.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 18:00:45 -06:00
Alex-GilbertandClaude Opus 4.6 dc40c1db00 feat: replace double-click zoom with spot redaction detection
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 18:00:08 -06:00
Alex-GilbertandClaude Opus 4.6 3d739b13f5 feat: add toast notification system
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:59:40 -06:00
Alex-GilbertandClaude Opus 4.6 fe9eb289ac feat: remove auto-detection from upload pipeline
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:59:00 -06:00
Alex-GilbertandClaude Opus 4.6 7fb5a85634 feat: extract _run_analysis helper and add /api/redaction/spot endpoint
Extract inline analysis logic from the analyze endpoint into a reusable
_run_analysis() helper function, then add a new /api/redaction/spot
endpoint that chains spot_redaction detection with analysis in one call.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:56:48 -06:00
Alex-GilbertandClaude Opus 4.6 5b395a6a8f fix: use _ for unused connectedComponents label count
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:55:18 -06:00
Alex-GilbertandClaude Opus 4.6 c35821dab2 feat: add spot_redaction() for click-targeted redaction detection
Uses OpenCV connected components to find a dark region at a specific
click point, complementing the existing detect_redactions() which
auto-detects all redaction bars via morphological operations.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:53:15 -06:00
Alex-GilbertandClaude Opus 4.6 6e8933f0f4 docs: add spot redaction implementation plan
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:51:12 -06:00
Alex-GilbertandClaude Opus 4.6 25f3705820 docs: add spot redaction detection design
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 17:49:01 -06:00
Alex-GilbertandClaude Opus 4.6 bd42f32cb9 feat: add green overlay, font toolbar, and text edit bar for active redactions
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 15:30:37 -06:00
Alex-GilbertandClaude Opus 4.6 3c867de6aa feat: add offset_x/offset_y to analyze response for alignment guess
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 15:20:11 -06:00
Alex-GilbertandClaude Opus 4.6 23cbfcc862 docs: add text editing & green overlay implementation plan
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 15:18:00 -06:00
Alex-GilbertandClaude Opus 4.6 5606157e37 docs: add text editing & green overlay design
Adds green segment overlay, floating font toolbar, bottom text edit
bar, and backend offset guess to the redaction-centric UI.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 15:13:50 -06:00
Alex-GilbertandClaude Opus 4.6 a481608d41 feat: add shift+drag to manually mark redaction boxes
Hold Shift and drag on the canvas to draw a custom redaction
rectangle. Creates an unanalyzed redaction entry that triggers
on-demand OCR when clicked.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:47:36 -06:00
Alex-GilbertandClaude Opus 4.6 5f2e1c5ec9 feat: rewrite frontend from line-based to redaction-centric UI
Replace line list with redaction list, add canvas-native redaction
overlays with hit-testing, popover with on-demand analysis and
solver integration. Remove old font/segment/overlay controls.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:46:11 -06:00
Alex-GilbertandClaude Opus 4.6 4a8716539d feat: add /api/redaction/analyze endpoint for on-demand OCR + font detection
When a user clicks a redaction, this endpoint crops the surrounding line,
runs Tesseract OCR, detects the font, and returns text segments (before/after
the redaction), gap width, font info, and character-level bounding boxes.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:40:17 -06:00
Alex-GilbertandClaude Opus 4.6 c0f52772ee refactor: simplify upload endpoint to use redaction detection instead of OCR
Replace upfront OCR + font detection + overlay rendering with lightweight
OpenCV-based redaction detection. Upload now just rasterizes and detects
black rectangles, making it significantly faster. Remove the overlay
endpoint and update the data endpoint to return redaction bboxes.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:37:54 -06:00
Alex-GilbertandClaude Opus 4.6 793ab1c970 feat: add OpenCV redaction detection module
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:34:22 -06:00
Alex-GilbertandClaude Opus 4.6 b0e7a3ea9c docs: add interactive redaction UI implementation plan
11 bite-sized tasks covering: OpenCV detection module, simplified
upload endpoint, on-demand analyze endpoint, frontend state rewrite,
redaction list, canvas overlays, popover, manual marking, test cleanup.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:31:51 -06:00
Alex-GilbertandClaude Opus 4.6 48de3857b4 docs: add interactive redaction UI design
Shift from upfront OCR to redaction-centric workflow with OpenCV
detection, canvas-native clickable overlays, on-demand analysis,
and per-redaction popover solver UI.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 14:28:09 -06:00
Alex-Gilbert caf6ec3576 emails in 2026-02-16 14:05:15 -06:00
Alex-GilbertandClaude Opus 4.6 62f25a267c feat: add Emails option to solve mode dropdown
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:43:09 -06:00
Alex-GilbertandClaude Opus 4.6 0f4ef6b816 feat: add emails solve mode with kerning-aware width matching
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:39:19 -06:00
Alex-GilbertandClaude Opus 4.6 cb53f2b8fc fix: add pandas/pyarrow as optional build dependencies for build_emails.py
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:36:55 -06:00
Alex-GilbertandClaude Opus 4.6 0d88d6c0e7 feat: add build script to fetch and merge Epstein-related email addresses
Fetches from 3 data sources (HuggingFace parquet, rhowardstone entities,
Epstein Exposed API) plus 8 court-verified addresses. Merges, deduplicates,
validates, and writes 644 unique emails to unredact/data/emails.txt.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:29:18 -06:00
Alex-GilbertandClaude Opus 4.6 efda2a06fc docs: add implementation plan for email unredaction
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:18:54 -06:00
Alex-GilbertandClaude Opus 4.6 d0a39c6dce docs: add design for email unredaction via known email dictionary
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 13:16:37 -06:00
Alex-GilbertandClaude Opus 4.6 2268e8549e feat: add separate V (victim) badge independent of associate tiers
Victim names are stored as a flat set of lowercased name variants
with no person details — the V badge appears but is not clickable,
protecting victim identities. A result can show both T1/T2/T3 and V
badges simultaneously.

- 15 known victims from public court records → 43 name variants
- Enabler/perpetrator categories promoted to T2
- Purple V badge with pointer-events disabled
- Victim matching uses prefix/suffix combination like associate matching

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 10:31:38 -06:00
Alex-GilbertandClaude Opus 4.6 d0e6a7c47a fix: combine filter prefix/suffix with gap text for associate lookup
When matching solver results against associates, now tries:
- gap text alone ("oe")
- prefix + gap ("joe" if prefix="j")
- gap + suffix
- prefix + gap + suffix

Composite matches (prefix+gap) get a +3 score boost since the
surrounding context confirms the match. Deduplicates by person_id,
keeping the highest-scoring match.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 09:42:35 -06:00
Alex-GilbertandClaude Opus 4.6 368df1a35b feat: clickable tier badges with associate detail popup
Badge is now a button — clicking it opens a popup listing all
matching associates with their tier description (flight logs /
inner circle / named in files), category, and match type.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 09:33:27 -06:00
Alex-GilbertandClaude Opus 4.6 921fafc828 fix: sort associates by tier first, boost with prefix/suffix hints
- Sort results strictly by tier (T1 > T2 > T3 > none), then by score
  within the same tier. Previously a T3 full-name match could outrank
  a T1 first-name match.
- Boost associate score by +2 when the person's name matches the
  user's filter prefix/suffix, surfacing likely candidates higher.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 09:30:15 -06:00
Alex-GilbertandClaude Opus 4.6 eb42b0e179 fix: correct scoring inversion, filter garbage names, add Makefile target
- Fix priority scoring: (4 - tier) * weight so T1 ranks above T3
- Filter upstream redaction placeholders like "(b) (6)" from data
- Add build-associates Makefile target
- Rebuild associates.json (1586 persons, 28 garbage entries removed)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 09:17:48 -06:00
Alex-GilbertandClaude Opus 4.6 dfe78a58f2 feat: frontend associate matching, badges, and priority sorting
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 07:55:47 -06:00
Alex-GilbertandClaude Opus 4.6 4bfe7c85a7 feat: add GET /api/associates endpoint
Lazy-loads associates.json from data dir and serves it at /api/associates,
with fallback to empty dicts if file is missing.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 07:51:07 -06:00
Alex-GilbertandClaude Opus 4.6 b5d2670fa3 feat: generate associates.json with tiered Epstein network data
Fix source_name/target_name field mapping in tier computation, use
compact JSON output (696KB). Stats: 7147 lookups, 1614 persons
(204 tier-1, 38 tier-2, 1372 tier-3).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 07:49:17 -06:00
Alex-GilbertandClaude Opus 4.6 8011cf4da2 feat: add associates data processor with nickname generation and tiering
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 07:46:56 -06:00
Alex-GilbertandClaude Opus 4.6 a0173a2f40 docs: add implementation plan for associates priority dictionary
7 tasks covering build script, API endpoint, frontend matching/sorting/badges,
and end-to-end testing. TDD approach with exact file paths and code.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 07:26:57 -06:00
Alex-GilbertandClaude Opus 4.6 c914028a0a docs: add design for Epstein associates priority dictionary
Defines tiered prioritization of known Epstein associates in solver
results using rhowardstone/Epstein-research-data as the data source.
Associates are matched by full name, first/last, nicknames, and aliases
with frontend-side sorting and badge display.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-16 07:24:06 -06:00
Alex-GilbertandClaude Opus 4.6 fc9eff2da5 test: add round-trip integration test for solver
Measures a known word's width in font context, then verifies the solver
recovers that word from its width. Proves the width table and solver
work correctly end-to-end.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 22:26:20 -06:00
Alex-GilbertandClaude Opus 4.6 556007f5fb feat: frontend solve panel with SSE streaming results
Add a solve panel UI that lets users attempt to recover redacted text
by finding strings whose rendered width matches the redaction gap.
Includes charset selection, length bounds, tolerance slider, and
dictionary/enumerate/both mode controls. Results stream via SSE and
can be clicked to insert into the gap.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 22:24:30 -06:00
Alex-GilbertandClaude Opus 4.6 d391bfa6d6 feat: SSE solve endpoint with dictionary and enumerate modes
Add POST /api/solve endpoint that streams results via Server-Sent Events,
supporting both enumerate (brute-force) and dictionary solve modes. Add
dictionary CRUD endpoints (POST/GET/DELETE /api/dictionary) and solve
cancellation (DELETE /api/solve/{id}). Move static files mount to end of
app.py so API routes take priority.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 22:20:20 -06:00