---
title: Session Refill Governor — "keep this many sessions running"
---

# Session Refill Governor — "keep this many sessions running"

## What it is

**What it does.** When you have fewer sessions working than you want, this quietly restarts ones
that were **interrupted** — until you are back to your target number. It checks every five minutes.

**Off by default.** Nothing restarts until you turn it on. The switch is right where you would look
for it: open **Manage sessions**, go to the **Refill** tab, and turn on **Restart interrupted
sessions automatically**. The same tab sets how many sessions to keep running, and whether paused
ones count. The rarely-touched knobs — how many to restart per check, the spending cap — stay in
**Settings → Lab** — look for "Session Refill Governor (keep X sessions running)".

> **The Refill tab is always there.** Whether the governor is on or off, the tab stays in the strip
> — so a switch you turn off is a switch you can turn back on, from the same place. The setting in
> **Settings → Lab** is the same one the tab switches, but neither is the only way back.

> It starts agent turns on its own, and agent turns cost money. Every limit on this page exists
> because of that.

---

## Where to find it

Open Manage sessions and switch to the Refill tab: that is where the switch lives, labelled "Restart interrupted sessions automatically", together with your target number of sessions and whether paused ones count. The Refill tab is always in the strip whether the governor is on or off, so a switch you turned off can always be turned back on from the same place.

The rarely-touched limits — how many to restart per check, and the daily spend cap — sit in Settings, in the Lab section, under "Session Refill Governor (keep X sessions running)".

The governor is off by default: nothing restarts until you turn it on.

The Refill tab works the same from your phone, and shows the values you actually saved. Until 2026-09-23 the phone showed the factory defaults instead — the switch read "off" and the target read 40 even while the governor was running — so a tap there could turn off a governor that was really on.

## How it behaves

### "Interrupted" — the one word that matters

A session is **interrupted** when its turn ended **abnormally and left work unfinished**. That is
the only kind of session this feature restarts.

**It restarts these:**

| What happened | What you see in the app |
|---|---|
| The process stopped mid-work — killed, crashed, or hit its context budget | Ended |
| It died mid-work against the AI provider | Failed |
| A sub-agent never came back, so the turn could not finish | Interrupted |
| It said it was waiting, then went silent past the cap | Interrupted |
| Automatic recovery tried and gave up — nothing else will retry it | Failed |
| It was genuinely mid-work when Omniscio closed | Interrupted |

**It never restarts these — and each exclusion is deliberate:**

| Situation | Why it is left alone |
|---|---|
| **The turn finished cleanly** | It is done, not stuck. Restarting it just makes it tell you so again — and that costs a turn every time. |
| **The session never actually ran** — you opened it and closed it without ever sending anything | There is no conversation to continue, so a restart spends a turn to be told "there is nothing here". These pile up quietly over months: on the machine that prompted this, **119 of 232** interrupted sessions were empty like this. |
| It is asking you a question, wanting plan approval, or requesting a permission | Restarting would consume an inbox item you never read. |
| A dev-pipeline run finished and is waiting for you to say ship | Same reason — it is your move. |
| A merge conflict was handed back to you | Only you can resolve it. |
| **You stopped the session yourself** | Nothing automated resurrects it — not even the switch below that can bring back a session you simply closed. A Stop is a stronger "no" than a close, and it holds until you restart or message the session yourself. |
| It hit an authentication error | It needs you to sign in again; a restart would just fail again. |
| It is parked on a usage limit, or out of provider credit | It resumes by itself once capacity or credit returns. |
| Its answer was cut off mid-stream | A separate recovery pass already owns the retry. If that pass gives up, the session becomes "Failed" and then this feature will pick it up. |

---

### Keeping it to the projects you choose

By default it will restart an interrupted session **in any project**. It has no idea what a repo
is — measured on one real machine, its list spanned six different projects purely by accident of
what had happened to be interrupted.

Set **only restart sessions in these projects** (`sessionRefillIncludeProjectNamePatterns`) to a
project name and it restarts there and nowhere else. Leave it empty and every project is allowed.

**It fails safe.** Once you have listed something, a session must match to be restarted — so if you
rename a project and nothing matches any more, it restarts **nothing** rather than quietly going
back to restarting everything.

### The limits, and what each one is for

| Setting | Default | What it does |
|---|---|---|
| Keep this many sessions running | 40 | The target. Below it, the governor tops you back up. |
| Only restart in these projects | *(empty — all)* | Names it may restart in. Empty means every project. |
| **Max restarts per session per day** | **1** | One session gets **one** nudge a day. This is the limit that makes a restart loop impossible. |
| Per-session cooldown | 20 min | A delay before the same session can be touched again — **not** a budget. |
| Max revives per check | 5 | Caps how big a single burst can be. |
| Daily spend cap | $25 | The most it may spend per day. **Only pay-per-use sessions count** — an API key or a per-token vendor. A session on one of your Claude Pro/Max subscription accounts costs nothing extra per turn, so it does not count. Set 0 to turn the dollar cap off — the count limits still apply. |
| Daily restart limit | 200 | A hard backstop in case cost reporting lags. |

**Cooldown and the per-session cap are different things, and the difference is the whole point.**
A cooldown only postpones; on its own, a session that keeps landing back in the pool gets restarted
again and again forever. The per-session daily cap is a budget that runs out.

### Reopening sessions you closed — off, and opt-in

There is a switch, **Also restart sessions I closed myself**, that lets the governor treat sessions
**you deliberately closed** as restartable too. It is **off**, and you should leave it off unless
you specifically want that behaviour — with it on (2026-09-06) the governor reopened three sessions
that had been closed on purpose.

**This switch never reaches a session you stopped with Stop.** Closing a session and stopping one are
different strengths of "no": a plain close is what this switch is for, but a Stop — the Stop button,
Manage sessions → Stop, a multi-select or right-click Stop — holds no matter how this switch is set.
The only way back for a stopped session is your own restart or message.

**It now lives on the Refill tab, next to the sentence it explains, and that is a real change.**
Until 2026-09-19 it existed only as a value in the config file — no screen anywhere in the app could
show or set it. So the single rule most likely to be holding the fleet down was also the one rule
nobody could find. Measured on the machine that prompted this: a pool of 268 interrupted sessions
yielded **0** eligible, and turning this one switch on took it to **136**.

Two things follow, and they are worth holding together. If the Refill tab is naming "you closed
yourself" as the biggest reason nothing is restarting, the numbers are real and this switch is the
lever. And each session it brings back is a **billable turn**, which is why it ships off and says
so.

---

### Seeing the queue — the Refill view

You do not have to read the log to know what it is about to do. Open **Manage sessions** and switch
to the **Refill** tab: it lists the sessions the governor would restart, in the order it would pick
them, each row saying **why** it qualifies in plain English — "Process stopped mid-work",
"Automatic recovery gave up", "Interrupted when the app closed".

A strip across the top gives you its live state at a glance:

- **how many sessions are running, against your target**,
- **how many automatic restarts it has left today**,
- whether it is **limited to chosen projects** or free to work in all of them,
- and, in one sentence, **what it is going to do** — "At or above your target, so nothing will
  restart on its own", or "3 will restart at the next check."

Above that strip are the controls themselves, so the tab that tells you what it is about to do is
also the tab where you change it:

- **Restart interrupted sessions automatically** — on or off.
- **Keep N running** — the target it is working toward.
- **Also restart paused sessions** — off by default, and worth understanding before you turn it on.
  Normally only interrupted work qualifies. With this on, a session you **paused** counts too, and
  gets un-paused when its turn comes. Pausing is something you did on purpose, so undoing it stays
  your call.

They stay on screen when the queue is empty, and when the queue fails to load — being able to turn
it **off** matters most exactly when its readout is broken.

**Every change here saves the moment you make it, and tells you so.** A **Settings saved** toast
confirms the write landed (the same one the Settings screen shows, and it follows the same
"settings confirmations" toast preference), and the strip above re-reads itself so it describes the
governor you just changed rather than the one you opened. Before this, turning the switch on left
the line beneath it still reading "Auto-restart is off" — the save had worked, the readout was
simply frozen at open time, and there was no way to tell those two apart. If a save fails you get
an error toast instead and the control snaps back to its old value.

**A full list with nothing happening is a normal, meaningful state.** If you have more sessions
running than your target, the governor holds back — so you will often see a long queue above a line
telling you nothing is coming. That is the honest answer, and it is exactly why the list is not
simply hidden.

**When the list IS empty, it tells you which kind of empty — and now it tells you WHY.** "No
interrupted sessions to restart" means nothing is broken. "209 interrupted sessions, but none are
eligible right now" means plenty is interrupted and the governor is deliberately holding back.

Under that sentence it now names the rule that did the holding, in the order the rules run:

```
Held back: 140 you closed yourself · 124 generic session shells · 4 outside your project scope
```

The counts are a waterfall, not a share: each session is counted once, where it was ruled out, so
the figures depend on the order the rules run and are not independent totals. A rule that excluded
nothing is left out rather than shown as a zero, so the number that matters is not buried.

> **This paragraph used to say the cause was "usually cooldowns, or sessions that have already had
> their one restart today."** That was measurably wrong on the machine where the feature was built:
> both of those rules removed **zero** sessions, while the two actually doing the work — "you closed
> yourself" and the generic-shell deny-list — were not mentioned anywhere. Anyone who went looking
> for the reason was pointed at rules that were not firing.

**It also tells you the number you were comparing it against.** The Restart tab and this one draw
different populations, and seeing only one of them made them look like they contradicted each
other. The line under the reasons names the Restart tab's own count, so the two read as one story:

```
Held back: 120 you closed yourself · 123 generic session shells · 4 outside your project scope
162 can be restarted by hand on the Restart tab.
```

Both numbers are worked out the same way, from the same rule, so they cannot drift apart again.

**You can restart any of them yourself, right now.** Tick the ones you want and press **Restart now
N**. They relaunch through the same paced path the Restart tab uses, so a big batch trickles back
instead of storming your machine. This works even with the feature switched off — the tab is then
simply a list of what it *would* restart. Like every restart, it cannot be undone: bringing an agent
back costs a turn.

**It shows you the truth, not a guess.** The queue is worked out by Omniscio's own engine — the same
filters a real check runs — rather than re-derived from the sidebar. That matters: things like
per-session cooldowns and today's restart counts are not visible to the screen, so a list built from
what is on screen would quietly disagree with what the governor actually does.

---

### When a session should never be restarted

Some work should be left alone — a long park, a run you deliberately halted, something whose next
step is not simply "carry on". A session can take **itself** off the list, for good:

```
POST /session/<id>/auto-restart-opt-out
```

That is a standing refusal, and nothing overrides it — not your settings, not the reopen option
that brings back sessions you closed. It does **not** stop you restarting that session by hand;
it only means the governor will never do it for you.

You can always undo it. An opted-out session shows a **"Won't auto-restart"** tag on the **Restart**
tab of Manage sessions; click the tag and it goes back on the list. That is the only place the tag
appears, because the Refill queue never lists an opted-out session at all.

---

### What it does not do

- It **restarts** interrupted sessions; it never starts brand-new ones to reach the target.
- Only one copy runs, even with a second window open.
- **It does nothing at all until your sessions have finished coming back from a restart.** Not for
  a set number of minutes — for as long as the queue of returning sessions actually still has work
  in it, which on a big fleet is half an hour. Restarting something already in that line would
  only start it twice.
- **It counts the sessions on their way back, not just the ones already up.** One that is starting,
  one waiting its turn after a restart, and a new session another agent asked for that is already
  being launched all count toward your target — so it never tops up against a gap that is about to
  fill itself.
- **A new session still waiting in the start-up line does not count.** When the machine is busy
  that line moves about one start a minute and agents keep adding to it, so it says nothing about
  the next few minutes. Counting it once kept the refill switched off for an hour while only 92 of
  a 100-session target were working — the Refill tab read "119 running" the whole time.
- If it cannot measure what it has spent, it does not spend. Withholding work is the safe direction.
- **Its spend cap counts real money only.** A restarted session on a Claude Pro/Max subscription
  costs nothing per turn, so it never counts toward the cap; one on an API key or a per-token vendor
  always does, and so does one whose billing it cannot tell. Counting subscription sessions at list
  price once used up the $25 default minutes after the first restarts and stopped the refill for the
  rest of the day. A session restarted twice counts once, and one you delete afterwards still counts.
- **When a daily limit stops it, the Refill tab names which one.** The spend cap reads "Today's $25
  spending limit for restarts is used up ($27 spent)…" with the Daily spend cap setting right below
  it; "Out of restarts for today" means the daily restart-count limit.
- **It restarts sessions whose worktree folder has gone to other work, too.** Omniscio hands a
  finished session's folder on to new work; such a session is never resumed in that folder, so its
  restart moves it into a fresh worktree of its own first and carries on there. On 2026-09-26, before
  the move existed, these sessions were refused on every restart — more than half of all picks —
  and the fleet sat about 20 below a target of 120. Only a restart whose move fails (for example, a
  full drive) is refused, and that refusal does not use up the session's daily restart.

**Kill switches:** `AMC_DISABLE_SESSION_GOVERNOR=1` (the whole thing),
`AMC_DISABLE_REFILL_REOPEN=1` (just the reopen carve-out).

Contract: `.claude/memory/contracts/session-refill-governor-contract.md`.

## For agents

### Reading its log

Every restart says why it picked that session:

```
[session-governor] revived: Build the corpus (interrupted: suspended, revive 1/1 today)
```

And a check that restarts nothing still says what it saw, so a pool that has quietly gone empty
cannot be mistaken for a healthy quiet one. **`pool=` is everything it weighed; `eligible=` is what
survives your limits** — the name exclusions, the project list, the cooldowns, today's counts — so
the gap between the two numbers is how you confirm your settings are actually being applied. `pool=`
counts interrupted sessions that have something to continue; a session that never ran is not in
either number, because no setting you can change would ever make it restartable. Both
are always real counts, including when you are above target and nothing is going to restart:

```
[session-governor] running=38 (live=30 resuming=6 launching=2; not counted: spawn-line=5) target=40 deficit=2
  spentToday=$4.10 -> no-eligible-candidates
  [pool=12 eligible=0 by-signal ended=9 suspended=2 recovery_failed=1]
```

When the rules did remove anything, the bracket also carries `blocked:` — what each rule took, in
rule order — e.g. `[pool=252 eligible=143 blocked: name-excluded=6 project-scope=101 …]`.
A session whose worktree folder went to other work is NOT held back: its restart moves it into a
fresh worktree of its own. Lines from 2026-09-26 may still print `worktree-recycled=N` — that screen
existed for one day and was removed once the move shipped.

**`spentToday=` is pay-per-use money only** — what the sessions it restarted today have spent on an
API key or a per-token vendor since their restart. Subscription sessions are left out, so this can
read cents while the same sessions show hundreds of dollars of list-price cost elsewhere.

**`running=` is everything that counts toward your target, and the bracket says what it is made
of** — `live` are up right now, `resuming` are queued to come back after a restart, `launching` are
new sessions another agent asked for that are starting this moment. The split matters because the
total alone cannot tell a genuinely small fleet apart from a big one still coming back, and acting
on the second as if it were the first is what once cost ten needless restarts.

**`spawn-line=` is printed but never counted** — new sessions still waiting their turn to start. It
is there so a quiet check beside a long line can be explained; counting it is what once held the
refill off below target for an hour. The Refill tab does not show this line — only the log does.
Log lines from before 2026-09-25 print `spawning=` instead, and that older number counted the whole
line, waiting sessions included.

**`stopped-by-you` is its own reason, screened ahead of `user-closed`, and no setting lifts it** —
unlike `user-closed`, which the reopen switch above can lift. It counts a session ended with Stop (the
Stop button, Manage sessions → Stop, a right-click or multi-select Stop), never a plain close. Lines
from before 2026-09-27 never print it, because a Stop was not yet held any more strongly than a close.

And while that restart queue is still draining, it says so and does nothing at all:

```
[session-governor] resume wave still draining — holding off; the fleet is coming back on its own
```

---

## Related

No sibling page is linked from this one, so start from the library map: [INDEX.md](INDEX.md) lists every page and area, which is the quickest route to the neighbouring session-lifecycle and cost pages.
