Zum Hauptinhalt springen

Außer Kontrolle geratene CI

Ein Coding-Agent, der in einer Schleife pusht, Läufe neu startet oder Pull-Requests öffnet, kann deine Runner-Minuten in Stunden aufbrauchen, und nichts sagt es dir bis zur E-Mail bei 80 % Verbrauch. fremforge achtet darauf.

Was gemessen wird

Alle 5 Minuten betrachtet fremforge für jede Organisation die Actions-Läufe der letzten 60 Minuten auf seinen gehosteten Runnern und misst:

SignalWasSchwelle
Läufe pro PersonLäufe, die eine Person in der Organisation gestartet hatÜber dem Dreifachen der höchsten normalen Stunde dieser Person, und nie unter 80
Runner-Minuten pro PersonRunner-Minuten, die diese Läufe verbraucht habenÜber dem Dreifachen der höchsten normalen Stunde dieser Person, und nie unter 600
Pushes auf einen Pull-RequestVerschiedene Commits, die eine Person auf einen Pull-Request gepusht hatMehr als 12

„Die höchste normale Stunde dieser Person“ ist ihre Stunde im 99. Perzentil der letzten 14 Tage, einmal täglich neu berechnet. Eine Person mit weniger als 20 aktiven Stunden in diesem Zeitraum wird stattdessen an der höchsten normalen Stunde der Organisation gemessen. Ein Team, dessen Agenten den ganzen Tag CI laufen lassen, wird also an seinem eigenen Normalmaß gemessen, nicht an dem eines ruhigen Teams.

Die Schwelle für Pull-Requests zählt Pushes, nicht Läufe: Ein Push startet so viele Läufe, wie das Repository Workflows dafür hat.

Gemessen wird immer eine Person. Ein Lauf, den ein Agent im Auftrag einer Person startet, ist ein Lauf dieser Person (der auslösende Benutzer des Laufs), und es gibt keine Agentenkonten. Bots wie Renovate werden genauso gemessen und als Bots gekennzeichnet. Läufe, die fremforge selbst startet, etwa Lockfile-Aktualisierungen, werden nicht gemessen.

Kalibrierung

Die Schwellen wurden anhand eines Monats an CI-Läufen festgelegt, in dem die meisten Läufe von Coding-Agenten stammen. Durch den Detektor nachgespielt, löst dieser Monat keinen einzigen Alarm aus, sobald jede Person 14 Tage Verlauf hat.

Was passiert

Überschreitet ein Wert seine Schwelle, erfasst fremforge einmalig einen Fall von außer Kontrolle geratener CI:

  • Eine E-Mail an jeden Owner der Organisation mit der Person, dem Ort (die Organisation oder ein bestimmter Pull-Request) und den Werten.
  • Eine E-Mail an die Person, der die Läufe gehören, an sie selbst gerichtet, damit sie ihre Sitzung beenden kann. Nicht bei einem Bot, und ein Owner, dem die Läufe gehören, bekommt eine E-Mail, nicht zwei.
  • Ein ci.runaway-Ereignis im Ereignis-Feed, eines pro Repository, in dem die Läufe stattfinden, sodass auch eine Agentensitzung, die den Feed liest, es sieht.
  • Ein Audit-Ereignis (ci_runaway.detected).
  • Eine Zeile auf der Seite zur CI-Nutzung (siehe In der Konsole).

Solange der Wert über der Schwelle bleibt, wird der Fall aktualisiert, aber nicht erneut gemailt. Er endet von selbst nach 60 Minuten wieder unter der Schwelle.

Nichts wird angehalten, es sei denn, deine Organisation hat die Pause eingeschaltet.

Die Pause (optional)

Mit eingeschalteter Pause verhindert ein Fall außerdem, dass die Runner von fremforge neue Läufe dieser Person starten – bei einem Fall auf einem Pull-Request die neuen Läufe dieser Person auf diesem Pull-Request –, bis ein Admin sie fortsetzt. Die Pause ist standardmäßig aus.

Was die Pause nie tut:

  • Sie bricht nie etwas ab. Ein zurückgehaltener Lauf wartet in der Warteschlange, wird unter Entdecken → Actions als pausiert angezeigt und startet Sekunden nach dem Fortsetzen.
  • Sie hält nie einen Lauf an, der schon begonnen hat. Ein Lauf mit einem bereits laufenden Job läuft zu Ende, einschließlich seiner späteren Jobs.
  • Sie hält nie jemand anderen zurück. Nur Läufe, die die pausierte Person (auf dem pausierten Pull-Request) ausgelöst hat, warten.
  • Sie schlägt offen fehl. Kann fremforge die Pause nicht lesen, starten Läufe wie gewohnt.

Sie gilt nur für die gehosteten Runner von fremforge. Ein Runner, den deine Organisation selbst betreibt, kann den Job weiterhin übernehmen.

Ein pausierter Fall endet nicht von selbst. Ein Owner setzt ihn fort oder schaltet die Pause aus, wodurch alle pausierten Fälle auf einmal fortgesetzt werden. Nach dem Fortsetzen wird dieselbe Person 60 Minuten lang nicht erneut gemeldet.

Die geplanten Workflows von Forgejo (der Benutzer forgejo-actions) werden gemessen und gemeldet, aber nie pausiert.

In der Konsole

Owner der Organisation finden diese Fälle unter Build und Deployment → CI-Nutzung, Abschnitt Außer Kontrolle geratene CI (https://frem.sh/<org>/_admin/ci-usage#runaways): zuerst den Schalter für die Pause, dann jeden Fall mit Person, Ort, höchster Stunde, Status und einer Schaltfläche Fortsetzen (oder Verwerfen). Ein Banner oben auf der Seite zeigt an, wenn gerade ein Fall aktiv ist.

API

Das Token braucht runners:read zum Auflisten und runners:write zum Fortsetzen oder zum Umschalten der Pause. Jede Änderung wird im Namen der Person auditiert, für die der Aufrufer handelt.

# List (state=live for open and paused only)
curl https://frem.sh/_app/api/v1/orgs/<org>/ci-runaways \
  -H "Authorization: Bearer $FREMFORGE_TOKEN"

# Turn the pause on (or off: off resumes every paused runaway)
curl -X PUT https://frem.sh/_app/api/v1/orgs/<org>/ci-runaways/settings \
  -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"pause": true}'

# Resume one (or close an open one)
curl -X POST https://frem.sh/_app/api/v1/orgs/<org>/ci-runaways/<id>/resume \
  -H "Authorization: Bearer $FREMFORGE_TOKEN"

Ein Fall in der Liste:

{
  "id": "4f0c…",
  "status": "paused",
  "scope": "pr",
  "person": "alice",
  "person_kind": "person",
  "repo": "api",
  "pr_number": 42,
  "signals": ["pr_pushes"],
  "runs": 48,
  "heads": 16,
  "minutes": 0,
  "detected_at": "2026-10-25T09:40:00.000Z",
  "paused_at": "2026-10-25T09:40:00.000Z",
  "resumed_at": null
}

status ist open (gemeldet), paused, ended oder resumed. Der MCP-Server listet die Fälle mit list_ci_runaways auf.

Die Schleife selbst stoppen

Die Warnung sagt dir, wessen Arbeit in einer Schleife läuft; die Sitzung gehört dieser Person. Beende die Agentensitzung oder widerrufe das Token, das sie nutzt. Bei On-behalf-of-Tokens beendet das Widerrufen des delegierten Tokens diese Sitzung, ohne die übrige Arbeit der Person zu berühren.