fix(scoring): definitive grantmaker exclusion + full-pool matching

Candidate orgs now also exclude any org whose EIN appears in the funders
table — an org that files a 990-PF IS a private foundation regardless of
its NTEE code (Bean/McIninch-style grantmakers carry E/S codes or none).
1,692 stale pending matches for PF-filer orgs cleaned. Candidate limit
raised to 2,000 after the enrichment drain grew the pool 56 -> 887.

Full-pool run: 856 candidates, 42,800 matches, 850 easy wins across 373
orgs, top heroes led by community-precedent pairs (Seacoast Pathways ->
Foundation for Seacoast Health; Granite Backcountry Alliance ->
Gibson-Woodbury). Known residual: hospital-legacy 'health foundation'
grantmakers file 990 (not 990-PF), so the PF roster can't catch them —
they reach the queue and rely on the human reject gate; profiler-based
classification is the durable fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Croissant Le Doux
2026-07-16 21:16:22 -04:00
parent 63b58e514d
commit 8f9c19a32c
2 changed files with 7 additions and 1 deletions

View File

@@ -46,6 +46,12 @@ export async function serverListMatchCandidateOrgs(
isNull(schema.orgs.nteeCode),
sql`${schema.orgs.nteeCode} NOT LIKE 'T%'`,
),
// Definitive grantmaker check: an org that files a 990-PF IS a
// private foundation, whatever its NTEE code says (many carry
// E/S codes or none). The funders table is exactly that roster.
sql`NOT EXISTS (
SELECT 1 FROM funders f WHERE f.ein = ${schema.orgs.ein}
)`,
),
)
.limit(limit);