Skip to content

chore(identity): remove the legacy underscore-username tier - #1400

Merged
kentcdodds merged 3 commits into
mainfrom
cursor/remove-legacy-username-tier-1636
Aug 12, 2026
Merged

kentcdodds merged 3 commits into
mainfrom
cursor/remove-legacy-username-tier-1636

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Aug 12, 2026 •

Copy link
Copy Markdown
Owner

Intent

Kent's call: no legacy affordances for underscore usernames. The two-tier validation from #1395/#1396 (lenient recognition of stored usernames, strict DNS labels for new ones) existed to protect existing underscore accounts — but production has exactly one, and it has now been migrated, so the lenient tier guards nobody and is pure legacy residue.

Summary

  • Production migration (already done, verified): the single underscore account debs_obrien (user 42, 2 stock platform forks, 1 inbox alias, no community listings, no debs-obrien collision) was renamed by hand via the D1 API: users.username, email_inbox_addresses.address/local_part, and both saved_packages.name values → debs-obrien. A post-migration sweep confirms zero underscore usernames, package scopes, or inbox locals remain.
  • getUsernameFormatValidationError is strict (DNS label) again and is the only username format rule; getDnsSafeUsernameValidationError and the lenient legacy pattern are removed.
  • The 409 "rename your username" response on the package-app entry is removed (unreachable: underscore paths no longer parse).
  • resolveHostedPackageAppUrl no longer falls back to the path mount for non-DNS-safe usernames; package_app_fetch mount selection simplifies accordingly.
  • dnsSafeUsernamePattern / isDnsSafeUsername stay in packages/shared/src/public-urls.ts as the single source of truth — still needed to validate subdomain labels from wildcard-routed hostnames, which are arbitrary strings.
  • Docs and decision 0017 record the one-time manual migration instead of the two-tier scheme (including the stale Consequences bullet CodeRabbit caught).
  • Drive-by CI unblock: the mock cloudflare preview worker's DO migrations switch from new_classes to new_sqlite_classes. Cloudflare now rejects creating key-value backed DO namespaces (error 10099), and every PR preview deploys a fresh mock script that runs these migrations from scratch — preview resource deploys were failing repo-wide (first seen on this PR's preview). Long-lived scripts already applied tags v1/v2 and are unaffected.

Known residual (self-healing): the package.json files inside her two Artifacts repos still say @debs_obrien/...; her next publish fails scope validation with a clear message prompting the fix. They are unmodified platform forks. Kent may want to give Debbie a heads-up that her handle is now debs-obrien.

Testing

  • npm run validate green (E2E was an infra flake — workerd webserver crash — and passed on re-run; Nx flagged the task flaky).
  • Updated: identity unit tests (strict-everywhere incl. resolveDisplayName fallback), removed the legacy-owner workers test; the full subdomain/handoff/host-label workers suite and search-identity/app-base-url/auth/account-profile suites pass unchanged otherwise.
Open in Web Open in Cursor 

Summary by CodeRabbit

  • Bug Fixes

    • Standardized username validation to allow only lowercase letters, numbers, and hyphens.
    • Removed legacy underscore username handling and migration prompts.
    • Improved hosted package-app routing with consistent subdomain behavior.
    • Invalid or nested hostname labels now fail safely with a 404 response.
  • Documentation

    • Updated security and architecture guidance to reflect strict DNS-safe username requirements.

Production had exactly one underscore username (debs_obrien); it was
renamed by hand on 2026-08-12 (users.username, email_inbox_addresses,
saved_packages names -> debs-obrien), so the two-tier validation shipped
in #1395/#1396 no longer guards anyone. Username validation is one strict
DNS-label rule everywhere again: the lenient recognition pattern, the
separate DNS-safe validator, the 409 rename prompt on the package-app
entry, and the hosted-URL path-mount fallback for non-DNS-safe usernames
are all removed. The shared dnsSafeUsernamePattern stays as the single
source of truth (also validating wildcard-routed subdomain labels).

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c19b3582-bb84-4fbc-9ecf-6282fd66af16

📥 Commits

Reviewing files that changed from the base of the PR and between 1c1f395 and 137469c.

📒 Files selected for processing (1)
  • docs/contributing/decisions/0017-per-user-package-app-subdomains.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/contributing/decisions/0017-per-user-package-app-subdomains.md

📝 Walkthrough

Walkthrough

The change removes legacy underscore-username handling. Username validation now applies strict DNS-label rules, and configured package-app origins consistently use per-user subdomains.

Changes

Username and package-app routing

Layer / File(s) Summary
Strict username validation
packages/worker/src/identity/username.ts, packages/worker/src/identity/platform-account-creation.ts, packages/worker/src/identity/username.node.test.ts
Username validation now uses the DNS-safe format directly. Platform account creation and tests use the shared format validator.
Package-app URL and origin routing
packages/shared/src/public-urls.ts, packages/worker/src/app/package-app-origin.ts, packages/worker/src/mcp/capabilities/packages/package-app-fetch.ts
Configured package-app origins use user subdomains without DNS-specific username checks. Origin redirects and package dispatch no longer use the username-path fallback.
Routing and security documentation
docs/contributing/decisions/0017-per-user-package-app-subdomains.md, docs/contributing/security.md
The documentation states that strict DNS-label usernames are required, legacy accounts were migrated, and invalid or nested labels return 404.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely identifies the removal of the legacy underscore-username validation tier.
Description check ✅ Passed The description includes intent, summary, testing results, migration evidence, and relevant residual risk; the optional system changes section is not required.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/remove-legacy-username-tier-1636

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kentcdodds
kentcdodds marked this pull request as ready for review August 12, 2026 03:17

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/contributing/decisions/0017-per-user-package-app-subdomains.md`:
- Around line 50-55: Update the outdated underscore-account consequence in this
decision document to reflect that the sole legacy account was already renamed
and no rename is required before hosting; replace the statement with a concise
historical migration note or remove it, while preserving the current strict
DNS-label policy.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b6252b05-1010-4315-bf30-f98fca023373

📥 Commits

Reviewing files that changed from the base of the PR and between 7ec8929 and 1c1f395.

📒 Files selected for processing (9)
  • docs/contributing/decisions/0017-per-user-package-app-subdomains.md
  • docs/contributing/security.md
  • packages/shared/src/public-urls.ts
  • packages/worker/src/app/package-app-origin.ts
  • packages/worker/src/app/package-app-origin.workers.test.ts
  • packages/worker/src/identity/platform-account-creation.ts
  • packages/worker/src/identity/username.node.test.ts
  • packages/worker/src/identity/username.ts
  • packages/worker/src/mcp/capabilities/packages/package-app-fetch.ts
💤 Files with no reviewable changes (2)
  • packages/worker/src/app/package-app-origin.ts
  • packages/worker/src/app/package-app-origin.workers.test.ts

Comment thread docs/contributing/decisions/0017-per-user-package-app-subdomains.md
cursoragent and others added 2 commits August 12, 2026 03:20
The sole underscore account was already migrated; CodeRabbit caught the
stale Consequences bullet still requiring renames before hosting.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Cloudflare now rejects creating key-value backed Durable Object
namespaces (error 10099). Every PR preview deploys a fresh
kody-pr-<n>-mock-cloudflare script that runs these migrations from
scratch, so preview resource deploys started failing repo-wide. Existing
long-lived scripts already applied tags v1/v2 and are unaffected.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-1400.kody-a99.workers.dev

Worker: kody-pr-1400
Runtime worker: kody-pr-1400-runtime (https://kody-pr-1400-runtime.kody-a99.workers.dev)
D1: kody-pr-1400-db
KV: kody-pr-1400-oauth-kv

Mocks:

@kentcdodds
kentcdodds merged commit cf7aef4 into main Aug 12, 2026
10 checks passed
@kentcdodds
kentcdodds deleted the cursor/remove-legacy-username-tier-1636 branch August 12, 2026 03:31
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.

2 participants