Skip to content

Code extractors - #308

Merged
sroussey merged 37 commits into
mainfrom
code-extractors
Aug 22, 2026
Merged

Code extractors#308
sroussey merged 37 commits into
mainfrom
code-extractors

Conversation

@sroussey

Copy link
Copy Markdown
Contributor

No description provided.

- Introduced `EvalOfferingTablesTask` to score the SPAC offering/promote table parser against stored rows using on-disk accession documents.
- Added a new CLI command `offering-tables` to facilitate the evaluation process with options for extractor ID, limit, and CIK.
- Implemented `printOfferingTablesReport` function to display evaluation results in a user-friendly format.
- Updated tests to cover the new command and its options, ensuring proper validation of input parameters.
- Added `EvalUnderwritersTask` to score the SPAC underwriter table parser against stored rows using on-disk cache.
- Implemented a new CLI command `underwriters` with options for extractor ID, limit, CIK, and output format.
- Created `printUnderwritersReport` function to display evaluation results in a structured format.
- Developed tests for the new command and its options, ensuring comprehensive coverage of input validation and functionality.
- Introduced new utility functions for parsing and evaluating underwriter data from S-1 filings.
… commands

- Introduced `EvalUseOfProceedsTask` and `EvalExecutiveCompensationTask` to score the respective parsers against stored rows using on-disk cache.
- Implemented new CLI commands `use-of-proceeds` and `executive-compensation` with options for extractor ID, limit, CIK, and output format.
- Created `printUseOfProceedsReport` and `printExecutiveCompensationReport` functions to display evaluation results in a structured format.
- Developed tests for the new commands and their options, ensuring comprehensive coverage of input validation and functionality.
- Added utility functions for parsing and evaluating use-of-proceeds and executive compensation data from S-1 filings.
- Introduced `EvalBeneficialOwnershipTask` to score the beneficial ownership parser against stored rows using on-disk cache.
- Implemented a new CLI command `beneficial-ownership` with options for extractor ID, limit, CIK, and output format.
- Created `printBeneficialOwnershipReport` function to display evaluation results in a structured format.
- Developed tests for the new command and its options, ensuring comprehensive coverage of input validation and functionality.
- Added utility functions for parsing and evaluating beneficial ownership data from S-1 filings.
…e, and spac classification evaluation commands

- Introduced new evaluation tasks: `EvalManagementTask`, `EvalRelatedPartyTask`, `EvalSpacSponsorsTask`, `EvalSpacProfileTask`, and `EvalSpacClassificationTask` to score respective parsers against stored rows using on-disk cache.
- Implemented CLI commands for each evaluation task with options for extractor ID, limit, CIK, and output format.
- Created reporting functions: `printManagementReport`, `printRelatedPartyReport`, `printSpacSponsorsReport`, `printSpacProfileReport`, and `printSpacClassificationReport` to display evaluation results in a structured format.
- Developed tests for the new commands and their options, ensuring comprehensive coverage of input validation and functionality.
- Added utility functions for parsing and evaluating management, related-party, spac sponsors, spac profile, and spac classification data from S-1 filings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds deterministic (“code”) extractors and local eval harness tasks for several S‑1/424 sections, plus improves HTML block parsing so common SEC layout-table patterns segment correctly. This fits the codebase’s broader goal of extracting/normalizing filing data reliably while keeping extraction testable and measurable.

Changes:

  • Factor accession-doc cache path computation into a shared utility (cachedAccessionDocPath) and update ProcessAccessionDocFormTask to use it safely.
  • Improve HTML parsing/segmentation by handling layout-wrapper tables, peeling leading “The Offering” caption rows, and consuming CSS two-column label/value runs as a single table.
  • Add multiple deterministic parsers + corpus tests, plus CLI task wrappers and eval functions to score deterministic extractors against stored rows (no EDGAR fetch).

Reviewed changes

Copilot reviewed 95 out of 95 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/util/accessionDocPath.ts Adds cachedAccessionDocPath helper (safe cache path derivation + traversal guard).
src/util/accessionDocPath.test.ts Tests for cachedAccessionDocPath happy-path and unsafe filename handling.
src/task/forms/ProcessAccessionDocFormTask.ts Replaces inlined cache-path logic with cachedAccessionDocPath.
src/task/eval/EvalUseOfProceedsTask.ts New task wrapper for runUseOfProceedsEval with CLI progress integration.
src/task/eval/EvalUnderwritersTask.ts New task wrapper for runUnderwritersEval with CLI progress integration.
src/task/eval/EvalSpacSponsorsTask.ts New task wrapper for runSpacSponsorsEval with CLI progress integration.
src/task/eval/EvalSpacProfileTask.ts New task wrapper for runSpacProfileEval with CLI progress integration.
src/task/eval/EvalSpacClassificationTask.ts New task wrapper for runSpacClassificationEval with CLI progress integration.
src/task/eval/EvalRelatedPartyTask.ts New task wrapper for runRelatedPartyEval with CLI progress integration.
src/task/eval/EvalOfferingTablesTask.ts New task wrapper for runOfferingTablesEval with CLI progress integration.
src/task/eval/EvalManagementTask.ts New task wrapper for runManagementEval with CLI progress integration.
src/task/eval/EvalExecutiveCompensationTask.ts New task wrapper for runExecutiveCompensationEval with CLI progress integration.
src/task/eval/EvalBeneficialOwnershipTask.ts New task wrapper for runBeneficialOwnershipEval with CLI progress integration.
src/storage/use-of-proceeds/UseOfProceedsRepo.ts Adds listAll() to support eval scoring across stored rows.
src/storage/related-party/RelatedPartyTransactionRepo.ts Adds listAll() to support eval scoring across stored rows.
src/storage/offering/SpacUnitTermsRepo.ts Adds listAll() to support eval scoring candidate set selection.
src/storage/offering/SpacPromoteTermsRepo.ts Adds listAll() to support eval scoring across stored rows.
src/storage/executive-compensation/ExecutiveCompensationRepo.ts Adds listAll() to support eval scoring across stored rows.
src/storage/canonical/UnderwriterLinkRepo.ts Adds listByAccession() and listAll() used by underwriters eval.
src/storage/beneficial-ownership/BeneficialOwnershipRepo.ts Adds listAll() to support eval scoring across stored rows.
src/sec/html/TableExtractor.ts Adds isLayoutTable + leadingOfferingCaption helpers for better table handling.
src/sec/html/TableExtractor.test.ts Tests isLayoutTable behavior for data tables vs layout wrappers.
src/sec/html/parseToBlocks.ts Uses isLayoutTable, peels offering caption rows, consumes CSS two-column runs.
src/sec/html/parseEdgarHtml.test.ts Adds regression test ensuring “The Offering” is promoted into a real heading.
src/sec/forms/registration-statements/s1/useOfProceedsSchema.ts Adds persist-only source?: "deterministic" marker.
src/sec/forms/registration-statements/s1/underwriterSchema.ts Adds persist-only source?: "deterministic" marker.
src/sec/forms/registration-statements/s1/spacSponsorSchema.ts Adds persist-only source?: "deterministic" marker.
src/sec/forms/registration-statements/s1/spacProfileSchema.ts Adds persist-only source?: "deterministic" marker.
src/sec/forms/registration-statements/s1/spacClassifierSchema.ts Adds persist-only source?: "deterministic" marker.
src/sec/forms/registration-statements/s1/sectionSchemas.ts Adds persist-only source?: "deterministic" markers for multiple rows.
src/sec/forms/registration-statements/s1/parseSummaryCompensationTable.corpus.test.ts Corpus test guardrails for deterministic summary-comp parser vs golden labels.
src/sec/forms/registration-statements/s1/parseSpacUseOfProceeds.test.ts Unit tests for deterministic SPAC use-of-proceeds parsing.
src/sec/forms/registration-statements/s1/parseSpacUseOfProceeds.corpus.test.ts Corpus tests for SPAC use-of-proceeds parser vs golden labels.
src/sec/forms/registration-statements/s1/parseSpacUnderwriters.corpus.test.ts Corpus tests for SPAC underwriters parser vs golden labels.
src/sec/forms/registration-statements/s1/parseSpacSponsors.ts Adds deterministic SPAC sponsor identification parser.
src/sec/forms/registration-statements/s1/parseSpacSponsors.test.ts Unit tests for deterministic sponsor parser behavior and noise rejection.
src/sec/forms/registration-statements/s1/parseSpacSponsors.corpus.test.ts Corpus tests for sponsor parser vs golden labels.
src/sec/forms/registration-statements/s1/parseSpacProfile.test.ts Unit tests for deterministic SPAC profile tagging parser.
src/sec/forms/registration-statements/s1/parseSpacProfile.corpus.test.ts Corpus tests for profile parser vs golden labels.
src/sec/forms/registration-statements/s1/parseSpacClassification.ts Adds deterministic SPAC formation classifier parser.
src/sec/forms/registration-statements/s1/parseSpacClassification.test.ts Unit tests for deterministic formation classifier behavior.
src/sec/forms/registration-statements/s1/parseSpacClassification.corpus.test.ts Corpus tests for formation classifier vs golden labels.
src/sec/forms/registration-statements/s1/parseRelatedPartyTables.test.ts Unit tests for deterministic related-party table parser behavior and noise rejection.
src/sec/forms/registration-statements/s1/parseRelatedPartyTables.corpus.test.ts Corpus tests for related-party parser vs golden labels.
src/sec/forms/registration-statements/s1/parseOfferingTables.test.ts Expands offering/promote parsing tests (edge cases + regressions).
src/sec/forms/registration-statements/s1/parseManagementRoster.test.ts Unit tests for deterministic management roster table parser.
src/sec/forms/registration-statements/s1/parseManagementRoster.corpus.test.ts Corpus tests for management roster parser vs golden labels.
src/sec/forms/registration-statements/s1/parseBeneficialOwnership.corpus.test.ts Corpus tests for beneficial-ownership parser vs golden labels.
src/sec/forms/registration-statements/s1/executiveCompensationSchema.ts Adds persist-only source?: "deterministic" marker.
src/sec/forms/registration-statements/Form_S_1.storage.sponsors.test.ts Storage-level test: deterministic sponsor parse avoids model call and stamps provenance.
src/sec/forms/registration-statements/Form_S_1.storage.related-party.test.ts Storage-level test: deterministic related-party parse avoids model call and stamps provenance.
src/sec/forms/registration-statements/Form_S_1.storage.profile.test.ts Storage-level test: deterministic profile parse avoids model call.
src/sec/forms/registration-statements/Form_S_1.storage.ownership.test.ts Storage-level test: deterministic ownership table parse avoids model call.
src/sec/forms/registration-statements/Form_S_1.storage.management.test.ts Storage-level test: deterministic management parse avoids model call and stamps provenance.
src/sec/forms/registration-statements/Form_S_1.storage.compensation.test.ts Expands compensation storage tests; adds deterministic-table path coverage.
src/sec/forms/registration-statements/Form_S_1.storage.classification.test.ts Storage-level test: deterministic classification upgrade avoids model call.
src/sec/forms/registration-statements/Form_424.storage.ts Wires markSectionResolved into offering sections runner for 424 processing.
src/eval/runUseOfProceedsEval.test.ts Tests bucketing logic when deterministic parser returns empty.
src/eval/runUnderwritersEval.test.ts Tests bucketing logic when deterministic parser returns empty.
src/eval/runSpacSponsorsEval.test.ts Tests bucketing logic when deterministic parser returns empty.
src/eval/runSpacProfileEval.test.ts Tests bucketing logic when deterministic parser returns null.
src/eval/runSpacClassificationEval.test.ts Tests bucketing logic when deterministic parser returns null.
src/eval/runRelatedPartyEval.test.ts Tests bucketing logic when deterministic parser returns empty.
src/eval/runOfferingTablesEval.test.ts Tests bucketing logic when deterministic parser returns null.
src/eval/runManagementEval.test.ts Tests bucketing logic when deterministic parser returns empty.
src/eval/runExecutiveCompensationEval.test.ts Tests bucketing logic when deterministic parser returns empty.
src/eval/runBeneficialOwnershipEval.test.ts Tests bucketing logic when deterministic parser returns empty.
src/cli/groups/evalOptionValues.test.ts Extends CLI option validation coverage for new sec eval subcommands/options.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

sroussey and others added 10 commits August 18, 2026 23:13
…promote

Generic "shares outstanding before this offering" can include underwriter (EBC) founder shares. Keep that count as a fallback and prefer a later named founder/Class B figure.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Introduced the `registerSafeFetch` function to the exports in `index.ts` for improved functionality.
- Updated tests in `index.barrel.test.ts` to verify the presence of the new `registerSafeFetch` function.
- Reorganized some exports for better clarity and consistency.
processFormS1 clears its destination tables up front and then, for each
section, ran a deterministic parser that won on ANY non-empty result while
hardcoding the columns it cannot read. The section persisted a strict subset
of what it had just emptied, resolved clean, and re-took the same path on
every replay, so nothing self-corrected: the related-party table lost every
transaction, the issuer ticker series was emptied and never refilled, the
SPAC profile's description/team were never written, and a partial roster
parse reported itself complete and closed person_role tenures the filing
still asserts.

Introduce a declared coverage contract. A DeterministicPass names the
destinations it covers; a section names the destinations it rewrites; the
runner lets the parse stand in for the model only when covers is a superset
of clears, and an undeclared clears never preempts. The parse runs ONCE,
outside the verification retry loop, all-or-nothing: a row that fails the
floor or span verification discards the whole parse and falls through to the
model recording nothing, rather than re-asking a pure function three times
and dead-lettering the model for a parser miss. Persist callbacks read
meta.source instead of a field on row zero, and meta.complete comes from the
pass itself (default false) rather than from counting already-filtered rows.

Also delete the isSpac && !looksLikeUnitIpo gate on the underwriters and
use-of-proceeds sections. looksLikeUnitIpo only reads markdown table rows, so
it fired on every SPAC whose "The Offering" section is prose — skipping both
sections after their tables were cleared, and resolving any pending dead
letter for them. Measured over the committed S-1 corpus it discards 2 of 20
SPAC fixtures, 87k characters of Underwriting prose and 33 hand-verified
golden rows. markSectionResolved goes with it: a parser failing to recognise
a unit IPO is not evidence about the Underwriting section.

Repairing already-processed filings needs `sec extractor backfill S-1 --force`
(and `424 --force` for the offering sections).
…ew-xs0tph-sec-deterministic-coverage

Deterministic passes may not preempt what they cannot supply
Run `bun run format`. Restores the trailing commas dropped from 18 export
lists and removes the trailing blank line at EOF, so `format-check` — the
first CI step — passes again. No behavioural change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LowBJQsCghLDiHwPN6FgUT
Four sections declared `clears` and `covers` at TABLE granularity while their
model-free parse fills only some of the table's columns, so `preempts` returned
true unconditionally — after the section had already cleared its rows. The
columns the parse cannot read were rewritten as NULL, the section resolved
clean, and every replay took the same path.

- underwriters: `role_detail` and `over_allotment_shares` are hardcoded null;
  the role is prose beside the syndicate table.
- beneficial ownership: six columns hardcoded, including
  `is_selling_stockholder: false` — a positive false claim.
- management: `bio` is hardcoded null and `observePerson` upserts the row.
- sponsor promote: the `||` gate returns a row on one of two anchors, so the
  other five columns come from a partial read.

No change to `preempts` was needed: destination names are compared as plain
strings, so naming a table column by column in both sets makes the pass decline,
and a mixed-granularity pair declines in both directions. `covers` may now be a
function of the section text, resolved before `extract` and treated as covering
nothing if it throws; `promoteCoverage` and `ownershipCoverage` compute it from
the same walk their parse performs, which keeps those two passes on for the
filings whose tables really do state every column.

Management roster closure (`closeUnassertedPersonRoles` for `s1:management`),
silently dead because a preempting pass can never report a complete population,
resolves as a side effect; `complete: () => false` is deleted as dead config.

`use_of_proceeds.note` stays bare — the prompt directs every qualifier into
`purpose`, which the parse copies verbatim. `executive_compensation.footnote` is
column-qualified: the prompt strips footnote markers out of every other column,
so that text lands nowhere else.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LowBJQsCghLDiHwPN6FgUT
sroussey and others added 10 commits August 20, 2026 09:29
…-extractors-format

chore: restore prettier formatting in src/index.ts
…-extractors-covers

fix(s1): a deterministic pass may not preempt what it cannot supply
SKIP_PURPOSE matched its total/source phrases ANYWHERE in a row label, but
those phrases are also how filers qualify a real line item. The
underwriting-commission row is routinely written "Underwriting commissions
(2.0% of gross proceeds from units offered to public)" and the residual trust
row "Not held in trust account after offering expenses", so both were dropped.

That is silent deletion, not a missed hit: `use-of-proceeds` declares
`clears: {use_of_proceeds}` and the deterministic pass declares the identical
bare `covers`, so it preempts the model on every SPAC filing, and the table has
already been emptied by the time the parse runs. The section then resolves
clean, with no dead letter and the same result on every replay. Measured
against the committed golden labels: 13 filings, 16 line items — the largest
expense row in each — and the same code path runs under extractor id `424` for
the priced prospectus, i.e. the final deal figures.

Every alternative is now anchored, or scoped to where it means what it says:

- the total/source/ratio family is anchored at the start of the label, which
  is where a filer names a row that is the table's own arithmetic;
- `reimbursed expenses` is dropped entirely — the golden labels record it as a
  real line item, and the parse now emits it (the label set for one Churchill
  fixture was missing the row its identically-tabled sibling carries, added
  here from the filing);
- the per-share/per-unit metric rules are tested against the label with its
  parentheticals removed, so a metric row is still skipped while a line item
  qualified "($10.20 per unit)" survives.

Anchoring exposed the other half of the shape: a filer who factors the sources
into a block under a bare "Gross proceeds" heading writes its children as plain
labels ("Offering", "Private Units"), which only the heading identifies as
sources. Such a heading now opens a block that the matching expenses heading
closes.

`useOfProceedsIsComplete` reports whether the walk enumerated the table, from
its own decline log rather than a second reading: a labelled row between the
first and last line item, carrying no readable figure and matching no declared
rule, is a row the parse could not represent. It errs toward incomplete, which
costs a model call rather than a filed line item.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ske1Jwk7fDFxHykfZGEzce
`preempts()` authorized a model-free parse to replace the model whenever
`covers` was a superset of `clears`, and both sets name DESTINATIONS. For a
destination holding many rows that says only "the parse fills every column
persist writes" — never "the parse found every ROW". The caller has already
cleared the destination, so a walk that reads N of M rows persists N and the
section is marked resolved: no dead letter, no diagnostic, the same answer on
every replay. The unanchored use-of-proceeds skip rules fixed in the previous
commit were one instance of exactly this hole, and two more were live:

- `spac-sponsors` covers `clears` exactly, so `parseSpacSponsors` preempted on
  its two prose patterns. Both require `our|the` immediately before `sponsor`,
  so a vehicle whose second sponsor is introduced as "our co-sponsor, Beta
  Holdings LLC, is …" rebuilt an already-cleared `spac_sponsor_link` with one
  of two sponsors.
- `beneficial_ownership` under a full `ownershipCoverage`: rows failing
  `looksLikeOwner` are dropped and ones whose stub carries a street number are
  truncated by `peelName`, before persist and before the section resolves.

`DeterministicPass.complete` already expressed the missing claim but was read
only for roster closure, and no wired pass declared it. It is now the row half
of the contract and a precondition of preempting at all, checked through
`assertsCompletePopulation` (a missing or throwing claim declines, matching how
a throwing `covers` is treated). A pass that cannot say its rows are the whole
population costs a model call instead of losing filed rows.

Declared per pass, from what each destination and walk can honestly support:

- `spac-classification` and `sponsor-promote` write one row per filing, so
  producing that row IS enumerating the population — they keep preempting, and
  `promoteCoverage` keeps answering the column question;
- `use-of-proceeds` claims completeness from the walk's own decline log
  (`useOfProceedsIsComplete`), which holds on 16 of the 20 committed SPAC
  fixtures it parses and correctly declines the one whose trust row carries no
  figure;
- `spac-sponsors` and `beneficial-ownership` declare nothing and stop
  preempting: neither prose regexes nor a table walk that filters its own rows
  can report that the section named no one else.

The corpus tests gain the recall side, which every existing assertion missed
because a dropped row invents nothing: sponsors and classification must agree
with the golden labels on every filing they answer for, the promote pass must
be right about every column its coverage claims (80 field checks over 17
filings), and the ownership walk's four known drops are pinned as a list so a
new one fails and closing one prompts revisiting the claim.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ske1Jwk7fDFxHykfZGEzce
Both pinned the preemption rule the previous commit replaced, and both were
mirror images of what the rule now says. `preempts()` used to authorize a
model-free parse on column coverage alone, so `spac-sponsors` and
`beneficial-ownership` stood in for the model; requiring a row-completeness
claim retires both, because two prose patterns cannot report that the section
named no other sponsor and a walk that filters its own rows cannot tell a row
it dropped from a row the table never had. The destination is cleared before
persist, so a subset there is filed data lost with no dead letter — the model
call is the cheaper side of that trade.

So the assertions flip rather than relax. Each test now proves the section
reaches the model and that the entity is still persisted through it: the
section's prompt appears in the recorded calls, and the observation's
provenance carries the model's id instead of `deterministic`. Each also opens
by running the deterministic parse over the same section text and requiring it
to read the filing outright, which is what makes the filing the case that
demonstrates the rule — coverage is not the question, and a parse that handles
the section perfectly still does not get to answer for it.

The ownership resale test keeps every assertion and gains an accurate name: it
no longer discriminates preemption from non-preemption, since no ownership
section preempts now, and what it verifies is that the class, offered and
after-offering figures the table states survive the model path — the three the
walk would have written null.

Verified on this branch: `bun run test` 428 files / 3885 tests passed, 3
files / 20 tests skipped, 0 failed; `bun run format-check` and `bun run build`
clean. The two tests were confirmed to pass on `code-extractors` and fail at
this branch's head before the change, and the replacements fail on
`code-extractors` and pass here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ske1Jwk7fDFxHykfZGEzce
…roved CIK management

- Introduced `spacProcessSweeps` to manage SPAC filings more effectively, allowing for differentiated handling of known and unknown CIKs.
- Updated `registerSecSyncLeaves` to utilize the new sweeps, improving the processing logic for SPAC filings.
- Enhanced `runFormsSweep` to accept `eightKItems`, allowing for more granular control over which 8-K filings are processed based on item codes.
- Added tests for the new functionality in `spacProcessSweeps` and updated existing tests to cover new CIK listing logic.
- Refactored `listSpacProcessCiks` to leverage `listKnownSpacCiks`, ensuring accurate identification of known SPACs.
…-deterministic-recall

Stop the deterministic passes from silently truncating the sections they preempt
…oved handling

- Added `--only` option to filter CIKs based on processing history (never-processed or updates).
- Introduced `--step` option to specify which step to run for multi-step SPAC commands.
- Enhanced `runSpacTimelineIssuers` to support concurrency and filing date filtering.
- Updated `ComputeFormsWorklistTask` to handle filings based on the `filedOnOrAfter` date.
- Added tests to validate new functionality and ensure correct behavior of filtering and command options.
Stub ModelRecord with no provider so CSV / --models can name the sync walk without a cloud key.

Co-authored-by: Cursor <cursoragent@cursor.com>
sroussey and others added 12 commits August 21, 2026 11:09
A list id of deterministic runs the section pass (or []) instead of StructuredGenerationTask.

Co-authored-by: Cursor <cursoragent@cursor.com>
runSection no longer always walks first; a miss falls through without re-asking a pure function.

Co-authored-by: Cursor <cursoragent@cursor.com>
Production wraps pass DeterministicPass into modelExtractChain; omit the id and the walk does not run.

Co-authored-by: Cursor <cursoragent@cursor.com>
Tests that need the parser pass deterministic in the model list; AI-only tests keep a single fake model.

Co-authored-by: Cursor <cursoragent@cursor.com>
Same reserved id as production; $0; no prompt; extractors with no parse return [].

Co-authored-by: Cursor <cursoragent@cursor.com>
Walk-then-model is SEC_S1_MODEL=deterministic,<id>; the built-in default stays cloud-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
The new deterministic row widened the provider column.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Introduced `ParserEvalCase` and `ParserEvalReport` interfaces to standardize the structure of evaluation reports.
- Removed redundant print functions for various report types, consolidating logic to improve maintainability.
- Enhanced error handling in parsing functions to ensure robustness during evaluation runs.
- Eliminated the `eightKItems` parameter from `runFormsSweep` and related functions to simplify the workflow.
- Removed associated tests and logic that filtered 8-K filings based on item codes, streamlining the forms processing task.
- Updated `ComputeFormsWorklistTask` to reflect the removal of `eightKItems` handling.
- Eliminated multiple `clears` sets across various sections in `Form_S_1.storage.ts` and `offeringSections.ts` to reduce redundancy and improve clarity.
- Updated related tests to reflect the changes in the handling of clears, ensuring consistency in the extraction process.
- Enhanced the `modelExtractChain` and `sectionRunner` to streamline the preemption logic, allowing for more efficient processing of deterministic passes.
- Added a global setup script to share a parsed S-1 corpus across multiple test files, reducing redundant parsing and improving test efficiency.
- Updated test files to utilize the new `loadS1Corpus` function, which caches the corpus for faster access.
- Refactored test cases to ensure they correctly reference the new corpus loading mechanism, enhancing maintainability and performance.
@sroussey
sroussey merged commit d0941de into main Aug 22, 2026
1 check passed
@sroussey
sroussey deleted the code-extractors branch August 22, 2026 01:05
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.

3 participants