Skip to content

fix(fm-primary): resolve installed-shim symlinks to the tracked repo root before launch - #5

Merged
Amplify-Logic merged 1 commit into
mainfrom
fm/firstmate-primary-shim-root-fix-q6
Jul 19, 2026
Merged

fix(fm-primary): resolve installed-shim symlinks to the tracked repo root before launch#5
Amplify-Logic merged 1 commit into
mainfrom
fm/firstmate-primary-shim-root-fix-q6

Conversation

@Amplify-Logic

Copy link
Copy Markdown
Owner

Intent

Fix the supported installed 'firstmate ' launcher so invocation through the generated symlink resolves and launches from this tracked Firstmate repository instead of treating the shim directory as the repository root. The exact captain-facing acceptance path is 'firstmate kimi': it must expand to the primary-only Kimi K3 profile and reach its normal primary launch path, without adding Kimi worker support. Preserve unchanged direct bin/fm-primary.sh behavior, safe refusal of unrelated existing shim files or symlinks, and exact-link idempotent installation. Keep root-resolution mechanics owned by the launcher header/help, cover actual generated-shim invocation with isolated temporary state and fake CLI seams, test a relative chained symlink as disconfirming evidence, review all supported primary profiles, and validate with tests/fm-primary.test.sh plus bin/fm-lint.sh.

What Changed

  • bin/fm-primary.sh now dereferences up to 40 absolute or relative symlink hops from the invoked command (via a new resolve_script_path helper) before computing SCRIPT_DIR/FM_ROOT, so running the installed firstmate <profile> shim resolves and launches from the tracked Firstmate repository root instead of the shim directory; direct bin/fm-primary.sh invocation behaves as before, and the launcher header comment documents the new resolution step.
  • tests/fm-primary.test.sh extends the shim-safety group to invoke the actual generated shim: firstmate kimi through the installed symlink must report the tracked root, expand to the kimi-k3 profile, and reach the pinned Kimi primary argv; a relative chained symlink must also resolve the tracked root; and shim reinstall through the installed command must stay idempotent.
  • All pipeline stages passed (tests, lint, docs, push); the review stage left one informational note that readlink "$source" could add a -- guard for stylistic consistency with the script's other hardened calls, though the case it guards is unreachable.

Risk Assessment

✅ Low: A small, standard bounded symlink-resolution fix confined to one launcher script, preserving direct-invocation and shim-install behavior, with new tests that exercise the actual generated shim, the Kimi acceptance path, and a relative chained symlink exactly as the stated intent requires.

Testing

Ran the focused fm-primary suite (all green, including the new shim and chained-symlink tests) on top of the already-green full baseline, then manually demonstrated the captain-facing acceptance path: installed the shim into isolated temp state and ran firstmate kimi through it with fake CLI seams, showing it resolves the tracked repo root, expands to kimi-k3, and reaches the normal primary launch path — while the base-commit launcher fails through the same symlink. Also swept all six profiles plus aliases through the shim and re-verified installer safety refusals; bin/fm-lint.sh was skipped per the no-linters testing rule and is handled by the pipeline's lint stage.

Evidence: firstmate kimi via installed shim (install, dry-run, real exec, idempotent reinstall)

$ cd $DEMO/somewhere-else && firstmate kimi root=/Users/larsmusic/.no-mistakes/worktrees/f569cc43ac96/01KXWZRJW50GZ3DPS7WT7AJT3Y profile=kimi-k3 role=FIRSTMATE KIMI_CODE_HOME=$DEMO/home/data/primary/kimi-k3 'kimi' '--model' 'kimi-code/k3' '--yolo' --- without dry-run seam --- FAKE-KIMI launched: pwd=<tracked repo root> KIMI_CODE_HOME=$DEMO/home/data/primary/kimi-k3 argv=--model kimi-code/k3 --yolo

=== E2E: installed 'firstmate' shim launches Kimi K3 from the tracked repo root ===
repo root under test: /Users/larsmusic/.no-mistakes/worktrees/f569cc43ac96/01KXWZRJW50GZ3DPS7WT7AJT3Y (commit 4ee281d)

$ bin/fm-primary.sh --install-shim   (FM_PRIMARY_SHIM_DIR=/var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/bin)
installed firstmate shim: /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/bin/firstmate -> /Users/larsmusic/.no-mistakes/worktrees/f569cc43ac96/01KXWZRJW50GZ3DPS7WT7AJT3Y/bin/fm-primary.sh

$ ls -l /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/bin/firstmate
lrwxr-xr-x@ 1 larsmusic  staff  97 Jul 19 13:18 $DEMO/bin/firstmate -> $REPO/bin/fm-primary.sh

--- captain runs 'firstmate kimi' from an unrelated cwd, shim dir on PATH (dry-run seam) ---
$ cd /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/somewhere-else && firstmate kimi
root=/Users/larsmusic/.no-mistakes/worktrees/f569cc43ac96/01KXWZRJW50GZ3DPS7WT7AJT3Y
profile=kimi-k3
role=FIRSTMATE
KIMI_CODE_HOME=/var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/home/data/primary/kimi-k3
'kimi' '--model' 'kimi-code/k3' '--yolo'

--- same invocation without the dry-run seam: execs the (fake) kimi CLI ---
$ cd /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/somewhere-else && firstmate kimi
FAKE-KIMI launched: pwd=/Users/larsmusic/.no-mistakes/worktrees/f569cc43ac96/01KXWZRJW50GZ3DPS7WT7AJT3Y KIMI_CODE_HOME=/var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/home/data/primary/kimi-k3 argv=--model kimi-code/k3 --yolo

--- reinstall through the installed command stays idempotent ---
$ firstmate --install-shim
firstmate shim already installed: /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/bin/firstmate -> /Users/larsmusic/.no-mistakes/worktrees/f569cc43ac96/01KXWZRJW50GZ3DPS7WT7AJT3Y/bin/fm-primary.sh
Evidence: Disconfirming evidence: base-commit launcher fails via symlink; fixed launcher resolves relative chained symlink

old launcher (6cf9e61) via symlink: fm-primary: could not inspect the Firstmate session lock: ... $DEMO/bin/fm-lock.sh: No such file or directory exit status: 1 fixed launcher via relative chained symlink (../bin/firstmate): root=<tracked repo root> profile=kimi-k3 'kimi' '--model' 'kimi-code/k3' '--yolo'

=== Disconfirming evidence: base-commit launcher (6cf9e61) through a 'firstmate' symlink ===
symlink: /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/oldbin/firstmate -> base-commit fm-primary.sh

$ cd /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/somewhere-else && firstmate kimi   (old launcher via symlink)
fm-primary: could not inspect the Firstmate session lock: /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/oldbin/firstmate: line 97: /private/var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/bin/fm-lock.sh: No such file or directory
exit status: 1

(old launcher resolved FM_ROOT from the symlink's own directory: it looked for
 bin/fm-lock.sh under /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU instead of the tracked repo, so the launch fails)

=== Fixed launcher (4ee281d) via relative CHAINED symlink also resolves the tracked root ===
$ ls -l /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/chain/firstmate
lrwxr-xr-x@ 1 larsmusic  staff  16 Jul 19 13:19 $DEMO/chain/firstmate -> ../bin/firstmate
$ cd /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/somewhere-else && /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/chain/firstmate kimi
root=/Users/larsmusic/.no-mistakes/worktrees/f569cc43ac96/01KXWZRJW50GZ3DPS7WT7AJT3Y
profile=kimi-k3
role=FIRSTMATE
KIMI_CODE_HOME=/var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/home/data/primary/kimi-k3
'kimi' '--model' 'kimi-code/k3' '--yolo'
Evidence: All supported primary profiles through the installed shim + installer safety refusals
=== Every supported primary profile launched through the installed 'firstmate' shim (dry-run seam) ===

$ firstmate pi
root=$REPO_ROOT
profile=pi
role=FIRSTMATE
'pi' '--name' 'FIRSTMATE'

$ firstmate claude-fable
root=$REPO_ROOT
profile=claude-fable
role=FIRSTMATE
'claude' '--model' 'claude-fable-5' '--effort' 'high' '--name' 'FIRSTMATE' '--dangerously-skip-permissions'

$ firstmate claude
root=$REPO_ROOT
profile=claude-fable
role=FIRSTMATE
'claude' '--model' 'claude-fable-5' '--effort' 'high' '--name' 'FIRSTMATE' '--dangerously-skip-permissions'

$ firstmate codex
root=$REPO_ROOT
profile=codex
role=FIRSTMATE
'codex' '--dangerously-bypass-hook-trust' '--dangerously-bypass-approvals-and-sandbox'

$ firstmate opencode
root=$REPO_ROOT
profile=opencode
role=FIRSTMATE
'opencode'

$ firstmate grok
root=$REPO_ROOT
profile=grok
role=FIRSTMATE
'grok' '--permission-mode' 'bypassPermissions'

$ firstmate kimi-k3
root=$REPO_ROOT
profile=kimi-k3
role=FIRSTMATE
KIMI_CODE_HOME=$DEMO/home/data/primary/kimi-k3
'kimi' '--model' 'kimi-code/k3' '--yolo'

$ firstmate kimi
root=$REPO_ROOT
profile=kimi-k3
role=FIRSTMATE
KIMI_CODE_HOME=$DEMO/home/data/primary/kimi-k3
'kimi' '--model' 'kimi-code/k3' '--yolo'

=== Shim installer safety refusals still hold ===

$ FM_PRIMARY_SHIM_DIR=$DEMO/occupied bin/fm-primary.sh --install-shim   (existing unrelated FILE)
fm-primary: refusing to replace an existing file: /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/occupied/firstmate
exit status: 1

$ FM_PRIMARY_SHIM_DIR=$DEMO/occupied bin/fm-primary.sh --install-shim   (existing unrelated SYMLINK)
fm-primary: refusing to replace a different symlink: /var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/tmp.MBZPtM45hr/fm-shim-demo.U8qJDU/occupied/firstmate
exit status: 1

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 info
  • ℹ️ bin/fm-primary.sh:64 - readlink &#34;$source&#34; omits the -- end-of-options guard that the surrounding code consistently uses (dirname --, cd -P --). Only the first iteration could ever see a path starting with - (later hops are always absolute), so this is unreachable in practice, but adding -- would make the resolver internally consistent with the script's hardening style.
✅ **Test** - passed

✅ No issues found.

  • command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"
  • Baseline configured test command: all tests/*.test.sh (ran green before this session)
  • bash tests/fm-primary.test.sh — all 10 test groups pass, including new installed-shim firstmate kimi, relative chained symlink, and shim-reinstall idempotency coverage
  • Manual e2e: bin/fm-primary.sh --install-shim into an isolated temp dir, then firstmate kimi via PATH from an unrelated cwd with fake kimi CLI seam — dry-run seam showed root=<repo>, profile=kimi-k3, pinned argv; non-dry-run pass exec'd the fake kimi CLI from the tracked repo root with the managed KIMI_CODE_HOME
  • Manual disconfirming check: base-commit (6cf9e61) launcher invoked through the same firstmate symlink resolves the shim dir as root and fails with missing bin/fm-lock.sh; fixed launcher via relative chained symlink resolves the tracked root
  • Manual sweep: all supported profiles (pi, claude-fable, codex, opencode, grok, kimi-k3) plus aliases (claude, kimi) launched through the installed shim, each resolving the tracked root with exact pinned argv
  • Manual safety check: installer refuses an unrelated existing file and an unrelated symlink at the shim path, and reinstall through the installed command stays idempotent
  • bin/fm-lint.sh was NOT run (testing step forbids linters; covered by the pipeline's lint stage)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@Amplify-Logic
Amplify-Logic merged commit 5053c3c into main Jul 19, 2026
@Amplify-Logic
Amplify-Logic deleted the fm/firstmate-primary-shim-root-fix-q6 branch July 19, 2026 11:28
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