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.
What happens
bin/fm-spawn.shcuts a task branch fromorigin/<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.shresolves the base as the remote-tracking ref and then hard-resets the pooled worktree to it: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 atorigin/<default>, andgit merge-base --is-ancestor <local-head> HEADfailed - 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.shitself, 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 suggestsfm-spawn.shis at least sufficient on its own, but reproducing deliberately is cheap.Environment
firstmate at
4179c50, treehouse worktree pool, tmux backend.