Skip to content

fix(sec): sync foreign private issuer forms (20-F/6-K/40-F) - #4419

Merged
daniel3303 merged 1 commit into
daniel3303:mainfrom
DrewWhittleNZ:feat/sec-foreign-filer-forms
Aug 21, 2026
Merged

fix(sec): sync foreign private issuer forms (20-F/6-K/40-F)#4419
daniel3303 merged 1 commit into
daniel3303:mainfrom
DrewWhittleNZ:feat/sec-foreign-filer-forms

Conversation

@DrewWhittleNZ

Copy link
Copy Markdown
Contributor

Disclosure: I'm not a C# developer and didn't write this fix by hand — I ran into this gap while evaluating Equibles for my own project (a foreign filer showed up as a known company with zero documents), used Claude (Anthropic's AI assistant) to trace the root cause against your source, and prepared this patch with it. I verified it live against a running instance with real data (see Testing below) before opening this. Happy to answer questions or make changes if anything here doesn't fit your conventions.

What

DocumentScraperOptions.DocumentTypesToSync's default list never included TwentyF/SixK/FortyF — a foreign private issuer's equivalents of TenK/EightK (FortyF specifically for Canadian filers using the MJDS annual-report regime). Everything downstream of that list already fully supports these three types:

  • DocumentTypeExtensions.DatabaseToSecMapping already maps all three to their DocumentTypeFilter
  • DocumentScraper's form-name detection, HTML/XBRL extraction, and PDF fallback (TryExtractPdfFallback, for paper-filed 6-K/20-F submissions that wrap a uuencoded PDF with no HTML) already handle them
  • DocumentScraper.ForeignFilerAnnualForms already uses 20-F/40-F report dates to infer fiscal year-end when no 10-K exists

But because the sync's own default type list never included them, a company with no domestic 10-K/10-Q/8-K on file synced as a known company with zero documents ever ingested, regardless of how many 20-F/6-K/40-F filings it actually has in EDGAR. Found this via OceanaGold (ticker OGC, CIK 1487326) — a Canadian gold miner that relisted on the NYSE in April 2026 and has been furnishing 6-Ks since, none of which were ever synced.

     public List<DocumentType> DocumentTypesToSync { get; set; } =
     [
         DocumentType.TenK,
         DocumentType.TenQ,
         DocumentType.EightK,
         DocumentType.TenKa,
         DocumentType.TenQa,
         DocumentType.EightKa,
+        DocumentType.TwentyF,
+        DocumentType.SixK,
+        DocumentType.FortyF,
         DocumentType.FormFour,
         ...

Testing

No .NET SDK or Docker in the environment used to write the patch, so this wasn't build/test-verified locally — verification happened entirely against a separate live self-hosted deployment (rebuilt just the worker service, since this lives in Equibles.Sec.HostedService which only Equibles.Worker.Host runs):

  • Before fix: OGC existed as a known company but had zero rows in Document despite the SEC having real filings for it.
  • After fix: confirmed via both a direct DB query and the MCP ListCompanyDocuments tool that all of OGC's real 6-K filings were ingested (12 documents, correctly typed and dated).
  • Cross-checked against SEC EDGAR directly (data.sec.gov/submissions/CIK0001487326.json, not just this codebase) to confirm the match is exhaustive, not a partial sample: OGC's entire EDGAR history is 34 entries total (no archive pagination — files is empty), of which exactly 12 are 6-K — matching what got ingested 1:1. Zero 20-F/40-F exist for OGC yet (they only resumed active SEC reporting this April after a historical Rule 12h-6 deregistration, so their first annual-report deadline hasn't arrived), so this fix can't yet be confirmed against a live 40-F/20-F for this specific company — but the sync mechanism treats all three added types identically (same filter mapping, same generic type-agnostic iteration in DocumentScraper), and 6-K ingesting correctly is strong evidence the other two will too once one exists to fetch.
  • Updated ConfigurationTests.DocumentScraperOptions_DocumentTypesToSync_DefaultsToExpectedTypes for the new count (18 → 21) and order.

The SEC filter mapping, form-name detection, and document extraction
already fully support these three types -- 40-F/20-F report dates are
even already used elsewhere to infer fiscal year-end when no 10-K
exists -- but DocumentScraperOptions.DocumentTypesToSync's default list
never included them alongside the domestic forms. A foreign filer with
no 10-K/10-Q/8-K on file (e.g. OceanaGold, ticker OGC, CIK 0001487326,
which files 6-K routinely and 40-F annually) synced as a known company
with zero documents ever ingested, no matter how many 20-F/6-K/40-F
filings it actually has in EDGAR.

Not build/test verified locally -- no .NET SDK or Docker available in
this environment.

@daniel3303 daniel3303 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The base-form change is correctly wired through the existing SEC mappings and generic ingestion path. Scoped Release build, formatting, configuration, and mapping tests pass. Foreign-form amendments can follow separately.

@daniel3303
daniel3303 merged commit 0be7e96 into daniel3303:main Aug 21, 2026
1 check passed
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.

2 participants