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>