EqualifyEverything / equalify-iris

fix(assembly): a word broken at a line end rejoins where the document proves the spelling (#448)
#334's third hyphen axis: a word the printing broke at a line end, carried into the markup with its hyphen, where the page it landed on never writes the word whole. `splitWordContradictions` cannot see it — its evidence is one page's own two spellings — and this file had already dismissed another arm's output as unavailable at run time. It never considered another PAGE of the same submission, which is available at assembly, and which is where the whole spelling usually is. So `joinBrokenWords` repairs where part B re-asks, and it takes three conditions to earn that: 1. the closed spelling appears somewhere in the document, or `ad-valorem` closes into an `advalorem` no page prints; 2. the fragment after the hyphen is not a word the document uses alone, because a compound joins WORDS — which is what leaves `inter-state`, `non-tax`, `non-farm`, `Mid-east` and `Non-property` for the model; 3. the closed spelling is not on the page carrying the hyphen, which keeps this pass off part B's ground. Without it, 7 of 36 joins reversed an answer the page agent gave holding the image. Each condition reads the document at its own width, and the widths are the whole argument. Corroboration LICENSES a join, so it is narrow: what a reader is shown, with `script` and `style` content dropped, because a `.crosshatch` selector is not a spelling the document prints and the log line's evidence field must name one a reader can find. The tail GUARD refuses a join, so it is wide: prose plus every attribute value, quoted or bare, entities decoded, plus any quote pair or `name=value` run anywhere in the markup, comments included — a bare `state` living only in an `alt` is still the document using the word. The page condition reads the page at part B's width exactly, so it declines precisely the population part B raises and no word falls to neither pass. Measured over the 1,221 page files on disk (75 dir x model x submission arms): 42 (word, submission) cases carry this shape mechanically, of which a hand-read is 26 line breaks, 13 printed compounds and 3 the model's own prose. The shipped function joins 29 cases / 18 distinct words across 8 submissions, removing 32 characters, and leaves 44 cases / 10 distinct hyphenated beside a closed spelling elsewhere. The ungated widening would have put a problem on 73 pages to reach 7 line-break splits, which is why it is not what shipped. Runs after `joinPageBreakProse`, which names its successor, so a word broken across a PAGE and one broken across a LINE are settled by the same pass; inside `assembleBodyWithReport`, not `runAssembly`, so the lint-disclosure reproduction claim still holds; not in the page loop, because extraction forbids relying on completion order. New `assembly_words_joined` event, documented, with `words` capped at 20 while `count` stays whole. Five limits are documented rather than fixed, including the `alt`/`aria-label` mismatch that makes one of them WCAG 2.5.3 rather than an inconsistency. Seven review rounds. Round 1 found a real defect — `extraction.ts` claimed the two passes could not overlap and they overlapped on 7 of 36 joins — which is where the third condition came from. Rounds 2 and 3 found the guard blind to attribute values, to entities inside them and to unquoted ones, each of which closed a printed compound; widening it cost zero joins at every width measured. Rounds 4 to 6 caught the stated width being narrower than the real one three times. Round 7 returned with no notes. The corpus figures were identical across all seven. #334 stays open: its dropped-cover axis is untouched. Co-Authored-By: bbertucc <46652+bbertucc@users.noreply.github.com> Co-Authored-By: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blake Bertuccelli-Booth Blake Bertuccelli-Booth committed on Sep 9, 2026, 06:09 PM
Showing 5 changed files +811 additions -20 deletions
Browse files at this commit →