diff --git a/web-ui/src/lib/api/types.ts b/web-ui/src/lib/api/types.ts index 8cbd229..d5fd766 100644 --- a/web-ui/src/lib/api/types.ts +++ b/web-ui/src/lib/api/types.ts @@ -466,11 +466,23 @@ export interface paths { }; /** * Get Curator Stats - * @description Cheap aggregate stats over decision_lessons + style_corpus. + * @description Aggregate over the THREE learning channels that feed the writer, for the + * /training "אוצֵר" tab. Each channel is surfaced honestly with its real + * backing store and how much of it actually reaches the writer: * - * Used by the Curator-Portrait tab to show "10 curator findings across 24 - * decisions". We deliberately keep this server-side and aggregate so the - * UI can render a single card without fanning out N queries. + * A. distillation — Claude draft↔final diff → methodology overrides + * (appeal_type_rules['_global']). Folded items flow to the writer now. + * B. panel — DeepSeek+Gemini 2/2 vote → decision_lessons + * (source='panel:deepseek+gemini'). Flow to the writer only once the + * chair approves (review_status='approved', INV-LRN1/G10). + * C. curator — the agent's Opus-read qualitative findings → decision_lessons + * (source='curator'). Same chair gate as the panel. + * + * Earlier this endpoint counted ONLY source='curator' and reported it as the + * whole story, so it read 0 while the panel/methodology channels carried all + * the real learning. The card was measuring a column nothing wrote (the agent + * posted findings as Paperclip comments, never as decision_lessons — a + * spec↔impl drift since closed). It now reports all three (INV-IA2/IA5). */ get: operations["get_curator_stats_api_training_curator_stats_get"]; put?: never; @@ -1067,9 +1079,26 @@ export interface paths { put?: never; /** * Api Aggregate Arguments - * @description Aggregate raw claims into distinct legal arguments via Claude. + * @description Queue claim→argument aggregation by waking the legal-analyst agent. * - * Runs as a BackgroundTask because the LLM pass can take 30-90 seconds. + * The aggregation itself calls `claude_session.query_json()`, which shells + * out to the local `claude` CLI — present on the agent host, **absent in + * this FastAPI container**. Running it inline as a BackgroundTask (the old + * behaviour) silently produced nothing, and on `force` it destructively + * deleted the existing arguments *before* the doomed LLM call. So we + * delegate to the analyst exactly like `extract-appraiser-facts`: create a + * child Paperclip issue, assign it to the company's analyst, and trigger a + * wakeup. The analyst runs the MCP tool locally and posts results. + * + * Cheap in-container pre-checks (DB only, no LLM) short-circuit before any + * agent is spun up: + * - `no_claims` — there are no raw claims to aggregate yet. + * - `exists` — arguments already computed and `force` is False. + * + * Response shape: + * {"status": "queued", "sub_issue_id", "analyst_id", "main_issue_id"} + * or {"status": "no_claims"|"exists", "total", "message"} + * or {"status": "skipped", "reason": "no_api_key"|"no_analyst"|"no_issue"} */ post: operations["api_aggregate_arguments_api_cases__case_number__aggregate_arguments_post"]; delete?: never; @@ -1304,6 +1333,66 @@ export interface paths { patch?: never; trace?: never; }; + "/api/cases/{case_number}/research/party-claims-summary": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Party Claims Summary + * @description Return the raw markdown of the party-claims executive summary. + */ + get: operations["api_party_claims_summary_api_cases__case_number__research_party_claims_summary_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/cases/{case_number}/research/party-claims-summary/download": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Party Claims Summary Download + * @description Download the raw party-claims-summary.md file. + */ + get: operations["api_party_claims_summary_download_api_cases__case_number__research_party_claims_summary_download_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/cases/{case_number}/research/party-claims-summary/export-docx": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Party Claims Summary Export Docx + * @description Export the party-claims summary as a DOCX using דפנה's template styles. + */ + get: operations["api_party_claims_summary_export_docx_api_cases__case_number__research_party_claims_summary_export_docx_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/cases/{case_number}/research/analysis/upload": { parameters: { query?: never; @@ -1404,6 +1493,50 @@ export interface paths { patch?: never; trace?: never; }; + "/api/cases/{case_number}/citation-verification": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Citation Verification + * @description Per legal-argument: supporting corpus precedents (with cited_by authority), + * their verify state + chair note, and per-issue radar (unlinked digests). Powers + * the compose 'אימות פסיקה' tab — the chair verifies before the writer cites. + */ + get: operations["api_citation_verification_api_cases__case_number__citation_verification_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/cases/{case_number}/citation-verification/verify": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Api Citation Verify + * @description Verify / un-verify a precedent for a specific argument (the INV-AH gate the + * writer respects). Upsert: PATCH an existing attachment, else attach a new one + * linked to the argument + corpus ruling and mark it. + */ + post: operations["api_citation_verify_api_cases__case_number__citation_verification_verify_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/precedents/{precedent_id}": { parameters: { query?: never; @@ -1928,6 +2061,29 @@ export interface paths { patch?: never; trace?: never; }; + "/api/cases/{case_number}/agents/reset": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Api Reset Case Agents + * @description Reset stuck agents for a case. + * + * Clears writer/QA agents from 'error' status and reassigns any open + * issues back to the chair user, stopping Paperclip recovery loops. + */ + post: operations["api_reset_case_agents_api_cases__case_number__agents_reset_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/settings/mcp/env": { parameters: { query?: never; @@ -2197,6 +2353,28 @@ export interface paths { patch?: never; trace?: never; }; + "/api/learning/style-distance-history": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Learning Style Distance History + * @description Path A — מגמת ה-held-out הפרוספקטיבי: snapshot של מרחק-הסגנון שנלכד בכל + * העלאת-סופי *לפני* הטמעת-לקחי-התיק, מול גודל-בריכת-הלקחים באותו רגע. ירידה + * ב-anti_pattern_total / change_percent ככל שהבריכה גדלה = הלמידה מכלילה. + */ + get: operations["api_learning_style_distance_history_api_learning_style_distance_history_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/learning/pairs/{pair_id}": { parameters: { query?: never; @@ -2814,6 +2992,30 @@ export interface paths { patch?: never; trace?: never; }; + "/api/cases/{case_number}/digest-radar": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Api Case Digest Radar + * @description Case-contextual digest radar (X12) — UNLINKED digests whose topic is close to + * this case (rulings we don't hold yet). Powers the case-page "📡 רדאר יומונים" lead + * so a relevant ruling known only via a digest doesn't fall through the cracks while + * the case is decided. INV-DIG1: points at the underlying ruling, never cites the + * digest. + */ + get: operations["api_case_digest_radar_api_cases__case_number__digest_radar_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/digests/upload": { parameters: { query?: never; @@ -3116,6 +3318,32 @@ export interface paths { patch?: never; trace?: never; }; + "/api/scripts/{name}/run": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Scripts Run + * @description Run a read-only allowlisted script via the court-fetch host bridge (#4). + * + * Only scripts in ``script_runner.SCRIPT_RUN_ALLOWLIST`` are runnable; the host + * bridge is the enforcer (allowlist + fixed read-only argv, no args from here). + * The script's exit code + stdout/stderr are relayed verbatim for the dashboard. + * We pre-check the allowlist here too (defense-in-depth, avoids a useless round + * trip). Audit scripts can take a while, so the timeout is generous. + */ + post: operations["scripts_run_api_scripts__name__run_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/digests/{digest_id}": { parameters: { query?: never; @@ -3284,8 +3512,11 @@ export interface paths { * ``cluster`` annotates near-duplicate groups for one-card review (#84.2), * ``include_equivalents`` attaches cross-precedent parallel-authority links, and * ``include_panel_round`` attaches the latest 3-judge panel deliberation so the - * chair sees why the panel split (#133/FU-2). All default off so existing callers - * are unaffected; the review queue opts in. + * chair sees why the panel split (#133/FU-2). ``search`` locates a pending + * halacha by case_number / case_name / rule text server-side (so an item below + * the display window stays reachable); ``with_total`` adds the full filter count + * so the UI can show "N of TOTAL". All default off so existing callers are + * unaffected; the review queue opts in. */ get: operations["halachot_list_api_halachot_get"]; put?: never; @@ -3337,6 +3568,26 @@ export interface paths { patch?: never; trace?: never; }; + "/api/canonical-halachot/{canonical_id}/instances": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** + * Canonical Halacha Instances + * @description All halachot instances sharing a canonical_id (V41 — used by the UI accordion). + */ + get: operations["canonical_halacha_instances_api_canonical_halachot__canonical_id__instances_get"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/goldset": { parameters: { query?: never; @@ -3562,6 +3813,32 @@ export interface paths { patch?: never; trace?: never; }; + "/api/plans/fetch": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Plan Fetch From Mavat + * @description Pull a plan's identity + validity from mavat (מנהל התכנון) for the chair form. + * + * Returns a candidate dict (display_name/plan_type/purpose/gazette_date/ + * yalkut_number/source_url) — does NOT write the registry; the chair saves via + * POST /api/plans (review_status gate stays, INV-AH source_url carried). The + * browser work runs on the host bridge (Camoufox past F5); 503 if it's down, + * 404 if the plan wasn't found. + */ + post: operations["plan_fetch_from_mavat_api_plans_fetch_post"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; "/api/missing-precedents": { parameters: { query?: never; @@ -3876,7 +4153,7 @@ export interface components { subject_tags: string; /** * Is Binding - * @default true + * @default false */ is_binding: boolean; /** @@ -4127,11 +4404,8 @@ export interface components { decision_date: string; /** Tags */ tags?: string[] | null; - /** - * Expected Outcome - * @default - */ - expected_outcome: string; + /** Expected Outcome */ + expected_outcome?: string | null; /** Appellants */ appellants?: string[] | null; /** Respondents */ @@ -4177,6 +4451,38 @@ export interface components { /** Content */ content: string; }; + /** CitationVerifyRequest */ + CitationVerifyRequest: { + /** Argument Id */ + argument_id: string; + /** + * Case Law Id + * @default + */ + case_law_id: string; + /** + * Quote + * @default + */ + quote: string; + /** + * Citation + * @default + */ + citation: string; + /** Chair Note */ + chair_note?: string | null; + /** + * Verified + * @default true + */ + verified: boolean; + /** + * Attached Id + * @default + */ + attached_id: string; + }; /** ClassifyRequest */ ClassifyRequest: { /** Filename */ @@ -4449,6 +4755,8 @@ export interface components { practice_areas?: string[] | null; /** Supporting Quote */ supporting_quote?: string | null; + /** Canonical Statement */ + canonical_statement?: string | null; }; /** InteractionResponseRequest */ InteractionResponseRequest: { @@ -4610,6 +4918,11 @@ export interface components { /** Aliases */ aliases?: string[] | null; }; + /** PlanFetchRequest */ + PlanFetchRequest: { + /** Plan Number */ + plan_number: string; + }; /** PlanMergeRequest */ PlanMergeRequest: { /** Source Id */ @@ -6807,6 +7120,99 @@ export interface operations { }; }; }; + api_party_claims_summary_api_cases__case_number__research_party_claims_summary_get: { + parameters: { + query?: never; + header?: never; + path: { + case_number: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + api_party_claims_summary_download_api_cases__case_number__research_party_claims_summary_download_get: { + parameters: { + query?: never; + header?: never; + path: { + case_number: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + api_party_claims_summary_export_docx_api_cases__case_number__research_party_claims_summary_export_docx_get: { + parameters: { + query?: never; + header?: never; + path: { + case_number: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; api_research_analysis_upload_api_cases__case_number__research_analysis_upload_put: { parameters: { query?: never; @@ -6978,6 +7384,72 @@ export interface operations { }; }; }; + api_citation_verification_api_cases__case_number__citation_verification_get: { + parameters: { + query?: never; + header?: never; + path: { + case_number: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; + api_citation_verify_api_cases__case_number__citation_verification_verify_post: { + parameters: { + query?: never; + header?: never; + path: { + case_number: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["CitationVerifyRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; api_precedent_delete_api_precedents__precedent_id__delete: { parameters: { query?: never; @@ -7752,6 +8224,37 @@ export interface operations { }; }; }; + api_reset_case_agents_api_cases__case_number__agents_reset_post: { + parameters: { + query?: never; + header?: never; + path: { + case_number: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; api_mcp_env_api_settings_mcp_env_get: { parameters: { query?: never; @@ -8153,6 +8656,26 @@ export interface operations { }; }; }; + api_learning_style_distance_history_api_learning_style_distance_history_get: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + }; + }; api_learning_pair_detail_api_learning_pairs__pair_id__get: { parameters: { query?: never; @@ -9182,6 +9705,40 @@ export interface operations { }; }; }; + api_case_digest_radar_api_cases__case_number__digest_radar_get: { + parameters: { + query?: { + limit?: number; + min_score?: number; + }; + header?: never; + path: { + case_number: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; digest_upload_api_digests_upload_post: { parameters: { query?: never; @@ -9621,6 +10178,37 @@ export interface operations { }; }; }; + scripts_run_api_scripts__name__run_post: { + parameters: { + query?: never; + header?: never; + path: { + name: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; digest_get_api_digests__digest_id__get: { parameters: { query?: never; @@ -9960,6 +10548,8 @@ export interface operations { cluster?: boolean; include_equivalents?: boolean; include_panel_round?: boolean; + search?: string; + with_total?: boolean; }; header?: never; path?: never; @@ -10085,6 +10675,37 @@ export interface operations { }; }; }; + canonical_halacha_instances_api_canonical_halachot__canonical_id__instances_get: { + parameters: { + query?: never; + header?: never; + path: { + canonical_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; goldset_list_ep_api_goldset_get: { parameters: { query?: { @@ -10514,6 +11135,39 @@ export interface operations { }; }; }; + plan_fetch_from_mavat_api_plans_fetch_post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["PlanFetchRequest"]; + }; + }; + responses: { + /** @description Successful Response */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": unknown; + }; + }; + /** @description Validation Error */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["HTTPValidationError"]; + }; + }; + }; + }; missing_precedents_list_api_missing_precedents_get: { parameters: { query?: {