fix(calibration): drop block-yod + per-cell guard + incremental write (#208) #365

Merged
chaim merged 1 commits from worktree-agent-aeea23e1387d8d3cb into main 2026-06-30 15:50:37 +00:00
Owner

מה ולמה

ריצת-כיול חיה של scripts/calibrate_effort.py (#208, מוזג ב-PR #360) קרסה ואיבדה ~2 שעות עבודה. הלולאה per-(תיק,בלוק,effort) ב-_run() קראה ל-_score_cell ללא טיפול-שגיאות; כשהגיעה ל-block-yod (בלוק הדיון), block_writer.write_block זרק ValueError("לא ניתן לכתוב בלוק דיון ללא כיוון מאושר…") כי בלוק-הדיון דורש כיוון-מאושר (brainstorm → approve_direction) שתיקי-הכיול חסרים. החריגה הפילה את כל הריצה, ומכיוון שהדוח נכתב רק בסוף ב-main() — כל הייצורים שכבר הושלמו אבדו.

שלושה תיקוני-עמידות (ללא שינוי לוגיקת-מדידה/ניקוד — G2):

  1. block-yod הוצא מ-CALIBRATABLE_BLOCKS (ברירת-מחדל) — מחוץ לתחום WS5 של טיוטת-הביניים וגם לא-ניתן-לכיול standalone (דורש כיוון-מאושר). נשמר ב-VALID_BLOCKS חדש כך שאפשר עדיין לכפות --blocks block-yod ידנית.
  2. try/except per-תא ב-_run() — כל כשל של תא בודד (תיק,בלוק,effort) נרשם כ-warning (case/block/effort/error) ומדולג, לעולם לא פטאלי. הגנה-לעומק לכפיית block-yod וגם ל-rate-limits חולפים באמצע-ריצה.
  3. כתיבה אינקרמנטלית_write_report נכתב אחרי כל בלוק שמסתיים (ts מושחל ל-_run), כך שקריסה מאוחרת בגריד לא מאבדת בלוקים שהושלמו. צורת ה-JSON/MD זהה — תוצאות חלקיות פשוט משמיטות בלוקים שטרם נגמרו מ-by_block. הכתיבה הסופית ב-main() נשארת.

Invariants — הצהרה (חובה)

  • נוגע / מקיים:
    • G8 (eval-harness robustness) — תוצאות חלקיות נשמרות; כשל-תא-בודד אינו פטאלי; ה-harness שורד את ה-raise של block-yod (כיוון-חסר) ואת ה-rate-limits.
    • G2 (מקור-מדידה יחיד) — אין שינוי במסלול-המדידה; _score_cell / block_distance_to_final / recommend_effort / aggregate_cell לא נגעתי.

צ'קליסט — פרוטוקול כתיבת-קוד

  • קראתי את docs/spec/00-constitution.md + ספ-התחום הרלוונטי לפני הכתיבה
  • השינוי לא יוצר מסלול מקביל ליכולת קיימת (G2) ולא מתקן תסמין בקריאה (G1) — רק טיפול-שגיאות, רשימת-בלוקים וקצב-persistence
  • לא הוספתי מגע-Paperclip מחוץ ל-Platform Port (G12)
  • אין בליעה שקטה של שגיאות — כל כשל-תא מסומן ומדווח כ-warning (case/block/effort/error)
  • בדקתי מול docs/spec/gap-audit.md — אין נגיעה ב-GAP/FU ממופה
  • בדיקות עוברות — --self-test ALL PASS (14/14)
  • לא data-migration

אימות

  • mcp-server/.venv/bin/python scripts/calibrate_effort.py --self-testALL PASS (14/14 assertions)
  • python -c "import ast; ast.parse(open('scripts/calibrate_effort.py').read())" → נקי
  • אומת ש-block-yod הוסר מברירת-המחדל: CALIBRATABLE_BLOCKS = [block-he, block-vav, block-zayin, block-chet, block-tet, block-yod-alef]; VALID_BLOCKS כולל block-yod לכפייה ידנית. לכן --dry-run בברירת-מחדל אינו מציג block-yod.
  • scripts/SCRIPTS.md עודכן לתיאור ההתנהגות החדשה (כתיבה אינקרמנטלית, שער-per-תא, block-yod מחוץ-לברירת-מחדל).

🤖 Generated with Claude Code

## מה ולמה ריצת-כיול חיה של `scripts/calibrate_effort.py` (#208, מוזג ב-PR #360) קרסה ואיבדה ~2 שעות עבודה. הלולאה per-(תיק,בלוק,effort) ב-`_run()` קראה ל-`_score_cell` **ללא טיפול-שגיאות**; כשהגיעה ל-`block-yod` (בלוק הדיון), `block_writer.write_block` זרק `ValueError("לא ניתן לכתוב בלוק דיון ללא כיוון מאושר…")` כי בלוק-הדיון דורש כיוון-מאושר (`brainstorm → approve_direction`) שתיקי-הכיול חסרים. החריגה הפילה את כל הריצה, ומכיוון שהדוח נכתב רק בסוף ב-`main()` — כל הייצורים שכבר הושלמו אבדו. שלושה תיקוני-עמידות (ללא שינוי לוגיקת-מדידה/ניקוד — G2): 1. **`block-yod` הוצא מ-`CALIBRATABLE_BLOCKS`** (ברירת-מחדל) — מחוץ לתחום WS5 של טיוטת-הביניים **וגם** לא-ניתן-לכיול standalone (דורש כיוון-מאושר). נשמר ב-`VALID_BLOCKS` חדש כך שאפשר עדיין לכפות `--blocks block-yod` ידנית. 2. **try/except per-תא ב-`_run()`** — כל כשל של תא בודד (תיק,בלוק,effort) נרשם כ-warning (case/block/effort/error) ומדולג, לעולם לא פטאלי. הגנה-לעומק לכפיית block-yod **וגם** ל-rate-limits חולפים באמצע-ריצה. 3. **כתיבה אינקרמנטלית** — `_write_report` נכתב אחרי כל בלוק שמסתיים (`ts` מושחל ל-`_run`), כך שקריסה מאוחרת בגריד לא מאבדת בלוקים שהושלמו. צורת ה-JSON/MD זהה — תוצאות חלקיות פשוט משמיטות בלוקים שטרם נגמרו מ-`by_block`. הכתיבה הסופית ב-`main()` נשארת. ## Invariants — הצהרה (חובה) - **נוגע / מקיים:** - **G8 (eval-harness robustness)** — תוצאות חלקיות נשמרות; כשל-תא-בודד אינו פטאלי; ה-harness שורד את ה-raise של block-yod (כיוון-חסר) ואת ה-rate-limits. - **G2 (מקור-מדידה יחיד)** — אין שינוי במסלול-המדידה; `_score_cell` / `block_distance_to_final` / `recommend_effort` / `aggregate_cell` לא נגעתי. ## צ'קליסט — פרוטוקול כתיבת-קוד - [x] קראתי את `docs/spec/00-constitution.md` + ספ-התחום הרלוונטי לפני הכתיבה - [x] השינוי **לא** יוצר מסלול מקביל ליכולת קיימת (G2) ולא מתקן תסמין בקריאה (G1) — רק טיפול-שגיאות, רשימת-בלוקים וקצב-persistence - [x] **לא** הוספתי מגע-Paperclip מחוץ ל-Platform Port (G12) - [x] אין בליעה שקטה של שגיאות — כל כשל-תא מסומן ומדווח כ-warning (case/block/effort/error) - [x] בדקתי מול `docs/spec/gap-audit.md` — אין נגיעה ב-GAP/FU ממופה - [x] בדיקות עוברות — `--self-test` ALL PASS (14/14) - [x] לא data-migration ## אימות - `mcp-server/.venv/bin/python scripts/calibrate_effort.py --self-test` → **ALL PASS** (14/14 assertions) - `python -c "import ast; ast.parse(open('scripts/calibrate_effort.py').read())"` → נקי - אומת ש-`block-yod` הוסר מברירת-המחדל: `CALIBRATABLE_BLOCKS = [block-he, block-vav, block-zayin, block-chet, block-tet, block-yod-alef]`; `VALID_BLOCKS` כולל `block-yod` לכפייה ידנית. לכן `--dry-run` בברירת-מחדל אינו מציג block-yod. - `scripts/SCRIPTS.md` עודכן לתיאור ההתנהגות החדשה (כתיבה אינקרמנטלית, שער-per-תא, block-yod מחוץ-לברירת-מחדל). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-06-30 15:50:07 +00:00
fix(calibration): drop block-yod + per-cell guard + incremental write (#208)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 5s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
70a06c3745
A live calibration run crashed with no error handling and lost ~2h of work:
the per-cell loop in _run() reached block-yod (discussion), block_writer.write_block
raised ValueError("לא ניתן לכתוב בלוק דיון ללא כיוון מאושר…") because the discussion
block needs an approved direction calibration cases don't have, and since the report
was only written at the very end of main(), every completed generation was lost.

Three robustness fixes (no metric/scoring change — G2):

1. Drop block-yod from default CALIBRATABLE_BLOCKS — out of WS5 interim-draft scope
   AND structurally non-calibratable standalone (needs brainstorm→approve_direction).
   Kept in new VALID_BLOCKS so a user can still force it via --blocks block-yod.
2. Per-cell try/except in _run(): any single (case, block, effort) cell failure is
   logged as a warning (case/block/effort/error) and skipped, never fatal —
   defense-in-depth for a forced block-yod and for transient rate-limits mid-run.
3. Incremental persistence: _write_report flushes after each completed block (ts
   threaded into _run), so a crash later in the grid never loses finished blocks.
   JSON/MD shape unchanged — partial results omit not-yet-done blocks from by_block.

--self-test: ALL PASS (14/14). block-yod gone from --dry-run defaults.

Invariants — נוגע / מקיים:
- G8 (eval-harness robustness) — partial results persist; a single-cell failure is
  non-fatal; the harness survives block-yod's missing-direction raise and rate-limits.
- G2 (מקור-מדידה יחיד) — no metric-path change; _score_cell / block_distance_to_final
  / recommend_effort / aggregate_cell untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chaim merged commit 73d2f15915 into main 2026-06-30 15:50:37 +00:00
chaim deleted branch worktree-agent-aeea23e1387d8d3cb 2026-06-30 15:50:37 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ezer-mishpati/legal-ai#365