feat(routing): ערובת at-least-once להערות-יו"ר → CEO (sweep-פיוס) #3

Merged
chaim merged 1 commits from feat/comment-delivery-guarantee into main 2026-06-30 10:40:45 +00:00
Owner

הבעיה

מסלול ניתוב ההערות הקיים (issue.comment.created → CEO) הוא best-effort: invoke שנכשל/התלכד/בוטל, או הערה שנוחתת בזמן שסוכן רץ — משאירים את ההערה ללא ניתוב וללא מי שינסה שוב. כך בדיוק הערת-יו"ר על CMP-190 (30.6.26) נשמטה בשקט: ה-wakeup הנייטיב בוטל (issue_execution_promoted/assignee_changed) ושום מסלול-פלאגין לא נורה. אין ספר-חשבונות של הערות-שטופלו.

הפתרון — sweep פיוס (at-least-once)

route-pending-comments, כל 2 דק':

  • מנתב כל issue פעיל שבו ההערה האחרונה היא של היו"ר (אין תגובת-סוכן אחריה) וש-id שלה ≠ הסמן last-routed-comment-id.
  • גם המסלול-המהיר וגם ה-sweep מסמנים את הסמן → אידמפוטנטי, בלי ניתוב-כפול של הערה בריאה.
  • "ההערה האחרונה היא של היו"ר" מכוון בדיוק לכשל (יו"ר הגיב, אין תגובת-סוכן) ומדלג על הערות שכבר נענו → טביעת-רגל ב-first-run אחרי deploy = 0.

שינויים

  • worker.ts: חילוץ routeCommentToCeo() + markCommentRouted() משותפים; ה-event handler מסמן את הסמן (כולל בענף "native handles it"); רישום ה-sweep עם guards per-company/per-issue ו-try/catch.
  • manifest.ts: הצהרת job route-pending-comments (*/2 * * * *).

Invariants

  • G12 — מגע-Paperclip רק במעטפת המוצהרת (הפלאגין)
  • G2 — מרחיב את הניתוב הקיים, ללא מסלול-מקביל

בדיקות

  • tsc נקי · biome check נקי · נמדד footprint=0 active issues עם הערת-יו"ר אחרונה.
  • חגורה-וכתפיות: תוספת HEARTBEAT §4ב (legal-ai, PR נפרד) — סוכן קורא הערות שנכנסו תוך-כדי-ריצה לפני done.

Refs legal-ai TaskMaster #164.

🤖 Generated with Claude Code

## הבעיה מסלול ניתוב ההערות הקיים (`issue.comment.created` → CEO) הוא **best-effort**: invoke שנכשל/התלכד/בוטל, או הערה שנוחתת בזמן שסוכן רץ — משאירים את ההערה ללא ניתוב וללא מי שינסה שוב. כך בדיוק **הערת-יו"ר על CMP-190 (30.6.26) נשמטה בשקט**: ה-wakeup הנייטיב בוטל (`issue_execution_promoted`/`assignee_changed`) ושום מסלול-פלאגין לא נורה. אין ספר-חשבונות של הערות-שטופלו. ## הפתרון — sweep פיוס (at-least-once) `route-pending-comments`, כל 2 דק': - מנתב כל issue פעיל שבו **ההערה האחרונה היא של היו"ר** (אין תגובת-סוכן אחריה) וש-id שלה ≠ הסמן `last-routed-comment-id`. - גם המסלול-המהיר וגם ה-sweep מסמנים את הסמן → **אידמפוטנטי**, בלי ניתוב-כפול של הערה בריאה. - "ההערה האחרונה היא של היו"ר" מכוון בדיוק לכשל (יו"ר הגיב, אין תגובת-סוכן) ומדלג על הערות שכבר נענו → **טביעת-רגל ב-first-run אחרי deploy = 0**. ## שינויים - `worker.ts`: חילוץ `routeCommentToCeo()` + `markCommentRouted()` משותפים; ה-event handler מסמן את הסמן (כולל בענף "native handles it"); רישום ה-sweep עם guards per-company/per-issue ו-try/catch. - `manifest.ts`: הצהרת job `route-pending-comments` (`*/2 * * * *`). ## Invariants - **G12** — מגע-Paperclip רק במעטפת המוצהרת (הפלאגין) ✅ - **G2** — מרחיב את הניתוב הקיים, ללא מסלול-מקביל ✅ ## בדיקות - `tsc` נקי · `biome check` נקי · נמדד footprint=0 active issues עם הערת-יו"ר אחרונה. - חגורה-וכתפיות: תוספת HEARTBEAT §4ב (legal-ai, PR נפרד) — סוכן קורא הערות שנכנסו תוך-כדי-ריצה לפני `done`. Refs legal-ai TaskMaster #164. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
chaim added 1 commit 2026-06-30 10:19:18 +00:00
The event-driven comment→CEO route (issue.comment.created) is best-effort:
a failed/coalesced/cancelled CEO invoke, or a comment that lands while an
agent is mid-run, can leave a chair comment unrouted with nothing to retry.
This is exactly how a chair comment on CMP-190 (2026-06-30) was silently
dropped — the host-native wake was cancelled (issue_execution_promoted /
assignee_changed) and no plugin route fired.

Adds a reconciliation sweep (route-pending-comments, every 2 min) that
re-routes any active issue whose LAST comment is the chair's (no agent reply
after it) and whose id ≠ the per-issue `last-routed-comment-id` marker.
Both the fast path and the sweep stamp the marker → idempotent, no
double-routing of healthy comments. "Last comment is user" precisely targets
the failure (chair commented, no agent response) and skips historically
answered comments, so first-run-after-deploy footprint is 0.

- worker.ts: extract shared routeCommentToCeo() + markCommentRouted();
  event handler stamps marker (incl. the native-handles-it branch);
  register route-pending-comments sweep with per-company/per-issue guards.
- manifest.ts: declare route-pending-comments job (*/2 * * * *).

Invariants: G12 (Paperclip touch only in the declared wrapper — plugin),
G2 (extends the existing route, no parallel path). Refs legal-ai #164.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
chaim merged commit 0bf2e46212 into main 2026-06-30 10:40:45 +00:00
chaim deleted branch feat/comment-delivery-guarantee 2026-06-30 10:40: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/plugin-legal-ai#3