Skip to content

fix(byo): the default agent name follows where it runs - #2365

Merged
lilyshen0722 merged 2 commits into
mainfrom
fix/byo-default-name-by-mode
Oct 21, 2026
Merged

lilyshen0722 merged 2 commits into
mainfrom
fix/byo-default-name-by-mode

Conversation

@lilyshen0722

@lilyshen0722 lilyshen0722 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

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:

Commonly runs this agent, so it has no runtime token. To run an agent yourself, connect your own agent instead.

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:

  • The default name follows where the agent runs.
    • Hosted, or no choice made yet: <user>-agent, as before.
    • Your own agent: <user>-claude or <user>-codex, following the adapter, including ?adapter=codex links.
    • A computer placement: <user>-<adapter>, or <user>-local for auto-detect.
  • A typed name is never replaced. The default re-applies when the user loads, or when the mode or adapter changes, only while the person hasn't typed. That replaces the old "refresh if still my-mcp-agent" effect.
  • A remaining collision with the person's hosted agent is explained. The in_process_agent_no_token refusal 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:

  • hosted stays sam-agent, own agent becomes sam-claude, and switching back returns sam-agent;
  • a ?adapter=codex link gives sam-codex;
  • a typed name survives both mode switches;
  • a persona link without ?name= keeps sam-<card> through both modes (added after sprint-review's PASS; moving the persona branch below the mode branch now fails it);
  • the 409 with in_process_agent_no_token shows 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 is sam-claude. All 10 BYO suites pass.

Mutations. Each fails a test:

mutation result
own-agent default back to -agent 2 failed
overwrite typed names 2 failed
drop the error mapping 1 failed
ignore the adapter 1 failed

tsc reports no frontend errors and lint reports 0 errors. git merge-tree is 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

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 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.ts imports only AUTO_GRANTED_INTEGRATION_SCOPES and revokeRuntimeTokensAfterLastUninstall from tokens.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 no code.

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 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@lilyshen0722
lilyshen0722 marked this pull request as ready for review October 21, 2026 18:26
@lilyshen0722
lilyshen0722 added this pull request to the merge queue Oct 21, 2026
Merged via the queue into main with commit e861ff4 Oct 21, 2026
30 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