feat(halacha-triage UI): wire gating + near-duplicate cluster cards (#84.2)
Completes #84 — surfaces the backend gating/prioritization (#84.1/#84.3, PR #93) in the chair's review UI and adds near-duplicate clustering (#84.2). Backend - db.list_halachot gains `cluster` (#84.2): annotates each row with cluster_id + cluster_size by unioning same-precedent halachot within HALACHA_CLUSTER_COSINE (0.90, new config). Display-only — never merges/deletes. Pairwise is confined to the returned set (cheap). - GET /api/halachot exposes the `cluster` query param (default off). Frontend (web-ui) - Halacha type gains optional cluster_id / cluster_size (hand-written module; no api:types regen needed — halachot aren't typed off the generated schema). - useHalachotPending(opts): the default "clean" queue now fetches exclude_low_quality + order_by_priority + cluster; needsFix:true returns the flagged 'needs extraction fix' bucket (filtered client-side). - HalachaReviewPanel: a "תור נקי / דורש תיקון-חילוץ" toggle (#84.1); near-dup clusters collapse into ONE card showing "+N וריאנטים" with an expandable list, and approve/reject/defer on a clustered card applies to all variants via the batch endpoint (#84.2 + #84.4). Counts show true halacha totals (pendingTotal). New flag labels added (application / near_duplicate / nevo_preamble_leak). Verified: - backend: list_halachot(cluster=True) on the live queue — algorithm correct (groups related same-precedent rules at 0.78; none at the production 0.90 because dedup #82 already removed near-dups — the desired state). - frontend: `tsc --noEmit` exits 0 (type-clean); no new lint errors (the one lint error is pre-existing in training/learning-panel.tsx from #94). Local Turbopack build can't run on the worktree node_modules symlink — CI builds in a clean checkout. Invariants: G1 (gate/cluster at source in SQL, not post-hoc); G2 (same list_halachot path); §6 (flagged items routed to a visible bucket, not dropped). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
10
web/app.py
10
web/app.py
@@ -6033,11 +6033,12 @@ async def halachot_list(
|
||||
offset: int = 0,
|
||||
exclude_low_quality: bool = False,
|
||||
order_by_priority: bool = False,
|
||||
cluster: bool = False,
|
||||
):
|
||||
"""List halachot. ``exclude_low_quality`` hides flagged items (#84.1) and
|
||||
``order_by_priority`` switches to the active-learning order (#84.3). Both
|
||||
default off so existing callers are unaffected; the review-queue view opts
|
||||
in."""
|
||||
"""List halachot. ``exclude_low_quality`` hides flagged items (#84.1),
|
||||
``order_by_priority`` switches to the active-learning order (#84.3), and
|
||||
``cluster`` annotates near-duplicate groups for one-card review (#84.2). All
|
||||
default off so existing callers are unaffected; the review queue opts in."""
|
||||
cid: UUID | None = None
|
||||
if case_law_id:
|
||||
try:
|
||||
@@ -6051,6 +6052,7 @@ async def halachot_list(
|
||||
limit=limit, offset=offset,
|
||||
exclude_low_quality=exclude_low_quality,
|
||||
order_by_priority=order_by_priority,
|
||||
cluster=cluster,
|
||||
)
|
||||
return {"items": rows, "count": len(rows)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user