fix(orchestrateur): garde anti-boucle sur les incidents abandonnés
Une source diagnostiquée irréparable (site_source_mort, tentatives épuisées) ne redonne plus d incident avant abandoned_retry_hours (168 h, policy). Sans cette garde, un connecteur désactivé côté app mais rapporté broken à perpétuité par la supervision api-ka relançait une mission toutes les ~10 min (2026-08-24 : 37 missions sur origin-north.ai + 37 sur visionartproductions.com, ~42 USD). Les deux lignes mortes ont aussi été acquittées dans connector_health côté api-ka. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 changed files +15 −2
modified
orchestrator/main.py
+12 −0
@@ -445,6 +445,18 @@ async def poll_once() -> None: | ||
| 445 | 445 | source, status = conn["source"], conn["status"] |
| 446 | 446 | inc = active_incident(c, service, source) |
| 447 | 447 | if status in trigger and inc is None: |
| 448 | + # Garde anti-boucle : une source déjà diagnostiquée irréparable | |
| 449 | + # (site_source_mort, tentatives épuisées) ne redonne pas | |
| 450 | + # d'incident tant que le délai de re-examen n'est pas écoulé. | |
| 451 | + # Sans elle, un connecteur désactivé côté app mais rapporté | |
| 452 | + # broken à perpétuité par api-ka relance une mission toutes | |
| 453 | + # les ~10 min (2026-08-24 : 37 missions sur origin-north.ai). | |
| 454 | + ab = c.execute( | |
| 455 | + "SELECT updated FROM incidents WHERE service=? AND source=? " | |
| 456 | + "AND state='abandoned' ORDER BY updated DESC LIMIT 1", | |
| 457 | + (service, source)).fetchone() | |
| 458 | + if ab and now() - ab["updated"] < POLICY.get("abandoned_retry_hours", 168) * 3600: | |
| 459 | + continue | |
| 448 | 460 | iid = uuid.uuid4().hex[:10] |
| 449 | 461 | c.execute("INSERT INTO incidents(id,service,source,status_detected,state,created,updated,detail) " |
| 450 | 462 | "VALUES(?,?,?,?,?,?,?,?)", |
modified
topology.json
+3 −2
@@ -179,6 +179,7 @@ | ||
| 179 | 179 | "mission_max_turns": 70, |
| 180 | 180 | "mission_timeout_seconds": 3600, |
| 181 | 181 | "effort_max_turns": 150, |
| 182 | − "effort_timeout_seconds": 7200 | |
| 182 | + "effort_timeout_seconds": 7200, | |
| 183 | + "abandoned_retry_hours": 168 | |
| 183 | 184 | } |
| 184 | −} | |
| \ No newline at end of file | ||
| 185 | +} | |
| 185 | 186 | |