diff --git a/.taskmaster/tasks/tasks.json b/.taskmaster/tasks/tasks.json index 9ca6e1b..bd9d6c8 100644 --- a/.taskmaster/tasks/tasks.json +++ b/.taskmaster/tasks/tasks.json @@ -1371,6 +1371,497 @@ "priority": "medium", "subtasks": [], "updatedAt": "2026-05-04T17:29:25.686Z" + }, + { + "id": "30", + "title": "תיקון 3 baגים בקטלוג (practice_area + source_kind + upload route)", + "description": "CRITICAL: 3 sub-bugs. (א) יצירת תיקים מתייגת practice_area='appeals_committee' במקום rishuy_uvniya/betterment_levy/compensation_197 לפי קידומת מספר התיק (1xxx/8xxx/9xxx) — audit + migration לכל התיקים הקיימים + תיקון נתיב היצירה. (ב) כל החלטה של ועדת ערר שהועלתה ל-case_law מסומנת כ-source_kind='external_upload' במקום 'internal_committee' — audit ל-case_law עם case_number שמתחיל ב'ערר' → reclassify + מילוי chair_name + district רטרואקטיבית. (ג) POST /api/precedent-library/upload לא מבחין — תיקון: ניתוב לפי תחילית הציטוט (ערר/ועדות ערר → internal_committee, אחרת → external_upload).", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #1. Pre-requirement: השתמש במחיקה+rerun של halachot אחרי שינוי source_kind. השתמש בpattern של internal_decisions.py (dry_run+log_action).", + "testStrategy": "", + "status": "done", + "dependencies": [], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "Audit + migration practice_area (1xxx→rishuy_uvniya, 8xxx→betterment_levy, 9xxx→compensation_197)", + "status": "done" + }, + { + "id": 2, + "title": "Audit + reclassify case_law source_kind external_upload → internal_committee עבור 'ערר' prefix", + "status": "done" + }, + { + "id": 3, + "title": "Delete + re-extract halachot עבור רשומות שעברו reclassification", + "status": "done" + }, + { + "id": 4, + "title": "תיקון נתיב יצירת תיק לתיוג practice_area נכון מההתחלה", + "status": "done" + }, + { + "id": 5, + "title": "תיקון /api/precedent-library/upload לניתוב לפי תחילית הציטוט", + "status": "done" + }, + { + "id": 6, + "title": "מבחני רגרסיה לכל 3 הbaגים", + "status": "done" + }, + { + "id": 7, + "title": "תיקון MCP `case_update` + API `PUT /api/cases/{case_number}` לתמוך בעדכון practice_area + appeal_subtype", + "status": "done", + "details": "התגלה ב-26/05/2026: MCP tool case_update והAPI לא מקבלים את השדה practice_area, ולכן אי-אפשר לתקן תיוג שגוי דרך הממשק. נאלצתי לעדכן ידנית ב-SQL. צריך להוסיף את השדות ל-CaseUpdateRequest ב-web/app.py וב-cases_tools.case_update בmcp-server." + }, + { + "id": 8, + "title": "[prevention] DB CHECK constraints: source_kind='internal_committee' ⇒ chair_name NOT NULL; cases.practice_area enum", + "status": "done", + "description": "מיגרציה: ALTER TABLE case_law ADD CONSTRAINT chair_required_for_internal CHECK (source_kind <> 'internal_committee' OR (chair_name IS NOT NULL AND chair_name <> '')); וכן CHECK על cases.practice_area לערכים תקינים. חייב לרוץ אחרי subtask #2 (backfill) אחרת constraint creation ייכשל." + }, + { + "id": 9, + "title": "[prevention] Unify practice_area taxonomy — מיפוי או מחיקה של appeals_committee מ-practice_area.py", + "status": "done", + "description": "ב-mcp-server/src/legal_mcp/services/practice_area.py:21 יש PRACTICE_AREAS={appeals_committee,national_insurance,labor_law} שסותר את ה-DB constraint של case_law (rishuy_uvniya/betterment_levy/compensation_197). grep מקיף לכל caller של 'appeals_committee'; להחליף במיפוי מפורש או למחוק." + } + ], + "updatedAt": "2026-05-26T08:35:22.762800Z" + }, + { + "id": "31", + "title": "מיצוי chair_name + district בהעלאת ועדת ערר", + "description": "תוספת לטופס + חילוץ אוטומטי מהציטוט/text הפסיקה. רטרואקטיבי לכל הרשומות הקיימות עם source_kind='internal_committee' שהשדות בהן ריקים.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #2. תלוי במשימה #30 (sub-bug ב).", + "testStrategy": "", + "status": "done", + "dependencies": [ + "30" + ], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "Backfill chair_name + district לכל 7 הרשומות החסרות (LLM extraction)", + "status": "done", + "description": "psql query: SELECT id, case_number FROM case_law WHERE source_kind='internal_committee' AND (chair_name IS NULL OR chair_name=''); לכל אחת — חילוץ ע\"י precedent_metadata_extractor.extract_and_apply." + }, + { + "id": 2, + "title": "[prevention] Validation: chair_name+district required ב-internal_decisions_upload (API+MCP)", + "status": "done", + "description": "ב-web/app.py:4607-4680 כיום chair_name/district = Form(\"\") (default ריק). שנה ל-required עם validation שדוחה ריק כשsource_kind='internal_committee'. הוסף enum של 6 ערכי district (ירושלים/מרכז/תל אביב/צפון/דרום/ארצי)." + }, + { + "id": 3, + "title": "[prevention] UI dropdown ל-district בטופס העלאת החלטות ועדה (web-ui)", + "status": "done", + "description": "במקום free-text — Select של 6 הערכים. גם בטופס חיפוש (search_internal_decisions)." + } + ], + "updatedAt": "2026-05-26T08:35:22.762800Z" + }, + { + "id": "32", + "title": "UI — דף עריכת פסיקה ייפתח רחב-במרכז (לא צר-בצד)", + "description": "חוסר נוחות בעריכה. שינוי ה-Dialog/Sheet ל-Modal רחב מרכזי. רלוונטי גם להוספת שדות chair_name + district מהמשימה #31.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #3.", + "testStrategy": "", + "status": "pending", + "dependencies": [], + "priority": "medium", + "subtasks": [], + "updatedAt": "2026-05-26T05:54:01.651259Z" + }, + { + "id": "33", + "title": "UI — הסתרת עמודת 'שם' (case_name) בדף רשימת פסיקה", + "description": "רוב הערכים זהים למספר התיק. להסתיר את העמודה ב-UI, לשמור עמודה ב-DB לשימוש עתידי.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #4.", + "testStrategy": "", + "status": "pending", + "dependencies": [], + "priority": "low", + "subtasks": [], + "updatedAt": "2026-05-26T05:54:01.651259Z" + }, + { + "id": "34", + "title": "חילוץ ציטוטי-פנים מהחלטות דפנה (internal_committee + ירושלים)", + "description": "פאטרן: 'ונפנה להחלטות של ועדת ערר זו...', 'כפי שקבעתי בערר X', 'בדומה לעמדתי בהחלטה Y'. חילוץ אוטומטי + שמירה ב-precedent_internal_citations table שיאפשר ל-search_internal_decisions להחזיר גם את הפסיקה המוזכרת.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #5. תלוי במשימה #30 (sub-bug ב) ובמשימה #31.", + "testStrategy": "", + "status": "pending", + "dependencies": [ + "30", + "31" + ], + "priority": "medium", + "subtasks": [], + "updatedAt": "2026-05-26T05:54:01.651259Z" + }, + { + "id": "35", + "title": "דף/דוח 'פסיקה חסרה בקורפוס' — פיצ'ר מלא", + "description": "טבלת DB missing_precedents (id, citation, case_name, cited_in_case_id, cited_in_document_id, cited_by_party, legal_topic, legal_issue, claim_quote, status, linked_case_law_id, closed_at, created_at), API endpoints (POST/GET/upload/PATCH), MCP tools (missing_precedent_create/list/close), דף Next.js /missing-precedents, הוק אוטומטי במחקר ע\"י legal-researcher.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #6.", + "testStrategy": "", + "status": "done", + "dependencies": [], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "Migration + model missing_precedents", + "status": "done" + }, + { + "id": 2, + "title": "API endpoints POST/GET/upload/PATCH /api/missing-precedents", + "status": "done" + }, + { + "id": 3, + "title": "MCP tools missing_precedent_create/list/close", + "status": "done" + }, + { + "id": 4, + "title": "Next.js page /missing-precedents עם list + detail + upload form", + "status": "done" + }, + { + "id": 5, + "title": "Auto-creation hook במחקר (legal-researcher יוצר רשומה כשמזהה ציטוט חסר)", + "status": "done" + }, + { + "id": 6, + "title": "Webhook עדכון לפלאגין Paperclip + Comment לחיים", + "status": "done" + } + ], + "updatedAt": "2026-05-26T08:35:22.762800Z" + }, + { + "id": "36", + "title": "כינוס פרופוזיציות לטיעונים משפטיים אמיתיים (de-dup/aggregation)", + "description": "extract_claims מחזיר ~60 פרופוזיציות לתיק, צריך לאגד ל-~10 טיעונים משפטיים אמיתיים. טבלה חדשה legal_arguments + טבלת קישור legal_argument_propositions (M:M ל-case_claims). LLM aggregation job (Hermes/DeepSeek). API + MCP + UI display שמציג 'X טיעונים משפטיים' במקום 'Y טענות'.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #7.", + "testStrategy": "", + "status": "done", + "dependencies": [], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "Migration + models legal_arguments + legal_argument_propositions", + "status": "done" + }, + { + "id": 2, + "title": "LLM aggregation job (Hermes/DeepSeek profile)", + "status": "done" + }, + { + "id": 3, + "title": "API + MCP tool aggregate_claims_to_arguments", + "status": "done" + }, + { + "id": 4, + "title": "UI display update — case detail page מציג טיעונים אמיתיים", + "status": "done" + }, + { + "id": 5, + "title": "Backfill לכל התיקים הקיימים", + "status": "done" + } + ], + "updatedAt": "2026-05-26T08:35:22.762800Z" + }, + { + "id": "37", + "title": "הפרדת תתי-סוגי בל\"מ לפי practice_area", + "description": "3 ערכי appeal_subtype חדשים: extension_request_building_permit (1xxx, ס'152 - 30 ימים), extension_request_betterment_levy (8xxx, ס'14 לתוספת ג' - 45 ימים), extension_request_compensation (9xxx, ס'198(ד) - 30 ימים). 3 templates מתודולוגיים נפרדים. אוטו-זיהוי מהsubject. UI badge + filter.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #8. Pre-requirement: עדכון mcp-server/src/legal_mcp/services/practice_area.py APPEALS_COMMITTEE_SUBTYPES + עדכון web/paperclip_client.py mapping appeal_subtype → company.", + "testStrategy": "", + "status": "done", + "dependencies": [], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "הוספת 3 ערכי enum ל-practice_area.py APPEALS_COMMITTEE_SUBTYPES", + "status": "done" + }, + { + "id": 2, + "title": "כתיבת 3 templates מתודולוגיים ב-docs/methodology/extension-request-{type}.md", + "status": "done" + }, + { + "id": 3, + "title": "אוטו-זיהוי בקוד יצירת תיק (subject='בקשה להארכת מועד' → קביעת subtype לפי practice_area)", + "status": "done" + }, + { + "id": 4, + "title": "UI badge + filter ייעודי לבל\"מ", + "status": "done" + }, + { + "id": 5, + "title": "עדכון web/paperclip_client.py mapping ל-company עבור 3 הערכים החדשים", + "status": "done" + } + ], + "updatedAt": "2026-05-26T08:35:22.762800Z" + }, + { + "id": "38", + "title": "שדרוג סוכני Paperclip להכרת השינויים מ-#30-#37", + "description": "עדכון 7 הגדרות סוכן (CEO/analyst/researcher/writer/QA/proofreader/exporter) + HEARTBEAT.md לזיהוי המבנים החדשים. בלי זה כל הפיצ'רים נשארים זמינים אבל הסוכנים לא יודעים להשתמש בהם. כולל הוספת research_complete כ-valid case_status.", + "details": "ראה תוכנית /home/chaim/.claude/plans/3-glimmering-oasis.md חלק א משימה #9. תלוי במשימות #30-#37.", + "testStrategy": "", + "status": "done", + "dependencies": [ + "30", + "31", + "34", + "35", + "36", + "37" + ], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "עדכון .claude/agents/legal-ceo.md — routing + statuses + wake reasons", + "status": "done" + }, + { + "id": 2, + "title": "עדכון .claude/agents/legal-analyst.md — practice_area, legal_arguments, בל\"מ detection", + "status": "done" + }, + { + "id": 3, + "title": "עדכון .claude/agents/legal-researcher.md — 2 layers, missing_precedents, citations, בל\"מ templates", + "status": "done" + }, + { + "id": 4, + "title": "עדכון .claude/agents/legal-writer.md — legal_arguments view, בל\"מ templates", + "status": "done" + }, + { + "id": 5, + "title": "עדכון .claude/agents/legal-qa.md — בל\"מ-aware validation", + "status": "done" + }, + { + "id": 6, + "title": "עדכון .claude/agents/HEARTBEAT.md — כללי routing משותפים + research_complete status", + "status": "done" + }, + { + "id": 7, + "title": "סנכרון לכל החברות CMPA mirror — sync_agents_across_companies.py", + "status": "done" + }, + { + "id": 8, + "title": "[alignment] researcher docs: דרישה מפורשת שכל 'ערר' → internal_decision_upload, לעולם לא precedent_library_upload", + "status": "done", + "description": "בלגל-researcher.md: דוגמת קוד מפורשת + flowchart החלטה: לפי תחילית הציטוט. הסבר על השלילה של precedent_library_upload כשמדובר ב-ערר. תלוי במשימה #39 (MCP tool חדש)." + }, + { + "id": 9, + "title": "[alignment] analyst docs: הסבר על 2 taxonomies של practice_area + מתי משתמשים בכל אחת", + "status": "done", + "description": "בלגל-analyst.md: טבלה ברורה — practice_area (case_law) vs practice_area (cases). מתי להעביר rishuy_uvniya ומתי appeals_committee. אחרי משימה #30.9 (taxonomy unification) — סביר שזה ייפשט." + }, + { + "id": 10, + "title": "[alignment] writer docs: הבחנה בין source_kind בציטוט (binding vs persuasive)", + "status": "done", + "description": "בלגל-writer.md: 'החלטת ועדת ערר אחרת ⇒ עקביות אופקית, לא הלכה מחייבת'. 'פס\"ד עליון/מנהלי ⇒ סמכותי בינדינג'. דוגמאות פרזיולוגיה מ-skills/decision/SKILL.md." + } + ], + "updatedAt": "2026-05-26T07:41:47.880478Z" + }, + { + "id": "39", + "title": "[ROOT CAUSE] MCP tool חדש: internal_decision_upload", + "description": "הוספת @mcp.tool() עם chair_name+district חובה ו-source_kind='internal_committee' אוטומטי. סוגר את ה-root cause של Bug (ב) ב-#30. בלעדיו 44 רשומות חדשות יחזרו כ-external_upload תוך חודש.", + "details": "מיקום: mcp-server/src/legal_mcp/tools/internal_decisions.py (אם לא קיים — ליצור). רישום ב-server.py סביב שורה 169 (ליד precedent_library_upload). הקריאה מנותבת ל-int_decisions_service.ingest_internal_decision (קיים ב-internal_decisions.py).", + "testStrategy": "1. שלח tool call ללא chair_name → JSON error. 2. שלח עם chair+district → רשומה נוצרת עם source_kind='internal_committee'. 3. precedent_chunks נוצרים עם source_kind ירש.", + "status": "done", + "dependencies": [ + "30" + ], + "priority": "high", + "subtasks": [], + "updatedAt": "2026-05-26T07:41:37.260868Z" + }, + { + "id": "40", + "title": "[שלב B - ROI מיידי] הפעלת VOYAGE_RERANK_ENABLED=true ב-Coolify", + "description": "Cross-encoder rerank-2 ממומש ב-mcp-server/src/legal_mcp/services/rerank.py אבל כבוי בייצור (default=false). POC הוכיח +4.5% mean@3 ו-+11.6% practical queries (latency +702ms acceptable לזרימה האסינכרונית). 5 דקות עבודה — env change ב-Coolify.", + "details": "mcp__coolify__env_vars set VOYAGE_RERANK_ENABLED=true. ראה web/mcp_env_catalog.py:71-72 לdescription. אופציה: rampup רק על search_precedent_library (לא על find_similar_cases — latency-sensitive).", + "testStrategy": "search_precedent_library('היקף הסמכות') לפני/אחרי — לראות שינוי ב-ordering. בדוק שלא יותר מ-1000ms latency.", + "status": "done", + "dependencies": [], + "priority": "high", + "subtasks": [], + "updatedAt": "2026-05-26T08:08:27.953285Z" + }, + { + "id": "41", + "title": "[שלב B] BM25/tsvector hybrid retrieval על precedent_chunks + halachot", + "description": "כיום כל החיפוש הוא 100% dense (cosine). ציטוטים מספריים ('עע\"מ 1461/20') נכשלים כי semantic לא מצליח בהם. הוספת tsvector GIN + RRF merge dense+lexical = +15-25% recall על ציטוטים — קריטי לאימות פסיקה ב-3-glimmering-oasis שלב 3.", + "details": "ALTER TABLE precedent_chunks ADD COLUMN content_tsv tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STORED; CREATE INDEX ... USING gin (content_tsv). באותו אופן על halachot.rule_statement. ב-db.py:2357 (search_precedent_library_semantic) — להוסיף שאילתה מקבילה של websearch_to_tsquery → RRF merge עם cosine. אזהרה: postgres אינו תומך ב-'hebrew' config — simple config יעבוד אבל בלי stemming.", + "testStrategy": "שאילתה 'עע\"מ 1461/20' לפני/אחרי. לפני: 0 hits. אחרי: 1 hit מדויק על הציטוט. וגם — שאילתות סמנטיות לא מאבדות recall.", + "status": "done", + "dependencies": [ + "40" + ], + "priority": "high", + "subtasks": [], + "updatedAt": "2026-05-26T08:08:27.953285Z" + }, + { + "id": "42", + "title": "[שלב B] Query expansion via Claude Haiku — 2-3 variants per query", + "description": "שאילתות עם abbreviations משפטיות ('בל\"מ'/'בקשה להארכת מועד') חוטפות recall. LLM expansion: שאילתה → 2-3 variants → union retrieval. +10-15% recall.", + "details": "להוסיף שכבה ב-search_precedent_library_semantic: אם query מכיל abbreviations נפוצים (mapping פנימי) — להריץ Haiku להרחבה. cache תוצאות לפי query hash (Redis TTL 24h).", + "testStrategy": "Eval על 20 שאילתות עם abbreviations: לפני/אחרי recall@10. צפוי +10-15%.", + "status": "deferred", + "dependencies": [ + "41" + ], + "priority": "medium", + "subtasks": [], + "updatedAt": "2026-05-26T08:08:27.953285Z" + }, + { + "id": "43", + "title": "[שלב B] MMR / diversity penalty — limit 2 chunks per case_law_id", + "description": "תוצאות חיפוש דומות מאוד זו לזו (אותה פסיקה, chunks סמוכים) — פסיקות חוזרות תופסות slots → diversity@10 נמוך. הוספת cap per case_law_id (2-3 max) או MMR אמיתי.", + "details": "פתרון קל: SQL DISTINCT ON (case_law_id) + 2 בpost-processing. פתרון איכותי: MMR — לכל candidate, score = λ*relevance - (1-λ)*max_similarity_to_selected. λ=0.7 דיפולט.", + "testStrategy": "כל שאילתה ב-top-10: <= 2 chunks per case_law_id. diversity score עולה.", + "status": "done", + "dependencies": [ + "40" + ], + "priority": "medium", + "subtasks": [], + "updatedAt": "2026-05-26T08:08:27.953285Z" + }, + { + "id": "44", + "title": "[שלב B] HNSW migration (or lists=68 IVFFlat) + REINDEX", + "description": "IVFFlat lists=50 עם 4,595 vectors — sub-optimal. sqrt(4595)≈68. HNSW עדיף ל-recall (אבל יותר זיכרון). שיפור +3-5% recall@10.", + "details": "אופציה 1: REINDEX עם lists=68 (פשוט, idempotent). אופציה 2: DROP+CREATE עם HNSW (m=16, ef_construction=64) — דורש pgvector ≥0.5 ובדיקת זמן build. בדוק SELECT extversion FROM pg_extension WHERE extname='vector'.", + "testStrategy": "EXPLAIN ANALYZE לפני/אחרי על 5 שאילתות מייצגות. בנצ'מרק recall@10 על blind set.", + "status": "done", + "dependencies": [], + "priority": "medium", + "subtasks": [], + "updatedAt": "2026-05-26T08:08:27.953285Z" + }, + { + "id": "45", + "title": "[שלב B] Halacha auto-approve sweep — בדיקת 219 pending + הורדת סף ל-0.78", + "description": "219 halachot pending review (17%) חסומות מ-search. אם dafna לא מסקר ידנית — הם מתבזבזים. dashboard batch + הורדת auto-approve threshold.", + "details": "1. בדוק 20 דגימות אקראיות של pending — אם רובן ראויות לאישור, הורד HALACHA_AUTO_APPROVE_THRESHOLD מ-0.80 ל-0.78. 2. הוסף UI batch approval ב-/halachot עם filter pending+confidence>0.75. 3. one-shot SQL לאישור 200 halachot שעמדו בקריטריונים החדשים.", + "testStrategy": "אחרי sweep: halachot approved יעלה מ-1,064 ל-~1,260. search_precedent_library יחזיר יותר rule-level results.", + "status": "done", + "dependencies": [], + "priority": "medium", + "subtasks": [], + "updatedAt": "2026-05-26T08:08:27.953285Z" + }, + { + "id": "46", + "title": "[שלב B] Dynamic halacha boost — לפי query-rule similarity", + "description": "כיום halacha boost = +0.05 קבוע. דינמי לפי query similarity ירוץ דייקנות (5% precision על שאילתות ספציפיות).", + "details": "ב-db.py:2479 — score = float(d['score']) + 0.05. החלף ב-boost = 0.10 * d['score'] (proportional). או — אם rerank ON, השתמש בrerank score כbaseline (אין צורך ב-boost כלל).", + "testStrategy": "A/B test על 10 שאילתות: precision@5 לפני/אחרי.", + "status": "done", + "dependencies": [ + "40" + ], + "priority": "low", + "subtasks": [], + "updatedAt": "2026-05-26T08:08:27.953285Z" + }, + { + "id": "47", + "title": "[שלב C - prevention] Audit script periodic: detect new external_upload עם case_number של ערר", + "description": "Drift detection: שגיאה דומה ל-Bug (ב) יכולה לחזור בעתיד. periodic check (יומי?) + alert ל-Slack/comment.", + "details": "scripts/audit_corpus_consistency.py — בודק: 1. case_law WHERE source_kind='external_upload' AND case_number ~ '^ערר|^ARAR'. 2. case_law WHERE source_kind='internal_committee' AND chair_name IS NULL. הרצה דרך cron או scheduled task ב-Paperclip.", + "testStrategy": "להריץ אחרי כל העלאה חדשה (וגם פעם ביום). אם מוצא drift — comment ב-Paperclip ל-CEO.", + "status": "pending", + "dependencies": [ + "30", + "39" + ], + "priority": "low", + "subtasks": [] + }, + { + "id": "48", + "title": "[שלב C] Parent-doc retrieval (child=300, parent=1500 tokens)", + "description": "chunk_size=600 חותך חלק מהלכות ארוכות. parent-doc: חיפוש על child קטן (300 tokens), החזרת parent גדול (1500 tokens) ל-LLM context.", + "details": "מיגרציה DB: precedent_chunks.parent_chunk_id (FK self). chunking pipeline משתנה ל-2 רמות. retrieval: SELECT distinct parent_chunk WHERE child_chunk matches.", + "testStrategy": "Eval: writer מקבל context מלא יותר, לא חתוך באמצע משפט/ציטוט.", + "status": "pending", + "dependencies": [ + "41" + ], + "priority": "low", + "subtasks": [] + }, + { + "id": "49", + "title": "[שלב C] Multimodal backfill ל-77 רשומות שנותרו", + "description": "כיום 40/117 precedent_image_embeddings (34%). 77 רשומות נותרו ללא image embeddings. ערך נמוך כשהמסמכים digital-native, אבל קריטי לscanned PDFs.", + "details": "scripts/multimodal_backfill.py כבר קיים. להריץ עם batch size 10 כדי לא לדפוק את Voyage rate limits. אומדן: 77×~10K tokens = ~770K tokens ($10-15).", + "testStrategy": "אחרי backfill: COUNT(*) FROM precedent_image_embeddings ≥ 117 (מותר יותר אם יש כמה pages per pdf).", + "status": "pending", + "dependencies": [], + "priority": "low", + "subtasks": [] + }, + { + "id": "50", + "title": "[שלב C] Closed-loop retrieval feedback + ndcg dashboard", + "description": "אין tracking של 'what was retrieved → what writer cited'. בלי זה — אי אפשר לעדכן את ה-RAG בצורה מדודה לאורך זמן.", + "details": "טבלה חדשה retrieval_feedback (query, candidates_retrieved JSONB, cited_in_final_decision UUID[], created_at). hooks ב-writer לדווח. dashboard חודשי עם ndcg@10.", + "testStrategy": "אחרי 3 החלטות סופיות: SELECT count FROM retrieval_feedback ≥ 3. dashboard מציג ndcg trend.", + "status": "pending", + "dependencies": [], + "priority": "low", + "subtasks": [] + }, + { + "id": "51", + "title": "[שלב C] Halacha quality monitoring — confidence drift, alert", + "description": "אם prompt או model משתנה — confidence distribution יכול לזוז. בלי monitoring — דרדור איכות עובר תחת הראדר.", + "details": "scheduled job: weekly mean confidence per practice_area. אם זז ביותר מ-0.05 — alert. dashboard ב-/halachot עם histogram.", + "testStrategy": "אחרי 4 שבועות — לבדוק שיש 4 datapoints + alert עובד על נתון synthetic.", + "status": "pending", + "dependencies": [], + "priority": "low", + "subtasks": [] } ], "metadata": { @@ -1380,7 +1871,8 @@ "completedCount": 24, "tags": [ "legal-ai" - ] + ], + "updated": "2026-05-26T06:39:31.733370" } } } \ No newline at end of file