ראיות וחקירה

הפגם שבו הכול תקין

משפחת פגמים שמייצרת פלט תקין לחלוטין מקלט שגוי או חסר, ואינה מתריעה על דבר. ארבעה מקומות שבהם היא מסתתרת, כלל אחד שמאתר אותה, ולמה דווקא פלט רהוט עושה את הפגם לקל להחמצה.

מה בודקים כששום דבר אינו נכשל?

יש סוג של פגם שאף בדיקה רגילה לא תמצא, מפני שכל בדיקה רגילה עוברת בהצלחה. יש לו חתימה אחת, והיא קצרה:

קלט שגוי, פלט תקין, אפס התרעות.

שום דבר אינו נזרק. שום דבר אינו נרשם ביומן. התוצאה מגיעה בזמן, בצורה הנכונה, עם השדות הנכונים והטיפוסים הנכונים, והיא שגויה. הרהיטות היא חלק מהכשל ולא פרט לצדו: תוצאה שמגיעה נקייה היא תוצאה שאין סיבה לפתוח.

זו שיטה, לא תוצאה. היא נולדה מתוך בדיקה ארוכה שהמשמעת היחידה שלה הייתה שהיא חייבת להיות מסוגלת להפריך את המסקנות הקודמות של מי שכתב אותה. היא שורדת את היציאה מאותה בדיקה מפני שאף חלק בה אינו תלוי במערכת שממנה צמחה.

למה בדיקה שעברה היא ראיה חלשה

בדיקה קובעת שדבר מסוים נכון. היא אינה קובעת שהדבר שנבדק הוא הדבר שחשוב לכם.

שימו לב להבדל בין שתי האמירות:

  • לא הוצגה שגיאה.
  • הדבר הנכון קרה.

רוב תהליכי האימות שקראתי מתייחסים לראשונה כראיה לשנייה. היא אינה כזו. שגיאה מוצגת רק במקום שבו מישהו דמיין מראש בדיוק את צורת הטעות הזו וכתב את ההתרעה. כל הערך של פגם מהמשפחה הזו הוא שאיש לא דמיין אותו, ולכן אין התרעה שתתפוס אותו.

לכן השאלה שמאתרת אותם אינה מה נכשל, אלא: עבור כל הסתעפות, כל ברירת מחדל, כל שומר וכל בנאי בנתיב הזה, מה קורה כשהקלט חסר או אינו מזוהה? אם התשובה הכנה היא “יוצא משהו תקין”, יש כאן ממצא, בין אם בדיקה כלשהי נכשלת כרגע ובין אם לא.

ארבעה מקומות שבהם היא מסתתרת

כל אחד מארבעת אלה נקרא החוצה ממופע מאומת: תחילה הפגיעה, אחריה הצורה הכללית. הסדר הזה הוא כל הערובה. גשש שהומצא מראש מתאר את דמיונו של הכותב; גשש שנגזר ממשהו שקרה באמת מתאר את העולם.

אחת. הסתעפות שנבחרת לפי שם ולא לפי מה שהחומר עצמו מצהיר. רכיב בוחר כיצד לטפל בקלט על סמך התאמת מחרוזת: שם קובץ, שם משפחה, תווית שמישהו הקליד בקובץ הגדרות. הקלט נושא בתוכו מטא־נתונים סמכותיים שעונים על אותה שאלה בדיוק, והקוד אינו קורא אותם. כשהמחרוזת אינה מתאימה, הקלט נכנס למסלול שנועד למשהו אחר לגמרי. הוא מטופל. הוא מטופל שגוי, בשקט, והפלט תקין לחלוטין.

שתיים. ברירת מחדל שהיא המקרה הנדיר. כל מנגנון ניתוב זקוק לנפילה אחורה, והנפילה אחורה נכתבת בדרך כלל מוקדם, כשקיים רק מקרה אחד. בהמשך מגיע המקרה השכיח, ואיש אינו חוזר לבדוק. מעתה כל קלט שאינו מזוהה נכנס בשקט למסלול החריג, וזה בדיוק ההפך ממה שברירת מחדל אמורה לעשות. המבחן כאן הוא שאלת ספירה, לא שאלת לוגיקה: מתוך הקלטים שהמערכת באמת מקבלת, כמה מהם ברירת המחדל משרתת נכון? אם התשובה היא אפס, ברירת המחדל הפוכה.

שלוש. מסלול מהודר ללא כיסוי, מאחורי שומר שהוא עצמו תקין. מימוש ייעודי נכתב, מוגן כראוי, ולעולם אינו רץ, מפני שהסתעפות מוקדמת יותר מנצחת בכל מכונה שמישהו באמת מפעיל. השומר אינו הפגם. השומר הוא הסיבה שאיש לא שם לב שהקוד לא נבדק אף פעם, וקוד שלא רץ אינו קוד תקין: הוא קוד שאין לגביו ראיה לכאן או לכאן. השאלה אינה “האם יש כאן הגנה” אלא “על החומרה שבאמת נמצאת ברשותנו, האם השורה הזו רצה אי פעם?”

ארבע. מבנה שנבנה ריק ומוגש כאילו אותחל. זה החד ביותר מבין הארבעה, והמביך ביותר למצוא בעבודה של עצמך. בנאי מייצר את הצורה הנכונה בלי שום דבר בתוכה. הצרכן מקבל אותה, עושה בדיוק את מה שהוא אמור לעשות, ומחזיר פלט במידות הנכונות שמתעלם מן הקלט לחלוטין. כל חוזה ממשק מכובד. הצורה היא האליבי.

שימו לב למה שמשותף לארבעה. באף אחד מהם הקוד אינו שגוי באופן שסוקר מחפש. בכל הארבעה משהו עוצב נכון וריק מן הדבר שנותן לו משמעות.

החומר הוא הראיה; הטקסט שמתאר אותו הוא טענה

החצי השני של השיטה משעמם יותר ועושה יותר עבודה.

הערה בקוד, שם קובץ, מפתח בהגדרות ומסמך, כולם מתארים את החומר. אף אחד מהם אינו החומר. במקום שבו התיאור והחומר יכולים לסתור זה את זה, החומר הוא הראיה והתיאור הוא טענה לגביו.

בפועל זה הופך לטבלה שאפשר לכתוב לכל מערכת, עם התכונה הנוחה שהעמודה הימנית תמיד זולה:

מה נטען מה באמת נבדק
קובץ הגדרות שמונה את הרכיבים הזמינים הספרייה שממנה הרכיבים נקראים
מסמך שאומר שתסדיר מסוים נתמך מזהה התסדיר בתוך הקובץ עצמו
גודל אוצר מילים מוצהר האם המבנה שמחזיק אותו נכתב אי פעם
“המודל מוגש” פלט משני קלטים שונים במכוון
“השדה הזה נדרש” האם השדה קיים בחומר בכלל

כל שורה בטבלה היא בדיקה שעולה פקודה אחת. כל שורה בטבלה, בבדיקה שממנה היא באה, שינתה מסקנה שכבר נכתבה.

צורת הכשל של דילוג עליה אינה שגיאה. היא מסמך שנקרא כמאומת ואינו כזה, וזו אותה משפחת פגמים בדיוק, רמה אחת למעלה. גם פרוזה היא פלט תקין.

המשמעת שהשיטה דורשת

שני דברים מאפשרים לשיטה לעבוד, ושניהם לא נוחים.

הראשון הוא שהיעדר חייב להירשם ולא להיפתר. כשמחפשים ראיה ולא מוצאים אותה, הרישום הכן הוא לא ידוע, וזו הסיבה שנשאר לא ידוע. “לא ידוע” שהומר בשקט להנחה אינו פליטת עט קטנה: הוא בדיוק אותו כשל של סבירות שקטה, שמבצע עכשיו מי שאמור היה לבדוק.

השני הוא שתוצאות שליליות חייבות להתפרסם כתוצאות. בדיקה שרושמת רק את מה שאישרה אינה בדיקה, מפני שאי אפשר לדעת אם היא בכלל חיפשה. הבדיקה שממנה זה בא מחזיקה רשימה של מסקנות קודמות של הכותב שמדידה מאוחרת יותר הרגה, ארבע טענות היעדר שנפלו באימות, ושיפור אחד לכאורה שנרשם כרעש כשלא הצליח לחזור על עצמו. הרשימה הזו היא החלק שהופך את כל השאר לראוי לקריאה.

על מה זה באמת

הסיבה שזה חשוב גם מחוץ לתוכנה היא שהחתימה מכלילה בלי שינוי.

דוח תקין, בזמן, עקבי בתוך עצמו, ובנוי על מקור שאינו אומר את מה שהדוח אומר שהוא אומר. תהליך שמייצר החלטה בפורמט תקין מתוך קלט שאיש לא בדק. מדד שמחושב נאמנה משדה שריק מאז הגירה שהתרחשה לפני שנתיים. קלט שגוי, פלט תקין, אפס התרעות.

רהיטות אינה ראיה. היא היעדר חיכוך, וחיכוך הוא מה שאימות התבסס עליו מאז ומעולם. כשמערכת מפסיקה לייצר חיכוך, מה שכדאי לבדוק אינו אם היא עוברת. מה שכדאי לבדוק הוא אם היא בכלל מסתכלת.