Skip to content

Aggregate-table captures and readers, part 1 (D4) - #574

Merged
MaxGhenis merged 36 commits into
masterfrom
ir/d4-20261024
Nov 3, 2026
Merged

MaxGhenis merged 36 commits into
masterfrom
ir/d4-20261024

Conversation

@MaxGhenis

@MaxGhenis MaxGhenis commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

This is part 1 of milestone D4 of the income-and-resources design (#559: the D4 row of the milestone table). It adds pinned captures and parsers for aggregate tables. Part 2 adds the SSA and BLS sources that refuse plain requests, through Internet Archive captures. Thirteen independent review rounds asked for fixes. 8cb397f5, on 17bdcf00, fixes round 13's one medium finding, a regression against the parent. The round's low findings change no record on a pinned input, so they stand as the limits listed under Open items, and the claims they falsified now say less. The round-14 delta review approved 8cb397f5. Since then we merged master into the branch four times and recounted the tiers three times. Only the merge of 89d064b5 conflicted outside the tier files; it combines D4's birth-evidence exclusions and reachability checks with #573's SSI0 additions.

What it adds

  • Captures in data/external/snapshots/income_resources_d4_v1/: 54 pinned sources. Each per-source manifest records time, size, SHA-256 and URL. A folder-level .gitattributes (* -text) keeps the 37 captures with CRLF line endings byte-exact.
  • Registries: 874 entries, comprising 861 numeric tables and 13 references:
    • SSA Annual Statistical Supplement Tables 4.B1, 4.B2, 4.B10 and 4.B11;
    • 777 POMS SI 01415 annual state-supplement payment charts;
    • POMS RS 01505 and SL Section 218 coverage references;
    • 18 Federal Reserve Z.1 tables (June 2026 codes);
    • 52 DOL Private Pension Plan Bulletin tables (2023 edition);
    • ten IRS SOI IRA tables (tax year 2023).
  • Readers (src/populace_dynamics/income_resources/aggregate_*.py):
    • every public reader checks the capture's size and SHA-256 before reading a cell;
    • they return typed cells, with table, row, column, unit and year.

Invariants

  • Hash and size match before a reader reads any cell.
  • Missing, suppressed and unavailable cells stay None, never zero.
  • Valid separators and footnotes keep magnitude and sign. Malformed numbers refuse without echoing their content.
  • HTML spans keep a rectangle, its hierarchy and its footnotes.
  • Duplicate cell identities refuse.
  • POMS cells keep state, claimant, living-arrangement code and category.
  • The POMS reader reads a State's code definitions from every definition table in its section and merges them. A code that two tables define differently refuses. A jointly published code ("C/H", "A or B") names each single code, and a full-width note row defines no code.
  • The POMS reader reads every chart's selector (State, claimant type, effective date and definition tables) right, or refuses with TableStructureError, on every form its module docstring says it reads. The docstring's Not modelled, Limits and leave-standing lists name the forms it does not read that the review probes found, among them an abbreviation without its period, text outside any block or in a chart's own caption, a long line of prose, an effective-date sentence of 80 characters or more whose second date takes another form, a claimant named in other words than its three claimant words, a date with a two-digit year in a form no sentence reads ("January 1, 31"), a date split across two blocks, a date split across a <br> in a block of 80 characters or more, a date in a form no list names ("July 1", "7/1", "July of 2030"), and a short line outside a heading that holds only years before the dates in force and no dating word. The tests pin the round-12 review's table rows and witnesses and many of the listed limits; neither the tests nor the lists show that no other form exists.
  • Every block that ends a paragraph, apart from a table or rule, names its State, claimant or date from its own text, read whole and line by line. A line ends at a <br> and where a nested block starts or ends, and drops Unicode format (Cf) characters and the text of script and style, which HTML does not render, a footnote marker's text included. The reader reads each block's whole text and each line five ways:
    • joined, as HTML renders inline text;
    • bare, without footnote markers: a sup, or a link to an anchor on the page (href="#..."), whose text is one to three word characters or footnote signs. A longer sup, or a link elsewhere, is text, so no word of prose vanishes;
    • spaced, with a space at every element edge;
    • unmarked, for the date checks only: without any element either marker rule counts, the bare reading's markers and any sup or link whose href holds "fn".
    • unlinked, for the date checks only: the unmarked reading without any link whose text has a marker's size, wherever its href points.
  • A State heading and a claimant come from the joined or bare reading, so Utah<sup>1</sup> heads Utah. Every State net reads all three readings, so no inline edge hides a State.
  • The reader chooses the date sentence from the joined reading. It refuses when its bare, unmarked or unlinked reading states other dates or a range the joined one does not, so a marker by either rule, or a link of a marker's size whatever its href, inside a date (January 1<sup>2</sup>, 2031, January 1<a href="0501415010#note5">5</a>, 2031) changes no date silently; the page refuses. A line that is a dated sentence only in its bare, unmarked or unlinked reading refuses too, unless what those readings drop all leads it, as a footnote body's markers do (<sup>1</sup>Effective ...), which dates nothing. A block's whole text is its sentence when it is one; otherwise each line that is one dates the block, and lines that date differently remain named alternatives. A range is "effective from", a date, "to" or "through", and a date; it dates a chart from and to, in its own order, when its two dates are the only ones the sentence states, and other dates remain named alternatives. A "to" that no date follows ends no range, and a range that does not end after it starts refuses, one from a date to the same date included.
  • A section's date stands until another sentence or State heading. A heading, or a line under 80 characters, that names a date no sentence of its block or section states, in a sentence's date form ("Payment levels as of January 1, 2031", "Effective: January 1, 2031") or one of these others ("Jan. 1, 2031", "January 2031", "1 March 2031", "2031-03-01", "July 1st, 2030", "1st of July", "July 1,2030", "July 1 , 2030", "07.01.2030", "2030/07/01", "7/2030", "as ofJuly 1, 2030"), leaves the date unread, and the next chart refuses unless a later sentence dates it; a date in one of those other forms does so even in the section's own year, apart from an ISO date that equals a date in force. So does a heading that holds a four-digit year from 1900 to 2099 outside the years of the dates in force, and a line under 80 characters that holds a later year, or an earlier one with a dating word ("payment", "level", "effective", "as of" or "rate"), as "Payment levels for 2031" or "Payment levels for 2029" in a section dated 2030. Each line names its own dates, without a revision range in title case, and a heading's whole text, or that of a block under 80 characters, adds the dates it names more often than its lines do, as one split across a <br>, though a revision range on a line still counts among the lines. Outside a heading, a footnote body dates no chart: a line, or a block's whole text, that opens with markers by either rule, every word they drop one to three digits or footnote signs or a single letter.
  • Only a claimant line names a chart's claimant: a heading form ("a. Individual payment levels for Nevada", "Couple") or a caption ending with its claimant word after a State date line or effective-date sentence that ends with a date or a State ("Utah Effective 1/1/03 Individual"). A block with a claimant line names every claimant word, or its plural, that any reading of its whole text or lines holds, so a block names at most one claimant type, across a <br> as within a line. A heading, or a line under 80 characters, that holds a claimant word or plural but is no claimant line ("Couple payment levels:", "Eligible couple", "Couples") names a claimant the reader does not read: the next chart refuses unless a later claimant line names one, and one that holds both types refuses as naming two. Prose of 80 characters or more outside a heading names none, though the State guard reads it. Every chart needs its own claimant line.
  • Every line passes the State guards, including the lines of a block whose whole text is a State date line, which do not head a section. A line that dates another State refuses, and so does an effective-date sentence, or a line that mentions a claimant, that names any State but its section's. The guards recognize a State date line by the names, D.C. aliases and postal suffixes a section heading takes. A block whose lines head two States refuses, as does a line shaped as another State's heading inside a whole-text date line, and any line shaped as a State heading whose postal code is not that State's.
  • Every line of an h1–h6 heading may name only its section's State. A line under 80 characters, in a block of any kind, that opens as another State's caption refuses: after optional leading dashes, bullets, asterisks, quotation marks or parentheses, a list label ("1.", "2)", "(b)"), a heading prefix, "The" and "State of", that State's name, spelling, D.C. alias (read first, so "Washington, D.C." is the District), abbreviation or upper-case postal code, as "Utah (continued)", "(b) Utah", "The State of Utah", "N.J. notes" or "UT (continued)". Any other line under 80 characters that names another State, as "Supplements for Utah", refuses too. Prose of 80 characters or more may name any State.
  • "Washington,DC" names the District and "Hawaiʻi" names Hawaii; postal codes, in parentheses or upper case standing as a word, and 14 abbreviations name States to the nets but never head a section. A lower-case word that spells a postal code, as "de" in "de facto", names none. Until the first State heading opens a section, no net that needs one runs.
  • The shared HTML tree builds paragraphs, headings, lists, buttons, cells, rows, table sections, captions and colgroups as the WHATWG parsing rules do, end-tag scopes included, so selectors do not depend on omitted or stray end tags. It reads CR LF and a lone CR as one newline, drops a newline that comes right after a pre, listing or textarea start tag, and gives a later html start tag's attributes to the html element, the document root standing for one HTML implies. It does not model the adoption agency rules or HTML's reopening of a formatting element left open, foster parenting, leading content HTML moves into an implied head, a form start tag inside an open form, a self-closing slash on another non-void element, or foreign content (svg and math, which HTML parses by other rules); no pinned capture opens a form inside another. Since HTML ends an svg or math at its breakout start tags (h1–h6, p, div, li, table, b, span and others) and keeps other HTML names there as foreign elements, the tree lets only svg and MathML elements start inside svg or math, and refuses a page on which svg or math ends other than at its own end tag, the end of the page included. It does not model an HTML element built inside an integration point: in <svg><foreignObject><g></svg> HTML ignores the end tag and keeps the svg open, while the tree ends it. A CDATA section holds no text in the tree, though HTML reads one inside svg or math as text. The tree reads a page the same way under Python 3.13 and 3.14: it pins raw text to HTML's six raw-text elements (script, style, xmp, iframe, noembed and noframes; noscript stays markup, as with scripting off), and a plaintext start tag or an abruptly closed empty comment refuses, and so does a script whose text holds <!-- and then a script start tag, which HTML's script data escape states may run on past its next </script>, a self-closed raw text or RCDATA start tag (<script/>), whose slash HTML ignores outside svg and math, and a raw text or RCDATA element inside svg or math whose text holds <, which HTML reads as markup there. A later html start tag only adds the attributes the html element lacks, the tree ignores a noscript end tag with a special element open inside it, and a table part's start tag outside a table builds nothing, as in html5lib.
  • No reader function calls itself; the tree builder, the document walk, the line, marker and cell readers and the chart skeleton keep their own stacks. A probe parses and iterates a page nested 300,000 deep under a recursion limit of 200, and a test reads a chart cell nested 50,000 deep in its own process.
  • Every chart code has a definition, or poms_open_questions.json records the chart. We infer no definition.
  • Payment-validity dates stay distinct from section-revision dates. Conflicting dates stay named options, within one sentence or across a block's lines.
  • Narrative state coverage text stays cited text. It never becomes an observed coverage share.
  • Totals reconcile within rounding, or keep a named published discrepancy without repair.
  • The parsers contain no print or logging calls.

Open items

  • POMS:
    • Fifteen Iowa (2006–2011) and Pennsylvania (2008–2010 couple) charts publish codes that no definition table in their section defines. We record them and leave their codes undefined.
    • The District of Columbia's 1999 tables carry two conflicting dates, so the year stays unknown.
    • Two Hawaii couple tables (2022, 2023) each have one malformed amount, which stays missing with named options.
    • Thirty selectors carry 33 published component-versus-total discrepancies. We flag them and correct none, and SSI2 adjudicates them before using them as conformance truth.
  • HTML limits, documented in _HTMLTree, _cell_token and the POMS module:
    • The tree does not model HTML's adoption agency rules, its reopening of a formatting element left open (in <h3>w0<b><i>w1</b>w2<h4>w3, HTML's h3 reads "w0w1w2w3" and the tree's "w0w1w2"), foster parenting of content misplaced in a table, leading content HTML moves into an implied head, a self-closing slash on another non-void element, or foreign content. So it refuses a page on which an element other than svg and MathML ones starts inside svg or math, breakout tags and HTML inside svg's foreignObject or MathML's mi included, on which svg or math ends other than at its own end tag, or whose script, style or title there holds <, and it refuses any self-closed raw text tag. The stated limits below name what that rule misses. The 40 pinned HTML captures hold 159 svg icons of path, title and desc elements and no math, so no pinned page refuses.
    • A <br> or nested block in one cell joins its lines with a space, so two amounts stacked that way would read as one space-grouped number. No pinned cell joins two amounts by a <br> within one paragraph. POMS charts stack amounts in paragraphs, which the reader splits into subrows.
    • The POMS nets read text that HTML or CSS hides, other than script and style (the hidden attribute, for one), as text. They never read a caption in a table cell, a chart's own caption element or text outside any block. They over-refuse where an acronym spells a postal code, as "MA" or "IA" in Pennsylvania's section, on a short line that names another State anywhere, on a heading or short line that names two claimant types or a date no sentence states, on a heading that holds a year outside the dates in force, on a short line that holds a later year, or an earlier one with a dating word ("Separate programs for 2029", whose "Separate" holds "rate"), on a number shaped as a dotted date ("Section 2.1.10"), on a footnote marker of two letters or of a digit and a letter, on a heading that opens with a footnote marker, on a link of a marker's size inside a date, and on a range from a date to the same date. No pinned page refuses.
  • Stated limits from round 13. These hold on invented pages only. They change no record on a pinned input, and the checks under the thirteenth review's entry show that. None covers a reader over PE-US sources.
    • Integration points: <svg><foreignObject><g></svg>, and the same shape in desc, title, mi, mo, mn, ms, mtext or annotation-xml, ends the svg in the tree while HTML keeps it open, so later blocks and cells read here and stay foreign in HTML.
    • CDATA: a CDATA section holds no text here. HTML reads one inside svg or math as text, as <svg><text><![CDATA[Couple]]></text></svg> reads "Couple", and in HTML content reads the text after its first >.
    • Split date beside a revision line: Effective Dates: 03/01/2031 - Present<br>Payment levels as of March 1,<br>2031 keeps the section's date.
    • Split date in a long block: a date split across a <br> in a block of 80 characters or more, outside a heading, names no date unless the block is an effective-date sentence, so a split date in a year in force keeps the date before it.
    • Dates with no year: "July 1", "July 1st" and "7/1" name no date: the date before them stands, and in a sentence the sentence's other dates stand alone.
    • Other date forms: "July of 2030", "01-Jul-2030", "Jul-01-2030", "July first, 2030", "2030 July 1", "July the 1st, 2030", "July 1, '30", "7 - 1 - 2030" and "1.VII.2030" name no date: the date before them stands unless the year net reads their year, and in a sentence the sentence's other dates stand alone.
    • Footnote bodies: a leading link or sup of one letter or digit makes a footnote body even where it opens a word or a year, as <a href="#top">A</a> new payment level applies from March 1, 2031 or <a href="#y">2</a>031 payment levels, so its date or year dates no chart.
    • Lower-case revision text: Effective dates: 03/01/2031 - Present reads as a sentence and dates the chart, since the label reads in title case only.
    • Title-case label in a long sentence: "Monthly payment levels effective January 1, 2031 (Effective Dates: 01/01/2031 - Present)" names no date, and a long line that holds the label and another State's name passes the effective-date sentence's State guard.
    • Second title-case range: a second "Effective Dates:" range in a section drops from its line and dates no chart.
    • Where the section's revision dates come from: the first title-case range anywhere on a page sets them, a script or a table cell included.
    • Dating words: "Amounts for 2029", "Benefit standard 2029", "COLA 2029", "2029 supplement amounts", "Supplement for 2029", "FBR 2029", "Chart for calendar year 2029" and "In 2029:" hold an earlier year and no dating word, so they keep the section's date.
    • Nested svg: parse_html's raw-text check walks every svg's whole subtree, so nested svg parses in quadratic time: 0.27 s at 4,000 levels, and the review estimates 40 s at 50,000.
    • Refusal message: aggregate_tables.py says "HTML element other than svg or MathML" for svg a and filter, which refuse because they sit outside _FOREIGN_VOCABULARY.
    • Mutants: Z1, Z2, Z3, Z5, Z6, Z7, Z8, Z9, Z10, Z12, Z14 and Z15 of the review's set survive its prescreen of the test module's pages, so no test pins their forms.
  • Census Annual Survey of Public Pensions: the data portal refused a plain request (SOURCE_BLOCKED), so we infer no coverage share.
  • Part 2:
    • SSA Supplement Tables 7.A–7.E and 3.C6;
    • the SSI Annual Statistical Report 2025;
    • SSI Recipients by State and County 2025;
    • BLS NCS benefits.

Review and fixes

The first review found that the POMS reader kept only the last definition table, so California 2004 lost codes A–F. The fix reads every definition table in the State's section. It also surfaced three more reader problems, now fixed:

  • The reader did not recognize the 2009 and 2010 headings "New Jersey (NJ)", so it labelled four New Jersey charts Nevada. The fix renames their registry entries new_jersey.
  • Iowa 1999–2005 defines codes jointly ("C/H", "D/I"); each joint row now defines both codes.
  • The reader took a full-width note row in Massachusetts 1999 for a code; it now skips the row.
  • A State named only in an "X Effective" date line would have kept the previous State's definitions. That path now refuses; no pinned capture uses it.

The fix adds these checks:

  • definition codes match an independent raw-HTML locator on all 777 charts;
  • registry selectors equal the structural reader;
  • each chart's State matches the State its date sentence names (775 charts name one);
  • a California 2004 regression;
  • Hypothesis properties for definitions split across tables and for joint codes.

Each of the four bugs, reintroduced, fails at least two tests. The birth-evidence seal's exclusions list the five new source files, with a reachability check.

The second review found that a definition table placed between two charts of one State section would have reached only the later chart. The source does not say which earlier chart such a table serves, so the reader now refuses it. No pinned capture has that order, and all 777 charts describe as before. The fix adds:

  • an invented regression of that ordering;
  • a Hypothesis property over any order of definition tables and charts within a section;
  • a stronger raw-HTML differential, which now locates State sections and definition tables itself and checks them against both the registry and the live reader.

The third review found that the reader did not recognize a State heading in a paragraph left unclosed, such as <p>Nevada followed by the chart's heading and table. The shared HTML tree never closes a paragraph implicitly, so the paragraph's text ran on into the chart, and the previous State's selector and definitions carried into the next State's chart. The reader now reads each paragraph or heading from its own text, up to the first nested element whose start tag closes a paragraph in HTML (we checked the set against html5lib 1.1). No pinned capture nests a block in a paragraph or heading (none of 68,336), and all 777 registered selectors, definitions and parsed cells keep their hashes. The fix adds:

  • the reviewer's minimized regression, with and without </p>;
  • a Hypothesis property that selectors do not depend on omitted paragraph ends;
  • a Hypothesis property that a block with no nested block reads its full text.

With the old reader, the regression and the omitted-ends property fail.

The fourth review found that this fix cut a heading's text at blocks that HTML keeps inside a heading, so <h3><div>Nevada</div></h3> again kept California's definitions. It also found that an omitted </p> in a stacked payment cell merged its amounts, that a page of thousands of unclosed paragraphs exhausted the stack, and that the closer set lacked dialog and search. The fix (401b3bc7):

  • the shared HTML tree follows the WHATWG "in body" rules for optional end tags: it ends a paragraph in button scope at every start tag that closes one, ends a heading when another starts while it is the current node, and closes an open cell or row at a new one;
  • the POMS reader reads a heading's text through nested blocks, reads a div as a block that can carry a State heading, refuses a claimant line that names a State other than its section's, and walks the document without recursion.

Against html5lib 1.1, the new tree agreed on 20,000 random pages of paragraphs, headings and block containers; the old tree disagreed on 6,639.

The fifth review found one medium and three low problems:

  • Medium: reading a heading through nested blocks up to the next table meant a heading that holds a block after its words, such as <h3>Nevada<p>Invented note</p>, no longer matched the State pattern, so the previous State's selector carried on. Claimant headings failed the same way. The tree also ended a heading only at its own end tag, where HTML ends it at any h1–h6 end tag.
  • Low: thead, tbody, tfoot, caption and colgroup start tags did not end an open cell or row, so a header cell took in the next section's text. This predates the round-4 fix.
  • Low: the reader still collected heading text recursively.
  • Low: the claimant-State guard refused safe lines: "Washington, D.C." in the District's section, and a claimant line before any State heading.

The fix (8613b313):

  • the tree ends the open heading in scope at any h1–h6 end tag, clears the stack back to the table at a caption, colgroup or table-section start tag, and ends an open caption at a row or cell start tag. The fix leaves col out: all 4,045 col tags in the 28 pinned captures that have one sit in a colgroup;
  • the POMS reader checks a heading's whole text, then each line split at its nested blocks, for the State, the claimant and the effective date. A whole-text "State Effective …" line stays a date line, and a heading whose lines name two States refuses;
  • "Washington, D.C." reads as the District of Columbia, and the claimant-State guard waits for the first State heading;
  • the readers read heading text and cell text without recursion; a cell nesting 1,500 spans had raised RecursionError too.

Nothing changes on the pinned captures: the tree comparison builds 44 identical trees, and all 874 registered entries hash identically. (Round 4's commit called these "43 HTML captures". The registry holds 41 HTML captures, and the comparison's byte filter also admits two xlsx workbooks and a zip archive.) Against html5lib 1.1, on 5,000 invented pages per mode, the new tree has no mismatch in headings (401b3bc7: 506) or in tables with optional cell, row, section and caption ends (401b3bc7: 1,230). Each of 27 mutants of the tree and the POMS reader fails at least one test, as does each of five mutants of the cell reader.

The fix adds, on invented HTML only:

  • the reviewer's State and claimant heading cases: blocks after the heading's words, open headings and mismatched end tags;
  • an effective line after heading words, a table inside an open heading, and a heading whose lines name two States;
  • deep headings, paragraphs and cells;
  • a claimant line before any State heading, and Washington, D.C.;
  • table sections, captions and colgroups ending open cells and rows, and heading end tags ending any heading in scope but stopping at scope;
  • a property that wrapping or ending heading text keeps the selectors;
  • a differential property of the cell reader against the recursive one.

The sixth review (delta, at 697ea340) found one medium and three low problems:

  • Medium: in a heading, a line from a nested section, list item or blockquote set the chart's date and claimant without the State guards that the same line passes in a paragraph, and the result changed with where </h3> sat.
  • Low: _payment_rows deep-copied the chart, and ElementTree's copy recurses, so a cell nesting 50,000 spans crashed the interpreter. The recursion invariant above was therefore false.
  • Low: a State heading with a <br>, a zero-width character or another State's postal code was misread, and so was a "Washington, D.C." heading.
  • Low: mutants of the new tree rules survived the tests.

The fix (4aae2820):

  • every line of a block passes both State guards, and the reader reads every block that ends a paragraph, apart from a table or rule, from its own text. A heading whose first line names a State other than its section's refuses;
  • the reader reads the chart through a skeleton built without recursion, whose cells hold keys to the original cells. A table nested in a cell stays that cell's text, as before;
  • lines end at a <br> and drop zero-width characters. A postal code after a State's name must be its own, and "Washington, D.C." and "Washington DC" name the District in headings;
  • the tree builds lists, buttons, nested tables, captions, colgroups, cols and implied table sections and rows as HTML does, and closes end tags by HTML's scope rules.

Nothing changes on the pinned captures: every registered reader's output, cell values included, hashes as at 697ea340. On the 40 pinned HTML captures, the tree's tables, block texts and nesting now equal html5lib 1.1's on all 40 (697ea340: 40, 40 and 32). That comparison removes comments and noscript from both trees. On 5,000 generated pages per mode, the tree has no heading or table mismatch with html5lib (697ea340: 1,561 and 3,969). Each of 46 mutants, one per new or changed rule, fails at least one test. 51 of the 157 tests in test_aggregate_poms_invented.py fail against 697ea340's modules.

The fix adds, on invented HTML only:

  • the reviewer's nested-line cases, for a section, list item and blockquote, with and without </h3>, and a property that selectors do not depend on heading ends or block kinds;
  • the claimant guard on every claimant line, and a <br>-separated line that dates another State;
  • headings with <br>, </br>, </p>, zero-width characters, postal codes and Washington, D.C.;
  • headings and paragraphs that name another State, refused or admitted by the first-line rule;
  • 12 table pages and 13 block pages whose expected trees are html5lib 1.1's;
  • a chart cell nested 50,000 deep, read in its own process, and a table nested in a chart cell.

The seventh review (delta, GPT-6.1 Sol, at 4aae2820) found three medium and three low problems and one note:

  • Medium: a block whose whole text is a State date line skipped its lines, so a later line could date or name another State.
  • Medium: a claimant line that named another State passed whenever it also named the section's own.
  • Medium: an effective-date sentence other than "State Effective ...", or one with a D.C. alias or postal suffix, carried another State's date into the section.
  • Low: a space at each inline element's edge split words such as "Utah".
  • Low: a later heading line shaped as a State heading, with another State's postal code, kept the section's selector.
  • Low: three tree mutants survived the tests: list items around an address, dd and dt ending each other, and </html> after an html start tag.
  • Note: the tree's WHATWG wording covered nested forms, which it does not model.

The fix (89b40e46):

  • every line of a block passes the State guards, and a whole-text State date line's lines still head no section;
  • claimant lines and effective-date sentences may name no State but the section's, and the guards recognize State date lines by the heading reader's names, aliases and postal suffixes;
  • inline elements join without a separator within a line;
  • any line shaped as a State heading with another State's postal code refuses;
  • tests pin the three tree cases to html5lib 1.1's blocks, and the tree's docstring lists nested forms among what it does not model.

The pinned 2011 California section's date sentence ends charts<span class="poms-bold">:</span>, which the old line reader read as "charts :". Its two charts' parameter_effective_date_text in poms_registry.json now read "charts:". Every registered reader's output, cell values included, hashes as at 4aae2820; only that page's selector digest changes. The html5lib comparisons hold as before: 40 of 40 pinned captures, and no mismatch on 5,000 generated pages per mode. Against 4aae2820's reader, 18 of the 187 invented POMS tests fail, the same 18 in each of three Hypothesis seeds; the new tree cases and the later-claimant-line case pass there, since 4aae2820 already built those trees and refused that line. This round's 14 mutants (G1–G11 for the guards, O1–O3 the review's tree mutants) and round 7's 41, rerun on the final code, all fail tests. P11 (the claimant guard stops at its first claimant line) passed at first, because a whole text naming another State now refuses on its own; a block too long to read as one claimant line, with its own State's claimant line first, now catches it.

The fix adds, on invented HTML only: the review's four repro fragments and their variants, refused or admitted, including long blocks whose whole text is no effective-date or claimant line, one with the section's own claimant line before another State's; controls that read the section's own State, date and claimant; an effective-date line before any State heading; and five tree pages whose expected blocks are html5lib 1.1's.

The eighth review (delta, Opus 5.5, at 93824c2c) found two medium and four low problems and three notes, and CI failed on Python 3.14.7:

  • CI: Python 3.14's HTMLParser reads xmp, iframe, noembed and noframes as raw text and turns the rest of the page into text after a plaintext start tag, so an invented paragraph-closer test failed there.
  • Medium: joining inline text without a separator hid a State name that touches a word character across an inline tag, such as a footnote sup, from every State net; 4aae2820 had refused those pages.
  • Medium: in a block whose whole text is a State date line, a line shaped as another State's heading kept the section's selector.
  • Low: three mutants (R1, R3, R5) survived the tests.
  • Low: claimant selection was silent and inconsistent: a block whose claimant lines named two types read one of them, and the claimant carried over after a chart.
  • Low: two of round 7's own boundary variants still read wrong without refusing, because no net checked heading lines after the first for another State.
  • Low: "Washington,DC" without a space did not name the District.
  • Notes: Unicode format characters, "Hawaiʻi", a postal code alone in a date sentence and "N.J."; a mid-body html start tag; and the round-8 count of round 7's mutants.

The fix (dfb30420):

  • pins the raw-text set to HTML's six elements, refuses plaintext and abruptly closed empty comments, and closes the parser at the end of the page, so the tree is the same on 3.13 and 3.14;
  • reads each block and line joined, bare and spaced, and runs every State net over all three;
  • refuses a line shaped as another State's heading inside a whole-text date line;
  • refuses a block naming two claimant types, and resets the claimant after each chart;
  • nets every line of an h1–h6 heading, reversing an earlier deliberate admission of a second heading line that names another State;
  • matches "Washington,DC" and "Washington,D.C.", strips Cf characters, reads "Hawaiʻi", and reads postal codes and 14 abbreviations as naming States without heading a section;
  • models a mid-body html start tag as html5lib does, and, found by the extended differential, a noscript end tag with a special element open inside it and a table part outside a table.

Every registered reader's output, cell values included, hashes as at 93824c2c on both Python versions, and all 777 pinned charts' selectors equal 93824c2c's. On 3.13, 92 of the 300 invented POMS tests fail against 93824c2c's reader, the same 92 in each of three Hypothesis seeds. mutants_r9.py's 60 mutants fail tests but one, H1, which nets only a heading's whole text and first line; the whole text holds every line's text, so it differs only for an alias split across lines. Of earlier rounds' mutants, the tests catch all 7 of mutants_r8.py's and all 31 of mutants_r7.py's that still apply; we ported the rest into mutants_r9.py, or they match a caught mutant. (Round 8's "round 7's 41" meant the 41 of mutants_r7.py's 46 that applied then.)

The round-9 build listed a prose line holding a claimant word, such as "A recipient or couple qualifies if ...", as able to set the next chart's claimant, and counted 70 such line forms on the pinned captures. That overstated the exposure. Those 596 lines are the block lines that hold a claimant word and then "or" under the old pattern. The 592 in table cells, which the claimant reader never reads, each hold two claimant words, one of each type; the other 4 are one h4 heading form with one claimant word and the source's "or" for "for", a claimant line under the new rules too. Of the 777 pinned charts, 594 take their claimant from h1–h6 lines, 99 from short whole-text paragraphs and 84 from State date captions; none takes it from prose. Round 10 makes prose name no claimant (below), and all 777 charts read as before.

The ninth review (delta, Opus 5.5, at 7adafa66) found three medium and two low problems and seven notes:

  • Medium A: prose set a chart's claimant: any line holding a claimant word was a claimant line, and a line naming two types read as its first. A test pinned "Individual or couple for Washington, D.C." as individual.
  • Medium B: the reader read the date sentence joined only, so a footnote marker inside it changed the date (January 1<sup>2</sup>, 2031 read January 12) or hid the sentence, silently.
  • Medium C: the bare reading dropped any sup, and any link whose href held "fn", so link or sup text vanished and prose read as another State's heading. Round 8 introduced this.
  • Low D: five of the reviewer's six mutants survived the tests: O1, O2, O3 and O6, and O4, which the reviewer judged equivalent.
  • Low E: the nets checked h1–h6 lines for another State, but not paragraph captions, though 183 of the 777 pinned claimant setters are paragraphs: <p>Utah (continued)</p><p>Couple</p> charted Nevada.
  • Notes: acronyms over-refuse in Pennsylvania's section; mutant H1 is equivalent but for a D.C. alias split across lines; the reader read script and style text; a census log printed amounts; the open claimant paragraph overstated exposure; the html5lib generator lacked comments, inline elements, the implied-html attribute case, table parts outside a table, RCDATA and upper-case raw-text tags; one mutant slice started above the load limit.

The fix (8a772f5a):

  • only a heading form or a date caption is a claimant line; prose names no claimant but still passes the State guard, and every claimant word of a claimant line counts, so a block naming two types refuses within a line as across lines. The Washington, D.C. test now states that "Individual or couple for Washington, D.C." names no claimant, so its chart refuses, and that single-type lines read;
  • a date sentence whose bare reading states other dates, or another range reading, refuses, and so does a line that is a dated sentence only when bare, unless its markers lead it. The pinned 2023 District of Columbia footnote body between two charts still dates nothing;
  • the bare reading drops only a sup or # link holding one to three word characters or footnote signs; _cell_token keeps its wider rule;
  • a short line in any block that opens as another State's caption refuses. The net reads the D.C. alias first, codes and abbreviations included, and runs after the other nets, so their messages stand;
  • every reading drops script and style text;
  • the html5lib generator gains the six gaps. It found three tree gaps on pages with no misnested formatting element, now modelled and tested: a later html start tag's attributes on a page with an implied html element, the newline HTML drops after pre, listing and textarea, and CR LF read as one newline. The tree's limits now also name HTML's reopening of formatting elements, which nests a heading inside one left open.

Every registered reader's output, cell values included, hashes as at round 8 on both Python versions, and all 777 pinned charts' selectors equal 7adafa66's; no pinned page refuses. On the 40 pinned HTML captures the tree's tables, blocks and nesting equal html5lib 1.1's. On 3.13, 94 of the 434 invented POMS tests fail against 7adafa66's reader, the same 94 in each of three Hypothesis seeds. All 41 of mutants_r10.py's mutants fail tests: at least one per new rule or guard, and ports of the round-9 and round-7 mutants whose snippets this round removed. A mutant of the marker pattern's three-character bound alone survived, because the marker walk capped text at three characters too; both now read one constant, and the tests catch its mutant. The review's O4 is not equivalent: a footnote body opening a State date line, followed by a line shaped as that State's heading, refuses on the head and reads under O4, and a test now pins it. Of the older sets, the tests catch the mutants whose code still exists: 5 of 5 from own_mutants_r9.py, 53 of 54 from mutants_r9.py (H1 survives, as in round 9), 7 of 7 from mutants_r8.py and 30 of 30 from mutants_r7.py.

The tenth review (delta, Opus 5.5, at 8a772f5a) found two medium and four low problems and six notes:

  • Medium 1 (regression): a block with a claimant line counted claimant words in its claimant lines only, so <h4>Individual<br>or couple</h4> read as individual and <h4>Couple<br>Eligible individual</h4> as couple.
  • Medium 2: a heading the claimant pattern did not admit, such as "Couple payment levels for Nevada:", "Eligible couple" or "Couples", left the claimant line before it standing, so the chart read the earlier type silently.
  • Low 1 (regression): a footnote marker holding a script or style joined a date (January 1<sup>5<script>x</script></sup>, 2031 read January 15).
  • Low 2: the caption net missed list labels and leading punctuation ("1. Utah", "(b) Utah", "- Utah", "(Utah)", "The State of Utah").
  • Low 3: a script holding <!--<script> ended at its first </script> in the tree, though HTML runs it on.
  • Low 4: three of the reviewer's mutants (M21, M4, M16) and round 9's H1 survived.
  • Notes: a footnote link by a full or relative URL changed a date; a long block took its first of two date sentences; the Limits and Not modelled lists missed several forms; two sentences of this PR's review text were wrong (corrected above); the in-cell newline rule; new date refusals.

The fix (85958483):

  • a block with a claimant line counts the claimant words of every view, its whole text included, and plurals count;
  • a heading or short line that holds a claimant word but is no claimant line names a claimant the reader does not read, so the chart refuses unless a later claimant line names one; one with both types refuses as naming two. The Washington, D.C. test's "Individual or couple for Washington, D.C." now refuses as naming two claimants;
  • the same shape, swept for the other selectors: a short line naming another State anywhere refuses, and a heading or short line naming a date no sentence states, in a sentence's date form or the four other forms the docstring lists, leaves the date unread so the next chart refuses (the sweep's table is in the evidence folder); round 11 found common forms this missed, which round 12 nets (below);
  • a marker's text drops script and style; the caption net takes list labels, leading punctuation and "The"; the tree refuses a script holding <!-- and then a script start tag;
  • the date checks read an unmarked reading, which drops any element either marker rule counts, so a footnote link whose href holds "fn", by a full or relative URL, changes no date silently; round 11 found that a link to a footnote whose href holds no "fn" still did, which round 12 fixes (below);
  • lines of a long block that date differently remain named alternatives, and a range dates a chart only with two dates;
  • the module's Limits and Not modelled list the caption nets' over-refusals, a chart's own caption, text outside any block, the script escape states and the new date refusals.

Every registered reader's output, cell values included, hashes as at round 8 on both Python versions, and all 777 pinned charts' selectors equal 8a772f5a's; no pinned page refuses. On the 40 pinned HTML captures the tree's tables, blocks and nesting equal html5lib 1.1's. On 3.13, 94 of the 548 invented POMS tests fail against 8a772f5a's reader, the same 94 in each of three Hypothesis seeds, over 19 test functions. Of mutants_r11.py's 49 mutants (at least one per new rule or guard, and ports of the earlier sets' mutants whose code this round rewrote), 40 failed tests at 85958483, and nine passed all six modules, one of them (R21) equivalent. 858fb546 adds 15 test cases on invented pages, one to three per survivor; at that commit 48 of the 49 fail tests, each of the eight first failing its own witness. R21 walks script children whose text no reading uses, so no test can tell it apart. Every mutant of my_mutants_r10.py, mutants_r10.py and own_mutants_r9.py whose code still exists fails tests (8, 30 and 3), M4, M16, M20 and M21 among them; the review's H1 differs only where the reader over-refuses, so no test can kill it without pinning that over-refusal. Rerun at 858fb546, the three oldest sets give: of mutants_r9.py's 60, 50 fail tests, 9 change code that no longer exists and H1 passes all six modules; of mutants_r8.py's 14, 7 fail tests and 7 change code that no longer exists; of mutants_r7.py's 46, 30 fail tests and 16 change code that no longer exists; the W2a and W2b ports fail tests too.

The eleventh review (delta, Opus 5.5, at 858fb546) approved it with six low findings and seven notes:

  • Low 1: the unread-date net exempted every date that a footnote body or revision range named, across its whole block, and took any leading sup or link whose href holds "fn" for a footnote marker, so short lines such as Payment levels as of March 1, 2031<br><sup>1</sup>Revised March 1, 2031 kept the section's earlier date silently. That made the Invariants' "never reads a wrong one silently there" false.
  • Low 2: a script or style inside svg or math is raw text in the tree but markup in HTML, and Not modelled did not say so.
  • Low 3: the range pattern read a prose "to" as a range's end, so "effective from January 1, 2031 apply to facilities licensed after July 1, 2030" dated a chart from 2031 to 2030.
  • Low 4: the net missed common date forms ("January 1st, 2031", "Payment levels for 2031", "01.01.2031"), while round 10's fix list and commit message claimed that it read every form.
  • Low 5: five claims overstated: the HTML-limits sentence on hidden text and captions, round 10's claims that the net read every date form and that a footnote link changed no date whatever its URL, the Invariants' "never reads a wrong one silently there", and a stale count of mutants_r7.py's results (all corrected above); the tree's docstring said HTML's escape states run a script on where they may not.
  • Low 6: eleven of the reviewer's fifteen mutants survived all six modules.
  • Notes: H1's random part never met a differing page; <script/> hides what follows in HTML but not in the tree; a short line that repeats the claimant in force refuses; a claimant named in other words keeps the earlier type; a range to the same date drops its end and a reversed range reads literally; padding can push a short line past 80 characters; process.

The fix (8efc4b65, with tests in 31ae38ef and docstring wording in 5bc9cb6f, and witness cases in 32cc85d0):

  • the net names each line's dates on its own, without the revision range's text, skips footnote-body lines, and adds the whole text's dates only where no line names them; a footnote body needs every word its markers drop to have a marker's size, and a block whose whole text opens as one dates no chart;
  • the tree refuses a page whose svg or math holds a raw text or RCDATA element with < in its text, and a page with any self-closed raw text or RCDATA start tag; a census finds neither in the 40 pinned HTML captures, and the tree's docstring lists foreign content under Not modelled;
  • a range needs a date right after "from" and right after "to" or "through", gives its two dates in its own order, and refuses when it does not end after it starts, a range from a date to the same date included;
  • a heading that holds a year outside the years of the dates in force, or a short line that holds a later one, leaves the date unread. Counting every year in short lines refused one pinned page, whose short line on a State-administered program names the year before its chart's, so short lines outside a heading count later years only; the docstring lists the forms, that limit and "January 1, 31";
  • the date checks read a fifth, unlinked reading, so a link of a marker's size inside a date refuses whatever its href holds;
  • the tree's docstring says the escape states may run a script on, and names the forms its check refuses beyond them (a "-->" between, a vertical tab or Unicode space, a long s); the PR's claims above now say what holds;
  • tests pin each surviving mutant's witness, both sides of each 80-character bound included, and the docstring's limits name Note 4's claimant vocabulary.

All 777 pinned charts' selectors equal 858fb546's on 3.13 and 3.14 (28 files the same, 0 differ, 0 refused, 777 charts, on each), and every registered reader's output, cell values included, hashes as at round 8 (874 specs, byte-identical on 3.13 and 3.14). 61 of the 667 invented POMS tests at 5bc9cb6f fail against 858fb546's readers, over 15 test functions, none of them one 858fb546 defines. Of mutants_r12.py's 45 mutants (29 for the new rules, 15 from the review's set ported, with X4 split into X4 and X4b for the whole text's bound), 44 fail tests at 5bc9cb6f; S24, which let any four digits count as a year, passed all six modules until 32cc85d0 added witness cases. Rerun on 5bc9cb6f's readers, which 32cc85d0 leaves unchanged, the older sets give: of mutants_r11.py, 34 fail tests, 14 change code that no longer exists and R21, the equivalent one, passes; of mutants_r10.py, 28 fail tests and 13 change code that no longer exists; of my_mutants_r10.py, 7 and 3; of mutants_r9.py, 49 and 9, H1 passes for the reason round 11 checked, and V1 now stops the module loading, since _TEXT_CONTENT reads the set it deletes; of mutants_r8.py, 7 and 7; of mutants_r7.py, 30 and 16; and W2a and W2b fail tests. Of round 9's own set, on the same readers, 3 fail tests and 3 change code that no longer exists.

The twelfth review (delta, at 32cc85d0) approved it with five low findings and six notes:

  • Low 1: dates in the section's own year, in forms neither date pattern read ("July 1st, 2030", "07.01.2030", "2030/07/01", "July 1,2030", "7/2030", a month glued to the word before it, and such a second date in a short date sentence), kept the section's date silently. The year net counts only years outside the dates in force, so the Invariants' "never reads a wrong one silently there" failed on forms the docstring did not list.
  • Low 2: the tree built HTML block and cell names inside svg or math (<svg><section>, <svg><td> and others) as HTML, where HTML keeps them foreign, and ended an h5 at an end tag inside MathML's mi, which HTML ignores there, so a date, State or claimant dropped out of its block, and a chart row's amounts moved one column on.
  • Low 3: footnote-body detection took any word of one to three characters that a leading sup or footnote link held for a marker, so <sup>As of</sup> March 1, 2031 and <a href='#new'>New</a> payment levels as of March 1, 2031 dated no chart.
  • Low 4: six of the reviewer's twelve mutants (Q1, Q4, Q5, Q8, Q9 and Q11) passed the invented module; Q9's witness, <script src='x.js'/>, is the common real form.
  • Low 5: five claims overstated: the Invariant above, the over-refusal sentence on years in short lines, the tree's Not-modelled sentence on which start tags end an svg, "28 files" for the 874-spec fingerprint, and two commits for one rerun (all corrected above).
  • Notes: the breakout pages, all classified (the Tests section gives the counts); an earlier year in a short line left a wrong date silent; three line-by-line cases (a split date that a footnote line repeats, a comma after a <br>, a heading that opens with a marker); a lower-case "Effective dates:" line dated a chart; the new over-refusals; process.

The fix (1b319dca, with tests in be276733 and 179496ec and docstring wording in 17bdcf00):

  • the unread-date net names six more forms, the section's own year included: an ordinal day, a comma with no space after it or a space before it, a dotted date, a date that opens with its year, a month and year in numbers, and a month glued to the word before it;
  • a short line's earlier year counts when the line holds a dating word ("payment", "level", "effective", "as of" or "rate"); the pinned line on a State-administered program holds none and still dates no chart;
  • inside svg or math the tree lets only svg and MathML elements start, and svg or math must end at its own end tag, the end of the page included, or the page refuses; the Not-modelled item names HTML's breakout start tags as html5lib 1.1 builds them;
  • a footnote body's dropped words must be one to three digits or footnote signs, or a single letter, and a heading is never a footnote body;
  • a block's whole text adds the dates it names more often than its lines do, so a footnote line that repeats a split date no longer covers it;
  • the revision range, and the date sentence's exclusion of it, read "Effective Dates:" in any case;
  • tests pin the six surviving mutants' witnesses, with new witnesses for Q8 and for the caught Q7, whose old witnesses now refuse with or without them, and the docstrings list the new over-refusals and two more forms left standing: a date split across two blocks, and a long date sentence whose second date takes another form.

All 777 pinned charts' selectors equal 32cc85d0's on 3.13 and 3.14 (28 files the same, 0 differ, 0 refused, on each), and every registered reader's output, cell values included, hashes as at round 8 (874 specs, byte-identical on 3.13 and 3.14). All 40 pinned HTML captures parse; their 159 svg hold only path, title and desc elements, and none holds math. 72 of the 774 invented POMS tests at 17bdcf00 fail against 32cc85d0's readers, over 12 test functions, none of them one 32cc85d0 defines. Of mutants_r13.py's 50 mutants (38 for the new rules and 12 from the review's set, ported), 49 fail tests at 17bdcf00, and Q2, the equivalent round 12 found, passes. In process, 49 of the 50 change the outcome of a page their tests build, all but Q2. Rerun at 17bdcf00, the older sets give: of mutants_r12.py, 31 fail tests and 14 change code that no longer exists; of mutants_r11.py, 33 and 15, and R21, the equivalent one, passes; of mutants_r10.py, 28 and 13; of my_mutants_r10.py, 7 and 3; of mutants_r9.py, 49 and 9, H1 passes for the reason round 11 checked, and V1 stops the module loading; of mutants_r8.py, 7 and 7; of mutants_r7.py, 30 and 16; and W2a and W2b fail tests. Of round 9's own set, 3 fail tests and 3 change code that no longer exists. Of the round-12 review's 12, 8 fail tests, 3 change code that no longer exists and Q2 passes, as above. be276733's message says two removed test cases each held a second dating word; "Effective in 2029" held one.

The thirteenth review (delta, at 17bdcf00) returned REVISE with one medium finding, six low findings and seven notes:

  • Medium 1 (regression): 1b319dca answered round 12's Note 4 by reading "Effective Dates:" in any case. A long sentence that held "effective dates:" then stopped dating its chart and stopped meeting the State guards, so a page that named Utah in Nevada's section read as Nevada, where the parent refused. A range in another case, in script text or a table cell, set the section's revision dates.
  • Low 1: inside foreignObject, html5lib ignores </svg>, so later blocks and cells stay foreign while the tree reads them. In a browser the same holds for desc, title and the MathML token elements.
  • Low 2: the tree drops CDATA inside svg or math, which HTML reads as text.
  • Low 3: the split-date rule counted a revision line's date on the lines' side only.
  • Low 4: date forms that still read wrong, a split date in a long block, and two claims that overreached.
  • Low 5: prose that still makes a footnote body.
  • Low 6: twelve of the reviewer's seventeen mutants survived a prescreen.
  • Notes: dating words; nested svg's quadratic parse time, which the builder's report had missed; a refusal message's wording; annotation-xml's second HTML encoding; the ISO form of the date in force; the equivalences it checked; process.

Under the project's review exit rule, a regression against the parent gets a fix, and an invented-input finding with zero effect on pinned inputs stands as a stated limit. So only Medium 1 changes code. The fix (8cb397f5):

  • _effective_line's exclusion, _REVISION and the "Present" check read title case again, the three lines as 32cc85d0 wrote them. Round 12's Note 4 returns as a stated limit. Each of the 29 pinned POMS pages holds a single revision range, in title case;
  • tests pin the review's E4, ES1, V6 and V7 and the lower-case revision line, and replace the four cases that pinned the any-case reading;
  • the docstrings and the claims above no longer say what Lows 1–5 and Notes 4 and 5 falsified. Open items lists the rest, one line per form.

All 777 pinned charts' selectors equal 32cc85d0's on 3.13 and 3.14 (28 files the same, 0 differ, 0 refused, on each), and every registered reader's output, cell values included, hashes as at round 8 (874 specs, byte-identical on 3.13 and 3.14). All 40 pinned HTML captures equal html5lib 1.1's tree. The review's 16 regression probes read alike on 8cb397f5 and 32cc85d0. aggregate_tables.py's syntax tree matches 17bdcf00's, docstrings aside, so the html5lib differentials below stand. 68 of the 775 invented POMS tests fail against 32cc85d0's readers, over 10 test functions, none of them one 32cc85d0 defines, and 5 fail against 17bdcf00's, over the four new functions. Of mutants_r13.py's 50 mutants, 46 fail tests, R1, R2 and R3 change code that no longer exists, and Q2, the equivalent round 12 found, passes. The review's twelve mutants pass all six modules, as it predicted. Only aggregate_poms.py's three lines changed, so we did not rerun the older sets.

A census of the pinned captures backs the limits. None of the 40 HTML captures holds a CDATA section. Each of the 29 POMS pages holds one revision range, in title case, and no "effective dates:" in another case. None of the listed date forms appears on any of the 4,263 lines under 80 characters that the reader's own _lines gives outside a table cell. The net also reads heading lines of any length: outside tables, in four readings, 14 lines match the date net's shape, each a page-title h1 of 97 to 100 characters before the first State heading, where no net runs.

The fourteenth review (delta, at 8cb397f5, an Opus 5.5 reviewer after the Sol lanes closed) approved, with no high or medium finding, one low finding and five notes:

  • 8cb397f5 restores the three lines round 13's medium named, each equal to 32cc85d0's text. On any page, the head gives 32cc85d0's read or refuses, and the review's own runs read 28 files the same, 0 differ, 0 refused and 777 charts on 3.13 and 3.14.
  • Low 1: four stated-limit lines named the right form and misstated its effect. They now read as the Stated limits above read. The head and the parent agree on every row, and no pinned input holds these forms.
  • Note 1 adds CDATA in HTML content to the limit. Note 2 widens the census line. Note 3 adds the refusal message's limit. Note 4 records that the restored "Present" check is an equivalent mutant: title-case _REVISION captures only "Present" or a date. Note 5 records the reviewer's own two runs above the load gate.
  • This entry changes the PR body only, so the head stays 8cb397f5.

The earlier slot turn merged master 18082859 (ce188f20) and recounted the tiers (5285c76d). Master's tier files replaced the branch's, and the recount added D4's 794 unit and 256 artifact tests. tests/tier_counts.json then read unit 20,458, artifact 4,527, integration_psid 1,471, reproduction_legacy 520 and oracle_policyengine 308, 27,284 in all. CI's tier-policy test at 8cb397f5 collected those unit and artifact counts on the PR's merge with master, against a manifest of 19,664 and 4,271 (run 41344829714).

A comparison of blob hashes from 8cb397f5 to 5285c76d finds 46 moved paths: the two tier files and 44 other paths that master changed since the merge base 0f69bbb2. All 44 match master's blobs. None of D4's 79 paths moved, and no path changed on both sides.

CI at 5285c76d passed every check but one test in shard 3, tests/test_track_b_b0_2_counts.py::test_a_failure_from_outside_this_script_prints_no_value, which ran first in that shard. CI at 8cb397f5 failed the same way. #596 ("Flush the real streams before each B0.2 test captures output") merged ahead of this branch as dd9c7be2, and 35859218 carries it. CI at 35859218 passed every check, shard 3 included.

ecc09804 merges master 89d064b5, which brings #573's SSI interface. #573 and D4 each added a block to the same exclusion tuple in scripts/first_estimates_birth_evidence.py. They also each added a block to the same reachability test in tests/estimates/test_birth_evidence_artifact.py, so both files conflicted. The merge keeps both blocks and lists the shared income_resources/__init__.py once, in D4's block. Against master, it adds the 7 and 20 lines D4 added to these files, and it drops only master's copy of that __init__ line. d5dd388f recounts on 89d064b5: unit 21,248, artifact 4,527, integration_psid 1,471, reproduction_legacy 520 and oracle_policyengine 337, 28,103 in all. 35859218 merges master dd9c7be2, which changes one test module for #596 and leaves the tier manifests unchanged, so the recount stands.

From 5285c76d to d5dd388f, 159 paths changed: the two tier files, the two conflicted files and 155 other paths that master changed since 18082859. All 155 match master's blobs. None of D4's other 77 paths moved. From d5dd388f to 35859218, one path moved: the test module #596 changed, now equal to master's blob.

38895135 merges master edba88f7, which brings #563's Track B changes and adds 2,405 unit tests to master's count. Only the two tier files conflicted, and the merge takes master's. ca93c707 recounts on edba88f7: unit 23,653, artifact 4,527, integration_psid 1,471, reproduction_legacy 520 and oracle_policyengine 337, 30,508 in all. From 35859218 to ca93c707, 63 paths changed: the two tier files and 61 other paths that master changed since dd9c7be2. All 61 match master's blobs. None of D4's paths moved.

Tests

D4's six modules (test_aggregate_coverage, _numbers, _pensions, _poms, _poms_invented and _ssa): 1,050 passed on Python 3.13.9 and 1,050 on 3.14.7, up from 944. On the merge of 89d064b5, all 1,050 passed again on Python 3.13. The birth-evidence seal tests' reachability test needs modules this sparse clone leaves out, so CI runs it, as it runs tests/track_u2/test_u2_isolation.py. black -l 79 and ruff are clean.

Tier Added
unit 794
artifact 256
  • Unit tests use invented inputs.
  • Artifact tests read the pinned public captures.
  • Microdata: D4 reads none and captures no Trustees Report cost table.
  • Tier counts: tests/tier_counts.json and tests/README-tiers.md carry the recount on master edba88f7: unit 23,653, artifact 4,527, total 30,508.
  • html5lib differentials: round 9's and round 7's generators find no mismatch on 5,000 pages per mode on both versions (round 7's rerun at 858fb546). Round 11's generator, round 10's with the script escape form added from its own random stream, refuses each page whose script html5lib runs on (32 headings and 72 table pages per 5,000) and finds no mismatch on pages without a formatting element left open or misnested (3,793 headings and 2,397 table pages compared); on pages with one, the differences are the adoption agency and reopening rules the tree does not model. The differential counts apart the pages that differ only by a newline right after a pre, listing or textarea start tag in a table cell or caption, which the tree drops, as it does everywhere, and html5lib 1.1 keeps there (18 headings and 90 table pages per 5,000). Round 12's generator, round 11's with svg and math content and self-closed raw text tags added from a third random stream, refuses 149 headings and 555 table pages for raw markup inside svg or math and 140 and 639 for a self-closed tag, and finds no mismatch on the 3,507 headings and 1,869 table pages with no formatting element left open or misnested and no svg or math breakout. Of the 132 headings and 380 table pages with breakout markup, 19 and 83 differ. Of the 19 heading pages, 9 are breakout, each a <math><h4> inside an h3, h4 or h5, which html5lib moves out, and 10 differ by the adoption agency rules alone; all 83 table pages differ by the adoption agency rules alone. At the reader's level, the 8 breakout pages with no formatting markup read the same, and page 919 differs only by an extra empty p. Round 11's generator gives the round-11 review's logs byte for byte on the round-12 tree. Round 13's generator, round 12's with the review's foreign forms added from a fourth random stream (<svg><section> and the other block names HTML keeps foreign, <svg><td> in a cell, and <math><mi> before a heading end tag), draws round 12's pages unchanged where it draws no round-13 form. On the round-13 tree it refuses 616 headings and 2,598 table pages because an element other than svg or MathML starts inside svg or math, 107 and 139 of them round 12's breakout pages, which the tree no longer reads. It refuses 181 and 79 because svg or math ends other than at its own end tag, and finds no mismatch on the 3,104 headings and 1,201 table pages with no formatting element left open or misnested. Of the 637 headings and 507 table pages with one, 133 and 152 differ, by the adoption agency and reopening rules. The 4 headings and 16 table pages it draws with breakout markup that the tree still reads hold no svg or math in html5lib's tree, because raw text took the markup. One of those table pages differs by the adoption agency rules, on a misnested <b><code></b></code> ahead of the noframes that holds its svg, and another differs only by the newline html5lib 1.1 keeps, one of 12 headings and 20 table pages that differ that way. Round 11's generator gives the round-11 review's logs byte for byte on the round-13 tree.

axiom: n/a: pinned public aggregate tables and their readers for microsim validation; no PolicyEngine country-model or RuleSpec encoding changed

🤖 Generated with Claude Code

MaxGhenis and others added 3 commits October 24, 2026 10:59
Plain-request captures of the SSA Supplement tables, the POMS SI 01415
annual payment tables and coverage sections, Federal Reserve Z.1, DOL
private-pension and IRS IRA tables, with per-source manifests (time,
size, SHA-256, URL) and additive registries of 861 numeric tables and 13
references. A folder-level .gitattributes stores the bytes as fetched.

Built by a Subfleet build lane in a standalone clone; committed by the
coordinating session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Typed cells and metadata, the registry loader, and parsers for the SSA,
POMS, coverage, Z.1, DOL and IRS sources. Every reader checks the
capture's size and SHA-256 before reading a cell; missing or suppressed
cells stay missing, and published discrepancies keep flags rather than
repairs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Invented-input properties for the number, HTML-span, date and workbook
handling, and checks of the real captures against independent raw-cell
reads and published identities.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
social-security-model Ready Ready Preview Nov 2, 2026 9:42pm UTC

Request Review

MaxGhenis and others added 3 commits October 24, 2026 16:23
The POMS reader kept only the last Code/Definition table it saw, so
California 2004 lost codes A-F. It now reads every definition table in
the State's section, merges them, and refuses a code that two tables
define differently.

Fixing that surfaced three more reader problems, now fixed:

- The 2009 and 2010 headings "New Jersey (NJ)" were not recognized, so
  four New Jersey charts were labelled Nevada and given both States'
  definitions. The registry entries are renamed to new_jersey.
- Iowa 1999-2005 defines codes jointly ("C/H", "D/I"). A joint row now
  defines each code it names, and Vermont's chart code "A or B"
  resolves to both codes.
- A full-width note row in the Massachusetts 1999 definitions was read
  as a code. It is now skipped.

Fifteen Iowa and Pennsylvania charts publish codes that no definition
table in their section defines. They are recorded in
poms_open_questions.json, and no definition is inferred for them.

New tests: every chart code resolves or is recorded; definition codes
match an independent raw-HTML locator on all 777 charts; registry
selectors equal the structural reader; each chart's State matches its
date sentence; a California 2004 regression; and Hypothesis properties
for definitions split across tables and for joint codes. Each of the
four bugs, reintroduced, fails at least two of them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The aggregate-table readers are opt-in source readers that nothing in the
historical projection imports. List their five source files as post-review
exclusions in the birth-evidence script and its expected tuple, and assert
that none of the modules is reachable from the birth-evidence reducer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Definitions are collected per State section heading. A State that is
named only in an "X Effective" line has no heading, so the walker would
have kept the previous State's definition tables. It now refuses. No
pinned capture changes State that way; the regenerated registry is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
describe_poms_tables gave each chart the definition tables seen so far, so
a Code/Definition table between two charts of one State section reached
only the later chart. The source does not say which earlier chart such a
table serves, so the reader now refuses it. No pinned capture has this
order: all 777 charts describe as before.

Tests:
- an invented regression of the reviewer's ordering;
- a Hypothesis property over any order of definition tables and charts in
  a section: a table after a chart refuses, and otherwise every chart reads
  every definition table of its section;
- the raw-HTML differential now locates State sections and definition
  tables itself, and checks them against both the registry and the live
  reader. Its joint-code split no longer uses the production helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shared HTML tree never closes a paragraph implicitly, so an unclosed
"<p>Nevada" held the heading and chart that followed it. Its whole-subtree
text missed the State heading match, and California's selector and
definitions carried into the Nevada chart.

The State, effective-date and claimant checks now read a paragraph or
heading's own inline text, up to the first nested element whose start tag
closes an open paragraph (checked against html5lib 1.1; table only outside
quirks mode). Nested blocks are still walked in turn. With no nested
block this equals normalized_text, and none of the 68,336 paragraphs and
headings in the 28 pinned SI 01415 captures nests one: all 777 registered
selectors, definitions and parsed cells are unchanged, by hash.

Tests, on invented HTML only: the reviewer's minimized regression in both
forms, a property that selectors do not depend on omitted </p> ends, and
a property that a block with no nested block reads its full text. With the
old reader the regression and the omitted-end property fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fourth review found four problems:
- e70848e cut a heading's text at blocks that HTML keeps inside a
  heading, so <h3><div>Nevada</div></h3> again kept California's
  definitions;
- an omitted </p> in a stacked payment cell merged its amounts;
- a page of thousands of unclosed paragraphs exhausted the stack;
- the closer set lacked dialog and search.

The shared HTML tree now follows the WHATWG "in body" rules for
optional end tags:
- it ends a paragraph, in button scope, at every start tag that closes
  one, with table read as in standards mode;
- it ends a heading when another heading starts while that heading is
  the current node;
- a new cell or row closes the open one, along with anything left open
  inside it.

The POMS reader now:
- reads a heading's text through nested divs, sections and paragraphs,
  and stops only at another heading or a table;
- reads a div as a block that can carry a State heading;
- refuses a claimant line that names a State other than its section's;
- walks the document without recursion.

Nothing changes on the pinned captures. The 43 HTML captures build
identical trees, and all 874 registered entries hash identically: their
cells, the 777 POMS selectors and the POMS definitions. Against html5lib
1.1, the new tree agrees on 20,000 random pages of paragraphs, headings
and block containers with optional </p>; the old tree disagreed on
6,639. The remaining differences are of two kinds. Inline end tags
misnested across an open paragraph are a documented limit. dialog and
search postdate html5lib 1.1.

Tests, on invented HTML only:
- blocks inside a heading, and a div as a heading;
- every paragraph closer, from a list copied from the specification;
- an effective date and a State date line inside a heading;
- a heading left open before its table;
- a property that wrapping heading text in blocks keeps the selectors;
- the claimant-State refusal;
- deep pages;
- stacked cells and table grids with optional end tags;
- a property on the tree's structure.

Removing each of eleven rules in turn fails at least one test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fifth review found one medium and three low problems:
- 401b3bc read a heading's text through nested blocks up to the next
  table. A heading that holds a block after its words, such as
  <h3>Nevada<p>Invented note</p>, then no longer matched the State
  pattern, and the reader kept the previous State's selector. Claimant
  headings failed the same way. The tree also ended a heading only at
  its own end tag, where HTML ends it at any h1-h6 end tag.
- thead, tbody, tfoot, caption and colgroup start tags did not end an
  open cell or row, so a header cell took in the next section's text.
  This was already in the parent.
- _own_text still recursed: a heading nesting 1,500 elements raised
  RecursionError.
- the claimant-State guard refused safe lines: "Washington, D.C." in
  the District's section, and a claimant line before any State heading.

The shared HTML tree now:
- ends the open heading in scope at any h1-h6 end tag;
- clears the stack back to the table at a caption, colgroup, thead,
  tbody or tfoot start tag, and ends an open caption at a tr, td or th
  start tag. col is left out, since HTML places it in an open colgroup,
  as all 4,045 col tags in the 28 pinned captures that have one are
  placed.

The POMS reader now:
- reads a heading as lines split at its nested blocks, and checks the
  whole text first, then each line, for the State, the claimant and the
  effective date. A whole-text "State Effective ..." line stays a date
  line;
- refuses a heading whose lines name two States;
- reads "Washington, D.C." as the District of Columbia;
- skips the claimant-State guard until the first State heading, since a
  chart there refuses anyway;
- collects text without recursion.

The cell reader, _cell_token, recursed too: a cell nesting 1,500 spans
raised RecursionError. It now keeps its own stack.

Invariants:
- A State or claimant heading names its State or claimant whatever
  blocks follow its words inside it, and whichever heading end tag
  closes it.
- Selectors do not depend on omitted end tags of paragraphs, headings,
  cells, rows, table sections or captions.
- No reader's recursion depth grows with the page's nesting.
- The iterative cell reader gives the recursive reader's text, flags
  and header identity.

Nothing changes on the pinned captures. The tree comparison builds 44
identical trees, and all 874 registered entries hash identically.
Round 4's message called the compared files "43 HTML captures": the
registry holds 41 HTML captures, and the comparison's byte filter also
admits two xlsx workbooks and a zip archive.

Against html5lib 1.1, on 5,000 invented pages per mode:
- headings left open, holding blocks or closed by another level: 0
  mismatches (401b3bc: 506);
- tables with optional cell, row, section and caption ends: 0
  (401b3bc: 1,230);
- round 4's paragraph generator: 59 for both trees, from span and b
  misnesting and from dialog and search, which the tree does not model.

Tests, on invented HTML only:
- the reviewer's heading cases: blocks after a State or claimant
  heading's words, open headings and mismatched end tags;
- an effective line after heading words, a table inside an open
  heading, and a heading whose lines name two States;
- deep headings, paragraphs and cells;
- a claimant line before any State heading, and Washington, D.C.;
- table sections, captions and colgroups ending open cells and rows;
- heading end tags ending any heading in scope, and stopping at scope;
- a property that wrapping or ending heading text keeps the selectors;
- a differential property of the cell reader against the recursive one.

368 tests pass. Each of 27 mutants of the tree and the POMS reader,
including two the review noted survived round 4's tests, fails at least
one test, as does each of five mutants of the cell reader.

Documented limits: end tags other than headings close at the matching
element regardless of scope, and a br or nested block in one cell joins
its lines with a space. No pinned cell, or paragraph of a cell, has a
number on each side of a br.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master gained D1a (#575). Both branches extended the birth-evidence
check's post-review exclusions and its reachability test, so the merge
keeps D1a's two PSID income and wealth readers and D4's five
aggregate-table modules, each with its own reachability assertion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Medium: every line of a block now passes both State guards. A line that
dates another State refuses, and the claimant guard runs on every
claimant line, while the claimant still comes from the first. Every block
that ends a paragraph, apart from a table or rule, is read from its own
text, so a list item, section or blockquote reads the same after a closed
heading as inside one left open. A heading whose first line names a State
other than its section's refuses.

Low 2: _payment_rows no longer deep-copies the chart. It builds a
skeleton of the table without recursion, whose cells hold only a key to
the original cell. A chart cell nesting 50,000 spans now reads in its own
process; at 697ea34 that process exits 139. As before, a table nested in
a cell is that cell's text, and its rows are not the chart's.

Low 3: a line also ends at a br, and lines drop U+200B and U+FEFF. A
postal code after a State's name must be that State's own, so "New York
(NJ)" heads no State. "Washington, D.C." and "Washington DC" name the
District in headings as well as claimant lines.

Low 4: the tree builder follows HTML for more tags:
- a button start ends an open button;
- an li, dd or dt start ends the open item unless a special element
  other than address, div or p is open inside it;
- a table start directly in a table ends that table;
- caption, colgroup and section starts clear back to the innermost table,
  and so does a col outside a colgroup;
- a row or cell start ends an open caption or colgroup of its own table;
- a row or cell directly in a table gets an implied tbody, and a cell
  directly in a section an implied row;
- a heading end tag ends the open heading in scope, through a button;
- </br> is a br, and </body> and </html> close nothing;
- </table> ends the innermost table, and a table part's end tag stops at
  its table;
- </p> closes a paragraph in button scope, or else inserts an empty one;
- </li> closes in list item scope, and other special end tags in scope;
- any other end tag stops at a special element.

Notes: _cell_token's br sentence now says what holds, the col and
not-modelled wording follow the code, and the PR's Tests section is
recounted.

Evidence, outside the repository:
- Every registered reader's output, cell values included, is
  byte-identical to 697ea34's.
- Against html5lib 1.1, on 5,000 generated pages each: this round's
  generator gives 0 heading and 0 table mismatches (697ea34: 1,561 and
  3,969), and round 6's gives 0 and 0. Round 4's gives 50, all on pages
  with search or dialog elements, which html5lib 1.1 predates
  (697ea34: 59).
- On the 40 pinned captures, with comments and noscript removed from both
  trees, tables, block texts and parent-child nesting equal html5lib's on
  all 40 (697ea34: 40, 40 and 32).
- In the pinned captures, 42 cells have a digit on each side of a br and
  39 within one paragraph; none joins two amounts by a br within one
  paragraph.
- 46 mutants, one per new or changed rule and including round 6's
  equivalents, are all caught. 51 of the 157 tests in
  test_aggregate_poms_invented.py fail against 697ea34's two modules.

Tests: D4's six modules give 432 passed (176 unit, 256 artifact). The
birth-evidence seal tests give 12 passed; the reachability test needs
modules this sparse clone leaves out, so CI runs it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 25, 2026 13:59
The round-7 delta review (GPT-6.1 Sol, at 4aae282) asked for revision.
Its three medium findings were State-guard bypasses:

- M1: a block whose whole text is a State date line skipped its lines, so
  a later line could date or name another State ("Nevada Effective
  ...<br>Utah Effective ..." kept Nevada with two date options).
- M2: a claimant line that named another State passed whenever it also
  named the section's own ("Couple for Utah (see Nevada)").
- M3: an effective-date sentence other than "State Effective ...", such as
  "Utah payment levels effective ...", carried another State's date into
  the section, and so did a D.C. alias or a postal suffix before
  "Effective".

The fix:
- Every line of a block passes the State guards. When the whole text is a
  State date line, its lines still do not head a section.
- A claimant line, and every effective-date sentence, may name no State
  but the section's own. Before the first State heading neither is
  guarded, as before: no section is open, and the heading that opens one
  sets its own date and claimant.
- A State date line is recognized by the names, D.C. aliases and postal
  suffixes a section heading takes, through the helpers the heading
  reader now shares (_state_name, _state_reference).

Low findings:
- L1: within a line, inline elements now join without a separator, as HTML
  renders them, so U<span>tah</span> reads "Utah" and Cou<span>ple</span>
  "Couple". normalized_text, which the tree tests use as a fingerprint and
  the table reader for labels, still separates every text node; the
  docstrings say so.
- L2: any line shaped as a State heading whose postal code is not that
  State's refuses, wherever it sits in the block ("Invented note<br>New
  York (NJ)"). A later line that only mentions a State in prose is still
  admitted.
- L3: the three tree mutants that survived now fail tests: list items
  around an address, dd and dt ending each other, and </html> after an
  html start tag, with the expected blocks html5lib 1.1 builds.
- Note: the tree's docstring lists a form start tag inside an open form
  among what it does not model, with the review's example. No pinned
  capture opens a form inside another.

The pinned 2011 California section has "charts<span
class="poms-bold">:</span>", which the old line reader read as
"charts :". Its two charts' parameter_effective_date_text in
poms_registry.json now read "charts:". Nothing else changes: every
registered reader's output, cell values included, hashes as at
4aae282, and only the 2011 page's selector digest moves.

Checks:
- 18 of the 187 invented POMS tests fail against 4aae282's reader, the
  same 18 in each of three Hypothesis seeds. The new tree cases and the
  later-claimant-line case pass there: 4aae282 already built those
  trees and refused that line, and the cases catch mutants of it.
- Mutants: the 14 for this round (G1-G11 for the guards, O1-O3 the
  review's tree mutants) and the 41 from earlier rounds, rerun on the
  final code, all fail tests. One earlier mutant, P11 (the claimant
  guard stops at its first claimant line), passed at first: a whole
  text naming another State now refuses on its own. A block too long to
  read as one claimant line, with its own State's claimant line first,
  now catches it.
- On the 40 pinned HTML captures, the tree's tables, block texts and
  nesting equal html5lib 1.1's on all 40; on 5,000 generated pages per
  mode there is no heading or table mismatch.
- D4's six test modules: 462 passed (unit 206, artifact 256).
- black -l 79 and ruff are clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits October 25, 2026 22:00
The round-8 delta review (Opus, at 93824c2) asked for revision, and CI
failed on Python 3.14.7.

Python 3.14: the standard library's HTMLParser reads xmp, iframe, noembed
and noframes as raw text in 3.14.7 and not in 3.13.9, turns everything
after a plaintext start tag into text in 3.14.7 only, and closes the empty
comments "<!-->" and "<!--->" at different places. The tree now pins
HTML's six raw text elements on its subclass (noscript stays markup, as
in HTML with scripting off), refuses a page with a plaintext start tag or
an abruptly closed empty comment, and closes the parser at the end of the
page, so raw text left open keeps its text. The paragraph-closer test
expects plaintext's page to refuse and still states the closer rule. The
tests pass on both versions, the differential finds no mismatch on
either, and 20 comment and raw-text edge pages build the same tree on
both.

Medium 1: a State name glued to an inline element's text became another
word, so no State net saw it. Each block's whole text and lines are now
read three ways: joined (inline text joins, as HTML renders it), bare
(the joined reading without footnote markers, a sup or a link to a
footnote, as table cells are read) and spaced (a space at every element
edge). The joined and bare readings recognize a State heading and a
claimant, so Utah<sup>1</sup> heads Utah; the joined reading alone gives
the date sentence, because reading it bare moved one pinned chart's date.
Every net runs over all three readings: another State's heading line,
the misnamed heading, the State date line and effective-date guard, the
claimant guard and the heading net. A claimant line that only the spaced
reading shows refuses.

Medium 2: when a block's whole text is a State date line, a line shaped
as another State's heading now refuses, whatever the whole text's length.
The test docstring that said a long block's lines refuse now says what
the reader does, with three long_heading_line cases.

Low 3: the review's R1, R3 and R5 witnesses are tests, and each mutant
fails them.

Low 4: a block whose claimant lines name two claimant types refuses, and
the claimant resets after each chart, so every chart needs its own
claimant line. No pinned chart loses its claimant.

Low 5: every line of an h1-h6 heading is netted, in every reading, for a
State other than the section's. This reverses round 8's admission of
"Invented note<br>Invented note on Nevada" in California's section; a
later heading line naming the section's own State, and paragraph prose
naming any State, are still admitted.

Low 6: the District alias takes "Washington,DC" and "Washington,D.C.".

Note 7: every reading drops Unicode format characters (category Cf, 170
code points, the same set in Unicode 15.1 and 16.0), the soft hyphen
included. "Hawaiʻi" and its apostrophe spellings name Hawaii and may head
its section. A postal code in parentheses in either case, an upper-case
postal code standing as a word and fourteen States' abbreviations, "N.J."
among them, name their States to the nets but never head a section.
Abbreviations without their period, lower-case codes outside parentheses
and hidden text are listed under "Not modelled".

Note 8: a later html start tag builds nothing and adds only the
attributes the html element lacks, as html5lib does. Extending the
differential to raw text, noscript and later html start tags found two
more tree gaps, now closed: a noscript end tag with a special element open
inside it is ignored, and a table part's start tag outside any table
builds nothing.

Checks:
- Every registered reader's output, cell values included, hashes as in
  round 8 on Python 3.13.9 and 3.14.7 (registry-v2-r8.json, byte for
  byte). All 777 pinned charts' selectors equal 93824c2's.
- On the 40 pinned HTML captures, the tree's tables, blocks and nesting
  equal html5lib 1.1's on all 40, on both versions.
- html5lib differential: no mismatch on 5,000 pages per mode with round
  7's generator, or with this round's, which adds raw text, noscript,
  later html start tags and plaintext (626 pages refused, 9,374
  compared), on both versions.
- D4's six test modules: 575 passed on 3.13.9 and on 3.14.7 (unit 319,
  artifact 256; round 8 had 462, unit 206).
- Mutants: 59 of this round's 60 fail tests. H1, which nets a heading's
  whole text and first line only, survives: the whole text holds every
  line's text, so only an alias split across lines tells it apart.
  mutants_r8.py: 7 of the 7 of its 14 that still apply. mutants_r7.py: 31
  of the 31 of its 46 that still apply. This round ports the rest, or
  names the round-8 or round-9 mutant that makes the same change.
- On Python 3.13.9, 92 of the 300 invented POMS tests fail against
  93824c2's reader, the same 92 in each of three Hypothesis seeds.
- black -l 79, ruff and git diff --check are clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits November 1, 2026 09:22
The svg and math end-tag check dropped its "more than one ended" branch:
an end tag that names the innermost svg or math closes only that one, so
the branch never decided a page.

The tests add a short line holding each dating word alone, a split date
that only the bare reading shows, and an h5 whose earlier year holds no
dating word, so that a mutant of each of those rules fails a test. The
earlier-year test drops two cases that held a second dating word.

Pinned output holds: 28 files the same, 0 differ, 0 refused, 777
charts, and the registry fingerprint matches round 8's byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under the round-13 footnote-word rule the review's Q7 witness, a leading
"See also" sup, refuses with or without the mutant. A digit marker before
a leading "As" sup separates them: every dropped word must be a footnote
word, so the line is no footnote body and its date leaves the section's
unread, while Q7, which needs any one word, makes it a footnote body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three sentences that the round-13 fix added or extended now name who
acts: aggregate_tables lists the tree's gaps, a long date sentence drops
its second date, and the tree pops the svg or math whose place the stack
has lost. Both modules' ast, without docstrings, equals 179496e's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Round 13 found that reading "Effective Dates:" in any case (1b319dc)
turned pages the parent read or refused into silent wrong reads. The
three lines go back to 32cc85d's text. A long sentence that holds the
words in lower case dates its chart and meets the State guards again,
and a range in another case sets no section revision date. Round 12's
Note 4 returns as a stated limit.

The round's other findings reach invented pages only and change no
record on a pinned input, so they stay as stated limits. The docstrings
of both readers stop claiming those forms, and aggregate_tables.py
changes in docstrings only.

Tests replace the four cases that pinned the any-case reading with the
review's E4, ES1, V6 and V7 and the lower-case revision line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits November 2, 2026 04:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master at 1808285 holds unit 19,664, artifact 4,271, integration_psid
1,471, reproduction_legacy 520, oracle_policyengine 308, total 26,234.
D4 adds 794 unit and 256 artifact tests, so the files now read unit
20,458, artifact 4,527, total 27,284. CI's tier policy test checks the
count on the full collection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 3 commits November 2, 2026 10:39
Keep both opt-in blocks in the birth-evidence exclusions and its
reachability test: SSI0 from master and the aggregate-table readers from
D4, with the shared package __init__ listed once. Take master's tier
files; the next commit recounts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master at 89d064b holds unit 20,454, artifact 4,271, integration_psid
1,471, reproduction_legacy 520, oracle_policyengine 337, total 27,053.
D4 adds 794 unit and 256 artifact tests, so the files now read unit
21,248, artifact 4,527, total 28,103. CI's tier policy test checks the
count on the full collection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master adds the B0.2 stream flush (#596) and no test, so the recount
on 89d064b stands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis and others added 2 commits November 2, 2026 16:40
Master adds #563's Track B changes. Only the two tier files conflicted;
take master's, and the next commit recounts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Master at edba88f holds unit 22,859, artifact 4,271, integration_psid
1,471, reproduction_legacy 520, oracle_policyengine 337, total 29,458.
D4 adds 794 unit and 256 artifact tests, so the files now read unit
23,653, artifact 4,527, total 30,508. CI's tier policy test checks the
count on the full collection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@MaxGhenis
MaxGhenis merged commit 97003ac into master Nov 3, 2026
12 checks passed
@MaxGhenis

Copy link
Copy Markdown
Contributor Author

The Microcosm Dynamics coordinator merged this PR at ca93c707dab8d26ef676c92b48d1333f5923f7fb with --merge --match-head-commit, as 97003ac27229a59617ff31eb0f15e5e31b2734bd (10:44Z, 2026-11-03).

  • Review. GPT-6.1 Sol reviewed 35859218 in Subfleet job 20261102-115756-d4-review-r15 and approved it, leaving no finding of medium or higher severity open. In its three low findings, GPT-6.1 Sol asked for wording in this PR's description, and the income-and-resources lane added that wording at 10:41Z.
  • After the review. The lane merged master edba88f7 in 38895135 and recounted the test tiers on the merged tree in ca93c707. Of the 63 files that changed between 35859218 and the head, 61 match master's copies, and the lane had changed none of them before the review. In the other two, tests/tier_counts.json and tests/README-tiers.md, the lane recorded 23,653 unit and 4,527 artifact tests, 30,508 in all.
  • CI. gh pr checks 574 exited 0 at the head, with 11 checks passing and deploy skipped (Tests run 41530649476). In that run, tests/test_tier_policy.py compared the committed counts with the collected suite and passed. GitHub reported the PR mergeable.
  • The slot. Before the next PR in the slot lands, its owner merges master 97003ac2, or later, into it and recounts the test tiers.

@MaxGhenis
MaxGhenis deleted the ir/d4-20261024 branch November 3, 2026 10:48
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
Master's #573 (SSI0) and #574 (D4) each added a block to the
birth-evidence exclusions, their expected tuple and the reachability
test, where D2 adds its own. Keep master's blocks and put D2's after
them in all three places. Both sides add the same empty
tests/income_resources/__init__.py. The merge takes master's tier
files, and the next commit recounts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
…nch's tests

Master adds #574 (D4), which changes no Track B file. The tier files
take master's counts plus the 2,667 unit tests this branch adds since
edba88f: 26,320 unit and 33,175 in all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis added a commit that referenced this pull request Nov 3, 2026
Master's #573 (SSI0) and #574 (D4) each added a block to the
birth-evidence exclusions, their expected tuple and the reachability
test, where CE1 adds its own. Keep master's blocks and put CE1's after
them in all three places. D4's block already lists
src/populace_dynamics/income_resources/__init__.py, which both sides add
as the same blob, so CE1's exclusion blocks keep only coverage_rules.py.
The merge takes master's tier files, and the next commit recounts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview — ca93c707 Deployed Nov 2, 2026 by vercel[bot]
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