Merge pull request 'feat(learning): FU-2 UI — התלבטות-הפאנל במסך-אישור היו"ר (#133)' (#220) from worktree-halacha-deliberation-ui into main
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m46s
G12 Leak-Guard / leak-guard (push) Successful in 9s

This commit was merged in pull request #220.
This commit is contained in:
2026-06-12 06:19:50 +00:00
4 changed files with 147 additions and 6 deletions

View File

@@ -4466,6 +4466,7 @@ async def list_halachot(
order_by_priority: bool = False,
cluster: bool = False,
include_equivalents: bool = False,
include_panel_round: bool = False,
) -> list[dict]:
"""List halachot with optional triage controls (#84).
@@ -4549,9 +4550,47 @@ async def list_halachot(
await _annotate_clusters(pool, out)
if include_equivalents and out:
await _annotate_equivalents(pool, out)
if include_panel_round and out:
await _annotate_panel_rounds(pool, out)
return out
async def _annotate_panel_rounds(pool, out: list[dict]) -> None:
"""Attach the LATEST 3-judge panel round to each row (#133/FU-2), display-only.
Surfaces the panel's deliberation — each lineage's vote + rationale and the
derived verdict — inside the chair's review card, so her decision (the gold
label the loop learns from) is informed by *why* the judges split. Reads the
capture table halacha_panel_rounds; never affects review_status (INV-G10)."""
ids = [d["id"] for d in out]
rows = await pool.fetch(
"SELECT DISTINCT ON (halacha_id) halacha_id, question, verdict, "
"applied_action, round_ts, claude_vote, claude_reason, deepseek_vote, "
"deepseek_reason, gemini_vote, gemini_reason "
"FROM halacha_panel_rounds WHERE halacha_id = ANY($1::uuid[]) "
"ORDER BY halacha_id, round_ts DESC",
ids,
)
by_id = {
str(r["halacha_id"]): {
"question": r["question"],
"verdict": r["verdict"],
"applied_action": r["applied_action"],
"round_ts": r["round_ts"].isoformat() if r["round_ts"] else None,
"judges": [
{"model": "claude", "vote": r["claude_vote"], "reason": r["claude_reason"]},
{"model": "deepseek", "vote": r["deepseek_vote"], "reason": r["deepseek_reason"]},
{"model": "gemini", "vote": r["gemini_vote"], "reason": r["gemini_reason"]},
],
}
for r in rows
}
for d in out:
pr = by_id.get(str(d["id"]))
if pr:
d["panel_round"] = pr
async def _annotate_clusters(pool, out: list[dict]) -> None:
"""Add cluster_id + cluster_size to each row (#84.2), display-only.