feat(nav): הסרת דף מדגם-זהב (goldset) מה-UI
הכיול החד-פעמי של ולידטורי חילוץ-ההלכות (#81.8) הסתיים — הוסר מה-UI: - web-ui/src/app/goldset/page.tsx (הדף) - web-ui/src/components/goldset/goldset-panel.tsx (הרכיב) - web-ui/src/lib/api/goldset.ts (מודול ה-API) - הקישור "מדגם-זהב" מתפריט "פסיקה" + השטחת התת-כותרת "ניתוח וכיול" (נותר רק "מפת הקורפוס" → רשימה שטוחה) - ניקוי אזכורי gold-set מהערות approvals/page.tsx ו-chair.ts ה-backend נשאר במכוון: טבלת halacha_goldset, ה-endpoints (/api/goldset*) ופונקציות ה-DB משמשים את סקריפטי ה-eval/benchmark ומחזיקים נתוני-תיוג אנושיים — אין מחיקת DB ואין שבירת סקריפטים. /api/chair/pending ממילא לא כלל goldset, אז אין קישור שבור במרכז-האישורים. Invariants: G2 (הסרת יכולת-UF מיותרת ללא יצירת מסלול מקביל). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,8 +3,8 @@ import { apiRequest } from "./client";
|
||||
|
||||
/**
|
||||
* Chair approval center (INV-G10) — aggregates every pending human-gate item
|
||||
* (halacha approvals, missing precedents, unapplied feedback, QA-failed cases,
|
||||
* gold-set review) so nothing Dafna must approve is forgotten.
|
||||
* (halacha approvals, missing precedents, unapplied feedback, QA-failed cases)
|
||||
* so nothing Dafna must approve is forgotten.
|
||||
*
|
||||
* Hand-typed (not from the generated types.ts) because /api/chair/pending is a
|
||||
* new endpoint; switch to the generated type after the next `npm run api:types`.
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/**
|
||||
* Gold-set tagging API (#81.7 / #81.8).
|
||||
*
|
||||
* The chair/Dafna manually labels a stratified sample of halachot
|
||||
* (is_holding / correct_type / quote_complete). Those human labels are the
|
||||
* ground truth used to measure the extraction validators and recalibrate the
|
||||
* auto-approve threshold. Endpoints under /api/goldset.
|
||||
*/
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { apiRequest } from "./client";
|
||||
|
||||
export type GoldsetItem = {
|
||||
id: string;
|
||||
halacha_id: string;
|
||||
// human tags (null until tagged)
|
||||
is_holding: boolean | null;
|
||||
correct_type: string;
|
||||
quote_complete: boolean | null;
|
||||
tagged_by: string;
|
||||
tagged_at: string | null;
|
||||
// halacha content + the machine's own labels
|
||||
rule_statement: string;
|
||||
supporting_quote: string;
|
||||
reasoning_summary: string;
|
||||
rule_type: string;
|
||||
// authority over the committee — DERIVED from the source (INV-DM7), read-only.
|
||||
authority?: "binding" | "persuasive" | null;
|
||||
confidence: number | null;
|
||||
quality_flags?: string[];
|
||||
review_status: string;
|
||||
case_number: string | null;
|
||||
case_name: string | null;
|
||||
source_type: string | null; // 'court_ruling' | 'appeals_committee' | ''
|
||||
// AI second-opinion (QA aid — independent, not ground truth, not auto-applied)
|
||||
ai_is_holding: boolean | null;
|
||||
ai_correct_type: string;
|
||||
ai_rationale: string;
|
||||
ai_generated_at: string | null;
|
||||
};
|
||||
|
||||
export type GoldsetScore = {
|
||||
batch: string;
|
||||
total: number;
|
||||
labeled: number;
|
||||
validators: Record<
|
||||
string,
|
||||
{ precision: number; recall: number; f1: number; tp: number; fp: number; fn: number; tn: number }
|
||||
>;
|
||||
};
|
||||
|
||||
export type GoldsetTag = {
|
||||
is_holding?: boolean | null;
|
||||
correct_type?: string;
|
||||
quote_complete?: boolean | null;
|
||||
};
|
||||
|
||||
const keys = {
|
||||
all: ["goldset"] as const,
|
||||
list: (batch: string) => ["goldset", "list", batch] as const,
|
||||
score: (batch: string) => ["goldset", "score", batch] as const,
|
||||
};
|
||||
|
||||
export function useGoldset(batch = "default") {
|
||||
return useQuery({
|
||||
queryKey: keys.list(batch),
|
||||
queryFn: ({ signal }) =>
|
||||
apiRequest<{ items: GoldsetItem[]; batch: string }>(
|
||||
`/api/goldset?batch=${encodeURIComponent(batch)}`,
|
||||
{ signal },
|
||||
),
|
||||
staleTime: 5_000,
|
||||
refetchOnMount: "always",
|
||||
});
|
||||
}
|
||||
|
||||
export function useGoldsetScore(batch = "default") {
|
||||
return useQuery({
|
||||
queryKey: keys.score(batch),
|
||||
queryFn: ({ signal }) =>
|
||||
apiRequest<GoldsetScore>(
|
||||
`/api/goldset/score?batch=${encodeURIComponent(batch)}`,
|
||||
{ signal },
|
||||
),
|
||||
staleTime: 5_000,
|
||||
});
|
||||
}
|
||||
|
||||
export function useTagGoldset(batch = "default") {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ id, tag }: { id: string; tag: GoldsetTag }) =>
|
||||
apiRequest<{ ok: boolean }>(`/api/goldset/${encodeURIComponent(id)}`, {
|
||||
method: "PATCH",
|
||||
body: { ...tag, tagged_by: "chair" },
|
||||
}),
|
||||
onSuccess: () => {
|
||||
qc.invalidateQueries({ queryKey: keys.list(batch) });
|
||||
qc.invalidateQueries({ queryKey: keys.score(batch) });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useCreateGoldsetSample(batch = "default") {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (n: number) =>
|
||||
apiRequest<{ batch: string; inserted: number; total: number }>(
|
||||
"/api/goldset/sample",
|
||||
{ method: "POST", body: { n, batch } },
|
||||
),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: keys.list(batch) }),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user