feat(escalation): primitive הסלמה-לאדם loop-safe בשער-הפלטפורמה (#218) #405

Merged
chaim merged 1 commits from worktree-agent-escalation into main 2026-07-06 21:03:45 +00:00
Owner

מה

פרוסה ראשונה של #218 (למידה מ-Gastown gt escalate): פרימיטיב הסלמה מדורגת-חומרה לאדם, חלופה loop-safe להשארת issue משויך-סוכן+blocked — שהיא מקור-הכאב החוזר של לולאות source_scoped_recovery_action / stranded_assigned_issue / issue_reopened_via_comment (reference_paperclip_recovery_loops).

איך

escalate_issue(issue_id, severity, reason) — שני אפקטים בטרנזקציית-DB אחת, במנגנון הקנוני של reset_case_agents (raw SQL ישיר, לא REST):

  1. מעבר-אטומי human-owned{status:'in_review', assignee_agent_id:null, assignee_user_id:CHAIM_USER_ID} (recovery-loops rule #7). direct-DB בכוונה: עוקף את ה-disposition-resolver של Paperclip — המכונה שה-multi-PATCH/issue.released שלה גורם ללולאות — כך שה-issue נוחת human-owned בשוט אחד בלי done→todo flip. (סוכן-החקירה הציע REST PATCH; דחיתי — REST מחזיר למכונת-הטריגרים הבעייתית. direct-DB הוא המסלול המוכח שעוצר לולאות.)
  2. הערת-severity עמידה author_type='system' — אינרטית ל-route-pending-comments (מנתב רק author_type='user'), לכן לא מעירה CEO (project_comment_delivery_guarantee). אפס wakeup — המטרה מסירה-לאדם, לא re-invoke.

חיווט

  • Port: pc_escalate_issue עטוף ב-agent.escalatedמרכיב על טלמטריית #219: הסלמות נספרות per-case באותו זרם כמו ה-wakeups שהן מחליפות.
  • app.py: POST /api/cases/{case}/agents/escalate (severity כ-Literal).

Invariants

  • G2 — אותו מנגנון-העברה-לאדם כמו reset_case_agents (single/bulk siblings של concept אחד); לא מסלול מקביל.
  • G12/INV-PORT1 — המגע מהשער בלבד; ליבת-האינטליגנציה לא נגעה.
  • §6 — severity לא-תקין / issue-חסר מוחזרים מפורשות; אין בליעה שקטה.

בדיקות

web/tests/test_escalate_issue.py — 3 (fake-asyncpg, ללא DB חי): severity-לא-תקין נדחה לפני-DB, happy-path (מעבר+system-note+אפס-wakeup נאכף), issue-לא-נמצא. 9/9 עם טסטי-הטלמטריה.

follow-up מוצהר (לא בפרוסה זו)

חיווט-סוכנים (MCP tool + החלפת blocked+prose ב-HEARTBEAT §4), auto-escalation מה-reaper, והתראת-מייל (notify.py) לחיים.

🤖 Generated with Claude Code

## מה פרוסה ראשונה של **#218** (למידה מ-Gastown `gt escalate`): פרימיטיב **הסלמה מדורגת-חומרה לאדם**, חלופה **loop-safe** להשארת issue משויך-סוכן+`blocked` — שהיא מקור-הכאב החוזר של לולאות `source_scoped_recovery_action` / `stranded_assigned_issue` / `issue_reopened_via_comment` ([[reference_paperclip_recovery_loops]]). ## איך `escalate_issue(issue_id, severity, reason)` — שני אפקטים ב**טרנזקציית-DB אחת**, במנגנון הקנוני של `reset_case_agents` (raw SQL ישיר, **לא** REST): 1. **מעבר-אטומי human-owned** — `{status:'in_review', assignee_agent_id:null, assignee_user_id:CHAIM_USER_ID}` (recovery-loops rule #7). direct-DB בכוונה: עוקף את ה-disposition-resolver של Paperclip — המכונה שה-multi-PATCH/`issue.released` שלה **גורם** ללולאות — כך שה-issue נוחת human-owned בשוט אחד בלי `done→todo` flip. (סוכן-החקירה הציע REST PATCH; דחיתי — REST מחזיר למכונת-הטריגרים הבעייתית. direct-DB הוא המסלול המוכח שעוצר לולאות.) 2. **הערת-severity עמידה** `author_type='system'` — אינרטית ל-`route-pending-comments` (מנתב רק `author_type='user'`), לכן **לא מעירה CEO** ([[project_comment_delivery_guarantee]]). **אפס wakeup** — המטרה מסירה-לאדם, לא re-invoke. ## חיווט - **Port**: `pc_escalate_issue` עטוף ב-`agent.escalated` — **מרכיב על טלמטריית #219**: הסלמות נספרות per-case באותו זרם כמו ה-wakeups שהן מחליפות. - **app.py**: `POST /api/cases/{case}/agents/escalate` (severity כ-`Literal`). ## Invariants - **G2** — אותו מנגנון-העברה-לאדם כמו `reset_case_agents` (single/bulk siblings של concept אחד); לא מסלול מקביל. - **G12/INV-PORT1** — המגע מהשער בלבד; ליבת-האינטליגנציה לא נגעה. - **§6** — severity לא-תקין / issue-חסר מוחזרים מפורשות; אין בליעה שקטה. ## בדיקות `web/tests/test_escalate_issue.py` — 3 (fake-asyncpg, ללא DB חי): severity-לא-תקין נדחה לפני-DB, happy-path (מעבר+system-note+**אפס-wakeup נאכף**), issue-לא-נמצא. ✅ 9/9 עם טסטי-הטלמטריה. ## follow-up מוצהר (לא בפרוסה זו) חיווט-סוכנים (MCP tool + החלפת `blocked`+prose ב-HEARTBEAT §4), auto-escalation מה-reaper, והתראת-מייל (`notify.py`) לחיים. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-07-06 21:03:13 +00:00
feat(escalation): primitive הסלמה-לאדם loop-safe בשער-הפלטפורמה (#218)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 3s
Lint — undefined names / undefined-names (pull_request) Successful in 10s
b3b7c48b8f
מוסיף escalate_issue(issue_id, severity, reason) — חלופה loop-safe להשארת
issue משויך-סוכן+blocked, שהיא מקור לולאות source_scoped_recovery_action /
stranded_assigned_issue / issue_reopened_via_comment (reference_paperclip_recovery_loops).

שני אפקטים בטרנזקציית-DB אחת, במנגנון הקנוני של reset_case_agents (raw SQL, לא REST):
- מעבר-אטומי למצב human-owned {status:in_review, assignee_agent_id:null,
  assignee_user_id:CHAIM_USER_ID} (rule #7). direct-DB בכוונה — עוקף את
  disposition-resolver של Paperclip שהוא-עצמו מקור-הלולאות; נוחת human-owned בשוט
  אחד בלי done→todo flip.
- הערת-severity עמידה author_type='system' — אינרטית ל-route-pending-comments
  (מנתב רק author_type='user'), לכן לא מעירה CEO. אפס wakeup — המטרה היא מסירה-לאדם.

חיווט:
- Port: pc_escalate_issue עטוף ב-agent.escalated (מרכיב על טלמטריית #219 —
  הסלמות נספרות per-case באותו זרם כמו ה-wakeups שהן מחליפות).
- app.py: POST /api/cases/{case}/agents/escalate (Literal severity).
- 3 בדיקות pytest (fake-asyncpg): severity לא-תקין, happy-path (מעבר+system-note+
  אפס-wakeup), issue-לא-נמצא.

Invariants: מקיים G2 (אותו מנגנון-העברה-לאדם כמו reset_case_agents, לא מסלול מקביל),
G12/INV-PORT1 (המגע מהשער בלבד; ליבה נקייה), §6 (אין בליעה שקטה — severity לא-תקין
וissue-חסר מוחזרים מפורשות).

follow-up מוצהר: חיווט-סוכנים (MCP tool + HEARTBEAT §4 להחליף blocked+prose),
auto-escalation מה-reaper, והתראת-מייל (notify.py) לחיים.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
chaim merged commit 653b951d30 into main 2026-07-06 21:03:45 +00:00
chaim deleted branch worktree-agent-escalation 2026-07-06 21:03:45 +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#405