Files
legal-ai/docs/spec/gap-audit.md
Chaim 37dcb30604 docs: FU-14 GAP-54 — סגירה כ-resolved-by-FU-1 (איחוד קליטת-פסיקה)
אימות (G2 — לא לפתור מחדש): קליטת-הפסיקה כבר מאוחדת ע"י FU-1. שני מסלולי-
הפסיקה (precedent_library + internal_decisions) עוברים דרך
ingest.ingest_document הקנוני עם ולידציית-enums + citation-guard סימטריים
(מתועד ב-01-ingest §4). המסלול ה-3 (training→style_corpus) הוא קורפוס נפרד
במכוון. מאומת ב-test_unified_ingest (9/9). אין קוד — רק תיעוד סגירה.

Invariants: מאשר INV-ING1 + G2 מקוימים. doc-only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 19:02:55 +00:00

30 KiB
Raw Blame History

Gap-Audit — פערים בין המערכת הקיימת ל-spec

מסמך זה הוא מפת-הפערים הקנונית בין המערכת הקיימת (קוד ב-web/, mcp-server/, scripts/) לבין ה-invariants שב-docs/spec/. הוא תוצר של תת-פרויקט 2 (מיפוי-פערים), ומובחן מ-docs/audit-report.md הישן: ה-audit הוא דוח-מצב נקודתי, וזה ה-gap-map שמקשר כל ממצא ל-invariant מופר וליחידת-תיקון.

איך הופק: סקירה חוצת-קבצים של כל קבצי-הספ (00 + 0107 + X1X5) מול הקוד הקיים, 30.5.2026. כל ממצא נושא: invariant מופר (ה-G*/INV-* שהוא סותר), הערכת-severity, קבצים מושפעים (file:line), ו-תיקון מוצע.

הערה על severity/priority: דירוג ה-severity להלן הוא הערכה הנדסית (לפי סיכון לשלמות-נתונים, דליפה חוצת-קורפוס, ועקיפת שער אנושי). קביעת ה-priority בפועל — מה לתקן ראשון — היא של היו"ר. ה-severity מנמק; הוא אינו מכריע.


23 הממצאים

סטטוס מחזור-1 (עודכן 31.5.2026): כל 23 הממצאים נסגרו — FU-1..FU-8b מוזגו ל-main (PRs #11#23: FU-1/2a, FU-2b #15, FU-2c #17, FU-3, FU-4, FU-5 #18, FU-6, FU-7 #13, FU-8a #16, FU-8b #23). 122 בדיקות עוברות. הטבלה נשמרת כתיעוד-מקור; פירוט-ה-FU והסטטוס בסעיף "יחידות-תיקון".

ID כותרת invariant מופר severity קבצים מושפעים (file:line) תיקון מוצע
GAP-01 שני מסלולי ingest מקבילים שמתפצלים INV-ING1, G2 High precedent_library.py:88, internal_decisions.py:73 מסלול-קליטה קנוני יחיד; ישויות-אחיות חולקות פייפליין
GAP-02 ingest פנימי מדלג על חילוץ metadata INV-ING3, DM1, RET2 Critical internal_decisions.py:208 להוסיף request_metadata_extraction לכל סוג; חוסם indexing ריק
GAP-03 אין upsert דטרמיניסטי על מזהה קנוני INV-ING2, G3 Critical precedent_library.py, internal_decisions.py upsert על מפתח קנוני — קליטה חוזרת = update לא duplicate
GAP-04 ולידציית-enum א-סימטרית INV-G4 Medium precedent_library.py:131-134 להחיל אותה ולידציית practice_area/source_type בשני המסלולים
GAP-05 staging/derivation/citation-guard/multimodal/fallback א-סימטריים INV-ING1, G2 High 01-ingest §4 (שני המסלולים) מיזוג כל שלבי-העיבוד למסלול הקנוני האחד
GAP-06 case_number מנורמל בקריאה בלבד INV-G1, ID1 High db.py:1196-1211 נרמול בנקודת-הכתיבה; 8126-25→canonical
GAP-07 מספרי-תיק מעורבים (חודש/חסר) — reconciliation חד-פעמי INV-ID1 High data (cases, case_law) מיגרציה: canonical = הצורה הרשמית שהוקצתה [chair-confirmed]
GAP-08 ציטוט-מלא נשמר כ-case_number INV-DM2, ID2 Medium data (legacy pre-V15) ניקוי: ציטוט = שדה-תצוגה נגזר, לא מזהה
GAP-09 embedding אינו GENERATED (בניגוד ל-tsvectors) INV-DM3, RET, G6 High schema (chunks/case_law) re-index באכיפה — טריגר או GENERATED-equivalent בשינוי תוכן
GAP-10 דליפת הלכה חוצת-קורפוס INV-RET1, G5 Critical db.py:3168, db.py:3401, JOINs 3236-3238/3475-3477 להוסיף cl.source_kind ל-halacha_filters
GAP-11 אין eval harness / gold-set מתויג INV-RET4, G8 High telemetry.log_search_bg (היחיד) להקים eval harness + gold-set; precision/recall נמדד
GAP-12 search_decisions מזהיר אך לא חוסם practice_area חסר INV-RET, G5 High search.py:45-49, search.py:172-176 לחסום query בלי practice_area — ערבוב-תחום אסור
GAP-13 אין דגל searchable מפורש INV-DM1 Medium schema (case_law, chunks) דגל searchable שמסומן רק כשחוזה-השלמות מתקיים
GAP-14 backlog הלכות סמוי INV-QA1, G10 Medium (אין health-check) לחשוף pending_review ב-health-check / dashboard
GAP-15 שער-ייצוא נאכף-זרימה ולא נאכף-קוד INV-QA3, EX3 Critical drafting.py:384 export_docx קורא validate_decision + בודק export_blocked
GAP-16 neutral_background קריטי-אך-עובר INV-QA3 (05 §1.2) High qa_validator.py:70 בלוק-ו ריק/חסר = passed=False; חוסם ייצוא
GAP-17 active_draft_path נגזר זוחל ל-source-of-truth INV-EX1, AUD2 High db.py:189 DOCX = נגזר; re-sync בלוקים אחרי revise/apply_user_edit
GAP-18 audit_log כמעט לא נכתב INV-AUD1 High cases.py:203 (היחיד) כתיבת audit על upload/extract/write_block/export
GAP-19 אין קישור block→source-chunks INV-AUD1 High decision_blocks (model_used בלבד) לתעד אילו chunks/precedents הזינו כל בלוק
GAP-20 citation→corpus לא נאכף אוטומטית INV-AUD3 Medium decision_paragraphs.citations ולידציה שכל ציטוט בטקסט פתיר לקורפוס
GAP-21 cross-company sync ידני ולא-נאכף INV-MC1 Medium sync_agents_across_companies.py:387-389 אכיפת --apply אחרי שינוי-Master; להרעיש על דילוג adapter_type
GAP-22 אינטגרציית-Paperclip על נוהל ולא מחסום-קוד INV-INT1, INT3 Medium schema / lint (אין) אילוץ-schema נגד DB-insert; linter נגד httpx/curl גולמי
GAP-23 הספ עדיין לא מחובר לסוכנים INV-AG1 High .claude/agents/HEARTBEAT.md, agent files חובת קריאת 00-constitution + ספ-תחום לפני פעולה

ממצאי מחזור-2 (8 משטחי-האפליקציה מחוץ לצינור-הליבה) — GAP-24..62

הופקו בסקירת-קוד word-for-word (3031.5.2026) של 8 המשטחים: גבול-Paperclip, web-ui, מילוי-שדות, אחסון-ניתוחים, כלי-MCP (71), סוכנים+skills, deploy/env. ממצאי-ה-UI ברמת-הדף מפורטים ב-ui-audit.md. ה-invariants ב-X6X10. כל מחזור-2 פתוח (אומת 31.5.2026: creds plaintext קיימים, 2 לקוחות קיימים, אין get_appraiser_facts, analyst חסר 3 כלים).

ID כותרת invariant מופר severity קבצים מושפעים (file:line) תיקון מוצע
GAP-24 שני לקוחות Paperclip מקבילים (api מול client legacy) INV-INT4, G2 High web/paperclip_api.py, web/paperclip_client.py לקוח-API קנוני יחיד
GAP-25 גישת-DB ישירה ל-Paperclip (INSERT projects/issues/plugin_state) עוקפת API+audit INV-INT4, G2, G9 High web/paperclip_client.py להעביר הכל ל-API; להסיר מסלול-DB
GAP-26 company/agent IDs קשיחים — סותר X3 §1א INV-INT5, G2 High web/paperclip_client.py:36-62, web/app.py:3976, plugin worker.ts מיפוי מ-config/env
GAP-27 company_id נגזר בשתי דרכים (prefix מול fallback-map) INV-INT6, G2 Medium web/app.py (prefix), web/paperclip_client.py (_FALLBACK_APPEAL_TYPE_TO_COMPANY) פונקציית-גזירה יחידה
GAP-28 webhooks fire-and-forget בולעים שגיאות, ללא idempotency INV-INT7, G9, §6 Medium web/paperclip_api.py:87-205 event-id+dedup+רישום-כישלון
GAP-29 חוזה-אירוע webhook לא-מתוקען (eventType חופשי, default שקט) INV-INT8, G2 Medium web/paperclip_api.py:87+, plugin onWebhook enum-אירוע מגורס
GAP-30 ~60% endpoints ללא Pydantic → unknown → טיפוסים ידניים סוטים INV-UI1/UI2, G2/G4 High web/app.py (רוב), web-ui/src/lib/api/cases.ts:1-9 response models + api:types
GAP-31 PracticeArea/enum-סטטוס משוכפלים פרונט (3 מקומות, ערכים שונים) INV-UI1, G2 High web-ui/src/lib/practice-area.ts:12, lib/api/precedent-library.ts:26, components/precedents/practice-area.ts SSoT יחיד (ui-audit UI-A1/B1)
GAP-32 אין envelope עקבי; שגיאות נבלעות ב-UI INV-UI3/UI4, §6 Medium web/app.py (search ועוד), דפי-UI envelope אחיד + error-card
GAP-33 fallback SSE מסתיר כישלון; cache-TTL לא-תואם (5ש'↔300ש') INV-UI5 Low web-ui/src/lib/api/documents.ts:226-232 terminal-state מפורש
GAP-34 URLs קשיחים ב-UI/בק INV-UI3/ENV3 Low web-ui/.../app-shell.tsx:70, web/app.py:110 env
GAP-35 מקור-מילוי-שדות לא-מוצהר — מפוזר על 4 שירותים INV-FP1, G9 High precedent_metadata_extractor.py, halacha_extractor.py, ingest.py, db.py (recompute_searchable) טבלת-provenance SSoT (X8 §2)
GAP-36 אין שקיפות-UI למה מולא ע"י Opus מול ידני INV-UI6/FP1, G9 Medium web-ui/src/app/precedents/[id]/page.tsx:160-185 חיווי מקור-מילוי
GAP-37 placeholder "(טרם חולץ)" כמחרוזת-קסם לא-מתועדת INV-FP2 Low internal_decisions.py, precedent_metadata_extractor.py constant מתועד
GAP-38 שתי עמודות-סטטוס-חילוץ ב-case_law INV-DM1, G2 Medium db.py:603-606 סטטוס יחיד / extraction-jobs
GAP-39 legal_arguments ללא שער-אישור (בניגוד ל-halachot) INV-DM5, G10 High db.py:845-872 review_status ל-legal_arguments
GAP-40 legal_arguments.cited_precedents TEXT[] ללא FK → הזיות-LLM נבלעות INV-DM6, G9, §6 Medium db.py:858, argument_aggregator.py FK + דיווח-כישלון-קישור
GAP-41 appraiser_factsclaims התנגשות; appraiser_side default '' מעורפל INV-DM6 Medium db.py:549-576 CHECK + הבחנה document↔case
GAP-42 20+ enums כ-TEXT חופשי; אין embedding-provenance INV-DM6/DM4, G4 Medium db.py (source_type, rule_type, status…) CHECK-enums + עמודת-model
GAP-43 case_precedentscase_law טבלאות-פסיקה מקבילות legacy INV-G2 Low db.py איחוד/סימון-deprecated
GAP-44 אסימטריית extract/get — אין get_appraiser_facts (חילוץ-חוזר יקר) INV-TOOL4, G2 High mcp-server/.../drafting.py, server.py:563 להוסיף get_appraiser_facts
GAP-45 תור-חילוץ סמוי (pending-initial מול pending-review); אין extraction-job table INV-TOOL4/FP5, G10 Medium precedent_library.py, ingest.py *_extraction_status tool + טבלת-jobs
GAP-46 הרשאות-סוכן לא-מתועדות (analyst/researcher חסרי כלים) INV-AG3/TOOL6 High .claude/agents/legal-analyst.md, legal-researcher.md יישור tools↔instructions
GAP-47 draft_section ללא provenance (chunk→document/page); הנחיות-יו"ר ב-md ולא DB INV-TOOL4, G9 Medium mcp-server/.../drafting.py provenance בפלט + DB ל-directions
GAP-48 envelope-תשובה לא-עקבי (71 כלים: string/JSON/{error}) INV-TOOL1, G2 Medium mcp-server/.../server.py, tools/ wrapper {status,data,message}
GAP-49 6 כלי-חיפוש חופפים + precedent_search_library שם-מטעה INV-TOOL2, G2 Medium server.py (search_*), precedents.py:81 שם-מטעה תוקן (precedent_search_librarysearch_case_precedents, alias deprecated); 5 הנותרים = קורפוסים מובחנים בשמות סבירים
GAP-50 6 כלי-כתיבת-בלוק חופפים (draft_section/get_block_context/write_/save_) INV-TOOL2, G2 Medium server.py:500-616 draft_section deprecated→get_block_context (הכרעת-יו"ר); write_/save_ מובחנים בכוונה (זרימות שונות), לא מוזגו
GAP-51 set_outcome enum-mismatch (3≠4); אוצרות-מילים סותרות INV-TOOL1/UI1 Medium block_writer.py:442 מול lessons.py:11, workflow.py:145 SSoT יחיד ל-outcome
GAP-52 רוב הכלים לא-idempotent (case_create/document_upload/precedent_attach) INV-TOOL3, G3 Medium server.py, tools/ upsert/ON CONFLICT
GAP-53 אין limit-caps (precedent_library_list/search_*/list_chair_feedback) INV-TOOL5 Low tools/ clamp ל-max
GAP-54 3 מסלולי-קליטת-פסיקה ולידציה א-סימטרית; citation-guard לא-מתועד INV-ING1, G2 Medium precedent_library.py, internal_decisions.py נפתר ע"י FU-1 — שני מסלולי-הפסיקה (library+internal) עוברים דרך ingest.ingest_document הקנוני (ולידציית-enums + citation-guard סימטריים, מתועד ב-01-ingest §4); המסלול ה-3 (training→style_corpus) הוא קורפוס נפרד במכוון (סגנון, לא פסיקה). מאומת ב-test_unified_ingest.py
GAP-55 Infisical dead-code; מקור-config לא-מתועד (Coolify-only) INV-ENV2, G2 Medium mcp-server/.../config.py לתעד Coolify SSoT / לבודד Infisical
GAP-56 UUIDs קשיחים (company/agent) — תואם GAP-26 INV-ENV3/INT5 High web/paperclip_client.py:36-62, web/app.py:3976 config-driven
GAP-57 creds plaintext בברירת-מחדל (paperclip:paperclip) INV-ENV4, G9, §6 High web/paperclip_client.py:21, web/app.py:3789,3964 default ריק + fail-loud
GAP-58 GITEA_ACCESS_TOKENGITEA_TOKEN שני שמות; קטלוג חלקי INV-ENV1 Low web/gitea_client.py:22, git_sync.py:30, tools/cases.py:28 שם קנוני יחיד + קטלוג
GAP-59 chat-URL docs↔reality (10.0.1.1 מול host.docker.internal) INV-ENV3 Medium web/chat_proxy.py:49, chat_service/server.py יישור env + תיעוד
GAP-60 13/40+ env vars ב-drift-catalog; 8+ סודות בלתי-מנוטרים INV-ENV5/ENV1 Medium web/mcp_env_catalog.py קטלוג מקיף
GAP-61 URLs + /home/chaim קשיחים INV-ENV3 Low web/paperclip_client.py:31, app.py env/config
GAP-62 start.sh לא-נכשל-על-uvicorn; deploy-curl fire-and-forget INV-ENV2/§6 Low start.sh, .gitea/workflows/deploy.yaml health-gate + אימות-deploy

יחידות-תיקון מוצעות (Proposed Fix-Units)

23 הממצאים מקובצים ל-8 יחידות-עבודה קוהרנטיות. הקיבוץ נגזר מהעיקרון שרבים מהממצאים נפתרים יחד (כל פערי ה-ingest-asymmetry → יחידה אחת). זהו זרע למשימות TaskMaster ולתת-פרויקט 3 (שכבת-שלמות).

מחזור-1 הושלם (31.5.2026): FU-1..FU-8b כולם מוזגו ל-main. מחזור-2 (FU-9..15, להלן) נגזר מ-GAP-24..62 ופתוח.

FU-1 — איחוד מסלול-הקליטה (Unify ingest path)

  • מכסה: GAP-01, GAP-02, GAP-04, GAP-05
  • מספק invariants: INV-ING1, INV-ING3, INV-G2, INV-G4; (תורם ל-DM1/RET2 דרך GAP-02)
  • effort: L
  • תלויות: — (יסוד — FU-2/FU-3 נשענים עליה)
  • סוג: pure-code

FU-2 — קליטה idempotent + מזהים קנוניים

  • מכסה: GAP-03, GAP-06, GAP-07, GAP-08, GAP-13
  • מספק invariants: INV-ING2, INV-G3, INV-G1, INV-ID1, INV-ID2, INV-DM2, INV-DM1
  • effort: L
  • תלויות: FU-1 (מסלול אחד לפני upsert אחיד)
  • סוג: data-migration — GAP-07 reconciliation של case_number מעורב (chair-confirmed), GAP-08 ניקוי ציטוט-כ-מזהה; + code (upsert key, write-time normalize, דגל searchable)

FU-3 — re-index באכיפה בשינוי-תוכן

  • מכסה: GAP-09
  • מספק invariants: INV-DM3, INV-G6, INV-RET (freshness)
  • effort: M
  • תלויות: FU-1 (re-embed יושב בקליטה הקנונית)
  • סוג: data-migration — re-chunk/re-embed של רשומות קיימות + טריגר/אכיפה קדימה

FU-4 — הפרדת-קורפוס נאכפת בכל query

  • מכסה: GAP-10, GAP-12
  • מספק invariants: INV-RET1, INV-G5
  • effort: M
  • תלויות: — (עצמאי; דחוף — Critical leak)
  • סוג: pure-code

FU-5 — eval harness + נראות-בריאות

  • מכסה: GAP-11, GAP-14
  • מספק invariants: INV-RET4, INV-G8, INV-QA1, INV-G10 (נראות backlog)
  • effort: M
  • תלויות: FU-2 (gold-set יציב דורש מזהים קנוניים)
  • סוג: pure-code + chair-decision — הגדרת gold-set מתויג דורשת אישור היו"ר (מה "תוצאה נכונה" לכל query)

FU-6 — שערי-QA נאכפים-קוד (Code-enforced gates)

  • מכסה: GAP-15, GAP-16
  • מספק invariants: INV-QA3, INV-EX3, INV-G10
  • effort: S
  • תלויות: — (עצמאי; חוסם עקיפת-ייצוא)
  • סוג: pure-code

FU-7 — Audit-trail + provenance (זרע תת-פרויקט 3)

  • מכסה: GAP-17, GAP-18, GAP-19, GAP-20
  • מספק invariants: INV-AUD1, INV-AUD2, INV-AUD3, INV-EX1, INV-G9
  • effort: L
  • תלויות: FU-1 (provenance נלכד בקליטה/כתיבה הקנונית)
  • סוג: pure-code (schema-additive) — חלק מ-GAP-17 דורש data-backfill קל לסנכרון בלוקים↔DOCX קיימים

FU-8 — מחסומי-תהליך הופכים למחסומי-קוד

  • מכסה: GAP-21, GAP-22, GAP-23
  • מספק invariants: INV-MC1, INV-INT1, INV-INT3, INV-AG1
  • effort: M
  • תלויות: ה-spec גמור (GAP-23 דורש קבצי-ספ יציבים לחבר לסוכנים)
  • סוג: pure-code + chair-decision — GAP-23 (חיבור ספ לסוכני-Paperclip) הוא prerequisite לתת-פרויקט 5 ומשנה התנהגות-סוכן בייצור
  • סטטוס: FU-8a (GAP-21/22, PR #16) + FU-8b (GAP-23, PR #23) מוזגו.

— מחזור-2 (FU-9..15): 8 משטחי-האפליקציה מחוץ לצינור-הליבה. כולם פתוחים. —

FU-9 — לקוח-Paperclip קנוני

  • מכסה: GAP-24..29 · invariants: INV-INT4INT8 · effort: L · תלויות: X7 יציב
  • סוג: code — איחוד 2 הלקוחות, הסרת מסלול-DB, IDs מ-config, company_id יחיד, webhook idempotency+enum

FU-10 — חוזה UI↔API + design-system SSoT

  • מכסה: GAP-30..34 + ui-audit (UI-A1..D6) · invariants: INV-UI1UI6 · effort: L · תלויות:
  • סוג: code — Pydantic models+api:types, SSoT ל-enums/תוויות/tones, helpers משותפים, ניקוי redundancy

FU-11 — מילוי-שדות מוצהר + שקיפות-UI

  • מכסה: GAP-35..37 · invariants: INV-FP1FP5, UI6 · effort: M · תלויות:
  • סוג: code — טבלת-provenance SSoT, formalize placeholder, חיווי "מולא-ע"י-Opus" + searchable + pending ב-UI

FU-12 — חיזוק אחסון-הניתוחים

  • מכסה: GAP-38..43 · invariants: INV-DM4DM6 · effort: M · תלויות: FU-1
  • סוג: code + data-migration קל — provenance, שער-אישור ל-legal_arguments, CHECK-enums, FK, איחוד case_precedents

FU-13 — סוכנים + skills — נסגר (2026-06-06)

  • מכסה: GAP-46 (מרחיב GAP-23) · invariants: INV-AG3, INV-TOOL6 · effort: S · תלויות: ה-spec יציב
  • סוג: code/docs — שלמות-הרשאות (tools↔instructions), DRY-boilerplate, dedup-skills
  • סטטוס: הכרעת-יו"ר "היבריד". התברר שהפער ב-31.5 היה רחב מדי (יוחס לפי תיאור-תפקיד, לא הוראות בפועל). researcher כבר היה תקין (מיושן ב-spec). analyst קיבל aggregate_claims_to_arguments + שלב 7 ("שלב 1"); extract_references/extract_internal_citations נשארו אצל researcher (מטלת-מחקר, לא analyst). עודכן X4 §2א.

FU-14 — חוזה כלי-ה-MCP

  • מכסה: GAP-44,45,47..54 · invariants: INV-TOOL1TOOL5 · effort: L · תלויות: FU-1
  • סוג: code — envelope אחיד, מיזוג חיפוש/בלוקים, idempotency, limit-caps, get-symmetry, set_outcome SSoT
  • סטטוס חלקי (פרוסה 1, 2026-06-06): GAP-44 — נוסף get_appraiser_facts (ה-get המקביל ל-extract, INV-TOOL4); GAP-53 — נוסף _clamp_limit (תקרה 200, INV-TOOL5) על ~13 כלי list/search + הוספת limit ל-list_chair_feedback (שהיה ללא תקרה).
  • סטטוס חלקי (פרוסה 2, 2026-06-06): GAP-52 (INV-TOOL3 idempotency) — case_create/precedent_attach/document_upload מחזירים קיים במקום כפילות (בדיקת-מפתח ברמת-אפליקציה; document_upload לפי SHA-256 → מדלג OCR/embed כפול); GAP-45 (INV-TOOL4 visibility) — נוסף extraction_status שחושף עומק תור-החילוץ (metadata/halacha) + גיל הבקשה הוותיקה.
  • סטטוס חלקי (פרוסה 3, 2026-06-06): GAP-51 (set_outcome SSoT, הכרעת-יו"ר "3 תוצאות + הוצאת betterment_levy") — קנוני rejection/partial_acceptance/full_acceptance ב-lessons.VALID_OUTCOMES; OUTCOME_LABELS_HE (עברית-ב-UI SSoT); canonical_outcome() ל-legacy; betterment_levyPRACTICE_AREA_OVERRIDES (override לפי practice_area); block_writer/set_outcome/drafting/web-ui יושרו; נתונים נורמלו (9 שורות + גיבוי).
  • סטטוס חלקי (פרוסה 4, 2026-06-06): GAP-47 (חלק provenance, INV-TOOL4/G9)draft_section חושף בפלט document_id+page+score לכל קטע ב-case_documents/precedents (ה-provenance כבר נשלף ב-search_similar ונזרק; כעת מוחזר), כך שהכותב יכול לעקוב אל המקור ולצטטו. תוספתי, לא-שובר. נותר ב-GAP-47: העברת הנחיות-יו"ר מ-analysis-and-research.md ל-DB (get_chair_directions) — שינוי-מסלול גדול יותר הנוגע ל-UI של דפנה ולזרימת-האנליסט; לפרוסה נפרדת.
  • סטטוס חלקי (פרוסה 5, 2026-06-06): 🔄 GAP-48 (envelope אחיד, INV-TOOL1) — תחילת מיגרציה הדרגתית. נוצר tools/envelope.py כ-SSoT יחיד (ok/empty/err{status,data,message}, status מבחין הצלחה/ריק/שגיאה) המחליף 3 מוסכמות סותרות (raw payload / {error} / {status,message} אד-הוק) ו-5 עותקי _ok/_err משוכפלים. משפחת-החיפוש הראשונה הומרה (search_decisions/search_case_documents/find_similar_cases/search_internal_decisions); web/app.py מפרק דרך envelope_unwrap לשמירת חוזה-ה-API (X6) ללא-שינוי; טסט test_search_domain_scope עודכן לחוזה החדש (5/5 ). החלטה הנדסית: הדרגתי לפי-משפחה ולא big-bang — מפת-צרכנים (Explore) הראתה ש-server.py הוא pass-through, web-ui מבודד (/api/*), ורק 17 כלים נצרכים ישירות מ-app.py — כך הסיכון לסוכנים החיים ממוזער. נותרו ~73 כלים בפרוסות הבאות.
  • סטטוס חלקי (פרוסה 6, 2026-06-06): 🔄 GAP-48 — מיגרציה רוחבית. הומרו 10 משפחות נוספות ל-envelope: precedent_library (14), citations (3), internal_decisions (1), missing_precedents (4), training_enrichment (2), precedents (4), legal_arguments (2), cases (7), documents (8), workflow (9). בוטלו 5 עותקי _ok/_err משוכפלים (alias ל-SSoT, G2). עיקרון: envelope-status = הצלחת-הקריאה; תוצאה-עסקית (idempotent_existing/noop/...) ב-data. צרכני-app.py של cases/workflow/precedents חוּוטו דרך envelope_unwrap + בדיקת status=="error"→4xx, לשמירת חוזה-ה-API. כל הטסטים עוברים (182/182; test_corpus_constraints עודכן לחוזה). נותר: משפחת drafting (18 כלים — מסלול הפקת-ההחלטה) בפרוסה נפרדת.
  • פרוסה 7, 2026-06-06 — GAP-48 הושלם. משפחת drafting (18 כלים) הומרה ל-envelope. export_docx/revise_draft/apply_user_edit משתמשים ב-err-לכשל (כך שהסוכן והמשתמש רואים את הכשל ברמת-המעטפת), כש-failed_gates רוכב ב-data; 6 צרכני-app.py (get_decision_template/apply_user_edit×2/revise_draft/list_bookmarks/export_docx) חוּוטו עם בדיקת envelope-status; test_export_qa_gate עודכן לחוזה (182/182 עוברים). GAP-48 סגור — כל ~12 המשפחות אחידות.
  • פרוסה 8, 2026-06-06 — GAP-49 (החלק הקריטי). השם המטעה precedent_search_library (ציטוטים מצורפים-לתיק) שונה ל-search_case_precedents ובכך בוטל ההיפוך המסוכן מול search_precedent_library (ספרייה סמכותית — מקור CREAC). הישן נשמר כ-alias deprecated (ב-server.py) → אפס שבירה לסוכנים חיים. docstrings הובהרו; עודכנו app.py (typeahead) + legal-researcher/legal-writer docs + precedent_library docstring. 5 כלי-החיפוש הנותרים מחפשים קורפוסים מובחנים בשמות סבירים — לא בוצע rename-המוני (churn גבוה, ערך נמוך). 182/182 עוברים. ⚠ אחרי merge+deploy: סנכרון cross-company של doc-הסוכן (frontmatter search_case_precedents). נותר ב-FU-14: GAP-50 (מיזוג כלי-בלוק — נוגע בתהליך-הכתיבה, דורש הכרעת-יו"ר), GAP-54, GAP-47-חלק-ב.
  • פרוסה 9, 2026-06-06 — GAP-50 (הכרעת-יו"ר). מיפוי הראה שכלי-הבלוק אינם "כפילות מיותרת": write_block/write_all_blocks/save_block_content/write_interim_draft משרתים זרימות שונות (CLI/initial-draft מול תהליך-ה-writer "התיקון בקובץ, לא ב-DB"). הכפילות האמיתית היחידה — draft_section (הקשר לפי-סעיף, כמעט-נטוש) חופף ל-get_block_context (לפי-בלוק, קנוני). הוחלט (יו"ר): draft_section deprecated (docstring ב-server.py+drafting.py מפנה ל-get_block_context; draft-decision.md עודכן) — בלי הסרה, בלי מיזוג כלי-הכתיבה (שמירת תהליך-הכתיבה המכוון). 182/182 עוברים. GAP-49+50 סגורים. נותר ב-FU-14: GAP-54 (איחוד קליטת-פסיקה), GAP-47-חלק-ב (הנחיות-יו"ר→DB).
  • פרוסה 10, 2026-06-06 — GAP-54 (נסגר כ-resolved-by-FU-1). אימות (G2: לא לפתור מחדש): ingest.ingest_document הוא המסלול הקנוני; precedent_library ו-internal_decisions שניהם עוברים דרכו עם ולידציית-enums + citation-guard סימטריים (מתועד ב-01-ingest §4); training→style_corpus הוא קורפוס נפרד במכוון. 9/9 test_unified_ingest עוברים — אין קוד לכתוב. FU-14 כמעט-מלא: נותר רק GAP-47-חלק-ב (העברת הנחיות-יו"ר מ-analysis-and-research.md ל-DB) — פיצ'ר UI+זרימת-אנליסט נפרד, לא דחוף.

FU-15 — deploy/env/secrets

  • מכסה: GAP-55..62 · invariants: INV-ENV1ENV5 · effort: M · תלויות:
  • סוג: code/config + chair-decision (rotation סודות) — env-catalog SSoT, מקור-config יחיד, de-hardcode, drift מלא, start.sh עמיד
  • סטטוס חלקי: GAP-57 (creds plaintext, אבטחה CWE-798) נסגר ב-web/ 2026-06-06 — 3 מופעים ב-web/paperclip_api.py/paperclip_client.py/app.py הומרו ל-require_paperclip_db_url() fail-loud. נותרו 2 מופעים בסקריפטים מקומיים (sync_agents_across_companies.py, sync_missing_agent_skills.py) + GAP-55,56,5862 — לטיפול ב-FU-15 המלא.

סיכום סיווג לפי סוג-עבודה

  • pure-code (ללא מיגרציה): FU-1, FU-4, FU-6; הליבה של FU-7, FU-8.
  • דורש data-migration: FU-2 (case_number reconciliation, ניקוי ציטוטים), FU-3 (re-chunk/re-embed), backfill קל ב-FU-7 (סנכרון בלוקים↔DOCX).
  • דורש chair-decision: FU-5 (הגדרת gold-set), FU-8/GAP-23 (חיבור ספ לסוכנים); GAP-07 כבר chair-confirmed (canonical = הצורה הרשמית שהוקצתה).

רצף מומלץ (תלויות): FU-1 → FU-2 → FU-3; FU-4 ו-FU-6 במקביל (עצמאיים, Critical); FU-7 אחרי FU-1; FU-5 אחרי FU-2; FU-8 אחרי ייצוב-הספ. (מחזור-1 הושלם.)

מחזור-2 (FU-9..15) — 8 משטחי-האפליקציה: FU-10 (UI+design-system) ו-FU-15 (deploy/env) עצמאיים — ניתן במקביל. FU-9 (לקוח-Paperclip) אחרי X7. FU-12 (אחסון) ו-FU-14 (כלי-MCP) אחרי FU-1. FU-11 (מילוי-שדות) עצמאי. FU-13 (סוכנים+skills) אחרי ייצוב-הספ. סיווג: pure-code — FU-9/10/11/13/14; +data-migration קל — FU-12; +chair-decision — FU-15 (rotation סודות). priority בפועל — של היו"ר.