PermDock
Decisions

0005: Naming convention

The brand is the noun; PermDock, permdock and createPermDock are used everywhere, import paths name the framework, and a small set of words is reserved.

Status

Accepted, September 2026.

Context

PermDock has one core and more than thirty adapters written by many contributors and, increasingly, by coding agents. Without a convention, adapters drift into NextDock, createHonoPermissions, useAbility, dock.can(...), and every skill and doc page has to special-case them. The landscape has three naming failures worth avoiding by rule: CASL uses can both to define and to check; Kilpi prefixes instance members with $ to dodge collisions with policy names; permix spells the same concept differently across adapters (permix.check, checkMiddleware, usePermix).

next-intl offers a model that Next.js developers already know: useTranslations() in client components and getTranslations() in async server code, same vocabulary, different verb.

Decision

  • The brand is the noun. The decision object's type is PermDock; the instance variable is permdock.
  • One factory name. Core and every server or agent adapter export createPermDock(policy, ...). The import path names the framework: permdock/next, permdock/hono, permdock/mcp. Identifiers never do: no NextDock, HonoDock, createNextPermDock.
  • React vocabulary. PermDockProvider, usePermDock, usePermission, Protected from permdock/react, direct exports, no factory.
  • use* / get* duality. usePermDock / usePermission are synchronous client and RSC hooks; getPermDock / getPermission are their async server counterparts returned by createPermDock from permdock/next.
  • Definition and policy vocabulary. definePermissions, resource, mergePermissions, listPermissions, findPermission; definePolicy, role, allow, deny, subject.
  • Instance methods. can, decide, assert, filter, where, simulate, snapshot, on.
  • Errors. PermDockDeniedError, PermDockApprovalRequiredError, PermDockValidationError.
  • Reserved words that never appear as public identifiers: dock, ability, can as a definer, and $-prefixed members.

Consequences

  • A skill can describe every adapter with one sentence: import createPermDock from permdock/<framework>, call it with the policy and a subject resolver, destructure the framework-shaped result.
  • Docs, examples and error messages read the same across adapters; permdock doctor can lint identifiers against the reserved list.
  • Helpers are functions, not tree methods, so a resource may be called list or find without shadowing anything.
  • The catalog lookup was renamed from getPermission to findPermission to keep get* exclusively for async server counterparts of use* hooks.
  • Contributors lose some freedom; an adapter proposing a new verb must add it to this page first.

Alternatives considered

  • Framework-prefixed identifiers (NextDock, HonoDock). Rejected: the subpath already carries that information and the identifiers leak into app code.
  • dock as the instance noun. Short, but it is half the brand and reads as jargon in error messages; permdock is unambiguous in logs.
  • ability / can as definers (CASL). Rejected as reserved.
  • $-prefixed members (Kilpi). Rejected; collisions are solved structurally with helper functions.
  • check instead of can. can reads naturally at call sites and is reserved as a checker only.

On this page