Repository navigation
fix(byo): the default agent name follows where it runs - #2365
Conversation
C14 call rehearsal, 2026-10-20: after "Run it here" created `<user>-agent`, "Use my own agent" pre-filled the same name, and "Get my connect command" was refused with "Commonly runs this agent, so it has no runtime token. To run an agent yourself, connect your own agent instead." That is what the person was doing, and it would have happened on the call right after the hosted step. - Hosted (and no choice yet) keeps `<user>-agent`. Your own agent defaults to `<user>-<claude|codex>`, following the adapter; a computer placement to `<user>-<adapter|local>`. The default updates with the mode and the adapter only while the person hasn't typed a name, and a typed name is never replaced. - If a name still collides with the person's hosted agent, the `in_process_agent_no_token` refusal reads "<name> is your hosted agent's name, and Commonly runs that one. Choose a different name for the agent you run yourself." (en, zh-CN), on both the own-agent and computer paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wkz5axAzCvoLEFkZ5KtkKG
lilyshen0722
left a comment
There was a problem hiding this comment.
Code gate — #2365 at 712d2ae7a2eb59531c50b0057042939475066a69
origin/main = cd37b32e0f9288ee24922362d3b86d17c5590368, which is this PR's merge-base. CI at the exact head: 14 pass / 2 skipping; Test & Coverage and Service Tests (Tier 1 — real DBs) SUCCESS in run 39507848455, E2E Tests in 39507848886, both head_sha read back as the head above. BASE: 10 BYO suites / 75 tests. tsc reports 28 errors on the tree, none in the changed file; eslint 0 errors, 2 warnings, both the house react/jsx-filename-extension noise.
The fix is right and your four mutations all discriminate. Two findings, and one of them is the question you asked me to check.
1. A persona card CAN be overwritten by a mode click — on the link shape that has no ?name=
?persona= and ?name= are independent params (:134 and :135), so a persona deep link without a name leaves nameTouched false and the branch order in defaultNameFor is the only thing protecting the name. Moving the persona branch below the mode branch leaves 75 / 75 green, and it is a live behaviour change. Probed at /v2/agents/byo?persona=code-reviewer with no ?name=:
| shipped | persona branch moved below the mode branch | |
|---|---|---|
| on load | sam-code-reviewer |
sam-code-reviewer |
| after "Use my own agent" | sam-code-reviewer |
sam-claude |
| back to hosted | sam-code-reviewer |
sam-code-reviewer |
So the property holds in the shipped code and nothing holds it in place. The existing persona arm cannot: "a card for Codex opens on Codex" comes from a link that carries ?name=, where nameTouched protects the name instead — which my nameTouched mutation confirms, since zeroing the prefill flag is exactly what breaks that arm. Two different mechanisms, one of them tested. One arm at ?persona=<key> with no ?name=, clicking through both modes, covers it.
2. The machine-placement half of the error mapping is unreachable
Dropping the IN_PROCESS_NAME_CODE branch from submitMachine's catch leaves 75 / 75 green, and that is not only a missing arm — nothing can trigger it. submitMachine calls exactly two endpoints, and neither can produce that code:
POST /api/registry/install→install.tsimports onlyAUTO_GRANTED_INTEGRATION_SCOPESandrevokeRuntimeTokensAfterLastUninstallfromtokens.ts(install.ts:45-48), and neither is a mint path.POST /api/agent-binding/request→agentBinding.ts:203, whose only 409 is{ message: 'Agent is bound to another machine — release it first', boundTo }, with nocode.
All five throw sites of InProcessAgentTokenRefused are inside backend/routes/registry/tokens.ts (:269, :350, :366, :377), and only two routes surface it: agentBinding.ts:389, which is inside router.post('/runtime-token') and gated by daemonAuth so no browser reaches it, and registry/agent-tokens.ts:196, which is the own-agent token route at V2AgentBYO.tsx:571. So the own-agent mapping is live and pinned (dropping it fails the fourth arm); the machine one is dead code that reads as a shipped fix. Harmless today, and it becomes correct the moment /request or /install learns to refuse the name — I would keep it and say so in the comment rather than remove it, but "on both submit paths" overstates what ships.
The open question underneath it, which I did not test and which is not this PR's: /api/agent-binding/request has no in-process guard at all — I grepped the handler for runsInProcess|native|hosted|runtimeType|in_process and got nothing. Reading it, a hosted agent's name resolves to a real identity, passes the bound-to-another-machine check, and reaches User.updateOne(..., { $set: { 'botMetadata.requestedMachineId': … } }). What consumes that field for an in-process agent I did not trace, so I am flagging the absence of the guard rather than claiming an outcome.
Verified as claimed
Needle asserted at one occurrence, site printed, source restored and re-verified after every run:
| mutation | site | result |
|---|---|---|
own-agent default back to -agent |
V2AgentBYO.tsx:165 |
3 failed |
| overwrite typed names | :265 |
3 failed |
| drop the error mapping, own-agent path | :588 |
1 failed |
| ignore the adapter | :165 |
3 failed |
nameTouched ignores a ?name= prefill (mine) |
:169 |
1 failed |
drop the local auto-detect fallback (mine) |
:165 |
1 failed |
drop setNameTouched from onChange (mine) |
:994 |
1 failed |
| persona branch below the mode branch (mine) | :163 |
75 / 75 |
| drop the error mapping, machine path (mine) | :516 |
75 / 75 |
The last two are findings 1 and 2. The seven above them cover every other term of the property, including the two halves of "a typed name is never replaced" separately — the effect guard and the onChange flag each have their own failing arm, which is the right shape for a two-term guarantee.
Also checked: cleanName is in scope at both catch sites (a parameter of submitMachine, a local in submit), the two fallback chains match their routes' payload shapes (message first for the binding route, error first for the token route), and agentByo.errors.nameIsHosted exists in both en.json and zh-CN.json with the {{name}} placeholder.
The two moved expectations are honest: V2AgentBYOMachine moves to sam-local and V2AgentBYOListenVerify to sam-claude because the defaults changed, each with a comment saying so, and three of the mutations above break those exact values — so they are pinned to the new behaviour rather than loosened to accommodate it.
Written by sprint-review, a Commonly agent — https://commonly.me/v2/pods/6a692a1be833c668acdb84cf
GATE: PASS
…chine mapping defensive sprint-review on #2365 (PASS at 712d2ae, two findings): - With ?persona= and no ?name=, only the persona branch's place in defaultNameFor keeps a mode click from renaming the agent; moving it below the mode branch stayed green. New arm; that mutation now fails it. - The machine path's in_process_agent_no_token mapping can't fire today: neither /api/registry/install nor /api/agent-binding/request returns the code. Kept, with a comment saying so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wkz5axAzCvoLEFkZ5KtkKG
lilyshen0722
left a comment
There was a problem hiding this comment.
Re-gate — #2365 at b337667396fc10f4f5240f1649e1c812fac79faf
Baseline: my PASS at 712d2ae7. One commit since, b3376673, authored Lily Shen. origin/main = cd37b32e0f9288ee24922362d3b86d17c5590368, still the merge-base. CI at the exact head: 14 pass / 2 skipping, Test & Coverage and Service Tests (Tier 1 — real DBs) SUCCESS in run 39513341291, head_sha read back as the head above. BASE: 10 suites / 76 tests, up one arm.
Both findings closed. One cross-PR note, because #2369 is in the same batch.
Finding 1 is pinned
Moving the persona branch below the mode branch now fails exactly one arm:
● BYO default agent name follows where it runs › a persona link without ?name= keeps the persona name through both modes
Tests: 1 failed, 75 passed, 76 total
A correction to my own measurement while I am here: my first run of this mutation reported 15 failures. That was my machine, not your code — I had three mutation batteries running at once, and the V2Thread/BYO suites are timing-sensitive under that load. Re-run on an idle machine it is the single arm above, which is the right answer and the one to trust.
Finding 2 is closed as documentation, and that documentation expires on Wednesday
The component change is exactly two comment lines; I diffed it to be sure nothing else moved. The comment reads:
// Defensive: neither route this path calls returns the in-process code
// today (sprint-review on #2365). It reads right the day one does.
#2369 is the day one does, and it ships in the same deploy. I built the merge of this head with 3a7f4a9a and ran it: clean, 10 suites / 77 tests pass, and in that tree POST /api/agent-binding/request returns in_process_agent_no_token, so the branch this comment calls defensive is live and renders agentByo.errors.nameIsHosted instead of the server's message.
So whichever of the two merges second should drop or amend those two lines, or they ship saying the opposite of what the code does. That is the only thing I would change, and it is a comment.
Written by sprint-review, a Commonly agent — https://commonly.me/v2/pods/6a692a1be833c668acdb84cf
GATE: PASS
Why
In the C14 call rehearsal on live, 10-20, "Run it here" created
<user>-agent. Then "Use my own agent" pre-filled the same name. "Get my connect command" was refused with:Connecting their own agent is exactly what the person was doing. On the call it would have happened right after the hosted step, which is the note's step 3 into step 4.
What
frontend/src/v2/components/V2AgentBYO.tsx:<user>-agent, as before.<user>-claudeor<user>-codex, following the adapter, including?adapter=codexlinks.<user>-<adapter>, or<user>-localfor auto-detect.my-mcp-agent" effect.in_process_agent_no_tokenrefusal reads " is your hosted agent's name, and Commonly runs that one. Choose a different name for the agent you run yourself." It's in en and zh-CN (智能体, 你). It is live on the own-agent token path. The computer-placement path carries the same mapping as a defensive branch: neither route it calls returns that code today (sprint-review).Tests
V2AgentBYOName.test.tsx, with hosting on so the page asks where the agent runs:sam-agent, own agent becomessam-claude, and switching back returnssam-agent;?adapter=codexlink givessam-codex;?name=keepssam-<card>through both modes (added after sprint-review's PASS; moving the persona branch below the mode branch now fails it);in_process_agent_no_tokenshows the new message, not "has no runtime token".Two existing expectations change on purpose: the machine placement is now
sam-local, and the issued own agent issam-claude. All 10 BYO suites pass.Mutations. Each fails a test:
-agenttscreports no frontend errors and lint reports 0 errors.git merge-treeis clean against #2297, #2196 and #2307, the open PRs touching this file or the locales.Merge
Draft, aimed at Wednesday's second deploy. The cut-off is an exact-head PASS by Wed 13:30 PT.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Wkz5axAzCvoLEFkZ5KtkKG