Usernames and owner-scoped project addresses like GitHub (/owner/project) #351

doneCreated by Claude Code (User hu_yMavF3p1) • Assigned to Claude Code (User hu_yMavF3p1) • Normal priority

Description

People (and organizations) get a unique, public handle, and project addresses become /{owner}/{project} instead of /projects/{slug}, as on GitHub. Idea from the user, 2026-09-24 ("evtl": decide before building).

Why now

Public projects (#322) make addresses something people share, link from READMEs and bookmark. Changing the address scheme after projects went public breaks those links, so this should be decided before or together with #322.

Today

  • UserAccount has DisplayName (not unique) and PublicId; no handle. Organizations have a Name.
  • Project.Slug is globally unique (unique index); a second "Memory MCP" becomes memory-mcp-2. Renaming a project changes its slug and the old address answers not found (ProjectRouteTests asserts this).
  • Every web route lives under a fixed first segment: agents, auth, connect, contact, explore, guide, imprint, login, memories, moderation, not-found, organizations, privacy, projects, register, sessions, settings, terms, trust; plus /mcp, /_blazor, /_framework, static files and badge.svg links.
  • MCP and .agents/conderis.json use the project id, so agents are not affected by addresses.

Decide first

  1. One namespace for people and organizations (like GitHub), so /acme/app works whether acme is a person or an organization? Proposal: yes.
  2. Handle rules: allowed characters and length (for example a-z0-9-, 2 to 39, no leading or trailing hyphen), case-insensitive uniqueness, and a reserved list containing every current and planned top-level route (see Today) plus names like admin, api, www, help, support, conderis.
  3. Choosing a handle: at sign-up, and for existing accounts on next sign-in. Never derived silently from the sign-in address, since its local part can be personal; a suggestion from the display name that the person confirms.
  4. Project names unique per owner instead of globally, with a migration of the unique index. Existing slugs stay as they are.
  5. Old addresses keep working: /projects/{slug}/... answers with a permanent redirect to /{owner}/{slug}/..., and so do addresses from before a rename of a handle or project (a redirect table like GitHub's), at least for badge.svg links in READMEs. Decide whether renames keep redirects forever or for a period.
  6. Where the owner shows: header path owner / project, sidebar entries only where names clash, Explore, project_get (for example fullName: owner/project), the badge.

Work

  • Handle on UserAccount and Organization in a shared, reserved-aware namespace; settings to choose and change it.
  • Routes /{owner}/{project} and /{owner}/{project}/{section}/... for every project page; /projects/... redirects.
  • Slug uniqueness per owner; creating, renaming and forking follow it.
  • Redirects for renamed handles and projects; badge links unaffected.
  • Guide, WEB.md routes page (#289) and the smoke test (#345) updated.

Acceptance

  • Every project page is reachable at /{owner}/{project}/...; every old /projects/{slug}/... address redirects there permanently. Tested.
  • A handle equal to a reserved route name or an existing handle (any case) is refused.
  • Two owners can each have a project called app.
  • Renaming a handle or project keeps old links and badge.svg URLs working as decided in 5.
  • No sign-in address becomes visible through a handle suggestion or an address.
Connection interrupted or session ended. Reload

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.