Skip to content

fix(bin): start crewmates on the project's recorded base branch - #1194

Open
talktejas wants to merge 2 commits into
kunchenguid:mainfrom
talktejas:fm/fm-spawn-base-branch
Open

fix(bin): start crewmates on the project's recorded base branch#1194
talktejas wants to merge 2 commits into
kunchenguid:mainfrom
talktejas:fm/fm-spawn-base-branch

Conversation

@talktejas

@talktejas talktejas commented Jul 28, 2026

Copy link
Copy Markdown

Intent

Stop fm-spawn from silently launching crewmates onto the wrong base branch: record each project's intended base branch in the registry, check it out in a freshly allocated task worktree, and refuse to launch a worker whose base cannot be confirmed correct.

What Changed

  • bin/fm-project-mode.sh now parses an optional base=<branch> token from a project's bracket in data/projects.md (unordered alongside +yolo) and gains a --base flag that prints the recorded base branch, or nothing when none is recorded.
  • bin/fm-spawn.sh resolves the expected base for every task spawn — the base= record, else origin/HEAD, else the primary checkout's branch — detaches the freshly allocated worktree at that ref, and refuses to launch when the branch is missing, when the checkout can't be moved there (reporting expected/actual base and the behind/ahead gap), or when an assumed default base is strictly behind the branch the primary checkout is on. local-only projects prefer the local branch over origin/<branch>, which merge-local leaves stale.
  • Added tests/fm-spawn-base-branch.test.sh (registered in the backend-dispatch family in bin/fm-test-run.sh) and documented the recorded base branch in docs/architecture.md, docs/scripts.md, and the project-management skill.

Testing

  • ⏭️ Test - skipped

Registry edits for the operator's local data/projects.md

data/projects.md is captain-private and gitignored, so this branch cannot contain the edit and this worktree's copy is not the live one. Apply these lines to the live registry - add base=develop inside the existing bracket, keeping the current mode and any +yolo untouched:

- jt2627s [<existing mode><, keep +yolo if present> base=develop] - <keep existing description>
- oc [<existing mode><, keep +yolo if present> base=develop] - <keep existing description>

A line with no bracket today becomes [no-mistakes base=develop], which preserves its current default mode.

Until those lines exist, spawns for jt2627s and oc will refuse rather than start a worker on a stale tree - the intended loud failure, but it means the registry edit should land before the next dispatch.

Validation note

The Review, Test, Document, and Lint steps show as skipped above because this run resumed at the Push step after an earlier push was rejected (no write access to this repository; the branch is now pushed from a fork). Those four steps ran and passed on this exact head in run 01KYMC3QNPFHRDRCZBTRAVCATC, whose review findings were fixed in commit 180fe58.

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

Step was skipped.

⏭️ **Rebase** - skipped

Step was skipped.

⏭️ **Review** - skipped

Step was skipped.

⏭️ **Test** - skipped

Step was skipped.

⏭️ **Document** - skipped

Step was skipped.

⏭️ **Lint** - skipped

Step was skipped.

✅ **Push** - passed

✅ No issues found.

@talktejas
talktejas force-pushed the fm/fm-spawn-base-branch branch from 180fe58 to 9ea5c0c Compare July 28, 2026 17:44
A freshly allocated pool worktree lands on the repository's default branch.
Both registered projects develop on `develop`, so a cold slot could start a
worker on a tree roughly a thousand commits behind current work, with no
warning anywhere; a reused slot already sits on the right branch, which is why
this stayed hidden. Task jt-style-number-column audited such a stale tree and
correctly reported that nothing described in its brief existed.

`data/projects.md` now records the intended base branch as a `base=<branch>`
token inside the existing bracket, alongside the delivery mode and `+yolo`.
`bin/fm-project-mode.sh` reads it with a new `--base` query; its default
two-word output and every pre-existing line shape parse exactly as before.

`bin/fm-spawn.sh` detaches the task worktree at that base before the harness
launches - the recorded branch, else the repository default branch as today -
and then asserts the result. A base it cannot confirm is refused, naming the
expected branch, the actual base, and the gap, instead of launching silently.
With no recorded base the primary checkout's own branch is independent
evidence: an assumed default base that is strictly behind it is the incident
above and is refused with the exact registry line to add.

An unregistered project, or a registry line without a base record, resolves its
base exactly as it does today.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant