feat(style-acq T15): הכותב צורך את כל הלמידה (/methodology overrides + /training lessons) + תיקון-מספור

עונה ל"להתחשב במה שכבר למדנו": הכותב התעלם מעריכות היו"ר ב-/methodology
(נשמרו ב-appeal_type_rules אך block_writer קרא רק קבועי lessons.py) ומ-
decision_lessons של /training. עכשיו הכל מגיע לכתיבה.

- db.get_methodology_overrides(category) — overrides של היו"ר (יחסי-זהב,
  כללי-דיון, צ׳קליסטים) מ-appeal_type_rules (כמו merge של ה-API).
- db.get_recent_decision_lessons(limit, practice_area) — לקחי /training.
- _build_style_context(practice_area): מוסיף סעיף " למידה מצטברת — גובר
  על ברירת-מחדל" עם שניהם, אחרי voice-fingerprint (T0). שני ה-callers מעבירים
  practice_area. עובד יחד עם הלולאה (T4/T5) שתזין לאותן טבלאות.

תיקון-מספור (חלק מ-T9, דחוף כי T0 הזריק את הטעות): voice-fingerprint §3.1
תוקן — ההחלטה ממוספרת תמיד (מספור-אוטומטי ב-Word); "ללא מספור" היה
ארטיפקט-חילוץ. האנטי-דפוס האמיתי: רשימת-מיני בתוך פסקה + מספרים ידניים.

INV-LRN4 (הזרמת למידה) · INV-LRN5 (טוהר). G11.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 16:36:32 +00:00
parent b97e8d595d
commit b9bdca0572
3 changed files with 87 additions and 8 deletions

View File

@@ -2194,6 +2194,48 @@ async def get_style_patterns(pattern_type: str | None = None) -> list[dict]:
return [dict(r) for r in rows]
async def get_methodology_overrides(category: str) -> dict:
"""Chair's /methodology edits for one category (golden_ratios / discussion_rules /
content_checklists). Returns {rule_key: parsed_value}. These OVERRIDE the hardcoded
lessons.py defaults — the writer must consume them (T15 / INV-LRN4). Mirrors the merge
in GET /api/methodology/{category}."""
pool = await get_pool()
async with pool.acquire() as conn:
rows = await conn.fetch(
"SELECT rule_key, rule_value FROM appeal_type_rules "
"WHERE appeal_type = '_global' AND rule_category = $1",
category,
)
out: dict = {}
for r in rows:
raw = r["rule_value"]
if isinstance(raw, str):
try:
raw = json.loads(raw)
except (json.JSONDecodeError, TypeError):
pass
out[r["rule_key"]] = raw
return out
async def get_recent_decision_lessons(limit: int = 15, practice_area: str = "") -> list[dict]:
"""Per-decision learnings the chair/curator attached in /training (decision_lessons),
so the writer consumes them too (T15). Prefers style/structure/lexicon, recent first."""
pool = await get_pool()
async with pool.acquire() as conn:
rows = await conn.fetch(
"""SELECT dl.lesson_text, dl.category, dl.source,
sc.decision_number, sc.practice_area
FROM decision_lessons dl
JOIN style_corpus sc ON sc.id = dl.style_corpus_id
WHERE ($2 = '' OR sc.practice_area = $2)
ORDER BY dl.created_at DESC
LIMIT $1""",
limit, practice_area,
)
return [dict(r) for r in rows]
async def upsert_style_pattern(
pattern_type: str,
pattern_text: str,