# How to Set Up FM_HOME and Manage the Firstmate Operational Home Layout

> Learn to set up FM_HOME, the environment variable for Firstmate's operational home directory. Manage state, data, and config in this essential guide for efficient workflow.

- Repository: [Kun Chen/firstmate](https://github.com/kunchenguid/firstmate)
- Tags: how-to-guide
- Published: 2026-08-13

---

**FM_HOME is the environment variable that defines the operational home directory where Firstmate stores mutable data (state/, data/, config/, projects/) while executing scripts from the immutable repository root.**

Setting up **FM_HOME** is essential for managing isolated operational environments in the kunchenguid/firstmate repository. This environment variable directs where the system stores mutable state, data, configuration, and project files, allowing you to separate active workspaces from the codebase. Understanding how to configure and switch between operational homes enables clean isolation for experiments, persistent second-mates, and reproducible sessions.

## Understanding the FM_HOME Operational Home Layout

When **FM_HOME** is unset, Firstmate defaults to legacy "whole-root" behavior, storing mutable directories directly in the repository root. According to [`AGENTS.md`](https://github.com/kunchenguid/firstmate/blob/main/AGENTS.md) (lines 50-52), this means `state/`, `data/`, `config/`, and `projects/` subdirectories live alongside the source code.

When **FM_HOME** is explicitly set, the scripts in `bin/` continue executing from the repository root, but all mutable data resolves under the custom path. As specified in [`docs/configuration.md`](https://github.com/kunchenguid/firstmate/blob/main/docs/configuration.md) (lines 191-200), this design keeps the codebase immutable while allowing flexible data placement.

## Variable Precedence and Override Behavior

The Firstmate environment follows a strict hierarchy for resolving operational paths. The precedence flows from most specific to least specific:

1. **FM_HOME** — The primary operational home directory
2. **FM_ROOT_OVERRIDE** — Fallback override for the entire root
3. **Repository root** — Default location when no overrides are set

Additionally, [`docs/turnend-guard.md`](https://github.com/kunchenguid/firstmate/blob/main/docs/turnend-guard.md) (lines 46-47) documents two granular overrides: **FM_STATE_OVERRIDE** and **FM_DATA_OVERRIDE** can redirect specific subdirectories while maintaining other paths under **FM_HOME**.

## Setting Up a Custom Firstmate Home

Creating an isolated operational home requires three steps:

1. Create a writable directory for your private data
2. Export the **FM_HOME** variable pointing to that directory
3. Execute Firstmate commands—the system will automatically generate the required subdirectories

```bash
mkdir -p ~/firstmate-home
export FM_HOME=~/firstmate-home

echo "Home root: $FM_HOME"
ls "$FM_HOME"

# → Firstmate will create state/, data/, config/, projects/ as needed

```

## Working with Second-Mate Homes

Each persistent **second-mate** requires its own isolated **FM_HOME** to maintain separate state, backlog, and session locks. As documented in [`AGENTS.md`](https://github.com/kunchenguid/firstmate/blob/main/AGENTS.md) (lines 50-52), this isolation prevents conflicts between concurrent operational contexts. Switching between second-mates is accomplished by changing the **FM_HOME** value before invoking commands, requiring no code modifications.

## Script-Specific Requirements and Bootstrap Handling

Certain scripts enforce stricter requirements for **FM_HOME** configuration. The [`bin/fm-send.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-send.sh) script explicitly requires **FM_HOME** to be set before execution to prevent steering commands to the wrong operational context, as noted in [`docs/configuration.md`](https://github.com/kunchenguid/firstmate/blob/main/docs/configuration.md) (lines 197-199).

During bootstrap operations, Firstmate injects the **FM_HOME** value specifically into generated Relay poll shims, while transient consumers retain their shell-relative behavior ([`docs/configuration.md`](https://github.com/kunchenguid/firstmate/blob/main/docs/configuration.md), lines 200-201).

## Practical Examples

The following examples demonstrate common workflows using custom operational homes.

Setting up and verifying a new home:

```bash
mkdir -p ~/my-firstmate-home
export FM_HOME=~/my-firstmate-home

echo "Home root: $FM_HOME"
ls "$FM_HOME"

# → should show (or create) state/ data/ config/ projects/

```

Sending a command to a running task:

```bash

# Assume a task id 12345 exists

FM_HOME=~/my-firstmate-home bin/fm-send.sh 12345 'status?'

```

Starting a new worker with the current home:

```bash
FM_HOME=~/my-firstmate-home bin/fm-brief.sh \
   --task-id new-task \
   --description "Run diagnostics on repo X"

```

Inspecting task state:

```bash
FM_HOME=~/my-firstmate-home bin/fm-crew-state.sh new-task

```

## Summary

- **FM_HOME** controls where Firstmate stores mutable data, separating operational state from source code
- When unset, mutable directories default to the repository root; when set, they resolve under the custom path
- Variable precedence follows: FM_HOME → FM_ROOT_OVERRIDE → repository root
- Specific subdirectories can be overridden using **FM_STATE_OVERRIDE** and **FM_DATA_OVERRIDE**
- Persistent second-mates require isolated **FM_HOME** directories to prevent state conflicts
- The [`bin/fm-send.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-send.sh) script requires explicit **FM_HOME** configuration to ensure correct routing

## Frequently Asked Questions

### What happens if FM_HOME is not set?

When **FM_HOME** is unset, Firstmate falls back to legacy "whole-root" behavior, placing all mutable directories (`state/`, `data/`, `config/`, `projects/`) directly in the repository root alongside the source code. This behavior is documented in [`AGENTS.md`](https://github.com/kunchenguid/firstmate/blob/main/AGENTS.md) (lines 50-52).

### Can I override specific subdirectories while using FM_HOME?

Yes. While **FM_HOME** sets the base operational home, you can redirect specific subdirectories using **FM_STATE_OVERRIDE** and **FM_DATA_OVERRIDE**. These variables take precedence over the paths derived from **FM_HOME**, as explained in [`docs/turnend-guard.md`](https://github.com/kunchenguid/firstmate/blob/main/docs/turnend-guard.md) (lines 46-47).

### Why does fm-send.sh require explicit FM_HOME?

The [`bin/fm-send.sh`](https://github.com/kunchenguid/firstmate/blob/main/bin/fm-send.sh) script enforces explicit **FM_HOME** configuration to prevent accidentally steering commands to the wrong operational context. This safety mechanism ensures that messages route to the correct task home, avoiding cross-contamination between isolated environments ([`docs/configuration.md`](https://github.com/kunchenguid/firstmate/blob/main/docs/configuration.md), lines 197-199).

### How do I switch between different operational homes?

Change the **FM_HOME** environment variable to point to a different directory and re-export it. The same Firstmate scripts can then operate on a completely separate operational context without any code changes, enabling rapid switching between projects or experimental setups.