fix: ארבעה תיקונים מדוח האימות של #3394 — ‎-B בתת-תהליך, כפילות ב-configuration, מספר תלוי-סביבה, ו-.pyc בגיט

Merged
AM
1mo ago
+37-41

✨ תיאור קצר

ארבעה תיקונים נפרדים שעלו מדוח אימות בלתי-תלוי של PR #3394 (squash dea1b9e). אין שינוי התנהגות בקוד ייצור: שניים מהם תיעוד, אחד מוסכמת טסטים, ואחד היגיינת גיט. כל אחד נמדד לפני ואחרי ולא הונח.

📦 שינויים עיקריים

  • קוד (Backend)
  • בוט טלגרם
  • מסד נתונים/מיגרציות
  • תיעוד (docs/)
  • DevOps/CI/CD

פירוט נקודות:

  • tests/test_doc_sections.py — התת-תהליך יוצא מעץ המקור. test_doc_sections_pulls_no_heavy_modules הריץ subprocess.run([sys.executable, "-c", code], cwd=_ROOT), כלומר תת-תהליך שכותב __pycache__ לתוך services/. השורש היה שהייבוא נשען על ה-cwd — הוא עבד רק מפני שהתהליך רץ בשורש הריפו, ולכן -B לבדו לא הספיק: sys.path.insert עם נתיב מוחלט מנתק את המדידה מעץ העבודה, ורק אז cwd=tmp_path אפשרי. זה בדיוק החיווט שכבר קיים ב-tests/test_rst_parser.py, וההערה שם מנמקת אותו.
  • docs/configuration.rst — הסרת בלוק כפול. שלושת הסעיפים "Databases and Cache (Pooling/Timeouts)", "HTTP Clients" ו-"שימוש ב-http_sync" הופיעו פעמיים.
  • mcp_server/outline_scanners/__init__.py — מספר תלוי-סביבה יוצא מה-docstring. הוא קבע "ארבעה מודולים מהריפו" ומנה אותם בשמם; בסביבה עם structlog הם שבעה.
  • __pycache__/*.pyc — יוצאים מניהול גיט. אחד-עשר קבצים שנכנסו ב-8098b67e (#3239) למרות ש-.gitignore חוסם אותם. git rm --cached בלבד — הם נשארים על הדיסק.

הכפילות ב-configuration.rst — מה נמצא ומה הוכרע

שני העותקים נכנסו בקומיט אחד, 171d8f66 (#1015, 23.10.2025), שהכניס את אותו בלוק פעם אחרי "Environment variables" ופעם אחרי "Security". לפניו הכותרות לא היו בקובץ כלל.

שני העותקים הושוו שורה-שורה לפני המחיקה, והם אינם זהים — אבל אף הבדל אינו הבדל בתוכן:

עותק א' (13–58)עותק ב' (85–111)סוג
Redis connection string. Use ``rediss://`` …Redis connection string (use ``rediss://`` …)פיסוק
ע״י (U+05F4) + "לא להשתמש"ע"י (ASCII) + "אל תשתמשו"ניסוח
שימוש ב‑http_sync (U+2011)שימוש ב-http_sync (ASCII)מקף

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

עוגנים — נבדק ולא הונח. autosectionlabel אינו מופעל ב-docs/conf.py, ולכן לכותרות אין לייבלים אוטומטיים ואף :ref: לא יכול להצביע עליהן. העוגן המפורש היחיד בקובץ הוא .. _config-error-signatures:, שיושב הרבה מתחת לבלוק שנמחק ואליו מפנה docs/observability/log-aggregator.rst. שאר ההפניות הנכנסות הן :doc: לעמוד כולו. לא נשבר אף עוגן, ולכן לפי docs/versioning-stable-anchors.rst אין כאן שינוי שובר-תיעוד שמחייב רשומה ב-whats-new.

משקל הייבוא — המדידה שהחליפה את המספר

סביבהסה"כ מודוליםמהריפוכבדים
בלי structlog73ארבעה — שרשרת ה-services0
עם structlog330שבעה — ועוד observability, monitoring, monitoring.error_signatures0

השרשרת: services/__init__.py מייבא state מ-backoff_state, ששורה 16 בו מנסה לייבא observability; ו-observability.py מייבא structlog בקשיחות בשורה 22 ומנסה monitoring.error_signatures בשורה 28. כלומר הזנב תלוי במה שמותקן בסביבה ולא בשורת קוד — וזה בדיוק המבחן ב-docs/doc-authoring.rst: מספר שיכול להשתנות בלי שאף שורת קוד תשתנה אינו ערך שנאכף, ואין לכתוב אותו. הניסוח החדש מתאר חלק קבוע וזנב מותנה, בלי מספר ובלי רשימה סגורה. האינווריאנט הנושא נשאר וזה מה שנמדד בשתי הסביבות: אפס מודולים כבדים.

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

🧪 בדיקות

  • Unit
  • Integration
  • Manual

413 טסטים עברו, אפס נכשלו — test_doc_sections, test_rst_parser, test_mcp_docs_handlers, test_mcp_outline, test_doc_summary_style, test_docs_literalinclude_anchors. flake8 נקי על שני קובצי הפייתון שהשתנו.

בקרה שמוכיחה שתיקון ה--B אינו no-op. התת-תהליך הורץ מבודד, בלי pytest, על services/__pycache__ ריק:

צורהנכתב ל-services/__pycache__
ישנה — בלי -B, cwd= שורש הריפו3 קבצים (__init__, backoff_state, doc_sections)
חדשה — עם -B, cwd=tmp_path0, ותיקיית ה-tmp נשארת ריקה גם היא

ומה שלא השתנה, כדי שלא ייקרא אחרת: בריצת pytest רגילה הדלתא הייתה אפס גם לפני התיקון, כי האיסוף עצמו מייבא את אותם מודולים וכותב את אותם קבצים. נמדד אחרי התיקון: איסוף=4, הטסט לבדו=4, דלתא=0. כלומר זו הפרה של מוסכמה ולא באג נצפה, והערך שלה הוא ביום שבו עץ המקור יהיה לקריאה בלבד — כלל 8 ב-CLAUDE.md.

ambiguous_section — הורץ מחדש על כל 208 קובצי ה-RST:

קובץלפניאחרי
docs/configuration.rst250
docs/development/tools.rst1212
docs/observability/query-performance-profiler.rst88
סה"כ4520

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

בניית תיעוד: python -m sphinx -b html -W --keep-going על כל האתר — build succeeded, קוד יציאה 0, אפס אזהרות. בניית עמוד בודד הוחלפה בבנייה מלאה בכוונה: היא מייצרת אזהרה search index couldn't be loaded שהיא ארטיפקט של הבנייה החלקית עצמה ולא ממצא, והבנייה המלאה היא ממילא מה ש-RTD מריץ.

.pyc — נבדק שאין תלות: כל עשרת האזכורים של __pycache__ בריפו הם החרגות בלבד (.ruff.toml, bandit.yaml, .yamllint.yaml, services/code_indexer.py, scripts/audit_config_definitions.py, scripts/find_duplicates.py, github_menu_handler.py, repo_analyzer.py ושני טסטים). אף אחד אינו קורא מהתיקייה. אחרי git rm --cached הם נשארו על הדיסק ואינם מופיעים כ-untracked, כי .gitignore:2 חוסם אותם.

🧪 בדיקות נדרשות ב‑PR

  • 🔍 Code Quality & Security
  • Unit Tests (3.11)
  • Unit Tests (3.12)

📝 סוג שינוי

  • feat
  • fix: תיקון באג
  • docs: שינוי תיעוד בלבד
  • refactor
  • perf
  • chore/ci: תשתית
  • breaking change

✅ צ'קליסט

  • הקוד עוקב אחרי הסגנון (flake8 נקי)
  • בדיקות רצות ועוברות
  • תיעוד עודכן
  • ג'ובים חדשים — לא רלוונטי
  • משתני סביבה — לא נוספו ולא שונו. הבלוק שנמחק מ-configuration.rst הוא כפילות מדויקת של בלוק ששורד באותו קובץ, ולכן אף משתנה לא ירד מהתיעוד
  • טוקנים/ערכות נושא — לא רלוונטי
  • אין סודות/מפתחות בקוד
  • אין מחיקות מסוכנות — כל מחיקה זמנית בסשן עברה דרך מעטפת שמאמתת readlink -f מול allowlist, לפי CLAUDE.md
  • הודעות הקומיט תואמות Conventional Commits
  • CHANGELOG — אין קובץ כזה בשורש
  • עיינתי במסמכי אתר התיעוד — נתיב: docs/doc-authoring.rst, docs/versioning-stable-anchors.rst | המשפט: "אם המספר יכול להשתנות בלי שאף שורת קוד תשתנה — הוא ספירת מופעים, ואין לכתוב אותו" ו-"לא לשבור מזהי עוגנים קיימים (refs) בין גרסאות"

🧩 השפעות/סיכונים

אפס שינוי בקוד ייצור. שני קבצי התיעוד הם פרוזה, קובץ הטסט הוא מוסכמת בידוד, וה-.pyc הם היגיינת גיט. הסיכון היחיד שנשקל הוא אובדן תוכן מ-configuration.rst, והוא נסגר במדידה: 17 מ-19 השורות שנמחקו קיימות כלשונן בעותק ששרד, והשתיים הנותרות הן ניסוח חלופי של אותו מידע.

סטייה מהמוסכמה, מדווחת: CLAUDE.md ו-docs/doc-authoring.rst אומרים לא לבנות את התיעוד מקומית עבור פרוזה בעמוד קיים, כי RTD תופס. נתבקשתי לבנות עם אזהרות כשגיאות, ולכן בניתי — ובניתי את האתר המלא ולא עמוד בודד, כי הצורה החלקית מייצרת אזהרת שווא משלה.

🔗 קישורים

  • מקור: דוח אימות בלתי-תלוי של #3394 (squash dea1b9e, בסיס 06983a8)
  • Issues קשורים: #
  • מסמכים רלוונטיים: docs/doc-authoring.rst, docs/versioning-stable-anchors.rst

🧯 סיכון / החזרה לאחור (Rollback)

git revert לכל אחד מארבעת הקומיטים בנפרד — הם עצמאיים לגמרי ואינם נוגעים באותם קבצים. ה-.pyc שיחזרו ב-revert יהיו זהים לאלה שעל הדיסק.


🤖 Generated with Claude Code

https://claude.ai/code/session_01P1AYmWhLGtpsr7sSdRZVD3


Generated by Claude Code

Summary by Sourcery

Clean up documentation, test isolation, and repository artifacts identified during validation without changing production behavior.

Bug Fixes:

  • Prevent the documentation import test from writing bytecode into the source tree by isolating its subprocess and disabling bytecode generation.

Enhancements:

  • Make outline scanner documentation describe the stable no-heavy-import invariant without environment-dependent module counts or incomplete module lists.

Documentation:

  • Remove the duplicated configuration guidance while retaining the complete canonical section.

Tests:

  • Update the subprocess-based import test to use an isolated working directory and repository path.

Chores:

  • Remove tracked Python bytecode artifacts from Git while preserving the files locally.