feat(calibration): כיול-אמפירי model×effort מול הסופיים (#208) #360

Merged
chaim merged 1 commits from worktree-agent-a5a22be0318670871 into main 2026-06-30 12:15:47 +00:00
Owner

מה ולמה

#208 (WS5 / Q1 בתוכנית עיצוב-מחדש זרימת-העבודה): כיול-אמפירי של ה-effort הנעוץ per-בלוק (#204/PR #356) מול הגרסאות הסופיות של דפנה. במקום לבחור effort "לפי תחושה", ההארנס מודד אילו (model×effort) מייצרים בלוק שהכי קרוב לסופי — INV-G8 (איכות נמדדת אמפירית, לא מונחת) מורם משכבת-האחזור גם לשכבת-הכתיבה.

איך זה עובד

לכל תא בגריד (תיק, בלוק, effort) מעל draft_final_pairs בעלי final_text:

  1. מייצר מחדש את הבלוק דרך מסלול-הייצורblock_writer.write_block(effort_override=…)claude_session.queryclaude -p (Opus 4.8 נעוץ, מקומי-בלבד).
  2. מודד מול הסקשן המתאים בסופי דרך style_distance.block_distance_to_final: change_percent (compute_diff_stats) · anti_pattern_total (lessons.ANTI_PATTERNS, הסיגנל הנקי-לסגנון) · golden_ratio_deviation_pp · distance מרוכב מנורמל.
  3. ממליץ per-בלוק על ה-effort בעל ה-distance-הממוצע-הנמוך (ties → פחות anti-patterns → change_percent נמוך), לצד ברירת-המחדל מ-#204.

דוח → data/eval/effort-calibration-<ts>.{json,md} (במודל eval_retrieval.py).

⚠️ אזהרת גודל-מדגם (מכובדת, לא מוסתרת)

מעט תיקים בעלי סופי-עלוי → ההארנס מדפיס n_finals בראש הדוח ומסמן את הפלט עדות-כיוון, לא רגרסיה. עם n<3 לבלוק ההמלצה אדוויזורית בלבד; ההכרעה בידי היו"ר/המפעיל. בנוסף change_percent מערבב סגנון עם שלמות-תוכן (07-learning §0.7) — anti_pattern_total הוא הסיגנל הנקי-יותר, והדוח מציג את שניהם.

הרצה חיה = host-only

מסלול-הייצור עובר claude CLI שקיים רק על המארח (לא בקונטיינר legal-ai, לא ב-worktree ללא-CLI). לכן ה-A/B החי לא ניתן-להרצה כאן; --self-test מוכיח את לוגיקת-המדידה offline (אפס DB/CLI) — 14/14 PASS.

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

  • נוגע / מקיים:
    • G8 (eval-harness) — איכות-הכתיבה נמדדת אמפירית מול הסופי; ההארנס הוא המדידה ש-INV-G8 דורש, מורם לשכבת-הכתיבה.
    • G2 (מקור-אמת יחיד)block_distance_to_final/split_final_by_section עושים reuse ל-compute_diff_stats (learning_loop), count_anti_patterns/golden-ים (style_distance) ו-chunker._split_into_sections (אותו splitter כמו measure_corpus_ratios). אין מסלול-מדידה מקביל.
    • claude_session local-only (reference_claude_generation_path) — הייצור עובר claude -p בלבד; אין Anthropic SDK; ה-knob היחיד הוא effort (Opus 4.7/4.8 דוחים temperature→400).
    • INV-LRN4/5 — מדידה מול הסופי per-בלוק (ניגוד-אמת); המדידה היא סגנון בלבד (anti-patterns/יחסי-מבנה/diff) — אין מהות-תיק נגררת.

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

  • קראתי את docs/spec/00-constitution.md + ספ-התחום (07-learning.md, 06-export.md) לפני הכתיבה
  • השינוי לא יוצר מסלול מקביל ליכולת קיימת (G2) — reuse של style_distance/learning_loop/chunker; ולא מתקן תסמין בקריאה (G1)
  • לא הוספתי מגע-Paperclip מחוץ ל-Platform Port (G12) — mcp-server/src וה-skills נקיים
  • אין בליעה שקטה — סקשן שלא-ממו��ה נזרק במפורש; denominator לא-ידוע → None (לא מומצא)
  • בדקתי מול docs/spec/gap-audit.md — אין GAP/FU ממופה שנדרס; ממומש כ-WS5/#208
  • בדיקות עוברות — --self-test 14/14 PASS; py_compile נקי; test_audit_provenance 4 passed
  • data-migration — לא רלוונטי (read-only על draft_final_pairs; הדוח ל-data/eval/)

אימות

$ mcp-server/.venv/bin/python scripts/calibrate_effort.py --self-test
  identical regen ⇒ change_percent==0 ... ok   (14 assertions)
  ALL PASS
$ python -c "import style_distance, block_writer, learning_loop"  # אין circular import
$ python scripts/calibrate_effort.py --efforts bogus   → exit 2 (ולידציה)
$ python scripts/calibrate_effort.py --blocks block-alef → exit 2 (template-block נדחה)

הריצה החיה (host-only): POSTGRES_PASSWORD=… mcp-server/.venv/bin/python scripts/calibrate_effort.py — תרוץ על המארח שבו קיים ה-claude CLI.

קבצים: scripts/calibrate_effort.py (חדש) · scripts/SCRIPTS.md · mcp-server/src/legal_mcp/services/style_distance.py · mcp-server/src/legal_mcp/services/block_writer.py.

🤖 Generated with Claude Code

## מה ולמה #208 (WS5 / Q1 בתוכנית עיצוב-מחדש זרימת-העבודה): **כיול-אמפירי של ה-effort הנעוץ per-בלוק (#204/PR #356) מול הגרסאות הסופיות של דפנה.** במקום לבחור effort "לפי תחושה", ההארנס מודד אילו (model×effort) מייצרים בלוק שהכי **קרוב לסופי** — INV-G8 (איכות נמדדת אמפירית, לא מונחת) מורם משכבת-האחזור גם לשכבת-הכתיבה. ### איך זה עובד לכל תא בגריד `(תיק, בלוק, effort)` מעל `draft_final_pairs` בעלי `final_text`: 1. מייצר מחדש את הבלוק דרך **מסלול-הייצור** — `block_writer.write_block(effort_override=…)` → `claude_session.query` → `claude -p` (Opus 4.8 נעוץ, **מקומי-בלבד**). 2. מודד מול ה**סקשן** המתאים בסופי דרך `style_distance.block_distance_to_final`: `change_percent` (compute_diff_stats) · `anti_pattern_total` (`lessons.ANTI_PATTERNS`, הסיגנל הנקי-לסגנון) · `golden_ratio_deviation_pp` · `distance` מרוכב מנורמל. 3. **ממליץ** per-בלוק על ה-effort בעל ה-distance-הממוצע-הנמוך (ties → פחות anti-patterns → change_percent נמוך), לצד ברירת-המחדל מ-#204. דוח → `data/eval/effort-calibration-<ts>.{json,md}` (במודל `eval_retrieval.py`). ### ⚠️ אזהרת גודל-מדגם (מכובדת, לא מוסתרת) מעט תיקים בעלי סופי-עלוי → ההארנס מדפיס `n_finals` **בראש הדוח** ומסמן את הפלט **עדות-כיוון, לא רגרסיה**. עם n<3 לבלוק ההמלצה אדוויזורית בלבד; ההכרעה בידי היו"ר/המפעיל. בנוסף `change_percent` מערבב סגנון עם שלמות-תוכן (07-learning §0.7) — `anti_pattern_total` הוא הסיגנל הנקי-יותר, והדוח מציג את שניהם. ### הרצה חיה = host-only מסלול-הייצור עובר `claude` CLI שקיים רק על המארח (לא בקונטיינר legal-ai, לא ב-worktree ללא-CLI). לכן ה-A/B החי לא ניתן-להרצה כאן; **`--self-test` מוכיח את לוגיקת-המדידה offline (אפס DB/CLI) — 14/14 PASS.** ## Invariants — הצהרה (חובה) - **נוגע / מקיים:** - **G8 (eval-harness)** — איכות-הכתיבה נמדדת אמפירית מול הסופי; ההארנס הוא המדידה ש-INV-G8 דורש, מורם לשכבת-הכתיבה. - **G2 (מקור-אמת יחיד)** — `block_distance_to_final`/`split_final_by_section` עושים reuse ל-`compute_diff_stats` (learning_loop), `count_anti_patterns`/`golden`-ים (style_distance) ו-`chunker._split_into_sections` (אותו splitter כמו `measure_corpus_ratios`). אין מסלול-מדידה מקביל. - **claude_session local-only** (`reference_claude_generation_path`) — הייצור עובר `claude -p` בלבד; אין Anthropic SDK; ה-knob היחיד הוא `effort` (Opus 4.7/4.8 דוחים temperature→400). - **INV-LRN4/5** — מדידה מול הסופי per-בלוק (ניגוד-אמת); המדידה היא סגנון בלבד (anti-patterns/יחסי-מבנה/diff) — אין מהות-תיק נגררת. ## צ'קליסט — פרוטוקול כתיבת-קוד - [x] קראתי את `docs/spec/00-constitution.md` + ספ-התחום (`07-learning.md`, `06-export.md`) לפני הכתיבה - [x] השינוי **לא** יוצר מסלול מקביל ליכולת קיימת (G2) — reuse של style_distance/learning_loop/chunker; ולא מתקן תסמין בקריאה (G1) - [x] **לא** הוספתי מגע-Paperclip מחוץ ל-Platform Port (G12) — `mcp-server/src` וה-skills נקיים - [x] אין בליעה שקטה — סקשן שלא-ממו��ה נזרק במפורש; denominator לא-ידוע → `None` (לא מומצא) - [x] בדקתי מול `docs/spec/gap-audit.md` — אין GAP/FU ממופה שנדרס; ממומש כ-WS5/#208 - [x] בדיקות עוברות — `--self-test` 14/14 PASS; `py_compile` נקי; `test_audit_provenance` 4 passed - [ ] data-migration — לא רלוונטי (read-only על draft_final_pairs; הדוח ל-`data/eval/`) ## אימות ``` $ mcp-server/.venv/bin/python scripts/calibrate_effort.py --self-test identical regen ⇒ change_percent==0 ... ok (14 assertions) ALL PASS $ python -c "import style_distance, block_writer, learning_loop" # אין circular import $ python scripts/calibrate_effort.py --efforts bogus → exit 2 (ולידציה) $ python scripts/calibrate_effort.py --blocks block-alef → exit 2 (template-block נדחה) ``` הריצה החיה (host-only): `POSTGRES_PASSWORD=… mcp-server/.venv/bin/python scripts/calibrate_effort.py` — תרוץ על המארח שבו קיים ה-`claude` CLI. קבצים: `scripts/calibrate_effort.py` (חדש) · `scripts/SCRIPTS.md` · `mcp-server/src/legal_mcp/services/style_distance.py` · `mcp-server/src/legal_mcp/services/block_writer.py`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-06-30 12:14:48 +00:00
feat(calibration): כיול-אמפירי model×effort מול הסופיים (#208)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
f935f166a9
A/B harness שמכייל את ה-effort הנעוץ per-בלוק (#204) מול הסופיים של דפנה:
מייצר מחדש כל בלוק דרך מסלול-הייצור (write_block(effort_override=…) →
claude_session.query → claude -p, Opus 4.8, מקומי-בלבד) ומודד מול הסקשן
המתאים בסופי דרך style_distance.block_distance_to_final (change_percent,
anti_pattern_total, golden-ratio deviation, composite distance). ממליץ
per-בלוק על ה-effort הקרוב-ביותר לסופי.

- scripts/calibrate_effort.py — ההארנס (מודל eval_retrieval.py): --self-test
  (offline, מוכיח מדידה+המלצה, אפס DB/CLI) · --dry-run · --efforts/--blocks/
  --case/--repeats. דוח data/eval/effort-calibration-<ts>.{json,md} עם
  גודל-מדגם בולט — עדות-כיוון, לא רגרסיה (מעט סופיים-עלויים).
- style_distance.py — block_distance_to_final + split_final_by_section
  (מקור-מדידה יחיד, G2; reuse compute_diff_stats/count_anti_patterns/chunker).
- block_writer.py — write_block(effort_override=) להזרקת effort per-קריאה
  בלי לדרוס את ברירות-המחדל הנעוצות; רושם את ה-effort האפקטיבי.
- scripts/SCRIPTS.md — ערך חדש.

Invariants: G8 (eval-harness — מדידה אמפירית, לא הנחה) · G2 (reuse של
style_distance/learning_loop — אין מסלול-מדד מקביל) · claude_session
local-only (reference_claude_generation_path) · INV-LRN4/5 (השוואה מול
הסופי, מדידת-סגנון; אין מהות-תיק נגררת). אומת: --self-test 14/14 PASS.
הריצה החיה host-only (claude CLI) — לא ניתנת-להרצה ב-worktree/קונטיינר.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chaim merged commit eb0653fb80 into main 2026-06-30 12:15:47 +00:00
chaim deleted branch worktree-agent-a5a22be0318670871 2026-06-30 12:15:47 +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#360