Repository navigation
fix(host): keep channel names unique when an agent or person renames a channel - #518
Merged
Merged
Conversation
…a channel The host injects a name claim into the channel. An owner's rename to a taken name is refused; an agent's chosen name is numbered (name-2, ...) and the tool result says so. The check covers taken(): every channel record on the host, including hidden and archived ones, and their lane prefixes. Checks and writes run under a host-wide SQLite lock shared by the host and workers. Fixes #503 Why: apps/host/src/catalog.ts#function claim | the name is written to the record inside the names.lock transaction, before pi commits it, so a concurrent claim in another worker sees it as taken
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.
Fixes #503
Channel names were only checked at creation. Now the host injects a
claiminto the channel (packages/channelstays runtime-neutral), and both rename paths go through it:channeltool: a taken name is numbered with fork's scheme (name-2,name-3, …), and the tool result saysAnother channel is named X, so this channel is named X-2.#rename,ace rename, the app): a taken name is refused with "A channel named X already exists", same as creation.Decision on the first open question — scope: uniqueness is per host and covers the same set as
taken(): every channel record on this host, including hidden and archived ones and other tailnets' records, plus their lane prefixes. A channel's own name and prefix are excluded, so renaming back to its original name works. Other hosts' channels in the directory and hosted channels in the team's cell are out of scope.Second open question — races: the check and the record write happen inside one
BEGIN EXCLUSIVEtransaction on a host-wide$ACE_HOME/channels/names.lockSQLite file, shared by the host process and every channel worker. The claimed name goes intochannel.jsonbefore pi commits it, so a concurrent claim in another worker already sees it as taken.catalog.createtakes the same lock, so creating a channel can't race a rename either.Notes:
channel.jsonand pi's metadata doc are unchanged;names.lockholds no data.services/channel) don't passclaim, because the cell can't see the host's channels, so their renames are still unchecked. Fork and hosted creation still check, then save after awaits, as before this change.forknow uses the sharedunused()numbering helper.Smoke-tested with the lane's CLI against an isolated
ACE_HOME(separate port and keychain service, so the running app and host weren't touched):ace rename beta alpha→ refused;ace rename beta gammathengamma beta(its own prefix) → allowed.alphawas renamed toomega,ace rename beta alpha→ refused, because ofomega's lane prefix.ace renamecalls todeltafrom different channels → one succeeded, one was refused.delta→ the tool returnedAnother channel is named delta, so this channel is named delta-2, andace lsshoweddelta-2.Built in Ace
No — Claude Code subagent outside Ace, run by the lead during a batch of fixes.