Commit Graph
38 Commits
Author SHA1 Message Date
Alex-GilbertandClaude Opus 4.6 4a92cb8463 fix: update app tests for mode/charset restructuring
Replaced test_solve_endpoint_dictionary and test_dictionary_crud with
test_solve_endpoint_name_mode testing the new name mode.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-18 13:16:57 -06:00
Alex-GilbertandClaude Opus 4.6 d0bd7967e4 feat: update solve_full_name_dictionary with casing and known_start/known_end
Replaces uppercase_only bool with casing string parameter. Adds
known_start/known_end support for filtering and gap-width measurement.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-18 13:11:53 -06:00
Alex-GilbertandClaude Opus 4.6 d32f27cb8d feat: add solve_name_dictionary for single-word associate name matching
Supports casing (lowercase/uppercase/capitalized), known_start/known_end
filtering with gap-width measurement of the unknown portion only.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-18 13:11:13 -06:00
Alex-GilbertandClaude Opus 4.6 7b0802d005 feat: add solve_full_name_dictionary with Cartesian product matching
Generate first x last name combinations from associate lists, apply
Title Case or UPPER casing, measure rendered widths, and return matches
within tolerance. Also checks associate name variants (initials,
nicknames) with deduplication.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-18 12:00:45 -06:00
Alex-GilbertandClaude Opus 4.6 b50a32a038 fix(solver): add max_results cap to prevent OOM in full-name solver
The full-name solver collected all results into a Vec with no limit,
causing OOM crashes for realistic targets where millions of valid
first×last combinations exist. Thread max_results through
solve_subtree, dfs_first, and the Cartesian product loop so the
search stops early once enough results are found.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-18 11:20:16 -06:00
Alex-Gilbert a5505c1fbb attempting to make redaction guessing better 2026-02-18 10:35:42 -06:00
Alex-GilbertandClaude Opus 4.6 0f9c7ff858 feat: add page analysis pipeline orchestrating OCR, LLM, OpenCV, and font detection
Wire together the per-page pipeline: OCR -> LLM redaction detection ->
guided OpenCV search -> font detection with masking -> pixel alignment.
Includes font caching per line and progress callbacks.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 15:31:17 -06:00
Alex-GilbertandClaude Opus 4.6 8b5511e7fd feat: add detect_font_masked for redaction-aware font detection
Adds a new detect_font_masked() function that masks redaction boxes to
white (255) before running pixel-based font detection on the full line
crop. This replaces the fragile approach of cropping just the left/right
portion of a line, which lost signal from narrow crops and coordinate
mismatches. The Dice-based scoring naturally ignores masked (white)
regions since they contain no ink pixels.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 15:26:14 -06:00
Alex-GilbertandClaude Opus 4.6 c39d74e46d feat: add guided OpenCV search for LLM-directed redaction regions
Add find_redaction_in_region() that searches for a black rectangle
within a specific page region identified by the LLM. Uses a lower
minimum area threshold (100px vs 500px) since the LLM provides
spatial guidance, preventing merged redactions and false positives.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 15:22:28 -06:00
Alex-GilbertandClaude Opus 4.6 51ef030322 feat: add LLM-based redaction detection module
Introduce llm_detect.py that sends OCR lines to Claude Haiku to identify
redaction locations via broken text patterns (garbled chars, brackets,
pipes). The LLM returns boundary words which are mapped back to pixel
positions using OCR character data. Includes comprehensive tests covering
single/multiple redactions, line start/end edge cases, and error handling.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 13:59:49 -06:00
Alex-GilbertandClaude Opus 4.6 a2ef97b349 feat: pixel-aligned text positioning for redaction overlay
Replace OCR-based offset calculation with pixel alignment that slides
rendered text across the page image to find the exact position with
maximum Dice overlap. Also fix char filtering to use center-point
(c.x + c.w/2) instead of right-edge, recovering characters like "nt"
in "Sent" that partially overlap the redaction box.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 13:02:36 -06:00
Alex-GilbertandClaude Opus 4.6 93f4502bfa fix: update score docstring, remove dead SIZE_RANGE, fix unused import
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 11:39:13 -06:00
Alex-GilbertandClaude Opus 4.6 1b863fdf21 feat: wire pixel scoring into _full_search and _fine_search
Replace word-width MAE scoring with pixel-overlap Dice scoring in both
_full_search() and _fine_search(). Both functions now accept a line_crop
parameter and use _score_font_line_pixel() instead of _score_font_line().
Comparisons are flipped (higher is better). The size range is now derived
from the OCR line height instead of the fixed SIZE_RANGE constant, and
uses step=1 since pixel scoring has sharp peaks at the exact font size.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-17 11:33:10 -06:00
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 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 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 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 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 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 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 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 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
Alex-GilbertandClaude Opus 4.6 b357713e5e feat: dictionary solver with in-memory word list store
Add solve_dictionary() for linear-scan matching of dictionary entries
against a target pixel width, and DictionaryStore for managing named
word/name lists. Reuses SolveResult from the solver module.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 22:15:21 -06:00
Alex-GilbertandClaude Opus 4.6 11cc29d3f8 feat: parallel solver with multiprocessing via ProcessPoolExecutor
Distribute branch-and-bound search across CPU cores by generating
depth-2 prefixes and farming each subtree to a worker process.
Includes on_progress callback and automatic prefix depth selection.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 22:12:49 -06:00
Alex-GilbertandClaude Opus 4.6 9021cf8a21 feat: single-threaded branch-and-bound gap solver
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 22:07:41 -06:00
Alex-GilbertandClaude Opus 4.6 696b0165ef feat: width table module with kerning-aware font metrics
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 22:00:12 -06:00
Alex-GilbertandClaude Opus 4.6 b9df273521 Add interactive font tuning UI with split-panel layout
Replace static overlay with client-side canvas rendering. Left panel
shows clickable OCR lines with font controls (dropdown + size slider).
Right panel renders green text overlay on the document via canvas.
Fonts loaded from backend TTF files using the FontFace API.

New endpoints: GET /api/fonts, GET /api/font/{id}

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 20:17:57 -06:00
Alex-GilbertandClaude Opus 4.6 d2b149f1ba feat: per-line font detection with prior bias
Instead of detecting one font per page, detect the font for each line
independently. The previous line's font is used as a prior — if it
scores within 15% of the best candidate, it's kept for consistency.
This handles documents with mixed fonts (bold headers, regular body,
different sections).

Also: redirect / to the static UI, fix data endpoint to return
per-line font info.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 19:24:48 -06:00
Alex-Gilbert a9c394151d test: end-to-end smoke test with visual output 2026-02-15 19:06:24 -06:00
Alex-GilbertandClaude Opus 4.6 8d82054b5d feat: overlay calibration with word-by-word rendering
- Render each word at its OCR'd position instead of whole lines,
  so word spacing matches the original document exactly
- Add y-offset correction using glyph bounding box
- Add fine-grained font size search (±3 around coarse best, step 1)
- Add alignment quality test (48.9% hit rate, >30% threshold)
- Add scipy to dev dependencies

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 19:04:40 -06:00
Alex-GilbertandClaude Opus 4.6 c95b6cb9d7 feat: FastAPI backend with upload, overlay, and data endpoints
Adds POST /api/upload (runs full pipeline: rasterize, OCR, font detect,
overlay), GET endpoints for original/overlay images and OCR data JSON.
Also adds python-multipart, anyio, and pytest-anyio dependencies.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 18:53:48 -06:00
Alex-GilbertandClaude Opus 4.6 73320365a3 feat: green text overlay renderer
Add render_overlay() that composites semi-transparent green text on
the original document image using the detected font. This is the
visual proof mechanism for font detection accuracy. Also adds numpy
to project dependencies for test pixel analysis.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 18:49:39 -06:00
Alex-GilbertandClaude Opus 4.6 2a3a0f2076 feat: font detection by comparing rendered vs OCR'd word widths
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 18:46:07 -06:00
Alex-GilbertandClaude Opus 4.6 b79ca81965 feat: OCR module with character-level bounding boxes
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 18:41:05 -06:00
Alex-GilbertandClaude Opus 4.6 420e20a8cf feat: PDF rasterization module
Add rasterize_pdf() that converts PDF pages to PIL images using
pdf2image. Supports configurable DPI and page range selection.
Includes tests verifying multi-page output, high-DPI dimensions,
and single-page extraction.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 18:38:50 -06:00
Alex-GilbertandClaude Opus 4.6 94877952db feat: project scaffolding with dependencies
Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-02-15 18:36:10 -06:00