Skip to content

maintenance: rebase fm/fm-launch-menu onto upstream main for PR #1288 - #22

Draft
sbracewell64 wants to merge 14 commits into
sync/upstream-main-2026-08-01from
fm/fm-launch-menu
Draft

maintenance: rebase fm/fm-launch-menu onto upstream main for PR #1288#22
sbracewell64 wants to merge 14 commits into
sync/upstream-main-2026-08-01from
fm/fm-launch-menu

Conversation

@sbracewell64

Copy link
Copy Markdown
Owner

Temporary maintenance PR used only to repair the head branch of upstream PR kunchenguid#1288.

Base: sync/upstream-main-2026-08-01 (mirrors current upstream main at 1e24757)
Head: fm/fm-launch-menu (original head preserved at backup/pr-1288-before-rebase-2026-08-01)

Goal: resolve merge conflicts while preserving the intent of upstream PR kunchenguid#1288, run relevant tests, and update the SAME head branch. Do not merge this maintenance PR; it is only a conflict-resolution workspace.

Copy link
Copy Markdown
Owner Author

@codex Please repair this maintenance PR by updating its existing head branch fm/fm-launch-menu against base sync/upstream-main-2026-08-01. Resolve all merge conflicts semantically, preserving the intent and behavior of upstream kunchenguid/firstmate#1288 while incorporating current upstream behavior. Do not choose ours/theirs mechanically when both sides matter. Run the relevant repository tests and no-mistakes checks. Update the SAME head branch; do not create a replacement implementation branch, do not modify backup/pr-1288-before-rebase-2026-08-01, do not merge this maintenance PR, and do not push to kunchenguid/firstmate. Stop and report instead of guessing if a semantic conflict cannot be resolved safely. When done, report the new head SHA, conflicts resolved, and verification run.

@chatgpt-codex-connector

Copy link
Copy Markdown

Captain, I had to stop rather than guess because the requested base commit is unavailable in the checkout and network access to GitHub is blocked.

Outcome

  • No files, commits, or branches were modified.
  • The current head remains 06a6fbd3caca9659e7a0a5e55a84bb8baf547eab.
  • backup/pr-1288-before-rebase-2026-08-01 was not modified.
  • No pull request was created or merged, and nothing was pushed.
  • Conflict resolution could not begin because base commit 1e247571aa75e00b00c7a01c4830025ecd44dc61 is not present locally.
  • Fetching that commit directly from kunchenguid/firstmate failed because the environment’s network proxy returned HTTP 403.
  • The required no-mistakes, gh, and gh-axi tools are also unavailable, and GitHub authentication is not configured.

Testing

  • git status --short --branch && git rev-parse HEAD && command -v no-mistakes || true && command -v gh || true — confirmed a clean checkout at the original head and confirmed the required tools are unavailable.
  • git cat-file -e 1e247571aa75e00b00c7a01c4830025ecd44dc61^{commit} — the requested base commit does not exist in the local object database.
  • ⚠️ git fetch --no-tags https://github.com/kunchenguid/firstmate.git 1e247571aa75e00b00c7a01c4830025ecd44dc61 — blocked by the environment’s network proxy with CONNECT tunnel failed, response 403.
  • ⚠️ Relevant repository tests and no-mistakes checks were not run because a semantic rebase could not be performed and no-mistakes is not installed.

View task →

sbracewell64 and others added 14 commits August 1, 2026 12:29
A fleet launcher will soon open PRIMARY firstmate sessions alongside the
crewmate sessions fm-spawn.sh opens, so both need the same verified launch
commands. Today that knowledge lives only inside bin/fm-spawn.sh, and the
drift a second copy causes is not hypothetical: a downstream registry
hand-copied claude's command as `claude --dangerously-skip-permissions`,
dropping CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=false - the ghost-text
suppression that keeps firstmate from reading predicted-prompt text as real
typed input when it captures a pane.

Extract launch_template, model_flag_for_harness, and effort_flag_for_harness
(plus the shell_quote both flag resolvers depend on) into a new sourced
bin/fm-launch-lib.sh, and have fm-spawn.sh source it. Every crewmate, scout,
and secondmate template is byte-identical to before, so spawn behavior is
unchanged on all six verified adapters.

launch_template also gains a `primary` kind for the launcher. A primary
session has no task, no worktree, no brief, and no status file, so it launches
bare and is greeted by the session-start adapters already installed in the
home; each primary template keeps its adapter's verified autonomy flag and
claude's ghost-text prefix. An unrecognized kind still resolves to the
crewmate shape, and an unverified adapter still returns non-zero for every
kind.

tests/fm-launch-lib.test.sh pins both arms directly, including a proof that
fm-spawn.sh redefines none of the functions and that no other script under
bin/ hand-writes a launch command. Existing suites that read the template
bytes now read them from their new owner.
bin/fm-launch.sh is the captain's front door: it renders a five-entry harness
menu, starts one firstmate primary session in this home, and attaches to it.

The menu is derived and probed, never declared. An entry is available only when
its harness binary resolves on PATH, or - for a Pi-routed entry - when the
provider named in its model appears in pi's local auth record. Unavailable
entries stay visible and dim, each with one actionable line, so the menu never
changes shape under the captain's muscle memory. Both probes are local file
reads, so the menu touches no network and executes no binary at all.

Menu entries carry no launch command. They name a harness plus an optional
model and effort, and the command is resolved through bin/fm-launch-lib.sh at
launch time - the single owner a downstream registry has already drifted from
once by hand-copying a launch string and dropping claude's ghost-text
suppression prefix.

The launcher states on every render, before the choice, that the session it
starts runs without permission prompts. That discharges the consumer obligation
bin/fm-launch-lib.sh's header binds on every consumer of a primary template.

Herdr is mandatory with no silent fallback to a bare shell, and the gate runs
after selection so no socket round trip sits on the critical path. Before
creating anything the launcher looks for a primary already running in this home
and offers to reattach, so two sessions can never contend for one home's
session lock.

Selection is one keypress. A human who mistypes gets a redrawn prompt; a
scripted caller keeps the refuse-don't-reprompt behavior, and a blank line or
EOF refuses rather than launching whatever the default happens to be - taking
the default there once started an unattended session nobody chose.

Presets live in gitignored config/launch-presets.json and the built-in five need
no configuration. They are deliberately not inherited into secondmate homes: a
secondmate is provisioned and launched by the primary through bin/fm-spawn.sh,
never through this front door, so there would be no consumer for an inherited
menu.

The Windows entry point and WSL bridge are out of scope here and land
separately.
…coverage

tests/fm-launch-lib.test.sh's one-owner guards grepped bin/fm-spawn.sh for
function definitions and its literal source line, and git-grepped bin/ for
launch-command markers - implementation-source assertions the coding
guidelines now forbid. Prove the same guarantee behaviorally instead: a
sandboxed copy of bin/ shows fm-spawn's launch decision follows a swapped
fm-launch-lib.sh in both directions and that fm-spawn cannot take a launch
decision without the library, so the launch knowledge has exactly one live
owner. The byte-for-byte template pins already go through the public
launch_template interface and stay.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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