feat(escalation): primitive הסלמה-לאדם loop-safe בשער-הפלטפורמה (#218) #405
Reference in New Issue
Block a user
Delete Branch "worktree-agent-escalation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
מה
פרוסה ראשונה של #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):{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→todoflip. (סוכן-החקירה הציע REST PATCH; דחיתי — REST מחזיר למכונת-הטריגרים הבעייתית. direct-DB הוא המסלול המוכח שעוצר לולאות.)author_type='system'— אינרטית ל-route-pending-comments(מנתב רקauthor_type='user'), לכן לא מעירה CEO (project_comment_delivery_guarantee). אפס wakeup — המטרה מסירה-לאדם, לא re-invoke.חיווט
pc_escalate_issueעטוף ב-agent.escalated— מרכיב על טלמטריית #219: הסלמות נספרות per-case באותו זרם כמו ה-wakeups שהן מחליפות.POST /api/cases/{case}/agents/escalate(severity כ-Literal).Invariants
reset_case_agents(single/bulk siblings של concept אחד); לא מסלול מקביל.בדיקות
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
מוסיף 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>