Files
legal-ai/scripts/SCRIPTS.md
Chaim 013fe39ea7
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 8s
fix(supervisor): re-probe claude.ai quota instead of waiting blindly for the reported reset
When the halacha drain hit a 429, the supervisor recorded the reset time the
error reported (e.g. "resets 6:50pm UTC") and then HELD until that timestamp,
re-reading it from its own state every tick without ever checking whether quota
had actually returned. claude.ai usually frees up quota earlier than the message
claims, so the drain sat idle for hours after it could have resumed — and only a
manual kick (clear cooldown + trigger) got it going again.

Now, on any tick where we'd otherwise hold on a cooldown, run a cheap live probe
(`quota_available()` → a tiny `claude -p` call, cost ~0) and resume the instant
it succeeds — at most one probe per 15-min tick, only while we believe we're
limited. Conservative on failure (non-zero exit / timeout / limit message →
stay held), so a flaky probe never resumes the drain into a real 429. Adds a
claude_bin() resolver so the probe works under pm2 cron where PATH is bare.

Invariants: G1 (resume decision driven by actual quota state, not a guessed
timestamp); no new control path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 09:35:45 +00:00

54 KiB
Raw Blame History

scripts/ — מדריך סקריפטים

כלל: כל עדכון, יצירה, או מחיקה של סקריפט בתיקייה זו מחייב עדכון של קובץ זה.


סקריפטים פעילים

Script Type Purpose Scheduled
pc.sh bash wrapper לכל קריאות Paperclip API מסוכנים — מוסיף Authorization, X-Paperclip-Run-Id (audit trail), Content-Type, base URL. תחביר: pc.sh <METHOD> <PATH> [BODY_JSON]. אסור curl ישיר ל-$PAPERCLIP_API_URL. ראה HEARTBEAT.md §0. counterpart ב-Python: web/paperclip_api.py. נקרא ע"י סוכנים
spec-guard.sh bash PreToolUse hook לאכיפת "פרוטוקול כתיבת-קוד" (CLAUDE.md §פרוטוקול כתיבת-קוד) — בכל Edit/Write/MultiEdit על נתיב-קוד (web/, mcp-server/, web-ui/src/, scripts/, adapters/) מזריק תזכורת ל-Claude לקרוא את docs/spec/00-constitution.md+ספ-התחום ולוודא קיום G1G12 — לפני שכותבים. + leak-guard בזמן-אמת (G12): על כתיבה ל-mcp-server/src/* בודק את התוכן-הנכתב (new_string/content) ומזהיר אם מוזרק מונח-Paperclip לשכבת-האינטליגנציה (לא-deduped). המקבילה האינטראקטיבית ל-INV-AG1. קלט JSON ב-stdin, פלט hookSpecificOutput.additionalContext (non-blocking, exit 0). Dedup פעם-בסשן לתזכורת-הספ. רשום ב-.claude/settings.json. נקרא אוטומטית ע"י Claude Code (hook)
leak_guard.py python המאכף הקנוני של INV-G12 (שער-הפלטפורמה / docs/spec/X15 §4 / R4). שני כללים קשיחים: (1) mcp-server/src ללא סמלי-Paperclip (allowlist מנומק לפי substring); (2) רק web/agent_platform_port.py (+ קבצי-המעטפת) מייבאים את לקוח-Paperclip. stdlib-בלבד (אין venv). leak_guard.py = סריקת-repo (exit 1 על הפרה); leak_guard.py <file>... = קבצים נתונים (ל-hook). משותף ל-spec-guard.sh (hook), ל-CI (.gitea/workflows/leak-guard.yaml) ול-mcp-server/tests/test_platform_port_leak_guard.py. CI + hook + pytest
migrate_gap51_outcomes.py python GAP-51 (FU-14) — נרמול ערכי outcome לאוצר הקנוני (rejected→rejection, accepted→full_acceptance, partial→partial_acceptance) ב-decisions.outcome + cases.expected_outcome. betterment_levy לא ממופה (practice_area, לא outcome). --dry-run (ברירת-מחדל) / --apply (גיבוי ל-data/audit/gap51-outcome-backup-*.csv + UPDATE טרנזקציוני). דורש POSTGRES_URL. בוצע 2026-06-06 (9 שורות). נוגע רק ב-cases/decisions — בטוח במקביל לחילוץ. חד-פעמי (בוצע)
sync_missing_agent_skills.py python סקריפט "אל-כשל" להוספת paperclipSkillSync ל-הגהת מסמכים ו-מנתח משפטי שפיספסו את ה-sync ההיסטורי (Gap #28). תומך --verify/--dry-run/--apply. גיבוי אוטומטי ל-agents-pre-skill-sync-*.sql. דורש PAPERCLIP_BOARD_API_KEY (Infisical /paperclip ב-nautilus env). idempotent. חד-פעמי (בוצע 2026-05-04). שמור לרפרנס
sync_agents_across_companies.py python סנכרון סוכנים מ-CMP (1xxx, master) ל-CMPA (8xxx, mirror) — Gap #25. משווה adapter_config (model/timeout/instructions/skills/etc), runtime_config (heartbeat), ושדות top-level (budget/metadata/icon/title/role). מסנן אוטומטית local skills שלא קיימים ב-mirror. לוגיקת subset (mirror יכול להחזיק יותר skills כי ה-API מוסיף required runtime skills). תומך --verify/--dry-run/--apply [--only NAME]. גיבוי אוטומטי. דורש PAPERCLIP_BOARD_API_KEY. להריץ אחרי כל שינוי הגדרות ב-CMP. ⚠ אם adapter_type שונה בין CMP ל-CMPA — --apply מדלג על הסוכן; --verify מדווח אותו רם כ-DRIFT. בעת מעבר adapter (למשל ל-deepseek_local) חובה לעדכן ידנית בשתי החברות. --verify יוצא exit≠0 על כל drift (needs-sync / adapter-mismatch / missing-in-mirror) — שמיש כ-gate ל-cron/CI (GAP-21/FU-8a). ידני אחרי כל שינוי
fix_paperclipai_skills_drift.py python סקריפט חד-פעמי (בוצע 2026-05-04) שניקה drift על paperclipai/* skills בין CMP ל-CMPA. הסיר paperclip-dev מכל 14 הסוכנים, ודאג ש-paperclip-converting-plans-to-tasks קיים רק על CEO ו-analyst. תומך --apply (ברירת מחדל: dry-run). דורש PAPERCLIP_BOARD_API_KEY. נשמר לרפרנס למקרה שhdrift חוזר. חד-פעמי (בוצע)
test_retrieval_by_name.py python בדיקת אחזור-לפי-שם (#52/RC-A) — מאמת שsearch_precedent_library/search_internal_decisions מדרגים את ההחלטה עצמה (אגסי) מעל מי שמצטט אותה, + רגרסיות לשאילתות מהותיות. הרצה: DOTENV_PATH=/home/chaim/.env DATA_DIR=.../data mcp-server/.venv/bin/python scripts/test_retrieval_by_name.py (exit 0 = עבר). ידני אחרי שינוי שכבת חיפוש
fu2b_reconcile_internal_case_numbers.py python FU-2b (GAP-07/08) — תיאום case_number של internal_committee מציטוט-מלא למספר-בסיס קנוני (X1: trim·prefix-strip·/-, חודש נשמר). דטרמיניסטי (token יחיד; 0/>1 → flag). --dry-run (ברירת-מחדל) מפיק טבלת-תיאום ל-data/audit/fu2b-reconciliation-*.{csv,md} עם flags (DUP_CHECK / PROC_MISMATCH / MISMATCH). --apply --approved <csv> מגבה ואז מעדכן רק שורות שאושרו ע"י היו"ר. scope: internal בלבד (external → #68). FK-safe. חד-פעמי, chair-gated (apply רק אחרי אישור דפנה)
fu2c_reconcile_external_case_numbers.py python FU-2c (GAP-08, #68) — תיאום case_number של פסיקה חיצונית (source_kind <> internal_committee) מציטוט-מלא לצורה קנונית מציין-הליך + docket (החלטת-יו"ר 2026-05-31, Option A: / נשמר, לא -; תואם db.py:369 ו-INV-ID2). דטרמיניסטי (designator+docket; 0/>1 docket → flag). --dry-run (ברירת-מחדל) מפיק data/audit/fu2c-reconciliation-*.{csv,md} עם flags (MISMATCH / NO_CITATION / CIT_NO_DOCKET / DESIG_MISMATCH / DUP_CHECK). --apply --approved <csv> מגבה ואז מעדכן שורות לא-חוסמות (כולל ADVISORY/NO_CITATION). --overrides <csv> (id,proposed_canonical,reason) פותח שורות-חוסמות בהכרעת-יו"ר מפורשת (למשל פס"ד מאוחד — ראה data/audit/fu2c-overrides.csv לרשומת לויתן/קלמנוביץ). לוגיקת-החילוץ + פיצול flags אומתו offline על 24 רשומות. scope: external בלבד (internal = FU-2b). FK-safe. חד-פעמי, chair-gated (apply רק אחרי אישור דפנה)
eval_gold_bootstrap.py python FU-5 (GAP-11) — bootstrap ל-gold-set של הערכת-אחזור ל-data/eval/gold-set.jsonl. שני מקורות: --source citations (cited==relevant מ-search_relevance_feedback; ריק עד שייצברו ציטוטים) ו---source known_item (query=שם-תיק → relevant=עצמו; אות אמיתי היום). Idempotent — שומר שורות source=chair, מחדש bootstrap_*. דורש POSTGRES. לפני eval; חוזר כשנצבר ground-truth
eval_retrieval.py python FU-5 (GAP-11, INV-RET4/G8) — harness הערכת-אחזור — מריץ את מסלול-האחזור בייצור (search_library/search_internal) על ה-gold-set, מחשב precision@k/recall@k/MRR/nDCG@k (k=5,10), מצרף overall+per-corpus+per-PA ל-data/eval/eval-report-<ts>.{json,md} + delta מול data/eval/baseline.json (מתעד retrieval_config). --self-test בודק את המטריקות offline; --update-baseline מאמץ snapshot. שער-CI במשמעת: הרץ לפני/אחרי כל שינוי בשכבת-האחזור באותו קונפיג. דורש POSTGRES+VOYAGE_API_KEY. לפני/אחרי שינוי RRF/k/embedder/rerank
legal-court-fetch-service.config.cjs pm2/js שירות-מארח Tier-1 לאחזור פסקי-דין מנט המשפט (X13) — 2 apps: (א) legal-court-fetch-xvfb (Xvfb :99, צג-וירטואלי ל-Camoufox); (ב) legal-court-fetch-service (python -m legal_mcp.court_fetch_service.server, bound 10.0.1.1:8771, Bearer COURT_FETCH_SHARED_SECRET מ-~/.legal-court-fetch-service.env, DISPLAY=:99). מריץ Camoufox דרך חבילת-הפייתון (in-process) כי הקונטיינר לא יכול דפדפן. תלות: pip install -e "mcp-server[court-fetch]" && python -m camoufox fetch. אחזור = ניווט→צופה→GetImages(X-Requested-With)→PDF, ללא CAPTCHA; כשל→ok:false→orchestrator מסלים ל-fallback אנושי. אומת על עת"מ 46111-12-22 (34 עמ'). מראָה לדפוס legal-chat-service.config.cjs. ספ: docs/spec/X13-court-fetch.md. התקנה: pm2 start scripts/legal-court-fetch-service.config.cjs && pm2 save. בריאות: curl http://10.0.1.1:8771/health. pm2 (host-side)
reap_orphan_procs.py python reaper לתהליכים-יתומים שמרווים את שרת Nautilus — הורג task-master-mcp (Node, מתנפח ל~3GB) ו-camoufox-bin (Firefox מ-X13 fetch שקרס) רק כשהם יתומים (ppid=1) — תהליך עם הורה-חי לעולם לא נוגעים בו. /proc טהור, בלי psutil. --dry-run (דיווח), --loop N (דמון כל N ש'). ראה זיכרון project_taskmaster_mcp_memory_leak. דרך legal-reaper.config.cjs (pm2)
legal-reaper.config.cjs pm2/js דמון pm2 ל-reap_orphan_procs.py --loop (ברירת-מחדל 180ש', REAP_INTERVAL_S לעקיפה). max_memory_restart 100M (ה-reaper עצמו לא ידלוף). התקנה: pm2 start scripts/legal-reaper.config.cjs && pm2 save. לוגים: pm2 logs legal-reaper. pm2 (host-side)
drain_court_fetch.py python ריקון תור-אחזור הפסיקה (X13) — קורא ל-court_fetch_orchestrator.drain_pending(limit) שמוריד+קולט כל job ממתין שהיומונים מילאו, וקושר חזרה ליומון. מקומי בלבד (ingest = claude CLI). no-op מהיר כשהתור ריק. הרצה ידנית: mcp-server/.venv/bin/python scripts/drain_court_fetch.py [limit]. דרך legal-court-fetch-drain.config.cjs (pm2 cron)
backfill_missing_precedents.py python הזנת missing_precedents פתוחים לתור-האחזור (X13) — מסווג כל פער-פתוח; עליון-סדרתי→Tier-0(supremedecisions), נט-format→Tier-1; ועדת-ערר/לא-מזוהה→דילוג. יוצר court_fetch_jobs (idempotent). --apply (ברירת-מחדל dry-run). אחרי הרצה: drain-court-fetch קולט. ידני (חד-פעמי/לפי-צורך)
legal-court-fetch-drain.config.cjs pm2/js תזמון שעתי של drain_court_fetch.py (cron 17 * * * *, COURT_FETCH_DRAIN_CRON לעקיפה) — הופך את לולאת יומון→אחזור→קליטה ל-fully-autonomous. autorestart:false (one-shot per tick). דורש legal-court-fetch-service רץ. התקנה: pm2 start scripts/legal-court-fetch-drain.config.cjs && pm2 save. pm2 cron (host-side)
drain_metadata_queue.py python ריקון תור חילוץ-המטא של הפסיקהprocess_pending_extractions(kind='metadata') ב-batches עד ריק. רץ על Gemini Flash (structured JSON, gemini_session) — מהיר ואמין, במקום ה-claude CLI ה-agentic שפגע ב-error_max_turns. no-op מהיר כשריק. הרצה ידנית: mcp-server/.venv/bin/python scripts/drain_metadata_queue.py [batch]. דרך legal-metadata-drain.config.cjs (pm2 cron)
legal-metadata-drain.config.cjs pm2/js תזמון כל 15 דק' של drain_metadata_queue.py (cron */15 * * * *, METADATA_DRAIN_CRON לעקיפה) — מונע סתימה של תור חילוץ-המטא ב-/precedents. דורש GEMINI_API_KEY ב-~/.env. התקנה: pm2 start scripts/legal-metadata-drain.config.cjs && pm2 save. pm2 cron (host-side)
reconcile_metadata_status.py python נרמול metadata_extraction_status תקוע (G1) — שורות עם ברירת-המחדל 'pending' שאינן בצנרת-Gemini נערמות כ-backlog-רפאים שהדריינר (סורק *_requested_at IS NOT NULL) לעולם לא מנקה ומנפח את מונה "ממתין" ב-/operations. מיישב כל שורה למצב-אמת במקור: internal_committeecompleted (מטא דטרמיניסטי, מחוץ ל-Gemini), external_upload מלא→completed, external_upload עם טקסט וחסר שם/תקציר→חותם requested_at (הדריינר יטפל), cited_only (אין טקסט)→skipped. אידמפוטנטי. תיקון-המקור הנלווה ב-db.create_internal_committee_decision. הרצה: mcp-server/.venv/bin/python scripts/reconcile_metadata_status.py. חד-פעמי / re-runnable כהגנת-drift
auto-sync-cases.sh bash סנכרון תיקי ערר ל-Gitea — רץ כל דקה * * * * * (cron)
backup-db.sh bash גיבוי PostgreSQL יומי ל-data/backups/ (gzip) לתזמן: 0 2 * * *
restore-db.sh bash שחזור DB מגיבוי (companion ל-backup-db.sh) ידני
notify.py python שליחת מייל התראה מסוכנים via SMTP (Gmail) נקרא ע"י סוכנים
bidi_table.py python יצירת טבלאות box-drawing עם תמיכה ב-BiDi (עברית+אנגלית) ספריית עזר
convert_decision_template.py python המרת data/training/טיוטת החלטה.dotxskills/docx/decision_template.docx לטעינה ב-python-docx להריץ כשמתעדכנת התבנית
deploy-track-changes.sh bash סנכרון skills CMP↔CMPA + בדיקות + הנחיות deploy לארכיטקטורת Track Changes ידני
retrofit_case.py python retrofit רטרואקטיבי — מזריק bookmarks לקובץ קיים של תיק ספציפי ומגדיר אותו כ-active_draft ידני (חד-פעמי לתיק)
reembed_voyage.py python Re-embed כל הוקטורים ב-DB עם המודל ב-VOYAGE_MODEL (לאחר שינוי מודל). 5 טבלאות, 1024 דמ', batches של 100. ראה docs/voyage-upgrades-plan.md ידני (אחרי החלפת VOYAGE_MODEL)
voyage_context3_poc.py python POC #1 — voyage-3 vs voyage-context-3 על פסיקה אחת קצרה (קלמנוביץ, 63 chunks). הכרעה: context-3 לא מציג שיפור עקבי בנצ'מרק חד-פעמי, נשמר לרפרנס
voyage_context3_poc_long.py python POC #2 — voyage-context-3 על פסיקה ארוכה (אהרון ברק 219 chunks) עם sliding windows. הכרעה: context-3 לא משתפר על פסיקה גדולה בנצ'מרק חד-פעמי, נשמר לרפרנס
voyage_multimodal_poc.py python POC #3 — voyage-multimodal-3 על דוח שמאי (89 עמודים). הכרעה: שיפור משמעותי לטבלאות + 22 עמודי image-only שhttp text-OCR מאבד בנצ'מרק חד-פעמי, מוכן לשלב C
voyage_rerank_judge_poc.py python POC #4 — voyage-3 vs rerank-2 vs context-3 על אהרון ברק, 18 שאילתות, claude-haiku-4-5 כ-judge. הכרעה: rerank-2 ניצח עם +9% mean@3 בנצ'מרק חד-פעמי
voyage_rerank_corpus_poc.py python POC #5 — voyage-3 vs rerank-2 על קורפוס מלא (785 docs). הכרעה: +4.5% mean@3 כללי, +11.6% על P queries (practical) בנצ'מרק חד-פעמי, אישר את שלב B
multimodal_backfill.py python Backfill voyage-multimodal-3 page embeddings על מסמכי תיקים קיימים. idempotent (skips by default), forces MULTIMODAL_ENABLED=true ל-run, רץ מהקונטיינר. שלב C — ראה docs/voyage-upgrades-plan.md ידני per-case (python multimodal_backfill.py 8174-24 8137-24)
backfill_chunk_pages.py python Backfill page_number ב-document_chunks קיימים. legacy chunker לא tracked עמודים → page_number=NULL חוסם boost של multimodal hybrid (text+image join על אותו עמוד). re-extracts כל PDF (re-OCR אם צריך, ~$0.0015/page), מחשב page_offsets, ומעדכן chunks. idempotent ידני per-case (python backfill_chunk_pages.py 8174-24 8137-24)
rechunk_legacy_precedents.py python #57 — re-chunk + re-embed פסיקה שהוטמעה לפני תיקון ה-chunker (#55). בוחר כל case_law עם chunk זעיר (length(trim(content))<50 — טביעת-האצבע של ה-chunker הישן) ומריץ ingest.reindex_case_law (re-chunk+re-embed מ-full_text שמור בלבד — ללא re-OCR/LLM, feedback_no_reocr_retrofit; idempotent DELETE-then-INSERT). idempotent ברמת-הבאטץ' (שואב מחדש את הסט המושפע בכל ריצה). דגל --limit N. רץ עם venv של mcp-server (cd mcp-server && .venv/bin/python ../scripts/rechunk_legacy_precedents.py) חד-פעמי — מיגרציית-נתונים של פסיקה legacy (תוקן 2026-06-03)
backfill_nevo_preamble.py python #86.2 — מיגרציית-נתונים: חיתוך preamble/רציו של נבו שדלף לפסיקה שהוטמעה לפני תיקון #86.1. מאתר כל case_law ש-strip_nevo_preamble(full_text) עדיין מקצר (דליפה היסטורית), ומבצע: (1) לכידת ה-מיני-רציו ל-case_law.nevo_ratio (gold-set ל-#86.3); (2) שכתוב full_text החתוך + חישוב-מחדש של content_hash; (3) reindex_case_law (re-chunk+embed, ללא re-OCR/LLM); (4) סימון (לא מחיקה) הלכות ש-supporting_quote שלהן בתוך ה-preamble שהוסר → pending_review + quality_flag nevo_preamble_leak. שומר-בטיחות: שורות עם keep%<--min-keep (ברירת-מחדל 60) מוחרגות מ---apply כחשד over-strip (אלא אם --include-suspicious). dry-run כברירת-מחדל; --apply כותב backup JSON + manifest CSV ל-data/audit/ תחילה. idempotent. רץ עם venv של mcp-server. chair-gated (לאמת manifest לפני apply) מיגרציית-נתונים — dry-run בוצע (19 פסקים, 27 הלכות מזוהמות); apply ממתין לאישור
nevo_ratio_benchmark.py python #86.3 — מדידת איכות חילוץ-הלכות מול ה-מיני-רציו של נבו (gold-set מקצועי חינמי). לכל פסק עם nevo_ratio (או נגזר מ-full_text אם טרם בוצע backfill): LLM-judge מקומי (claude_session, אפס עלות) ממפה סמנטית את הלכות-המערכת מול הלכות-נבו ומפיק recall (כיסוי הלכות-נבו), precision (אחוז הלכותינו הממופות), granularity (יחס פירוק — איתות over-extraction ל-#81.5). --case <num> / --all [--limit N] / --model / --out. כותב CSV ל-data/audit/. רץ עם venv של mcp-server (דורש Claude CLI מקומי). אומת על בג"ץ 1764/05: recall 0.875, precision 1.0, granularity 1.75x ידני — מדידת-איכות (CI/ad-hoc)
migrate_blobs_to_minio.py python #106.4 — הגירת בלובים לדיסק→MinIO (DB-driven, dry-run-default). סורק 6 עמודות-נתיב (documents.file_path · cases.active_draft_path · digests.source_document_path · draft_final_pairs.final_path · *_image_embeddings.image_thumbnail_path), מנרמל 3 פורמטי-נתיב legacy (container-abs /data/, host-abs, relative) ל-key יחסי-DATA_DIR, וגוזר bucket per-file-semantic (מסמך→documents, thumbnail→derived). dry-run מפיק תוכנית+מניפסט CSV (data/audit) + מדווח חסרים; --apply מעלה דרך mcli ומאמת size (דיסק לא נוגע → הפיך). אומת 2026-06-11: 3404 קבצים/899MB, 0 outside, 28 חסרים. חובה mcli alias legalminio. ידני — הגירת-אחסון X14
storage_leak_tripwire.py python INV-STG1 tripwire (ניטור-ריצה). משלים את ה-CI leak-guard: סורק בלובים ב-data/{cases,precedent-library,internal-decisions,digests,training} ומשווה מול ה-key-sets החיים של legal-documents/legal-derived (json-key match, סיווג bucket per-file כמו בהגירה). מדווח בלובים שדלפו (בדיסק אך לא ב-MinIO → יאבדו בניקוי, לא מוגשים/מגובים). read-only, --since <ISO>. אומת: 0 דליפות. חובה מקומי (mcli legalminio). תקופתי / לפני ניקוי-דיסק #128
nevo_corpus_audit.py python #86.2/#86.3 — אודיט קורפוס-נבו (read-only). leak סורק chunks+הלכות למרקרי-preamble של נבו (מיובאים מ-extractor._NEVO_MARKERS), מבחין בין הווקטור המזיק (מרקר בתוך הלכה=רציו-עריכה כהלכה) ל-benign (רשימת-ציטוטים), ומפיק CSV. אומת 2026-06-11: 0 הלכות מזוהמות (שכבת-הידע נקייה) → אין purge/re-ingest (גם נוגד no-reocr). leak --apply מבצע backfill אדיטיבי של case_law.nevo_ratio מטקסט שמור (extract_nevo_ratio, ללא re-OCR) — captured 16→32. benchmark משווה הלכות-שלנו מול ה-מיני-רציו דרך הפאנל התלת-מודלי → recall כיסוי (1110-20: 13 הלכות, recall=1.0). חובה מקומי (benchmark). ידני — ניטור-זיהום / ground-truth
halacha_goldset.py python #81.7 — הארנס gold-set לאיכות חילוץ-הלכות. export --n N מייצא מדגם מרובד (לפי precedent×rule_type) ל-CSV עם עמודות-תיוג ריקות (is_holding/correct_type/quote_complete) לתיוג ידני (חיים/דפנה). score --in <csv> קורא את ה-CSV המתויג ומודד כל ולידטור (compute_quality_flags/is_fact_dependent/is_quote_truncated/is_thin_restatement) מול אמת-המידה האנושית: P/R/F1 + confusion. בסיס ל-#81.8 (כיול סף האישור). מייבא את אותם ולידטורים שה-extractor מריץ. רץ עם venv של mcp-server. הערה: קיים גם דף-תיוג אינטראקטיבי DB-backed (/goldset) — זה ה-CSV-fallback ידני — export→תיוג→score
goldset_panel_label.py python #81.7 — תיוג ה-gold-set בקונצנזוס תלת-מודלי (ללא man-in-the-loop, הנחיית-יו"ר 2026-06-11). מריץ את שלושת השופטים העצמאיים (Opus/claude_session · DeepSeek · Gemini, מיובאים מ-halacha_panel_approve) עם ה-prompt העשיר (is_holding+type+נימוק מ-goldset_ai_recommend) על כל פריט; רוב 2/3 נכתב ל-is_holding/correct_type עם tagged_by='panel:opus+deepseek+gemini'יצול→NULL→יו"ר, INV-G10). מודד Fleiss κ (3 מעריכים) ומריץ מבחן-אנונימיזציה (שמות-תיק ממוסכים→שיפוט-מחדש; flip=שינון). לא מעגלי — הוולידטורים הנמדדים rule-based. כותב per-model+consensus+anon ל-DB ודוח ל-data/audit/. מחליף תיוג-ידני; goldset_ai_recommend/goldset_independent_judge נשארים כבדיקות single-model. --limit/--no-anon/--force. חובה מקומי. ידני — לאחר יצירת/הרחבת batch
goldset_ai_recommend.py python #81.7 QA (single-model, נבלע ב-panel) — חוות-דעת claude בלבד ל-ai_*. כעת לינאז' 1/3 בתוך goldset_panel_label; נשאר כבדיקת-claude עצמאית/חידוש נקודתי. --force/--limit. חובה מקומי. ידני — בדיקה נקודתית
goldset_independent_judge.py python INV-DM7 ולידציה — שופט-תפקיד עצמאי שני ממודל אחר (DeepSeek API ישיר, OpenAI-compatible) ששובר את עיגון-ה-AI: מסווג rule_role בעיוור (בלי לראות תיוג-אדם או המלצת-claude) ומחשב מטריצת-הסכמה (deepseek↔אדם מול ai↔אדם) + ציר-גס (כלל-בר-הכללה מול application/obiter). ממצא (2026-06-07): ai↔אדם=100% (מעוגן), deepseek↔אדם=50% מדויק אך 92% גס → תת-הסוג holding/interpretive/procedural עמום-מטבעו (לא לשער עליו); הציר-הגס אמין חוצה-מודלים. read-only על הזהב. --model/--limit/--concurrency. מפתח מ-~/.hermes/profiles/deepseek/.env. raw→/tmp/goldset_judge_raw.json. ידני — ולידציית אמינות-תוויות
halacha_panel_approve.py python פאנל-אישור הלכות (Trust-or-Escalate, dry-run). 3 שופטים בלתי-תלויי-לינאז' (Opus/claude_session · DeepSeek · Gemini-2.5-flash) מצביעים על הציר-הגס האמין (92% חוצה-מודלים): נקיות→"הלכה לשמירה?"; nli_unsupported→"הציטוט תומך בכלל?" (שיפוט-מחדש); פגומות→re-extraction. רק ורדיקט מוסכם פועל אוטומטית, פיצול מסלים ליו"ר (INV-G10). --apply מחווט (clean: רוב 2/3; nli: פה-אחד-entailed מנקה flag) — הפיך, מגבה ל-data/audit/ קודם. מפתחות: DeepSeek מ-~/.hermes/..., Gemini מ-~/.env. חובה מקומי. dry-run 2026-06-07: 197→103 אוטו (פה-אחד) / ~15 (רוב). FU-1 (#133): כל סבב — הצבעות +נימוקי-כל-שופט — נשמר ל-halacha_panel_rounds בשני המצבים (capture-only, לא נוגע ב-halachot; apply_mode מתעד dry-run מול apply); ה-seed ללמידה נוצר בהצלבה מול הכרעת-היו"ר המאוחרת על אותה הלכה. --no-capture לדילוג. ידני / שלב-אימות-הלכות במסלול-הסופי
style_lesson_panel.py python פאנל-סגנון דו-סוכני (למידה כפולה). על-גבי דיסטילציית-ה-Opus (draft↔final ב-draft_final_pairs.analysis), שני שופטים בלתי-תלויים — DeepSeek + Gemini-2.5-flash — מצביעים לכל לקח על השאלה הגסה "האם זו הנחיית-סגנון מופשטת ובת-הכללה (INV-LRN5 — קול ולא מהות)?". הסכמה 2/2-keep → נכתב כ-decision_lesson (source=panel:deepseek+gemini); 2/2-drop → לא נכתב; פיצול/substance → מוסלם ליו"ר. --apply הפיך, מגבה ל-data/audit/. הטמעה ל-SKILL.md/lessons.md נשארת שער-יו"ר ידני (INV-G10). מפתחות כמו פאנל-ההלכות. חובה מקומי. --case <num> / --pair-id <uuid>. שלב-למידה במסלול-הסופי
final_learning_pipeline.py python תזמור שלב-הלמידה (פקודה אחת). מופעל ע"י הרמס כשלוחצים "הרץ למידת-קול" במסלול-הסופי. דטרמיניסטי: (1) ingest_final_version עם נתיב-הסופי, (2) רישום לקורפוס-הסגנון (idempotent), (3) style_lesson_panel --apply. עמיד (X16/INV-DUR1): 3 הצעדים רצים דרך _pipeline_runtime.py (משותף עם halacha) עם checkpoint לכל תיק — קריסה בפאנל [3] ממשיכה מ-[3] במקום לשלם שוב על דיסטילציית-Opus [1]. ברירת-מחדל auto-resume; --fresh ריצה נקייה. idempotent. חובה מקומי. --case <num> / --force / --fresh. אוטו (כפתור run-learning) / ידני
final_halacha_pipeline.py python תזמור שלב-אימות-ההלכות (פקודה אחת). מופעל ע"י הרמס כשלוחצים "הרץ אימות-הלכות". דטרמיניסטי: (0) precedent_extract_halachot (החלטה), (1) extract_internal_citations(chair), (2) corroboration.build_all(), (3) halacha_panel_approve --apply. עמיד (X16/INV-DUR1): 4 הצעדים רצים דרך _pipeline_runtime.py עם checkpoint לכל תיק — קריסה בפאנל [3] ממשיכה מ-[3]. ברירת-מחדל auto-resume; --fresh ריצה נקייה. חובה מקומי. --case <num> / --limit N / --fresh. אוטו (כפתור run-halacha) / ידני
_pipeline_runtime.py python runtime עמידות משותף (X16 / INV-DUR1) ל-final_halacha_pipeline ו-final_learning_pipeline (מימוש אחד, G2). עוטף רשימת-צעדים async ב-LangGraph StateGraph ליניארי עם AsyncSqliteSaver (checkpoint לכל צעד; resume מדלג על צעדים שהושלמו). degradation חיננית: ללא langgraph (pip install -e ".[durable]") — ריצה ליניארית כמו קודם (הכפתור לא נשבר). Step(name, run) + run_pipeline(steps, thread_id, checkpoint_db, fresh). נבדק: mcp-server/tests/test_pipeline_runtime.py. מיובא ע"י סקריפטי-המסלול-הסופי
curator_apply_pipeline_branch.py python מקור-אמת לחיווט-הכפתורים של הרמס. prompt-ה-curator חי רק ב-Paperclip DB (agents.adapter_config.promptTemplate). הסקריפט מקדים branch כך שיקיצה עם reason final_learning_*/final_halacha_* מריצה את ה-pipeline המתאים (HOME/DOTENV/DATA_DIR מוחלטים → DeepSeek+Gemini keys + DATA_DIR נפתרים נכון) ועוצרת, אחרת §A/§B כרגיל. idempotent (מסיר branch קודם). מחיל על שני הסוכנים (CMP+CMPA). --verify. להריץ אחרי reset/יצירה-מחדש של סוכן-curator. אחרי reset prompt של curator
halacha_panel_audit.py python רשת-ביטחון לפאנל (selective-prediction monitoring) — דוגם הלכות שאושרו ע"י הפאנל (reviewer LIKE 'panel:%'), מריץ עליהן שוב את הצבעת-ה-KEEP של 3 השופטים, ומציף כל מקרה שכעת נוטה DROP (false-keep פוטנציאלי). report-only כברירת-מחדל; --flag מחזיר את ה-flips ל-pending_review לסקירת-יו"ר. --sample N/--seed. בסיס 2026-06-07: 0/15. מיועד להרצה תקופתית (שבועי). מייבא שופטים מ-halacha_panel_approve. חובה מקומי. תקופתי (שבועי) — ניטור
halacha_panel_calibrate.py python כיול + מדידת הפאנל (Trust-or-Escalate, ICLR 2025). --source live (ברירת-מחדל): מריץ את שאלת-ה-KEEP על מדגם-הזהב ומודד מול is_holding precision+coverage+split-rate לכל מדיניות + false-keep/false-drop (מייבא שופטים מ-halacha_panel_approve, חובה מקומי). #133/FU-5--source captured: אפס-עלות (בלי re-vote/LLM) — מצליב סבבים שמורים (FU-1) מול הכרעות-יו"ר (FU-2) דרך db.panel_rounds_vs_chair ומדווח split-rate+auto-precision לכל סבב (מגמת הלולאה: ככל שהרובריקה משתפרת precision נשמר ו-split יורד); משתף את analyze_pairs של FU-4 (מקור-יחיד). שתי המדידות מדווחות anon-stability (מבחן-אנונימיזציה #81.7) כמטריקת-בריאות נגד echo-chamber. --batch/--limit/--concurrency. ידני — לפני חיווט --apply (live) / תקופתי — מעקב-לולאה (captured)
halacha_rubric_distill.py python #133/FU-4 — זיקוק-רובריקה PROPOSE-ONLY. מצליב halacha_panel_rounds (FU-1, הצבעות+נימוקים) מול הכרעות-היו"ר (FU-2, seeds ב-halacha_goldset batch chair-live) דרך db.panel_rounds_vs_chair (read-only), מנתח דטרמיניסטית כשלים שיטתיים (false-keep/false-drop, פיצולים-שהוכרעו, שיעור-מחלוקת-עם-היו"ר לכל שופט), ומציע KEEP_SYSTEM v2 + exemplars מופשטים (claude_session מקומי, אפס עלות) כדוח-diff ל-data/learning/rubric-proposal-<ts>.md. לעולם לא auto-apply — אימוץ v2 = עריכה אנושית של הקבוע דרך PR (INV-LRN1); exemplars מופשטים בלבד (INV-LRN5); הסיגנל היחיד = הכרעת-יו"ר, לא הצבעות-פאנל (anti-echo). מתחת ל-12 זוגות → "אין מספיק נתונים". --no-llm (סטטיסטיקה בלבד) / --limit N. חובה מקומי. תקופתי — אחרי שהצטברו הכרעות-יו"ר על מחלוקות-פאנל
halacha_rule_role_backfill.py python INV-DM7 — backfill חד-פעמי: מסווג-מחדש את ההלכות הישנות (rule_type IN ('binding','persuasive') — ערכי-סמכות שנשמרו במסווה תפקיד לפני פיצול הצירים) לאחד מחמשת תפקידי-הכלל (holding/interpretive/procedural/application/obiter) דרך claude_session המקומי (אפס עלות). לא נוגע בסמכות (נגזרת מ-precedent_level). --apply (ברירת-מחדל dry-run) / --limit N / --concurrency. כותב backup CSV ל-data/audit/ תחילה. fail-safe (פריט שנכשל → נשמר ערך ישן). חובה מקומי (claude_session). ידני חד-פעמי אחרי deploy של פיצול-הסמכות
halacha_batch_reconcile.py python #82.7 — dedup חוצה-פסקים offline (שמרני, dry-run בלבד). dedup-on-insert משווה רק תוך-פסק; כאן סף מחמיר (cosine ≥0.95, --cosine) ולא-הרסני: מאתר זוגות הלכות near-duplicate בין פסקים שונים (pgvector <=> exact) עם איתות לקסיקלי (Jaccard/Levenshtein) ומדווח ל-CSV ב-data/audit/ לסקירת היו"ר. לא מדלג/ממזג/מוחק. --include-pending. --link רושם את הזוגות שנמצאו כ-equivalent_halachot (parallel authority, #84.2 — קישור-מקביל ברמת-הלכה, לא ציטוט; idempotent, לא-הרסני). רץ עם venv של mcp-server. אומת: 800 הלכות → 5 זוגות (קושרו). ידני — דוח-סקירה / --link לקישור
calibrate_halacha_dedup.py python #82.1 — כיול ספי ה-dedup הלקסיקלי (#82.3) מול gold-set הניקוי. קורא halacha-cleanup-manifest-*.csv (זוגות duplicate↔survivor מתויגי-אדם), טוען טקסט-survivor מה-DB, ו-sweep של (jaccard_min × levenshtein_min) עם P/R/F1, מסמן את נקודת-העבודה המוגדרת. אימת ש-(0.55, 0.70) → precision 1.0 (אפס false-merge), recall 0.30 — מתאים לאיתות-משני שחוסם auto-approve. --manifest <path>. רץ עם venv של mcp-server חד-פעמי — כיול (בוצע 2026-06-06)
audit_corpus_integrity.py python בדיקה תקופתית של עקביות הקורפוס — 5 בדיקות SQL read-only על case_law ו-cases: (A) external_upload עם prefix פנימי ערר/בל"מ; (B) internal_committee חסר chair_name/district; (C) cases.practice_area מחוץ ל-{rishuy_uvniya, betterment_levy, compensation_197, ''}; (D) תיקים מוכרעים (final/exported/reviewed) ללא chair_name (chair ריק מפיל בשקט את העתק-הסופי לקורפוס-הפסיקה — INV-G1); (E) תיקי final חתומים שחסרים מקורפוס-הפסיקה הפנימי (internal_committee). כותב log מצטבר ל-data/logs/corpus_integrity_audit.log ובמצב הפרות שולח wakeup ל-CEO ב-Paperclip (best-effort, רק אם PAPERCLIP_API_URL+PAPERCLIP_API_KEY מוגדרים). דגל: --no-notify. Idempotent, יוצא 0. Cron יומי 07:00: 0 7 * * * /home/chaim/legal-ai/mcp-server/.venv/bin/python /home/chaim/legal-ai/scripts/audit_corpus_integrity.py 0 7 * * * (cron)
backfill_legal_arguments.py python Backfill legal_arguments לתיקים עם claims קיימים (TaskMaster #36). מקבץ פרופוזיציות גולמיות לטיעונים משפטיים מובחנים (~6-12 לכל צד) דרך argument_aggregator.aggregate_claims_to_arguments (Claude CLI). תומך --dry-run/--apply/--force/--case <num>.... חייב לרוץ מהמכונה המקומית (לא קונטיינר) — claude_session דורש Claude CLI ידני per-case (python scripts/backfill_legal_arguments.py --apply --case 1017-03-26)
upload_blam_decisions.py python חד-פעמי (2026-05-26) — העלאת 2 החלטות בל"מ ל-case_law (8126/24 סופר נוח, 8047/23 הרנון) דרך ingest_internal_decision ישיר, עוקף MCP server שטרם נטען מחדש אחרי הוספת proceeding_type. לא להריץ שוב חד-פעמי — להעביר ל-.archive/ בהזדמנות
process_pending_blam.py python חד-פעמי (2026-05-26) — הרצת metadata + halacha extraction על 2 החלטות בל"מ שעלו ב-upload_blam_decisions.py. עוקף MCP (אותו טעם). לא להריץ שוב חד-פעמי — להעביר ל-.archive/ בהזדמנות
ab_halacha_opus48.py python A/B לא-הרסני לחילוץ הלכות — מריץ מחדש חילוץ הלכות על פסק-דין בודד דרך מודל/effort נבחרים (AB_MODEL/AB_EFFORT, ברירת-מחדל claude-opus-4-8/xhigh) ומשווה לסטטיסטיקות ההלכות הקיימות ב-DB בלי למחוק/לכתוב כלום. משכפל את halacha_extractor.extract() (אותם פרומפטים, בחירת-צ'אנקים, אימות-ציטוט) ומחליף רק את קריאת ה-LLM ב-claude -p --model --effort. מפיק data/ab_halacha_<case>_<effort>.json. הרצה: DOTENV_PATH=/home/chaim/.env DATA_DIR=.../data .venv/bin/python scripts/ab_halacha_opus48.py <case_law_id>. ממצא 2026-05-31 (שטיין 1128-08-20): Opus 4.8@xhigh חילץ 51 מול 124 בייצור (100% quote-verified מול 96%) אך ביטחון מכויל-נמוך יותר (חציון 0.75 מול 0.82) — ולכן לא מקטין את תור-האישור-הידני תחת sweep אוטו-אישור conf≥0.78 (26 מול 24). שיפור איכות, לא צמצום-תור. ידני (החלטת מודל-חילוץ)
compute_ndcg.py python חישוב nDCG@10 על search_relevance_feedback (TaskMaster #50, Stage C). aggregation לפי search_type ולפי שבוע, כולל top-cited case_law ו-coverage %. דגלים: --k 10, --weeks 12, --pretty. read-only, פלט JSON. משמש גם את GET /api/admin/rag-metrics (מיובא inline) — שינוי חתימה ב-compute() ישבור את ה-endpoint ידני / cron עתידי לדיווח שבועי
backfill_multimodal_precedents.py python Backfill voyage-multimodal-3 page embeddings על רשומות case_law (external_upload + internal_committee) שחסרות precedent_image_embeddings. בונה אינדקס קבצים מ-data/precedent-library/ ו-data/internal-decisions/, מנסה התאמה לפי tokens של מספרי תיק (כולל parts-match לפורמטים שונים של Nevo doc-id). מדלג על רשומות בלי קובץ-מקור או עם MD בלבד (PyMuPDF לא מרנדר MD). תומך --dry-run (default) / --apply / --only external_upload|internal_committee / --limit N. רץ בקונטיינר (יש /data + Voyage env). הופעל 2026-05-26: 70 חסרים → 26 backfilled (503 pages, ~$0.21 voyage tokens), 44 אין-קובץ-מקור. ניתן להריץ שוב אחרי שיועלו עוד PDF/DOCX לספרייה ידני
monitor_halacha_quality.py python מנטר איכות חילוץ הלכות. בודק drift של avg(confidence) בין baseline היסטורי לחלון אחרון. מחזיר JSON מטריקות + alert ב-stderr אם drift > threshold (ברירת מחדל 5%). 2 סדרות: trusted (approved+published) ו-all_extracted. תומך --window N / --threshold X / --min-sample N / --silent / --exit-on-alert. רץ ב-container או מקומית עם mcp-server/.venv (אין תלות ב-LLM, רק SQL). תזמון מומלץ: 0 8 * * 1 (יום ראשון 08:00, שבועי) 0 8 * * 1 (לתזמן)
audit_training_corpus.py python audit של style_corpus — לכל החלטה: שדות מטא-דאטה מאוכלסים (summary/outcome/key_principles/appeal_subtype/subject_categories), קישור ל-documents (FK + chunks + embeddings). מפיק data/audit/corpus-YYYY-MM-DD.json + summary בקונסול. דרוש POSTGRES_URL או POSTGRES_*. אין תלויות חיצוניות מלבד asyncpg. רץ מהמכונה המקומית (לא קונטיינר) — חיבור ישיר ל-Postgres :5433 ידני / קדם-עבודה לפני enrichment של מטא-דאטה
backfill_style_exemplars.py python T1 (style-acquisition) — מאכלס style_exemplars מקורפוס דפנה (style_corpus + internal_committee chair=דפנה): מפצל לסעיפים (chunker._split_into_sections) → פסקאות (25-450 מילים) → embed (Voyage) → שמירה עם section/outcome/practice_area. מאפשר לכותב לאחזר פסקאות-בלוק אמיתיות של דפנה (T2/T3). מקור-סגנון בלבד (INV-LRN5). אידמפוטנטי (מנקה per-decision). --dry-run (default) / --apply. דורש POSTGRES_URL + Voyage. רץ מקומית (venv). ידני (python scripts/backfill_style_exemplars.py --apply)
ingest_bulletins.py python קליטת ארכיון העלון החודשי "עו"ד על נדל"ן" לקורפוס-הגילוי (X12) — כל PDF ב-data/bulletins/incoming/ מפוצל ע"י LLM למצביעי-פסיקה (digest_kind='decision') + מאמרים (digest_kind='article'), עם tag publication='עו"ד על נדל"ן', דרך bulletin_library.ingest_bulletin. idempotent (dedup per-item לפי content_hash; הרצה חוזרת מוסיפה רק חדשים); כשל בעלון אחד לא עוצר את ה-batch. רץ מהמכונה המקומית (LLM מקומי-בלבד) עם venv של mcp-server: mcp-server/.venv/bin/python scripts/ingest_bulletins.py [--dir PATH] [--limit N]. ידני, per-batch

תיקיית .archive/ — סקריפטים שהושלמו

סקריפטים חד-פעמיים שהפונקציונליות שלהם הוטמעה ב-MCP server או ב-API. נשמרים ב-git לצורך היסטוריה — אין להריץ אותם.

Script Original Purpose Superseded By
backfill_pattern_frequency.py עדכון תדירות דפוסי סגנון ב-DB web/app.py::_extract_pattern_variants()
batch_upload_training.py העלאת קורפוס אימון (16 קבצים) Web UI: /api/training/upload
benchmark_embeddings.py השוואת מודלי embeddings (voyage-3 vs voyage-4) הושלם — voyage-3-large נבחר
benchmark_new_vs_old.py השוואת Google Vision vs markdown קיים הושלם — בדיקה חד-פעמית לתיק 1130-25
decompose-decisions.py פירוק החלטות סופיות ל-12 בלוקים MCP: write_block(), write_all_blocks()
export-decision-docx.py ייצוא החלטה ל-DOCX MCP: export_docx()
extract-citations.py חילוץ ציטוטי פסיקה מבלוק י MCP service: references_extractor.py
extract-claims.py חילוץ טענות מבלוק ז MCP: extract_claims() + claims_extractor.py
extract_claims_8174.py חד-פעמי — חילוץ טענות חסרות לתיק 8174-24 אחרי timeout של האנליסט (43 טענות עורר נוספו 30/04/26) phase 1: claude_session async + 30min timeout + chunking סמנטי
extract_all_google_vision.py OCR בכמות עם Google Vision MCP: document_upload() pipeline
extract_originals.py חילוץ טקסט מ-PDF עם Claude Opus MCP service: extractor.py
extract_originals_ocr.py חילוץ OCR מלא מ-PDF MCP service: extractor.py
generate-embeddings.py יצירת embeddings לבלוקים ופסיקה אוטומטי — נוצרים עם יצירת בלוקים
link-claims-to-discussion.py קישור טענות לפסקאות דיון MCP service: qa_validator.py
proofread_training_corpus.py ניקוי Nevo מ-DOCX/PDF ל-Markdown MCP service: proofreader.py + Web UI
seed-appeals.py seeding תיקי ערר ראשוניים ל-DB MCP: case_create()
seed-knowledge.py seeding לקחים, ביטויי מעבר, פסיקה MCP: record_chair_feedback(), precedent_attach()
validate-decision.py ולידציה מול block-schema MCP: validate_decision() + qa_validator.py
run_curator_deepseek_test.sh A/B test #1 (2026-05-05) — Hermes Curator על CMP-78 דרך DeepSeek V4-Pro ב-provider:custom, ללא interaction. תוצאה: 6:33 דק׳, 5 ממצאי סגנון/לקסיקון, פי 3 מהיר מ-Sonnet baseline (CMP-80) ופי ~20 זול. הסקריפט נקודתי לתיק 1130-25 — לא להריץ שוב החלפת Curator לאדפטר DeepSeek מקומי (בתהליך)
run_curator_deepseek_test_v2.sh A/B test #2 (2026-05-05) — אותו run אבל עם interaction. תוצאה: 9:08 דק׳, 5 ממצאים, היחיד מ-4 הריצות שזיהה תוצאה עובדתית נכונה (קבלה חלקית). interaction נכשל ב-API ("Agent run id required" בריצה ידנית). החלפת Curator לאדפטר DeepSeek מקומי
run_curator_sonnet_rerun.sh A/B test #3 (2026-05-05) — ריצה חוזרת של Sonnet 4.5 על אותו CMP-78. תוצאה: 12:52 דק׳ (לעומת 20:13 בריצה המקורית — כי בלי לולאת interaction.json). זיהה תוצאה שגויה ("דחייה") בעקביות עם הריצה המקורית — Sonnet עקבי-בטעות, DeepSeek אקראי. בדיקה חד-פעמית — לא להריץ שוב
ingest_incoming_batch.py python קליטת batch של החלטות ועדת ערר מ-data/precedents/incoming/ דרך המסלול הקנוני (ingest_internal_decision) + חילוץ מטא-דאטה לכל תיק (המסלול הפנימי לא מתזמן metadata — INV-ING3). רצף (לא מקבילי, להימנע מעומס CLI). רשימת DECISIONS נערכת ידנית לכל batch. config מ-~/.env. תומך תהליך project_precedent_incoming_workflow.
drain_halacha_queue.py python ריקון תור חילוץ ההלכות (process_pending_extractions kind='halacha') ב-batches של 4 עד שהתור ריק (2 סבבים ריקים). רץ רק בחלון-לילה 23:0005:00 שעון ישראל (_in_window, zoneinfo DST-safe — המכונה UTC); מחוץ לחלון ===SKIP===, ונעצר ===STOP=== כשהחלון נסגר (השאר ממשיך בלילה הבא, FIFO+checkpoint). env: HALACHA_DRAIN_WINDOW_START/_END/HALACHA_DRAIN_TZ. kill-switch /operations: בודק is_drain_disabled בעלייה וגם בתחילת כל סבב — כיבוי באמצע-ריצה עוצר את הלולאה בגבול-הסבב הבא (התהליך עצמו נהרג מיד דרך ה-UI-toggle/סופרוייזר). חילוץ-הלכות נשאר על claude_session (לא Gemini). self-heal ל-orphaned processing. ההלכות נוחתות pending_review (שער-יו"ר). חילוץ תיק-בודד שהיו"ר מבקש רץ מיד דרך ה-CEO (precedent_extract_halachot) ואינו מגודר כאן.
legal-halacha-drain.config.cjs pm2/js תזמון חלון-לילה של drain_halacha_queue.py (cron UTC 10 20,21,22,23,0,1,2,3 * * * = superset שמכסה את 23:0005:00 ישראל בקיץ ובחורף; הסקריפט גוזם לחלון המדויק ב-zoneinfo). דקת-הצתה :10 (לא :00) כדי לא לחלוק דקה עם metadata-drain (:00) או supervisor (:05) — מונע deadlock של DDL-המיגרציה כששני דריינים עולים יחד. HALACHA_DRAIN_CRON לעקיפה. ירייה כל שעה גם מחדשת one-shot שמת באמצע (advisory-lock הופך חפיפה לבטוחה). דורש claude CLI. התקנה: pm2 start scripts/legal-halacha-drain.config.cjs && pm2 save.
halacha_drain_supervisor.py python מנהל-בריאות קבוע ל-legal-halacha-drain (אפס צריכת-Claude — קורא DB/לוגים/pm2 ומצית את הדריינר הקיים). טיק יחיד: מכבד is_drain_disabled בעדיפות עליונה — אם כבוי ב-/operations עוצר את הדריינר ולא מצית · מצית כשבטל+תור≠ריק · restart ל-run תקוע (liveness לפי checkpoints-per-chunk, לא mtime-לוג שמתעדכן רק בסיום תיק ~10 דק') · backoff ב-rate-limit (429 + parse איפוס, מגודר-טריות; cost=0=מנוי) — אך לא ממתין בעיוורון לשעה המדווחת: בכל טיק-בהמתנה מריץ quota_available() (בדיקת claude -p זעירה, cost=0) ומתחדש מיד כשהמכסה באמת חזרה (≤ טיק אחד), כי claude.ai משחרר לרוב מוקדם מהמדווח · מאמת ש-staging מתחייב. BURST (חלון "רוץ ברצף עכשיו" ידני): מקור-אמת = drain_controls.burst_until ב-DB — אותו ערך ש-/operations קורא/כותב (G1 מקור-יחיד, G2 בלי מסלול מקביל); בעתיד→חלון מורם, אחרת חלון-לילה 23-05; פג-תוקף אוטומטי במועד. תת-פקודות: tick (ברירת-מחדל), burst-on [--until], burst-off, status.
legal-halacha-supervisor.config.cjs pm2/js תזמון כל 15 דק' של halacha_drain_supervisor.py (cron 5-59/15 * * * * = :05,:20,:35,:50, HALACHA_SUPERVISOR_CRON לעקיפה; דקת-הצתה :05 כדי לא לחלוק דקה עם metadata-drain :00 או halacha-drain :10 — מונע deadlock של DDL-המיגרציה). autorestart:false (one-shot per tick). מצב-state ב-~/halacha-drain-monitor/ (מחוץ ל-repo). התקנה: pm2 start scripts/legal-halacha-supervisor.config.cjs && pm2 save.
ingest_digests_batch.py python קליטת batch של יומוני "כל יום" מ-data/digests/incoming/ דרך המסלול העצמאי של קורפוס-הגילוי (digest_library.ingest_digest) — חילוץ-LLM (תג-מושג, כותרת-הלכה, מראה-מקום, שני-תאריכים), embedding יחיד, ו-autolink לפסק המקורי (X12/INV-DIG3). רצף (לא מקבילי). מזהה-יומון+תאריך נגזרים משם-הקובץ; העלון החודשי מדולג. לא מעביר קבצים — ה-DB (content_hash) הוא מקור-האמת היחיד; הרצה חוזרת מדלגת על קיימים (exists). config מ-~/.env.
drain_digests.py python ריקון תור ההעשרה של יומונים (X12): מעבד כל digest בסטטוס pending דרך digest_library.enrich_digest (חילוץ-LLM Sonnet + embedding + autolink). מקבילי (CONCURRENCY=3, env-tunable), idempotent. מוסיף ~/.local/bin ל-PATH כדי שה-claude CLI יימצא תחת cron. בודק דגל drain_controls('legal-digest-drain') ב-startup → no-op כשכבוי מ-/operations.
legal-digest-drain.config.cjs pm2/js תזמון כל שעתיים של drain_digests.py (cron 12 */2 * * *, DIGEST_DRAIN_CRON לעקיפה; דקת-הצתה :12 כדי לא לחלוק דקה עם metadata-drain :00 — מונע deadlock של DDL-המיגרציה) — הועבר מ-crontab של המערכת ל-pm2 כדי שיופיע ויהיה שליט בדף /operations (הרץ-עכשיו/הפעל/כבה). autorestart:false (one-shot per tick). דורש claude CLI + VOYAGE_API_KEY. התקנה: pm2 start scripts/legal-digest-drain.config.cjs && pm2 save.

| renumber_cases.py | python | מיגרציה חד-פעמית (בוצעה 2026-06-12) — תיקון 11 מספרי-תיקים לפורמט קנוני NNNN-MM-YY (הוספת ספרות-חודש; 1046-26→1024-02-26 תיקון-סידורי). רץ על ה-host (לא בקונטיינר): DB pool של האפליקציה + mcli (MinIO) + Gitea API + Paperclip DB. אטומי per-case עם גיבוי ל-data/audit/ ואימות-אחרי. FK-ים על cases.id (UUID) לא נגעו; משכתב כל עמודה עם cases/{old}/ (file_path וגם image_thumbnail_path שהוא storage-key בלי /data), מנרמל זהות חוצת-קורפוס (case_law/style_corpus/style_exemplars/citations — לא תוכן/full_text), מעביר מפתחי-MinIO ב-3 buckets (legal-immutable=WORM copy-only), משנה-שם repo ב-Gitea, ומעדכן שם-פרויקט ב-Paperclip. dry-run כברירת-מחדל; --apply --tier clean\|archive. מיצוי — לא להריץ שוב (ה-MAPPING היסטורי). | חד-פעמי — בוצע |

סקריפטים שנמחקו (git history בלבד)

Script Reason
import-final-decisions.py מיגרציה הושלמה — כל ההחלטות ב-data/training/
compare_extractions.py בדיקה חד-פעמית לתיק 1130-25
decompose-decisions-v2.py כפילות של v1
extract_google_vision.py hardcoded לתיק בודד
extract_google_vision_single.py wrapper חד-פעמי
test-search.py סקריפט דיבאג