feat(spawn): pin each secondmate's Claude account to its own home - #2859
Open
Lyxterai wants to merge 5 commits into
Open
feat(spawn): pin each secondmate's Claude account to its own home#2859Lyxterai wants to merge 5 commits into
Lyxterai wants to merge 5 commits into
Conversation
fm-spawn forwarded only firstmate's OWN CLAUDE_CONFIG_DIR onto claude launches, and only when it happened to be set in the invoking environment. That is fleet-wide and all-or-nothing: a secondmate that is a separate business with its own Claude subscription still billed the primary's account, and forcing the right store by hand at one relaunch reverted on the next automatic respawn. A home now pins its Claude account in a local, gitignored config/claude-account holding the absolute path of a Claude config store. fm-spawn resolves the store from that file at every launch instead of inheriting it from the invoking environment, so the pin holds across every respawn path: a fresh spawn, the session-start liveness respawn that passes only the task id, a control-plane relaunch, and a remote route's host-local launch. /updatefirstmate never relaunches an agent, so it cannot move one. A --secondmate spawn reads the target home's file and a crewmate or scout spawn reads its own home's, which is what carries the account down to the workers a pinned second mate spawns itself. A pinned secondmate gets the store whatever harness its own agent runs, because a codex or cursor second mate still spawns claude workers. A remote route's pin lives in the remote home's config/, where the host-local spawn reads and validates it against the filesystem it is on. With no pin the forwarded store is firstmate's own CLAUDE_CONFIG_DIR exactly as before, so unpinned spawns are unchanged. A pin that is not an absolute, traversal-free, readable, searchable directory refuses the spawn before any endpoint exists rather than falling back to the primary's account, because silently billing the wrong subscription is the failure the pin exists to prevent. A pinned launch reports claude_account=<path>. The file is deliberately outside the inherited config set: inheriting an account pin would put the whole fleet back on one subscription.
…able config, extract line parser
…success-line docs
Confidence Score: 5/5The PR appears safe to merge; no concrete blocking or independently actionable non-blocking defect remains. The account pin is resolved from the appropriate durable home, validated consistently before spawn and relaunch mutation, and covered across local, remote, pinned, unpinned, and refusal paths. Reviews (1): Last reviewed commit: "no-mistakes(document): clarify claude-ac..." | Re-trigger Greptile |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Gives each persistent secondmate its own durable Claude account (credential/config store), so work done by one secondmate bills that secondmate's own Claude subscription instead of the primary's.
config/claude-accountpin resolved fresh from durable state at every spawn (not inherited from the launching environment), so it survives every respawn path: session-start liveness relaunch,/updatefirstmate, andfm-control relaunch.fm-spawn.shforwarding once the secondmate's own environment carries the value.Test plan
tests/following the existing<subject>.test.shpattern (fm-control-relaunch.test.sh,fm-remote-secondmate-lifecycle-e2e.test.sh,fm-spawn-dispatch-profile.test.sh)bin/fm-lint.shpasses, changedbin/*.shshellcheck-cleanbin/fm-doc-audience-check.shpasses🤖 Generated with Claude Code