Skip to content

fm-spawn cuts task branches from origin/<default>, silently dropping a home's local-only commits #3058

Description

@AlexAgenCheck

What happens

bin/fm-spawn.sh cuts a task branch from origin/<default> rather than the home's local default branch, so any local-only commits on that branch are silently dropped from the worker's base.

Code

bin/fm-spawn.sh resolves the base as the remote-tracking ref and then hard-resets the pooled worktree to it:

target="origin/$default"
...
if ! git -C "$worktree" reset --hard "$target" >/dev/null; then

There is no comparison against the local default branch, so a home whose local default is ahead of its remote gets a base that lacks those commits, with no warning.

Observed

Local default branch was 6 commits ahead of origin/<default>. Spawning a task produced a branch based at origin/<default>, and git merge-base --is-ancestor <local-head> HEAD failed - the base contained none of the local commits. Caught before the worker edited anything, and corrected by steering it to rebase.

Reproduced again while writing this report: the same home is currently 7 commits ahead and the behaviour is unchanged at 4179c50.

Why it matters

Any home that carries local-only commits on its default branch is exposed on every task in that repository. The worker silently loses those commits, and the failure surfaces much later - typically as a merge refusal - where it reads as a merge problem rather than a base problem.

This is not an exotic configuration. A home that runs firstmate against a repository it cannot push to will always carry local-only commits on its default branch.

Desired behaviour

A task branch is cut from the home's local default branch.

If that cannot be guaranteed, the spawn should refuse loudly rather than produce a branch whose base lacks local-only commits. A silent wrong base is the dangerous outcome, and this project's own principle is that unlanded work is never put at risk.

A regression check that fails when the local default branch is ahead of its remote and a spawned branch does not contain it would pin the behaviour.

Worth establishing before fixing

Whether the base comes from fm-spawn.sh itself, from the pooled worktree's inherited HEAD, or from a remote-tracking default in between. The pool worktree in the original observation had just been released by a previous teardown, so an inherited HEAD was a live hypothesis. The code above suggests fm-spawn.sh is at least sufficient on its own, but reproducing deliberately is cheap.

Environment

firstmate at 4179c50, treehouse worktree pool, tmux backend.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-prTriage: real bug or VISION-aligned feature, open for a PR

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions