Chapter 5 · Runtime Layout: FM_HOME and Directory Conventions
Chapter goals: Master the FM_HOME mechanism and the responsibility division of the four private directories
data/,state/,config/,projects/; understand the boundary between tracked shared materials and gitignored私有 materials; learn to safely run multiple firstmate instances.
5.1 One Instance, One Home: What Is FM_HOME
The FirstMate code repository itself is the "distro," but each running firstmate instance needs its own operational home to store私有状态. The FM_HOME environment variable is this home's address:
- When unset: most scripts直接使用仓库根目录 as home;
- When set: scripts still run from this repo's
bin/, butstate/,data/,config/,projects/all读 from$FM_HOME.
This设计 lets "code" and "state"彻底分离: you can git pull to update the distro anytime without touching any instance's fleet records.
# Unset: repo root is home
cd firstmate && claude
# Set: state all falls under ~/fm-homes/main; code stays原地
FM_HOME=~/fm-homes/main claudeTwo配套 variables also exist: FM_ROOT_OVERRIDE replaces the firstmate repo根 used by scripts; FM_STATE_OVERRIDE, FM_DATA_OVERRIDE, FM_PROJECTS_OVERRIDE, FM_CONFIG_OVERRIDE can individually override one operational directory — mainly for testing and特殊 harness environments.
5.2 Responsibility Division of the Four Private Directories
configuration.md is the唯一权威定义 for the top-level layout. Four directories各有分工:
$FM_HOME/
├── data/ Persistent fleet archives: project & secondmate registries, captain preferences, learnings,
│ backlog, task briefs, scout reports
├── state/ Runtime records: task metadata, append-only state events, endpoint signals,
│ watcher & wake queue coordination, terminal-outcome receipts, away-mode state,
│ Relay-generated artifacts, secondmate pending-reply records etc.
├── config/ Local运营 choices (gitignored): backend selection, harness overrides etc.
└── projects/ Local project clones; firstmate read-only,
changes only发生 via Hard Rule 1's guarded exceptionsMemory trick: layer by lifecycle. data/ is the long-retention "archive room"; state/ is the ever-changing "duty log"; config/ is your "操作偏好面板"; projects/ is the borrowed "project bookshelf."
Scout任务产出 falls under data — e.g., a recon report at data/<id>/report.md — which explains why scout tasks don't produce PRs yet remain追溯.
5.3 Tracked Shared Materials vs Gitignored Private Materials
AGENTS.md划 the repo content into两泾渭分明的 categories. Shared tracked materials are part of the distro,随 git commit and update:
AGENTS.md / README.md / CONTRIBUTING.md Operations contract and docs
.tasks.toml Default backlog backend config
.github/workflows/ Shared CI and PR enforcement
bin/ Helper script toolbelt
.agents/skills/ firstmate internal skills
skills/ Standalone skills for public installersWhile the following paths属于 captain-private gitignored materials, never entering version control:
.env Optional Relay pairing token (LOCAL)
data/ Persistent fleet档案
state/ Runtime records
config/ Local运营选择
projects/ Local project clones
.no-mistakes/ no-mistakes pipeline local datafirstmate's write权限 differs for these two categories: it可以维护本仓库的私有运营状态; modifications to shared tracked materials must走 the repo's own no-mistakes pipeline and PR path — it obeys the same merge authority even toward itself.
5.4 fails-closed: fm-send.sh's Explicit FM_HOME Requirement
In多实例并存 scenarios, the biggest risk is "指令发错了家." To prevent this, bin/fm-send.sh is刻意 stricter than一般 scripts: it requires FM_HOME to be explicitly set before解析 targets; otherwise it fails closed — never silently falls back to the repo root. This guarantees a steer never quietly lands in the wrong home.
# Correct: explicitly specify home before sending steer
FM_HOME=~/fm-homes/main bin/fm-send.sh <id> 'Please add regression tests'
# Wrong示范: FM_HOME unset; fm-send.sh refuses to execute rather than guess
bin/fm-send.sh <id> 'hello' # fails closedAnother safety detail: fm-brief.sh, fm-spawn.sh, fm-afk-launch.sh resolve relative-form FM_HOME and override dirs to absolute paths before persisting or passing to other processes; unresolvable relative dirs are rejected with报错 naming which variable failed.
5.5 Practice: Building and Verifying an Independent Home
Below are the最小步骤 to create an运营之家脱离 the repo root and confirm the directory skeleton:
# 1. Create home directory (子directories生成 on first launch)
mkdir -p ~/fm-homes/main
# 2. Launch primary harness from the firstmate repo root, pointing at that home
cd /path/to/firstmate
FM_HOME=~/fm-homes/main claude
# 3. After让 firstmate执行 a small task, check what appeared in the home
ls ~/fm-homes/main
# data/ state/ config/ projects/If you need multiple并行 instances (e.g., one personal project, one work project),给各自独立的 FM_HOME:
FM_HOME=~/fm-homes/personal claude # Terminal A
FM_HOME=~/fm-homes/work claude # Terminal BNote: each secondmate also拥有自己持久隔离的 FM_HOME (with独立 state, backlog, projects, and session lock) — this is the物理基础 for the Secondmate mechanism in Chapter 14.
5.6 Chapter Summary
FM_HOMEselects一个 firstmate instance's operational home; when unset, repo root is used; when set,state/data/config/projectsall come from$FM_HOME;- Four directories layered by lifecycle:
data/persistent档案,state/runtime记录,config/local偏好,projects/read-only project clones; - Shared tracked materials随发行版走 git;
.env/data/state/config/projects/.no-mistakes/are captain-private gitignored materials; bin/fm-send.shrequires explicitFM_HOMEor fails closed —杜绝 steer落到错误 home; relative paths must resolve to absolute before persisting;- Multi-instance = multiple独立
FM_HOME; secondmates同样以独立 home实现隔离.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. When FM_HOME is explicitly set, how do scripts run?
2. Which of the following belongs to data/ rather than state/?
3. Why does bin/fm-send.sh require explicit FM_HOME?
4. Which组全部属于 captain-private gitignored materials?
🛠️ Hands-On Exercises
- Launch firstmate once with
FM_HOMEunset and once withFM_HOME=~/fm-homes/lab; dispatch a small task in each;对比 the出现位置 ofdata/andstate/;画 your machine's actual directory tree. - 故意 call
bin/fm-send.sh <id> 'ping'in a shell withoutFM_HOME; observe the failure behavior; then setFM_HOMEand retry;验证 the "fails closed" semantics. - Create independent homes for "personal" and "work" scenarios; dispatch不同项目 tasks to each; then
lsthe two homes'projects/to confirm克隆彼此隔离.
Layout understood. Next, session backends: tmux and experimental alternatives.