Foreman›Docs›Reference›Files Foreman writes

Files Foreman writes

Reference · page 5 of 6

The state folder, the env files, and what lives under ~/.config/foreman.

Foreman 0.11.04 sections

Foreman writes to four places: the state folder inside your project (.foreman/ by default), two env files at the project root, a folder under your home directory for sign-ins that must never sit in a repo, and each slot’s worktree. This page lists every path, what it holds and whether it is ever committed. Read it when you want to know what is safe to delete, what to back up, or what travels to another machine on the state branch. For the keys and settings themselves see foreman.config.json and Settings and switches.

“Committed?” means one of three things. Never: the file stays on this machine. State branch: when state.store is branch, the file moves to the state branch and is shared through your remote (see Run state on a branch); with the default files store it stays local. Your repo: the file is meant to be committed with your project.

.foreman

The state folder is <stateDir> in your project, .foreman/ unless the stateDir config key renames it. foreman init adds the folder to .gitignore when nothing ignores it yet, so none of it reaches your repo by accident. The environment variable FOREMAN_STATE_DIR overrides the location, which is how every slot’s worktree writes to the main checkout’s copy. Paths below are relative to that folder.

The run itself

Path What it holds Committed?
state.json The supervisor’s own state: the loop (running, standby, paused, halted, stopped), the worker count, recent results, stray process pids. State branch
control.json The owner’s controls: pause, resume, workers, next, fixed. Written by foreman pause and friends and by the dashboard. State branch
STOP One JSON line saying who asked the run to stop (foreman stop, the dashboard’s Stop, or a cloud runner’s signal). The supervisor takes it and removes it. State branch
last-stop The last STOP record, kept after the supervisor took it, so status can still say who stopped the run. State branch
HALT Present while a release failure holds the factory. Its text is the reason (cut to 300 characters when shown). foreman fixed clears it. See When things go wrong. State branch
service-stopped Left by foreman stop so a run started by the service manager waits for a plain foreman run. Holds the same stop record as STOP. Never
supervisor.pid The running supervisor’s pid, written at start and removed as it exits. Never
supervisor-adopted.json After a restart on new code: which earlier supervisor pids still stand for live sessions, so their locks are not treated as stale. Never
events.jsonl The live feed: one line per event, tagged with the slot. Everyone appends. State branch
status.json The last snapshot the console published; what foreman status reads. Never
schema-stories.json The ids of stories that were deferred because their plan needs an exclusive resource, so the picker treats them as needing the resource lock before it picks them again. State branch
claude-signin.json Whether sessions run on the Console API key or the subscription, since when and why. Never holds a key. State branch
settings.json The local settings layer: a flat object of setting name to value, this machine only. State branch
setup-checks.json The Set up tab’s cached check results, per machine, with checkedAt. Never
logs/supervisor.out The supervisor’s own output. Never
logs/<slot>-<time>.log One story session’s transcript as stream-json, one event per line (-2, -3 when a slot started twice in one second). Never
slots/<slot>.json One slot’s session: state, story, stage, heartbeat, result. State branch
slots/<slot>/agents/ Which agents run in that slot and what each is doing, from the agent hook. Never
slots/<slot>/spans.jsonl Each finished agent’s start and stop, for minutes per stage. Cleared per session. Never
slots/<slot>.install The hash of the install.when file at the last install, so npm ci runs only when the lockfile changed. Never
session-config/<slot>-settings.json, <slot>-mcp.json, <slot>-env.json What the supervisor passed a session: its settings, its MCP config and its exact environment, mode 600. foreman checks reads the env file to run in the session’s environment. Never
session-files/ Marks naming each slot’s live Claude session and its log, so a restarted supervisor finds the transcripts again. Never
sync/, sync.log The artifacts console’s work folder and the log of each push. Only with console.adapter: "artifacts". Never

Stories, decisions and locks

Path What it holds Committed?
stories/<id>.json The state overlay a story source keeps beside stories it must not edit: status, blockedBy, fields and dated notes. Always used for Jira and Salesforce stories; for markdown stories only with stories.track: "state". State branch
stories/new/<id>.md A follow-up story waiting to be added by a pull request (markdown source in state mode). Once the stories folder has a file with that id the waiting copy is deleted. State branch
stories/<id>.md Cached briefs the Salesforce story source writes from a Case, unless stories.briefsDir points elsewhere. Never
briefs/<id>.md Cached briefs for markdown stories. Never
jira/list.json The Jira poll cache: the last answer to the JQL. See Stories from Jira. Never
jira-outbox/<time>-<rand>.json Jira writes (comments, transitions, links) Jira did not take yet, replayed in order before the next write. State branch
salesforce/list.json The Salesforce Cases poll cache. See Stories from Salesforce. Never
salesforce-outbox/<time>-<rand>.json The same queue for Case comments and Status changes. Never
story-notes/pending/, story-notes/posted/ Notes Foreman will post on a story (design, review rounds, decisions) and the keys of those already posted, so none goes twice. Never
decisions/<id>.json One item per thing that waits on you: the question, its options, your answer and when it was applied. State branch
claims/<id>.json Which slot is building a story, or that you have taken it (“Taken by you”). State branch
locks/resource-<name>.json An exclusive resource’s holder. The schema resource keeps the older name locks/schema.json. State branch
locks/ship.json The ship lock: one release at a time, with the stage it reached. State branch
locks/release-watch.json One foreman release watch at a time. State branch
locks/file-<hash>.json One file’s holder, so two stories never change the same file. <hash> is the first 16 hex characters of the path’s sha256. State branch
locks/reserve-<hash>.json A freed file kept for the highest-priority story waiting on it. State branch
locks/keys.json The lock each key write holds. State branch
waits/<id>.json Why a story was deferred: the holders and files it waits on. State branch
parks/<id>.json A parked release: the step, the reason, the check that says whether it finished. State branch
plans/<id>.json, plans/<id>.md The architect’s plan as JSON, and its design and test plan as markdown for the agents to read. Never
checkpoints/<id>.json What a stopped session’s agents had finished, so the next session resumes from the last stage. Machine-local like the worktree it describes. Never
runs/<story>-<stamp>.json One run record per story session: result, cost, turns, minutes, rounds, stages, tokens per agent. foreman report reads them. State branch
check-runs.jsonl What foreman checks ran: one line per run, reuse or denied hand run. A cache local to this machine. Never
findings.jsonl Every tester and reviewer finding, one per line, written by foreman story end. State branch

Learning

Path What it holds Committed?
learn.json The foreman learn ledger: proposals made, ignored and applied. State branch
lessons.json The output of foreman learning scan, a derived file for the learner. Never
learning.jsonl The learning ledger: one line per change to a learned item, never rewritten. State branch
learned/traits/<role>.md A role’s learned traits, each tagged [L-n]. State branch
learned/skills/foreman-learned-<slug>/SKILL.md A learned skill. State branch
learned/.history/L-<n>/v<k>.md The text of each version of each learned item, written once. State branch
learner.jsonl The learner’s calls and spend, failed ones too, for the daily cap and foreman report. State branch
learning.lock, learning-tick.lock Held while the store changes and while a learning tick runs. Never

See How Foreman learns for what these mean.

Salesforce

The Salesforce pack is a preview: its release paths pass their own tests, but no story has yet shipped through them on a live org, and the Gearset path has not run against a live Gearset pipeline.

Path What it holds Committed?
salesforce/releases/<story>.json What a story’s release reached: the stages, the first deploy (what a rollback reverts), any rollback, any agents published. Never
salesforce/deployed/<stage>.json The last thing Foreman deployed to each stage. Never
salesforce/baseline/<alias>.json An org’s failing tests and coverage before any story touched it. Never
salesforce/deletes/<story>.json Your answer to a story’s metadata deletes, bound to the sha256 of the destructiveChanges.xml it was asked for. Never
salesforce/orgs/<org id>.json A sandbox pool record: which story last built on that org and on which branch. Never
salesforce/scratch/<story>.json The scratch org registry: a story’s org, its Dev Hub, username and state. Never
salesforce/agent-evals.json The Agentforce evaluation suite counter. Never

See Build orgs.

Worktrees

Path What it holds Committed?
worktrees/w<n> One git worktree per slot, detached at <remote>/<baseBranch>. A story’s work happens here. See Slots. Never

What moves to the state branch

With state.store: "branch", the state folder becomes a git worktree of an orphan branch, foreman-state by default (state.branch), that holds only Foreman’s run state and shares no history with your project. Only small state files go on it: the files marked “State branch” above, which are claims, locks, waits, decisions, story overlays and waiting follow-ups, parks, run records, slot records, the Jira outbox, control, settings, the learn ledger and findings, the learning ledger and learned items with their history, the learner’s spend, the supervisor’s state, who stopped the run, and which Claude sign-in the sessions use. The branch’s own .gitignore keeps out logs, worktrees, the sync folder, the Jira cache, session config, briefs, the outbox, cached story files, slot agent folders, status.json, temp and lock files, and anything named like an env file or a key. A file whose content looks like a token is refused and never committed, whatever its name. Nothing with a .tmp suffix or a secret-looking name is staged.

The first clone to use the store creates the branch and pushes it. Files already in the state folder move into the worktree once; where the branch already has a copy, the local one is kept aside as <stateDir>.local-<stamp>. Each foreman command that writes state pulls first and pushes after; one that fails to pull does not run. foreman cloud tick syncs once around a whole run and sets FOREMAN_STATE_SYNC=off for the run’s children. See Run state on a branch and Run in the cloud.

.env.foreman and the project env file

Two env files sit at the project root. Foreman’s own keys go in the file named by foremanEnvFile (.env.foreman). The project’s keys, the ones your build and tests need, go in the file named by envFile (.env.local). The two must not be the same file; foreman config check refuses that. Everything that reads one of Foreman’s names takes the process environment first, then .env.foreman, then the project env file.

Path What it holds Committed?
.env.foreman Foreman’s own keys and nothing else is read from it: JIRA_CLIENT_ID, JIRA_CLIENT_SECRET, RESEND_API_KEY, RESEND_FROM_EMAIL, FOREMAN_NOTIFY_EMAIL, FACTORY_NOTIFY_EMAIL, FOREMAN_DASHBOARD_TOKEN, GEARSET_API_TOKEN, ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN. Written only by foreman keys set and the Set up tab, through a temp file and a rename, left at mode 600. Never linked or copied into a slot, so the agents cannot read it. Of its names, only ANTHROPIC_API_KEY and CLAUDE_CODE_OAUTH_TOKEN reach a story session, in its environment. Never
.env.local (or your envFile) The project’s keys for its builds and tests. Linked into every slot worktree from the main checkout, so the builder, tester and reviewers can read it. Foreman writes a project key here when you set one that is not its own. Never
.env.runner For a container runner: FOREMAN_REPO and the other runner variables the Set up tab’s Cloud runner step writes, mode 600. The step adds it to .gitignore. Never
.gitignore foreman init adds the state folder. foreman keys set refuses to write a key file git does not ignore and offers to add it; the Set up tab’s fix does the same. Your repo

A key write refuses a file git already tracks, with no fix offered, and a file that is a link to somewhere git could commit. A key name set in the process environment cannot be changed by Foreman, and foreman keys says so. On a cloud runner, keys arrive as environment variables and are written to these same two files, .env.foreman after adding it to the clone’s .git/info/exclude when nothing ignores it; they are then removed from the environment the sessions get. See Notifications for the Resend names and Run in the cloud for the runner’s.

~/.config/foreman

Sign-ins that must never sit in a repo, an env file or a worktree live under your home directory. Story sessions are denied the Read tool on the Salesforce key folder, and the Salesforce Bash guard denies a command that names it.

Path What it holds Committed?
~/.config/foreman/jira-<site>.json The Jira OAuth tokens for one site, written by foreman jira login, mode 600 in a folder at mode 700. foreman jira logout deletes it. Never
~/.config/foreman/sf-home/ The isolated sf home the Salesforce pack signs orgs into, holding only the orgs in salesforce.orgs, so sessions never see your own sf logins. FOREMAN_SF_HOME overrides the location. Its .foreman/bin/ holds the sf and sfdx wrappers each session gets first on its PATH. Never
~/.config/foreman/sf/<project id>/server.key, server.crt The key pair Foreman signs in to Salesforce orgs with (JWT bearer), both mode 600 in a folder at mode 700. <project id> is the slug of project.name, a hyphen and 8 hex characters of the project path’s sha256. Never

The Salesforce entries are part of the pack preview described above. See Salesforce set-up for how the key and the isolated home are made.

In each slot

A slot is one git worktree under <stateDir>/worktrees/w<n>, where one story builds at a time. Besides the story’s own branch, Foreman puts these in it.

Path What it holds Committed?
<envFile> A symlink to the main checkout’s project env file, made when the worktree is created and the file exists. Not made when envFile names .env.foreman. Never
.claude/skills/foreman-learned-*/ Copies of Foreman’s learned skills in force, refreshed before each story when learning.apply is on. Foreman adds /.claude/skills/foreman-learned-* to the repo’s .git/info/exclude first, so a story commit never holds them. Folders skills-lock.json lists (pack skills) or without the prefix are never touched. Never
.claude/foreman/traits/all.md, <role>.md Your own project traits, read for every role or one. You write these; Foreman only reads them. Your repo
.agents/skills/<name>/, .claude/skills/<name>, skills-lock.json The Salesforce pack’s pinned skills: the files, a relative symlink to them, and the lock naming the source, tag and commit of each. Installed by foreman sf skills, in the layout the official npx skills CLI uses. Your repo
leftover/<slot>-<story>-<date> (a branch) When a story’s session ends with uncommitted work, Foreman commits it to this local branch (-2, -3 for a second one that day), then resets and cleans the folder. New key files are never committed to it. The branch is never pushed. Never
.github/workflows/foreman.yml The GitHub Actions workflow foreman cloud actions init writes, in the main checkout. An existing file is left alone unless --force. Your repo

Everything a session writes elsewhere goes to the state folder through FOREMAN_STATE_DIR, never to the slot. Claude Code’s own session transcripts live under ~/.claude/projects/ (or CLAUDE_CONFIG_DIR); Foreman reads them for each agent’s tokens and removes them when the session ends.