Skip to content

Naming conventions

OrbitalReg enforces a single slug grammar for new projects and repositories. Slugs appear in URL paths, in API-token scopes, and in client-side configs (.npmrc, pip.conf, ~/.docker/config.json, …), so a consistent grammar avoids three classes of pain at once.

The rule

regex
^[a-z][a-z0-9]*(\.[a-z0-9]+)*$

In English:

  • Lowercase letters a–z and digits 0–9 only.
  • The first character must be a letter (no leading digit).
  • Dots . are the only segment separator. No hyphens, underscores, spaces, or other punctuation.
  • No consecutive dots, no leading dot, no trailing dot.
  • Length: 2–63 characters inclusive (matches the DNS-label ceiling, which keeps slugs URL-safe across every adapter).

Examples

SlugOK?Reason
acme.platformStandard Maven-style coordinate.
acme.foo.bar2Digits inside a segment are fine.
internal.toolsTwo segments, all lowercase.
ghTwo-character minimum is fine.
Acme.PlatformUppercase letters.
acme-platformHyphen.
acme_platformUnderscore.
2acme.platformLeading digit.
acme..platformConsecutive dots.
.acmeLeading dot.
acme.platform.Trailing dot.

Why this grammar

  1. Consistency across the install. Without a rule, operators end up with Acme-Platform, acme_platform, and acme.platform side by side — same company, three slugs, none of them mutually discoverable in a search-by-prefix.

  2. URL- and path-safe across every adapter. Maven's coordinate grammar, npm's scope grammar, Docker's repository-name grammar, and DNS labels all overlap exactly here: lowercase letters, digits, and dots. Hyphens / underscores are valid in some adapters but not all (Cargo refuses leading digits, and several adapters percent-encode underscores inconsistently).

  3. Maven / Java idiom. tld.company.product is a 25-year-old convention; matching it removes friction for the largest single body of registry consumers.

How enforcement works

  • POST /api/v1/projects and POST /api/v1/repos reject a non-compliant slug with HTTP 400 and a structured envelope:
    json
    {
      "error": "invalid_slug",
      "field": "slug",
      "message": "slug must be lowercase letters/digits with dots as separators (no hyphens, underscores, leading digits, or special chars)",
      "examples": ["acme.platform", "internal.tools", "team.foo.api"],
      "suggestion": "acme.platform"
    }
    CLI / Terraform-provider / scripted callers can switch on error == "invalid_slug" without parsing the English message; the suggestion field, when present, is a best-effort rewrite of the rejected input that already passes validation.
  • PATCH /api/v1/projects/{id} and PATCH /api/v1/repos/{id} only validate when the patch body actually moves the slug. A no-op edit (or any patch that touches other fields only) on a legacy row never fails on slug grounds.
  • The OrbitalReg dashboard's create-form for projects and repositories live-validates the slug input on every keystroke, surfaces the same error message inline, and offers a one-click "Did you mean acme.platform?" suggestion that fixes the most common typos (Acme-Platform, acme_platform, 2acme.platform).

Existing legacy slugs

Slugs that pre-date this rule stay valid forever — renaming them would break every bookmark, CI config, and API-token scope that references them. The rule only applies to:

  1. Newly-created projects and repositories.
  2. Existing projects / repositories whose slug is being explicitly changed via PATCH.

For operators who want to migrate voluntarily, the admin dashboard has a "Slug audit" page under Identity & Access in the sidebar (or the "Legacy-named projects (N)" banner on the Admin overview when one or more rows are non-compliant). Each row shows:

  • the current slug,
  • the human-friendly name,
  • a suggested rename that already passes validation.

Renaming preserves the row's UUID, so role-bindings, retention policies, security blocks, webhook subscriptions, and audit-log references all continue to work after the rename. URL bookmarks, CI configs, and any hard-coded clients have to be updated by hand.

Caveats

  • "Are digits OK?" Yes. Digits are allowed inside any segment (acme.foo.bar2, team.svc1, service42.api) — they just can't be the very first character. The leading-digit ban is a defensive default that mirrors Cargo's crate-name rules and the DNS-label convention from RFC 1035, and it sidesteps the small set of clients that do path-parsing without quoting. If you have a use case that needs a leading digit, file an issue — we'd rather hear the motivating example than relax the rule by default.
  • Reserved slugs (e.g. admin, api, system) are not enforced today. If they ever conflict with a routing prefix we'll add a small rejection list as a follow-up — for the moment, the routing layer scopes everything under /api/... and the UI under /projects/... / /repos/... so collisions are not possible.
  • Multi-tenancy / namespace prefixes. OrbitalReg is single-tenant by design; slugs are flat. If multi-tenancy ever ships, tenants will get their own slug namespace rather than tenant-prefixed slugs.
  • Slug-rename redirects. Today a renamed slug returns 404 at the old URL — there is no automatic 301/302 redirect. Plan rename windows accordingly. A redirect-and-soak workflow is on the long-tail roadmap.

Released under the Apache-2.0 License.