feat(scripts): כפתור "הרץ" מ-UI לסקריפטי read-only (קטגוריה B #4) #283

Merged
chaim merged 1 commits from worktree-scripts-run-ui into main 2026-06-17 04:31:20 +00:00
Owner

מה ולמה

הפריט האחרון מדוח-הנאמנות: המוקאפ 16-scripts מציג כפתור "הרץ"; הקוד הציג "מקור" בלבד. הכרעת חיים: להוסיף הרצה-מ-UI, רק לסקריפטי read-only/audit, argv-קבוע, בלי --apply. שימוש-חוזר בגשר-המארח הקיים (court-fetch) — שיכפול דפוס /adapter-migration.

אבטחה (הליבה)

  • allowlist בצד-המארחmcp-server/.../services/script_runner.py (מקור-אמת יחיד, stdlib-only): name → argv קבוע ובטוח. 5 סקריפטים מאומתים read-only: leak_guard.py · check_undefined_names.py · storage_leak_tripwire.py · audit_training_corpus.py · audit_corpus_integrity.py --no-notify.
  • הגשר (court_fetch_service/server.py): POST /run-script — Bearer-auth (COURT_FETCH_SHARED_SECRET הקיים), ולידציית-allowlist, create_subprocess_exec (ללא shell), timeout 600s, audit-log. מתעלם מכל ארגומנט מהבקשה — ה-argv נלקח אך-ורק מה-allowlist (אין הזרקת --apply).
  • קונטיינר (web/app.py): POST /api/scripts/{name}/run proxy לגשר + pre-check allowlist; הרחבת /api/scripts/catalog בשדה runnable_scripts.
  • UI (scripts/page.tsx + lib/api/scripts.ts): כפתור "הרץ" (ירוק) רק לשורות-runnable, window.confirm לפני הרצה, ודיאלוג-פלט (exit-code + stdout/stderr). שאר השורות — "מקור" בלבד.

שער-עיצוב

מוקאפ 16-scripts עודכן עם כפתור "הרץ" + באנר-הסבר + דיאלוג-פלט, ואושר ע"י חיים.

Invariants

  • G12leak_guard עובר; אין סמלי-פלטפורמה בשכבת-האינטליגנציה (הערה תוקנה).
  • G2 — allowlist יחיד משותף לגשר (אכיפה) ול-API (תצוגה).

בדיקות

py_compile ✓ · leak_guard (קבצי-backend) exit 0 ✓ · smoke: build_argv('leak_guard.py')→argv תקין, build_argv('renumber_cases.py')→None (חסום) ✓ · tsc --noEmit ✓ · eslint ✓.

⚠️ Deploy דו-שלבי

  1. גשר-המארח (server.py + המודול החדש) רץ על המארח דרך pm2 — דורש git pull בעותק-המארח + pm2 restart legal-court-fetch-service (צעד ידני). עד אז POST /run-script יחזיר 404 וה-UI יציג שגיאת-גשר.
  2. קונטיינר (web/app.py + web-ui) — Coolify deploy רגיל.
  3. npm run api:types אחרי שה-openapi החי כולל את ה-endpoint.

🤖 Generated with Claude Code

## מה ולמה הפריט האחרון מדוח-הנאמנות: המוקאפ `16-scripts` מציג כפתור **"הרץ"**; הקוד הציג "מקור" בלבד. הכרעת חיים: להוסיף הרצה-מ-UI, **רק לסקריפטי read-only/audit, argv-קבוע, בלי `--apply`**. שימוש-חוזר בגשר-המארח הקיים (court-fetch) — שיכפול דפוס `/adapter-migration`. ## אבטחה (הליבה) - **allowlist בצד-המארח** — `mcp-server/.../services/script_runner.py` (מקור-אמת יחיד, stdlib-only): `name → argv קבוע ובטוח`. 5 סקריפטים **מאומתים read-only**: `leak_guard.py` · `check_undefined_names.py` · `storage_leak_tripwire.py` · `audit_training_corpus.py` · `audit_corpus_integrity.py --no-notify`. - **הגשר** (`court_fetch_service/server.py`): `POST /run-script` — Bearer-auth (`COURT_FETCH_SHARED_SECRET` הקיים), ולידציית-allowlist, `create_subprocess_exec` (ללא shell), timeout 600s, audit-log. **מתעלם מכל ארגומנט מהבקשה** — ה-argv נלקח אך-ורק מה-allowlist (אין הזרקת `--apply`). - **קונטיינר** (`web/app.py`): `POST /api/scripts/{name}/run` proxy לגשר + pre-check allowlist; הרחבת `/api/scripts/catalog` בשדה `runnable_scripts`. - **UI** (`scripts/page.tsx` + `lib/api/scripts.ts`): כפתור "הרץ" (ירוק) **רק** לשורות-runnable, `window.confirm` לפני הרצה, ודיאלוג-פלט (exit-code + stdout/stderr). שאר השורות — "מקור" בלבד. ## שער-עיצוב מוקאפ `16-scripts` עודכן עם כפתור "הרץ" + באנר-הסבר + דיאלוג-פלט, ואושר ע"י חיים. ## Invariants - **G12** — `leak_guard` עובר; אין סמלי-פלטפורמה בשכבת-האינטליגנציה (הערה תוקנה). - **G2** — allowlist יחיד משותף לגשר (אכיפה) ול-API (תצוגה). ## בדיקות `py_compile` ✓ · `leak_guard` (קבצי-backend) exit 0 ✓ · smoke: `build_argv('leak_guard.py')`→argv תקין, `build_argv('renumber_cases.py')`→None (חסום) ✓ · `tsc --noEmit` ✓ · `eslint` ✓. ## ⚠️ Deploy דו-שלבי 1. **גשר-המארח** (`server.py` + המודול החדש) רץ על **המארח** דרך pm2 — דורש `git pull` בעותק-המארח + **`pm2 restart legal-court-fetch-service`** (צעד ידני). עד אז `POST /run-script` יחזיר 404 וה-UI יציג שגיאת-גשר. 2. **קונטיינר** (`web/app.py` + web-ui) — Coolify deploy רגיל. 3. `npm run api:types` אחרי שה-openapi החי כולל את ה-endpoint. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-06-17 04:31:12 +00:00
feat(scripts): כפתור "הרץ" מ-UI לסקריפטי read-only (קטגוריה B #4)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 11s
221975fe23
הרצת-סקריפט-מ-UI ב-/scripts, רק לסקריפטי קריאה-בלבד/אודיט, דרך גשר-המארח
הקיים (court-fetch) — שיכפול דפוס /adapter-migration.

אבטחה:
- allowlist בצד-המארח (services/script_runner.py, מקור-אמת יחיד): name→argv
  קבוע ובטוח. 5 סקריפטים מאומתים: leak_guard, check_undefined_names,
  storage_leak_tripwire, audit_training_corpus, audit_corpus_integrity --no-notify.
- הגשר (court_fetch_service/server.py): endpoint POST /run-script, Bearer-auth,
  ולידציית-allowlist, create_subprocess_exec (ללא shell), timeout 600s,
  audit-log; מתעלם מארגומנטים מהבקשה (argv מה-allowlist בלבד).
- קונטיינר (web/app.py): POX /api/scripts/{name}/run proxy ל-גשר + pre-check
  allowlist; הרחבת /api/scripts/catalog ב-runnable_scripts.
- UI: כפתור "הרץ" (ירוק) רק לשורות-runnable + דיאלוג-פלט (exit-code+stdout);
  שאר השורות "מקור" בלבד. confirm לפני הרצה.

מאושר דרך שער-העיצוב (מוקאפ 16-scripts עודכן עם כפתור "הרץ").
G12: leak_guard עובר (אין סמלי-פלטפורמה בשכבת-האינטליגנציה).

Deploy דו-שלבי: גשר-המארח דורש git pull בעותק-המארח + pm2 restart
legal-court-fetch-service; הקונטיינר נפרס דרך Coolify כרגיל.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chaim merged commit e7124e94a3 into main 2026-06-17 04:31:20 +00:00
chaim deleted branch worktree-scripts-run-ui 2026-06-17 04:31:21 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ezer-mishpati/legal-ai#283