שלושה באגים אמיתיים שבהם הקליק לא עושה כלום — Claude טעה בכל פעם עד שמשפט אחד נוסף בפרומפט נעל את התשובה.
באגים מגיעים בשני סוגים. אלה שזורקים שגיאה — תעביר ל-Claude את ה-stack trace ותוך 30 שניות יש לך תשובה. אלה שלא זורקים — הכפתור שלא עושה כלום, העמוד שלא זז, הטופס שנופל בשקט — באלה Claude טועה בניסיון הראשון. לא כי הוא טיפש. כי הוא לא רואה.
נתקלתי בשלושה כאלה ברצף כשבניתי את תהליך התשלום של how2claude. הנה הדו"ח שאחרי, ודפוסי הפרומפט שאני משתמש בהם עכשיו לבאגים שקטים.
חיברתי את תשלומי x402. מקומית עבד. הקליק הראשון בפרודקשן: invalid_string at payTo בקונסול. ה-signing flow אפילו לא התחיל — סכמת ה-Zod של ה-facilitator דחתה את הבקשה לפני כן.
הארנק היה כתובת 0x... באורך 42 תווים, לעין נראתה תקינה. ביקשתי מ-Claude לבדוק את שדה ה-wallet ב-config/credentials/production.yml.enc:
w = Rails.application.credentials.dig(:x402, :wallet_address).to_s
puts "length: #{w.length}"
# => 43
43 תווים. כתובות EVM צריכות להיות 43 — לא, 42. התו ה-43 היה סימן שאלה סיני ברוחב מלא ? (U+FF1F) שנדבק בזמן העתק-הדבק ממתודת קלט סינית.
הסריקה הראשונה של Claude לא סימנה כלום — בשבילו זו הייתה מחרוזת שמתחילה ב-0x ונראית תקינה. הוא לא ספר את האורך ביוזמתו. תוסיף לפרומפט: "הכתובת הזאת ארוכה בתו אחד מהמצופה — הדפס כל codepoint בנפרד". 0xFF1F מופיע, תיק נסגר.
כפתור Subscribe בעמוד התמחור — לוחצים, העמוד לא זז. בלי שגיאות. טאב ה-network הראה שה-POST יוצא, ש-Stripe מחזיר 302 אל checkout.stripe.com — ואז... כלום.
תחילה הפניתי את Claude לקונטרולר. הלוגיקה תקינה: redirect_to session.url, allow_other_host: true. JS — אין listener רלוונטי.
לבסוף שמתי לב לכותרת התגובה: Content-Type: text/vnd.turbo-stream.html. Turbo יירט את ה-submit של button_to כבקשת Turbo Stream, ו-Turbo Stream לא עוקב אחרי 302 ל-origin חיצוני — אז ה-redirect נבלע, והעמוד נשאר בשקט במקום.
תיקון:
<%= button_to "Subscribe", ..., data: { turbo: false } %>
אותו באג חזר והכה אותי חודש אחר כך בכפתור Google OAuth. מיירטים ברמת ה-framework הם קרקע פוריה לבאגים שקטים — Claude כברירת מחדל חושב ליניארי request/response ולא ילך לחפש שכבה אמצעית ששכתבה את הסמנטיקה. תוסיף לפרומפט: "עבור על כל מיירט ברמת framework שהקליק הזה עובר בו — פרט כל middleware/שכבת JS שמעבדת את הבקשה הזאת במסלול browser → server → browser".
ה-Stimulus controller של מתג החודשי/שנתי בעמוד התמחור — לוחצים על הכפתור, שום דבר לא מתחלף. מתודת ה-controller ירתה (אושר עם console.log), אבל this.monthlyTarget היה undefined.
הניחוש הראשון של Claude: טעות כתיב בשם ה-target. לא היה. data-pricing-target="monthly" היה ב-DOM.
הבעיה הייתה ב-scope. data-controller="pricing" ישב על ה-container של כפתור המתג, אבל שני מקטעי ה-grid ישבו מחוץ ל-container ההוא. Stimulus מחפש targets רק בתוך תת-העץ של אלמנט ה-controller; אלה שבחוץ לא קיימים בשבילו. הרמתי את data-controller אל ה-<section> שעוטף הכל — תוקן.
הבאג הזה צועק "הקוד תקין" — כל השמות תואמים, כל התכונות שם, רק הפיצ'ר שבור. Claude כברירת מחדל קורא את הקוד שורה אחר שורה; הוא לא יצייר את מבנה ה-DOM מיוזמתו. תוסיף לפרומפט: "צייר את עץ האבות והצאצאים של האלמנט עם data-controller='pricing' — סמן אילו data-pricing-target נופלים בתוך תת-העץ ואילו לא".
שלושת הבאגים נראו זהים מבחוץ: קליק, שום דבר לא קורה, אין שגיאה. Claude טעה בניסיון הראשון בכל פעם, ובכל פעם משפט אחד נוסף בפרומפט נעל את התשובה. הדפוס המשותף:
1. ספר לו את ה-delta הכמותי בין הצפוי למציאותי — לא רק "זה לא בסדר"
לא "יש בעיה בכתובת הארנק", אלא "היא ארוכה בתו אחד מהמצופה".
לא "הכפתור לא עובד", אלא "התגובה היא 302, אבל הדפדפן לא עקב אחריה".
לא "המתג שבור", אלא "מתודת ה-controller יורה, אבל ה-target הוא undefined".
ככל שה-delta צר יותר, כך מרחב החיפוש של Claude קטן יותר.
2. כוון אותו לשכבות הבלתי נראות — framework, דפדפן, קידוד
באגים שקטים כמעט אף פעם לא גרים בקוד העסקי שלך. הם גרים ב-Turbo, ב-scope של Stimulus, בקידוד תווים, ב-CSP, ב-CORS, ב-service workers. ברירת המחדל של Claude היא לקרוא את הקוד שלך. תגיד לו מפורשות ללכת להסתכל בשכבות האחרות האלה.
3. בקש מצב ביניים, לא מסקנות
"הדפס כל codepoint." "פרט את כותרות התגובה." "עשה dump לתת-עץ ה-DOM." תממש את מצב הביניים במקום לבקש מ-Claude להסיק את דרכו אל התשובה. ה"שקט" של באג שקט הוא שצעד כלשהו בשרשרת ההיסק נשען על הנחה מוסתרת שלא מתקיימת. מימוש מצב הביניים הוא הדרך לאלץ את ההנחה ההיא לצוץ החוצה.
שגיאות בוחנות מה Claude יודע. באגים שקטים בוחנים את איכות האות שאתה נותן לו. ככל שתהיה מדויק יותר, הוא ימצא את התשובה מהר יותר.