Doc Authoring Guide (Sphinx/RTD)
- summary:
כללי כתיבת תיעוד בפרויקט — הצהרת תקציר בראש כל עמוד, הטמעת קוד לפי שם או סימון ולא לפי מספרי שורות, ההבחנה בין ספירת מופעים לערך שנאכף, ובנייה ללא אזהרות.
מטרות
בנייה ללא אזהרות (
-W --keep-going/fail_on_warning: true).עקביות בכותרות, קישורים ועוגנים.
מדיניות
עמודי סקירה חופפים: הוסיפו
:noindex:(api, database, handlers, services, configuration).autodoc_mock_imports: רשימת מודולים כבדים/לא זמינים בזמן build.אין להריץ קוד בזמן import ברמת מודול.
עמוד שאינו אמור להתפרסם — ל-**``exclude_patterns``**, לא ליתום. עמוד שאינו רשום באף
toctreeמייצרdocument isn't included in any toctree, ומכיוון ש-RTD נכשל על אזהרות זה מפיל את הבילד.exclude_patternsב-docs/conf.pyמרכז את העמודים שהוחרגו בכוונה — למשל כפילויות.md/.rstכשה-MyST פעיל. לפני שמוסיפים החרגה, ודאו שהעמוד באמת לא אמור להיות בתוכן העניינים.
הצהרת תקציר בראש העמוד
כל עמוד ידני מצהיר על תקציר בראשו.
AI-MAP.md— מפת הניווט לסוכני AI — קורא את ההצהרה הזו ולא מנסה לנחש אותה מהגוף.ב-
.rst: שדה:summary:מיד מתחת לקו הכותרת. Sphinx מכבה אתdoctitle_xform, ולכן אין קידום ל-docinfo— השדה מרונדר במקומו, כ-field-listמתחת ל-H1, ו**מוצג בעמוד**. הגלוּת מכוונת: תקציר שרואים הוא תקציר שמתיישן בקול.ב-
.md: מפתחsummaryב-front matter, שנקרא ב-yaml.safe_loadבדיוק כמו ש-MyST קורא אותו.אין הצהרה ← המפה מציגה את הכותרת בלבד.
python3 scripts/generate_ai_map.py --checkמתריע על עמודים כאלה ואינו מפיל את הבנייה.משפט אחד או שניים, בגוף ההווה, שעונים על ”מה יש בעמוד הזה“. שורת המפה נחתכת ב-220 תווים; ההצהרה בעמוד נשארת מלאה.
אל תתחילו בשם העמוד. שורת המפה היא
נתיב — **כותרת**: תקציר, כך שהכותרת כבר שם; תקציר שפותח בה מייצר כפילות מיידית (Playbook קצר להתראות: פלייבוק קצר להתראות: ...). התחילו בתוכן.אל תכתבו בתקציר ספירה או הבטחת יכולת. ”שבעה מסלולי API“, ”28 אייקונים“, ”דוגמאות מוכנות להרצה“, ”תומך בחיפוש סמנטי“ — כל אלה טענות שדורשות אימות מול הקוד, והן מתיישנות בלי שאיש ישים לב. שלושה סבבי ריוויו רצופים בפרויקט הזה נפלו בדיוק על זה: ספירה שהשתנתה, קוד עם
...שהוצג כרץ, ו-SearchTypeשקיים ב-enum ואינו ממומש. תארו מה יש בעמוד, לא כמה ולא מה עובד.tests/test_doc_summary_style.pyאוכף את זה על ספירה במילים ועל ספירה בספרות שאחריה מילה עברית — והוא רשת לצורות הנפוצות, לא אישור שהתקציר נכון; מה שהוא במפורש אינו תופס מתועד ב-docstring שלו.אל תשאירו כותרת יתומה. אם ההצהרה מחליפה פסקת פתיחה והסעיף שהכיל אותה נשאר ריק — מחקו גם את הכותרת. סעיף ריק מרונדר בעמוד כשורה ללא גוף.
למה הצהרה ולא חילוץ אוטומטי: הגרסה הקודמת חילצה את פסקת הפרוזה הראשונה, וכדי לעשות זאת מימשה חלקים מ-GFM ומ-RST ביד. ארבעה סבבי ריוויו רצופים מצאו שם מקרי קצה — כולל תקציר שיצא טבלה שלמה ותקציר שיצא ריק. מי שכתב את העמוד יודע מה התקציר.
ספירות בפרוזה: ספירת מופעים לעומת ערך שנאכף
הכלל שלמעלה אוסר ספירה בתקציר, אבל הסיבה אינה מוגבלת לשם: כל מספר שנכתב בפרוזה מתיישן באותה שקט. ההבחנה שמכריעה אינה איפה המספר יושב אלא מי אחראי עליו.
ספירת מופעים — אל תכתבו. ”בשתי ההפניות לעמוד הזה“, ”28 אייקונים“, ”שבעה מסלולי API“. אף אחד לא שומר על המספר הזה: כל הוספה שוברת אותו, ושום בדיקה לא מתריעה. נסחו בלי כמות — ”בכל מקום שבו העמוד נוגע בנימוק הנדסי“ נכון גם אחרי התוספת הבאה.
ערך שנאכף — כן תעדו. ”20 פתקים לקובץ“, ”תקרה של 1000 פתקים למשתמש“, ”עד 500KB לקובץ“. המספר הזה חי בקוד ונאכף בו, ולכן הוא אינו נסחף מעצמו — ומי שקורא את התיעוד חייב אותו. שינוי שלו הוא שינוי מוצר שממילא מחייב עדכון תיעוד.
המבחן: אם המספר יכול להשתנות בלי שאף שורת קוד תשתנה — הוא ספירת מופעים, ואין לכתוב אותו.
tests/test_doc_summary_style.py אוכף את הכלל על תקצירים בלבד. בפרוזה אין אכיפה אוטומטית, וזה הפער שכבר נתפס כאן: הכלל הזה נוסח אחרי שריוויוור מצא ספירה שגויה בפרוזה של עמוד — בתוך סעיף שכל נושאו דיוק בתיעוד.
הטמעת קוד מהמקור (literalinclude)
אסור למען לפי מספרי שורות (
:lines:) — הקוד זז והתיעוד ממשיך להציג את הטווח הישן בלי שום אזהרה. זה דפוסline-number-coupling(ראו amir-bug-patterns), והוא כבר קרה כאן: בלוק שהצביע עלmain.py:739הציג פנימיות של פונקציה אחרת, במרחק 2,900 שורות מהיעד.פונקציה או מחלקה שלמה ←
:pyobject:. הקוד נמשך לפי שם בכל בנייה, ושינוי שם מפיל את הבנייה ברעש.קטע בתוך פונקציה ← הערות סימון בקוד בפורמט
# docs:<שם>:start/# docs:<שם>:end, ומיעון ב-:start-after:/:end-before:. הערת ה-start חייבת לומר שהתיעוד תלוי בה ולאיזה דף — אחרת הריפקטור הבא ימחק אותה כהערה סתומה.marker חסר מפיל את הבנייה תחת
-W(אזהרת docutils, שאינה מושתקת בקונפיגורציה) — נבדק. marker כפול מסוכן יותר: הבלוק ירונדר מהמופע הראשון בלי אזהרה, ולכן כל שם מופיע פעם אחת בדיוק.tests/test_docs_literalinclude_anchors.pyאוכף את שני הכללים.
טיפים מהירים
אל תריצו את הבנייה המלאה לוקאלית כדבר שבשגרה — אבל דעו מי בדיוק תופס את האזהרות, כי לא כל בדיקה תופסת. ה-GitHub Action שרץ על PR הוא
documentation.yml, והוא בונה בלי-W(sphinx -b html . _build/html --keep-going -j auto), כלומר אינו נכשל על אזהרות.docs.ymlכן מריץ-W, אבל הואworkflow_dispatch— ידני בלבד, ובכוונה, כדי לא לחפוף. מי שתופס אזהרות על PR הוא Read the Docs:.readthedocs.yamlמגדירfail_on_warning: true, וה-check שלו יורד לאדום. לכן בנייה מקומית של פרוזה בעמוד קיים היא בזבוז — RTD יתפוס.אל תסיקו מזה ש-RTD שקול לבנייה המקומית. הוא מתקין
docs/requirements.txtמשלו ורץ בסביבה אחרת, כך שגרסת Sphinx או תוסף יכולים להתנהג שם אחרת. אם RTD אדום ולוקאלית ירוק — RTD צודק, כי הוא הסביבה שמפרסמת.החריג: עמוד חדש, או נגיעה ב-``toctree``/``conf.py``. שם טעות מפילה את הבילד כמעט בוודאות (
document isn't included in any toctree), והבדיקה זולה כי אפשר לבנות עמוד בודד:python -m sphinx -b html -W . _build/html <עמוד>.rst.השתמשו ב‑
copybuttonלקוד שמיועד ל‑Copy‑Paste.שמרו עוגנים יציבים לכותרות עיקריות.