fix: rewrite PDF extraction -- real bytes, one clean read, geometry-based markup flag - #82
Merged
Conversation
…ased markup flag Three fixes to actions/extract's PDF handling, all found while investigating why a bill's extracted text was duplicated: 1. Raw PDF storage bug: the "original content" file (e.g. H0493_Bill_Text.pdf) was never actually the real PDF -- it was the already-extracted text, re-saved under a .pdf-looking filename, written in text mode. The real downloaded bytes were discarded after in-memory processing. extract_pdf() now returns the genuine raw_bytes alongside the extracted text, and text_extraction.py writes them in binary mode. This matters because handing the real PDF to a vision-capable model is the plan for redline-heavy bills going forward -- can't do that with a mislabeled text file. 2. Duplicated output: every extracted .txt file wrote the same content twice, once as a "Section N:" breakdown and once as "Raw Text:". Section detection (in all three extractors -- XML, HTML, PDF) never reliably produced more than one section for most real bills (the PDF regex in particular broke on any state that numbers every line, i.e. most of them), so the whole document became "Section 1" and then got printed again in full as the raw text dump. Dropped section-splitting entirely in favor of one clean read -- arbitrary formatting-based splits don't reliably capture anything meaningful across 56 states' differing bill formats anyway. 3. Strikethrough detection replaced with a geometry-based visual-markup flag. The old is_likely_strikethrough() guessed off font name/character spacing/color -- unreliable proxies that don't actually correspond to how most legislative PDFs render strikethrough, and its character-by- character text reconstruction (joined with no separators) produced unreadable garbage even when it did fire. Replaced with a check for actual drawn line/rect objects (pdfplumber page.lines/page.rects) overlapping a character's vertical span -- catches both strikethrough (deleted text) and underline (added text), which matter equally for knowing a document needs full-fidelity handling rather than plain text extraction. This is a routing signal (has_visual_markup), not an attempt to reconstruct the marked text ourselves. Verified against ID H0493 (a real redline bill): raw bytes now start with the genuine %PDF- magic bytes, text is a single clean 2545-char read with no duplication, and has_visual_markup correctly detects true. Verified false on a synthetic clean PDF with no drawn marks. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Merged
4 tasks
tamara-builds
added a commit
that referenced
this pull request
Jul 21, 2026
…ching session config (#90) ## Summary - Adds `rebuild_data_repos.py`: archives a locale's current `govbot-data` repo (transfer to `govbot-archive`, full git history preserved, then marked read-only) and recreates it fresh, so format/extract-text rebuild from scratch with no inherited incremental state to trust or distrust. - Motivated by lingering doubt about incremental-skip state after tonight's DC/MA/NY ad hoc repo deletions and the PDF-extraction bug fix (#89 / PR #82). - Reuses `close_session.py`'s transfer/rename/archive primitives and `apply.py`'s `create_repo`, but deliberately never writes `locales.<locale>.session` in either config file — this isn't a legislative session closing, and writing that field would plant a misleading marker for real close-session decisions later. - Renames **before** transferring (reverse of `close_session.py`'s order): `govbot-archive` already holds a same-named placeholder repo for every locale from this morning's migration, and GitHub's transfer API rejects a transfer outright if the source name already exists at the destination — no atomic rename-during-transfer option. - Transfers retry with backoff — confirmed via an IL pilot that GitHub can return a transient "previous repository operation in progress" lock immediately after the pre-transfer rename. - Detects and resumes a locale whose rename succeeded but transfer didn't (rather than treating it as missing) — the exact state the IL pilot landed in mid-run. ## Test plan - [x] Dry run against a single untouched locale (`ca`) — all 5 steps report correctly - [x] Ran for real against `il` (the pilot) — hit and fixed the two issues above live; final state verified: `govbot-data/il-legislation` fresh and active, `govbot-archive/il-legislation-pre-rebuild-2026-07-21` archived read-only with full history, this morning's `govbot-archive/il-legislation` placeholder untouched - [x] Re-ran dry run afterward — correctly refuses on `il` (already done) and proceeds cleanly on `ca` - [ ] Not yet run at `--all-states` scale — planned as a follow-up once this PR is in 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three fixes to `actions/extract`'s PDF handling, all surfaced while investigating why a bill's extracted text was duplicated (ID H0493):
Test plan
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com