Foreman›Docs›Running›Run, pause and stop

Run, pause and stop

Running · page 1 of 7

Standby, workers and slots, the background service, keep-awake, and the two kinds of stop.

Foreman 0.11.06 sections

This page is for the person who runs Foreman: how a run starts and what it does when the backlog is empty, how many stories build at once, how to pause and stop it, how to keep it running after a reboot, and how to tidy up processes a run left behind. Every control here has a matching button on the dashboard.

foreman run and standby

foreman run starts the supervisor, the process that picks stories, starts a Claude session for each one in its own slot and watches them. The full form is foreman run [N] [--workers W] [--exit-when-idle] [--foreground] [--dry-run]:

Name What it does Default When it applies
N How many new stories to start before the run ends. No limit: the run goes until you stop it. Not with the service installed.
--workers W How many slots build at once for this run, 1 to slots. The workers setting. Not with the service installed.
--exit-when-idle Stop with “Nothing left to build.” instead of standing by. Off: the run stands by. Not with the service installed.
--foreground Stay attached to the terminal; Ctrl-C, kill and a closed terminal stop the run. Off: the run is detached. Always.
--dry-run Print what each slot would start and change nothing. It may run beside a live run. Off. Always.

By default the supervisor starts in its own session, so closing the terminal or the Claude session that ran the command does not stop it. Its output is appended to .foreman/logs/supervisor.out. The command waits up to 5 seconds for the supervisor to write its pid, then prints the pid, the dashboard address and the log path, and returns. If the supervisor ends before it writes its pid, the command prints the last 20 lines of the log: “The supervisor finished as it started:” for a clean exit (nothing to build, exit code 0), or “The supervisor stopped as it started:” for anything else (exit code 1). If it has written no pid after 5 seconds, the command says it is still starting and that foreman status will say when it runs.

A second foreman run while a supervisor runs is refused with “Foreman is already running (pid N).” An invalid foreman.config.json stops the run at start. One that turns invalid while the run goes does not: the run carries on with the last good config, which it saves as .foreman/config.last-good.json, and shows the problem on Waiting on you and in foreman status until the file is valid again.

A new run clears a STOP left by an earlier foreman stop. With the run state on a branch, that removal is pulled and pushed too, so a stop from another machine cannot stop this run.

Standby

When nothing is running or queued and the last pick found nothing to build, a run with no story limit stays up on standby. It logs one event on entering standby and one on leaving, not one per check. Every tick (5 seconds) it reads the story source again, the Jira refresher keeps polling, and your answers from Waiting on you are applied. The first story that becomes buildable (a new story, a blocker that ships, an owner task marked done, an answered decision) leaves standby and starts. Only foreman stop, a signal or new code ends standby; a halt or a pause shows over it, and the run goes back to standby after.

A run with N, or with --exit-when-idle, stops instead with “Nothing left to build.”

When the run enters standby with things waiting on you, it writes one event and sends one standby notification, once foreman learn has finished proposing follow-ups: it names what waits and what one answer would start, for example “Standby: 3 follow-up proposals and 1 owner task wait on you; finishing ACME-300 starts ACME-301.” Nothing is sent when nothing waits, and the same text is not sent twice.

Restart on new code

When the plugin code the supervisor was loaded from changes under it (a new plugin version, or a commit to plugin/ when Foreman builds its own repo), it starts no new story and restarts itself: it checks the new code accepts the config with foreman config check, saves the run’s counts, logs “Restarted on new code (<old> -> <new>).” and exits with code 75. foreman run starts it again with the same arguments, and the new process carries the run on: the sessions keep running and are adopted with one “Kept N running across the restart” event. Until the restart happens, Waiting on you shows a “Restarting on new code” FYI, foreman status has a line for it, and idle slots read “waiting for restart”. A stop wins over a pending restart; a dry run never watches the code.

Inside a story session

A foreman run started inside a Foreman story session always runs in the foreground and never through the service, so nothing it starts outlives the session. The owner’s controls on this page (pause, stop, slot and the rest) are refused inside a story session.

Workers and slots

A slot is one copy of the repository (a git worktree) with its own environment, named w1 to wN. A worker is a slot that is allowed to build. The two settings, both in the Run group of Settings:

Name What it does Default When it applies
slots How many repo copies Foreman keeps, 1 to 8. A pack can lower that cap (the Salesforce pack needs an org per slot). 1 When the run restarts.
workers How many stories build at the same time, 1 to slots. 1 From the next pick.

Three things set the worker count while a run goes: foreman run --workers W at start, foreman workers <n> or the Workers control on the dashboard, and a change to the workers setting. At start the flag wins over the setting. After that, the newest change wins and applies at the next pick; a settings change that leaves workers as it was changes nothing. A value above the run’s slots is capped, with the warning “Workers N is more than the M slots this run has; using M.”

A slot picks a new story only while fewer than workers stories are running across all slots. When you lower the count, the slots above it finish the story they have first; foreman status shows them as draining. Work queued for a slot above the limit (a crash resume) moves to a slot under it, with its claim, its file locks and its folder.

Pause, resume, stop and stop –now

Name What it does What happens next
foreman pause Starts no new stories. Each slot finishes the story it has, then waits. Answers are still applied and the dashboard keeps updating.
foreman resume Lets the run pick again. Every free slot picks at the next check. It also clears a pause Foreman made itself.
foreman stop Asks the run to finish the stories in progress, then stop. The run writes .foreman/STOP, runs its last foreman learn and sends the stopped email, then exits. With the service installed it stays stopped until the next foreman run.
foreman stop --now Stops at once. The same STOP is written, then the supervisor gets SIGTERM. It stops each session (SIGTERM, then SIGKILL after 10 seconds) and exits. The stories keep their claims and resume by priority at the next start; a session cut off this way ends as interrupted, not failed, and its transcripts are kept. With no supervisor running the command says so and stops nothing.

Ctrl-C, kill or a closed terminal on a foreground run does what stop --now does. Every stop records who asked: your terminal, a browser on the dashboard or the cloud runner. A stop that came from anywhere else (a story session, say) emails you at once as an unexpected-stop, and foreman status names who stopped the run.

Foreman also pauses itself. It does so after 3 misses in a row (a miss is a failure the pipeline caused, such as a crash or a failed round; a story waiting on you never counts), when the Console API key runs out of credit or hits its usage limit with no subscription to switch to, and when the Claude sign-in fails. A credit pause resumes by itself at the reset time Claude printed, or an hour on, and tries again every 30 minutes until it works; a sign-in pause clears itself once a sign-in check passes. A rate limit or an outage never pauses the run: it waits 15, 30, 60 and then 120 minutes between tries. Three endings in a row that the environment caused (a tool missing, an org down) wait 15, 30 and 60 minutes, and only a fourth pauses. In every case the self-pause shows on Waiting on you with Resume, and foreman resume works sooner.

A halt is different from a pause: a failed release writes .foreman/HALT, every release is frozen, and the slots that had committed are held. Fix the cause, then run foreman fixed or press “I’ve fixed it” on the dashboard. That runs foreman health; only when its checks pass does the halt clear and the held stories ship, oldest first. Otherwise the run stays halted and shows what still fails. Release safety has the detail.

Three more controls act on stories rather than the run. foreman next <id> asks for a story next: every pick tries it first, and the request stays pending until the story has started in a slot; after 3 failed starts it is shown on Waiting on you, still first in line. It also clears a skip. foreman handback <id> gives a story you took over back to the factory: your claim is removed and the story goes back to todo. foreman slot <wN> <action> acts on one slot; the actions are on Waiting on you.

Running as a service

foreman service install hands the factory to the operating system as a per-user background service: a launchd agent on macOS, labelled ai.foreman.<slug>, or a systemd --user unit on Linux, named foreman-<slug>.service. The slug comes from project.name, else the project folder’s name. The service runs foreman run --foreground --service in the project, starts it again after a crash (a non-zero exit or a signal, never after a clean exit) and at each log-in. Its output goes to .foreman/logs/supervisor.out. On Linux, loginctl enable-linger $USER starts it at boot before you log in.

The service runs until stopped, on standby when there is nothing to build. While it is installed a plain foreman run asks the service manager to start it and takes no story count, --workers or --exit-when-idle; for those, run foreman run --foreground N in your own terminal, and change the workers with foreman workers. foreman stop leaves a marker (.foreman/service-stopped) that the service honours, so a stopped factory stays stopped across crashes and log-ins until your next foreman run.

Install refuses while a supervisor runs (“Stop it with foreman stop, and install once it has finished.”), when the label is already installed for another folder, when the project or log path has a control character in it, on Linux when systemctl --user does not work, and inside a story session. foreman service uninstall stops the run it had going and removes the service; its stories resume at the next start. foreman service status prints one line: not installed, running with its pid, stopped with foreman stop, or installed but not running with the log to look at. Other platforms get “foreman service works on macOS and Linux only.”

The service file carries only PATH, HOME, LANG, LC_ALL, FOREMAN_STATE_DIR, FOREMAN_PLUGIN_DIR and CLAUDE_CONFIG_DIR from your environment, plus the project folder; no key is written into it, and the run reads the Claude sign-in from .env.foreman itself. It starts Node by a path an upgrade keeps (Homebrew’s link rather than the versioned folder), and foreman doctor warns when that Node is gone and says whether the factory runs as a service.

Keeping the Mac awake

The features.keepAwake switch (on by default, applies when the run next starts) runs caffeinate -i -s -w <pid> on macOS while the run builds: -i stops idle sleep, and -s stops system sleep too, which macOS honours only on mains power, so on battery idle sleep alone is held off. Keep-awake is let go on standby and taken again when a story starts. On Linux it does nothing. The old top-level keepAwake config key still works but is deprecated; foreman config check tells you to move it to features.keepAwake.

macOS may still sleep when the lid is closed and no external display is attached. The supervisor notices: when its loop wakes more than 15 seconds late it logs “The supervisor woke N late: its event loop was held or the computer slept.” (or names the command that held the loop), asks Jira for a fresh answer before it judges the cached stories, polling at most twice for up to 30 seconds each, and restarts the progress watchdog’s clocks so the sleep itself is never read as a stall.

Stray supervisors

A stray is a Foreman process that is not this run’s: a supervisor, a hook run or a foreman learn or notify run that tests or an agent’s manual check left running, in a temp folder or in this project’s folders (its slot worktrees). Only a process over 10 minutes old counts, so the live tests another slot is running are not. Another project’s real run is never counted unless it lives in a temp folder.

A real run looks for strays at its first loop and every 10 minutes, and keeps their pids in state.json. Waiting on you shows them as an FYI, “N stray processes running”, with End them. foreman doctor counts them on its “stray processes” line, and foreman doctor --end-strays ends them: SIGTERM to each, SIGKILL to any still there after 5 seconds, then “Ending <what>: pid a, b.”, “Ended N.” and “Still running: pid x.” for any left (exit 1). With none it prints “No stray processes.”; when ps cannot run it prints “Could not list the running processes.” and ends nothing. It refuses inside a story session, so a slot never ends another slot’s tests.

A supervisor that belongs to a test or a scratch copy ends on its own: one started inside a story session stops within a tick or two of the shell that started it ending, and one with a leash or a state folder under the temp folder stops after 5 minutes on standby. A real run has neither limit.