Skip to content

chore(mcp): ארבעה פריטים קטנים מסקירת #3429 — SUGG-014, SUGG-001, SUGG-004, SUGG-010 (#3433) - #3439

Closed
amirbiron wants to merge 1 commit into
mainfrom
claude/gracious-einstein-sevk8p-3433b
Closed

amirbiron wants to merge 1 commit into
mainfrom
claude/gracious-einstein-sevk8p-3433b

Conversation

@amirbiron

@amirbiron amirbiron commented Sep 20, 2026 •

Copy link
Copy Markdown
Owner

✨ תיאור קצר

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

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

פירוט נקודות (רשימת תבליטים):

  • SUGG-004 — _installed_width ו-_width_label ב-mcp_server/server.py. האישו הציע שתי דרכים: getattr(read_pool, "_max_workers", sizing.workers) או להצהיר שכשל עלייה כאן מכוון. נבחרה דרך שלישית שמכבדת את שני העקרונות בבת אחת: המאפיין הפרטי עדיין נקרא (state-record-without-state-change — השורה מתארת את המאגר שקיים, לא את זה שהתבקש), אבל כשהוא ייעלם התשובה היא None — לא הרוחב שהתבקש, שהיה בדיוק ההד שהשורה קיימת כדי למנוע — והשורה מדפיסה read pool 10 (requested; installed width unreadable) threads עם WARNING שאומר למה. שורת לוג לעולם אינה מפילה את העלייה, וההבטחה בדוקסטרינג נשארת נכונה. אותו כלל גם ב-WARNING של ה-fallback, דרך אותה פונקציה. הפורמט במצב הרגיל לא השתנה (read pool 3 threads, הטסט הקיים).
  • SUGG-010 — md_parser.token_count(text). פונקציה ציבורית ומתועדת שסופרת טוקנים על _MD, המופע שהכלי מריץ, בלי env ולכן בלי תקרה ובלי טוקני inline — כלומר בדיוק מה שהפרסור האמיתי סופר. הסקריפט קרא ל-_build_parser הפרטית ובנה פרסר חדש לכל קובץ; עכשיו התלות גלויה ואין בנייה. מחוץ ל-__all__ בכוונה: הרשימה שם היא החוזה של "שני פארסרים בני-החלפה", וטסט מקבע את ההפרש בינה לבין זו של rst_parser (וגם כדי לא להתנגש עם fix(parsers): rst_parser בודק את הקלט בכניסה, וברירת המחדל של max_sections מיושרת ל-MAX_SECTIONS (#3421, #3420) #3436 שעורך את אותו טסט). הנימוק בדוקסטרינג.
  • SUGG-014 — שני טסטים ב-tests/test_mcp_to_thread.py: memory.max שקיים אבל ריק (split() ריק ← IndexError) ו-memory.max עם מילה שאינה max (ValueError) — שניהם נופלים ל-cgroup v1 ומחזירים את הערך שלו, דרך _fake_cgroup הקיים. כיסוי השורות היה מלא; התרחיש חסר.
  • SUGG-001 — האסרשן workers != min(32, cpu_count + 4) or workers == 2 לא יכול היה ליפול אחרי שהשורה שלפניו קיבעה workers == 2. הוחלף: os.cpu_count מוצמד ל-16 כדי ש"cpu_count + 4" יהיה 20 — מספר שהרצפה לעולם אינה — ו-fallback שהיה מתייעץ בליבות המארח היה עונה 20 ונופל.
  • docs/whats-new.rst: רשומה אחת לארבעת הפריטים.

🧪 בדיקות

  • על הקוד הישן (worktree מנותק על origin/main = 1a45c28c, עם שלושת קובצי הטסטים): שלושה נופלים — הרוחב הלא-קריא (AttributeError על _max_workers), token_count (אינו קיים), והסקריפט דרך הפונקציה הציבורית (קורא ל-_build_parser); שלושת האחרים (שני טסטי SUGG-014 ו-SUGG-001) עוברים שם, כי הם מקבעים התנהגות קיימת — ולכן הוכחו במוטציות.
  • מוטציות (worktree על הקוד החדש): ה-fallback מוחזר ל-min(32, cpu_count + 4) ← טסט SUGG-001 נופל; IndexError מוסר מה-except של קורא ה-v2 ← טסט הקובץ הריק נופל; ValueError מוסר ← טסט הקובץ הלא-מספרי נופל.
  • סוויטות: 159 ב-test_mcp_to_thread, test_md_parser, test_measure_md_parse_cost_script, test_mcp_logging_visible (שמריץ uvicorn אמיתי ובודק את שורת הקיבולת בפלט), ועוד 654 ב-test_mcp_server_build, test_mcp_docs_handlers, test_mcp_outline, test_mcp_analytics_privacy, test_mcp_primer, test_md_parser_oracle, test_doc_sections — ירוקים. flake8 עם ה-selection של CI (E9,F63,F7,F82) וגם F401,F841,E303,W291,W293,E501 על הקבצים שנגעתי בהם — נקי (נשאר E302 קיים ב-server.py:206 מ-feat(mcp): docs_get_section קורא גם Markdown, לפי מדיניות נתיבים לכל ריפו #3428, שכבר מתוקן ב-fix(mcp): תקרה לרשימת המועמדים של ambiguous_section, וטסט שמקבע את חוזה Suggestions במסלול ה-Markdown (#3426) #3434 וב-fix(mcp): תקרת גודל לגוף בקשה והגבלת קצב לפי זהות, עם סירוב שנוקב בסיבתו (#3431) #3435). docutils על whats-new.rst — 0 אזהרות.
  • לא אימתתי: פייתון שבו _max_workers באמת חסר — אין כזה; המקרה מדומה באובייקט בלי המאפיין, שזה בדיוק מה שהקוד היה רואה.
  • Unit
  • Integration
  • Manual

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

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

📝 סוג שינוי

  • feat: פיצ'ר חדש
  • fix: תיקון באג
  • docs: שינוי תיעוד בלבד
  • refactor: שינוי קוד ללא שינוי התנהגות
  • perf: שיפור ביצועים
  • chore/ci: תשתית/CI
  • breaking change: שינוי שובר תאימות

✅ צ'קליסט

  • הקוד עוקב אחרי הסגנון (Black/isort/flake8/mypy)
  • בדיקות רצות ועוברות
  • תיעוד עודכן (README/Docs)
  • אם נוספו ג'ובים חדשים (Background Jobs) – לא נוספו
  • אם נוספו/שונו משתני סביבה – לא נוספו
  • אם נוספו/השתנו טוקנים – לא רלוונטי
  • אין סודות/מפתחות בקוד
  • אין מחיקות מסוכנות/פעולות על root (ראו .cursorrules)
  • הודעת הקומיט תואמת Conventional Commits (ע"פ הטבלה)
  • CHANGELOG עודכן אם נדרש — docs/whats-new.rst עודכן
  • כל ה‑Required Checks לעיל ירוקים — ייבדק ב-CI
  • צילום/וידאו UI מצורף אם רלוונטי — לא רלוונטי
  • עיינתי במסמכי אתר התיעוד — נתיב: AI-MAP.md, docs/mcp-server.rst ("מודל הריצה של הכלים" — תיאור שורת הקיבולת), docs/development/scripts.rst (הסקריפט שמודד את עלות הפרסור) | המשפט: "שורת הקיבולת ... קוראת את _max_workers של המאגר שהותקן בפועל" — הכלל שהמימוש כאן שומר גם כשהמאפיין חסר
  • לא נדרש עיון — התנאי התקיים (התנהגות מתועדת)

דפוסי באגים שנקראו ומה שקבעו בקוד: bugbot-rules/state-record-without-state-change.md — הבחירה ב-SUGG-004: כשהמצב אינו קריא, השורה אומרת זאת ואינה מהדהדת את הבקשה; bugbot-rules/silent-fallback-to-worse-path.md — הרוחב הלא-קריא מדווח ב-WARNING, לא נופל בשקט; RECURRING-PATTERNS.md R6 — token_count הוא פונקציה אחת במקום בנייה חוזרת של פרסר; claude-md-snippets/testing.md §5 + TESTING-PATTERNS.md T2 — ריצה על הקוד הישן, ומוטציות לשלושת הטסטים שעוברים שם; bugbot-rules/widened-exception-scope.md — לא הורחב אף except (המוטציות דווקא מצרות אותו כדי להוכיח את הטסטים).

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

  • ייצור: אין שינוי בפלט של שורת הקיבולת על פייתון 3.11/3.12; אין שינוי בפרסור. הסקריפט מודד את אותה צפיפות (token_count על _MD הוא אותו פרסר באותה תצורה).

🔗 קישורים

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

  • revert של הקומיט היחיד. אין מיגרציה ואין משתנה סביבה.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SfJTSpDAhDr2yhtmpFkwTx


Generated by Claude Code

Review in cubic

Summary by Sourcery

Address four small review follow-ups across MCP capacity reporting, cgroup limit handling, Markdown measurement, and test reliability.

Bug Fixes:

  • Make MCP capacity logging resilient when the installed thread-pool width cannot be read, reporting the limitation instead of failing startup.
  • Handle empty and malformed cgroup v2 memory-limit files by falling back to cgroup v1 values.

Enhancements:

  • Expose a documented Markdown token-counting API and update the measurement script to use it instead of the private parser builder.
  • Correct the fallback worker-count test so it reliably validates the conservative floor.

Documentation:

  • Document the four review follow-ups in the what's-new notes.

Tests:

  • Add coverage for unreadable thread-pool capacity, malformed cgroup v2 limits, the public Markdown token-counting API, and its script integration.

…G-004, SUGG-010 (#3433)

- SUGG-004: שורת הקיבולת קוראת את ThreadPoolExecutor._max_workers הפרטי
  דרך _installed_width, וכשהמאפיין ייעלם היא מדפיסה את הרוחב שהתבקש עם
  "(requested; installed width unreadable)" ו-WARNING שאומר למה — במקום
  שהשירות לא יעלה בגלל שורת לוג, ובמקום להדהד את הבקשה כאילו היא המצב
  (state-record-without-state-change). אותו כלל גם ב-WARNING של ה-fallback.
- SUGG-010: md_parser.token_count — פונקציה ציבורית ומתועדת שסופרת טוקנים
  על _MD, המופע שהכלי מריץ — במקום שהסקריפט יקרא ל-_build_parser הפרטית
  ויבנה פרסר חדש לכל קובץ. מחוץ ל-__all__ בכוונה: הרשימה שם היא החוזה של
  "שני פארסרים בני-החלפה", וטסט מקבע את ההפרש בינה לבין זו של rst_parser.
- SUGG-014: שני טסטים לקובץ memory.max שקיים אבל ריק (IndexError) או
  לא-מספרי (ValueError) — שניהם נופלים ל-cgroup v1 ומחזירים את הערך שלו.
  כיסוי השורות היה מלא; התרחיש חסר. מוטציה שמסירה כל אחת מהחריגות
  מה-except מפילה את הטסט שלה.
- SUGG-001: האסרשן שלא יכול היה ליפול הוחלף: os.cpu_count מוצמד ל-16 כדי
  ש"cpu_count + 4" יהיה 20, מספר שהרצפה לעולם אינה — ומוטציה שמחזירה את
  ה-fallback ל-min(32, cpu_count + 4) מפילה אותו.

על origin/main: שלושה טסטים נופלים (הרוחב הלא-קריא, token_count, הסקריפט
דרך הפונקציה הציבורית); שלושת האחרים עוברים שם ומוכחים במוטציות.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfJTSpDAhDr2yhtmpFkwTx
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @amirbiron, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 13 minutes by commenting @sourcery-ai review. Upgrade to get a review now.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Next included review available in 52 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 10143381-639a-4f4d-9477-bf5f5f7fcb8b

📥 Commits

Reviewing files that changed from the base of the PR and between 1a45c28 and be911e0.

📒 Files selected for processing (7)
  • docs/whats-new.rst
  • mcp_server/server.py
  • scripts/measure_md_parse_cost.py
  • services/md_parser.py
  • tests/test_mcp_to_thread.py
  • tests/test_md_parser.py
  • tests/test_measure_md_parse_cost_script.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🧯 Dangerous deletes guard report

Policy: see .cursorrules — dangerous deletions are blocked unless wrapped safely.

Summary:

  • Flagged findings (blocking): 0
    0
  • Excluded matches (not blocking): 15
  • Total matches (all files): 128

Flagged findings (file:line:snippet):
(none)

Excluded matches (by path pattern)
./webapp/static/js/md_preview.bundle.js.map:4:  "sourcesContent": ["// Markdown-it plugin to render GitHub-style task lists; see\n//\n// https://github.com/blog/1375-task-lists-in-gfm-issues-pulls-comments\n// https://github.com/blog/1825-t … [truncated]
./docs/DOCUMENTATION_GUIDE.md:453:rm -rf _build
./docs/Makefile:24:	rm -rf $(BUILDDIR)
./Dockerfile:42:    rm -rf /var/lib/apt/lists/*
./Dockerfile:121:    rm -rf /var/lib/apt/lists/*
./node_modules/katex/package.json:153:    "build": "rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c --failAfterWarnings && webpack && node update-sri.js package dist/README.md",
./node_modules/katex/src/fonts/Makefile:139:	rm -rf pfa ff otf ttf woff woff2
./node_modules/mermaid/dist/mermaid.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values for tr … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm/chunk-2M32CCKP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence d … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequen … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.esm.min/chunk-4HFYJGYH.mjs:1:var r={name:"mermaid",version:"11.12.0",description:"Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graph … [truncated]
./node_modules/mermaid/dist/chunks/mermaid.core/chunk-KS23V3DP.mjs.map:4:  "sourcesContent": ["{\n  \"name\": \"mermaid\",\n  \"version\": \"11.12.0\",\n  \"description\": \"Markdown-ish syntax for generating flowcharts, mindmaps, sequence  … [truncated]
./node_modules/mermaid/dist/mermaid.min.js:1524:`,"getStyles"),c1e=RQe});var h1e={};dr(h1e,{diagram:()=>NQe});var NQe,f1e=N(()=>{"use strict";$ge();a1e();l1e();u1e();NQe={parser:Fge,db:n1e,renderer:o1e,styles:c1e}});var m1e,g1e=N(()=>{"use  … [truncated]
./node_modules/mermaid/dist/mermaid.min.js.map:4:  "sourcesContent": ["/**\n* Default values for dimensions\n*/\nconst defaultIconDimensions = Object.freeze({\n\tleft: 0,\n\ttop: 0,\n\twidth: 16,\n\theight: 16\n});\n/**\n* Default values fo … [truncated]
./README.md:842:find . -name "__pycache__" -exec rm -rf {} +

@sourcery-ai

sourcery-ai Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

This maintenance PR hardens MCP startup diagnostics, exposes shared Markdown token counting for the measurement script, adds missing cgroup parsing coverage, and fixes an ineffective fallback assertion, with corresponding documentation and tests.

Sequence diagram for resilient MCP capacity logging

sequenceDiagram
    participant Startup
    participant Logger
    participant Pool
    participant Sizing
    Startup->>Logger: _log_dispatch_capacity(read_pool, memory_display, sizing)
    Logger->>Pool: _installed_width(read_pool)
    alt _max_workers available
        Pool-->>Logger: installed width
        Logger->>Sizing: _width_label(read_pool, sizing)
        Sizing-->>Logger: installed width
    else _max_workers unavailable
        Pool-->>Logger: None
        Logger-->>Logger: warning(unreadable installed width)
        Logger->>Sizing: _width_label(read_pool, sizing)
        Sizing-->>Logger: requested width (unreadable)
    end
    Logger-->>Startup: capacity line, startup continues
Loading

Sequence diagram for shared Markdown token counting

sequenceDiagram
    participant Script as measure_md_parse_cost.py
    participant Parser as md_parser
    participant MD as _MD
    Script->>Parser: token_count(text)
    Parser->>MD: parse(text)
    MD-->>Parser: block tokens
    Parser-->>Script: token count
    Script-->>Script: compute density per KB
Loading

File-Level Changes

Change Details Files
Make read-pool capacity logging resilient when CPython’s private executor width is unavailable.
  • Read _max_workers through a helper that returns None when absent.
  • Report requested width as explicitly unreadable and emit a warning instead of failing startup.
  • Use the same honest labeling in the memory-limit fallback log path.
mcp_server/server.py
tests/test_mcp_to_thread.py
Replace the measurement script’s private parser construction with a documented public token-counting API.
  • Add md_parser.token_count() backed by the shared _MD instance.
  • Update Markdown density measurement to use the public function without exporting it via __all__.
  • Add coverage proving the script does not call _build_parser and the API preserves parser behavior.
services/md_parser.py
scripts/measure_md_parse_cost.py
tests/test_md_parser.py
tests/test_measure_md_parse_cost_script.py
Expand cgroup fallback tests to cover malformed readable v2 limit files.
  • Verify empty and non-numeric memory.max values fall through to cgroup v1.
tests/test_mcp_to_thread.py
Repair the fallback sizing test so its assertion can detect regression to the host-CPU default.
  • Pin os.cpu_count() to 16 and rely on the resulting distinction between the floor and cpu_count + 4.
tests/test_mcp_to_thread.py
Document the four maintenance fixes in the release notes.
  • Add a whats-new entry covering capacity logging, parser API usage, cgroup edge cases, and fallback-test correction.
docs/whats-new.rst

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions

Copy link
Copy Markdown
Contributor

⏱️ Performance report

(No performance test durations collected. Mark tests with @pytest.mark.performance.)

@github-actions

Copy link
Copy Markdown
Contributor

📖 Documentation Preview

The documentation has been built successfully!

To view locally:

  1. Download the artifacts
  2. Extract the zip file
  3. Open index.html in your browser

@codecov

codecov Bot commented Sep 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@amirbiron

Copy link
Copy Markdown
Owner Author

נכנס דרך #3443

@amirbiron amirbiron closed this Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants