Context
Follow-up from the retained RC3 application validation in better-stack-web#37 and its full report.
This is a post-v3 incremental DX improvement. It must not block or reopen v3.
Friction
RC3 correctly infers registered client plugin IDs and typed authorization facts, but the vocabulary changes between the two surfaces:
plugins: {
formBuilder: formBuilderClientPlugin(),
}
rules: ({ forms }) => [
forms.form.render.when(...),
]
formBuilder is the canonical programmatic plugin ID while forms is the authorization catalog namespace. The types are safe, but the relationship is not visible at either call site. During real migration, the only reliable way to discover it was to inspect the permission declaration .d.ts files and trace which catalog supplied each facts shape.
Most first-party names happen to align (blog, cms, comments, media), making the one mismatch look accidental even if the domain namespace is intentional.
Proposed better alternative
Use the canonical programmatic plugin ID as the default authorization namespace and add a compatibility alias in a minor release:
rules: ({ formBuilder }) => [
formBuilder.form.render.when(...),
]
Preferred implementation:
- Give each permission catalog explicit typed metadata for
pluginId and authorizationNamespace.
- Expose the catalog under
pluginId by default in defineAuthorization.
- Keep
forms as a deprecated typed alias through the next major release so this is incremental and non-breaking.
- Include hover documentation on the alias explaining its owning plugin and replacement.
- Export a typed catalog-to-plugin map for tooling/docs rather than requiring source inspection.
If domain namespaces must remain distinct, the fallback should still make the mapping explicit in autocomplete and generated reference docs; silent naming divergence is the part to remove.
Acceptance criteria
Release boundary
Post-v3 enhancement only. Do not hold v3 publication or change RC3 package contracts for this issue.
Context
Follow-up from the retained RC3 application validation in better-stack-web#37 and its full report.
This is a post-v3 incremental DX improvement. It must not block or reopen v3.
Friction
RC3 correctly infers registered client plugin IDs and typed authorization facts, but the vocabulary changes between the two surfaces:
formBuilderis the canonical programmatic plugin ID whileformsis the authorization catalog namespace. The types are safe, but the relationship is not visible at either call site. During real migration, the only reliable way to discover it was to inspect the permission declaration.d.tsfiles and trace which catalog supplied each facts shape.Most first-party names happen to align (
blog,cms,comments,media), making the one mismatch look accidental even if the domain namespace is intentional.Proposed better alternative
Use the canonical programmatic plugin ID as the default authorization namespace and add a compatibility alias in a minor release:
Preferred implementation:
pluginIdandauthorizationNamespace.pluginIdby default indefineAuthorization.formsas a deprecated typed alias through the next major release so this is incremental and non-breaking.If domain namespaces must remain distinct, the fallback should still make the mapping explicit in autocomplete and generated reference docs; silent naming divergence is the part to remove.
Acceptance criteria
pluginId/namespace metadata.formBuilderis available as the primary rule callback key.formscode remains source-compatible and receives a deprecation hint.Release boundary
Post-v3 enhancement only. Do not hold v3 publication or change RC3 package contracts for this issue.