fix(executor): don't route a task whose project already pins a Claude profile - #697
Merged
Conversation
routeTask only checked the per-task config dir, so a project that names its own was silently overridden. That is worse than untidy: a config dir carries the account's MCP connectors and their OAuth logins, and those logins are per-profile keychain entries that cannot be shared. An influencekit task routed onto a personal profile does not error — it runs without the Linear/InfluenceKit servers it needs and the agent works around the gap, which is how we got executors hacking the DB when taskyou's own MCP went missing. Syncing the definitions across profiles would not have helped, since the credentials do not travel and a defined-but-unauthenticated server is no better than a missing one. So the project's choice is the lever: pinning a config dir is now also how a project opts out of routing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
govulncheck flags this one as reachable, not merely present: the trace is internal/server -> charmbracelet/ssh -> golang.org/x/crypto/ssh, which is ty's own SSH server. The advisory covers callbacks in that package. Pulled forward x/sys, x/term and x/text as go mod tidy required. The CI job is continue-on-error, so this was not blocking the PR — it is here because a reachable CVE in the SSH server we expose is worth fixing when we notice it, not when something forces us to. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
routeTaskonly checked the per-task config dir, so a project that pins its own was silently overridden.That's not cosmetic. A config dir carries the account's MCP connectors and their OAuth logins, and those logins are per-profile keychain entries — they can't be shared. On this machine
influencekitpins~/.claude-ik, which holds ~12 connector logins (InfluenceKit, Figma, Cloudflare, Linear-influencekit…);~/.claude-offerlabhas 2, and a different Linear workspace. Routing an influencekit task onto the other profile doesn't error — it runs without the servers it needs and the agent works around the gap. That's the shape of the incident where executors lost taskyou's MCP and started hacking the DB directly.Syncing definitions across profiles wouldn't fix it either: the credentials don't travel, and a defined-but-unauthenticated server is no better than a missing one. So the project's own setting is the lever — pinning a project's config dir is now also how it opts out of routing.
Unpinned projects still route, so the feature is unaffected where profiles are interchangeable.
Tests
TestRouteTask_ProjectPinnedProfileIsNotOverridden— a pinned project is left alone.TestRouteTask_UnpinnedProjectStillRoutes— the flip side, so the fix can't quietly disable routing.Also: golang.org/x/crypto v0.52.0 → v0.55.0
GO-2026-6303(callbacks ingolang.org/x/crypto/ssh) turned red on this PR — published after main's last CI run, so main is green only by timing. It predates this branch, which touches neithergo.modnorgo.sum, and the job iscontinue-on-error, so it was never blocking.Fixed here anyway because govulncheck flags it as reachable, not merely present:
internal/server→charmbracelet/ssh→golang.org/x/crypto/ssh, i.e. ty's own SSH server.go mod tidypulled x/sys, x/term and x/text forward with it. Verified locally: the finding is gone, and what remains is stdlib on go1.25.5 — CI uses 1.25.14 withcheck-latest: true, where those are already patched.Follow-up to #690.
🤖 Generated with Claude Code