Skip to content

feat(models): download model weights before use, with on-screen progress#198

Merged
sroussey merged 4 commits into
harnessfrom
claude/sec-model-download-harness-8ibeca
Jul 16, 2026
Merged

feat(models): download model weights before use, with on-screen progress#198
sroussey merged 4 commits into
harnessfrom
claude/sec-model-download-harness-8ibeca

Conversation

@sroussey

@sroussey sroussey commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Commands that use a model must have its weights on disk before generation, but providers differ on when that happens: cloud models have nothing to download; HuggingFace ONNX auto-fetches on first generation; but node-llama-cpp (GGUF) loads its model_path directly and never fetches at generation. This PR adds a single seam that normalizes the download across providers, makes the download's progress render on screen, and surfaces per-section generation progress on the CLI task row.

What changed

ensureModelDownloaded (src/config/ensureModelDownloaded.ts) — the single seam.

  • Runs ModelDownloadTask for the local providers (HF_TRANSFORMERS_ONNX, LOCAL_LLAMACPP); no-op for cloud (they register no model.download run-fn, so dispatching would throw).
  • Skips a bare-path GGUF (model_path only, no model_url) — the file is assumed on disk.
  • Memoized per model id, so a per-section sweep pays the download once.
  • Takes the running task's real IExecuteContext: the download run-fn's phase events are forwarded to context.updateProgress (via DirectExecutionStrategy's job.onJobProgress bridge), which the @workglow/cli progress UI (withCli) renders — so a multi-GB GGUF/ONNX fetch shows a live percentage. context.signal also aborts it on Ctrl-C.

Downloadable GGUF ids. A gguf: id may now be a remote URI — a node-llama-cpp HuggingFace URI (gguf:hf:org/repo:Q4_K_M) or an https:// URL — which secModelRecord turns into a model_url (download source) plus a local model_path / models_dir under the GGUF models dir. A plain gguf: path stays a load-directly local file, unchanged.

Download prefetch wiring (prefetchModel). A context threaded through the eval loops and the shared storageArgs in ProcessAccessionDocFormTask reaches the AI processors (processFormS1, processForm424, processMergerProxy, processRedemption8K, processLoi8K), each prefetching once after resolving its model — so sec eval and sec fetch form show download progress, and download time isn't charged to a model's measured latency.

Per-section generation progress. The same context is threaded on down to runStructured so each section's AI generation reports progress on the task row instead of running silently. The context alone isn't enough — StructuredGenerationTask.execute() keeps only the finish event and drops the phase events — so runStructured now drives the task's executeStream itself (identical result: same retry/validation loop, same finish) and forwards the Preparing/Generating phases to context.updateProgress. context is optional throughout: eval sweeps and unit tests use the two-arg (no-context) signature and fall back to a self-contained stub, so their behavior is unchanged and all side-effects are preserved.

Testing

  • New unit tests (src/config/ensureModelDownloaded.test.ts): cloud no-op, bare-path GGUF skip, ONNX/remote-GGUF attempt, memoization, and a progress-forwarding test asserting a fake model.download run-fn's phase progress reaches context.updateProgress.
  • GGUF id-parsing tests in registerModels.test.ts (local path vs hf: URI vs https:// URL).
  • A per-section progress regression test (sectionExtractors.test.ts) asserting a threaded context receives Preparing/Generating during extraction (guards against execute() silently dropping phases again).
  • npx tsc --noEmit clean against workglow@0.3.26; config / eval / form-pipeline suites pass (the ~20 tests pinning processFormS1/ProcessAccessionDocFormTask side-effects stay green).

Scope note

Progress is surfaced by threading the real context (the download shows a live %; each section's row shows Preparing/Generating). This deliberately stops short of a full graph-ification into one distinct CLI row per section — investigation showed nested sub-graphs render nothing and distinct rows would require restructuring the monolithic ProcessAccessionDocFormTask (a much larger change against the ~20-test-pinned pipeline). That remains a possible follow-up.

🤖 Generated with Claude Code

https://claude.ai/code/session_011HoQKRtpU7mGpK8Dah9ySm

claude added 3 commits July 16, 2026 03:19
Local model weights must be present on disk before generation, but the
providers differ on when that happens: cloud models have nothing to
download, HuggingFace ONNX auto-fetches on first generation, and
node-llama-cpp (GGUF) loads its model_path directly and never fetches at
generation. Add ensureModelDownloaded as the single seam that normalizes
this — it runs ModelDownloadTask for the local providers (no-op for cloud,
memoized per model id) and skips a bare-path GGUF whose file is assumed on
disk.

Wire it into runStructured (the chokepoint every extractor funnels
through) so normal runs fetch weights before use, and prefetch in the eval
loops before their timed sections so download time isn't charged to a
model's measured latency.

Make GGUF ids fetchable rather than pre-staged: a gguf: id may now be a
remote URI (gguf:hf:org/repo:quant or an https URL), which secModelRecord
turns into a model_url download source plus a local model_path/models_dir
under the GGUF models dir. Plain gguf: paths stay load-directly local
files, unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HoQKRtpU7mGpK8Dah9ySm
The download seam used a throwaway execute context, which silently
discarded the download run-fn's progress events — a multi-GB GGUF/ONNX
fetch looked like a hang. Thread the running task's real IExecuteContext
into ensureModelDownloaded and on to ModelDownloadTask.execute: the
download's phase events are forwarded to context.updateProgress, which the
@workglow/cli progress UI (withCli) already renders, and context.signal
now aborts a long download on Ctrl-C.

Add prefetchModel, the best-effort wrapper the CLI-task boundaries call to
fetch weights (with visible progress) before the work begins:
- eval sweeps pass their task context so `sec eval` shows download progress;
- the AI form processors (S-1, 424, merger-proxy, redemption, LOI) prefetch
  once after resolving their model, via a context threaded through the
  shared storageArgs in ProcessAccessionDocFormTask.

runStructured keeps a context-less ensureModelDownloaded call as a
per-section correctness safety-net (it downloads silently only if a model
was never prefetched, e.g. a sub-extractor's distinct model); the
progress-bearing fetch lives at the task boundary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HoQKRtpU7mGpK8Dah9ySm
Thread the running task's IExecuteContext down the extraction stack
(processFormS1 / runOfferingSections / the 424, merger-proxy, redemption
and LOI processors → extract* → runGuardedExtraction → runStructured), so
each section's AI generation reports progress on the CLI task row instead
of running silently.

The context alone is not enough: StructuredGenerationTask.execute() keeps
only the finish event and drops the phase events, so a threaded context
would still see nothing. runStructured now drives the task's executeStream
itself — identical result (same retry/validation loop, same finish) — and
forwards the Preparing/Generating phases to context.updateProgress. Each
section's row now shows the model actively working; the download progress
already added shows alongside it.

context is optional throughout: the eval sweeps and unit tests call the
extract* functions with the two-arg (no-context) signature and fall back
to the self-contained stub, so behavior there is unchanged. All side
effects are preserved, so the form-pipeline tests that pin
processFormS1/ProcessAccessionDocFormTask stay green. Adds a regression
test asserting a threaded context receives the phase progress.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HoQKRtpU7mGpK8Dah9ySm

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

This PR introduces a unified “download before use” seam for local AI model providers and threads the running task IExecuteContext through form/eval pipelines so that both model download progress and per-section generation phases render on the CLI task row.

Changes:

  • Added ensureModelDownloaded / prefetchModel to normalize local-provider weight downloads (no-op for cloud providers) and forward download progress via IExecuteContext.
  • Extended gguf: model id parsing to support remote URIs (HF hf: and https://) by producing model_url + local cache model_path.
  • Threaded context through eval and form extraction code paths and updated structured generation to forward Preparing/Generating phase progress.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/task/forms/ProcessAccessionDocFormTask.ts Threads the running task context into form storage args so downstream AI processors can surface download/progress.
src/task/eval/EvalUnitTermsTask.ts Passes context into eval runner to enable progress rendering and prefetch behavior.
src/task/eval/EvalS1Task.ts Passes context into eval runner to enable progress rendering and prefetch behavior.
src/task/eval/EvalExtractTask.ts Passes context into eval runner to enable progress rendering and prefetch behavior.
src/sec/forms/registration-statements/s1/sectionExtractors.ts Ensures models are downloaded before structured generation and forwards generation phase progress via executeStream.
src/sec/forms/registration-statements/s1/sectionExtractors.test.ts Adds regression test asserting threaded context receives Preparing/Generating phase updates.
src/sec/forms/registration-statements/s1/offeringSections.ts Threads optional context to per-section extraction calls for CLI progress.
src/sec/forms/registration-statements/Form_S_1.storage.ts Adds best-effort prefetchModel and threads context through extractor calls.
src/sec/forms/registration-statements/Form_424.storage.ts Adds best-effort prefetchModel and threads context through offering section runner.
src/sec/forms/proxies-information-statements/Form_DEFM14A.storage.ts Adds best-effort prefetchModel and threads context into extraction.
src/sec/forms/miscellaneous-filings/redemption8k.ts Adds best-effort prefetchModel and threads context into extraction.
src/sec/forms/miscellaneous-filings/loi8k.ts Adds best-effort prefetchModel and threads context into extraction.
src/sec/forms/miscellaneous-filings/Form_8_K.storage.ts Threads context into 8-K sub-processors.
src/eval/runUnitTermsEval.ts Adds context option and prefetches model weights before timed evaluation runs.
src/eval/runOracleEval.ts Adds context option and prefetches participating models up front when context is present.
src/eval/runExtractionEval.ts Adds context option and prefetches model weights before timed fixture loops.
src/config/registerModels.ts Allows gguf: ids to be remote URIs by generating model_url + cache path config.
src/config/registerModels.test.ts Adds tests for GGUF id parsing (local path vs HF URI vs HTTPS URL).
src/config/ensureModelDownloaded.ts Introduces centralized model download seam plus best-effort prefetch wrapper.
src/config/ensureModelDownloaded.test.ts Adds unit coverage for no-op cloud behavior, GGUF skip, download attempts, memoization, and progress forwarding.
CLAUDE.md Documents the new download-before-use harness and updated GGUF usage guidance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/config/ensureModelDownloaded.ts Outdated
Comment on lines +63 to +65
const modelId = (model as { model_id?: string }).model_id ?? "";
if (modelId && ensured.has(modelId)) return;

Comment thread src/config/registerModels.ts
Comment on lines +316 to +329
function ggufCacheFileName(uri: string): string {
let rest = uri.replace(/^https?:\/\//i, "").replace(/^hf:/i, "");
// A trailing `:quant` (HF quant selector) is a filename hint, not a path segment.
let quant: string | undefined;
const quantMatch = rest.match(/:([^/:]+)$/);
if (quantMatch) {
quant = quantMatch[1];
rest = rest.slice(0, rest.length - quant.length - 1);
}
const last = rest.split(/[/?#]/).filter(Boolean).pop() ?? "model";
const base = last.toLowerCase().endsWith(".gguf") ? last.slice(0, -".gguf".length) : last;
const name = [base, quant].filter(Boolean).join("-") || "model";
return `${name}.gguf`;
}
Comment on lines 391 to 395
} else if (event.type === "finish") {
result = (event as { data?: { object?: unknown } }).data;
}
}
return (result?.object as Record<string, unknown> | undefined) ?? {};
Use the task run() lifecycle instead of hand-driving execute()/executeStream
for the three model tasks:
- runStructured runs StructuredGenerationTask.run() and forwards its
  Preparing/Generating phases to the caller's context.updateProgress via
  the runConfig.updateProgress hook (caching disabled to match execute()'s
  never-cache semantics). run() also fails loudly — a generation that can't
  finish throws rather than returning {}, so the prior executeStream
  finish-guard concern no longer applies.
- ensureModelDownloaded runs ModelDownloadTask.run(); unloadLocalModel runs
  ModelDownloadRemoveTask.run() (dropping its throwaway stub context).

Address the PR review:
- Memoize ensureModelDownloaded on a robust key (model_id ?? model ??
  provider_config.model_url ?? model_path), mirroring resolveModelId, so a
  record without model_id still downloads once instead of every call.
- isRemoteGgufUri matches hf: case-insensitively.
- ggufCacheFileName folds the whole source path into the cache filename so
  distinct remote GGUF sources (same repo name / different org, or two
  repos each holding model.gguf) don't collide on disk.

Adds tests for the model-identified-by-`model` memo path, uppercase HF:,
and same-repo-name/different-org cache-target uniqueness.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HoQKRtpU7mGpK8Dah9ySm
@sroussey
sroussey merged commit f79ed3b into harness Jul 16, 2026
1 check passed
@sroussey
sroussey deleted the claude/sec-model-download-harness-8ibeca branch July 16, 2026 16:47
sroussey added a commit that referenced this pull request Jul 17, 2026
### Features

- expose library surface for superset CLIs (#203)
- add accredited-investor portal attribution for Form D filings (#197)
- add SPAC consolidated report with lifecycle tracking (#164)
- add Form 8-K parsing and event storage infrastructure (#68)
- add CFPORTAL form parsing and Reg A query support (#133)
- track company facts fetch/store outcomes with retry support (#132)
- add offering terms, underwriters, and use-of-proceeds extraction (#128)
- extend ReadOnlyTabularStorage with new getOffsetPage method and update getBulk signature
- enhance ReadOnlyTabularStorage with pagination and query capabilities
- enhance bootstrap tasks and error handling

#### cli

- run query and db commands as task graphs via the workflow renderer
- honor --json flag in status and error output (#193)
- sponsor-family alias management + alias-aware 'spac by-family' query
- extend sec version coverage to resolver kind
- add sec canonical {person|company} alias commands
- add sec resolve --kind --version --all

#### models

- download model weights before use, with on-screen progress (#198)

#### eval

- default the S-1 oracle reference to opus
- golden-truth oracle + reconcile table/bio roles
- score field-values by F1 so over-production is penalized
- surface per-row/field disagreements after a run
- add OpenAI, Gemini, and xAI providers to the model harness
- oracle comparison over real S-1 sections
- model comparison harness + local model wiring

#### spac

- AI SPAC classifier, sponsor promote, de-SPAC linkage (#149, #150, #151)
- investorpres slot, portal featured, family descriptions
- target_description from merger proxies onto the deal + row
- SPAC business profile + leadership bio/birth_year extraction

#### xbrl

- ISO date transforms + CIK/dimension query coverage (#154) (#195)

#### s1

- skip nonce echo for local providers
- treat a board chair as implying director (drop redundant "Director")
- model person titles as a list of distinct roles (titles[])
- canonicalize management titles post-model
- extract SPAC sponsors into legal-sponsor + family tiers with links
- add extractSpacSponsors structured extractor
- write deterministic SPAC classification from header SIC
- add shared SGML-header + primary-document submission parser
- add real S-1 fixture sampler and document the extraction flow
- add dead-letter retry sweep, extractor CLI, and promote eligibility announce
- add S-1 prospectus extraction pipeline and dispatch
- add observation-provenance, beneficial-ownership, related-party, and dead-letter storage tiers

#### config

- node-llama-cpp GGUF local provider + workglow mega imports
- register SEC AI models in the global model repository

#### extractors

- register AI providers + retry model-error dead-letters without a version bump

#### sec

- SPAC de-SPAC lifecycle — 8-K milestones, merger-proxy & redemption extraction (#166)

#### forms

- route F-1 / F-1/A / F-1MEF (foreign issuer) through the S-1 extractor
- dispatch DRS/DRS/A to S-1 extractor; fetch registration forms as .txt
- split fetch/parse failure domains in ProcessAccessionDocFormTask
- ingest Section 16 (3/4/5) and Form 144 ownership filings (#116)

#### canonical

- add SponsorFamilyMembership + SpacSponsorLink tables with DI
- add CanonicalSponsorFamily + alias tables with DI
- emit current_canonical_* view DDL
- add alias repos with single-hop invariant
- add four canonical-level address/phone junction repos
- add CompanyIdentityLinkRepo
- add PersonIdentityLinkRepo
- add CanonicalCompanyRepo
- add CanonicalPersonRepo
- add alias schemas
- add canonical-level address/phone junction schemas
- add identity-link schemas
- add CanonicalCompanySchema
- add CanonicalPersonSchema

#### resolver

- add SponsorFamilyResolver + register sponsor-family resolver kind
- add EntityObserver helper for form storage modules
- add CompanyResolver v1 with CIK/CRD/name rules + alias pass
- add PersonResolver v1 with CIK/name rules + alias pass
- add resolverIds module

#### storage

- add S1ClassificationRepo (filing-level SPAC record) + DI

#### html

- add form-agnostic EDGAR HTML to Document-tree converter

#### versioning

- add dropPrevious tests for extractor and resolver kinds
- extend drop-previous to resolver rows + orphan cleanup
- add ceremony CLI (start-dev, promote, rollback, drop-next, coverage, history); remove seed-test
- add VersionCoverage and VersionHistory queries
- add ceremonies module (startDev / promote / rollback / dropNext)
- add getActiveSlot helper (next-if-exists routing)
- add VersionEventRepo for ceremony audit log
- add VersionEvent schema and DI wiring
- add semver helpers (parse, major.minor, bump-progression validation)
- add target_count column to component_versions
- add ExtractorRunRepo helper
- bootstrap extractor versions on db setup
- add idempotent bootstrapExtractorVersions seeder
- add FORM_TO_EXTRACTOR_ID mapping and ExtractorId type
- add 'sec version status' and 'sec version seed-test' CLI
- add VersionStatus query for CLI rendering
- add VersionRegistry helper with slot accessors
- register ComponentVersion and ExtractorRun repos in DI
- add ExtractorRun schema and DI token
- add ComponentVersion schema and DI token

#### observation

- add CompanyObservationRepo
- add PersonObservationRepo with natural-key upsert
- add CompanyObservationSchema
- add PersonObservationSchema

### Bug Fixes

- address xhigh code-review findings
- update warning messages and improve test descriptions
- DRSLTR dispatch, SPAC sponsor span verification, resolver test + RFC-9112 Content-Length (#127)
- address code review issues — dropPrevious orphan check, DbStatus new tables, drop-previous CLI verb, resolve test coverage, CompanyResolver secondary keys
- init

#### sec

- CLI validation, portal-attribute reporting, gguf path check (#201)
- make local GGUF models usable in eval and exit cleanly
- isolate redemption model-resolution + bulk-skip backfill candidates
- record extractor_runs for redemption + idempotent, fast backfill

#### query

- reject empty CIK filters

#### cli

- report expected user-errors through task output ports; dedupe tier wiring
- preserve JSON workflow error handling
- make streamed query totalApprox a meaningful lower bound (#112)

#### editorial

- isolate multi-file import failures

#### s1

- one owner per name; quote key lists in eval diffs
- drop ownership subtotal rows; add beneficial-ownership golden truth
- close the GBNF []-shortcut on nested titles[] too
- harden sponsor extraction + sponsor-family storage from code review

#### eval

- fail loudly when an extractor has no fixtures
- normalize commas and initial/suffix periods in name alignment
- restore stderr progress for eval tasks when piped

#### spac

- make de-SPAC linkage a write-once close-time snapshot
- stop deriving phantom deals after a completed combination
- gate SQLite withSpacCikLock through process-wide mutex (avoid concurrent BEGIN IMMEDIATE crash)
- allow caller-supplied pool client to recomputeSpacDeals to avoid deadlock with outer lock
- atomic per-CIK rollup writes + monotonic history chain
- record extractor_runs for merger-proxy + transactional recompute

#### storage

- implement no-op updateWhere on ReadOnlyTabularStorage

#### resolver

- stabilize person name parts across punctuation/glyph variants
- instance-scope per-key mutex so multi-process race tests test what they claim (#160)
- FamilyResolver — alias inside mutex + UPPER case-normalization (#129)
- add readonly to PersonClaim/CompanyClaim; single timestamp per method

#### s1,eval

- director nominees + typographic name alignment

#### eval,s1

- render titles arrays clearly in diffs; sharpen split prompt

#### sec/424

- record deterministic SPAC IPO event even when AI model fails to resolve

#### facts

- derive fy sentinel from end_date to preserve PK width across period-agnostic facts
- accept EDGAR facts with null fy/fp

#### sec/extractors

- move verify nonce out of untrusted fence into trusted preamble
- add NONCE_MISMATCH dead-letter reason code
- gate reapStaleObservations on version change to prevent LLM-variance data loss on same-version re-runs

#### sec/html

- strip title/svg/math to close prompt-injection bypass in body-level and foreign-content elements

#### config

- declare Anthropic model capabilities so StructuredGenerationTask resolves
- init SQLite binding in setupAllDatabases before view DDL

#### extractors

- degrade gracefully when the AI model is unregistered

#### submissions

- store every filing row (proxy slice yielded undefined)

#### review

- clarify details doc + single-pass investorpres derivation
- address code-review findings + prettier
- close wave-2 (#177/#178/#179) review findings
- close 6 findings from max-effort review of the consolidation

#### canonical

- serialize junction observation_count with KeyedMutex
- align junction columns with address/phone schemas

#### util

- parseDate rejects calendar-invalid dates

#### xbrl

- XbrlFactRepo.replaceForAccession no-ops on 0 rows unless intentionalClear

#### forms

- close stripDoctype bypass via leading XML comment / PI
- restore predefined-entity decoding via bounded processEntities + DOCTYPE strip
- apply prompt-injection seal to merger-proxy + redemption extractors
- treat empty fetch body as no-text and swallow dead-letter write failures
- explicit null address_id/international_number in Form_1_Z signature observation
- remove dead resolveCountryCode from Form_1_K.storage

#### forms/s1

- close residual Unicode-invisible defang bypass
- widen defang TAG_SHAPED to admit whitespace mid-tag (closes &#10; bypass)
- wire new extractMergerDeal / extractRedemption to nonce-fence API
- per-call nonce fence + raw-span cap + multi-stage defang

#### forms/8-K

- auto-resolve redemption-partial-oversized dead-letter (informational only)
- cap redemption AI input bytes; drop oversized exhibits
- persist redemption extraction even when SPAC has no deal yet
- trust the actual repo nature, not the lingering SEC_DB_TYPE token
- tx writes, versioned PK, accession unification, XML entity hardening

#### versioning

- partial-success outcome on extractor_runs
- bump test timeout on multi-spawn CLI tests to 15s
- address PR #109 review feedback
- address final review items
- reject all start-dev variants when next slot exists; drop dead check; comment promote atomicity
- patch-gate listFilingsWithoutSuccessfulRun on major.minor prefix
- address independent code review
- address PR #107 review feedback
- use cik: number in ExtractorRunRepo query API (matches codebase convention)
- address PR #106 review feedback
- enforce semver and coverage_complete invariants in putSlot
- drop redundant PK-prefix indexes; wire resetAllDatabases; sort imports

#### resolver,forms/s1

- PG unique-violation recognition + family-tier UNIQUE convergence + S-1/424 prompt-injection hardening (3× HIGH) (#163)

#### forms,storage

- Form 144/Ownership whitespace→null, PG dedup, Form_C/1-A stale-replay guards (#159)
- 5 HIGH review findings — stale replay, point-in-time, undated guard, deal sort, Schedule A (#155)
- Crowdfunding history on stale replay + CFPORTAL/A inheritance + docs (#135)
- address Copilot review on PR #124

#### storage/canonical

- enforce UNIQUE constraints to close resolver race (#158)

#### forms,portal

- undated 1-K/1-Z guard + deterministic stale-replay tie-break (2 HIGH from code review) (#156)

#### forms,storage,cli

- person-collision issuer guard + alias chain block + CLI input validation + coverage perf (#122)

#### resolver,storage,cli

- resolver race + observation_id PK + CSV NBSP + download leak (sec) (#121)

#### section16

- preserve null vs 0 for empty numeric leaves on Forms 3/4/5 (#116 follow-up) (#117)

#### observation

- align raw_phone_id maxLength with PhoneSchema

#### ci

- set 30s global test timeout for multi-spawn CLI tests

### Refactors

- remove unused fn

#### task

- move src/fetch to src/task/fetch
- relocate EnsureModelDownloadedTask to src/task/model and name the file after the task

#### config

- make ensureModelDownloaded a task that infers provider from the model id
- import node-llama-cpp via the workglow mega package
- drop the spac narrative-column migration

#### eval

- inline oracle sweep into EvalS1Task; own AI subtasks
- rename `sec eval s1 --candidates` to `--models`

#### cli

- graph-ify every command through the workflow renderer

#### normalize

- shared typographic-punctuation fold for names

#### portal

- drop the featured column

#### canonical

- extract shared CanonicalJunctionRepo base

#### resolver

- extract shared normalizeSponsorFamilyName for consistent family keys

#### queue

- integrate wrapQueueStorage for SecJobQueue components

#### storage

- delete legacy PersonRepo, CompanyRepo, and their schemas

#### forms

- rewrite Form_1_Z.storage onto EntityObserver
- rewrite Form_1_K.storage onto EntityObserver
- rewrite Form_1_A.storage onto EntityObserver
- rewrite Form_C.storage onto EntityObserver
- rewrite Form_D.storage onto EntityObserver
- rewrite Form_D.storage onto EntityObserver

#### versioning

- route form-processing tasks via getActiveSlot (next-if-exists)
- UpdateAllFormsTask reads extractor_runs, drops --force
- write extractor_runs from ProcessAccessionDocFormTask
- derive TypeBox literal unions from const arrays

### Tests

- use vitest so we can try node when needed
- add unit tests for SecFetchJob functionality

#### 424

- isolate the priced-prospectus fixture from S-1 discovery globs
- pin priced-prospectus pipeline with a real 424B4 golden fixture

#### versioning

- update registered-component assertions for sponsor-family resolver kind

#### s1

- add synthetic DRS .txt fixture exercising header parse + DRS dispatch
- end-to-end SPAC classification + sponsor family linkage + DRS dispatch

#### forms

- assert FETCH_ERROR status pending; clarify Domain 3 throw comment
- cover fetch-layer dead-letter paths (PRIMARY_DOC_UNRESOLVED, FETCH_ERROR, parse rethrow)

#### fixtures

- add fetch-fixtures script for pulling real EDGAR data (#108)

### Documentation

- update CLAUDE.md and new-module JSDoc for PR4
- update paths for design specs and plans in various skills and documentation

#### eval

- drop LFM2.5 references; default the sweeps to cloud models
- document evaluating Bonsai 27B via the local GGUF path (#187)

#### 8-K

- note metadata items/report_date are authoritative

#### s1

- document sponsor-text extraction strategy in processFormS1

### Chores

- rename bunsrc scripts for clarity
- bump workglow/cli 0.3.26, compromise 14.16.0, fast-xml-parser 5.10.0
- keep typebox 1.3.6 from main after rebase
- update deps
- keep extractor versions at 1.0.0 (no data to re-extract)
- update deps
- update deps
- ignore .worktrees directory
- update deps
- update deps
- update dependencies and ESLint configuration
- update dependencies and enhance CIK query functionality

#### config

- drop local HuggingFace/ONNX provider wiring
- register observation/canonical repos in DI; add view DDL

#### extractors

- default AI model to claude-sonnet-5 via shared SecModelDefault

#### deps

- update @workglow/cli and related packages to version 0.3.13; add new domNodes.ts file for cheerio DOM node types

#### versioning

- rename bootstrapExtractorVersions; seed resolver components
- register resolver:person and resolver:company
- retire processed_filings; DbStatus reports extractor_runs

### CI

- limit rebuilds

### Updated Dependencies

- `@modelcontextprotocol/sdk`: ^1.29.0
- `@workglow/cli`: 0.3.26
- `commander`: ^15.0.0
- `compromise`: ^14.16.0
- `fast-xml-parser`: ^5.10.0
- `pdf2json`: ^4.0.3
- `pg`: ^8.22.0
- `typebox`: 1.3.6
- `workglow`: 0.3.26
- `@types/bun`: 1.3.14
- `bunset`: 1.0.13
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