fix(halacha): split authority (derived) from rule_role — stop source-conflation (INV-DM7)
The extractor classified rule_type by SOURCE bindingness (higher-court→binding, committee→persuasive) instead of by rule KIND. The gold-set proved it: 'binding' appeared on 19/19 external rulings & 0 committees; 'persuasive' on 13/13 committees & 0 external — only 58% agreement with the human role tags. The two axes (authority vs rule role) were crammed into one enum. This splits them per INV-DM7: - authority (binding/persuasive) — DERIVED from case_law.precedent_level (עליון/מנהלי→binding, ועדת_ערר_מחוזית→persuasive), never stored, never LLM-guessed. New helper halacha_quality.derive_authority; surfaced read-only in list_halachot / goldset_list / search results. - rule_type — now the rule ROLE only: holding/interpretive/procedural/ application/obiter. Both extractor prompts unified to this vocabulary; _coerce_halacha no longer defaults rule_type from the source; legacy binding→holding / persuasive→interpretive fold for safety. UI: authority shown as a separate read-only badge (gold=מחייב / muted=משכנע) across the review queue, precedent detail, and gold-set; the gold-set role selector drops binding/persuasive and adds מהותי (holding). Migration: scripts/halacha_rule_role_backfill.py re-classifies the 276 pre-split binding/persuasive rows into a genuine role via local claude_session (run after deploy). Gold-set correct_type/ai_correct_type 'binding'→'holding' via SQL. Sources (≥3, per research-decision policy): OASIS LegalRuleML v1.0 (appliesAuthority/Strength as metadata orthogonal to rule logic) · SemEval-2023 Task 6 LegalEval (rhetorical roles by function, authority kept separate) · Bluebook signals (weight-of-authority is a separate dimension). Invariants: ESTABLISHES INV-DM7. Upholds G1 (normalize at source — extractor classifies role, system derives authority) and G2 (single source of truth — authority derived, not a parallel stored field). Tests: 211 pass + new derive_authority/coerce coverage. web-ui build + tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,15 +7,7 @@ import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { CorroborationBadge } from "@/components/precedents/corroboration-badge";
|
||||
import { useUpdateHalacha, type Halacha } from "@/lib/api/precedent-library";
|
||||
|
||||
const RULE_TYPE_LABELS: Record<string, string> = {
|
||||
binding: "הלכה מחייבת",
|
||||
interpretive: "פרשני",
|
||||
procedural: "פרוצדורלי",
|
||||
obiter: "אמרת אגב",
|
||||
application: "יישום הלכה",
|
||||
persuasive: "משכנע",
|
||||
};
|
||||
import { AuthorityBadge, ruleTypeLabel } from "./halacha-meta";
|
||||
|
||||
type StatusFilter = "all" | "approved" | "pending" | "rejected";
|
||||
|
||||
@@ -172,8 +164,9 @@ export function ExtractedHalachotSection({ halachot }: { halachot: Halacha[] })
|
||||
</span>
|
||||
<ReviewStatusPill status={h.review_status} />
|
||||
<Badge variant="outline" className="text-[0.65rem]">
|
||||
{RULE_TYPE_LABELS[h.rule_type] ?? h.rule_type}
|
||||
{ruleTypeLabel(h.rule_type)}
|
||||
</Badge>
|
||||
<AuthorityBadge authority={h.authority} />
|
||||
<Badge variant="outline" className="text-[0.65rem] tabular-nums">
|
||||
ביטחון {h.confidence.toFixed(2)}
|
||||
</Badge>
|
||||
|
||||
Reference in New Issue
Block a user