Show every heading the XML tags in its breadcrumb, and measure the ledger on each kind of bill that appropriates - #739
Conversation
Ordered, fail-closed passes re-read detected headings across the reading order. pdf_text records each line's letter case pattern; pdf_anchors uses it to bound an agency's reach. Pins re-derived for the new parser revision.
Grades every amount T0-T4 against the XML twin and pins the tiers per version. python -m tests.ledger_location prints before/after totals.
ADR 0022 (Proposed). ADR 0018 admits named exceptions; ADR 0012 notes the case pattern. bill-structure.md, signal inventory and TESTING.md updated.
willhea
left a comment
There was a problem hiding this comment.
Hey @mattzamora! Thank you for this work. Preserving headings that the XML explicitly tags is a valuable improvement for change cards, navigation, and the bill tree. I’d like to move that forward, with the following changes. Reviewed with GPT Sol 6.1 High.
1. Separate this work from #736.
This branch includes #736’s commits, so merging it would also introduce the financial displays and data changes discussed there. Please separate the heading improvements from that integration and make any remaining dependency on #734 explicit.
2. Revise ADR 0024’s approach to ambiguous heading scope.
My preference is to recover the structure the input supports and accept documented limitations where it does not. PDFs will often produce less complete structure than XML. We should improve that with defensible general rules, while allowing some gaps to remain.
That approach is already reflected in accepted ADRs 0012, 0014, and 0018. ADR 0018 states: “A shallower breadcrumb that is true beats a deeper one that is invented.”
Proposed ADR 0024 makes a different tradeoff. It acknowledges that the XML does not establish where some headings stop, then carries them over subsequent sections. For example, in tests/corpus/118-hr-4366/2_engrossed-in-house.xml, SEC. 421 changes from:
TITLE IV → GENERAL PROVISIONS → sec. 421
to:
TITLE IV → GENERAL PROVISIONS → SPENDING REDUCTION ACCOUNT → sec. 421
SEC. 421 concerns Veterans Affairs restrictions involving state marijuana programs. The additional parent relationship is misleading.
Please revise the ambiguous-scope decision and its implementation. Preserving a heading should not require making it the parent of unrelated content. I would accept shallower breadcrumbs where the relationship cannot be established.
3. Keep agreement metrics subordinate to source correctness.
ADR 0024 reports better PDF/XML agreement under the broader scope rule, but agreement does not establish correctness when both readers make the same assumption. Please also qualify the claim that the remaining disagreement is necessarily the PDF’s error.
Similarly, I support ADR 0022’s general typography and reading-order improvements, but the named wording exceptions and associated relaxation of ADR 0018 remain a separate decision. They should not be assumed accepted through this PR.
4. Strengthen the tests around placement and repeated headings.
The new rule tests are meaningful: in focused verification, all 14 passed with the new reader, and 10 failed with the previous reader.
The corpus coverage check only establishes that each heading name appears somewhere. It can pass after incorrect placement or loss of a repeated occurrence. Please add focused checks that fail when unrelated content inherits a heading, including SEC. 421, or when a repeated heading occurrence disappears. Retain the existing matching controls without duplicating them.
I’m requesting changes because these scope decisions need resolution, while the underlying heading-preservation work is worth keeping.
…dc#115) Schema 3.1 adds an optional financial field: for each version on its own, every dollar amount with its chain of headings, its clause, a type read from the wording by the research notebook's rules (classifier 1.0, moved into the package unchanged) and flags. A change still carries no money. PDF sections are read so they give the notebook's rows: gutter and running header off, page-seam hyphens rejoined, paragraphs split where the XML has nodes, quote marks removed for the rules only. The report gains Inferred Financial Comparison, Financials - Version A and Version B, each with a CSV export and a not-authoritative alert. Find also searches collapsed rows; each tab keeps its scroll position; jump targets clear the sticky bar at its measured height; the change navigator and changes export show only on Changes and Full bill. The PDF heading keeps the whole bill title and an upload label is the file name as given. The civictechdc#671 no-money checks now look where civictechdc#671 drew the line, the Changes view. Canonical baselines re-pinned: the digests move by the new field only.
ADR 0023 (Proposed): the per-side ledger, reading PDF sections for the notebook's values, why the classifier is versioned and how it improves, the three views, and the open question on money in the API's JSON. ADR 0006 amended in place; schema doc at 3.1; TESTING.md gains check 8 and the financial rows pin; research README records that the classifier moved into the product.
… each kind that appropriates (civictechdc#733) The XML reader keeps a heading that carries no text of its own in display_path, placed as the page lays it out, and builds match_path exactly as before: every other field is byte-identical on every node, and no pairing digest moves. The corpus gains a continuing resolution, a supplemental, a second reconciliation bill and an authorizing law with an appropriations division; every manifest bill names its vehicle and the ledger report totals per vehicle. Pins regenerated with their evidence in the PR.
ADR 0024 (Proposed): display_path shows every heading the XML tags, placed as the page lays it out; match_path unchanged. ADR 0022 points to it where it deferred the reader change; bill-structure.md and TESTING.md updated for the reader and the per-vehicle ledger totals.
d4841a7 to
e7229c7
Compare
|
@mattzamora, the class renames, schema-version folding and stylesheet move described on #736 (#736 (comment)) apply here too, since this branch is stacked on it: the same |
Records the three root causes, the target stage layout and decisions D1-D6, with D1 (per-document node identity) made concrete as the minimal slice to settle before #736 merges. Compares the three open PRs against the node-identity gap, with F4b re-measured on #739's code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEnpabyUh8apyPahzKyrj4
|
@mattzamora, a note on overlap with #525 (a section with only a heading is dropped by the XML reader, and the provision after it loses its account and chapter headings). Its rewritten body has the cause and a synthetic repro.
On your 2026-09-28 request: #732 is now typed Bug and assigned to you. We couldn't assign #524 too. GitHub only lets us assign someone without repository access who has commented on that issue. A short "claiming" comment on #524 is enough, and we'll assign it. Generated by Claude Code |
Related issue
Closes #733
Closes #521
Depends on #736, which depends on #734. This branch is built on #736's branch, so its first six commits are those two pull requests'; review from the seventh. It will be rebased onto
developas they merge.Related: #557 (a display-only change to a heading can alter the structure tree, and no test would catch it), #474 (an account whose name and money sit in separate elements), #468 (a display change that rewired diff pairing), #519 (the PDF subsection detector misses catchline subsections on engrossed-amendment prints, and leaks quoted-block ones), #115 (financial semantics).
What does this change?
The XML reader now shows every heading the bill's XML tags in its breadcrumb. GPO often marks a heading up as an element of its own, a heading and no text, with the text it heads in the elements after it. The reader kept such a heading only while it sat in one of two slots, so it dropped 2,744 of the 10,172 on the committed corpus:
North atlantic treaty organizationover its security investment program,Food and drug administrationover its first account,ADMINISTRATIVE PROVISIONS—FEDERAL HIGHWAY ADMINISTRATIONover its sections, a reconciliation bill's fourth level of nesting. They now appear on change cards, in the sidebar and the tree, as heading lines in the Full bill view, and as locations in the financial views.The key the diff pairs sections on (
match_path) is built exactly as before. The breadcrumb (display_path) is built beside it from the same walk, so a heading shown in the breadcrumb cannot re-pair a section. Where the XML does not say how far a heading reaches, the breadcrumb follows the page's layout: a section sits under the nearest heading printed above it, until the next heading. Decision record: ADR 0024 (Proposed).The corpus now has one bill of each kind that appropriates money, and the ledger check reports each kind separately. Added: a continuing resolution (118-hr-5860), a large supplemental (118-hr-815), a second reconciliation bill (the Tax Cuts and Jobs Act, 115-hr-1) and an authorizing law with an appropriations division (the Bipartisan Safer Communities Act, 117-s-2938). Every bill in
tests/corpus_manifest.tomlnow names itsvehicle.Evidence
Diff pairing did not move. Every field the reader emits except
display_pathis byte-identical before and after, on every node of 116 XML files (the committed corpus and the fetched bills);display_pathonly gains headings. The round-1 pairing sentinel, re-stamped, changes only its parser-revision field on all 27 existing pairs: no pairing digest moved.Every tagged heading reaches the breadcrumb. A new corpus gate,
tests/test_corpus_properties.py::test_every_heading_the_file_tags_reaches_a_breadcrumb, checks the reader against the raw file's heading tags: it passes on every committed XML file, and with the previous reader 45 of the 63 fail it.#521 (provision-group and agency-container headings reach no node in the parsed tree), by its own measure. Distinct headers in the raw XML that appear in no node's heading or breadcrumb, on the paired bills #521 measured: 118-hr-4820 9 → 0, 118-hr-4366 4 → 0, 114-hr-2029 3 → 0, 115-hr-5895 2 → 0, 117-hr-4502, 118-hr-8774 and 118-s-4795 1 → 0. All nine of 118-hr-4820's reach the leveled tree as nodes of level
heading, notaccount, and the account vocabulary inscripts/heading_precision.pyis unchanged: it is built from the headings nodes carry, which this does not touch. That is #521's verification as written; if a different node type is wanted, drop theCloses #521line.Where the PDF files each dollar amount, against the XML (the ledger check from #734), per kind of bill. "OK" is same place, same place relabeled, or true but shallower:
The versions pinned before this change, before → after (only the XML answer key moved; the PDF reader is unchanged):
The versions this change adds:
Reconciliation is "OK" but rarely in the same location: its print has no subtitle or part level, so the PDF files its amounts true but shallower (a known residual in ADR 0022). No pinned version got worse; 23 improved. The regular and omnibus rows are where the XML answer key changed: the PDF was being graded "wrong parent" for headings it printed and the reader dropped.
The new kinds expose a PDF gap, now pinned rather than fixed here: on the supplemental's House version and the authorizing law, the PDF reader misses agency and account headings, so an account's money is filed under another account or under a title with no account (58 of 127 and 45 of 59 amounts). Filed as #738 (on a supplemental and an authorizing law, the PDF reader misses account headings, so money is filed under the wrong account).
Choices a reviewer should check
ADMINISTRATIVE PROVISIONS—…over SEC. 120 to 126). The known cost: a section with no heading of its own after a single-topic heading is filed under that topic, 71 sections on the committed corpus (SEC. 421 of 118-hr-4366 v2, a floor-added restriction, underSPENDING REDUCTION ACCOUNT), exactly as the PDF reads it. The alternative, one section per heading, never does that but shows every provisions block one level shallower than the page (98.0% against 98.9% OK). A heading over the next account of its own level heads only that account (FDA overSalaries and expenses, not over the accounts after it): the XML carries none of the typography the PDF uses to bound it.vehicleis the bill's, not the version's. 117-hr-2471 and 118-hr-2882 areomnibusalthough their introduced text is something else: both became an omnibus.Pins regenerated, each with its cause
tests/data/canonical_baseline.json: 22 of 27 XML pairs change digest and byte count, every one with its change count and summary identical; 2 pairs added.tests/data/pdf_canonical_baseline.json: all 23 pairs unchanged; 2 pairs added (the continuing resolution's is declined: its enrolled print has no line numbers).tests/data/round1_pairing_sentinel.json:parser_revisiononly on the 27 existing pairs; 2 pairs added.tests/data/ledger_location_baseline.json: 23 versions improved, none worse; 5 versions added.tests/test_round1_stages.py: similarity-call table gains the two pairs (0 and 12; total 1,108 → 1,120).tests/test_pdf_round1_revocation.py: split population 225 + 6 → 263 + 7, all of it the two new pairs (38 accepted, 1 declined).tests/test_pdf_subsection_recall.pyEXPECTED, the zero-anchor registries,_KNOWN_DUPLICATE_COUNTS(118-hr-815 v5: its twenty divisions each number sections from 1) andALLOWED_CORPUS_SKIPS(the continuing resolution and the reconciliation bill carry no appropriations headings): entries for the new bills, each with its reason.examples/hr4366_*_xml_diff.html: re-rendered; the breadcrumbs gain the headings. The PDF and H.R. 8752 examples and the web sample are unchanged.Docs
ADR 0024 (new, Proposed) and its index row; ADR 0022 points to it where it deferred the reader change;
docs/bill-structure.md(the reader shows header-only headings; the tree nests sections under their provisions heading on both pipelines);TESTING.md(check 7's limit, the ledger pin's answer key, totals per kind of bill);tests/corpus_manifest.toml(thevehiclefield and the new bills' notes).How to test
To see it on a page: compare
tests/corpus/118-hr-4366/1_reported-in-house.xmlwith2_engrossed-in-house.xml. The change card for SEC. 420 readsTITLE IV > GENERAL PROVISIONS > SPENDING REDUCTION ACCOUNT > sec. 420(wasTITLE IV > GENERAL PROVISIONS > sec. 420), and the sidebar groups those sections underSPENDING REDUCTION ACCOUNT.Test results (local, WSL)
ruff check .andruff format --check .: clean.-m "not slow and not browser"): 2,142 passed. The 8 failures are the checks that every fixture is committed, which pass once the 12 new files are staged, andtest_every_cli_command_appears_in_the_readme_command_reference, which fails only because this machine's Windows mount reports every file as executable (git recordstools/fetch_govinfo.pyas 100644; the test passes on agit archiveexport with real modes).-m browser --run-browser), run on Windows: 48 passed. Its scroll and jump-link tests build their report from the committed H.R. 4366 XML with this branch's reader.developon Windows (backslash paths, executable bit, CI-report checks, line endings). A fresh render of every committed example on Windows equals the committed bytes once CR is removed (On Windows, regenerating the example reports fails, because the renderer writes OS-dependent encoding and line endings #737).tests/test_engine_installs.py), run on Windows: 7 passed, against a wheel freshly built from this branch.Checklist
Closes #733)AI assistance
Claude Code (Claude Opus 5.5) wrote the code, tests and docs under the contributor's direction; the contributor decided how far a heading reaches after reviewing the three cases on the printed pages.
🤖 Generated with Claude Code