Full stage: extract the entities a chunk is about and PERSIST them.
Each extracted surface is RESOLVED to a canonical entity through the variant
resolver (squeeze/alias/token-subset; see resolve.ts) so casing/spacing/brand
variants collapse onto ONE entity instead of minting a fresh row each — the
dedup fix. The resolver is seeded from the store's existing entities/aliases
AND the curated gold (so notable brand-only nicknames fold), and accumulates
minted canonicals across chunks when the caller threads one in via opts.
Upserts the resolved canonical entities row (article_stem NULL — no article
exists yet; ROUTE/CREATE promote it later) so the chunk_entities FK is
satisfied, records the raw surface as an alias of the canonical, and writes one
chunk_entities row per distinct resolved entity. Idempotent: re-running on the
same chunk INSERT-OR-IGNOREs the same rows.
Returns the extracted list (also useful to callers that route immediately).
Full stage: extract the entities a chunk is about and PERSIST them.
Each extracted surface is RESOLVED to a canonical entity through the variant resolver (squeeze/alias/token-subset; see resolve.ts) so casing/spacing/brand variants collapse onto ONE entity instead of minting a fresh row each — the dedup fix. The resolver is seeded from the store's existing entities/aliases AND the curated gold (so notable brand-only nicknames fold), and accumulates minted canonicals across chunks when the caller threads one in via
opts.Upserts the resolved canonical
entitiesrow (article_stem NULL — no article exists yet; ROUTE/CREATE promote it later) so the chunk_entities FK is satisfied, records the raw surface as an alias of the canonical, and writes one chunk_entities row per distinct resolved entity. Idempotent: re-running on the same chunk INSERT-OR-IGNOREs the same rows.Returns the extracted list (also useful to callers that route immediately).