16 KiB
X5 — Audit-Trail ועקיבוּת-מקור (Provenance)
קובץ-תחום זה כפוף ל-חוקת המערכת ומגדיר את חוזה העקיבוּת וה-audit-trail (TARGET) של עוזר משפטי: (א) כל תוצר מסיוע-AI (בלוק-טיוטה, תוצאת-אחזור, הצעת-curator) מתעד מה הפיק אותו (מקורות/נתונים/מודל); (ב) כל סמכות מצוטטת בהחלטה פתירה חזרה לקורפוס; (ג) שלמות-הרשומה לאורך זמן — החלטה/רשומה שלמה ובלתי-משתנה אלא דרך שינויים עקיבים ומיוחסים (היסטוריית git + Track Changes). הקובץ אוכף את INV-G9 (עקיבוּת + audit-trail) ואת INV-G5 (attribution באחזור).
TARGET, לא תיאור-מצב. היכן שהקוד בפועל סוטה מהיעד — מתועד כ-audit-finding (§5), תסמין לתיקון, לא התנהגות תקינה. כל טענה על הקוד מצוטטת
file:line.
כשל-השורש שהקובץ מייבש: קיימים רכיבי-עקיבוּת נקודתיים (commit git לפלטים · model_used לכל בלוק ·
decision_paragraphs.citations · גרף-ציטוטים · telemetry של חיפושים), אך אין רשומת-provenance
מאוחדת מקצה-לקצה שמקשרת בלוק-החלטה → קטעי-הקורפוס/הגנרציות שהפיקו אותו, וטבלת ה-audit_log
אינה מתועדת בפועל לרוב פעולות ה-AI.
1. שלוש שכבות העקיבוּת (TARGET)
| שכבה | מה צריך להירשם | היכן (קיים / יעד) |
|---|---|---|
| A — provenance של תוצר-AI | לכל בלוק-טיוטה/תוצאת-אחזור/הצעת-curator: מודל, סוג-גנרציה, וקטעי-המקור (chunks/precedents) שהוזנו | קיים חלקית: decision_blocks.model_used/generation_type/temperature (db.py:326-328); חסר קישור בלוק→קטעי-מקור |
| B — עקיבוּת ציטוט→קורפוס | כל סמכות מצוטטת פתירה ל-case_law_id/document_id + locator |
קיים: decision_paragraphs.citations JSONB [{case_law_id,text,type}] (db.py:343); גרף precedent_internal_citations (db.py:937-947) |
| C — שלמות-רשומה לאורך זמן | החלטה/מסמך שלם ובלתי-משתנה אלא דרך שינוי עקיב ומיוחס | קיים: commit git לכל פלט (git_sync.commit_and_push); Track Changes ב-revisions (06-export §3) |
2. רכיבי-העקיבוּת הקיימים (מאומת file:line)
- קיבוע-פלט ב-git. כל כתיבת-DOCX/עדכון-תיק מקובעת בהיסטוריית-git של תיקיית-התיק:
export_docx(drafting.py:408),export_interim_draft(drafting.py:536),apply_user_edit(drafting.py:582),revise_draft(drafting.py:695), עדכון-תיק (cases.py:387), הוספת-מסמך (documents.py:86) — כולםgit_sync.commit_and_push(...)(git_sync.py:75). זו שכבת ה-audit-trail של שלמות-הפלט (שכבה C). - provenance של מודל לכל בלוק.
decision_blocksנושאmodel_used/generation_type/temperature(db.py:326-328), הנכתבים ב-upsert של ה-block-writer (block_writer.py:1017-1034,_build_result:400-407). מתעד איזה מודל הפיק את הבלוק (שכבה A — חלקי). - עקיבוּת ציטוט ברמת-סעיף.
decision_paragraphs.citations(db.py:343) שומר[{case_law_id, text, type}]— כל ציטוט בסעיף מצביע ל-case_law(שכבה B). telemetry ממנף זאת ל-"cited == relevant" (telemetry.py:18-23). - גרף-ציטוטים פנימי.
precedent_internal_citations(db.py:937-947) רושם קשת החלטה→החלטה מצוטטת (resolved ל-case_lawאו stub); נחשף דרךextract_internal_citations/list_internal_citations/list_incoming_citations(citations.py:40,81,112). ON CONFLICT DO NOTHING → idempotent (citations.py:54). - locator פתיר בכל תוצאת-אחזור. כל span מוחזר נושא מזהה-מקור + locator
(03-retrieval INV-RET5,
search.py:77-86,322-343); הלכות נושאותsupporting_quote(db.py:652) +page_number(db.py:631,711,729). - telemetry של חיפושים.
telemetry.log_search→search_logs(telemetry.py:105,search.py:62,118,190,271) רושם query/practice_area/top_case_law_ids — תצפית על מה נשלף, fire-and-forget (telemetry.py:8-12,100-101). - לקחים ופידבק מיוחסים.
decision_lessons.source(db.py:208: manual/curator/chair/ style_analyzer) ו-chair_feedback.lesson_extracted/applied_to(db.py:458-459) מתעדים את מקור הלקח (07-learning.md). - טבלת
audit_log(פעולה כללית).log_action(action, case_id, document_id, details, actor)(audit.py:18-44) →audit_log(db.py:159-167, אינדקסים:168-170). קיימת, אך נכתבת כיום כמעט-ורק ב-case_subtype_override(cases.py:203) — ראה §5.
3. Invariants של התחום
INV-AUD1: כל תוצר מסיוע-AI מתעד את ה-provenance שלו (→G9)
כלל: כל תוצר שנוצר בסיוע-AI — בלוק-טיוטה, תוצאת-אחזור, הצעת-curator — רושם את מקורו:
איזה מודל הפיק אותו, באיזה סוג-גנרציה, ואילו קטעי-מקור (chunks/precedents/מסמכי-תיק)
הוזנו אליו. הרשומה ניתנת-לביקורת בדיעבד (מי/מתי/ממה).
מקורות: Council of Europe / CEPEJ — European Ethical Charter on AI in judicial systems
(2018, transparency/traceability + user-control) · NCSC/JTC — Principles & Practices for AI Use
in Courts (auditable AI output) · ISO 15489-1:2016 (records authenticity — metadata about
creation) | סטטוס: verified
אכיפה: decision_blocks.model_used/generation_type/temperature בכל upsert של בלוק
(block_writer.py:1017-1034); telemetry על כל חיפוש (telemetry.py:105); יעד נוסף: קישור
מפורש בלוק→קטעי-מקור (provenance edges) + כתיבת audit_log.log_action לכל גנרציה. אוכף את
G9.
הפרה ידועה (GAP): ה-provenance קיים חלקית — model_used נרשם לכל בלוק, וה-commit ב-git
מקבע פלטים, אך אין רשומה מאוחדת שמקשרת בלוק-החלטה לקטעי-הקורפוס/הגנרציות שהזינו אותו, וטבלת
audit_log כמעט-ולא נכתבת לפעולות-AI (רק case_subtype_override, cases.py:203) → יעד
(§5).
INV-AUD2: רשומה שמורה שלמה ובלתי-משתנה אלא דרך שינוי עקיב ומיוחס (→G9, שלמות-רשומה)
כלל: החלטה/רשומה שמורה היא שלמה ובלתי-משתנה — כל שינוי בה נעשה רק דרך מנגנון עקיב
ומיוחס (commit git עם הודעה + actor, או Track Changes מיוחסות), ולא דרך דריסה שקטה. ניתן
לשחזר את מצב-הרשומה בכל נקודת-זמן ולזהות מי שינה מה ומתי.
מקורות: ISO 15489-1:2016 (§5.2.2 — integrity: records protected against unauthorized
alteration; אמינות/שלמות-רשומה) · Council of Europe / CEPEJ (2018, traceability) · DAMA-UK —
Six Primary Dimensions for Data Quality (2013, consistency/integrity over time) | סטטוס: verified
אכיפה: קיבוע git לכל פלט (git_sync.commit_and_push — drafting.py:408,536,582,695;
cases.py:387; documents.py:86) עם הודעה תיאורית; Track Changes ב-revisions עוקבות
(06-export §3); decision_blocks עם מפתח
קנוני UNIQUE(decision_id, block_id) (db.py:333) ו-updated_at. אוכף את
G9.
הפרה ידועה: עריכת-DOCX (revise_draft/apply_user_edit) הופכת את active_draft_path למקור-
בפועל בלי לעדכן את בלוקי-ה-DB חזרה — הנתון-הנגזר זוחל למקור-אמת ושלמות ה-DB מול המסמך-החי
נחלשת (06-export INV-EX1) → ממצא ל-audit.
INV-AUD3: כל סמכות מצוטטת פתירה חזרה לקורפוס (→G5)
כלל: כל סמכות-משפטית המצוטטת בהחלטה (פסק-דין, הלכה, מסמך-תיק) פתירה לרשומת-מקור בקורפוס
דרך locator יציב — case_law_id/document_id + מזהה-עמוד/chunk/quote. ציטוט שאינו פתיר אינו
תקין; הוא נחסם או מסומן לאימות-יו"ר. זהו צד-ה-attribution של INV-RET5.
מקורות: Pinecone — Implement multitenancy (metadata-locator לכל פריט מואנדקס) · RAG
attribution (Lewis et al., 2020, NeurIPS — pinned/non-leaking provenance) · ISO 8000 (Data
quality — completeness/identifiability) | סטטוס: verified
אכיפה: decision_paragraphs.citations [{case_law_id,text,type}] (db.py:343); גרף
precedent_internal_citations (db.py:937-947) פותר ציטוט ל-case_law קיים או שומר stub;
פורמטרי-האחזור מצרפים מזהה+locator (search.py:77-86,322-343). אוכף את
G5.
הפרה ידועה (GAP): הקישור קיים ברמת-הסעיף (decision_paragraphs.citations), אך אין אכיפה
שכל ציטוט בטקסט-הבלוק אכן מקושר לרשומת-קורפוס; ציטוט שהמודל ייצר בלי locator יכול לעבור בלי
חסימה אוטומטית — אימות נשען על שער-היו"ר (05-qa-review) → יעד.
4. רשומת-ה-provenance המאוחדת (TARGET)
היעד שמאחד את שלוש השכבות: לכל בלוק-החלטה נשמר, מעבר ל-model_used הקיים, קישור לקטעי-
המקור שהוזנו לגנרציה (chunk-ids/case_law_ids שהוחזרו מהאחזור והוצגו ל-writer) — כך שניתן לענות
"מאיזו פסיקה/מסמך נולד המשפט הזה?". המנגנון הקנוני המוצע: כתיבת audit_log.log_action
(audit.py:18) בכל גנרציה (action="write_block", details={model, generation_type, source_chunk_ids, retrieved_case_law_ids}) — הטבלה כבר תומכת ב-details JSONB + actor + case_id/document_id
(db.py:159-167). זה ממיר את ה-audit_log מ"כמעט-ריק" ל-audit-trail מקצה-לקצה, בלי טבלה חדשה
(תואם כלל-ההנדסה "סימטריה" — הרחבת מסלול קיים, חוקה §6).
5. Current vs Target — ממצאי-audit
ההבדלים בין הקוד בפועל ל-TARGET. אלו תסמינים, לא התנהגויות תקינות. כל פריט אומת מול הקוד.
audit_logקיימת אך כמעט-ולא נכתבת (INV-AUD1).log_action(audit.py:18-44) ו-טבלתaudit_log(db.py:159-167) מוכנות, אך הקריאה היחידה בפועל היאcase_subtype_override(cases.py:203) — אין רישום ל-upload/extract_claims/write_block/export(למרות ש-docstring שלlog_actionמונה אותם,audit.py:28). תסמין: אין audit-trail אחיד "מי עשה מה מתי" לרוב פעולות-ה-AI. יעד: קריאתlog_actionבכל פעולה משנה-מצב, כולל גנרציות.- אין קישור בלוק→קטעי-מקור (INV-AUD1).
decision_blocksמתעדmodel_used/generation_type(db.py:326-327) אך לא את ה-chunks/precedents שהוזנו לגנרציה. תסמין: אי-אפשר לשחזר מאיזו פסיקה/מסמך נגזר בלוק ספציפי. יעד: רשומת-provenance מאוחדת (§4). - ציטוט→קורפוס לא נאכף אוטומטית (INV-AUD3).
decision_paragraphs.citations(db.py:343) תומך בקישור, אך אין בדיקה שכל ציטוט בטקסט אכן פתיר ל-case_law. תסמין: ציטוט שהמודל ייצר בלי locator יכול לעבור. יעד: ולידציה שכל citation בעלתcase_law_idפתיר, אחרת flag לאימות-יו"ר. - שלמות ה-DB מול ה-DOCX-החי נחלשת אחרי עריכה (INV-AUD2). אחרי
revise_draft/apply_user_edit,active_draft_pathהופך מקור-בפועל בלי re-sync לבלוקים (db.py:185-188; 06-export INV-EX1). יעד: re-sync מהבלוקים או חוזה מפורש + health-check לגילוי drift. - telemetry בולעת שגיאות בשתיקה (תיעוד, לא הערכה).
log_searchswallow מכוון (telemetry.py:100-101) כדי שלא להפיל חיפוש — תקין כ-fire-and-forget, אך אינו audit-trail מהימן (רשומה עלולה ללכת לאיבוד בשקט). תואם את העיקרון "אין בליעה שקטה" רק כי זו telemetry-תצפית, לא רשומת-שלמות; ה-audit-trail המהימן הוא git (§2.1).
6. הפניות-אחיות
- 00-constitution.md — INV-G9 (עקיבוּת + audit-trail) · INV-G5 (attribution).
- 03-retrieval.md — INV-RET5 (locator פתיר בכל span — בסיס ל-INV-AUD3).
- 06-export.md — INV-EX2 (עקיבוּת בפלט) + commit git (INV-AUD2).
- 05-qa-review.md — שער-היו"ר שמאמת ציטוטים (משלים את INV-AUD3).
- 02-data-model.md —
decision_blocks/decision_paragraphs/case_law(הישויות שעליהן נשמרת ה-provenance). - 07-learning.md —
decision_lessons.source+chair_feedback(מקור הלקחים). - 01-ingest.md — קליטה שמייצרת את הקטעים שאליהם פותרים ציטוטים.