Repository navigation
fix(text): aligned tables, cover-only form detection, 8-Ks read with their exhibits - #96
Merged
Merged
Conversation
A "$" merged into its number dropped the symbol's cell, so every value after it sat one column left of the rows without one; a value spanning the symbol and number columns (colspan 2) landed apart from one beside a "$". A self-closing <td /> spacer swallowed the cell after it. Merges now keep each cell's position, a symbol column joins the number's where no row fills both, and a self-closing cell reads as empty.
A document opened on its own took the first "Form 10-K" anywhere in its first 400,000 characters as its form, so an earnings release whose safe harbor cites the annual report loaded as a 10-K. A cover names its form in its first few hundred characters; only those are read now.
An 8-K loaded from EDGAR was its cover page alone, so search_text found nothing the release says and told the caller to reword. Its EX-99 exhibits are now read into the same text, each a section under its type with its offset — the layout the RoboSystems sec server reads an 8-K in, so the two answer alike. join_texts is the assembly, exported for a host that builds the text itself. The items note and next steps point at the text when the exhibits are in it; an 8-K whose exhibits cannot be reached loads alone.
…read Under pure, or reading the tagged text alone, the exhibits are not in the text the tools search and sections.items is not shown, yet the note and next steps sent the caller there; they now say documents in those modes. One exhibit out of reach no longer drops the rest, and two exhibits typed plain EX-99 each keep a section id of their own.
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Comparing the two servers on Workiva's latest earnings 8-K showed three problems in xbrlkit's text tools.
search_texton the 8-K found nothing in the release, because an 8-K loaded as its cover page alone. The financial tables put values in the wrong column. And the release, loaded by its own URL, came back labelled a 10-K. This PR fixes all three. The table fix also reaches the RoboSystemssecserver, which renders filing text through xbrlkit.Changes
text/tables.py(table → markdown)$,(or($merged into its number, the cell it sat in was dropped, so every value after it in the row moved one column left. The same happened when a trailing)or%was attached. Cells now keep their positions. Each column a symbol stood in is joined to the next column when no row has values in both. That also lines up Workiva's layout, where a value without a$spans the symbol and number columns.<td ... />(Apple's filing agent writes spacers this way) was read as an open tag and swallowed the cell after it. It now reads as an empty cell.serve/session.py(cover form)_form_on_the_coversearched the first 400,000 characters for "Form 10-K", so a press release's safe-harbor citation made it a 10-K. Only the top 2,000 characters are searched now. Real covers name their form within about 200.serve/(8-K exhibits)other_documents/read_other_document. They are joined into one text:## Form 8-K, then## EX-99.1and so on, each a section with its offset. This is the layout the RoboSystemssecserver reads an 8-K in. If the exhibits can't be reached, the 8-K loads on its own as before.join_textsandFORM_SECTION_IDare added to the declaredxbrlkit.servesurface, so a host that builds the text itself can use the same assembly.items_note,nextsteps, server instructions, thedocumentstool description andserve/README.mdnow point toread_text/search_textwhen the exhibits are in the text and the text tools read it whole. Underpure, or when only the tagged text is read, they still point todocuments, because there the exhibits aren't in the text the tools search.EX-99each get their own section id.Output Impact
CHANGED OUTPUT in the text tools (
search_text,read_text,describe_filingsections), not in the serializations. Holon, TAVI and model.json don't go through the table renderer.sections.itemsgainsform_8k/ex_99_1. A load costs the index fetch plus one fetch per exhibit.form: nullinstead of a guess.build_text, so it picks up the table change when its pin moves. Text it has already cached or indexed keeps the old rendering until rebuilt.Testing
The pre-commit hook ran ruff, basedpyright and the suite on each commit; the last run had 696 passed, 2 skipped. New tests cover the
$position shift, the colspan-2 layout, a symbol column that holds real values, self-closing cells, cover vs. citation,join_texts, an 8-K read with its release, an 8-K whose exhibits can't be reached, one exhibit failing while the others load, the exhibit guidance inpureand tagged-text modes, and a 10-K that doesn't reach for exhibits.Tables, old vs. new renderer: five documents, counting rows with values outside the columns most rows use. The total fell from 1,574 to 329:
0001445305-26-000059): 47 → 00000320193-25-000079): 79 → 50001193125-26-323660): 270 → 270001045810-26-000021): 111 → 110001628280-26-008131): 1,067 → 286I read the six tables this count flagged as worse; each is now correct. For example, Apple's buyback total sits under "Approximate Dollar Value", and JPMorgan's loan maturities sit under their buckets.
Cover form: the first "Form X" match is at 125–215 characters in the four 10-Ks and the Workiva 8-K, and at 13,455 in the Workiva release.
8-Ks live from EDGAR:
WK 8-K(0001445305-26-000059, inline XBRL cover): EX-99.1 is read in, and "free cash flow|guidance" returns 20 hits, all labelled EX-99.1.0001445305-18-000131, document-only path): EX-99.1 is read in, with 7 hits.🤖 Generated with Claude Code