CI som løper løpsk
En kodeagent som pusher, kjører på nytt eller åpner pull requests i en løkke, kan bruke opp runner-minuttene dine på noen timer, og ingenting sier fra før e-posten om 80 % forbruk. fremforge holder øye med det.
Hva som måles
Hvert 5. minutt ser fremforge, for hver organisasjon, på de siste 60 minuttene med Actions-kjøringer på de hostede runnerne og måler:
| Signal | Hva | Grense |
|---|---|---|
| Kjøringer per person | Kjøringer én person har startet i organisasjonen | Over 3 ganger personens travleste normale time, og aldri under 80 |
| Runner-minutter per person | Runner-minutter disse kjøringene brukte | Over 3 ganger personens travleste normale time, og aldri under 600 |
| Pusher til én pull request | Ulike commits én person har pushet til én pull request | Flere enn 12 |
«Personens travleste normale time» er 99-persentiltimen deres de siste 14 dagene, beregnet på nytt én gang i døgnet. En person med færre enn 20 aktive timer i den perioden måles i stedet mot organisasjonens travleste normale time. Et team der agentene kjører CI hele dagen, måles altså mot sitt eget normalnivå, ikke mot et rolig teams.
Grensen for pull requests teller pusher, ikke kjøringer: én push starter like mange kjøringer som repositoryet har workflower for den.
Subjektet er alltid en person. En kjøring som en agent starter på vegne av noen, er den personens kjøring (kjøringens trigger-bruker), og det finnes ingen agentkontoer. Boter, som Renovate, måles på samme måte og merkes som boter. Kjøringer som fremforge starter selv, som oppfrisking av lockfiler, måles ikke.
Kalibrering
Grensene ble satt ut fra en måned med CI der de fleste kjøringene kommer fra kodeagenter. Kjørt gjennom detektoren på nytt gir den måneden ingen løpske kjøringer så snart hver person har 14 dager med historikk.
Hva som skjer
Når et tall krysser grensen sin, registrerer fremforge én løpsk hendelse, én gang:
- En e-post til alle eiere av organisasjonen som navngir personen, hvor (organisasjonen eller én pull request) og tallene.
- En e-post til personen kjøringene tilhører, skrevet til dem, slik at de kan stoppe økten sin. Ikke for en bot, og en eier som selv eier kjøringene, får én e-post, ikke to.
- En
ci.runaway-hendelse i hendelsesfeeden, én per repository kjøringene er i, slik at også en agentøkt som leser feeden, ser den. - En revisjonshendelse (
ci_runaway.detected). - En rad på siden for CI-forbruk (se I konsollen).
Så lenge tallet holder seg over grensen, oppdateres hendelsen uten at det sendes ny e-post. Den avsluttes av seg selv etter 60 minutter under grensen igjen.
Ingenting stoppes med mindre organisasjonen din har slått på pausen.
Pausen (tilvalg)
Med pausen slått på stopper en løpsk hendelse også fremforges runnere fra å starte personens nye kjøringer – eller ved en løpsk pull request, personens nye kjøringer på den pull requesten – til en administrator gjenopptar dem. Pausen er av som standard.
Dette gjør pausen aldri:
- Den avbryter aldri noe. En kjøring som holdes tilbake, venter i køen, vises som satt på pause under Utforsk → Actions og starter i løpet av sekunder etter at den gjenopptas.
- Den stopper aldri en kjøring som har startet. En kjøring der en jobb allerede kjører, fullføres, inkludert de senere jobbene.
- Den holder aldri tilbake noen andre. Bare kjøringer som er utløst av personen som er satt på pause (på pull requesten som er satt på pause), venter.
- Den feiler åpent. Hvis fremforge ikke kan lese pausen, starter kjøringene som vanlig.
Den holder bare tilbake fremforges hostede runnere. En runner som organisasjonen din kjører selv, kan fortsatt plukke opp jobben.
En løpsk hendelse som er satt på pause, avsluttes ikke av seg selv. En eier gjenopptar den, eller slår av pausen, noe som gjenopptar alle hendelser som er satt på pause, på én gang. Etter en gjenopptakelse blir den samme personen ikke flagget igjen på 60 minutter.
Forgejos planlagte workflower (brukeren forgejo-actions) måles og varsles om, men settes aldri på pause.
I konsollen
Eiere av organisasjonen finner løpske hendelser under Bygg og utrulling → CI-forbruk, avsnittet Runaway CI (https://frem.sh/<org>/_admin/ci-usage#runaways): bryteren for pausen, og deretter hver løpske hendelse med person, hvor, travleste time, tilstand og en knapp for Gjenoppta (eller Avvis). Et banner øverst på siden sier fra når en er aktiv.
API
Tokenet trenger runners:read for å liste og runners:write for å gjenoppta eller slå pausen av og på. Hver endring revideres som personen kalleren handler på vegne av.
# 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"En løpsk hendelse i listen:
{
"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 er open (varslet), paused, ended eller resumed. MCP-serveren lister dem med list_ci_runaways.
Stopp selve løkken
Varselet forteller deg hvilken persons arbeid som går i løkke; økten er deres. Stopp agentøkten, eller tilbakekall tokenet den bruker. Med on-behalf-of-tokener stopper du den økten ved å tilbakekalle det delegerte tokenet, uten å røre personens andre arbeid.