מה עובר שיעור אחד לפני שהוא נחשב נלמד
הבוחן הוא שער: השיעור נחשב הושלם רק אחרי מעבר, וכל שאלה נכנסת אחר כך למחזור החזרה
החלק שהכי מעניין אותי הוא איפה הקוד של הלומד רץ. מסוף השיעור מריץ JavaScript אמיתי, ולכן הוא חייב להיות מבודד מהמערכת שמחזיקה את ההתקדמות. הוא רץ בקובץ נפרד תחת sandbox="allow-scripts" בלי allow-same-origin — כלומר במקור אטום, שממנו קריאה ל-localStorage של האפליקציה פשוט זורקת חריגה. הדרך הקצרה, iframe עם srcdoc, לא עובדת כאן: הוא יורש את ה-CSP של העמוד, ו-script-src 'self' חוסם את המריץ בשקט. אותו אילוץ הוא גם הסיבה שהגרפים הם SVG שכתבתי בעצמי ולא ספריית תרשימים — CSP שאוסר סקריפט מרוחק לא משאיר ברירה, ושש צבעי הסדרה נבדקו כקבוצה מול רקע הקרם: הפרדה לעיוורי צבעים, רצפת ניגודיות ומרחק בין גוונים סמוכים.
מה זה
Master AI LMS היא מערכת הלמידה שבניתי לקורס הבינה המלאכותית שלי — קורס יישומי בעברית שלוקח מאפס עד פרויקט אישי. היא בנויה React 18 עם Vite, עברית מלאה מימין לשמאל, ובלי backend: כל ההתקדמות, התשובות, הקוד וההגדרות נשמרים בדפדפן של הלומד.
התוכן הוא 31 שיעורים בשמונה מודולים, כ-17 שעות. כל שיעור נפתח לעשר לשוניות: סקירה עם יעדים ונקודות מפתח, המחשה אינטראקטיבית, תרגול, בוחן, קוד, מסוף, הערות, תמלול מלא, דוגמאות קוד ומשאבים. מעל השיעורים יושבת שכבת ניהול למידה: "המסע שלי" עם רצף ימים, יעד שבועי ומתכנן קצב, חזרה מרווחת על כל 155 השאלות, מילון של 36 מונחים, ותעודת סיום.
הבעיה
קורס AI מזדקן מהר. מחירים, שמות מודלים ויכולות משתנים בתוך חודשים, וקורס וידאו מוקלט הופך לא נכון בלי שאף אחד ישים לב. רציתי מערכת שבה התוכן הוא נתונים שאפשר לבדוק, לא קבצי וידאו שאי אפשר לתקן.
הבעיה השנייה היא שצפייה לא מייצרת יכולת. לומד שראה שיעור על MCP לא בהכרח יודע לחבר שרת. לכן כל שיעור חייב לכלול משהו שהלומד עושה בעצמו — ולא כמסך הדגמה, אלא כקוד שבאמת רץ.
והשלישית: אני רוצה שאפשר יהיה ללמוד בלי חשבון ובלי שרת. בלי הרשמה, בלי מסד נתונים, בלי עלות תפעול — אבל עם התקדמות אמיתית שנשמרת, וגיבוי שאפשר לייצא ולייבא.
מה בניתי
את התוכן בניתי מול החומר הרשמי של Anthropic, שיעור אחר שיעור, כולל המודול המתקדם שמכסה את היום-יום של Claude Code, hooks ואוטומציה, סוכני משנה ותזמור, ה-Agent SDK, MCP מתקדם והנדסת הקשר. כל מפתח תשובה בבוחן נבדק בנפרד ובאופן יריב — הבדיקה הזאת החזירה 23 תיקונים אמיתיים, בהם שאלה שהתרחיש שלה לא יכול היה להוביל לתשובה שלה, וטענה שגויה שתקציבי משימה קיימים רק במודל אחד.
לכל אחד מ-31 השיעורים בניתי הדמיה אינטראקטיבית משלו, כולן מאותה ערכת רכיבים משותפת — חיזוי טוקן אחרי טוקן, התפלגות טמפרטורה, מסע שאילתה ב-MCP, לולאת הסוכן, מחשבון כלכלת טוקנים ועוד. כולן דטרמיניסטיות, בלי רשת, מודעות ל-prefers-reduced-motion ועובדות ברוחב 360 פיקסלים.
המסוף הוא שתי מכונות באותה לשונית: הדמיה של Claude Code CLI עם פלט שנכתב כדי להתאים לכלי האמיתי, ולצידה REPL אמיתי של JavaScript. ערכת הגרפים היא SVG שכתבתי מאפס — עמודות, קו עם צלב וטולטיפ, טבעת, מפת חום, עמודות מוערמות וקו זעיר — והיא נמתחת לפי רוחב המכל דרך ResizeObserver.
איך זה עובד
אין שרת, אז כל מצב חי במרחבי שמות מופרדים ב-localStorage: התקדמות, קוד, הגדרות, פרופיל, חזרה ומסע. שכבת הגיבוי מייצאת ומייבאת את שלושתם יחד, כך שלומד יכול לעבור מכשיר בלי חשבון.
הבידוד של מריץ הקוד הוא ההחלטה הארכיטקטונית האמיתית כאן, והיא מוסברת במלואה בפאנל שלמעלה: מקור אטום שלא יכול לגעת בהתקדמות של הלומד, וקובץ נפרד במקום srcdoc כדי לא לרשת את ה-CSP של האפליקציה.
הבאג המלמד ביותר במערכת היה במובייל, ושתי הסיבות שלו לא נראו בכלל בגיליון הסגנונות. שכבת ההגנה מפני העתקה הסיקה "אפס תוספים משמעו דפדפן אוטומטי" — נכון בדסקטופ, ושקר גמור במובייל, כך שכל דפדפן אנדרואיד קיבל מסך חסום; ואותה שכבה הסתירה את הדף כשההפרש בין גובה החלון החיצוני לפנימי עבר סף, כלומר בכל פעם שנפתחה מקלדת. במקביל, הפריסה החזיקה שתי עמודות בזמן שהתפריט הצדדי הפך position:fixed — אלמנט קבוע יוצא מזרימת הרשת, ולכן התוכן נחת בעמודה ברוחב אפס והאפליקציה כולה נפתחה בתוך קופסה ריקה. מה שפיצח את זה היה מדידה של פרופיל טלפון אמיתי, לא קריאה של ה-CSS.
התוצאה
המערכת חיה ב-master-ai-lms.vercel.app ומשמשת אותי להעברת הקורס. בדיקת שלמות על הנתונים מאשרת 31 שיעורים, שמונה מודולים ו-155 שאלות שכל מפתחות התשובה שלהן בטווח תקין, וסריקת קצה-לקצה של 74 בדיקות עוברת גם בדסקטופ וגם בפרופיל אייפון ברוחב 390 — כולל 11 מתוך 11 מול הפרודקשן על פרופיל אייפון אמיתי.
מה שאני לוקח מזה הוא שהאימות היריב של מפתחות התשובה החזיר את ההשקעה בעצמו. 23 תיקונים שנתפסו לפני שלומד ראה אותם, כולל שאלות שנראו סבירות לגמרי — וזה בדיוק ההבדל בין קורס שנראה מקצועי לבין קורס שאפשר לסמוך עליו.