diff --git a/.agents/skills/bootstrap-diagnostics/SKILL.md b/.agents/skills/bootstrap-diagnostics/SKILL.md index 3e6d4737132..8b4adfc9e99 100644 --- a/.agents/skills/bootstrap-diagnostics/SKILL.md +++ b/.agents/skills/bootstrap-diagnostics/SKILL.md @@ -2,7 +2,7 @@ name: bootstrap-diagnostics description: >- Agent-only handling playbook for session-start bootstrap diagnostics. - Use whenever the session-start digest's bootstrap section prints any diagnostic or capability line - MISSING, MISSING_MANUAL, BACKEND_INVALID, NEEDS_GH_AUTH, TANGLE, CREW_HARNESS_OVERRIDE, CREW_DISPATCH, FLEET_SYNC, SECONDMATE_SYNC, SECONDMATE_LIVENESS, TASKS_AXI, NUDGE_SECONDMATES, or FMX - or when a standalone bin/fm-bootstrap.sh run prints one. + Use whenever the session-start digest's bootstrap section prints any diagnostic or capability line - MISSING, MISSING_MANUAL, BACKEND_INVALID, ACCOUNT_ROUTING, NEEDS_GH_AUTH, TANGLE, CREW_HARNESS_OVERRIDE, CREW_DISPATCH, FLEET_SYNC, SECONDMATE_SYNC, SECONDMATE_LIVENESS, TASKS_AXI, NUDGE_SECONDMATES, REPORT_RETENTION, or FMX - or when a standalone bin/fm-bootstrap.sh run prints one. A silent bootstrap section means all good and needs no skill load. user-invocable: false metadata: @@ -22,6 +22,7 @@ The inline rules in `AGENTS.md` section 3 still bind: detect, then consent, then For `quota-axi`, bootstrap requires it because crew-dispatch `quota-balanced` may call it; `bin/fm-dispatch-select.sh` still degrades at runtime when quota data is unavailable. - `MISSING_MANUAL: (instructions: )` - tell the captain why the tool is required and give them the printed instructions URL, but do not pass the tool to `bin/fm-bootstrap.sh install`; wait for the captain to complete the manual installation, then rerun session start to confirm the dependency is present. - `BACKEND_INVALID: (known: )` - the resolved runtime backend has no verified dependency or lifecycle contract, so do not dispatch work until the invalid `FM_BACKEND` or `config/backend` value is corrected to one of the listed backends. +- `ACCOUNT_ROUTING: invalid routing policy - ` - the environment or `config/account-routing-mode` cannot resolve to exactly one of `off`, `observe`, or `enforce`; fix the reported source before dispatch because managed spawns will fail closed on the same policy error. - `NEEDS_GH_AUTH` - ask the captain to run `! gh auth login` (interactive; you cannot run it for them). - `TANGLE: ` - the primary checkout is stranded on a feature branch instead of its default branch; `AGENTS.md` section 8 explains why this guard exists and what it protects. The work is safe on that branch ref; restore the primary to its default branch with the printed `git -C checkout `, then re-validate that branch in a proper worktree. @@ -45,5 +46,7 @@ The inline rules in `AGENTS.md` section 3 still bind: detect, then consent, then - `NUDGE_SECONDMATES: fm-...` - the secondmate sweep fast-forwarded one or more *running* secondmate homes to firstmate's current version and their instruction surface (`AGENTS.md`, `bin/`, or `.agents/skills/`) actually changed; send a one-line re-read nudge with `FM_HOME= bin/fm-send.sh 'firstmate was updated to the latest - please re-read your AGENTS.md to pick up the new instructions.'` unless `FM_HOME` is already set to the active firstmate home. This mirrors `/updatefirstmate`'s `nudge-secondmates:` report: it is a gentle steer, never an interruption, and the fast-forward already landed safely. A secondmate that was skipped, already current, or whose advance changed no instructions is not listed and must not be disturbed. +- `REPORT_RETENTION: unavailable: ` - the machine-global report-retention LaunchAgent is absent, stale, unloaded, or has not reported a recent successful prune, so opportunistic bounded pruning remains available but post-minimum-age cleanup is not guaranteed to run while Firstmate is idle. + Surface the failure, wait for the captain's consent, then run `bin/fm-bootstrap.sh install report-retention`; never install or activate it without that consent. - `FMX: X mode on ...` / `FMX: X mode off ...` - bootstrap confirmed or removed the local X-mode poll artifacts (`docs/configuration.md` "X mode (.env)"). Only when a running watcher needs the cadence transition applied immediately, restart the home-scoped watcher through the emitted harness supervision protocol; bootstrap deliberately never restarts the watcher itself. diff --git a/.agents/skills/firstmate-orca/SKILL.md b/.agents/skills/firstmate-orca/SKILL.md index f8261cacdb1..1ab43b34094 100644 --- a/.agents/skills/firstmate-orca/SKILL.md +++ b/.agents/skills/firstmate-orca/SKILL.md @@ -1,6 +1,6 @@ --- name: firstmate-orca -description: Agent-only operator checklist for Firstmate's Orca runtime backend. Use when switching to Orca, spawning or supervising Orca-backed work, smoke-testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata. +description: Agent-only operator checklist for Firstmate's Orca runtime backend. Use when recovering or supervising eligible legacy Orca-backed work, testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata. user-invocable: false metadata: internal: true @@ -25,18 +25,19 @@ Use raw `orca` only when the helper surface cannot answer the inspection questio Work from the current firstmate home or repo root. If `FM_HOME` is set, remember that operational state lives under `$FM_HOME` while the helper scripts still run from this repo's `bin/`. -Before switching or spawning against Orca: +Before recovering a task onto Orca: -- Confirm Orca is intentionally selected through `--backend orca`, `FM_BACKEND=orca`, or local `config/backend`. -- Confirm the Orca app is running and the backend readiness checks pass before expecting spawn to work. +- Confirm the task meets the eligibility contract in `docs/orca-backend.md`; new work must use tmux, Herdr, zellij, or cmux. +- Confirm Orca is intentionally selected for this eligible recovery through `--backend orca` or `FM_BACKEND=orca`. +- Confirm the Orca app is running and the backend readiness checks pass before expecting the respawn to work. - Inspect active `state/*.meta` records before changing backend selection. -- Treat a backend switch as affecting future spawns only; existing tasks keep their recorded backend. +- Do not set Orca as the durable backend for a home that launches new tasks. - Reconcile watcher wakes before unrelated work, especially if Orca tasks are already in flight. ## Spawn -Use `bin/fm-spawn.sh` so firstmate creates the brief, worktree, terminal, metadata, status file, and watcher surface together. -Pass `--backend orca` for a one-off Orca task, or rely on the already-selected Orca backend when that selection is intentional. +Use `bin/fm-spawn.sh` for an eligible pre-cutover respawn so firstmate creates the worktree, terminal, metadata, status file, and watcher surface together. +New task spawns refuse `backend=orca` before any owned mutation; `docs/orca-backend.md` owns the rationale and exact legacy eligibility rule. After spawn, check the task with firstmate helpers: @@ -45,7 +46,7 @@ After spawn, check the task with firstmate helpers: - `bin/fm-crew-state.sh ` when the current run state matters. - `bin/fm-watch.sh` whenever there are tasks in flight and this session owns supervision. -Do not manually create the Orca worktree or terminal for a normal firstmate task. +Do not manually create the Orca worktree or terminal for an eligible firstmate recovery. Do not manually patch metadata to make an externally-created Orca terminal look like a firstmate task. ## Supervision @@ -73,19 +74,18 @@ For a messy Orca-backed task: 5. Avoid raw deletion of Orca worktrees or manual branch cleanup. 6. Stop and inspect if the recorded worktree path, Orca worktree id, or project checkout no longer matches expectations. -Teardown remains governed by the normal firstmate landing rules. -Scout work can be torn down after the report exists. -Ship work can be torn down only after the work is landed by its project mode. +Teardown remains governed by `docs/orca-backend.md`'s eligible legacy task contract; follow its report and landing rules exactly. -## Smoke Test +## Regression Verification -Keep Orca smoke tests focused on lifecycle plumbing: +Do not synthesize legacy metadata or spawn a disposable Orca task merely to smoke-test the backend. +Run the focused fake-Orca suite in `docs/orca-backend.md` to verify lifecycle plumbing. +When an actual eligible legacy recovery is already required, verify it through the normal lifecycle: -1. Select Orca intentionally for a disposable task or scout. -2. Spawn through `bin/fm-spawn.sh`. +1. Confirm the task metadata has no `report_required` marker and select Orca for that recovery. +2. Respawn through `bin/fm-spawn.sh`. 3. Confirm metadata records the Orca backend, terminal, Orca worktree id, and isolated worktree path. 4. Verify `bin/fm-peek.sh`, a short `bin/fm-send.sh` steer, watcher wake behavior, and `bin/fm-crew-state.sh`. 5. Tear down through `bin/fm-teardown.sh` after the task is safely disposable or landed. -6. Restore the previous backend selection if Orca was selected only for the smoke test. -Do not mix a backend smoke test with unrelated feature work. +Do not mix adapter verification with unrelated feature work. diff --git a/.agents/skills/fmx-respond/SKILL.md b/.agents/skills/fmx-respond/SKILL.md index 02502827b76..22e55378979 100644 --- a/.agents/skills/fmx-respond/SKILL.md +++ b/.agents/skills/fmx-respond/SKILL.md @@ -139,7 +139,7 @@ Treat `state/x-inbox/` as the source of truth and process **every** file you fin **Destructive, irreversible, or security-sensitive work is the exception** (X mode is a public, relayed channel and does not carry full in-session trust): do not execute it from the mention. Flag it to the captain through the normal trusted channel first - the same carve-out as `yolo` (AGENTS.md §1, §7) - act only on the captain's word, and in step 2d say only that it has been flagged for the captain. **If the request spawned a real, longer-running task** (you ran `bin/fm-spawn.sh`), link that task to this mention so milestone and completion follow-ups can be posted: `bin/fm-x-link.sh `. **Link here, in step 2c, before the step 2f inbox cleanup** - `bin/fm-x-link.sh` can copy both the mention's reply platform and explicit budget from the still-present inbox payload without a relay lookup. - If that local context is incomplete it uses the durable resolution contract in `docs/configuration.md` and warns loudly, while the follow-up path refuses to post unless both values can be resolved authoritatively. + If that local context is incomplete it uses the durable resolution contract in `docs/configuration.md` and warns loudly, while the follow-up path proceeds when either the platform or a valid explicit budget of at least 50 characters is resolved authoritatively and refuses only when neither is available. Then step 2d's reply is an **acknowledgement** ("on it, captain"), and genuine milestone updates plus the final outcome come later as follow-ups (see "Completion follow-up" below), with the terminal one posted using `--final`. If the work completed in this turn (a backlog item filed, a question answered), there is no task to link and step 2d reports the outcome directly. d. **Compose the reply.** For a **question**, answer `.text` from the fleet state gathered in step 1. For an **actionable request that completed now**, report the outcome of step 2c (what was done, or - for escalated work - that it has been flagged for the captain). For an **actionable request that spawned a linked task**, acknowledge that you have the order and are on it - milestone updates and the final outcome follow later as completion follow-ups, so do not promise a result you do not yet have. Either way keep it short, in firstmate's voice, and public-safe. @@ -199,7 +199,8 @@ This skill's own responsibility during the mention-handling turn is linking the When the update carries one real visual artifact, add `--image `; the helper forwards it to `bin/fm-x-reply.sh --followup` so the same image contract used for ordinary replies applies here too. - On a terminal wake (PR merged / scout report / local merge / failed), firstmate posts the task's **final** outcome ("done, here's the result"; for a failure, an honest "this one didn't pan out") with `bin/fm-x-followup.sh --final --text-file `, which always clears the link after that post regardless of how many follow-ups remain under the cap. - Every follow-up is held to the exact same public-safety bar as every reply here: outcomes only, no task ids, internals, captain-private material, or secrets. Past the window, past the cap, or on the relay's own rejection of an exhausted binding, a follow-up attempt is skipped silently and the link is cleared - never treated as a failure worth retrying. -- If either a follow-up's platform or explicit budget cannot be authoritatively resolved from per-request context, inbox payload, or relay answer, `bin/fm-x-followup.sh` does NOT post it: the fail-safe holds it (the link is kept, exit non-zero) rather than use a local default. This is a retryable hold - a later milestone wake retries it once both values are recoverable. +- If neither a follow-up's platform nor a valid explicit budget of at least 50 characters can be authoritatively resolved from per-request context, inbox payload, or relay answer, `bin/fm-x-followup.sh` does NOT post it: the fail-safe holds it (the link is kept, exit non-zero) rather than use a local default. + This is a retryable hold - a later milestone wake retries it once either value is recoverable. ## Notes diff --git a/.agents/skills/reports/SKILL.md b/.agents/skills/reports/SKILL.md new file mode 100644 index 00000000000..9c6c4b67e98 --- /dev/null +++ b/.agents/skills/reports/SKILL.md @@ -0,0 +1,22 @@ +--- +name: reports +description: Browse, search, open, or summarize Firstmate's durable completion report stack. Use when the captain asks what Firstmate or its crews finished, wants a completion report or visual evidence, asks to review recent work, or invokes /reports. +user-invocable: true +metadata: + internal: true +--- + +# Completion reports + +Use `bin/fm-report-stack.mjs` from the Firstmate installation that loaded this skill. + +Run `bin/fm-report-stack.mjs open` to regenerate and open the searchable offline stack. +Run `bin/fm-report-stack.mjs list` for a concise inventory, or add `--json` when structured filtering or summarization is needed. +Run `bin/fm-report-stack.mjs path ` to locate one report without opening it. +Run `bin/fm-report-stack.mjs open ` to open one report directly. + +When the captain asks for a summary in chat, read the selected entry's `manifest.json` and `report.md`, then summarize the outcome, verification, visual evidence, and follow-ups. +Do not inspect provider account homes or raw session state for report browsing. +Treat the report stack as the durable completion ledger and the source task state as volatile. + +Read `docs/report-stack.md` only when diagnosing publication, explaining the storage contract, or intentionally publishing a pre-cutover task. diff --git a/.agents/skills/reports/agents/openai.yaml b/.agents/skills/reports/agents/openai.yaml new file mode 100644 index 00000000000..9151db11dae --- /dev/null +++ b/.agents/skills/reports/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Completion Reports" + short_description: "Browse completed Firstmate task reports" + default_prompt: "Use $reports to open and summarize the Firstmate report stack." diff --git a/.agents/skills/secondmate-provisioning/SKILL.md b/.agents/skills/secondmate-provisioning/SKILL.md index c8febd24d1e..1cf5920bf60 100644 --- a/.agents/skills/secondmate-provisioning/SKILL.md +++ b/.agents/skills/secondmate-provisioning/SKILL.md @@ -3,7 +3,7 @@ name: secondmate-provisioning description: >- Agent-only reference for persistent secondmate setup and retirement. Use when creating, seeding, validating, launching, recovering, handing backlog to, pushing inherited config into, or retiring a secondmate home, or when editing data/secondmates.md. - Covers home leases, transactional seeding, project clone restrictions, secondmate harness pins, inherited config push, idle charter, handoff helper, and teardown safety. + Covers home leases, transactional seeding, project clone restrictions, secondmate harness and account-pool pins, inherited config push, idle charter, handoff helper, and teardown safety. user-invocable: false metadata: internal: true @@ -71,14 +71,19 @@ When the file's tokens do apply, an explicit per-spawn `--model` or `--effort` f Because this resolves from the file on every spawn, the pin is durable across every respawn (recovery, `/updatefirstmate`, restart) exactly like the harness axis itself - e.g. `config/secondmate-harness` containing `claude opus` keeps a secondmate pinned to Opus even if the primary's own default model later changes. This is secondmate-only: crewmate/scout model resolution is untouched by this file. +`config/secondmate-account-pool` is the primary's optional Agent Fleet pool for launching secondmate agents when account routing is already enabled. +The file contains one non-secret dynamic pool id, is re-read on every spawn, and does not activate account routing by itself. +An explicit `--account-pool` or `--account-profile` overrides it for that spawn, and an explicit profile without a pool is never constrained by this file. +This pool is not inherited into the secondmate home because it governs the primary's secondmate launch, while `config/account-routing-mode` is inherited so the secondmate applies the same off/observe/enforce policy to its own crewmates. + This section is the single owner of the secondmate sync and inheritable-config propagation contract; `AGENTS.md` sections 3 and 4 point here. Before launch, `fm-spawn.sh --secondmate` locally fast-forwards the home to the primary firstmate checkout's current default-branch commit when it is safe; dirty, diverged, or in-flight homes launch unchanged with a warning. The locked session-start bootstrap sweep runs the same guarded fast-forward for every live secondmate home, discovered from `state/.meta` records with `kind=secondmate` (`data/secondmates.md` only backfills `home=` for older records). That no-fetch path is a purely local fast-forward of tracked files, never an origin fetch, and it never touches the gitignored operational dirs, so a secondmate's backlog, projects, and in-flight work are never disturbed; a linked worktree advances immediately, while a standalone clone that lacks the target receives firstmate updates through `/updatefirstmate`'s origin refresh. -The same launch and the same locked bootstrap sweep also propagate the primary's declared inheritable local config, currently `config/crew-dispatch.json`, `config/crew-harness`, and `config/backlog-backend`, into the secondmate home's `config/`. +The same launch and the same locked bootstrap sweep also propagate the primary's declared inheritable local config, currently `config/crew-dispatch.json`, `config/crew-harness`, `config/backlog-backend`, and `config/account-routing-mode`, into the secondmate home's `config/`. Because `config/` is gitignored, that propagation is a separate, primary-authoritative copy independent of the tracked-files fast-forward: it re-converges every live home whether or not its tracked files advanced, and it touches only the declared items. Inheritance copies the literal `config/crew-harness` file, so a secondmate's own crewmates use the primary's crewmate harness only when it names a concrete adapter such as `codex`; an unset or `default` value has nothing concrete to inherit, and the secondmate's own crewmates fall back to the secondmate's own or detected harness instead. -`config/secondmate-harness` is not inherited because it is only the primary's knob for launching secondmate agents. +`config/secondmate-harness` and `config/secondmate-account-pool` are not inherited because they are only the primary's knobs for launching secondmate agents. No reread nudge is needed at spawn or respawn because the agent reads `AGENTS.md` fresh on launch; only the bootstrap sweep's `NUDGE_SECONDMATES:` case (a RUNNING home whose instruction surface advanced) needs one. For already-live secondmates, use `bin/fm-config-push.sh` to push a mid-session inherited-config change without running the tracked-file fast-forward or nudging the agents. It uses the same live-home discovery and propagation helper as bootstrap and reports each item as `pushed`, `unchanged`, `skipped`, or `error`. @@ -118,7 +123,15 @@ Do not hand off `local-only` items. ## Recovery -For `kind=secondmate` meta with no window, treat the secondmate as a dead persistent direct report and respawn it with: +For managed `kind=secondmate` meta with `account_profile=`, preserve the sticky account and provider session by recovering it with: + +```sh +bin/fm-spawn.sh --resume-account +``` + +This path requires the recorded Agent Fleet SessionStart mapping and uses `lease recover` rather than new-task quota selection. +If exact native resume is unavailable, recover the same task under a fresh Claude or Codex profile with `bin/fm-spawn.sh --continue-account` after re-verifying the endpoint is dead; `bin/fm-account-continuation.sh` owns the provider-neutral packet and fail-closed state checks. +For unmanaged `kind=secondmate` meta with no window, treat the secondmate as a dead persistent direct report and respawn it with: ```sh bin/fm-spawn.sh --secondmate @@ -126,7 +139,7 @@ bin/fm-spawn.sh --secondmate Use the recorded `home=` in meta. If meta is missing but `data/secondmates.md` still registers the secondmate, respawn from the registry entry and its persistent on-disk home. -Respawn re-resolves the secondmate harness from current config, uses the same guarded pre-launch sync, and re-propagates inheritable config, so recovered secondmates converge to the primary firstmate version and local dispatch, crew-harness, and backlog-backend settings whenever their home can be cleanly fast-forwarded. +Respawn re-resolves the secondmate harness from current config, uses the same guarded pre-launch sync, and re-propagates inheritable config, so recovered secondmates converge to the primary firstmate version and local dispatch, crew-harness, backlog-backend, and account-routing settings whenever their home can be cleanly fast-forwarded. If the secondmate is already running and only inherited config changed, prefer `bin/fm-config-push.sh` over respawning. Do not reconstruct a secondmate's whole tree from the main home. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a75d82d3bf2..15511f7f5d7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,9 +27,10 @@ jobs: tests: name: Behavior tests runs-on: ubuntu-latest - # The suite should finish in ~2-3 minutes; this generous cap fails loudly on a - # hung watcher or tmux test instead of riding GitHub's 360-minute default. - timeout-minutes: 15 + # The complete suite now takes roughly 16 minutes on ubuntu-latest. Keep a + # bounded cap that accommodates healthy growth while still failing loudly + # on a genuinely hung watcher or tmux test. + timeout-minutes: 30 steps: - uses: actions/checkout@v6 with: diff --git a/.gitignore b/.gitignore index 5ed2da0c32a..09d38e81ac4 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ __pycache__/ .env config/crew-harness config/crew-dispatch.json +config/account-routing-mode +config/secondmate-account-pool config/secondmate-harness config/backlog-backend config/backend diff --git a/AGENTS.md b/AGENTS.md index 6cbeb6b98c5..7b822ad814d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,7 +34,7 @@ Hard rules, in priority order: `bin/fm-teardown.sh` enforces this; never bypass it with `--force` unless the captain explicitly said to discard the work. Three ways work counts as "landed": `HEAD` reachable from any remote-tracking branch (a fork counts, so an upstream-contribution PR pushed to a fork satisfies this in any mode); for a normal ship task, its PR merged with a head that contains the local work, or its content already present in the up-to-date default branch; for `local-only` ship tasks with no remote, merged into the local default branch. Uncommitted changes are never landed. - The scout carve-out: a scout task's worktree is declared scratch from the start - its deliverable is the report, and teardown lets the worktree go once that report exists (section 7). + The scout carve-out: a scout task's worktree is declared scratch from the start - its deliverable is the report, and teardown lets the worktree go once the applicable report contract is satisfied (section 7; `docs/report-stack.md`). The full PR-containment mechanics and the `pr=` discovery fallback are owned by `bin/fm-teardown.sh`'s header, not restated here. 4. **Crewmates never address the captain.** All crewmate communication flows through you. @@ -77,8 +77,10 @@ bin/ helper scripts, committed; read each script's header before config/crew-harness crewmate harness override; LOCAL, gitignored; absent or "default" = same as firstmate. Inherited as the literal file: a concrete primary adapter value also controls a secondmate home's own crewmates (section 4) config/crew-dispatch.json optional crewmate dispatch profiles; LOCAL, gitignored; firstmate-maintained but human-editable natural-language rules that choose a per-task harness/model/effort profile (section 4). Inherited by secondmate homes config/secondmate-harness harness the PRIMARY uses to launch SECONDMATE agents, optionally followed by a model and effort token on the same line (" [] []"; section 4); LOCAL, gitignored; absent or "default" harness falls back to config/crew-harness then firstmate's own. The primary's own setting; NOT inherited into secondmate homes (secondmates do not spawn secondmates) +config/account-routing-mode optional Agent Fleet routing policy (`off`, `observe`, or `enforce`); LOCAL, gitignored; default off; inherited by secondmate homes (docs/configuration.md "Agent Fleet account routing") +config/secondmate-account-pool optional Agent Fleet pool the PRIMARY uses for SECONDMATE launches when routing is enabled; LOCAL, gitignored; selection-only and NOT inherited config/backlog-backend backlog backend override; LOCAL, gitignored; absent or "tasks-axi" = default tasks-axi backend, "manual" = force routine backlog updates to hand-editing; inherited by secondmate homes (section 10) -config/backend runtime session-provider backend override for new tasks; LOCAL, gitignored; absent = falls through to runtime auto-detection (the runtime firstmate itself is executing inside), then tmux; tmux is the verified reference backend (docs/tmux-backend.md), while herdr, zellij, orca, and cmux are experimental spawn backends (docs/herdr-backend.md, docs/zellij-backend.md, docs/orca-backend.md, docs/cmux-backend.md) - herdr and cmux can also be selected by runtime auto-detection, zellij and orca never are (always explicit), and codex-app is not accepted; see docs/codex-app-backend.md; not inherited into secondmate homes +config/backend runtime session-provider backend override for new tasks; LOCAL, gitignored; absent = falls through to runtime auto-detection (the runtime firstmate itself is executing inside), then tmux; tmux is the verified reference backend, herdr/zellij/cmux are experimental new-task spawn backends, and Orca is legacy-recovery-only (docs/tmux-backend.md, docs/herdr-backend.md, docs/zellij-backend.md, docs/orca-backend.md, docs/cmux-backend.md) - herdr and cmux can also be selected by runtime auto-detection, zellij and Orca never are (always explicit), and codex-app is not accepted; see docs/codex-app-backend.md; not inherited into secondmate homes config/cmux-socket-password optional cmux control-socket password; LOCAL, gitignored; read fresh on every cmux CLI call and passed through without ever overriding an operator's own ambient CMUX_SOCKET_PASSWORD when absent (docs/cmux-backend.md "Setup") config/wedge-alarm optional away-mode wedge-alarm active-alert directives; LOCAL, gitignored; absent means auto (macOS Notification Center when available); see docs/wedge-alarm.md config/x-mode.env generated X-mode watcher cadence; LOCAL, gitignored; source before arming watcher when present @@ -90,12 +92,14 @@ data/ personal fleet records; LOCAL, gitignored as a whole secondmates.md secondmate routing table; firstmate-private, maintained by fm-home-seed.sh (section 6) /brief.md per-task crewmate brief, or per-secondmate charter brief when kind=secondmate /report.md scout task deliverable, written by the crewmate; survives teardown + /completion.md ship task completion report, published to the machine-global report stack through fail-closed teardown + /visuals/ optional screenshots and diagrams copied into that durable completion report projects/ cloned repos; gitignored; READ-ONLY for you state/ volatile runtime signals; gitignored .status appended by crewmates: ": " wake-event lines, not current-state truth .turn-ended touched by turn-end hooks .grok-turnend-token firstmate-owned grok hook registry token for the task; removed by teardown - .meta written by fm-spawn: window=, worktree=, project=, harness=, model=, effort=, kind=, mode=, yolo=, tasktmp=; kind=secondmate also records home= and projects=; a non-default runtime backend records further backend-specific fields (docs/configuration.md "Runtime backend"; bin/fm-backend.sh, section 8); fm-pr-check, including through fm-pr-merge, appends pr= and GitHub's pr_head= when available; fm-x-link appends x_request=, x_request_ts=, x_followups=, and optional x_platform=/x_reply_max_chars= for an X-mode-originated task (section 14) + .meta written by fm-spawn: window=, worktree=, project=, harness=, model=, effort=, kind=, mode=, yolo=, tasktmp=, generation_id=, report_required=; managed tasks add account_pool=, account_profile=, account_task=, account_attempt=, and provider_session_id= (docs/configuration.md "Agent Fleet account routing"); kind=secondmate also records home= and projects=; a non-default runtime backend records further backend-specific fields (docs/configuration.md "Runtime backend"; bin/fm-backend.sh, section 8); fm-pr-check, including through fm-pr-merge, appends pr= and GitHub's pr_head= when available; fm-x-link appends x_request=, x_request_ts=, x_followups=, and optional x_platform=/x_reply_max_chars= for an X-mode-originated task (section 14) .check.sh optional slow poll you write per task (e.g. merged-PR check) x-watch.check.sh generated X-mode relay poll shim; present only when opted in (section 14) x-inbox/ generated X-mode pending mention payloads; fmx-respond drains it (section 14) @@ -127,7 +131,7 @@ It composes today's `fm-lock.sh`, `fm-bootstrap.sh`, and `fm-wake-drain.sh` - ca 1. **Lock** - acquires the per-home session lock first, before anything mutates shared state. 2. **Bootstrap** - detect-only diagnostics (tool/version problems, GitHub auth, the worktree-tangle check, harness override, dispatch-profile validation, backlog-backend status) always run and always print. When the lock could not be acquired, the worktree-tangle check uses read-only advisory wording without a checkout repair command. - The four MUTATING sweeps - fleet sync, the local secondmate fast-forward sweep, the secondmate liveness sweep, and X-mode artifact writes - run only when this session actually holds the lock from step 1. + The five MUTATING sweeps - report-retention ownership, fleet sync, the local secondmate fast-forward sweep, the secondmate liveness sweep, and X-mode artifact writes - run only when this session actually holds the lock from step 1. The secondmate liveness sweep deterministically guarantees every registered secondmate is actually running: it probes each live secondmate's endpoint for a real agent process (not just pane presence) and respawns only on a confident dead reading, reported as `SECONDMATE_LIVENESS:` lines (`bin/fm-bootstrap.sh`; `bin/fm-backend.sh`'s `fm_backend_agent_alive`). 3. **Wake queue** - when locked, drains the durable wake queue and prints the records prominently as this turn's first work queue, exactly as `bin/fm-wake-drain.sh` did before; a lapsed watcher chain still surfaces here via the same guard banner. When the lock could not be acquired, the queue is left untouched because another session owns it, and the guard's tangle/watcher-liveness alarms still print in read-only advisory mode without drain, supervision repair, or checkout repair commands. @@ -191,7 +195,7 @@ Pick the single best-fit rule using your own judgment. This is explicitly not first-match: weigh all rules, their `when` text, and their `why` rationales against the actual task. For a chosen rule with a single-object `use`, or an array `use` with no `select`, resolve the first profile directly. For a chosen rule with `select: "quota-balanced"`, pipe the full rule JSON to `bin/fm-dispatch-select.sh` and use the compact JSON profile it prints. -Extract that chosen concrete profile `(harness, model, effort)` and pass it to `bin/fm-spawn.sh` with explicit `--harness`, `--model`, and `--effort` flags for the axes that are set. +Extract that chosen concrete profile `(harness, model, effort, account_pool, account_profile)` and pass it to `bin/fm-spawn.sh` with explicit `--harness`, `--model`, `--effort`, `--account-pool`, and `--account-profile` flags for the axes that are set. If no rule fits, use `default`. If `default` is absent, fall back to `config/crew-harness` through `bin/fm-harness.sh crew`, exactly as the static path did before dispatch profiles, but still pass that resolved harness explicitly. This is enforced: when `config/crew-dispatch.json` exists, `bin/fm-spawn.sh` refuses crewmate and scout launches that do not include an explicit harness (`--harness `, a positional adapter name, or a raw launch command). @@ -199,7 +203,8 @@ That refusal is the consultation backstop, so the rules are never silently skipp The requirement is gated only on the file's presence; when the file is absent, `fm-spawn.sh` keeps resolving the crewmate harness from `config/crew-harness` as before. Secondmate launches are exempt because they resolve through `fm-harness.sh secondmate`, not the crewmate dispatch-profile rules. -`quota-balanced` selection is deterministic and owned by `bin/fm-dispatch-select.sh`; its header documents the general-window rules, freshness margin, and every fallback, and it degrades to the first array element whenever quota data is unusable. +`quota-balanced` selection is deterministic and owned by `bin/fm-dispatch-select.sh`; its header documents the general-window rules, Agent Fleet pool-summary path, freshness margin, and every fallback, and it degrades to the first array element whenever quota data is unusable. +When candidates carry account pools, the selector uses only Agent Fleet summaries and never falls through to quota-axi's default-account data; pass its selected pool to spawn for the atomic concrete-profile lease. Quota trouble must never block dispatch. Precedence, highest first: @@ -222,7 +227,7 @@ An explicit per-spawn harness still overrides either kind, and every secondmate `config/secondmate-harness` can also pin a model/effort for the secondmate agent in one line (` [] []`); format, accessors, and inheritance exceptions live in `secondmate-provisioning` (load before creating/seeding/launching/recovering a secondmate). -`config/crew-dispatch.json`, `config/crew-harness`, and `config/backlog-backend` are inherited into every secondmate home; `config/secondmate-harness` is not, because secondmates never spawn secondmates. +`config/crew-dispatch.json`, `config/crew-harness`, `config/backlog-backend`, and `config/account-routing-mode` are inherited into every secondmate home; `config/secondmate-harness` and `config/secondmate-account-pool` are primary-owned launch knobs and are not inherited. `secondmate-provisioning` owns the propagation timing, mechanism, the literal-file inheritance nuance, and `bin/fm-config-push.sh`. Each adapter splits into mechanics and knowledge. @@ -246,8 +251,9 @@ Reconcile reality with your records before doing anything else, working from the Do not sweep every `fm-*` tmux window, herdr tab, zellij tab, Orca terminal, or cmux workspace across all sessions during recovery; another firstmate home's child endpoints may share that namespace and are not this home's orphans. 5. If the digest reports a recorded direct-report's endpoint as `dead` (or a meta has no `window=`), reconcile it through its meta as described below. 6. For meta with no window, or an endpoint the digest reported dead, reconcile by kind. + If meta records `account_profile=`, first try the exact sticky session with `bin/fm-spawn.sh --resume-account`; when that session/profile is unavailable, use `--continue-account` for the task-owned provider-neutral handoff after re-verifying live and repository state, with `bin/fm-account-continuation.sh` owning the fail-closed packet contract. For ordinary crewmates, check the recorded backend metadata first; use `treehouse status` for treehouse-backed tasks, and the recorded `orca_worktree_id=`/`terminal=` for Orca tasks. - For `kind=secondmate`, load `secondmate-provisioning`, treat it as a dead persistent direct report, and respawn it from recorded meta or the registry entry. + For an unmanaged `kind=secondmate`, load `secondmate-provisioning`, treat it as a dead persistent direct report, and respawn it from recorded meta or the registry entry. 7. Do not reconstruct a secondmate's whole tree from the main home. The main firstmate reconciles only direct reports. Each secondmate is a firstmate in its own home, so it reconciles only work that is already its own and then idles; it never creates new work during recovery. @@ -416,13 +422,17 @@ Load `harness-adapters` before spawning or recovering any direct report so trust ```sh bin/fm-spawn.sh projects/ # uses the active crewmate harness only when no crew-dispatch.json is active bin/fm-spawn.sh projects/ --harness codex --model gpt-5.5 --effort high # explicit profile axes -bin/fm-spawn.sh projects/ --backend # explicit runtime backend (docs/configuration.md "Runtime backend") +bin/fm-spawn.sh projects/ --harness codex --account-pool codex-crew # dynamic Agent Fleet account pool +bin/fm-spawn.sh projects/ --harness claude --account-profile claude-2 # explicit Agent Fleet profile +bin/fm-spawn.sh --resume-account # sticky managed recovery; never a fresh prompt +bin/fm-spawn.sh --continue-account # fresh managed session from verified task-owned continuation state +bin/fm-spawn.sh projects/ --backend # explicit new-task runtime backend (docs/configuration.md "Runtime backend") bin/fm-spawn.sh projects/ --scout # scout task; records kind=scout in meta bin/fm-spawn.sh [] --secondmate # launch or recover a persistent secondmate in its home bin/fm-spawn.sh =projects/ =projects/ [--scout] # batch: one call, several tasks ``` -Batch dispatch spawns each `id=repo` pair through the same single-task path, with shared `--scout`, `--harness`, `--model`, `--effort`, and `--backend` flags applying to all; one failed pair does not stop the rest, and the batch exits non-zero. +Batch dispatch spawns each `id=repo` pair through the same single-task path, with shared `--scout`, `--harness`, `--model`, `--effort`, `--backend`, `--account-pool`, `--account-profile`, and `--no-account-routing` flags applying to all; one failed pair does not stop the rest, and the batch exits non-zero. When `config/crew-dispatch.json` exists, include an explicit resolved harness for every crewmate or scout spawn or batch after consulting the dispatch rules (section 4). `bin/fm-spawn.sh`'s header owns the full resolution contract: harness and runtime-backend resolution order, spawn-capable backends and the `codex-app` rejection, verified launch templates, delivery-mode resolution, recorded meta fields, and per-harness turn-end hook installation. A backend spawn refusal - a missing dependency, an unauthenticated socket, or a version gate - must be surfaced to the captain as a blocker; never silently retry the spawn on a different backend to work around it. @@ -511,6 +521,7 @@ bin/fm-teardown.sh ``` The script refuses if the worktree holds uncommitted changes or committed work that has not landed; treat a refusal as a stop-and-investigate, not an obstacle. +For a task whose metadata carries `report_required=1`, teardown quiesces the endpoint, runs non-destructive safety checks, and publishes the validated completion report before releasing the account lease or removing the worktree; a safety refusal after quiescence leaves the endpoint stopped while preserving all task state for repair and retry. `bin/fm-teardown.sh`'s header owns the full landed-work definition (remote-reachable, merged-PR-head containment for the squash-merge-then-delete-branch flow, content already in the default branch, local-only merges) and the `pr=` discovery fallback for merges that skipped `bin/fm-pr-check.sh`. Known benign case: after an external-PR task, a squash merge leaves the branch commits reachable only on the contributor's fork; add the fork as a remote and fetch (`git remote add fork && git fetch fork`), then retry - never reach for `--force`. A successful PR-based teardown also refreshes that project's clone through `bin/fm-fleet-sync.sh`, best-effort. @@ -532,9 +543,11 @@ A scout task follows Intake, Spawn, and Supervise exactly as above - scaffold th - There is no Validate or PR-ready stage. When the crewmate's status says `done`, read `data//report.md`. - Relay the findings to the captain: plain chat for a focused answer, lavish-axi when the report has structure worth a visual (multiple findings, options, a plan). -- Tear down immediately - no merge gate. `bin/fm-teardown.sh` allows a scout worktree's scratch commits and dirty files once the report exists; if the report is missing, it refuses, because the findings are the work product. +- Tear down immediately - no merge gate. For a post-cutover scout, `bin/fm-teardown.sh` requires the report's completion sections and publishes it before discarding the scratch worktree; a missing or incomplete report refuses teardown because the findings are the work product. - Record it in Done with the report path instead of a PR link using `tasks-axi done` when the default tasks-axi backend is active and compatible, otherwise hand-edit `data/backlog.md` and keep Done to the 10 most recent, then re-evaluate the queue and dispatch only queued work whose blockers are gone and whose time/date gate, if any, has arrived. +When the captain invokes `/reports` or asks to browse, open, search, or summarize completed work, load the `reports` skill. + **Promotion.** When a scout's findings reveal shippable work (a reproduced bug with a clear fix) and the captain wants it shipped, promote the task in place instead of respawning: run `bin/fm-promote.sh ` (flips `kind=` to ship in meta, restoring teardown's full protection), then from an active firstmate session send the crewmate its ship instructions with `FM_HOME= bin/fm-send.sh` unless `FM_HOME` is already set to the active firstmate home - inventory scratch state, reset to a clean default-branch base, carry over only intended fix changes, create branch `fm/`, implement, and report `done` according to the project's delivery mode. The crewmate keeps its worktree, loaded context, and repro, but the ship branch must start from a clean base with only intended changes; scratch commits and debug edits from the scout phase never ride along. The repro becomes the regression test. @@ -732,6 +745,7 @@ The no-mistakes brief points to no-mistakes' version-matched guidance and keeps The scaffold reads the mode via `fm-project-mode.sh`, so you do not pass it. Ship briefs also include the project-memory contract: run `bin/fm-ensure-agents-md.sh` when the project already has agent-memory files or when the task produced durable project-intrinsic knowledge, then record proportionate learnings in `AGENTS.md`. For scout tasks add `--scout`: the scaffold swaps the definition of done for the report contract (findings to `data//report.md`, no branch, no push, no PR) and declares the worktree scratch; scout is mode-agnostic. +Every post-cutover ship brief also requires `data//completion.md`, and both task shapes use the completion-report sections and optional `data//visuals/` artifacts enforced at publication; `docs/report-stack.md` owns the storage and teardown contract. Scout briefs do not include the project-memory step, because their deliverable is a report rather than a committed project change. For a crewmate task that will drive Herdr lifecycle behavior, add `--herdr-lab`: the scaffold embeds the hard Herdr-isolation contract backed by `bin/fm-herdr-lab.sh` (a never-`default` lab session, a trailing `--session` on every Herdr call, guarded teardown, and a before/after fleet-state tripwire), and the flag is rejected for `--secondmate` briefs. The flag must be explicit because the scaffold cannot read the `{TASK}` text it fills in later, so every ship or scout brief scaffolded without it carries a loud not-enabled gate telling the crewmate to stop and regenerate with `--herdr-lab` if the task turns out to touch Herdr lifecycle. @@ -758,9 +772,9 @@ It performs only fast-forward self-updates of firstmate and registered secondmat These skills are not captain-invocable; they are conditional operating references you must load at the trigger points below. -- `bootstrap-diagnostics` - load whenever the session-start digest's bootstrap section prints any diagnostic or capability line (`MISSING:`, `MISSING_MANUAL:`, `BACKEND_INVALID:`, `NEEDS_GH_AUTH`, `TANGLE:`, `CREW_HARNESS_OVERRIDE:`, `CREW_DISPATCH:`, `FLEET_SYNC:`, `SECONDMATE_SYNC:`, `SECONDMATE_LIVENESS:`, `TASKS_AXI:`, `NUDGE_SECONDMATES:`, or `FMX:`); silence needs no load. +- `bootstrap-diagnostics` - load whenever the session-start digest's bootstrap section prints any diagnostic or capability line (`MISSING:`, `MISSING_MANUAL:`, `BACKEND_INVALID:`, `ACCOUNT_ROUTING:`, `NEEDS_GH_AUTH`, `TANGLE:`, `CREW_HARNESS_OVERRIDE:`, `CREW_DISPATCH:`, `FLEET_SYNC:`, `SECONDMATE_SYNC:`, `SECONDMATE_LIVENESS:`, `TASKS_AXI:`, `NUDGE_SECONDMATES:`, `REPORT_RETENTION:`, or `FMX:`); silence needs no load. - `harness-adapters` - load before spawning or recovering a crewmate or secondmate, handling a trust dialog, sending a harness-specific skill invocation, interrupting or exiting an agent, resuming an exited agent, or verifying a new harness adapter. -- `firstmate-orca` - load before switching to Orca, spawning or supervising Orca-backed work, smoke-testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata. +- `firstmate-orca` - load before recovering or supervising legacy Orca-backed work, testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata. - `stuck-crewmate-recovery` - load after a stale wake, looping pane, repeated confusion, an answered-by-brief question, an unresponsive crewmate, or a failed steer. - `secondmate-provisioning` - load before creating, seeding, validating, launching, handing backlog to, recovering, pushing inherited config into, or retiring a secondmate home, and before editing `data/secondmates.md`. - `fmx-respond` - load on an `x-mention ` `check:` wake to handle the mention, on an `x-mode-error ...` `check:` wake to report the X-mode configuration blocker, and on any milestone or terminal wake for an X-mode-linked task before posting its completion follow-up; relevant only when X mode is on. diff --git a/README.md b/README.md index b330847449a..a6295b0417d 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,13 @@ Launching a supported harness inside it instantiates your first mate - and makes ## Features - **One liaison** - you talk only to the first mate; it dispatches, supervises, escalates only real decisions, and reports plain outcomes. -- **A visible crew** - every crewmate works in its own tmux window, experimental herdr/zellij tab, cmux workspace, or Orca terminal you can watch or type into; the first mate reconciles. -- **Disposable worktrees** - each task runs in a clean [treehouse](https://github.com/kunchenguid/treehouse) git worktree, or an Orca-managed worktree when `backend=orca`, so parallel work on one repo never collides. +- **A visible crew** - every new crewmate works in its own tmux window, experimental herdr/zellij tab, or cmux workspace you can watch or type into; the first mate reconciles. +- **Disposable worktrees** - each new ship or scout task runs in a clean [treehouse](https://github.com/kunchenguid/treehouse) git worktree, so parallel work on one repo never collides. - **Two task shapes** - ship tasks deliver a change; scout tasks investigate, plan, reproduce, or audit and leave a report. - **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, supervising project clones or a project-less firstmate-repo domain, kept on the primary firstmate version by guarded local fast-forwards and checked for live agent processes at session start. +- **Optional multi-account routing** - route Claude and Codex crews through explicit or pooled Agent Fleet profiles while preserving sticky recovery and provider-neutral continuation. +- **Durable completion reports** - every new ship and scout task publishes a detailed, visual, searchable report to one machine-global stack through fail-closed teardown. - **Event-driven, zero-token supervision** - a bash watcher sleeps on the fleet and wakes the first mate only when something needs you; verified primary harnesses also get a turn-end backstop that blocks or follows up on a blind stop when work is in flight and supervision is not live. - **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, acknowledge spawned work, and post up to three public-safe completion follow-ups within seven days for genuine milestones and the final outcome without changing non-X behavior; dry-run preview records would-be replies and dismissals 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. @@ -59,10 +61,11 @@ Full detail on every feature lives in [docs/architecture.md](docs/architecture.m ### Requirements - A verified agent harness: Claude Code, Grok, Pi, Codex, or OpenCode. +- Node.js and Python 3. - Git and the GitHub CLI, authenticated through `gh auth login`. - tmux, for the reference session backend. -The first mate detects and offers to install everything else. +The first mate detects missing dependencies, offers supported installs after consent, and prints instructions for manual-only tools. ### Recommended harnesses @@ -122,7 +125,7 @@ For Pi, approve the project trust prompt once per clone on first launch so both ### More backends -Setup guides for tmux (the default) and every other supported backend (herdr, zellij, Orca, cmux) are linked in [Documentation](#documentation) below. +Setup guides for tmux (the default) and the new-task-capable herdr, zellij, and cmux backends are linked below; the Orca guide documents its legacy recovery-only path. ## How It Works @@ -138,23 +141,26 @@ Setup guides for tmux (the default) and every other supported backend (herdr, ze │ backend sends / status files │ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────┐ - │fm-task1│ │fm-task2│ ... │fm-taskN│ tmux windows, herdr/zellij tabs, cmux workspaces, or Orca terminals + │fm-task1│ │fm-task2│ ... │fm-taskN│ tmux windows, herdr/zellij tabs, or cmux workspaces │crewmate│ │crewmate│ │crewmate│ one autonomous agent each └───┬────┘ └───┬────┘ └───┬────┘ ▼ ▼ ▼ - treehouse worktree, Orca worktree, or isolated secondmate home + treehouse worktree or isolated secondmate home │ - ├─ ship: project mode ► PR/local merge ► teardown + ├─ ship: completion.md + project mode ► PR/local merge ► teardown │ - └─ scout: report at data//report.md ► relay findings ► teardown + └─ scout: report.md ► relay findings ► teardown + + teardown publishes both task shapes to the machine-global report stack ``` You chat with the first mate. It routes each request to a crewmate in its own session endpoint and git worktree, supervises the fleet with a zero-token event-driven watcher, and brings you finished PRs, approved local merges, or investigation reports. Optional secondmates extend this to persistent domain supervisors, dispatch profiles let you steer which harness handles which task, and an opt-in X mode lets the same fleet answer public mentions. +Optional Agent Fleet routing distributes Claude and Codex work across account profiles, while the completion report stack keeps the result independent of any account or Firstmate home. `codex-app` is not a runtime backend yet; [docs/codex-app-backend.md](docs/codex-app-backend.md) owns the Codex App boundary. -Full architecture - the supervision engine, worktree isolation, secondmates, dispatch profiles, project modes, optional X mode, fleet sync, and self-update - is in [docs/architecture.md](docs/architecture.md). +Full architecture - the supervision engine, worktree isolation, secondmates, dispatch and account routing, completion reports, project modes, optional X mode, fleet sync, and self-update - is in [docs/architecture.md](docs/architecture.md). ## Built-in skills @@ -165,6 +171,7 @@ Claude and grok use the slash form shown here; codex uses the same names with `$ | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | | `/afk` | Enter away-mode supervision: the sub-supervisor self-handles routine wakes in bash, escalates captain-relevant events and bounded declared-external-wait rechecks as batched digests, and actively alerts if delivery wedges while you step away | | `/bearings` | Generate a "pick up where I left off" status report from the read-only fleet snapshot - backlog, per-task crew state, open PRs, scout reports, pending decisions, and date-gated queued work - written to a dated file in `data/` and surfaced concisely in chat; read-mostly, mutates no task state | +| `/reports` | Browse, search, open, or summarize the machine-global completion report stack, including visual evidence and follow-ups | | `/updatefirstmate` | Self-update the running firstmate and its secondmates to the latest from origin with fast-forward-only pulls, then re-read instructions and nudge secondmates | | `/stow` | Sweep the session for uncaptured durable knowledge, route each finding to its disk home per AGENTS.md, file undone next steps to the backlog, and report what is now safe to reset | @@ -182,16 +189,17 @@ Firstmate's skills live in two separate places with different audiences: ## Documentation -- [docs/architecture.md](docs/architecture.md) - how the crew, supervision, worktrees, secondmates, and project modes work. -- [docs/configuration.md](docs/configuration.md) - environment variables, `FM_HOME`, runtime backend selection, optional X mode, the files you set, and harness support. +- [docs/architecture.md](docs/architecture.md) - how the crew, supervision, worktrees, secondmates, account routing, completion reports, and project modes work. +- [docs/configuration.md](docs/configuration.md) - environment variables, `FM_HOME`, runtime backend and Agent Fleet account routing, optional X mode, the files you set, and harness support. - [docs/wedge-alarm.md](docs/wedge-alarm.md) - configure the active alert for a wedged away-mode escalation delivery. - [docs/tmux-backend.md](docs/tmux-backend.md) - setup guide for the tmux reference backend: prerequisites, attaching, and watching crew windows. - [docs/herdr-backend.md](docs/herdr-backend.md) - setup guide for the experimental herdr backend, plus its verification notes and known gaps. - [docs/zellij-backend.md](docs/zellij-backend.md) - setup guide for the experimental zellij backend, plus its verification notes and known gaps. -- [docs/orca-backend.md](docs/orca-backend.md) - setup guide for the experimental Orca backend, plus its lifecycle notes and known gaps. +- [docs/orca-backend.md](docs/orca-backend.md) - legacy Orca task recovery, lifecycle notes, and known gaps; new task spawns are refused. - [docs/cmux-backend.md](docs/cmux-backend.md) - setup guide for the experimental cmux backend, plus its verification notes and known gaps. - [docs/codex-app-backend.md](docs/codex-app-backend.md) - Codex App backend boundary, evidence, and rollout contract. - [docs/turnend-guard.md](docs/turnend-guard.md) - the primary session's structural "no turn ends blind" backstop: verified per-harness hook mechanisms, scoping, loop safety, and fail-open tradeoffs. +- [docs/report-stack.md](docs/report-stack.md) - completion-report requirements, publication safety, stored artifacts, and browsing commands. - [docs/supervision-protocols/](docs/supervision-protocols/) - rendered primary-harness watcher protocols for Claude, Codex, OpenCode, Pi, Grok, and unknown harness fallback. - [docs/scripts.md](docs/scripts.md) - the `bin/` toolbelt reference. - [`AGENTS.md`](AGENTS.md) - the distro's core instruction file and the first mate's full operating manual. diff --git a/bin/backends/cmux.sh b/bin/backends/cmux.sh index 69dc0b53bde..c6958a5eefc 100644 --- a/bin/backends/cmux.sh +++ b/bin/backends/cmux.sh @@ -325,14 +325,43 @@ fm_backend_cmux_scoped_title() { # printf 'fm-%s-%s' "$home" "$rest" } +fm_backend_cmux_all_workspaces() { + local wins window_ids wid wss all='[]' + wins=$(fm_backend_cmux_cli list-windows --json --id-format uuids 2>/dev/null) || return 1 + window_ids=$(printf '%s' "$wins" | jq -r ' + if type == "array" + and all(.[]; type == "object" and (.id | type) == "string" and (.id | length) > 0) + then .[].id + else error("invalid window record") + end + ' 2>/dev/null) || return 1 + while IFS= read -r wid; do + [ -n "$wid" ] || continue + wss=$(fm_backend_cmux_cli workspace list --json --id-format uuids --window "$wid" 2>/dev/null) || return 1 + printf '%s' "$wss" | jq -e ' + (.workspaces | type) == "array" + and all(.workspaces[]; + type == "object" + and (.id | type) == "string" + and (.id | length) > 0 + and (.title | type) == "string") + ' >/dev/null 2>&1 || return 1 + all=$(jq -cn --argjson current "$all" --argjson next "$wss" '$current + $next.workspaces') || return 1 + done <, or empty. cmux enforces no title uniqueness (finding #6), # so this adopts the FIRST match `jq` returns, mirroring herdr's/zellij's own # duplicate-check posture. fm_backend_cmux_workspace_id_for_label() { #