fix(writer): always feed canonical anti-patterns to the writer
The learning loop measured anti-patterns but never corrected them. style_distance detects markdown headers / bullet lists / mid-paragraph mini-lists (from the canonical lessons.ANTI_PATTERNS), but the writer only received anti-pattern guidance if a chair `anti_patterns` override existed in appeal_type_rules — and none does. So _build_style_context's `if ov:` branch injected nothing, the writer was never told to avoid them, and drafts kept emitting them (8137: 28 hits, the worst, newest — anti-patterns were trending UP, not down). Anti-patterns are structural invariants of Dafna's voice (continuous legal narrative — no markdown, no bullets), not overridable preferences. So inject the canonical ANTI_PATTERNS notes ALWAYS, from the same list style_distance measures against (single source of truth), with any chair additions layered on top. This closes the measure-but-don't-correct gap: the next draft should show the markdown/ bullet anti-patterns drop, and Path A (style_distance_history) will confirm it. Invariants: G1 (correct at source — the writer, not a post-hoc stripper), G2 (one canonical anti-pattern list shared by detection and instruction — no parallel list), INV-LRN4 (closes the feedback half of the draft↔final loop). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -983,6 +983,22 @@ async def _build_style_context(practice_area: str = "") -> str:
|
|||||||
("anti_patterns", "אנטי-דפוסים (להימנע)"),
|
("anti_patterns", "אנטי-דפוסים (להימנע)"),
|
||||||
):
|
):
|
||||||
ov = await db.get_methodology_overrides(cat)
|
ov = await db.get_methodology_overrides(cat)
|
||||||
|
if cat == "anti_patterns":
|
||||||
|
# Anti-patterns are STRUCTURAL INVARIANTS of Dafna's style (no
|
||||||
|
# markdown headers, no bullet lists, no mid-paragraph mini-lists —
|
||||||
|
# she writes continuous legal narrative). They must reach the writer
|
||||||
|
# ALWAYS, from the SAME canonical list style_distance measures against
|
||||||
|
# (lessons.ANTI_PATTERNS) — otherwise the loop detects them but never
|
||||||
|
# corrects them, and drafts keep emitting them (the gap that left
|
||||||
|
# 8137 with 28 hits). Chair additions layer on top; they never
|
||||||
|
# remove the canonical ones.
|
||||||
|
from legal_mcp.services.lessons import ANTI_PATTERNS as _ANTI
|
||||||
|
learned.append(f"\n**{label} — כתוב נרטיב משפטי רציף; הימנע מ:**")
|
||||||
|
for ap in _ANTI:
|
||||||
|
learned.append(f"- {ap['note']}")
|
||||||
|
for k, v in (ov or {}).items():
|
||||||
|
learned.append(f"- (יו\"ר) {k}: {json.dumps(v, ensure_ascii=False)}")
|
||||||
|
continue
|
||||||
if ov:
|
if ov:
|
||||||
learned.append(f"\n**{label} — ערכי היו\"ר (גוברים על ברירת-המחדל):**")
|
learned.append(f"\n**{label} — ערכי היו\"ר (גוברים על ברירת-המחדל):**")
|
||||||
for k, v in ov.items():
|
for k, v in ov.items():
|
||||||
|
|||||||
Reference in New Issue
Block a user