fix(extraction): סינון cited_only מתור/מוני החילוץ (#140)
31 שורות case_law עם source_kind='cited_only' (ציטוט-בלבד, ללא full_text/chunks) נושאות halacha_extraction_status='pending' רק כברירת-מחדל ומזהמות את מונה ה-pending ובמתזמר/בדף-התפעול — אין להן מה לחלץ. תיקון (G1 — תיקון-במקור, G2 — מסנן יחיד משותף): - db.EXTRACTION_ELIGIBLE_PREDICATE — מקור-אמת יחיד ל"שורה ברת-חילוץ" (source_kind <> 'cited_only' AND יש precedent_chunks). מוחל ב-list_pending_extraction_requests; #139 יעשה בו שימוש-חוזר ל-reconcile (אותו כלל, לא כפול). - מוני-snapshot מסננים cited_only: halacha_drain_supervisor.db_snapshot, web/app.py meta+hal_ext (GROUP BY status). - reconcile_metadata_status.py מורחב לכסות גם את תור-ההלכות: cited_only→'skipped' (אותו terminal-state כמו צד-המטא, תור-תאום, G2). בוצע על ה-DB החי: 31 הועברו ל-'skipped' (metadata כבר היה מיושב — אידמפוטנטי). התפלגות-אחרי: halacha pending=9 (עבודה אמיתית), skipped=31, completed=309. בדיקות: test_extraction_queue_eligibility (predicate + list_pending מחיל אותו, שני ה-kinds). כל 345 בדיקות mcp עוברות. guards נקיים. Invariants: G1 (terminal-state אמיתי במקור), G2 (predicate יחיד, ללא תור מקביל), INV-DM1 (stub לא-searchable אינו מועמד-חילוץ), G12 (leak-guard נקי). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6746,6 +6746,19 @@ async def request_halacha_extraction(case_law_id: UUID) -> bool:
|
||||
return result == "UPDATE 1"
|
||||
|
||||
|
||||
# Single source of truth for "this row can actually be extracted" (#140, G2):
|
||||
# a real precedent whose text was chunked into precedent_chunks. ``cited_only``
|
||||
# stubs are citation-only (no full_text, no chunks) and can NEVER yield an
|
||||
# extraction, so they must never enter the work queue or get proactively
|
||||
# re-queued. Shared by the queue reader (list_pending_extraction_requests) and
|
||||
# the orphan-reconcile job (#139) so the eligibility rule lives in ONE place.
|
||||
# Assumes the surrounding query exposes the table as ``case_law``.
|
||||
EXTRACTION_ELIGIBLE_PREDICATE = (
|
||||
"case_law.source_kind <> 'cited_only' "
|
||||
"AND EXISTS (SELECT 1 FROM precedent_chunks pc WHERE pc.case_law_id = case_law.id)"
|
||||
)
|
||||
|
||||
|
||||
async def list_pending_extraction_requests(
|
||||
kind: str = "metadata", # 'metadata' | 'halacha'
|
||||
limit: int = 20,
|
||||
@@ -6764,11 +6777,14 @@ async def list_pending_extraction_requests(
|
||||
# internal_committee rows could be stamped (we opened that gate in
|
||||
# request_metadata_extraction / request_halacha_extraction) but stayed
|
||||
# invisible to the worker forever.
|
||||
# Exclude ineligible rows (cited_only / chunkless) so a stub can never sit in
|
||||
# the work queue — same predicate the reconcile job uses (#140, G2).
|
||||
rows = await pool.fetch(
|
||||
f"""SELECT id, case_number, case_name, court, date,
|
||||
practice_area, is_binding, {col} AS requested_at
|
||||
FROM case_law
|
||||
WHERE {col} IS NOT NULL
|
||||
AND {EXTRACTION_ELIGIBLE_PREDICATE}
|
||||
ORDER BY {col} ASC
|
||||
LIMIT $1""",
|
||||
limit,
|
||||
|
||||
Reference in New Issue
Block a user