Commit Graph

103 Commits

Author SHA1 Message Date
943696efbd docs(heartbeat): §1.5ד — קרא legal_predecessor_context בעת continuation (#220)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
משלים את follow-up #1: מנחה סוכן שמתעורר-מחדש על תיק לקרוא את כלי-ה-plugin
legal_predecessor_context(case_number) לפני שיגלה-מחדש הקשר מאפס — כך ממשיך
מנקודת-העצירה ומונע blind heartbeat. הכלי חי ב-plugin (plugin-legal-ai #5+#6,
toolCount=9); ה-endpoint by-case חי (legal-ai #410).

תוקף: HEARTBEAT נקרא ע"י claude_local מ-~/legal-ai — דורש host git pull.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 05:18:32 +00:00
9e7ef4fced refactor(export): שם קובץ טיוטת-הביניים → טיוטה-טענות_הצדדים_{N} (הנחיית חיים)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 31s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
במקום "טיוטת-ביניים-v{N}.docx" — שם מדבר יותר: "טיוטה-טענות_הצדדים_{N}.docx".
הפורמט הסופי ("טיוטה-v{N}") לא משתנה.

- docx_exporter._draft_naming: (prefix, sep) פר-מצב; interim=("טיוטה-טענות_הצדדים","_"),
  final=("טיוטה","-v"). glob/parse משתמשים ב-rsplit(sep,1) — נכון גם כשה-prefix
  עצמו מכיל "_".
- app.py _generation_output_ready + frontend pickLatestVersioned: matcher-prefix
  מעודכן; regex-הגרסה עוגן-לסוף /[_v](\d+)$/ (ה-"_" שבתוך הprefix לא מבלבל).
- docstrings + legal-ceo.md + הערות מעודכנים לשם החדש. types.ts (auto-gen)
  יתעדכן ב-api:types.

שינוי-נתון (שם-קובץ), לא layout — בגדר חריג-שער-העיצוב. tsc+eslint+py_compile
ירוקים. הערה: ייצור-השם רץ ב-MCP המקומי (host) → דורש reload; ה-matchers
בקונטיינר (Coolify).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 12:31:30 +00:00
3462cb7320 fix(generate): הפקת מסמכים דרך issue-ילד משויך-ל-CEO — לא מבוטלת בהמתנה-ליו"ר (#227)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 33s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
באג: כפתורי "הפקת מסמכים" (טיוטת-ביניים / סיכום-מנהלים) העירו את ה-CEO
*על ה-issue הראשי*. כשהתיק ב-in_review משויך-לחיים (המצב הרגיל של תיק
ממתין-ליו"ר), Paperclip ביטל את הריצה מיד (issue_assignee_changed) — הכלום
הופק, וה-endpoint החזיר 202 בכל מקרה, כך שהכשל היה שקוף.

תיקון: wake_ceo_for_action יוצר issue-ילד משויך-ל-CEO תחת ה-issue הראשי
ומעיר על הילד — בדיוק כדפוס wake_analyst_for_argument_aggregation שעובד.
ה-CEO בעל הילד → הריצה לא מבוטלת. ההוראה מוכלת בתיאור-הילד (הרץ את הכלי,
comment, סגור done) ולא תלויה בפענוח payload.action. legal-ceo.md מעודכן
שההערה מגיעה על issue-ילד ייעודי שיש לסגור בסיום.

מגע-Paperclip רק בשער-הפלטפורמה (G12). זהו החצי הראשון (ב) של #227; חצי
שני (ג) = סימון-סטטוס ב-UI. py_compile ירוק.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 11:16:46 +00:00
5867f7175f docs(status): align agent status maps to the canonical (nested) status model
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
Follow-up to the status SSoT (#382): analyst_verified + research_complete are
now first-class canonical statuses, so refresh the docs that still framed them
as legacy/decorative.

- HEARTBEAT.md §7: rewritten to point at the single source
  (case_status_model.py / GET /api/status-model), list the 12 canonical statuses
  by phase, and state the two intermediates are canonical (not legacy); genuinely
  old markers (proofread/analysis_enriched/…) are display-only fallbacks.
- legal-qa.md / legal-ceo.md status maps: dropped the "legacy/optional" framing
  on research_complete; point to the canonical model.
- scripts/backfill_case_status_trim.py: removed analyst_verified +
  research_complete from the downgrade map (they are valid statuses again — must
  NOT be downgraded) + updated the docstring.

Docs/prompts only — no behaviour change. py_compile clean.
NOTE: the host ~/legal-ai needs `git pull` for the Paperclip agents to pick up
the refreshed prompts (they run on the host tree, not the container).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 19:52:27 +00:00
b560417dd7 feat(ceo): wire party-claims executive summary as chair-requestable stage (#202 follow-up)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
The summarize_party_claims tool (#202) generated a distilled executive
summary of party claims but was orphaned: not granted to any agent and
no CEO trigger. Wire it parallel to the interim-draft (שלב H).

- Grant mcp__legal-ai__summarize_party_claims in legal-ceo.md frontmatter.
- Add שלב H2 (סיכום מנהלים) mirroring שלב H: side-quest (no cases.status
  change, no sub-agent issues), in_progress → run tool → in_review + notify.
  Two triggers: chair comment ("סיכום מנהלים"/"סיכום טענות"/"סיכום לקראת
  דיון"/"executive summary") OR structured action
  $PAPERCLIP_WAKE_PAYLOAD_JSON action == "party_claims_summary".
- Add structured-action trigger to שלב H (interim draft):
  action == "interim_draft" — same deterministic UI-button path.
- שלב 0 + HEARTBEAT.md: route structured actions deterministically.
- Spec note in docs/spec/04-analysis-writing.md §1.4.

Invariants: G2 (reuse existing summarize_party_claims tool/path, no parallel
route), G10 (chair-requested side-quest). Agent-prompt/docs only — no app code.

Note: CEO prompt is shared across CMP+CMPA via instructionsFilePath; after
merge the host tree needs `git pull` (agents run host-side reading
.claude/agents/*.md).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 19:22:26 +00:00
9836957848 feat(agents): שטן-מליץ — שער-קבע אוטומטי אחרי הניתוח עם עצירת-אישור לידים ליו"ר (#211)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
שינוי-מדיניות יו"ר: ה-red-team (gemini_local) עובר מ-on-demand ל-standing gate
שרץ אוטומטית אחרי שלב-הניתוח ולפני הכותב — אבל הלידים נעצרים לאישור-יו"ר ולעולם
אינם מוזנים לכותב אוטומטית. רק לידים שהיו"ר מאשר → chair_directions (דרך
record_chair_feedback → get_chair_directions → approve_direction). הכותב צורך רק
פלט-מנתח מעוגן + הנחיות-מאושרות.

- legal-ceo.md: שורת-הטבלה + סעיף שטן-מליץ (on-demand→שער-קבע) + שלב A2 (red-team
  אוטומטי) + שלב A3 (עצירת-אישור לידים, in_review + notify) מוזרקים אחרי שלב A
  ולפני שלב B; מפת-הסטטוסים (documents_ready/analyst_verified/research_complete)
  מנתבת דרך השער.
- legal-analyst-gemini-critique.md: trigger=standing gate (לא on-demand); הפלט
  נשאר לידים לא-סמכותיים תחת אישור-יו"ר.
- HEARTBEAT.md §7: שער שטן-מליץ בזרימת-הסטטוס.
- docs/spec/X4-agents.md: INV-AG4 + הערה במפת-הסוכנים.
- docs/spec/04-analysis-writing.md §1.6: שער ה-red-team בין ניתוח לכתיבה.

Invariants: G10 (שער אנושי קשיח), INV-AH/INV-LRN5 (לידים לא-סמכותיים, לא
מוזנים אוטומטית), G12 (שינוי מוגבל למשטח agent-prompt).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 18:08:50 +00:00
26451f7c9d fix(ceo): company-wide pending-comment scan with mandatory case binding
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
Root cause (proven 2026-06-30, legal-ai #164): the comment-sweep wakes the CEO
via ctx.agents.invoke, which does NOT populate $PAPERCLIP_WAKE_REASON or
payload.issueId. The run transcript showed "generic heartbeat with no scoped
wake" — the CEO's `user_commented` branch never fired, it ran a generic
heartbeat that scans only CEO-assigned issues, and chair comments on
chaim/sub-agent-owned issues (e.g. CMPA-116) were invisible → no-op. Two real
6-day-stale chair requests sat undelivered.

Fix: on any wake without a scoped reason, the CEO must DISCOVER pending chair
comments itself. Adds "סריקת הערות-יו"ר תלויות (company-wide)":
- enumerate all active company issues (/api/companies/{id}/issues)
- pending = newest user comment newer than newest agent comment (ignore
  system); order-independent sort_by(createdAt) since the API is newest-first
- MANDATORY case binding from the STRUCTURED project.name ("ערר <case> — …"),
  never from the title (CMPA-116 has none) nor the comment content (which may
  name a different case, e.g. "ניסיתי ב-CMPA-89"). No confident case → do NOT
  act; escalate to chair.
- handle each pending comment scoped to its own $ISSUE_ID/$CASE_NUMBER

Verified end-to-end against live data: 13 active issues → exactly 2 pending
(CMPA-116, CMPA-89), both resolved to case 8125-09-24 via project.name, zero
false positives. Step 0 + Step A wired to run the scan on blind wakes.

Refs #164. Pairs with the plugin sweep (delivery) — this is discovery+action.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 12:19:05 +00:00
24e02621df docs(heartbeat): comment-recheck gate before done — prevent dropped chair comments
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
Belt-and-suspenders to the plugin sweep (plugin-legal-ai #3). Comments that
arrive mid-run aren't re-read automatically — an agent reads comments once at
run start (§2), so a chair comment that lands after that point and before the
run closes the issue is never seen. That is exactly how a chair comment on
CMP-190 (2026-06-30) was dropped.

Adds a mandatory gate to HEARTBEAT §4ב: before PATCH status=done, re-read
comments and compare to the run-start list. If a new unaddressed chair comment
exists — do not close. Either handle it (and record a comment) or, if it
widens scope, keep the issue open and hand back to the CEO (§4ג). Never mark
done while a chair comment waits unanswered.

The plugin sweep catches orphaned comments within ~2 min; this gate prevents
the drop at the source. Refs legal-ai #164.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 10:20:47 +00:00
4d6268820c feat(learning): curator §A fires on mark-final — capture source='curator' findings on every final (#159)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
חלופה ז (agent-centric) — סוגר את פער-המימוש מ-#157:

1. final_learning_pipeline.py — סדר-מחדש: enroll_style_corpus רץ ראשון (לפני הדיסטילציה של עד
   30 דק'), כך שרשומת style_corpus קיימת תוך שניות — והאוצֵר יכול לרשום ממצאים בלי מירוץ.
   enroll/ingest בלתי-תלויים; panel נשאר אחרון. תוויות [1/3]/[2/3] עודכנו.

2. hermes-curator.md PIPELINE-WAKE BRANCH — מבדיל final_learning_* (ממשיך ל-§A, מצב AUTO) מ-
   final_halacha_* (exit כקודם). ב-AUTO: §A.1–§A.5b → record_curator_findings, דילוג על §A.6
   (interaction) כדי לא להעיר את דפנה (הממצאים proposed ונסקרים ב-/training). §A.5b קיבל retry
   כרשת-ביטחון למירוץ-שארית.

3. docs/spec/07-learning.md §0.6 + §1.1 — עודכנו לסדר-הצינור החדש; הערת "פער-מימוש פתוח" → "נסגר".

Invariants: G2 (מחולל-יחיד לממצאי-curator — הסוכן; אין כפילות-תבונה), INV-LRN1/G10 (proposed,
שער-יו"ר), INV-LRN3, INV-DUR1 (סדר-צעדים בשמות יציבים; checkpoint resume — edge-case של ריצה
מקבילה-לפריסה, סיכון נמוך). depends-on #157.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 21:56:36 +00:00
be774ab87e fix(learning): honest 3-channel curator card + capture curator findings (source='curator')
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 9s
תיקוני-מבנה ללולאת-הלמידה (TaskMaster #157):

1. כרטיס ה-curator (/training טאב "אוצֵר") ספר decision_lessons WHERE source='curator'
   — ערך שאף מסלול-קוד לא כתב → תמיד 0. עוצב-מחדש (דרך שער-העיצוב Claude Design, אושר)
   להציג ביושר את שלושת ערוצי-ההזנה לכותב: דיסטילציה→appeal_type_rules (180, זורם),
   פאנל→decision_lessons (81, ממתין), אוצֵר→source='curator'. get_curator_stats שוכתב.

2. drift ספ↔סוכן: 07-learning.md §1.1 + INV-LRN3 קבעו שהאוצֵר רושם ממצאים כ-decision_lesson
   source='curator', אך הסוכן כתב comments בלבד — הממצאים האיכותיים אבדו. נוסף כלי-MCP
   record_curator_findings + §A.5b ב-hermes-curator.md (read-only נשמר; הצעה מגודרת-שער).

3. get_recent_decision_lessons(limit=15) חתך בשקט — נוסף WARN על מה שנחתך (חוקה §6);
   הפתרון האמיתי = סינתזת-לקחים (TaskMaster #158).

Invariants: מקיים INV-LRN1/G10 (שער-יו"ר), INV-LRN3 (לכידה מובנית), INV-IA2/IA5 (מקור-אמת
יחיד), G12 (leak-guard עובר), G2 (אין מסלול מקביל — אותם מאגרים). פער-מימוש פתוח מתועד:
§A לא רץ אוטומטית על mark-final (pipeline-wake exits) → נדחה לתכנון נפרד.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 21:20:05 +00:00
ccc5a73bc8 feat(x11): treatment-aware citation authority wired into research agents (#154)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 4s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
The internal citation graph fed only RANKING (raw in-degree), and the per-citation
TREATMENT was never classified — so a precedent distinguished N times got the same
authority boost as one followed N times (INV-COR2 violation), and the signal never
reached the agents' reasoning. Wires the full path:

Phase 1 — scripts/classify_citation_treatments.py: classify each linked edge's
  treatment (followed/distinguished/…) from its match_context via
  corroboration.classify_treatment (Opus 4.8 @ xhigh, local), filling
  precedent_internal_citations.treatment. Idempotent.
Phase 2 — db.refresh_verified_layer: count only NON-negative treatments toward
  verified/cite_count (INV-COR2/COR4). Unclassified counts as neutral-positive so
  the signal degrades gracefully before classification runs.
Phase 3 — db.citation_authority(ids): per-precedent {total, positive, negative,
  unclassified, by_treatment}. Surfaced as `cited_by` in search_precedent_library
  hits and precedent_library_get, and `treatment` per incoming citation.
Phase 4 — legal-researcher/analyst/writer prompts: weigh & ARGUE authority
  ("הלכה שאומצה ב-N החלטות ועדת-ערר"), flag distinguished/overruled, never invent
  the count (INV-AH; writer is read-only of the analyst).

Auto-approval stays kill-switched off (chair gate preserved, INV-G10). No schema
change (treatment column already existed). Operational: run the classifier +
refresh_verified_layer over the 379 edges, then sync agents across companies.

Invariants: G2 (one classifier + one authority query, reused), INV-COR2/COR3/COR4
(negative never corroborates; point-specific; ≥N), INV-G10 (no auto-approval),
INV-AH (no invented numbers).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 16:04:04 +00:00
3c4454651a chore(settings): חסימת כלי task-master-local מבוססי-LLM שנתקעים
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 5s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
update_task וקרוביו (update/expand/analyze/research/parse_prd/scope) קוראים
ל-backend-LLM של TaskMaster ונתקעים שוב ושוב. נחסמים ב-permissions.deny.
עדכוני-תוכן של משימות ייעשו בעריכה ישירה של .taskmaster/tasks/tasks.json
(אותו מאגר — תואם feedback_taskmaster_cli_cwd). הכלים הדטרמיניסטיים
(get_tasks/get_task/next_task/set_task_status/add_task/move_task/…) נשארים.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 10:41:46 +00:00
46bcaa8fa3 feat(plans): הרשאות-סוכנים + dedup/merge/edit + API לתור-אישור תכניות (backend)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
Follow-ups למרשם-התכניות (PR #252), חלק ה-backend (ללא-UI):
- סוכנים: הוספת extract_plans/plan_get/plan_search/plan_list ל-CEO ול-חוקר
  (+ plan_upsert לחוקר); plan_review נשאר אנושי בלבד (G10). .claude/agents/*.md.
- db: _plan_core_token + find_similar_plans (הצפת כפילות-וריאנט לאישור ידני, בלי
  מיזוג-אוטומטי), update_plan (עריכה+renumber, guard התנגשות→merge), merge_plans
  (איחוד aliases, מילוי-חוסר, סתירות→discrepancies, מחיקת מקור).
- plans_extractor: צירוף possible_duplicates לפלט החילוץ.
- web/app.py: GET /api/plans(+/{id},/{id}/duplicates) · POST /api/plans · PATCH
  /api/plans/{id} · POST /api/plans/{id}/review · POST /api/plans/merge; +קטגוריית
  "תכניות הממתינות לאישור" ב-/api/chair/pending.

תיקון-נתונים (DB, מחוץ ל-PR): הל/מח/250 ד' → 7.1.2002, י"פ 5045.
ה-UI (טאב /precedents + מונה /approvals) ב-PR נפרד אחרי שער Claude Design.

Invariants: G1 (נרמול בכתיבה/עריכה) · G2 · G3 · G10 (review_status + מיזוג ידני,
אישור אנושי) · INV-DM2/DM5 · INV-AH · X9 · אין בליעה שקטה (discrepancies).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 14:39:46 +00:00
e6778d26e5 docs(#126): תיעוד Hermes כ-runtime + self-learning אינרטי; ניקוי persona→אוצֵר
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 5s
המשך ל-#123. ממצא: אנחנו מריצים את ה-Hermes CLI של Nous כ-runtime ל-deepseek_local
(harness בלבד), וה-self-learning דלוק-אך-אינרטי (state.db = תמלילים בלבד, ללא
memories/user_profile/skills; רדום מאז 5-6.2026).

- doc חדש: docs/research/hermes-runtime-and-self-learning-state.md
  (חקירה פורנזית + playbook להפעלת Hermes המלא בעתיד + שערי-ממשל INV-LRN1/LRN5/G12)
- cross-link מ-#123 feasibility
- ניקוי persona "Hermes" ב-hermes-curator.md (Hermes=runtime CLI, זהות=אוצֵר-ידע)

שינויי-host (לא בריפו, מתועדים): כיבוי self-learning ב-curator-{cmp,cmpa}/config.yaml
+ persona ב-SOUL.md → אוצֵר-ידע (גיבוי .bak). HERMES_HOME/HERMES_CLI נשמרו (runtime).

Invariants: INV-LRN1/LRN5 (יישור — self-learning לא-מגודר כובה), G12 (Hermes=runtime
מאחורי Port, לא פלטפורמה מקבילה), G2. מסמך+config, אין שינוי-קוד.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:54:16 +00:00
621dcf749a fix(ceo): corroboration_rebuild בחילוץ-ספרייה מסוקף ל-case_law_id (לא כל-הקורפוס)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 7s
המשך אבחנת ה-heartbeat-timeout (#120): שלב 4 בזרימת חילוץ-הספרייה של ה-CEO הורה
להריץ `corroboration_rebuild()` עם ארגומנט ריק = `build_all()` שעובר על כל הקורפוס
עם קריאת-LLM (Opus xhigh) לכל ציטוט-נכנס = שעות → חורג מ-heartbeat של שעה
(timeout/process_lost). זה רץ בכל ריצת חילוץ-ספרייה, מיד אחרי החילוץ — כך שגם אחרי
שהחילוץ הפך לתיק-בודד (#120), שלב הקורובורציה היה ממשיך ל-timeout.

תיקון: הפרומפט מורה כעת `corroboration_rebuild(case_law_id="<issue>")` — מסוקף לתקדים
הבודד (bounded, דקות), עם אזהרה מפורשת לא להריץ ריק. ה-backfill המלא של כל-הקורפוס
נשאר ב-pipeline המקומי הדורבילי (scripts/final_halacha_pipeline.py, X16 checkpoint/resume).

קובץ-פרומפט בלבד — נקרא חי דרך instructionsFilePath מהעץ הראשי (אין deploy ל-Coolify;
דורש git pull בעץ הראשי אחרי מיזוג). leak_guard עובר.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 16:15:51 +00:00
4fa62db192 feat(halacha): drain לילי (23:00–05:00) + per-upload חילוץ תיק-בודד דרך ה-CEO (#120)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 6s
מפריד בין ריקון-באקלוג המוני לבין חילוץ per-upload, ומסיר את ה"פקק" שגרם
timeout/process_lost ב-heartbeat של ה-CEO.

הבעיה (אבחנה 2026-06-11): לחיצת "חלץ הלכות" על תיק בודד יצרה issue (CMP-165)
שהורה ל-CEO להריץ precedent_process_pending(halacha) — בולען סינכרוני שמרוקן את
כל התור ההיסטורי (147 ממתינים, שעות) בתוך heartbeat שחסום לשעה. תוצאה: timeout
כל שעה → process_lost בפירוק קבוצת-התהליכים → retry → סטורם, והתיק הבודד (FIFO
אחרון) לא טופל. לא OOM, לא קוד שבור — אי-התאמה ארכיטקטונית.

התיקון:
1. per-upload (web/paperclip_client.py, wake_for_precedent_extraction): גוף ה-issue
   + תיאור-הפרויקט מורים כעת להריץ precedent_extract_metadata +
   precedent_extract_halachot ל-case_law_id של ה-issue **בלבד** — עם אזהרה
   מפורשת לא להריץ process_pending. reextract_halachot כבר מנקה requested_at
   ומסמן completed → התיק לא יחזור לתור הלילי.
2. הוראות ה-CEO (.claude/agents/legal-ceo.md): אותו שינוי — חילוץ תיק-בודד, לא
   ריקון-תור. (צריך sync_agents_across_companies.py --apply אחרי מיזוג.)
3. ריקון-באקלוג (scripts/drain_halacha_queue.py): שער חלון-לילה 23:00–05:00 שעון
   ישראל (zoneinfo, DST-safe — המכונה UTC). מחוץ לחלון ===SKIP===; נעצר ===STOP===
   כשהחלון נסגר, השאר ממשיך בלילה הבא (FIFO + per-chunk checkpoint). env:
   HALACHA_DRAIN_WINDOW_START/_END/_TZ.
4. cron (scripts/legal-halacha-drain.config.cjs): UTC band 20:00–03:00 שמכסה את
   חלון-ישראל בשני מצבי-DST; הסקריפט גוזם לחלון המדויק. ירייה שעתית מחדשת
   one-shot שמת (advisory-lock → חפיפה בטוחה).

רשת-ביטחון: request_halacha_extraction עדיין מסמן requested_at, כך שאם wakeup
ל-CEO נכשל — הדריינר הלילי יתפוס את התיק (בלילה, חסום), אך שום נתיב יומי לא
מרוקן את כל התור.

Invariants: מקיים G12/INV-PORT1 (paperclip_client = shell; leak_guard עובר).
נוגע X16 (durability — מתקציב-זמן heartbeat ל-job ייעודי).

בדיקות: py_compile ✓ · window-logic + zoneinfo ✓ (17:00 IDT→False) · leak_guard ✓.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 14:02:38 +00:00
a4e006ab50 feat(agents): deepseek_local טוען פרומפט מקובץ — איחוד מקור-אמת לפרומפט של Hermes (G2)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 8s
כל סוכני המערכת טוענים את ה-system prompt מקובץ תחת .claude/agents/ דרך
instructionsFilePath (claude_local + gemini_local), פרט ל-Hermes/curator על
deepseek_local שתמך רק ב-promptTemplate inline ב-DB — מסלול-פרומפט מקביל (הפרת G2),
לא מגורסת ב-git, ושני המקורות (DB ↔ hermes-curator.md) כבר התפצלו בתוכן.

מה השתנה:
- adapters/deepseek-paperclip-adapter: buildPrompt קורא instructionsFilePath אם הוגדר
  (resolveTemplate; עדיפות file > promptTemplate > DEFAULT). הקובץ עובר renderTemplate
  כך ש-{{wakeReason}}/{{#taskId}}/… ממשיכים לעבוד. כשל-רועש אם הקובץ הוגדר ואינו
  קריא — לא fallback שקט (כלל-הנדסה §6, feedback_silent_swallow).
- hermes-curator.md הופך ממסמך-תיעוד למקור-האמת בפועל: מיזוג current-from-both —
  ה-runbook התפעולי מה-DB (PIPELINE-WAKE/X16 + §A/§B + interactions) + שער
  anti-hallucination (INV-AH) וקריאת-ספ (INV-AG1) שהיו רק ב-md ומעולם לא הגיעו
  ל-runtime של הרמס. ה-ingest_final_version/lessons הידני הושמט — ה-pipeline (X16)
  כבר מריץ אותו durably; הרצה ידנית הייתה כפילה.

נותר תפעולי (לא ב-git): עדכון 2 רשומות deepseek_local ב-Paperclip DB
(instructionsFilePath=.../hermes-curator.md, ריקון promptTemplate) + git pull בעץ
הראשי + pm2 restart paperclip + sync-agents.

Invariants: מקיים G2 (ביטול מסלול-פרומפט מקביל), G12/X15 (מגע-פלטפורמה רק במעטפת
המוצהרת — adapter), INV-AH + INV-AG1 (מגיעים סוף-סוף ל-Hermes), כלל-הנדסה §6
(כשל-רועש). ללא שינוי התנהגות-runtime פרט להוספת שער-ה-AH (כוונה מפורשת, אישור יו"ר).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 12:16:33 +00:00
bfea8d8895 chore(agents): מחק את קובץ-הבנצ'מרק הנטוש legal-analyst-gemini.md
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 7s
הוחלף ב-legal-analyst-gemini-critique.md (שטן מליץ); 0 סוכנים מצביעים אליו.
שירת רק את ניסוי-ההשוואה החד-פעמי מול Opus (מתועד ב-comparison-opus-vs-gemini.md
ובזיכרון). אין סיבה לשמור קוד מת.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:33:51 +00:00
1c182edb29 docs(agents): centralize completion/wakeup protocol to HEARTBEAT §4 (R1, G12, #110)
6 סוכני-העובד (writer/exporter/proofreader/qa/researcher/analyst) שכפלו inline את
בלוק-הדיווח-וההשכמה הזהה (PATCH done/blocked + CEO_ID if-block + wakeup JSON +
אזהרת agent_wakeup_requests) — שהוא כבר המקור הקנוני ב-HEARTBEAT.md §4ב/§4ג.

הוחלף בכל קובץ במצביע קומפקטי ל-HEARTBEAT §4ב/§4ג, תוך שימור: ה-rationale
(auto-retry), reason ספציפי-לתפקיד, ומלכודות ספציפיות (UUID של analyst, QA gate
של writer). כפילות הפרוטוקול הקשיח: 288→83 hits (היתרה: orchestration לגיטימי של
CEO + מצביעי-HEARTBEAT). סוכני gemini נשארו (וריאנט מצומצם מכוון, ללא CEO).

Invariants: G12 (פרומפטים מצביעים ל-HEARTBEAT, לא משכפלים פרוטוקול) · G2 (מקור יחיד).

הפצה לסוכנים-רצים: לאחר מיזוג — git pull בעץ הראשי + sync_agents_across_companies.py
(הפרומפטים נטענים מ-cwd המשותף). אומת מבנית: code-fences מאוזנים, מצביעי §4 מדויקים.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 09:22:20 +00:00
d156bcfaf1 feat(agents): שער anti-hallucination משותף מעוגן-מקור (INV-AH) לכל הסוכנים
מחלץ את דיסציפלינת מניעת-ההזיות לבלוק קנוני אחד (docs/anti-hallucination-gate.md)
ומחיל אותו אחיד על כל הסוכנים — במקום שכל סוכן ימציא אותה מחדש ad-hoc (G2: בלי מסלולים מקבילים).

5 טכניקות, כל אחת מעוגנת במקור מקצועי:
- AH-1 עיגון-מקור (אפס ציטוט מהזיכרון) — Stanford RegLab/Magesh JELS 2025 (כלי-RAG משפטיים הוזים 17-33%)
- AH-2 quote-or-retract + AH-3 abstention — Anthropic Reduce-hallucinations
- AH-4 תיוג-ודאות — NIST AI RMF GenAI Profile + RAGAS
- AH-5 Chain-of-Verification — Dhuliawala et al. arXiv:2309.11495

הפצה DRY: הפניה ב-HEARTBEAT.md (נקרא ע"י כל סוכני Paperclip) + שורה אחידה בבלוק
'קרא לפני פעולה' של כל 8 הסוכנים, עם הערת-יישום לכל תפקיד (writer=read-only, qa=אוכף,
proofreader=אל תתקן לכיוון מונח משפטי, exporter=אפס מהות חדשה).

בנוסף: legal-ceo.md מקבל ידע על 'שטן מליץ (Gemini)' עם מדיניות on-demand טהורה —
לא בפייפליין, מופעל רק לבקשת חיים/דפנה, הפלט=לידים ליו"ר (לא לכותב, human-in-the-loop).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 17:05:33 +00:00
1a50aa7709 feat(agents): שטן מליץ (Gemini) — red-team מוגבל עם שער anti-hallucination
ממסד את סוכן-Gemini מחדש כשכבת דעה-שנייה (devil's advocate) שרצה אחרי Opus
ומפיקה מזכר-לידים לא-סמכותי ליו"ר — לא ניתוח מתחרה. read-only (critique-gemini.md בלבד).

9 אילוצי anti-hallucination קשיחים, מעוגנים במקורות מקצועיים:
- Stanford RegLab/Magesh JELS 2025 (כלי-RAG משפטיים הוזים 17-33%) → עיגון-קורפוס מוחלט
- Anthropic Reduce-hallucinations → quote-or-retract + abstention
- Chain-of-Verification (Dhuliawala 2023, arXiv:2309.11495) → מעבר-אימות חובה
- RAGAS faithfulness → atomic-claim grounding
- NIST AI RMF GenAI Profile 2024 → human-in-the-loop, לידים-לא-הכרעות

מתחיל בכותרת # (לא ---) למניעת כשל yargs ב-gemini --prompt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 16:15:53 +00:00
7f573c0db3 fix(agents): הסר YAML frontmatter מ-legal-analyst-gemini.md
adapter gemini_local מעביר את תוכן הקובץ כ-arg ל-`gemini --prompt <content>`.
כש-content מתחיל ב-`---` (frontmatter), yargs מפרש זאת כדגל ולא כערך →
'Not enough arguments following: prompt' וה-run נכשל ב-adapter_failed תוך 2ש'.
הפיכת הראש לכותרת # פותרת. (claude_local לא נתקל בזה — הוא מעביר --append-system-prompt-file <path>.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 15:30:18 +00:00
e57730f375 feat(agents): מנתח משפטי וריאנט Gemini (read-only benchmark)
עותק של legal-analyst שרץ תחת gemini_local (Gemini CLI, gemini-3.1-pro-preview)
לצורך השוואת איכות-ניתוח מול Opus. מצב read-only: שלבי extract/aggregate/case_update
מוחלפים בקריאה בלבד, והפלט נכתב ל-analysis-and-research.GEMINI.md בלבד — כדי לא לדרוס
את ניתוח-Opus הקנוני. אכיפת read-only גם ברמת MCP (excludeTools ב-~/.gemini/settings.json).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 15:13:08 +00:00
8171572cdd feat(digests): קורפוס יומונים כשכבת-גילוי (radar) — X12
מאגר חדש ליומוני "כל יום" (עפר טויסטר) כשכבת-גילוי מעל קורפוסי-הפסיקה:
מקור-משני המצביע על פסק הדין המקורי, נקלט לטבלה נפרדת `digests`, נחפש
סמנטית, ומקושר לפסק המקורי בספריית הפסיקה — אך לעולם אינו מצוטט בהחלטה
ואינו מחלץ הלכות.

Phase 0 (spec):
- docs/spec/X12-digests-radar.md — INV-DIG1 (מצביע לא מצוטט) /
  INV-DIG2 (מסלול-קליטה נפרד, לא מקביל — מקיים G2) / INV-DIG3 (קישור-לפסק
  הוא הגשר; חוסר-קישור = פער גלוי). עדכון אינדקס 00/03/README.

Phase 1 (MVP):
- SCHEMA_V30: טבלת `digests` (HNSW על embedding — לא ivfflat, להימנע מ-recall
  cliff בקורפוס קטן/צומח) + GIN/FTS + UNIQUE חלקי ל-idempotent.
- services/digest_metadata_extractor.py — חילוץ-LLM (claude_session local-only,
  ייבוא lazy): תג-מושג, כותרת-הלכה, מראה-מקום, שני-תאריכים מובחנים, תגיות.
- services/digest_library.py — מסלול קצר עצמאי (INV-DIG2): extract→hash→LLM→
  embedding יחיד→autolink. לא משתמש ב-ingest.ingest_document.
- tools/digests.py + רישום 7 כלים ב-server.py (digest_upload/list/get/link/
  relink/delete + search_digests).
- scripts/ingest_digests_batch.py — קליטה ידנית מ-data/digests/incoming.
- legal-researcher.md: שלב 2ב.0 (סריקת-radar לפני אימות) + סעיף-דוח ט +
  3 כלים ב-frontmatter. HEARTBEAT §8: ניתוב יומון→digest_upload.

אומת end-to-end: 4 יומונים נקלטו (מטא-דאטה מדויק), חיפוש סמנטי מדרג נכון
("היטל השבחה"→5160, "תמא 38"→5158), link/relink/autolink/revert + מעטפת-MCP.

Invariants: מוסיף INV-DIG1/2/3 (X12). מקיים G2 (bounded context נפרד, לא
מסלול מקביל), G3 (idempotent upsert), G4 (אין בליעה שקטה — פער-קישור מוצף),
G9 (עקיבוּת — היומון מצביע על מקור עקיב). נוגע G7 (RRF) — נדחה, חיפוש
סמנטי-בלבד בשלב 1 (FTS index מוכן).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 17:49:00 +00:00
a2236363d4 feat(mcp): FU-14 GAP-50 — deprecate draft_section לטובת get_block_context
INV-TOOL2. מיפוי הראה ש-6 כלי-הבלוק אינם כפילות מיותרת: write_block/
write_all_blocks/save_block_content/write_interim_draft משרתים זרימות שונות
(CLI/initial-draft מול תהליך-ה-writer "התיקון בקובץ, לא ב-DB"). הכפילות
האמיתית היחידה — draft_section (הקשר לפי-סעיף, granularity ישן) חופף ל-
get_block_context (לפי-בלוק, תואם 12-הבלוקים הקנוני).

הכרעת-יו"ר: draft_section סומן deprecated (docstring ב-server.py + drafting.py
מפנה ל-get_block_context; draft-decision.md עודכן). ללא הסרה, ללא מיזוג כלי-
הכתיבה — שמירת תהליך-הכתיבה המכוון.

בדיקות: 182/182 עוברים. GAP-49+50 סגורים.

Invariants: מקדם INV-TOOL2 + G2. מתועד ב-X9 (נסגר) + gap-audit פרוסה 9.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:57:02 +00:00
14568fdd15 feat(mcp): FU-14 GAP-49 — תיקון שם-הכלי המטעה (precedent_search_library)
INV-TOOL2: `precedent_search_library` (שמחפש ציטוטים מצורפים-לתיק) היה הפוך
וכמעט-זהה ל-`search_precedent_library` (ספריית-הפסיקה הסמכותית, מקור CREAC),
מה שסיכן ציטוט מהמקור הלא-נכון בהחלטה. שונה ל-`search_case_precedents` (שם
ברור: case-attached). השם הישן נשמר כ-@mcp.tool() alias deprecated המנתב לחדש
→ אפס שבירה לסוכנים חיים.

docstrings של שני כלי-הפסיקה הובהרו (case-attached מול authoritative).
עודכנו: web/app.py (typeahead), legal-researcher/legal-writer docs, precedent_library docstring.

5 כלי-החיפוש הנותרים (search_decisions/case_documents/find_similar/internal/
precedent_library) מחפשים קורפוסים מובחנים בשמות סבירים — לא בוצע rename המוני
(churn גבוה, ערך נמוך מול הסיכון).

בדיקות: 182/182 עוברים. אחרי deploy — סנכרון cross-company של doc-הסוכן.

Invariants: מקדם INV-TOOL2 + G2. מתועד ב-X9 + gap-audit פרוסה 8.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:51:17 +00:00
7a2865339c Merge pull request 'feat(style-acq T4+T5): פנקס-התאמה draft↔final + דיסטילציה אוטומטית דרך ה-curator' (#74) from worktree-style-acquisition-mvp into main
Some checks failed
Build & Deploy / build-and-deploy (push) Failing after 2m31s
2026-06-06 17:21:23 +00:00
0d995483ce feat(style-acq T4+T5): פנקס-התאמה draft↔final + דיסטילציה אוטומטית דרך ה-curator
סוגר את לולאת-הלמידה (INV-LRN4): כל החלטה נסגרת מול הסופי, וכל סופי
מנותח מול הטיוטה. מזין את הטבלאות ש-T15 כבר קורא מהן.

T5 — פנקס-התאמה:
- SCHEMA_V26: טבלת draft_final_pairs (snapshot draft + final + diff + analysis + status).
- db: create/update/list_draft_final_pairs.
- mark-final (app.py): תופס snapshot של הטיוטה (decision_blocks) ברגע החתימה,
  לפני שאפשר לדרוס אותו, ופותח שורת-פנקס (status=final_received).

T4 — דיסטילציה אוטומטית:
- learning_loop.process_final_version: משתמש ב-snapshot (לא בבלוקים שאולי השתנו),
  מסווג style_method↔substance, שומר הצעה ב-pair (status=analyzed).
  **הוסר ה-auto-upsert של style_patterns** — ביטל את ה-bug שדרס את שער-היו"ר
  וזיהם סגנון במהות (INV-LRN1 + INV-LRN5).
- LESSONS_PROMPT: הפרדת style_method↔substance מפורשת + לקח מופשט בלבד.
- curator wake + hermes-curator.md: מריץ ingest_final_version ראשון; מציע רק
  style_method שלא תועד; substance→מסלול precedent.

INV-LRN1 (שער-יו"ר, אין auto-commit) · INV-LRN4 (ניגוד-אמת) · INV-LRN5 (טוהר).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 17:20:57 +00:00
c482414819 docs+config: בידוד-סשנים נתמך-סביבה לעבודה מקבילה (worktree defaults)
הופך את כלל ה-worktree המבודד מ-דיסציפלינה-ידנית ל-ברירת-מחדל נתמכת-סביבה,
לפי המקורות הרשמיים של Anthropic (worktrees + settings) ו-Git.

- .claude/settings.json: worktree.baseRef=fresh (בסיס מ-origin/main),
  worktree.symlinkDirectories=[web-ui/node_modules] (שיתוף 789MB במקום npm ci לכל worktree),
  ו-WorktreeRemove hook עם --force לעקיפת באג cleanup #40259. spec-guard נשמר.
- .worktreeinclude: העתקת .claude/settings.local.json (allowlist הרשאות) + env לכל worktree.
- .gitignore: הוספת .claude/worktrees/ (טיפ רשמי) — מנקה את git status של העץ הראשי.
- CLAUDE.md: שדרוג מקטע "בידוד-סשנים" — claude --worktree כברירת-מחדל תחת .claude/worktrees/,
  caveat בידוד-DB (לא migrations מ-2 worktrees), אזכור באג #60588 (אימות baseRef).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 16:39:11 +00:00
482f302d54 fix(security+agents): GAP-57 fail-loud PAPERCLIP_DB_URL + FU-13 analyst tool alignment
GAP-57 (אבטחה, CWE-798 / INV-ENV4): ה-default הקשיח
postgresql://paperclip:paperclip@... הוסר מ-3 קבצי web/. נוסף resolver משותף
require_paperclip_db_url() ב-paperclip_api.py שנכשל בקול אם PAPERCLIP_DB_URL לא
מוגדר — במקום ליפול בשקט ל-creds ידועים. Coolify מגדיר את המשתנה (אומת), אז
הייצור לא נפגע. (2 מופעים בסקריפטים מקומיים נותרו ל-FU-15 המלא.)

FU-13 (INV-AG3, GAP-46): יישור הרשאות-סוכן. התברר שהפער שמופה ב-31.5 היה רחב
מדי — יוחס לפי תיאור-תפקיד, לא ההוראות בפועל. הכרעת-יו"ר "היבריד":
- legal-analyst: נוסף aggregate_claims_to_arguments (frontmatter + שלב 7) — הכלי
  שמקבץ את הטענות שהוא חילץ לטיעונים משפטיים.
- extract_references/extract_internal_citations הם מטלת-researcher (שכבר מחזיק
  אותם), לא analyst — הוסרו מרשימת "החסרים".
- legal-researcher: כבר היה תקין; ה-spec היה מיושן.
עודכנו X4-agents.md (§2א, INV-AG3) ו-gap-audit.md (FU-13 , FU-15 חלקי).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 14:14:39 +00:00
7f4e036211 feat(spec): חיבור ספ-המערכת למסלול-הכתיבה האינטראקטיבי (אכיפה 3-שכבתית)
הספ (docs/spec/, G1–G11) חובר לסוכני Paperclip דרך INV-AG1 אבל לא למסלול
שבו רוב הקוד נכתב בפועל — הסשן האינטראקטיבי של Claude Code. סוגר את הפער
לפני מחזור-2 (FU-9..15), שהוא כולו כתיבת-קוד.

שלוש שכבות אכיפה:
1. תיעוד — CLAUDE.md §"פרוטוקול כתיבת-קוד" + docs/spec בטבלת-הייחוס
2. hook — scripts/spec-guard.sh (PreToolUse על Edit/Write/MultiEdit, רשום
   ב-.claude/settings.json) מזכיר פעם-בסשן בכל נגיעה בקובץ-קוד; non-blocking
3. PR — .gitea/PULL_REQUEST_TEMPLATE.md עם סעיף-חובה "Invariants"

המקבילה האינטראקטיבית ל-INV-AG1 שכבר אוכף על הסוכנים (HEARTBEAT §"קריאת-ספ").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 13:28:15 +00:00
4174217179 feat(feedback): סימון "יושם" מפעיל CEO לקיפול הלקח לקובץ הנכון
סוגר את לולאת פידבק-יו"ר→ידע-סוכנים. עד כה resolve רק עדכן את ה-DB; עכשיו
לחיצה ב-/feedback מעירה את ה-CEO שמקפל את הלקח לקובץ לפי הקטגוריה.

- paperclip_client.py: wake_ceo_for_feedback_fold() — יוצר issue ב-Paperclip
  עם הלקח + rubric ניתוב (style→SKILL.md, wrong_structure→block-schema,
  אחר→lessons.md), מעיר CEO. משכפל את דפוס wake_for_precedent_extraction
- db.py: get_chair_feedback(id) — שליפת הערה בודדת עם case_number/appeal_type
- app.py: resolve endpoint מקבל fold (ברירת מחדל true); BackgroundTask
  fire-and-forget; guard — רק עם lesson_extracted. מחזיר fold_queued
- legal-ceo.md: dispatch ל-feedback_fold_ + סעיף "קיפול הערת יו"ר" עם rubric
- frontend: useResolveFeedback מקבל fold; /feedback שולח fold=true עם toast;
  drafts-panel שולח fold=false (bookkeeping per-case, בלי קיפול כפול)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 13:08:41 +00:00
e79f74bc23 docs(X11): wire corroboration tools into CEO halacha flow + guide (X11 Phase 2)
- CEO: run corroboration_rebuild after precedent_process_pending(halacha);
  report {approved, demoted}; tools added to allowlist
- researcher: halacha_corroboration (read) in allowlist
- TaskMaster #75 → done

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 04:52:02 +00:00
a02a606f34 feat(agents): wire spec into agents — INV-AG1 read-before-act gate (FU-8b/GAP-23)
חיווט ספ-המערכת לסוכני-Paperclip כך שכל סוכן חייב לקרוא את 00-constitution
תחילה, ואז את ספ-התחום הרלוונטי לתפקידו (לפי טבלת X4 §2) — לפני עבודה מהותית.

- HEARTBEAT.md: סעיף עליון "קריאת-ספ — קודם החוקה (00), אז ספ-התחום" לפני §0–§8,
  עם טבלת תפקיד→ספ ל-8 הסוכנים.
- 8 קבצי-סוכן (ceo/proofreader/researcher/analyst/writer/qa/exporter/hermes):
  סעיף "קרא לפני פעולה (INV-AG1)" בראש הגוף.
- X4-agents.md: שדה "אכיפה" של INV-AG1 → "מחוּוט (פרוצדורלי)"; §5 → "בוצע".

אכיפה פרוצדורלית בכוונה — invariant פרויקטלי-תפעולי, אין שער-קוד שמכריח קריאה.
prereq לסוכני-התהליך (תת-פרויקט 5). gap-audit נשמר כ-snapshot (כמו FU-8a).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 16:02:04 +00:00
58ab003206 fix(retrieval): make decisions findable by name + unhide committee uploads
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m57s
Root cause of "agent can't find the Agasi decision in the corpus" (CMPA-55):
the decision was fully ingested, but the retrieval layer failed on the
realistic agent query — searching by case name.

- RC-A (#52): lexical tsvector covered only chunk content + halacha text,
  so a bare-name query ("אגסי") matched decisions that *cite* the case, not
  the case itself. Add meta_tsv on case_law(case_name, case_number) (SCHEMA
  V20) and OR it into the lexical halacha/chunk SQL with a match boost, so a
  name/number hit surfaces the case's own rows. Agasi: rank 4 → rank 1.
- RC-B (#53): precedent_library_list hard-defaulted source_kind=external_upload
  and never exposed the param, hiding uploaded ערר/בל"מ (internal_committee)
  decisions. Thread source_kind through service → tool → MCP tool (supports
  'internal_committee' / 'all_committees').
- #54: agent instructions (researcher/analyst/writer) — search-by-name
  protocol: add content/case-number, search both corpora, use all_committees
  before declaring "not in corpus".
- #55: chunker produced tiny fragment chunks ("דיון", "החלטה") from header
  keywords matched mid-sentence. Anchor SECTION_PATTERNS to line start +
  merge sub-min sections; exclude <50-char fragments at query time (484
  existing fragments hidden; full re-chunk tracked as #57).

Tests: scripts/test_retrieval_by_name.py (name ranks case above citer +
substantive regressions); chunker unit checks (0 tiny chunks). New findings
filed as tasks #56 (halacha source_kind leak) and #57 (re-chunk migration).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:26:19 +00:00
bb0cd7c6a2 feat(training): Style Studio — upload, rich corpus, lessons, curator portrait, chat
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 2m7s
Six-phase upgrade of /training from a read-only dashboard into a full
Style Studio for managing Daphna's style corpus.

- Upload Sheet on /training: file → proofread preview → commit (no more
  CLI-only `upload-training` skill).
- Rich corpus metadata: GET /api/training/corpus returns summary, outcome,
  key_principles, page_count, parties (regex), legal_citation, lessons_count.
  PATCH endpoint for chair edits. CorpusDetailDrawer with 4 tabs (details
  /content/lessons/patterns) replaces the bare table row.
- LLM metadata enrichment: style_metadata_extractor + MCP tools
  (style_corpus_enrich, style_corpus_pending_enrichment) fill summary
  /outcome/key_principles via claude_session (free, host-side).
- Per-decision lessons: new decision_lessons table + 4 REST endpoints +
  LessonsTab in drawer; hermes-curator now auto-posts findings as
  decision_lessons(source=curator).
- Curator Portrait tab: prompt rendered with link to Gitea, recent
  curator findings, style_analyzer training prompts, propose-change
  form that writes proposals to data/curator-proposals/ for manual
  chair review (no auto-mutation of the agent file).
- Style chat tab: SSE-streamed conversations with the style agent.
  New host-side pm2 service (legal-chat-service, port 8770) wraps
  claude CLI with stream-json + --resume continuation; FastAPI proxies
  via host.docker.internal. Zero API cost — uses chaim's claude.ai
  subscription. chat_conversations + chat_messages persist history.

Architecture: keeps the existing rule that claude_session only runs
on the host (not the container). The new legal-chat-service is the
canonical bridge between the container and the local CLI for the chat
feature; everything else (upload, metadata, lessons) stays within the
container's existing capabilities.

Audit script (scripts/audit_training_corpus.py) included for verifying
which corpus rows still need enrichment.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 10:06:22 +00:00
d359ab9884 feat(proceeding-type): explicit ערר/בל"מ field for cases + corpus
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m40s
Same case_number can exist as both a regular appeal (ערר) and an
extension-of-time request (בל"מ), and we were inferring the difference
from appeal_subtype prefixes — fragile, and case-number lookups
weren't disambiguated. Now stored as a first-class field on both
case_law (corpus) and cases (live cases), with partial unique indexes
on (case_number, proceeding_type).

- SCHEMA_V15: column + CHECK constraints + backfill from
  appeal_subtype LIKE 'extension_request_%' + partial unique indexes
  replace the old global UNIQUE(case_number).
- derive_proceeding_type() centralizes the inference rule
  (extension_request_* → בל"מ; subject regex fallback; default ערר).
- Metadata extractor prompt asks Claude to populate the new field
  explicitly; apply_to_record writes it for internal_committee rows.
- internal_decision_upload, case_create, case_update accept an
  optional proceeding_type; FastAPI request models expose it.
- Wizard + edit dialog get a sided Select; case header renders the
  resolved label (ערר / בל"מ).
- Uploaded the 2 staged בל"מ decisions on betterment levy:
  8126/24 (סופר נוח, 13 chunks), 8047/23 (הרנון, 48 chunks).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 09:17:33 +00:00
f3cc9ca9d4 feat: Stage A finalizers + #35/#36/#37 — critical-gap closure
Some checks failed
Build & Deploy / build-and-deploy (push) Has been cancelled
Four parallel sub-agents closed the remaining critical gaps from the
26/05 Stage A/B sprint. Each block independently tested; aggregated here.

## #30/#31 finalizers (sub-agent A)
* Auto-derive practice_area in case_create from case_number prefix
  (1xxx→rishuy_uvniya, 8xxx→betterment_levy, 9xxx→compensation_197);
  default for CaseCreateRequest is now "" (the DB constraint catches
  any stray "appeals_committee").
* practice_area.py: derive_subtype now handles axis-B domain values
  (rishuy_uvniya/betterment_levy/compensation_197) without parsing the
  case number; new helper derive_domain_practice_area().
* Halacha re-extraction verified unnecessary — all 6 reclassified
  records already had is_binding=false and approved halachot.
* Regression tests: 6 cases in tests/test_corpus_constraints.py
  covering practice_area enum, internal-committee chair/district,
  external-upload arar prefix, MCP guard.
* UI: district input → Select dropdown (7 districts) in
  precedent-edit-sheet.tsx, preserving legacy free-text values.

## #37 בל"מ subtypes (sub-agent B)
* 3 new appeal_subtypes: extension_request_{building_permit,
  betterment_levy,compensation}. APPEALS_COMMITTEE_SUBTYPES extended,
  SUBTYPES_BY_AREA mappings added.
* New helpers: is_blam_subject(), is_blam_subtype(),
  derive_subtype_with_blam(case_number, subject, practice_area).
  case_create now uses it to auto-detect "בקשה להארכת מועד" subjects.
* 3 methodology templates under docs/methodology/extension-request-*.md.
* paperclip_client.py mapping updated for the 3 new subtypes
  (extension_request_building_permit→CMP, the other two→CMPA).
* Frontend: bilingual "בל"מ" badge + filter dropdown on cases list +
  detail header; appeal-type-bars collapseBlam() merges בל"מ into its
  parent domain for aggregate bars.
* Wizard auto-detects בל"מ from subject during case creation.
* 3 Berlinger cases (1017/1018/1019-03-26) migrated to
  appeal_subtype=extension_request_building_permit via psql.

## #35 missing_precedents feature (sub-agent C)
* Schema V13: missing_precedents table (citation, case_id, party,
  legal_topic, status, linked_case_law_id, claim_quote, ...) +
  FK constraints + 3 indexes. Applied via psql + idempotent migration.
* 6 db.py service functions, 3 MCP tools, 6 FastAPI endpoints
  (POST/GET/PATCH/DELETE/upload — upload routes by citation prefix
  to ingest_internal_decision or ingest_precedent).
* Next.js page /missing-precedents with 5 status tabs + filters +
  sidebar badge counter + detail drawer with metadata edit + smart
  upload form that switches fields per committee/court.
* Bootstrap: 7 rows imported from the JSON file
  (3 citations × cases, all status=closed with linked_case_law_id).
* legal-researcher.md: new §2ב.5 with missing_precedent_create
  usage + dedup semantics + tool grant.

## #36 legal_arguments aggregation (sub-agent D)
* Schema V14: legal_arguments + legal_argument_propositions M:M.
  Applied via psql.
* New service argument_aggregator.py with two functions —
  aggregate_claims_to_arguments() (Claude CLI / claude_session) and
  get_legal_arguments(). Graceful llm_unavailable handling when CLI
  is missing (containers).
* 2 MCP tools + 2 API endpoints (POST .../aggregate-arguments as
  BackgroundTask, GET .../legal-arguments).
* Frontend: shadcn Accordion + new legal-arguments-panel.tsx with
  hierarchical (party → priority badge → arguments) display, "טיעונים"
  tab on the case page, "חשב/חשב מחדש" buttons.
* scripts/backfill_legal_arguments.py + SCRIPTS.md entry — dry-run
  found 8 candidate cases including 1017/1018/1019.

## Open follow-ups (intentionally deferred)
* npm run api:types in web-ui (CLAUDE.md flow) — recommended before
  the next UI commit; not required for backend deployment.
* Run backfill_legal_arguments.py --apply once the container picks up
  the new aggregator service.
* webhook on missing-precedents upload-close to Paperclip (optional).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 08:34:40 +00:00
c6e368e4f7 feat(corpus): Stage A — corpus tagging fixes + prevention layer
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 3m8s
מתקן את הבאג של תיוג שגוי לועדות ערר ומונע חזרתו:

**Code changes:**
* New MCP tool `internal_decision_upload` (chair_name+district required)
  — sole supported path for ingesting committee decisions; tags
  source_kind='internal_committee' automatically.
* Citation guard in `precedent_library_upload` rejects citations starting
  with "ערר" or "בל\"מ" with a directive to use internal_decision_upload.
* `practice_area.py` taxonomy unification: PRACTICE_AREAS now accepts
  both multi-tenant (appeals_committee/national_insurance/labor_law)
  and domain (rishuy_uvniya/betterment_levy/compensation_197) values.
  New helper `to_db_practice_area(multi_tenant, subtype) -> domain`.

**Agent docs:**
* legal-researcher (+5K): upload-tool decision flowchart, code samples
  per source_kind, district enum (ירושלים/מרכז/תל אביב/צפון/דרום/חיפה/ארצי)
* legal-ceo, legal-analyst, legal-writer, legal-qa, HEARTBEAT — taxonomy
  awareness + source_kind-aware citation patterns + research_complete
  as valid status.
* Fixed two pre-existing wrong practice_area values in examples
  (histael_hashbacha→betterment_levy, pitsuim_197→compensation_197).

Closes TaskMaster #30(parts), #38(parts), #39 (root cause).
DB-side backfill + CHECK constraints applied directly via psql:
* 11 cases.practice_area corrected (1xxx→rishuy, 8xxx→betterment)
* 6 case_law records reclassified external_upload→internal_committee
  with inferred district
* 6 chair_name backfilled from full_text (5 שרית אריאלי + 1 דפנה תמיר)
* 88 new halachot extracted for newly-uploaded precedents
  (אנטרים + ירושלים שקופה 1112/22 + אגא וכט)
* CHECK constraints: cases.practice_area enum, case_law internal⇒district

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 07:40:18 +00:00
f3ecccd4f0 docs: add procedural patterns layer (interim decision template)
Document new daphna-procedural-patterns.md cataloging the
"appraiser clarification request" interim-decision pattern observed in
8174-24 — structure only, not phrasing (case is an outlier example).

- daphna-decision-tree.md §0.5: gating question before main tree
- legal-ceo.md voice docs table: register procedural patterns doc
- legal-writer.md: mandatory consultation when pattern_tag is set,
  with explicit warning against copying 8174-24 wording

Approved via interaction request_confirmation (CMPA-15) 2026-05-17.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 16:29:58 +00:00
a2fc36d65f fix: recognize extended chair-position placeholders as empty
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m35s
The legal-analyst agent was generating a longer placeholder form
[ימולא ע"י יו"ר הוועדה — עמדה/הנחיה לגבי סוגיה זו שתשמש את סוכן הכתיבה]
which _is_placeholder() did not match (substring check fails because ] is
further along in the longer form). Result: UI showed "✓ עמדה נקבעה" (green)
for all 4 issues even though no chair direction had been entered.

Fixes:
1. research_md.py: add regex fallback — any text starting with [ימולא is a placeholder
2. legal-analyst.md: template now emits the standard short placeholder only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:59:13 +00:00
c3ce0e7e1f upgrade: upgrade opus-4-6 → opus-4-7 for all heavy-reasoning agents
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
DB: עדכון 8 סוכנים (CMP + CMPA) — CEO, מנתח, כותב, מגיה
instructions: עדכון 4 קבצי הנחיות להתאמה ל-DB

opus-4-7 מחליף opus-4-6 לכל הסוכנים שדורשים reasoning כבד.
sonnet-4-6 נשאר ל-QA, חוקר, מייצא. deepseek-v4-pro נשאר לcurator.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:42:33 +00:00
1608ea5ed0 fix: medium/low audit items — model drift, placeholders, corpus check, curator ownership
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 7s
Model drift (instructions → match DB):
- CEO: claude-sonnet-4-6 → claude-opus-4-6 (DB runs opus; CEO needs opus quality)
- מנתח/כותב/מגיה: claude-opus-4-7 → claude-opus-4-6 (DB runs 4-6; no 4-7 in adapter)

legal-proofreader.md:
- {issue-id} placeholder → $PAPERCLIP_TASK_ID בשני המקומות (done + blocked)

legal-researcher.md:
- הוסף reference ל-HEARTBEAT.md בראש הקובץ

legal-qa.md:
- הבהרת שיטת בדיקת corpus_queries_logged: grep ידני בלבד, לא validate_decision

CLAUDE.md (curator):
- הוסף תהליך אישור הצעות curator: comment → חיים מאשר → commits ל-SKILL.md/lessons.md

maxConcurrentRuns CEO: כבר 2 ב-DB — לא נדרש שינוי

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:35:49 +00:00
35423eafc1 fix: high-priority agent audit items — CEO hardcoded IDs + researcher search_internal_decisions
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
CEO (legal-ceo.md):
- הסרת company UUID ו-project UUID קשוחים בדוגמת יצירת issue
- שימוש ב-$PAPERCLIP_COMPANY_ID לחברה
- project_id נשלף דינמית מה-issue ההורה דרך $PAPERCLIP_TASK_ID

researcher (legal-researcher.md):
- הוסף mcp__legal-ai__search_internal_decisions לרשימת tools
- הוסף סעיף 2ב.2א המסביר את ההבדל: search_decisions = דפנה בלבד;
  search_internal_decisions = כל ועדות הערר בכל המחוזות
- הוראות מתי להשתמש + אזהרת היררכיה (ועדת ערר < מחוזי)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:29:47 +00:00
a584dc3602 fix: legal-exporter — versioning, dynamic skill path, case status update
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
- טיוטה-V → טיוטה-v (lowercase) בכל המקומות (שלב 4 + כללים קריטיים)
- hardcoded CMP UUID בנתיבי legal-docx SKILL → $PAPERCLIP_COMPANY_ID (תומך CMP + CMPA)
- הוסף case_update לרשימת tools
- הוסף שלב 4.5: עדכן סטטוס תיק ל-exported אחרי שמירת DOCX

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 12:14:24 +00:00
ea0532b7ba fix: weekly-feedback-job handler writes to file only (no Paperclip issue)
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m39s
CEO wakes for weekly-feedback-job via agents.invoke without issueId,
so $PAPERCLIP_TASK_ID is empty. Removed steps 4-5 (comment + close
issue) from handler — now file-write only with stdout logging.

Also commits pending docs and agent instructions from prior session.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:08:14 +00:00
cddc7c8d24 fix: start-workflow wakeup failure now returns 502 instead of silent success
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 1m33s
If pc_wake_ceo fails, the endpoint now raises HTTP 502 and skips the
case_update to processing — preventing cases from silently getting stuck
with no CEO running. Also adds `processing` to CEO routing table and
updates case_list docstring with full status list.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 11:02:30 +00:00
8dc7a40fa2 fix: exclude exported cases from stale; add weekly-feedback-job handler to CEO
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 8s
- /api/cases/stale: exclude 'exported' status — exported cases await Dafna's
  review intentionally, they are not stuck
- legal-ceo.md: add routing for weekly-feedback-job reason + explicit handler
  (analyze feedback, update decision-lessons.md, close issue)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 10:35:39 +00:00
45341a0bc8 feat(curator): switch Hermes Curator to DeepSeek V4-Pro via deepseek_local adapter
A/B test (2026-05-05) showed DeepSeek V4-Pro is 2-3x faster and ~20x cheaper
than Sonnet for style/lexicon pattern analysis, with comparable quality.
Adds adapters/deepseek-paperclip-adapter/ package, documents adapter requirements
(env injection, run-id headers), updates CLAUDE.md with adapter integration notes,
and records lessons from ערר 1200-25 (block order for 1xxx, "להלן מתוך" pattern,
expanded factual background, bridge planning analysis, flat heading structure).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-10 05:58:52 +00:00
ea29778197 docs(hermes-curator): document interaction-driven conversation support
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 7s
The curator's promptTemplate (stored in DB) now teaches Hermes how to
post issue_thread_interactions instead of free-text comments. Three
patterns supported, curator picks per context:

- ask_user_questions for filtering findings (multi-select)
- request_confirmation for accept/reject of a single proposal
- suggest_tasks for proposing follow-up issues

Verified end-to-end on CMP-71: curator hit a real obstacle (couldn't
read the final DOCX from its container) and chose request_confirmation
on its own to ask the user how to proceed — exactly the conversational
behavior we want.

Paperclip auto-wakes the curator with $PAPERCLIP_APPROVAL_ID when the
user responds. The new prompt has a §B branch that handles the second
wake (read response → act → close).

The UI side was already built in d099470 (mirror Paperclip interactions
in case page) — now Hermes-side agents produce interactions too, not
just claude_local agents.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 15:24:57 +00:00