Skip to content

research: resolve SEC. 256's text-named accounts to account nodes - #876

Open
willhea wants to merge 3 commits into
developfrom
research/sec256-account-resolver
Open

willhea wants to merge 3 commits into
developfrom
research/sec256-account-resolver

Conversation

@willhea

@willhea willhea commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Why

ADR 0025 (#875) attributes a referential figure, one whose account is named in its text rather than given by its position, only when (1) the text names exactly one account and (2) that name resolves to an account in the same bill's structure. #869 covered (1): H.R. 4366 Senate amendment v4, SEC. 256, now records text_account for its two rescissions. This PR covers (2). Until now, neither figure was attributed.

What changes

docs/research/financial-semantics/figure_example.py, the bounded experiment:

  • resolve_text_account(bill, name) returns the ordinal of the one parsed node whose trailing whole headings spell the name, or None.
    • Only case, whitespace and the separator are normalised. The separator is an em dash ("Veterans Health Administration—Medical Services") or a comma ("Veterans Health Administration, Medical Services"), on both sides, so a heading's own comma ("Military construction, defense-Wide") matches too.
    • It abstains when no node or more than one node matches. It never falls back to the figure's own heading path. There is no fuzzy, substring or leaf-only matching, and a match never starts inside a heading.
  • Figure gains text_account_ordinal and text_account_heading_path. The ordinal, with the record's existing source sha256 and parser revision, is the resolved node's ADR 0019 identity. heading_path, text_account and fiscal_year stay separate facts, and funding years stay None.
  • The README's SEC. 256 section records the rule and the manual findings. The roadmap's Outcome D row and "Next turn" are updated.

ADR 0018 is unaffected: the tree does not change. The resolver reads the parsed headings and changes nothing.

Development examples (not holdouts)

Both are Military Construction and Veterans Affairs provisions; see Reach below.

Provision Resolved Abstains
H.R. 4366 v4 SEC. 256 (em dash) Medical Services id329E…DE3B, Medical Community Care id718C…1041 none
H.R. 1865 enrolled Sec. 253 (comma, 7 names) 6, including the one-heading "National Cemetery Administration" "DOD-VA Health Care Sharing Incentive Fund": the bill funds no such account

Elsewhere in the same lists, H.R. 1865 Sec. 125's "Military Construction, Defense-Wide" matches three headings (titles I, IV, V) and abstains. Its "NATO Security Investment Program" does not match the heading "Security investment program" and abstains. These are limits, not errors.

Corpus check (manual, all filled lists)

Across all 58 bill versions in the corpus, #869's rule fills names in 10 lists (6 bills). I read every name against the bill by hand:

Names Correct
Resolved 26 26: each lands on the account's own appropriation paragraph
Abstained 11 11 follow the rule; none is a missed exact match

The abstentions fall into three groups:

  • Name doesn't match the heading (4): "NATO Security Investment Program" ×4 (heading "Security investment program").
  • One account, several paragraphs (4): "Military Construction, Air Force" ×3 and "Military Construction, Defense-Wide" ×1. The bill appropriates to the same account in a base title and again in an Overseas Contingency Operations or disaster title, so the name matches 2 or 3 headings.
  • No heading for it in the bill (3): the DOD-VA fund (Sec. 253), and a statutory fund named by U.S.C. citation (115-hr-5895, two versions).

Reach: one drafting shape, one subcommittee

"Following accounts in the amounts specified:" occurs only in Military Construction and Veterans Affairs divisions. That is #869's reader, not the resolver. Other subcommittees rescind from named accounts routinely, in shapes text_account does not read yet:

  • "Of the unobligated balances available under the heading X, $N are rescinded": Labor-HHS, State-Foreign Ops, THUD, Agriculture, Energy-Water.
  • Numbered lists "(1) Working Capital Fund, $30,000,000; (2) …": CJS, Homeland Security, Defense.

The names in those shapes take the forms this resolver already handles ("U.S. Customs and Border Protection, Salaries and Expenses"; "Rural Development Programs—Rural Housing Service—…"). A few would need more:

  • an en dash as separator (5 of about 350 "under the heading" names);
  • headings in a prior Act ("in division H of Public Law 114–113");
  • names carrying a Treasury Appropriation Fund Symbol (State-Foreign Ops), which ADR 0025 already names as an independent identifier.

Evidence: manual only

The expected nodes were read from each bill by hand. That makes them an acceptance case, not independent evidence. independent_evidence stays not_checked, and the findings are in the README, not the record.

Tests and negative controls

The SEC. 256 assertions extend #869's existing test, so there is no second parse of the same node. A new slow test covers Sec. 253. A fast test on a constructed bill calls the resolver directly. Each mutation below was applied and its test observed red, then reverted:

Mutation Red test
The two SEC. 256 resolutions swapped (ordinal; separately, heading path) SEC. 256
Resolved heading path taken from the figure's own node SEC. 256
Unresolved name falls back to the figure's own ordinal, or its heading path Sec. 253
Leaf-only match (unique hit, and first-of-several hit) constructed
A name matching no account resolves anyway constructed, Sec. 253
A name matching two account nodes resolves to one constructed
Substring match constructed
Match starting inside a heading ("Defense-Wide") constructed
Fuzzy match (difflib ratio > 0.9) constructed
Comma not treated as a separator constructed, Sec. 253
Case not normalised all three

Gates (run locally on this branch)

  • lint (uv run ruff check .): passed
  • format (uv run ruff format --check .): passed
  • fast (uv run pytest -m "not slow and not browser"): 2368 passed, 4 skipped, 15 xfailed
  • browser (uv run pytest -m browser --run-browser): 30 passed
  • slow (uv run pytest -m slow --deselect tests/test_govinfo_corpus_parity.py): 2232 passed, 30 skipped

Out of scope

Widening #869's list grammar, committing S.Rept. 118-43, the rescission-row check, cross-bill or cross-year matching, abbreviated report names ("Medical Services (MS)"), Treasury Account Symbols, and any classifier, display, export, total, roll-up or cross-version pairing. #736's contribution credit is preserved. #734, #736 and #739 are not touched.

Next

Commit S.Rept. 118-43 as a frozen input and implement ADR 0025's rescission-row check, matching each row to a figure typed as a rescission by resolved account and amount, starting with the VA Administrative Provisions block. That check is what can move independent_evidence off not_checked.

🤖 Generated with Claude Code

willhea and others added 3 commits October 30, 2026 00:23
A referential figure is attributed only when the account its text names
resolves to an account in the same bill's structure (ADR 0025). The
resolver maps a text_account to the one node whose trailing whole
headings spell the name, normalising only case, whitespace and the
separator (em dash or comma), and abstains on no match or several. It
never falls back to the figure's own heading path.

Exercised on H.R. 4366 v4 SEC. 256 and H.R. 1865 enrolled Sec. 253 as
development examples; the expected nodes were read by hand, so
independent_evidence stays not_checked.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant