Skip to content

Ten dispatcher domains still claim by bare startsWith/datax, /metaxyz, /uifoo are claimed by /data, /meta, /ui, the same defect just fixed on /auth #16263

Description

@os-litant

Found while implementing the /auth segment-boundary repair for #16026. Out of that card's scope (it narrows exactly one prefix); filed unassigned.

The mechanism

DomainRoute.match defaults to 'prefix'DomainHandlerRegistry.matches' default: branch is a bare path.startsWith(route.prefix) with no segment boundary. The registry preserved that on purpose when the domains were lifted out of the legacy if-chain, and says so in its own header comment:

Matching semantics are deliberately faithful to the legacy if-chain, INCLUDING its rough edges (match: 'prefix' on /i18n also matches /i18nxx, exactly as startsWith did) — fixing those edges is explicitly not this seam's job; behavior preservation is.

That was the right call for the migration. The migration is now well past that point, and the tree is visibly half-converted.

Enumerated on origin/main at 8647c87b2f5

Declare match: 'segment' and are boundary-correct — 5 routes:

packages/runtime/src/domains/security.ts      /security
packages/runtime/src/domains/share-links.ts   /share-links
packages/runtime/src/domains/keys.ts          /keys
packages/runtime/src/domains/mcp.ts           /mcp
packages/runtime/src/domains/mcp.ts           /mcp/skill

Still carry the implicit 'prefix' default — 10 routes:

packages/runtime/src/domains/actions.ts        /actions
packages/runtime/src/domains/ai.ts             /ai
packages/runtime/src/domains/analytics.ts      /analytics
packages/runtime/src/domains/automation.ts     /automation
packages/runtime/src/domains/data.ts           /data
packages/runtime/src/domains/i18n.ts           /i18n
packages/runtime/src/domains/meta.ts           /meta
packages/runtime/src/domains/notifications.ts  /notifications
packages/runtime/src/domains/packages.ts       /packages
packages/runtime/src/domains/ui.ts             /ui

So /datax, /metaxyz, /uifoo, /aixx, /packagesomething are each claimed by a domain that does not own them, exactly as /authx and /authentication/foo were claimed by /auth.

What IS measured here, and what is not

MEASURED: the enumeration above (read from source), and the mechanism (the registry's default: branch). The /auth member of this family was measured end to end on a real boot for #16026 and is fixed.

NOT MEASURED here, deliberately, and it is the reason this is its own card rather than a rider:

  • The wire consequence per domain. /auth's was 200 {} because the auth domain forwards a Fetch Response. The other ten each hand their sub-path to a different handler with a different parse, so what /datax actually answers has to be measured per domain, not assumed to match. One of them may already be harmless; another may be worse.
  • Whether any of the ten is load-bearing. A caller may already depend on a lexical extension being claimed — the sibling-namespace claim is a bug, but it is a shipped bug on a shipped HTTP surface, and each removal narrows what that surface answers.

Why not one guard for the whole class

The obvious repair is to flip DomainHandlerRegistry's default from 'prefix' to 'segment', which closes all ten at once. That is attractive and may well be the answer, but it changes ten shipped route claims in a single unmeasured step, which is precisely what the per-domain measurement above exists to prevent. Whoever takes this should decide between the one-line default flip plus ten measurements, and ten explicit match: 'segment' declarations plus ten measurements — the measurements are owed either way.

Context: #16026 (the /auth member, fixed) and its repair, which added match: 'segment' to createAuthDomain and pinned both the narrowed rows and the overshoot controls.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions