New dynamic route /cases/[caseNumber] wired to the FastAPI details
endpoint, using Next 16's async params pattern with React's use()
hook. TanStack Query handles 5s refetchInterval so the page
self-updates during long-running processing without manual polling.
New components: CaseHeader (breadcrumb + meta), WorkflowTimeline
(5-phase RTL pipeline view), DocumentsPanel (categorized list).
Tabs split overview/documents/actions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Initialize shadcn/ui (radix-nova preset) and wire its semantic tokens
to the editorial navy/cream/gold palette so primitives inherit the
judicial voice without per-component overrides.
Replace the Phase 2 live-probe with a real dashboard: KPI tiles,
conic-gradient status donut (ported from the vanilla renderHero),
and a TanStack Table cases list with search + sort. Add useCase(n)
hook with 5s staleTime/refetchInterval to replace the old manual
polling loop when Case Detail ships next.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- create-next-app with TypeScript, Tailwind v4, App Router
- Port design-system.css tokens into Tailwind @theme (navy/gold/parchment, Heebo)
- Install TanStack Query, react-hook-form, zod, lucide-react, react-dropzone
- layout.tsx: RTL Hebrew + Heebo via next/font/google
- AppShell component with navy header + gold rule + nav
- next.config.ts: output:standalone + rewrites to proxy /api/* to production FastAPI
- Dockerfile: multi-stage Node 20 Alpine build for Next.js standalone
(branch-local override of the FastAPI Dockerfile; main is unaffected)
- Switch .taskmaster to claude-code provider (no API key required)
- Add 7 phase tasks (83-89) tracking the full rewrite plan
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The home page already has a prominent '+ תיק חדש' button in the hero.
Cases are always opened by clicking a case card on the home list, so
the top-nav link is noise. Keyboard shortcut 'n' still opens the
wizard directly for power users.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Closes the loop so דפנה's positions (written inline in the UI and
saved to analysis-and-research.md) automatically become binding
direction for the legal-writer agent — no manual copy-paste,
no bypass.
Backend:
- research_md.extract_chair_directions(path) returns a compact dict
with status (missing/empty/partial/complete), filled_count,
empty_count, and a reduced list of threshold_claims + issues each
with {id, number, title, direction}. Designed to be directly usable
as direction_doc by the writer.
- New MCP tool: drafting.get_chair_directions(case_number) wraps the
helper, resolves the case research file path via config.find_case_dir,
returns formatted JSON.
- Registered in server.py as mcp__legal-ai__get_chair_directions.
legal-writer agent update:
- Adds get_chair_directions to the tools list.
- New mandatory "שלב 1ב" before any block writing: call
get_chair_directions, branch on status.
- missing → halt, report "legal-analyst לא רץ עדיין"
- empty → halt, instruct Dafna to fill positions via the UI URL
- partial → halt unless user confirms; write only filled sections
- complete → proceed
- New "שלב 1ג" constructs an internal direction_doc from the
received chair rulings before writing block י.
- Block י section expanded with 5 binding rules:
1. Open each discussion with Dafna's ruling as the thesis
2. Frame the reasoning in her style (use get_style_guide phrases)
3. Match her tone (decisive vs nuanced)
4. Must NOT contradict her position — if she disagreed with your
own inclination, her position rules
5. Use legal_questions from the analysis file as the analytical
structure (principle question first, concrete application second)
- New bullet section for block יא: summarize each chair ruling
briefly, state final outcome, close with the signed date formula.
Verified all four status paths (missing/empty/partial/complete) via
local test. Now Dafna's workflow is fully end-to-end: she reads the
analyst report in the UI, fills "עמדת ועדת הערר" in each card, hits
blur to auto-save, then triggers legal-writer — which picks up her
positions as direction without any file shuffle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New feature on case view: the analysis-and-research.md produced by the
legal-analyst agent is now rendered as structured cards in the UI,
with inline editing of "עמדת ועדת הערר" that writes directly back to
the markdown file (atomic rename).
Backend (research_md.py):
- parse(Path) → dict with header, prose sections, threshold_claims[],
issues[], conclusions, other_sections
- Tolerant field extractor handles both block ("**LABEL:**\ncontent")
and inline ("**LABEL:** content") variants
- Detects [ימולא ע"י יו"ר הוועדה] placeholder → empty chair_position
- update_chair_position(path, section_id, text) locates the exact
subsection by ordinal, replaces or appends the chair field, writes
atomically via temp file + os.replace
- Section IDs: threshold_N / issue_N (1-based)
Endpoints:
- GET /api/cases/{n}/research/analysis — returns parsed JSON or 404
- PATCH /api/cases/{n}/research/analysis/chair-position — {section_id, position}
Frontend (#page-case):
- New card "ניתוח משפטי ומחקר" below local-files card
- Prose sections as justified text panels (background + gold border)
- Threshold claims and issues as collapsible <details> items with
gold right-border on open, numbered pills
- Each item shows all extracted fields with label above content
- Chair position editor: gold-wash background, 📝 icon label, textarea
with placeholder prompt
- onblur → PATCH with save indicator: ⏳ שומר → ✓ נשמר HH:MM → fade
- Status pill next to each item title: "ממתין לעמדה" / "✓ עמדה נקבעה"
- First threshold claim opens by default, rest closed
- Card hidden entirely when no analysis file exists (404)
Tested against real file: case 1033-25 with 3 threshold claims and
6 issues, all chair positions correctly empty, update writes only the
targeted section, atomic rewrite preserves all other content.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document titles are '[קורפוס] ARAR-23-1188 - ...' but decision_number
is '1188/23' — previous LIKE %1188/23% wouldn't match. Now extracts
the first numeric segment and matches against title.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dark mode:
- body.dark overrides CSS variables (navy→cream reverse)
- Persisted in localStorage, applied before paint to avoid flash
- Toggle button in nav (moon/sun icon), Shift+D shortcut
Keyboard shortcuts:
- g h/n/u/t/s/c/w/d/k for page navigation
- n for new case, ? for help (Shift+/)
- Esc closes any open dialog, blurs focused input
- Help modal via showShortcutsHelp() with styled kbd elements
SSE tasks stream:
- /api/system/tasks/stream pushes snapshots whenever _progress changes
- Client uses EventSource instead of 3s polling
- Auto-reconnect after 5s on error
- 15s heartbeat keeps proxies alive
Compare decisions (new #/compare page):
- /api/training/compare?a=id&b=id serializes both decisions' metadata,
section breakdown from document_chunks, and three buckets of patterns
(only in A, only in B, shared) using variant matching
- Two-column header with section-length breakdown + patterns count
- Three-column diff row (only_a / shared / only_b)
Compose with suggestions (new #/compose page):
- Large RTL justified textarea with Hebrew display font title input
- Sidebar lists all 47 style_patterns grouped by type with filter chips
- Click a pattern → inserts at cursor, replacing [placeholders] with ___
- Live section guess (פתיחה / רקע / טענות / דיון / סוף דבר) based on
most-recent 400 chars
- Auto-save draft to localStorage every second; restore on page load
- "העתק טקסט" copies title+body to clipboard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Case view:
- Header card gets gold right-border, serif display title, pill-style
action links with gold hover
- Document groups: gold-underlined section headers, hover rows with
parchment background
Wizard (new case):
- Step tabs in display font with separators; active/done states use
navy/success colors with proper background contrast
- Nav buttons separated by hairline divider
Skills page:
- Pill badges for ok/warn, gold icon, hover elevation
Upload zone:
- Larger dashed border, serif header, gold-wash hover state
Loading skeletons:
- .skeleton / .skeleton-line classes with shimmer animation
- Case list shows 3 skeleton cards while loading
- Style report shows skeleton hero while loading
Empty states:
- Case list gets ornamental ❦ + emotional copy in display font
- Error messages include underlying error detail
Print stylesheet:
- Hides header/nav/sidebar/buttons
- Forces card borders and page-break-inside for portrait printing
- Expands details elements so content prints
Responsive:
- Mobile: simplified hero, narrower process panel, wrapping header
- Tablet: home grid collapses to single column
Fixes:
- DONUT_COLORS reverts to hex literals (was var(--color-gold) string
which doesn't interpolate in conic-gradient reliably across browsers)
- Sig-phrase headline now prefers clean phrases over template-heavy ones
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DELETE /api/training/corpus/{id} + delete button on training page,
with confirmation dialog and recompute hint
- /api/system/tasks + floating process panel (bottom-left) showing
active background tasks with live 3s polling
- /api/system/recent-activity derives a feed from cases, style_corpus,
and last style_patterns run; sidebar on home page renders with
relative timestamps
- /api/system/diagnostics + /#/diagnostics page showing DB health,
row counts per table, active tasks, stuck documents (>10 min),
failed extractions
- Cosmetic: signature phrase headline now prefers clean phrases over
bracket-heavy templates for display
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces Frank Ruhl Libre + Assistant with single-family Heebo for both
display and body. Weight contrast (900/700 for headings, 400 for body,
300 for light captions) provides the hierarchy. Single font family reduces
network requests and renders consistently.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New design-system.css: CSS variables for Navy/Cream/Gold palette,
Frank Ruhl Libre (display) + Assistant (body) typography via Google Fonts,
spacing/shadow/motion tokens, RTL-safe utilities
- All body paragraphs justify to both sides (text-align: justify, inter-word)
- Existing inline <style> migrated from hardcoded #e94560/#1a1a2e/#27ae60 to
CSS variables
- Header: deep navy with gold accent rule under, display-font brand mark,
active nav link marked with gold underline
- Buttons: navy primary, gold-wash focus rings, elevation on hover
- Case cards: gold right-border, hairline top glow on hover, display font
on case number
- Home dashboard: new hero with eyebrow/title/subtitle, 4 KPI cards with
gold-rule side marker, loadKPIs() fetches case count, corpus size,
pattern count, processing queue
- Style report: larger hero h1, ornamental pull-quote headline with
drop-cap open quote, gold divider under section titles
- Toast, status bar, form inputs: navy/gold palette, serif italics for
subtitles and empty states
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Visual dashboard at #/style-report with 4 sections:
- Hero: 24 decisions, char counts, subject donut, timeline
- Anatomy: average section-length breakdown (intro → ruling → conclusion)
- Signature Phrases Wall: pattern cards with real corpus frequencies, filter
chips by type, click → modal with examples
- Contribution: per-decision "new vs confirmed" patterns, growth curve SVG
Backend:
- /api/training/style-report endpoint computes all 4 sections in one call
- Headlines in Hebrew are computed server-side from real data
- Backfill script for style_patterns.frequency using _strip_nikud +
pattern-variant extraction (templates with [placeholders], / alternatives,
ellipsis all handled)
Real findings from the 24-decision corpus:
- דיון משפטי = 49% of avg decision (the focus)
- 23/24 use "לפנינו ערר" opening formula
- 21/24 use "ניתנה פה אחד" closing
- After 7 decisions we already learned 85% of her style patterns
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New proofreader service strips Nevo editorial additions (front matter,
postamble, page headers, watermarks, inline codes) from DOCX/PDF/MD
- PDF pages use Google Vision OCR for clean Hebrew RTL extraction
- New training page at #/training with drag-and-drop upload, automatic
metadata extraction (decision number, date, categories), reviewable
preview, and style pattern report grouped by type
- API endpoints: /api/training/{analyze,upload,corpus,patterns,
analyze-style,analyze-style/status}
- Fix claude_session.query to pipe prompt via stdin, avoiding ARG_MAX
overflow when analyzing 900K+ char corpus
- CLI scripts for batch proofreading and corpus upload
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add "עמדת ועדת הערר" placeholder to legal-analyst agent template
for each legal issue, to be filled by the chair as guidance for the
writing agent
- Fix green checkmark not showing for proofread documents (treat
'proofread' status same as 'completed')
- Show time alongside date in local files listing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add cases symlink, Google Vision extraction and benchmark
embedding data, and Paperclip bug report.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add delete_document_chunks for reprocessing, save extracted text to disk
- Expand case directory structure (original/extracted/proofread/backup)
- Update classifier patterns (תגובה, הודעת עמדה)
- Fix proofreader agent paths for new directory layout
- Update HEARTBEAT to notify on every task completion
- Improve bidi_table with LRE/PDF directional embedding
- Add Paperclip project verification and auto-close setup issue
- Add auto-sync-cases.sh for Gitea synchronization
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Documents with extraction_status='proofread' were incorrectly shown
as "in processing" on the case list page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New API endpoint /api/cases/{num}/local-files lists files from disk
- New API endpoint /api/cases/{num}/local-files/{folder}/{file} serves file content
- Case view now shows research/analysis files, proofread texts, and draft decisions
- Files are clickable and open in new tab
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove cases/new|in-progress|completed subdivision (status managed in DB)
- Rename documents/original → documents/originals (consistent plural)
- Move exports from global data/exports/ into cases/{num}/exports/
- Add documents/research/ for case law and analysis files
- Update all agents, scripts, config, web API endpoints, and DB paths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Benchmark on case 1130-25 (4 Hebrew legal docs, 8 queries) showed:
- voyage-law-2: avg top-1 score 0.5839 (+27% over voyage-3-large)
- voyage-4-large: avg top-1 score 0.4119 (worse than current)
- voyage-3-large: avg top-1 score 0.4589 (baseline)
voyage-law-2 costs ~4.6x more per run but delivers significantly
better retrieval quality for Hebrew legal text. Model is now
configurable via VOYAGE_MODEL env var.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- POST /api/admin/skills/{slug}/sync — read SKILL.md from disk, insert/update DB
- DELETE /api/admin/skills/{slug} — remove skill from DB (keeps disk files)
- UI: Sync/Re-sync and Delete buttons per skill in the skills list
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- POST /api/admin/skills/install — upload ZIP, extract to skills dir, update DB
- GET /api/admin/skills — list installed skills with DB/disk sync status
- POST /api/admin/paperclip/restart — restart Paperclip (pm2 or flag file)
- New Skills page in web UI with drag-and-drop ZIP upload
- Coolify volume mount for /paperclip-skills
- Host-side crontab watcher for restart flag file
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Export DOCX now saves to data/exports/{case_number}/ with auto-versioning
(טיוטה-v1, v2...). The case view UI shows all drafts with download buttons,
allows uploading revised versions (עריכה-v1...), and marking a version as
final (copies to training corpus for style learning).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
legal-ai MCP server now configured globally for all Claude Code sessions,
including Paperclip agents.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New: scripts/notify.py — sends via SMTP (notify@marcus-law.co.il → paperclip+chaim@marcus-law.co.il)
Updated: HEARTBEAT.md — agents must send email when waiting for human decision
Triggers: outcome choice, direction approval, QA failures, review ready.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All agent output — comments, status, errors, summaries, thinking — must be in Hebrew.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two issues that caused QA agent to fail:
1. save_block_content saved to DB only — now also rebuilds drafts/decision.md
2. legal-writer.md now has explicit mandatory step: case_update(status="drafted")
Without these, workflow_status reports has_draft=false and QA can't run.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Paperclip moved back from Docker to pm2 on host.
Reverts c83dcd6 (Docker migration URL change).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Paperclip moved from embedded PG (localhost:54329) to Coolify-managed
PostgreSQL container (10.0.2.13:5432).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
brainstorm_directions tool uses claude -p subprocess which times out
when called from inside a claude session (agent). CEO should think
about directions directly — it already has all the context.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CEO now follows a step-by-step interactive flow:
A. Check status and what's been done
B. Summarize case + ask Chaim for outcome (1/2/3)
C. Read response, run brainstorm, present directions
D. Read direction choice, approve, launch writer agent
E. Monitor writing progress
F. QA and export
All interaction happens through Paperclip comments.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Manages the decision writing pipeline:
- Creates issues and assigns to specialist agents
- Tracks status across all active cases
- Reports to human (Chaim) when approvals needed
- Never writes or analyzes directly — delegates
All 4 specialist agents now report to CEO.
Hierarchy: עוזר משפטי → מנתח/חוקר/כותב/בודק
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Symlinked to Paperclip instructions directory for each agent.
Single source of truth: .claude/agents/ files → symlinked to Paperclip.
Cleaned duplicate soul_md from DB metadata.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete agent pipeline for decision writing:
1. legal-analyst (existing) — extract claims/responses/replies
2. legal-researcher (new) — analyze precedents, plans, protocols
3. legal-writer (new) — write decision blocks in Dafna's style
4. legal-qa (new) — validate before export (6 checks)
All agents use claude_local adapter (Claude Code session, zero API cost).
Each has YAML frontmatter with specific tools and detailed Hebrew instructions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Defines the agent's role, tools, document type rules, and workflow.
Linked to Paperclip agent via --agent legal-analyst extraArg.
Key rules:
- Claims only from appeal docs, responses from response docs, replies from supplementary
- Never extract from precedents, plans, or protocols
- Must report results to Paperclip before finishing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New module claude_session.py provides query() and query_json() that
run prompts via `claude -p` CLI — uses the claude.ai session, zero API cost.
Converted 6 services:
- claims_extractor.py: extract_claims_with_ai
- brainstorm.py: brainstorm_directions
- block_writer.py: write_block (was streaming+thinking, now simple)
- qa_validator.py: claims_coverage check
- style_analyzer.py: 3 API calls (single pass, multi pass, synthesis)
- learning_loop.py: extract_lessons
Only extractor.py still uses Anthropic API (for PDF OCR with Vision).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wizard now creates: project + issue (CMP-N) + plugin_state entry
linking the issue to the legal-ai case number. This enables the
sync job in the marcusgroup.legal-ai plugin to track case status.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces API-based classifier with:
1. Filename pattern matching (covers 95%+ of legal docs)
2. Content keyword matching for ambiguous filenames
3. Claude Code headless (claude -p) fallback for edge cases
No Anthropic API calls needed for classification.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Text extraction, chunking and embedding proceed even if Claude API
classification or reference extraction fails (e.g. API quota exceeded).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>