Username Allocation (Koder ID)
Regras de alocação de usernames no Koder ID: reservas, padrões proibidos, migração. Depende de RFC-012 (account models) e RFC-013 (invite chain). Status: Draft (proprietário: Koder ID team).
Policy — Username Allocation for Koder ID
- *wner:*Koder ID team
- *epends on:*
platform/id/v2/docs/rfcs/RFC-012-account-models.md,platform/id/v2/docs/rfcs/RFC-013-invite-chain.md - *ate:*2026
0411 - *tatus:*Draft
Scope
This policy governs the allocation, format, reservation, transfer, and reclamation of user handles in the Koder ID individual account namespace. Every handle h in this namespace becomes the email address h@koder.dev and the public identifier @h throughout the Koder ecosystem.
Workspaceowned email addresses (012 for the distinction.ana@crescer.com.br, rodrigo@vivver.com.br, etc.) are *ot*governed by this policy — they are issued by the workspace admin under the workspace's own domain. See RFC
Format rules
A handle is a string satisfying all of:
- *ength:*2 to 20 characters
- *haracters:*lowercase ASCII letters (
a–z), digits (0–9), hyphens (-), dots (.) - *ust start*with a letter
- *ust not end*with a hyphen or a dot
- *o consecutive special characters*—
foo..bar,foo--bar,foo-.barare invalid - *o leading digits*—
2rodrigois invalid (digit in any other position is fine:rodrigo2,r2d2) - *o RFC
5321 localpart edge cases*— anything that would require quoting in an email local part is forbidden, even if technically legal
*anonicalization:*handles are stored and compared in lowercase ASCII; Unicode is not permitted in the current version. A user who types Rodrigo@koder.dev gets routed to the same identity as rodrigo@koder.dev.
*onfusable check:*on allocation, the candidate handle is checked against a confusables table (similar to IDN homograph detection). rodrlgo (lowercase L instead of i) is rejected if rodrigo already exists. The confusables set is versioned and enforced only at allocation — existing handles are never broken by adding new confusables.
Length tiers and tier-based reservation
Handles are partitioned into *ength tiers*with different allocation rules:
| Tier | Length | Allocation rule |
|---|---|---|
| *2* | 2 chars | *eserved*for Koder staff (roles staff or board). Allocated during Phase 0 only. Cannot be claimed by external users. |
| *3* | 3 chars | *eserved*for trust-score ≥800 during Phases 0 and 1; opens to general allocation in Phase 2 if still available |
| *4–T6* | 4–6 chars | First-come, subject to the reservation dictionary |
| *7+* | 7+ chars | First-come, subject to the reservation dictionary |
Tier T2 is the scarcity anchor — the whole namespace knows that 2letter handles are staffonly forever. This is the strongest visual marker we can give without breaking the singledomain rule from RFC012.
Reservation dictionary
Certain handles are reserved at all times and cannot be allocated to any user via the normal flow. The dictionary has the following categories:
1. System handles (locked forever)
These are used by the Koder ID service itself and by Koder system features. Examples:
admin root system koder support help
noreply postmaster abuse security hostmaster webmaster
mailer-daemon info contact privacy legal billing
api auth id oauth sso webhook
mail ns dns www ftp smtpThe full list lives in platform/id/v2/services/identity/reserved_system.txt and is loaded at service startup.
2. Product names (locked unless Koder-owned)
Every Koder product slug is reserved — these can only be used by system accounts owned by the Koder workspace:
kruze kortex flow talk jet kall
kode koda koder store wallet kdb
dok grid kompass kmd apis hubRenames are handled by adding the new name and keeping the old. The dictionary is append-only.
3. Brands and trademarks (locked)
Global brand names and registered trademarks are pre-reserved to prevent squatting. Categories include:
- *ig tech:*google, apple, microsoft, amazon, meta, facebook, twitter, x, tiktok, netflix, openai, anthropic, ...
- *anks and payments:*visa, mastercard, paypal, stripe, nubank, itau, bradesco, santander, ...
- *overnments:*gov, governo, fed, eu, un, nato, ...
- *eo:*names of countries, states, capital cities, and top-50 cities globally (one list per language)
A brand reservation means the handle is held by the Koder ID system account, not assigned to anyone. If the trademark owner wants to claim it, they go through the reclamation process (below). The initial list has ≈5000 entries; it is maintained quarterly.
4. Profanity and hate speech (locked)
Handles that would be offensive or promote hate are reserved. The list is multilingual and curated by the Koder trust & safety team. Exact contents are not public to avoid providing a blocklist users can test against; contents are versioned and updated as needed.
5. Ambiguous / confusing (casebycase)
Handles that would be routinely mistaken for system handles (e.g., admln, r00t, postmast3r) are reserved even if they pass the confusables check for existing handles. Added ad-hoc to the dictionary.
Allocation during rollout phases
The allocation rules depend on the rollout phase from RFC-012.
Phase 0 — Internal alpha (closed)
- *ho allocates:*Koder ID admin, manually, on behalf of each staff member
- *ier availability:*all tiers (T2, T3, T4+) open to staff
- *taff handle preferences:*collected via an internal form; allocated in order of seniority for conflicts, then alphabetical
- *eservation dictionary:*enforced (staff cannot take
adminorgoogle, even during Phase 0) - *udit:*every Phase-0 allocation is logged with actor, reason, and handle
Phase 1 — Invite-only (seed)
- *ho allocates:*the invitee, at redemption time
- *ier availability:*T4+ open to all invitees; T3 only to invitees with starting trust score ≥800 (i.e., invited directly by staff)
- *eservation dictionary:*enforced
- *onfusables:*enforced; the signup form suggests alternatives if the chosen handle is a confusable of an existing handle
- *eclaim path:*trademark owners can initiate reclamation (see below) even during Phase 1
Phase 2 — Public signup
- *ho allocates:*the signup user, at signup time
- *ier availability:*T3 opens to general allocation (for handles not already taken); T2 remains staff-only forever
- *eservation dictionary:*enforced
- *raud detection:*bulk handle registration patterns (many handles from same IP, same payment method, etc.) trigger review
Transfer rules
Handles are *pt-in only*transferable. There is no involuntary reassignment during normal operation.
Voluntary transfer
A user can transfer their handle to another user (both must consent) via the admin UI. The transfer:
- Requires both users to be in
status = 'active' - Requires the source user to have a secondary handle already allocated (nobody ends up identity-less after transfer)
- Is logged in the audit trail with both actor IDs
- Cannot be used to bypass the reservation dictionary (a transferred handle must have been validly owned — the dictionary check happens on allocation, not on every transfer)
Deletion and release
When a user deletes their account:
- The
usersrow is soft-deleted (deleted_atset) - *he handle is NOT released.*It remains bound to the soft-deleted user row
- Rationale: releasing the handle allows an attacker to register
@rodrigo@koder.devafter the real Rodrigo deletes his account, and impersonate him in third-party systems that cached Rodrigo's handle as an identity
Reclamation (handle release after long dormancy)
After *8 months*of continuous inactivity (no login, no API activity, no email delivery), a handle *ay*be released through a formal process:
- The identity service flags the user as
dormantat 12 months - At 15 months, an email is sent to the registered recovery address warning of pending release
- At 18 months, the handle enters
pending_releasestate for 30 days with a public listing - During the 30-day window, the owner can reactivate by logging in (reclaim is instant) OR any other user can apply to claim the handle
- After the window, if unclaimed, the handle is released and returned to the general pool; if claimed by another user, a dispute review is triggered
*his process does not apply to staff handles or to T2/T3 handles ever allocated to staff.*Once staff-tagged, a handle stays in the staff namespace even after the staff member leaves (their alumni record retains the handle).
Reclamation (trademark and impersonation disputes)
A third party may request reclamation of a handle they believe belongs to them legally (trademark) or factually (impersonation).
Process
- Submit a reclamation request via
https://id.koder.dev/reclaimor via email toabuse@koder.dev - Provide: the disputed handle, proof of trademark registration or documentation of identity, a contact email, a clear statement of what the claimant wants (transfer, take-down, suspension)
- Koder ID trust & safety team reviews within 10 business days
- If the claim is valid and the current handle holder is not a Koder staff member:
- The current holder is notified and given 14 days to respond
- If no response or the response does not establish a legitimate claim, the handle is suspended and transferred to the claimant (or parked in the reservation dictionary if the claimant only wanted take-down)
- If the claim is invalid, it is denied with a written explanation
- Disputes about the decision can be escalated to Koder legal (not in scope for this policy)
Limitations
- Trademark reclamation applies only to handles that could plausibly be confused with the trademark —
mcdonaldsis reclaimable by McDonald's,mcdonaldsptmay or may not be,iloveeatingatmcdonaldsis not - Impersonation reclamation requires evidence of actual impersonation (the holder is actively pretending to be the claimant), not just name similarity
- Celebrities and public figures can request reclamation of their own name handles if the current holder is inactive or clearly impersonating them
- Staff-held handles are not reclaimable via this process — they are resolved through internal HR/legal channels
Handle lifecycle
┌──────────────┐
│ (unclaimed) │
└──────┬───────┘
│ allocation
▼
┌──────────────┐
│ active │◄────────────────┐
└──────┬───────┘ │
│ │ reactivation
│ 12 months no activity │
▼ │
┌──────────────┐ │
│ dormant │─────────────────┘
└──────┬───────┘
│ + 6 months
▼
┌──────────────┐
│pending_release│
└──────┬───────┘
│ + 30 days
▼
┌──────────────┐
│ released │─────► back to unclaimed pool
└──────────────┘Orthogonal to lifecycle:
- *uspended*— handle is held by the user but they cannot login or use the account. Reason logged. Cleared manually by admin.
- *isputed*— handle is held but frozen pending reclamation review. Cleared by decision.
- *eserved*— handle is in the dictionary and unallocable.
Staff handle policy
Special rules apply to handles used by Koder staff (role staff in the Koder workspace):
- *nce staff, staff-marked*— a handle that was ever allocated to a staff member is tagged in the system as
staff_allocated = true, and this tag is permanent - *lumni retain their handle*— when a staff member leaves Koder and transitions to
alumni, they keep the handle; it never goes back to the pool - *2 handles are staff
only forever*— even in Phase 2, 2letter handles are not offered in the signup flow - *taff cannot take brand reservations*— even staff cannot allocate
googleorapple; the dictionary applies equally - *taff cannot self
transfer to external accounts*— a handle that was staffallocated cannot be transferred to a non-staff individual outside the alumni flow
Audit and transparency
- Every allocation is logged in
users_auditwith{handle, user_id, phase, allocator, reason} - Every transfer, reclamation, suspension, and release is logged
- Aggregate statistics (number of allocated handles, number of suspended, number of reserved) are published on a public status page; individual allocations are not
- The reservation dictionary is *ppend
only*and versioncontrolled; additions are reviewed by ≥2 members of trust & safety; removals are disallowed without RFC
Decisions — hyperscalealigned (202604-11)
These items are resolved in favor of the 100M+ tenant hyperscale target. The shape of the policy is now frozen; only cosmetic adjustments remain.
Unicode in handles — forbidden, forever (subject to new RFC)
*SCII lowercase only*in the current version and all foreseeable versions. Enabling Unicode would reintroduce:
- *omograph attacks*at massive scale (Cyrillic
аvs Latina, Greekοvs Latino, etc.) — the IDN homograph problem has been a source of phishing for 20 years and is unsolvable at the registry level - *orting and indexing complexity*— collation rules vary by locale and break global uniqueness guarantees
- *endering inconsistency*— different fonts render the same Unicode codepoint differently; users cannot reliably distinguish handles visually
- *ength ambiguity*— grapheme clusters vs codepoints vs bytes, each with different answers
The lesson from DNS, email localparts, IRC nicks, and every global identifier system is the same: *owercase ASCII is the Schelling point for global identity* Users who want nonASCII displays can set a display_name with any Unicode they want — the handle stays ASCII. A future RFC may revisit this, but it is a binding "no" for v1.
Handle resale — forbidden, period
No monetary transfer of handles, ever, by any mechanism. Reasons:
- *revents handle squatting markets*— the whole reason we have a reservation dictionary and a strict allocation policy is to prevent handles from becoming financial assets
- *revents pressure on the trust & safety team*— if handles had dollar values, every dispute would involve economic damages claims; the dispute process becomes litigation
- *revents disparate access*— wealthy users cannot buy
@ceoor@adminfrom the current holder even if both agree - *ligns with Koder's brand*— the Koder identity is a credential of membership, not a tradeable asset. Selling it would contradict "todos somos dev".
Voluntary transfers between users (no money involved) remain permitted through the normal transfer flow, but the trust & safety team audits transfers for implicit compensation patterns (off-platform payments disguised as free transfers) and can reverse suspicious transfers.
Public handle registry — yes, rate-limited
A public endpoint GET https://id.koder.dev/u/:handle is provided and returns:
{
"handle": "rodrigo",
"taken": true,
"display_name": "Rodrigo P.",
"has_avatar": true,
"badges": ["verified", "developer"], // badge kinds only, not signatures
"created_year": 2026 // year granularity, not exact date
}*ate limits:*
- *nauthenticated:*30 requests per minute per IP, 500 per hour per IP
- *uthenticated:*300 requests per minute per user, 5 000 per hour per user
- *lobal:*1M requests per hour across the entire endpoint (circuit breaker)
These limits prevent bulk handle enumeration (scraping the whole namespace) while supporting legitimate uses: signup form availability checks, profile previews, handle mention autocomplete. Suspicious patterns (sequential handle scans, randomname fuzzing) trigger perIP backoff.
The endpoint does *ot*return: email address (always derivable from handle), phone number, login methods, billing info, workspace memberships, invite chain, trust score.
Dormancy period — tiered by identity value
Revised from the single "18 months" to a tiered schedule based on identity value:
| Account class | Inactive trigger | Pending release window |
|---|---|---|
| *nverified, no paid activity, T4+ handle* | 24 months | 60 days |
| *erified (KYC badge) OR paid transaction history* | 60 months (5 years) | 90 days |
| *3 handle (3 chars)* | Never auto-releases | n/a |
| *2 handle (2 chars, staff-only)* | Never auto-releases | n/a |
| *lumni* | Never auto-releases | n/a |
| *taff* | Never auto-releases | n/a |
The tiering recognizes that at hyperscale, some handles are much more valuable and represent real people with sunk investment. Five years of inactivity is roughly the Gmail industry standard for "serious accounts." Shorter tiers for low-value accounts keep the namespace fresh.
The 18-month general cap from the earlier draft is *eplaced*by these tiers.
Staff handle after death — never reuse without nextofkin
Confirmed as policy:
- A staff member's handle is never automatically released or repurposed, even after confirmed death
- The workspacemembers row transitions to
status = 'deceased'(a new distinct status) with `deceasedat` timestamp - A memorial badge may be added with next
ofkin consent - The handle can be transferred to a named beneficiary *nly*if the staff member left explicit written instructions and next
ofkin and Koder trust & safety agree - Absent instructions, the handle stays indefinitely in the Koder workspace reservation namespace — neither released nor actively used
This same policy extends to any verified public figure whose death is confirmed — the handle is preserved as a matter of dignity, not recycled for namespace efficiency.
Machine identities — separate namespace entirely
Bots, service accounts, API integrations, webhook senders, and other non-human identities do *ot*consume human handle slots. They live in a distinct namespace with its own rules:
- *andle format:*
<name>.bot@koder.dev— the.botsuffix is reserved and may not be claimed by any human handle - *o trust score*— machines have
trust_classinstead (fromsystem,verified_org,third_party,untrusted) - *o invites*— machines are provisioned by workspace admins, not invited
- *o badges*— machines carry
service_attestationinstead (also cryptographically signed, but a different issuer key) - *tored in a separate table*
service_identitieswith its own schema (to be specified in a companion RFC)
This isolation means a human on @rodrigo@koder.dev and a machine on @rodrigo.bot@koder.dev can coexist without ambiguity — the .bot suffix is an unforgeable marker because humans cannot register handles ending in .bot.
Reservation dictionary versioning at hyperscale
At 10⁸ identities, adding entries to the reservation dictionary has operational impact: handles that were valid allocations yesterday cannot be re-queried as valid today, which breaks assumptions. Policy:
- *ppend-only*— entries are added, never removed (even if a reservation was a mistake, it stays)
- *ever retroactive*— adding
acmeto the reservation dictionary does *ot*affect any user who already owns@acme@koder.devprior to the addition. Existing allocations are grandfathered. - *eviewed by ≥2 members of trust & safety*for every addition — four-eyes principle
- *ersion-stamped in KDB*— the dictionary has a
versioncolumn so replay and audit are deterministic
Handle allocation writes at hyperscale
The allocation path uses the singlewriterperprefix pattern described in RFC012: 36 writers (one per a–z, one per 0–9) elected via KDB leader election. Per-prefix throughput targets:
- *ustained:*1 000 allocationssecond per prefix × 36 prefixes = 36 000s cluster-wide
- *urst:*10 000 allocations/second per prefix for up to 60 seconds
These numbers are well above expected real signup rates even at peak (no SaaS in history has sustained >100/s signup in steady state without going viral) but give us headroom for viral events and abuse spikes.
Remaining open questions
Items for empirical calibration or UX iteration during Phase 0/1.
- *eservation dictionary size and maintenance cadence*— the initial ≈5 000 entries need review. Quarterly update cadence is the starting point.
- *ate limit fine-tuning for the public handle registry*— if legitimate use patterns exceed 30minIP, we'll raise; if scrapers find workarounds, we'll lower
- *isplay
name Unicode limits*— separate from the handle ASCII rule, the display_name field is UTF8; max length, allowed scripts, and confusable filtering in display names are still to be specified
Changelog
- 2026
0411 — Initial draft