feat(learning): graduated gate — panel-consensus style lessons auto-flow to writer (P0)
The voice-learning panel produced 81 vetted style lessons — all stuck at review_status='proposed' with 0 ever approved — so the writer (which reads only 'approved') received NONE of them. The system captured learning but never let it flow. Chair decision (2026-06-28): a GRADUATED gate by content risk. - STYLE lessons (categories style/structure/lexicon/tabular) the 2/2 panel kept → created as review_status='approved' → flow to the writer immediately, reversibly (chair vetoes in /training). The deepseek+gemini panel only emits style_method and only on 2/2 consensus, so this is exactly the gate's criterion; substance is already filtered out and skipped, and routes through the strict halacha gate. - SUBSTANCE (halacha/precedent/fact) stays a HARD chair gate — unchanged. style_lesson_panel.py: _review_status_for(category) sets the gate explicitly (approved for _STYLE_CATEGORIES, else proposed); the apply loop passes it to db.add_decision_lesson (which already accepts review_status — no DB change). Spec: INV-LRN1 rewritten as the graduated gate (hard for substance; reversible auto-flow for consensus style — still "under user control" via veto, per NCSC/CEPEJ); §0.6 updated to match. A one-time backfill of the 81 existing panel style lessons to 'approved' runs separately (DB, post-merge). Invariants: INV-LRN1 (amended — graduated), INV-LRN5 (style-only, substance never auto-flows), G10 (human control preserved as reversible veto). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,9 +62,9 @@
|
|||||||
3. **בדיקת-ציטוטים** — `extract_internal_citations` מקשר את הפסיקה שההחלטה מצטטת לספרייה; כל ציטוט שאינו בספרייה **מסומן אוטומטית** כ-`missing_precedent` (open) להעלאה ע"י היו"ר.
|
3. **בדיקת-ציטוטים** — `extract_internal_citations` מקשר את הפסיקה שההחלטה מצטטת לספרייה; כל ציטוט שאינו בספרייה **מסומן אוטומטית** כ-`missing_precedent` (open) להעלאה ע"י היו"ר.
|
||||||
4. הציטוטים-המקושרים מזינים את **לולאת-ה-corroboration** (X11): ציטוט-נכנס מההחלטה שלנו מחזק את ההלכות של התקדים המצוטט (`corroboration_rebuild`).
|
4. הציטוטים-המקושרים מזינים את **לולאת-ה-corroboration** (X11): ציטוט-נכנס מההחלטה שלנו מחזק את ההלכות של התקדים המצוטט (`corroboration_rebuild`).
|
||||||
ואז שני שלבים אוטומטיים נפרדים (`run-learning` / `run-halacha`) המעירים worker מקומי (claude/DeepSeek/Gemini מקומיים בלבד):
|
ואז שני שלבים אוטומטיים נפרדים (`run-learning` / `run-halacha`) המעירים worker מקומי (claude/DeepSeek/Gemini מקומיים בלבד):
|
||||||
- **למידה:** `ingest_final_version` (Opus distillation) → **פאנל-סגנון דו-סוכני** (DeepSeek+Gemini, "למידה כפולה") שמצביע על כל לקח-style_method; הסכמה 2/2 → `decision_lesson` (`source=panel:deepseek+gemini`); פיצול → ליו"ר.
|
- **למידה:** `ingest_final_version` (Opus distillation) → **פאנל-סגנון דו-סוכני** (DeepSeek+Gemini, "למידה כפולה") שמצביע על כל לקח-style_method; הסכמה 2/2 → `decision_lesson` (`source=panel:deepseek+gemini`) **שזורם אוטומטית לכותב** כ-`approved` (שער-מדורג, INV-LRN1) — הפיך (veto-יו"ר ב-/training); פיצול → ליו"ר.
|
||||||
- **הלכות:** `extract_internal_citations` → `precedent_extract_halachot` → `corroboration_rebuild` → **פאנל-הלכות תלת-סוכני** (`halacha_panel_approve.py --apply`).
|
- **הלכות:** `extract_internal_citations` → `precedent_extract_halachot` → `corroboration_rebuild` → **פאנל-הלכות תלת-סוכני** (`halacha_panel_approve.py --apply`).
|
||||||
שני הפאנלים **הפיכים** (גיבוי-CSV ל-`data/audit/`) ומסלימים מחלוקות. ההטמעה הסופית ל-`SKILL.md`/`legal-decision-lessons.md` נשארת **אישור-יו"ר ידני** (INV-LRN1/G10) — הפאנל יוצר *הצעות* בלבד.
|
שני הפאנלים **הפיכים** (גיבוי-CSV ל-`data/audit/`) ומסלימים מחלוקות. ההטמעה ל-`SKILL.md`/`legal-decision-lessons.md` ולכל **מהות** נשארת **אישור-יו"ר ידני קשיח** (INV-LRN1/G10); לקחי-**סגנון** בקונצנזוס זורמים אוטומטית-והפיך לכותב.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -162,13 +162,12 @@
|
|||||||
|
|
||||||
## 3. Invariants של התחום
|
## 3. Invariants של התחום
|
||||||
|
|
||||||
### INV-LRN1: עדכון-ידע דורש אישור-יו"ר ידני — אין auto-commit (governance →G10)
|
### INV-LRN1: עדכון-ידע דורש שער-יו"ר — **שער מדורג** לפי סיכון (governance →G10)
|
||||||
**כלל:** מנגנוני-הלמידה (Hermes, ניתוח-פידבק שבועי) **מציעים בלבד**. כל שינוי ב-
|
**כלל (מעודכן 2026-06-28, הכרעת-יו"ר):** השער **מדורג לפי סיכון-התוכן**, לא אחיד:
|
||||||
[SKILL.md](../../skills/decision/SKILL.md) או ב-[legal-decision-lessons.md](../legal-decision-lessons.md)
|
- **מהות** (הלכה / תקדים / עובדה / כל שינוי ב-[SKILL.md](../../skills/decision/SKILL.md) או ב-[legal-decision-lessons.md](../legal-decision-lessons.md)) → **שער-קשיח**: בחינה ואישור ידניים של היו"ר/חיים ואז commit ידני — **לעולם לא auto-committed**. פאנל-ההלכות התלת-סוכני מציע בלבד.
|
||||||
מחייב **בחינה ואישור ידניים של היו"ר/חיים** ואז commit ידני — **לעולם לא auto-committed**.
|
- **סגנון** (`decision_lessons` בקטגוריות style/structure/lexicon/tabular, וכן discussion_rules / transition_phrases / anti_patterns) שעבר **קונצנזוס-פאנל 2/2** → **זורם אוטומטית לכותב** (`review_status='approved'`), **הפיך**: היו"ר רואה ויכול **לבטל בדיעבד** ב-/training. זהו שינוי-קול נמוך-סיכון (טהור-מהות לפי INV-LRN5), בקרת-איכות מובנית (2 מודלים), והפיכוּת — ולכן עדיין "תחת בקרת-המשתמש" במובן NCSC/CEPEJ (veto, לא אישור-מראש על כל פריט).
|
||||||
Hermes כותב comment + `decision_lesson`, לא קבצים; ה-CEO השבועי כותב לקובץ אך הצעותיו
|
|
||||||
מאומתות ידנית לפני קיבוע. זהו פֶּאֶט של [INV-G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant)
|
זהו פֶּאֶט של [INV-G10](00-constitution.md#inv-g10-המערכת-מסייעת--שערים-אנושיים-הם-invariant) על שכבת-הידע: הלמידה כפופה לשיקול-הדעת האנושי — קשיח למהות, הפיך-veto לסגנון. **מימוש:** `scripts/style_lesson_panel.py:_review_status_for` קובע `approved` לקטגוריות-סגנון בקונצנזוס, `proposed` אחרת; הכותב צורך רק `approved` ([db.get_recent_decision_lessons]).
|
||||||
על שכבת-הידע: גם הלמידה כפופה לשיקול-הדעת האנושי.
|
|
||||||
**מקורות:** NCSC/JTC — *Principles & Practices for AI Use in Courts* (human-in-the-loop;
|
**מקורות:** NCSC/JTC — *Principles & Practices for AI Use in Courts* (human-in-the-loop;
|
||||||
never replace human judgment) · Council of Europe / CEPEJ (2018, under user control) ·
|
never replace human judgment) · Council of Europe / CEPEJ (2018, under user control) ·
|
||||||
Federal Judicial Center — *Judicial Writing Manual* (2d ed.) | סטטוס: verified
|
Federal Judicial Center — *Judicial Writing Manual* (2d ed.) | סטטוס: verified
|
||||||
|
|||||||
@@ -110,6 +110,19 @@ def _category(change: dict) -> str:
|
|||||||
return "style"
|
return "style"
|
||||||
|
|
||||||
|
|
||||||
|
# Graduated gate (INV-LRN1, chair decision 2026-06-28): a STYLE lesson the panel
|
||||||
|
# kept by 2/2 consensus flows straight to the writer (review_status='approved'),
|
||||||
|
# reversibly — the chair can veto it in /training. SUBSTANCE (halacha/precedent/
|
||||||
|
# fact) never reaches here (it's filtered to `substance` and skipped, and routes
|
||||||
|
# through the strict 3-judge halacha gate), so every category this panel emits is
|
||||||
|
# style and auto-approves. The constant keeps the gate explicit and future-proof.
|
||||||
|
_STYLE_CATEGORIES = frozenset({"style", "structure", "lexicon", "tabular"})
|
||||||
|
|
||||||
|
|
||||||
|
def _review_status_for(category: str) -> str:
|
||||||
|
return "approved" if category in _STYLE_CATEGORIES else "proposed"
|
||||||
|
|
||||||
|
|
||||||
# ── two judges, one signature: (system, user) -> dict|None ──
|
# ── two judges, one signature: (system, user) -> dict|None ──
|
||||||
|
|
||||||
async def judge_deepseek(client: httpx.AsyncClient, system: str, user: str) -> dict | None:
|
async def judge_deepseek(client: httpx.AsyncClient, system: str, user: str) -> dict | None:
|
||||||
@@ -323,18 +336,24 @@ async def main(args: argparse.Namespace) -> int:
|
|||||||
_lesson_text(r["_change"])])
|
_lesson_text(r["_change"])])
|
||||||
|
|
||||||
written = 0
|
written = 0
|
||||||
|
approved = 0
|
||||||
for r in fresh:
|
for r in fresh:
|
||||||
|
cat = _category(r["_change"])
|
||||||
|
rs = _review_status_for(cat)
|
||||||
await db.add_decision_lesson(
|
await db.add_decision_lesson(
|
||||||
UUID(corpus_id),
|
UUID(corpus_id),
|
||||||
lesson_text=_lesson_text(r["_change"]),
|
lesson_text=_lesson_text(r["_change"]),
|
||||||
category=_category(r["_change"]),
|
category=cat,
|
||||||
source="panel:deepseek+gemini",
|
source="panel:deepseek+gemini",
|
||||||
created_by="panel",
|
created_by="panel",
|
||||||
|
review_status=rs,
|
||||||
)
|
)
|
||||||
written += 1
|
written += 1
|
||||||
|
approved += (rs == "approved")
|
||||||
|
|
||||||
chair = cc["split"] + cc["incomplete"]
|
chair = cc["split"] + cc["incomplete"]
|
||||||
print(f"\nAPPLIED (reversible): wrote {written} decision_lesson proposals "
|
print(f"\nAPPLIED (reversible): wrote {written} decision_lessons "
|
||||||
|
f"({approved} auto-approved style → writer; graduated gate) "
|
||||||
f"(source=panel:deepseek+gemini) · {skipped_dup} כפילויות דולגו · "
|
f"(source=panel:deepseek+gemini) · {skipped_dup} כפילויות דולגו · "
|
||||||
f"{chair} escalated to chair · {len(substance)} substance skipped")
|
f"{chair} escalated to chair · {len(substance)} substance skipped")
|
||||||
print(f"backup → {backup}")
|
print(f"backup → {backup}")
|
||||||
|
|||||||
Reference in New Issue
Block a user