Skip to content

feat: launch crews from direct account directories - #24

Merged
ruby-dlee merged 15 commits into
mainfrom
fm/cutover-publish-p1
Jul 24, 2026
Merged

feat: launch crews from direct account directories#24
ruby-dlee merged 15 commits into
mainfrom
fm/cutover-publish-p1

Conversation

@ruby-dlee

Copy link
Copy Markdown
Owner

Intent

Publish the already validated per-account crew launch cutover onto origin/main through this repository’s no-mistakes pipeline so dependent browser-isolation work can rebase onto it. Preserve the complete thirteen-commit history from 610f55d through f036ae7, including all nine no-mistakes(review) hardening commits and the validation/test commits; do not squash, rebase away, refactor, or extend that work. The pipeline must raise a compliant replacement PR rather than reuse or bypass hand-raised PR #23. Never push directly to main or to upstream, and keep all shell files shellcheck-clean. This is a republication of a result already gate-validated once; only pipeline-owned fixes are permitted if the gate finds an actual issue.

What Changed

  • Add direct Claude and Codex account-directory selection for new ship and scout crews, including fresh Codex quota-based health checks and per-profile Herdr hook setup.
  • Rework spawn, recovery, bootstrap, dispatch, and teardown flows to preserve direct-routing identity and rollback state while retaining Agent Fleet compatibility for secondmates and legacy tasks.
  • Update account-routing documentation and add hermetic coverage for account selection, recovery, bootstrap, dispatch, and cleanup lifecycles.

Risk Assessment

✅ Low: The narrow fix safely refuses teardown before mutation when retained direct-recovery cleanup is pending, preserves rollback state, adds focused coverage, and leaves the required thirteen-commit history intact.

Testing

The supplied full baseline and targeted launch, recovery, bootstrap, dispatch, and teardown checks passed; CLI transcripts and exact history evidence were captured, while GitHub verification confirmed PR #23 has not been reused but the required replacement PR has not yet been created.

Evidence: Per-account launch cutover transcript
== Direct per-account launch and recovery lifecycle ==
ok - direct routing safely adopts the required detached-to-task-branch transition
ok - direct recovery preserves recorded task context while refreshing account selection
ok - direct account recovery refuses secondmate metadata before selection
ok - failed new direct spawn removes its endpoint and returns its worktree
ok - direct spawn persists cleanup state when worktree return cannot be confirmed

== Bootstrap account-directory cutover ==
fatal: not a git repository (or any of the parent directories): .git
fatal: not a git repository (or any of the parent directories): .git
fatal: not a git repository (or any of the parent directories): .git
fatal: not a git repository (or any of the parent directories): .git
fatal: not a git repository (or any of the parent directories): .git
fatal: not a git repository (or any of the parent directories): .git
ok - bootstrap requires direct launch tools for crews and Agent Fleet for enforced secondmates or legacy recovery

== Dispatch selection account-directory cutover ==
ok - account_pool dispatch defers account choice to direct spawn selection
fm-dispatch-select: account_pool is a direct-routing compatibility input; using the first profile and deferring account selection to spawn
ok - fully pooled dispatch honors explicit pool precedence over ambient routing
Evidence: Rollback-preserving teardown evidence
+ printf '%s\n' direct_recovery_cleanup=pending direct_recovery_backup=.task-x1.meta.rollback.recovery direct_recovery_artifacts=.task-x1.artifacts.rollback.recovery
+ run_teardown /var/folders/y_/bfdbj_vx20l9b9tw7crgkzwm0000gn/T//fm-teardown-tests.yykSkD/retained-direct-recovery --force
+ rc=1
+ assert_grep 'direct recovery cleanup is pending for task-x1' /var/folders/y_/bfdbj_vx20l9b9tw7crgkzwm0000gn/T//fm-teardown-tests.yykSkD/retained-direct-recovery/stderr 'retained direct-recovery teardown did not explain the cleanup blocker'
+ grep -F -- 'direct recovery cleanup is pending for task-x1' /var/folders/y_/bfdbj_vx20l9b9tw7crgkzwm0000gn/T//fm-teardown-tests.yykSkD/retained-direct-recovery/stderr
+ assert_present /var/folders/y_/bfdbj_vx20l9b9tw7crgkzwm0000gn/T//fm-teardown-tests.yykSkD/retained-direct-recovery/wt/.git 'retained direct-recovery teardown recycled the worktree'
+ assert_present /var/folders/y_/bfdbj_vx20l9b9tw7crgkzwm0000gn/T//fm-teardown-tests.yykSkD/retained-direct-recovery/state/task-x1.meta 'retained direct-recovery teardown erased cleanup metadata'
+ assert_present /var/folders/y_/bfdbj_vx20l9b9tw7crgkzwm0000gn/T//fm-teardown-tests.yykSkD/retained-direct-recovery/state/.task-x1.meta.rollback.recovery 'retained direct-recovery teardown erased the metadata backup'
+ assert_present /var/folders/y_/bfdbj_vx20l9b9tw7crgkzwm0000gn/T//fm-teardown-tests.yykSkD/retained-direct-recovery/state/.task-x1.artifacts.rollback.recovery/status 'retained direct-recovery teardown erased artifact backups'
ok - retained direct-recovery teardown preserves rollback state
Evidence: Preserved thirteen-commit history
Preserved cutover history (oldest to newest):
610f55df14e8003d9d4990247d6efb18dd29ec64 Launch crews from account directories
9ceada3c80d4167054b5f8b9476268ca4adc79f5 Make bootstrap backend tests hermetic
4cb474aea7111db4ed78ce573a8027d7604e452e no-mistakes(review): Fix direct account routing and secondmate recovery
c264874eeae56343c7ec222818d5792bb144933a no-mistakes(review): Complete direct account routing cutover fixes
feb6c44d28bccb9fe13b50172780c62e953efd6e no-mistakes(review): Preserve direct recovery context and actionable diagnostics
4e0d3c4fbf600b7f4f015937e431e9f3db6d1ffc no-mistakes(review): Harden direct recovery identity and retained endpoint cleanup
8dee67eb47f992d08b2119ebabdf3cf86df0c289 no-mistakes(review): Harden direct recovery worktree identity validation
98a9bb766554207fdc94be62f7fab8fb236f1a7f no-mistakes(review): Harden direct routing recovery identity and retained state
18fd38d37bd024ffe62f39e514a14ee924a994e4 no-mistakes(review): Finalize direct recovery identity and cleanup lifecycle
359f9d0ff275cd30a0ac6b084c3cb981917e6965 no-mistakes(review): Defer direct secondmate sync to guarded recovery
a4dbcafe6da1dee78af730c5f453e64fa20e8b33 no-mistakes(review): Restore legacy secondmate routing scope
295ec04fab3a90a4952be55d839c5a15c4abecbd no-mistakes(test): Fix legacy continuation missing-brief fixture
f036ae7ed3ccdce7c8acc8fb60a1fe0b6f22af42 Fix account launch shell lint

preserved_commit_count=13
review_hardening_commit_count=9

pipeline_fix_target=049e00b16e5d48d551da93941a0da545e20b4e1b
pipeline_fix_parent=f036ae7ed3ccdce7c8acc8fb60a1fe0b6f22af42
pipeline_fix_subject=no-mistakes(review): Preserve retained direct recovery state during teardown

publication_branch_ref=049e00b16e5d48d551da93941a0da545e20b4e1b
checked_out_head=049e00b16e5d48d551da93941a0da545e20b4e1b

Configured remotes (no upstream remote configured):
origin	https://github.com/ruby-dlee/firstmate.git (fetch)
origin	https://github.com/ruby-dlee/firstmate.git (push)
Evidence: GitHub publication state
Replacement PR lookup for fm/cutover-publish-p1:
[]

Hand-raised PR #23 (must not be reused):
number=23 state=OPEN head=fm/publish-account-directory-cutover base=main url=https://github.com/ruby-dlee/firstmate/pull/23
- Outcome: ⚠️ 1 warning across 1 run (1h7m56s)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

⚠️ **Rebase** - 1 warning
  • ⚠️ AGENTS.md - branch carries 13 commit(s) that exist on your local main branch but were never pushed to origin/main; rebasing would bundle this unrelated work (15 file(s)) into the PR:
  • f036ae7 Fix account launch shell lint
  • 295ec04 no-mistakes(test): Fix legacy continuation missing-brief fixture
  • a4dbcaf no-mistakes(review): Restore legacy secondmate routing scope
  • 359f9d0 no-mistakes(review): Defer direct secondmate sync to guarded recovery
  • 18fd38d no-mistakes(review): Finalize direct recovery identity and cleanup lifecycle
  • 98a9bb7 no-mistakes(review): Harden direct routing recovery identity and retained state
  • 8dee67e no-mistakes(review): Harden direct recovery worktree identity validation
  • 4e0d3c4 no-mistakes(review): Harden direct recovery identity and retained endpoint cleanup
  • feb6c44 no-mistakes(review): Preserve direct recovery context and actionable diagnostics
  • c264874 no-mistakes(review): Complete direct account routing cutover fixes
  • 4cb474a no-mistakes(review): Fix direct account routing and secondmate recovery
  • 9ceada3 Make bootstrap backend tests hermetic
  • 610f55d Launch crews from account directories

Push main to origin, or rebase your branch onto origin/main, before gating.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ bin/fm-spawn.sh:1071 - Failed direct recovery persists direct_recovery_cleanup, backup, and artifact markers, but teardown only handles direct_spawn_cleanup. Tearing down this retained recovery can delete its metadata/worktree while orphaning rollback artifacts and losing the prior-generation restoration path. Handle direct-recovery markers equivalently or explicitly refuse teardown while cleanup is pending.

🔧 Fix: Preserve retained direct recovery state during teardown
✅ Re-checked - no issues remain.

⚠️ **Test** - 1 warning
  • ⚠️ A read-only GitHub check found no PR for fm/cutover-publish-p1; hand-raised PR feat: launch crews from per-account directories (publish local-only cutover) #23 remains open on the separate fm/publish-account-directory-cutover branch. The replacement-PR outcome therefore cannot yet be demonstrated during this pre-publication validation. Decide whether to accept this evidence until the pipeline’s push/PR stage runs, or require post-publication verification.
  • 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; uv run --directory tools/agent-fleet --locked pytest || rc=1; uv run --directory tools/agent-fleet --locked python -m compileall -q src || rc=1; exit "$rc"
  • Validator-supplied baseline: command -v tmux …; for t in tests/*.test.sh; …; uv run --directory tools/agent-fleet --locked pytest; uv run --directory tools/agent-fleet --locked python -m compileall -q src (passed before this run).
  • FM_TEST_FOCUSED=direct-recovery-cleanup bash tests/fm-teardown.test.sh
  • FM_TEST_FOCUSED=direct-recovery-lifecycle bash tests/fm-account-directory.test.sh
  • FM_TEST_FOCUSED=account-directory-cutover bash tests/fm-bootstrap.test.sh
  • FM_TEST_FOCUSED=account-directory-cutover bash tests/fm-dispatch-select.test.sh
  • Commit topology inspection using git rev-list, git show, and git show-ref.
  • Read-only publication checks: gh pr list -R ruby-dlee/firstmate --state all --head fm/cutover-publish-p1 … and gh pr view 23 -R ruby-dlee/firstmate ….
  • Final cleanup check: git status --short --branch.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@ruby-dlee
ruby-dlee merged commit 0deccf0 into main Jul 24, 2026
5 checks passed
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