Skip to content
This repository was archived by the owner on Aug 25, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ bin/fm-watch-arm.sh --restart # home-scoped forced restart; never a broad pkill
bin/fm-watch-session.sh start # durable home-scoped tmux runner for lanes without reliable tracked background tasks
bin/fm-watch-session.sh --status # report whether this home's runner window is live
bin/fm-watch.sh # the watcher itself; exits with: signal|stale|check|heartbeat
bin/fm-supervise.sh # read-only checklist/JSON view of current work; never mutates state, tmux, git, treehouse, or GitHub
bin/fm-wake-drain.sh # drain queued wake records at turn start; asserts guard after draining
bin/fm-crew-state.sh <id> # one-line current-state read; reconciles matching run-step, pane, and status log
```
Expand All @@ -510,6 +511,8 @@ On wake, in order of cheapness:
5. `heartbeat:` a heartbeat wake now reaches you only when the watcher's bash fleet-scan caught a captain-relevant status the per-wake path missed (no-change heartbeats are absorbed in bash, never surfaced), so treat it as "something turned up" and review the whole fleet: read each crewmate's current state with `bin/fm-crew-state.sh <id>` (the cheap first read - it reconciles the authoritative run-step over a possibly-stale status-log line, so a crewmate whose gate you already resolved no longer reads as still parked), peek panes that look off, check PR-ready tasks for merge, reconcile data/backlog.md, then re-arm the watcher.
Do not report that the fleet is unchanged.

When the picture is unclear or a display surface needs the shared decision model, run `bin/fm-supervise.sh` for a read-only checklist or `bin/fm-supervise.sh --json` for the `firstmate.supervision.v1` model. The command may report watcher proof as `unknown` when the current sandbox cannot see the watcher process; prove liveness with `bin/fm-watch-arm.sh` or `bin/fm-watch-session.sh --status` before treating that as an actual down watcher.

Heartbeats back off exponentially while they are the only wakes firing (600s doubling to a 2h cap - an idle fleet stops burning turns); any signal, stale, or check wake resets the cadence to the base interval.
Due per-task checks run before signal scanning so chatty crewmate status updates cannot starve slow polls like merge detection.

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ This is.. a directory that turns any agent into your firstmate, and you the capt
- **Explicit project modes** - each project ships via `no-mistakes`, `direct-PR`, or `local-only`, with an optional `+yolo` autonomy flag.
- **Optional secondmates** - opt in to persistent domain supervisors that run from isolated firstmate homes with their own `FM_HOME`, state, projects, and session lock, kept on the primary firstmate version by guarded local fast-forwards.
- **Event-driven, zero-token supervision** - a bash watcher sleeps on the fleet and wakes the first mate only when something needs you.
- **Read-only supervision view** - `bin/fm-supervise.sh` turns current state, tmux, git, watcher, and optional GitHub reads into a stable checklist or `firstmate.supervision.v1` JSON without changing anything.
- **Optional X mode** - opt in with one local `.env` token so firstmate can answer your public `@myfirstmate` mentions, act on normal reversible mention requests through the same lifecycle as chat requests, and report public-safe outcomes without changing non-X behavior; dry-run preview records would-be replies locally before go-live.
- **Guarded by construction** - the first mate is read-only over your projects outside guarded clone refreshes, safe branch pruning, and approved `local-only` fast-forward merges; crewmates make every project change behind your merge approval.
- **Restart-proof** - all state lives on disk and in tmux; kill the session anytime and the next one reconciles and carries on.
Expand Down Expand Up @@ -109,6 +110,7 @@ Outside tmux, crewmates land in a detached `firstmate` session you can attach to

You chat with the first mate.
It routes each request to a crewmate in its own tmux window and git worktree, supervises the fleet with a zero-token event-driven watcher, and brings you finished PRs, approved local merges, or investigation reports.
When the current fleet state is unclear, `bin/fm-supervise.sh` gives a passive read-only checklist, and `bin/fm-supervise.sh --json` exposes the same shared model for display tools such as Radar.
Persistent secondmate homes are linked firstmate worktrees; startup syncs live ones and secondmate launch syncs the target home to the primary default-branch commit without fetching from origin when it is safe.
When a routed request goes to a secondmate, firstmate marks it so the answer returns through status or a document pointer; direct typing into that secondmate window stays conversational.
A presence-gated sub-supervisor (`/afk`) can self-handle routine events and batch only what matters while you step away.
Expand Down
55 changes: 55 additions & 0 deletions bin/fm-supervise.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# Print a read-only Firstmate operational supervision checklist.
set -eu

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=bin/fm-supervision-model.sh
. "$SCRIPT_DIR/fm-supervision-model.sh"

MODE=text
INCLUDE_OK=0
DEFAULT_REMINDERS=1
EXTERNAL_PRS=""

while [ "$#" -gt 0 ]; do
case "$1" in
--text)
MODE=text
;;
--json)
MODE=json
;;
--schema)
MODE=schema
;;
--include-ok)
INCLUDE_OK=1
;;
--no-default-reminders)
DEFAULT_REMINDERS=0
;;
--external-pr)
shift
if [ "$#" -eq 0 ]; then
fm_supervision_usage >&2
exit 2
fi
EXTERNAL_PRS="${EXTERNAL_PRS:+$EXTERNAL_PRS }$1"
;;
--help|-h)
fm_supervision_usage
exit 0
;;
*)
fm_supervision_usage >&2
exit 2
;;
esac
shift
done

export FM_SUPERVISE_INCLUDE_OK="$INCLUDE_OK"
export FM_SUPERVISE_DEFAULT_REMINDERS_ENABLED="$DEFAULT_REMINDERS"
export FM_SUPERVISE_EXTERNAL_PRS="$EXTERNAL_PRS"

fm_supervision_collect_and_emit "$MODE"
Loading