Files
legal-ai/docs/ia-audit-redesign.md
Chaim 80455af62d
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 5s
docs(ia): אבחון משטח-ההפעלה + ספ-יעד X17 — מפה אחת לכל הדפים/הכפילויות/הסנכרון (#127)
חיים (2026-06-11): "המערכת מסובכת מדי לתפעול." סריקת-עומק רב-סוכנית (18 סוכנים,
6 אשכולות × קטלוג→אימות-אדוורסרי→תכנון-יעד) מיפתה 34 משטחים ואימתה 37 ממצאים
(file:line). כולם ביטוי-UI אחד של G2 מופר שלא הורחב לשכבת-ה-UI.

תוצרים:
- docs/ia-audit-redesign.md — מצב-קיים: 5 מחלות-שורש (16 פערי-סנכרון, משטחי-אישור
  כפולים, 6 נתונים-שגויים, 5 מתים, כפילות-ניווט), ממצאים פר-אשכול בטבלאות.
- docs/spec/X17-information-architecture.md — ספ-יעד: INV-IA1..IA6 מרימים את G2
  (מקור-אמת יחיד) ו-G10 (שערים-אנושיים) לשכבת-המשטח; משטח-יעד (3 משטחי-intent +
  בעלים-יחיד לכל ישות); כל invariant מגובה ≥3 מקורות (NN/g, GOV.UK, USWDS,
  Rosenfeld/Morville, TkDodo/TanStack, Krug).
- docs/spec/README.md — אינדקס מעודכן (X1–X17 + ia-audit-redesign).

יחס לקיים (דאבל-צ'ק): ui-audit.md=שכבת-קוד (FU-10); X17=שכבת-IA מעל X6. לא כופל.
G10 נשמר 100% — מסירים משטח/ערוץ כפול, לא שער ("שער אחד"=מקום-אחד-להחליט).
עוצרים על המסמך (3א) — בקלוג-איחוד ב-#127.6, ביצוע באישור-יו"ר.

Invariants: מקיים G2 (מזהה+ממפה הפרות-UI), מקיים G10/INV-LRN1 (שערים נשמרים),
ממליץ דלתות-ספ ל-X6/07-learning/00-constitution (לאישור).

ref: #127 · feedback_operational_simplicity

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

18 KiB
Raw Blame History

IA-Audit & Redesign — מפת משטח-ההפעלה, כפילויות, וניווט-יעד

מה זה. אבחון שיטתי של משטח-ההפעלה של המערכת (כל דף/טאב/drawer/פונקציה) — מה כל אחד עושה, מה כפול, מה מת, מה מציג נתון שגוי, ואיך הכול מסתנכרן — ותכנון-מחדש של ארכיטקטורת-המידע (IA). נכתב לפי בקשת חיים (2026-06-11): "המערכת מסובכת מדי לתפעול… כל הדפים האלה מפוזרים ואין לי מושג מה כל אחד עושה והאם יש כפילויות."

היקף: משטח-ההפעלה (1א). ה-backend נכלל רק היכן שהוא גורם לכפילות/נתון-שגוי ב-UI. תוצר-אחות: ספ-היעד docs/spec/X17-information-architecture.md. יוזמה: TaskMaster legal-ai #127.

איך הופק: סריקת-עומק רב-סוכנית (18 סוכנים, 6 אשכולות × 3 שלבים — קטלוג → אימות-אדוורסרי מול הקוד → תכנון-יעד מגובה-מקורות). כל ממצא אומת ב-file:line; כל עקרון-תכנון מגובה ב-≥3 מקורות סמכותיים (ראה X17 §מקורות).

יחס למסמכים קיימים (דאבל-צ'ק — לא לכפול)

  • ui-audit.md — ביקורת-קוד פר-רכיב (enums כפולים, טיפוסים, helpers → FU-10). שכבה אחרת. מסמך זה הוא בשכבת ה-IA/הפעלה (אילו משטחים, מה כל אחד עושה, סנכרון, ניווט). חופף נקודתית ב-UI-C1 (3 דפי-פסיקה חופפים) ו-UI-D2/D3 (שקיפות-מקור) — מורחב כאן.
  • gap-audit.md — ממצאי-ארכיטקטורה (GAP→FU). מסמך זה ברמת-הדף.
  • X6-ui-api-contract.md — חוזה UI↔API (UI1UI6). X17 מוסיף שכבת invariants מעל X6.

1. תקציר-מנהלים — 5 מחלות-השורש

הסריקה אימתה 37 ממצאים על פני 34 משטחים. כולם נופלים ל-5 דפוסים:

# מחלת-שורש כמה מהות
D1 פערי-סנכרון ב-cache 16 mutation מבטל רק את ה-queryKey המקומי, לא את ה-aggregator/האח/ה-namespace השני → מונה/נתון תקוע ב-060ש' בין דפים. זהו G2 בשכבת ה-TanStack-Query cache.
D2 משטחי-כתיבה/אישור כפולים 6 (dup) + 2 confusing אותו datum נערך/מאושר ב-2 מקומות שכותבים ל-2 ערוצים. החריף: שני שערי-למידה (decision_lessons מול promote) ו-מתודולוגיה (PUT מול promote כותבים לאותה שורה — מירוץ lost-update). זו בדיוק ה"למה 2 שערים" של חיים.
D3 נתונים-שגויים/מטעים 6 KPI סופר דגל אינפורמטיבי-בלבד (applied_to_skill/findings_applied — "מזויף"); signature_phrases עם תווית-קרדינליות שקרית; מונה-תור שמתעלם מחברה לא-זמינה.
D4 משטחים/פונקציות מתים 5 endpoint queue/pending ללא צרכן; כפתור applied_to_skill; ז'רגון T7/T15; AuthorityBadge חסר בחיפוש.
D5 כפילות-ניווט הערות-יו"ר ב-2 דפים; /operations+/diagnostics אותו intent; precedents מול precedent-library.

התובנה המאחדת: רוב המחלות הן ביטוי-UI אחד של עקרון-על מופר — G2 (מקור-אמת יחיד / אין מסלולים מקבילים) — שמעולם לא הורחב לשכבת-ה-UI (cache + משטחים). זה בדיוק מה שחיים חווה כ"מסובך לתפעול": אותו מספר בשני מקומות, שני שערים לאותה החלטה, ומספרים שלא מתעדכנים.

ניווט-היעד (תמצית — מלא ב-X17)

שלושה משטחי-intent עם בעלים-יחיד, במקום פיזור-לפי-פורמט:

  1. /approvals = תיבת-ההחלטות-האנושית היחידה — המקום היחיד שבו פועלים על שער. דפים אחרים מצביעים למונה, לא משכפלים אותו.
  2. /operations = משטח-הקריאה-בלבד היחיד ("מה המכונה עושה") — בולע את /diagnostics.
  3. /settings = משטח-התצורה היחיד. ובתוך-התחום: החלטה=workspace אחד · למידה=תיבה+ערוץ+שער אחד · /methodology=עורך-הכללים היחיד · פסיקה=3 קורפוסים נפרדים אך מתפעלים אחיד.

כל ההצעות שומרות 100% מהשערים-האנושיים (G10/INV-LRN1). מסירים משטח/ערוץ כפול, לא שער. זו ההתאמה בין "פשטות-הפעלה" ל-G10.


2. ממצאים לפי אשכול

לכל אשכול: משטחים שקוטלגו · ממצאים מאומתים (file:line) · כיוון-היעד. הפירוט המלא (כל אלמנט + כל מקור) נשמר בפלט-הסריקה (data/audit/).

2.1 תיקים (/, /archive, /cases/[n], /compose)

3 משטחים · 2 ממצאים. מחלה: תוכן-ההחלטה מפוצל ל-2 משטחי-כתיבה עצמאיים + עורך-compose שלישי.

ID סוג ממצא file:line תיקון
CAS-1 sync-gap DraftsPanel (העלאת DOCX) לא מבטל ['decision-blocks']DecisionBlocksPanel מציג source_of_truth='blocks' תקוע; אזהרת-הסטייה לא מופיעה עד רענון ידני exports.ts:103-107 מול decision-blocks.ts:46-49; app.py:2673 add-invalidation
CAS-2 sync-gap useExportDocx לא מבטל ['decision-blocks'] — אותו שורש exports.ts:80-82 add-invalidation

יעד: workspace-החלטה אחד (block-editing + DOCX-פעיל) עם מחוון-מקור-אמת אחד בבעלות-המערכת ו-cache-slice משותף; אזור "השלמה והעברה" אחד לכל שערי-סיום-התיק.

2.2 אישורים + הערות-יו"ר (/approvals, /feedback)

3 משטחים · 6 ממצאים. מחלה: /api/chair/pending גוזר 4 מונים, אך כל משטח-משימה מבטל רק את ה-cache שלו ולא את ה-aggregator → התיבה והתג-בסרגל תקועים עד 60ש'.

ID סוג ממצא file:line תיקון
APR-1 sync-gap פתרון הערה ב-/feedback לא מבטל ['chair','pending'] → מונה /approvals והתג תקועים feedback.ts:105; chair.ts:36; app-shell.tsx:336 add-invalidation
APR-2 duplication הערות-יו"ר ב-2 caches (['feedback'] מול ['chair','pending']) ללא הצלבה — שני endpoints על אותה chair_feedback WHERE NOT resolved app.py:5650,5654 add-invalidation
APR-3 wrong-data דגימת-ההערות ב-/approvals יכולה להראות 5 ישנות בעוד המונה כבר 0 app.py:5650-5654; chair.ts:36 fix-data
APR-4 sync-gap ApprovalsBadge בסרגל תקוע אחרי פתרון-הערה/אישור-הלכה/העלאת-פסיקה app-shell.tsx:336; feedback.ts:105; missing-precedents.ts:256-258; precedent-library.ts:648,668 add-invalidation
APR-5 sync-gap אישור-הלכה לא מבטל ['chair','pending'] precedent-library.ts:648,668; app.py:5619-5620 add-invalidation
APR-6 sync-gap העלאת/סגירת פסיקה-חסרה לא מבטל ['chair','pending'] missing-precedents.ts:256-258; app.py:5636-5637 add-invalidation

יעד: /approvals = תיבת-הגייטים הקנונית היחידה; ['chair','pending'] = מקור-אמת יחיד ל"מה ממתין"; התג בסרגל = המונה היחיד; הערות-יו"ר יורד מהניווט-הראשי והופך לכרטיס-משימה מתוך התיבה.

2.3 פסיקה (/precedents, /missing-precedents, /digests, /precedents/[id], /graph)

13 משטחים · 5 ממצאים. מחלה: 3 קורפוסים אמיתיים ושונים — אך מתפעלים שונה ומבלבלים בשמות.

ID סוג ממצא file:line תיקון
PRE-1 confusing שני namespaces כמעט-זהים: /api/precedents/search (typeahead לתיק) מול /api/precedent-library/search (חיפוש-קורפוס) app.py:3109 מול 6057 clarify (rename/label)
PRE-2 dead GET /api/precedent-library/queue/pending — אפס צרכני-frontend (רק digests משתמש ב-queue/pending) app.py:6282 delete
PRE-3 wrong-data AuthorityBadge (binding/persuasive, DERIVED) מוצג בתור-הביקורת אך נשמט בחיפוש library-search-panel.tsx:26-73 מול halacha-review-panel.tsx:109 fix-data
PRE-4 confusing תג "ממתין" ב-/digests נראה לחיץ אך אינו (ב-/precedents הוא טאב-תור אמיתי) digests/page.tsx:23-35 clarify
PRE-5 dead HalachaCard בחיפוש לא מרנדר authority אף שהשדה על החוט library-search-panel.tsx:26-73 fix-data

יעד: 3 הקורפוסים נשארים נפרדים (גבול אמיתי — G2/INV-DIG1) אך מתפעלים אחיד: שם-חיפוש עקבי לכל קורפוס, תבנית-"ממתין" אחת, authority מוצג בכל מקום. מחיקת ה-endpoint המת.

2.4 למידה + סגנון (/training — 6 טאבים + CorpusDetailDrawer) ⚠️ האשכול הקריטי

8 משטחים · 10 ממצאים. מחלה: "לקח" חי ב-2 namespaces ומאושר ב-2 מקומות שכותבים ל-2 ערוצי-כותב; 3 KPI על דגלים-ללא-צרכן.

ID סוג ממצא file:line תיקון
LRN-1 sync-gap כפתור applied_to_skill ("אומץ לסקייל") אינפורמטיבי-בלבד — לא כותב ל-SKILL.md; היו"ר מאמין שהפעולה הושלמה lessons-tab.tsx:12-14; app.py:1471-1475 fix-data (להסיר)
LRN-2 confusing למידה מפוצלת ל-/api/learning + /api/training לאותה ישות learning.ts; training.ts; app.py:1448,4616 clarify (לאחד)
LRN-3 confusing שני שערי-אישור ללא יחס אכוףpromote מתעלם מ-review_status לגמרי learning-panel.tsx:89-150; lessons-tab.tsx:168-179; app.py:4574 clarify (שער אחד)
LRN-4 wrong-data StyleReportPanel: "12 מתוך 487 שחולצו" — signature_phrases ו-total_patterns מחושבים עצמאית; אין יחס-תת-קבוצה style-report-panel.tsx:87-90 fix-data
LRN-5 wrong-data findings_applied ("ממצאים שאומצו ל-SKILL: 42") סופר דגל-אינפורמטיבי → KPI "מזויף" curator-portrait-panel.tsx:85-86; app.py:1300-1302 fix-data
LRN-6 sync-gap מחיקת-קורפוס לא מאפסת בחירת ComparePanel → submit מחזיר 404 compare-panel.tsx:119-120; training.ts:172-174 fix-data
LRN-7 keep FullTextLazy ב-raw-fetch מחוץ ל-Query — שביר לעתיד, לא באג חי corpus-detail-drawer.tsx:320-348 keep
LRN-8 sync-gap מחיקת-קורפוס מייתמת צ'אטים (style_corpus_id→NULL) בשקט, ללא אזהרה corpus-panel.tsx:45-54; db.py:234 add-invalidation
LRN-9 keep סינון PatternsForSubtype stubbed (אין endpoint) — fallback חינני corpus-detail-drawer.tsx:351-353 keep
LRN-10 sync-gap usePromoteLearning מבטל רק learningKeys, לא lessonsKeys.forCorpus → LessonsTab תקוע learning.ts:104-115; training.ts:499-502 add-invalidation

יעד: תיבת-אישור-למידה אחת (מקובצת לפי זוג draft↔final) · ערוץ-כותב אחד + סטטוס "זורם-לכותב" אחד (review_status='approved') · הסרת applied_to_skill (אוצרות SKILL.md = מעשה-git ידני, לא כפתור) · כל artifact תלוי בזוג שלו (progressive disclosure) · תיקון 2 ה-KPI.

2.5 מתודולוגיה (/methodology — 5 טאבים)

2 משטחים · 8 ממצאים. מחלה: כללי-הכותב נערכים מ-2 משטחים שכותבים לאותה שורה appeal_type_rules(_global, …, 'universal') — מירוץ lost-update + פער-cache.

ID סוג ממצא file:line תיקון
MET-1 sync-gap promote מבטל ['learning'] בלבד; /methodology (['methodology',cat], staleTime 30ש') תקוע אחרי אישור learning.ts:113; methodology.ts:26-28; app.py:4629-4631 add-invalidation
MET-2 duplication discussion_rules['universal'] נכתב ב-2 מקומות (PUT מול promote) — כתיבה-שנייה דורסת בשקט discussion-rules-panel.tsx:35-36; learning-panel.tsx:138-139; app.py:4491-4495,4629; db.py:290 fix-data
MET-3 duplication transition_phrases['universal'] — אותו מירוץ methodology/page.tsx:45-49; learning-panel.tsx:125-129; app.py:4631 fix-data
MET-4 confusing universal מוצג כדלי-תוצאה אח, אך בפועל מוקדם (prepended) לכל התוצאות — אין מודל-מנטלי discussion-rules-panel.tsx:16-22; lessons.py:376-379 clarify
MET-5 dead ז'רגון T15/T7 בטקסט-העזר — מזהי-משימות פנימיים חסרי-משמעות למפעיל methodology/page.tsx:48,55 fix-data
MET-6 wrong-data עורך-צ'קליסטים מציג 5 סוגי-ערר ללא מיפוי איזה appeal_type צורך כל אחד content-checklists-panel.tsx:17-31; app.py:4414 clarify
MET-7 confusing 3 מושגי-"כלל" מתערבבים (ratios/rules/checklists) ללא מודל-תחולה methodology/page.tsx:16-19; block_writer.py:912-923 clarify
MET-8 sync-gap סדר-callbacks ב-promote → toast-הצלחה אחרי invalidation לא-מספק learning.ts:112-113; learning-panel.tsx:138-143 add-invalidation

יעד: /methodology = העורך הקנוני היחיד (כל כתיבה דרך PUT אחד, עם תג-מקור "ידני/מאומץ-מלמידה"); הלמידה מנותבת דרכו (לא כותבת-במקביל) ומבטלת את שני ה-caches; explainer-תחולה inline; קופי בעברית-פשוטה (בלי T7/T15).

2.6 תפעול + אבחון + הגדרות (/operations, /diagnostics, /settings, /skills)

5 משטחים · 6 ממצאים. מחלה: 4 משטחים שמריצים שאילתות-מקור זהות בלי cache משותף + נתונים-מתים/מטעים.

ID סוג ממצא file:line תיקון
ADM-1 sync-gap halacha_backlog מוחזר מה-backend אך נזרק ב-frontend (אין בטיפוס, לא מרונדר) app.py:2253; system.ts:21-32; diagnostics/page.tsx fix-data (לרנדר/להסיר)
ADM-2 sync-gap מוני-הלכות כפולים ב-/operations ו-/approvals ללא קישור-cache operations.ts:60; chair.ts:36; app.py:6520,5619-5633 add-invalidation (consolidate)
ADM-3 sync-gap מוני-פסיקה-חסרה כפולים ב-/operations ו-/approvals operations.ts:60; app.py:6521,5636-5647 add-invalidation (consolidate)
ADM-4 confusing court_fetch: "בתור" כולל failed, מטשטש pending מול queued operations/page.tsx:286-304; app.py:6562 clarify
ADM-5 sync-gap עריכת env ב-Coolify לא מרעננת את ערך-ה-Container ולא מזהירה על staleness עד redeploy env-var-row.tsx:76-96; settings.ts:135 fix-data
ADM-6 wrong-data מוני-סוכנים מסכמים רק חברות-Paperclip זמינות → עומק-תור מוקטן בשקט כשחברה לא-נטענת app.py:6667-6689; operations/page.tsx:461-465 clarify (להציג חלקיות)

יעד: /approvals=תיבת-ההחלטות (כל גייט נפעל רק כאן; /operations מצביע ולא משכפל) · /operations=משטח-קריאה יחיד (בולע את /diagnostics, מרנדר halacha_backlog, מתקן queued/pending, מציג חלקיות) · /settings=תצורה (עריכת-env שמשלימה-את-עצמה: סימון-staleness + redeploy באותה שורה).


3. עדכוני-ספ מומלצים (מתועדים ב-X17)

הסריקה זיהתה ש-X6 לא מכסה את שכבת-ה-UI-state, וש-07-learning מסנקצן בטעות שני-ערוצים. ההמלצות (כל אחת מגובת-מקורות ב-X17):

  1. X6 — invariants חדשים בשכבת-UI: (א) aggregate-נגזר = מקור-אמת; כל mutation לטבלת-מקור חייב לבטל את ה-queryKey שלו; אסור מונה-מתחרה client-side. (ב) למונה-גייט בעלים-משטח-יחיד; אחרים מצביעים. (ג) שדה ב-OpenAPI-response — לרנדר או להסיר (אסור לזרוק בשקט). (ד) אסור להציג aggregate מדויק כש-partial-failure השמיט תורם — להציג חלקיות.
  2. 07-learning §0.4/§0.6: שער-אישור אחד, טרנזקציית-כותב אחת, applied_to_skill מוסר; לקחים-מאושרים נכתבים רק דרך מסלול-המתודולוגיה היחיד.
  3. 00-constitution G2 "הפרות ידועות": להוסיף את תאום-המתודולוגיה (discussion_rules['universal'] נכתב ע"י PUT וגם promote).

4. הבא — בקלוג-איחוד (פאזה F)

מסמך זה ממפה ומאבחן; הוא אינו משנה קוד. הבקלוג המתועדף (TaskMaster, מקושר לכל ממצא) נגזר ב-#127.6 ומחולק ל-3 גלים:

  • גל-1 (זול, גבוה-ערך): הוספת-invalidation ל-16 פערי-הסנכרון + תיקון 6 הנתונים-השגויים + מחיקת המתים. תיקון מקומי, אין הגירת-IA.
  • גל-2 (איחוד-משטחים): תיבת-אישור אחת · ערוץ-למידה אחד (הסרת applied_to_skill, איחוד שני-השערים) · /operations/diagnostics.
  • גל-3 (ניווט): הורדת /feedback מהראשי · שמות-חיפוש עקביים · X17 ל-canonical.

הכרעת-יו"ר נדרשת לפני גל-2/3 (3א — עוצרים על המסמך).