# Spec 003: FirstMate from General Chat

Status: draft revision 2 for review
Date: 2026-08-08
Depends on: [Spec 000](spec-000-system-overview.md), [Spec 001](spec-001-core-and-live-work.md), and [Spec 002](spec-002-sandboxed-execution.md)

## Outcome

From General Chat, a user selects FirstMate and asks for an outcome. FirstMate
can bind the request to a selected project, dispatch or message agents through
Herdr, supervise them without polling, surface real decisions, and return one
coherent result. Every
child remains visible as a normal Work chat.

Agents may use the same scoped crew tools to call or message other agents when
their parent capability permits it. Humans are participants in the graph, not
the only possible orchestrators.

## Inspired by FirstMate, not a second platform

The upstream [FirstMate project](https://github.com/kunchenguid/firstmate)
demonstrates four useful product ideas: one human liaison, visible workers,
isolated worktrees, and event-driven supervision.

Godloop keeps those ideas but does not clone, vendor, or run the FirstMate
distro. Its shell watchers, private state tree, backlog system, multiple runtime
backends, PR automation, and secondmates would duplicate Godloop, Herdr, and
Spec 001.

In v2, `firstmate` is a user-facing agent kind implemented as a versioned
profile over the same chat agent loop used everywhere else:

```text
profile = instructions + allowed crew tools + default budget + result style
```

It is not a model, daemon, microservice, MCP server, or separate scheduler.
The initial profile is one readable, versioned Markdown instruction file plus a
small capability declaration in Go. There is no profile DSL or builder UI.

## General Chat contract

General Chat is private to the user and offers two kinds initially:

- `assistant`: answers and plans without agent orchestration;
- `firstmate`: may use the crew tools below.

FirstMate may discuss or plan without a project. Before reading a repository,
using a Space, or starting an agent, it must bind the command to an explicitly
selected project and contributed Space. Project commands, child conversations,
events, and results are shared with project members; private General Chat
context is not copied automatically.

One conversation has at most one active FirstMate turn. A new user message may
steer that turn or queue behind it; it does not start a competing orchestrator.

## One agent loop

The Go monolith runs one bounded model/tool loop for `assistant`, `firstmate`,
future specialist profiles, and eventually Loops. The profile changes
instructions and capabilities, not execution infrastructure.

The loop persists each user message, tool request, tool result, and final reply
before advancing. A crash resumes from durable state or ends visibly; it never
replays an uncommitted tool effect.

FirstMate yields after dispatch. Godloop wakes it only for an actionable event:
a child result, a blocked decision, a failed delivery, cancellation, or a user
message. There is no model polling loop and no held HTTP request.

## Small crew API

FirstMate and authorized children receive four Godloop tools, not the Herdr CLI,
socket, pane control, Crabbox CLI, SSH, or credentials:

```text
crew.start(task, agent_kind, mode, expected_result) -> child_execution
crew.send(execution, message) -> delivery
crew.inspect(scope = active | child_execution) -> bounded state and results
crew.cancel(execution, reason) -> cancellation
```

`crew.start` creates a durable parent-child edge before provisioning. `mode` is
`read_only` or `writing`; writing uses Spec 002. It returns after acceptance,
not after completion.

`crew.send` persists an attributed message before delivery. It can target a
child or another project agent explicitly marked callable by its Space owner.
Busy delivery queues until Herdr reports a safe state.

`crew.inspect` returns structured lifecycle, unread results, and bounded
evidence. It never treats terminal scrollback as canonical output.

`crew.cancel` records intent and remains pending until runtime cleanup is
confirmed.

A child with delegation permission receives the same tools with smaller limits.
This is how agents call and communicate with one another without acquiring raw
terminal authority.

## Herdr adapter

The trusted Space connector maps crew commands to the installed Herdr API:

```text
session snapshot + event subscription
worktree create/open
tab create --no-focus
agent start / prompt / wait / read
```

Godloop authorizes and records the command first. The connector then uses only
IDs returned by Herdr. Events wake reconciliation; a fresh snapshot recovers
after disconnect. Herdr lifecycle is observation, while Godloop executions and
results are durable product state.

For a new writing child, the adapter also binds the Spec 002 execution lease.
For an existing callable agent, it records a message edge without inventing new
filesystem authority.

## Crew graph and limits

Every delegation records root, parent, child, requesting actor, project,
capability, budget, and state. The graph must remain acyclic and inside one
project.

Initial hard limits are intentionally small:

- depth 2 including children created by a child;
- two concurrent children per FirstMate root;
- four children total per root;
- explicit time and model budget per child;
- no capability wider than the parent or project policy.

SQLite reserves capacity before dispatch so racing calls cannot exceed a
budget. Limits are code-enforced, not prompt advice.

The initial built-in worker kinds are only `researcher`, `implementer`, and
`reviewer`. They map to a supported Herdr agent kind plus instructions and a
result shape. Add another kind only after a real task cannot fit these three.

## Typed results

A child returns:

```text
status = completed | failed | blocked | cancelled
summary
structured output when requested
artifacts and effects
test/runtime evidence
usage
```

The result is persisted before FirstMate wakes. FirstMate may send a follow-up,
ask a reviewer, compose the result, or request a human decision. It cannot call
a terminal transcript a successful result or auto-apply a writing result.

Agent-to-agent messages and results retain their source actor and execution so
the human can reconstruct who asked whom to do what.

## Human control

General Chat shows FirstMate's concise narrative. Project Work shows the same
root and children as a small crew tree beside ordinary chats:

- requester, parent, kind, execution mode, state, and remaining budget;
- unread results and queued messages;
- blocked decisions;
- inspect, message, steer, cancel, and take-over controls allowed by role.

Starting background work never changes Herdr focus or another user's selected
chat. High-risk actions—apply, push, merge, deploy, publish, secrets, wider
network, more budget, or Space sharing—retain explicit commands or approval.

FirstMate escalates a decision once with context and safe options. Agents never
approve security prompts on behalf of humans.

## Recovery rules

- Dispatch accepted but Herdr start fails: keep a failed child result; do not
  create another child implicitly.
- Prompt delivery uncertain: reconcile the Herdr agent and idempotency key
  before retrying.
- Child blocked: wake FirstMate and the human once; do not busy-loop.
- FirstMate crashes: resume from persisted messages, tool calls, and events.
- Parent cancelled: cancel active children by default and preserve completed
  results.
- Invalid result: retain bounded evidence, mark failure, and do not scrape the
  terminal into success.
- Connector or server restarts: reconcile graph, Herdr snapshot, execution
  leases, and results without duplication.

## Acceptance

1. Select `firstmate` in General Chat and request two changes in project
   Godloop.
2. FirstMate confirms the project/Space boundary, starts a read-only researcher
   and a writing implementer, then yields.
3. Both appear as live Work chats and background Herdr agents without refresh
   or focus changes. The writer receives a Spec 002 execution lease.
4. The researcher sends a durable message to the implementer while it is busy;
   delivery occurs once at a safe state.
5. The implementer calls a reviewer within the remaining depth and budget. A
   cycle, third concurrent child, cross-project call, or raw Herdr request is
   rejected before runtime mutation.
6. Restart v2 and the connector. The same crew graph, messages, budgets, and
   results reconcile without duplication.
7. One child blocks for a human decision. The user answers from General Chat or
   Work, and execution continues once.
8. FirstMate consumes typed results, reports one coherent outcome, and links to
   each child and reviewable change without auto-applying it.
9. Cancel another run and confirm child cleanup while retaining its history.

## Build gates

1. Implement the profile and crew API against a deterministic fake Herdr
   adapter. Prove idempotency, limits, cycles, wakeups, and crash recovery.
2. Connect one read-only child in a named Herdr test session.
3. Pass Spec 002's Crabbox feasibility gate and connect one writing child.
4. Add two-child fan-out, agent-to-agent messaging, and human blocked decisions.
5. Run the full acceptance path before adding Loops or more agent kinds.

## Not in this spec

- vendoring or operating the upstream FirstMate distro;
- shell watchers, filesystem backlogs, secondmates, multiple session backends,
  or autonomous PR/merge/deploy machinery;
- arbitrary recursive swarms, unbounded budgets, hidden agents, or raw Herdr
  access inside prompts;
- a separate orchestration engine for Loops.
