כל agent שכותב מקבל worktree משלו ================================= כתובת העמוד: https://yotamfromm.dev/developer/blog/worktree-isolation/ עודכן: 2026-09-20 גרסת Markdown: https://yotamfromm.dev/developer/blog/worktree-isolation.md מפת האתר ל-agents: https://yotamfromm.dev/llms.txt אם יותר מ-agent אחד כותב לאותו repo, הם מתנגשים גם כשאף אחד מהם לא מואצל. ההחלטה שרשמתי אחרי שני סשנים שלי שהתנגשו: העותק הראשי הוא מקום לקרוא ולמזג, וכל מי שכותב עובד ב-worktree משלו. אם יותר מ-agent אחד כותב לאותו repo, הם מתנגשים גם כשאף אחד מהם לא מואצל. הפוסט הוא החלטה שרשמתי לעצמי אחרי שהתנגשות כזאת צצה אצלי, כולל מה שנשאר פתוח בה. באחד הימים בספטמבר הוספתי למנהל הסשנים של ה-agents שלי עמודת התראה חיה. בתוך שעה היא ירתה שוב ושוב, וההתנגשויות שהיא תפסה לא היו של agents מואצלים. הן היו של שני סשנים שלי, ב-Claude Code, שכתבו לאותו repo באותו זמן. ההחלטה: העותק הראשי של כל repo הוא מקום לקרוא ולמזג, וכל מי שכותב עובד ב-worktree משלו. למה זה מסוכן שני agents שכותבים לאותו עותק של repo מתחרים על האינדקס של git, מכניסים ל-commit את העריכות החצי גמורות של השני, ועושים rebase על עץ שזז מתחתיהם. מה היה עד אז כל מה שהיה עד ההחלטה זיהה או המליץ, ושום דבר לא מנע: | משטח | מה הוא עושה | למה זה לא מספיק | |---|---|---| | המשגר | מזהיר בקול כש-agent מתחיל בעותק הראשי | מתחיל אותו בכל זאת | | כלל בדיקה | מסמן שיתוף תיקייה כחמור | אחרי מעשה, ורק כשמריצים אותו | | עמודת ההתראה | חיה ובשדה הראייה | אומרת שההתנגשות קורית, לא שנמנעה | | הוראות בפרוזה | מסויגות | "כשהבידוד חשוב", "כשה-agent עשוי לכתוב קבצים" | מוסכמה שהיא רק המלצה בכל נקודת מעבר היא לא מוסכמה. מה שאפשר לעשות בקוד, עושים בקוד. ההחלטה: שלוש בחירות 1. היקף: כל חלון שכותב, כולל שלי. הגבלה ל-agents מואצלים בלבד הייתה משאירה בדיוק את ההתנגשויות שקרו, כי הן היו של סשנים אינטראקטיביים. 2. אכיפה: יוצרים worktree בהתחלה, וחוסמים כתיבה בעותק הראשי כגיבוי. מניעה לבד מפספסת חלון שנפתח ביד. חסימה לבד מגלה כל הפרה ברגע שהיא קוטעת אותך. לכן שתיהן. 3. רדיוס: כל ה-repos. תיקיות ההערות של מחסן הידע שלי פטורות (`wiki/`, `.raw/`, `_attachments/`, `_templates/`), כי כתיבה מקבילה של הערות היא merge ולא השחתה. המנגנון - זיהוי עותק ראשי: משווים בין `git rev-parse --git-dir` לבין `--git-common-dir`. בעותק ראשי הם זהים, ובעותק מקושר שונים. בחרתי בזה על פני בדיקה אם `.git` הוא קובץ (שגויה ב-submodules וב-repos חשופים) ועל פני ניתוח של `git worktree list` (יותר פלט, אותה תשובה). - חסימת הכתיבה: כלל חדש ב-hook שכבר רץ על כל עריכה וכתיבה. הוא פועל כשהיעד בתוך repo git, ה-repo הוא עותק ראשי והנתיב אינו בתיקיית תוכן פטורה. ההודעה בדחייה מציינת את הפקודה המדויקת שיוצרת worktree ואת משתנה הסביבה שמאפשר חריגה לסשן. - נתיב היצירה: עזר אחד שעוטף את יצירת ה-worktree בשם קבוע וב-branch לפי המשימה, ואידמפוטנטי כשהוא כבר קיים. משימות לקריאה בלבד נשארות פטורות, כי agent שלא כותב לא יכול להתנגש. - מה נשאר זיהוי בכוונה: כלל הבדיקה ועמודת ההתראה לא משתנים. הם הגיבוי לחלונות שנפתחו מחוץ לנתיבים האלה, והמדד לכך שהמדיניות עובדת: אחרי שהיא נכנסת, התראה פירושה פער באכיפה ולא אירוע שגרתי. הסידור, כדי לא להרוג את הסשן הכלל חוסם גם את הסשן שמתכנן אותו, שכותב בעותק הראשי של אחד ה-repos. לכן הסדר: קודם הכללים הטהורים והעזר, אחר כך העברת החלונות החיים ל-worktree, ואת ה-hook מפעילים אחרון. משתנה הסביבה מכסה את החלון שביניהם ואת החריגות המכוונות. קריטריוני הקבלה שנכתבו מראש 1. התחלת agent בעותק ראשי יוצרת worktree ומתחילה אותו שם, בלי לציין תיקייה, והיא אומרת איזה worktree נוצר. 2. עריכה בתיקיית הסקריפטים של עותק ראשי נדחית וההודעה מציינת את הפקודה שמתקנת. אותה עריכה תחת `wiki/` מצליחה. 3. משתנה החריגה מעביר את שתיהן, ושום דבר אחר לא. 4. הרצת pipeline מציבה כל עובד ב-worktree משלו, ובדיקת הצי לא מדווחת על תיקייה משותפת. 5. מערך ה-tests מכסה את הכללים החדשים, ומספר הכשלים שהיו קודם לא גדל. מה נשאר פתוח - ניקוי: שום דבר לא מסיר worktree אחרי שמשימה מוזגה. לא הוחלט אם זה ידני, חלק מסיום branch או משימה שבועית. - repos מחוץ לתיקיית הפיתוח: הכלל כתוב ל-repos git בכלל, ולא נבדק אם להגביל אותו לשורש. - הקוד של מחסן הידע עצמו: הסקריפטים שבו הם קוד לפי הכלל, ולכן עבודה עליהם דורשת worktree ועל התוכן לא. ההפרדה מכוונת, ושווה לבחון אותה אם תתברר כמעצבנת. ההחלטה נרשמה ב-20 בספטמבר 2026 כתכנון, ולא כמימוש גמור: המשטחים וקריטריוני הקבלה שלמעלה הם העבודה. מה אפשר לקחת מזה 1. תחייב כל מי שכותב לעבוד בעותק משלו, כולל עצמך. הגבלה ל-agents מואצלים בלבד הייתה משאירה את ההתנגשויות שקרו, כי הן היו של סשנים אינטראקטיביים. 2. שלב מניעה וחסימה. יוצרים worktree בהתחלה, וחוסמים כתיבה בעותק הראשי כגיבוי לחלונות שנפתחו ביד. 3. זהה עותק ראשי בהשוואה בין `git rev-parse --git-dir` לבין `--git-common-dir`. זה נכון גם ב-submodules וב-repos חשופים, ופשוט מניתוח של `git worktree list`. 4. הפעל את החסימה אחרונה. הכלל חוסם גם את הסשן שמתכנן אותו, ולכן קודם הכללים הטהורים והעזר, אחר כך העברת החלונות החיים, ורק בסוף ה-hook. 5. השאר את הזיהוי כמדד. אחרי שהמדיניות נכנסת, התראה פירושה פער באכיפה ולא אירוע שגרתי, וקריטריוני הקבלה נכתבים לפני המימוש.