ConceptsCapabilities

Capabilities

A capability is a runtime behaviour your Surface can opt into: fetching data, routing between Surfaces, persisting client state, running form validation, or wiring blocks into a per-World entity model. Capabilities ship as pwpacks and resolve per World at runtime — there is no global capability table.

Surface = Blocks + Capabilities. Blocks are the visual primitives; capabilities are the runtime behaviours that animate them.

The canonical 5

As of 2026-04-23 the registry contains exactly 5 canonical capabilities. All other names you may see in older docs (auth, data, state, seo, i18n, analytics, forms, behaviors) were retired in ADR-094 / ADR-095 / ADR-110 / ADR-116.

IDPackResponsibility
platform/persistence@pwpack/phiwebs/persistenceData fetch + cache; owns dataSources and initialState in binding config (ADR-124).
platform/entities@pwpack/phiwebs/entitiesTenant data model, CRUD, lifecycle.
platform/navigation@pwpack/phiwebs/navigationClient-side routing between Surfaces (ADR-096).
platform/interaction@pwpack/phiwebs/interactionEvent-driven rules — attach triggers/actions to Surface events.
platform/input@pwpack/phiwebs/inputForm field state, validation, submission.

platform/appearance is not a capability. Visual appearance ships as a dedicated atom kind (ui-appearance) through the same publish pipeline. Don’t list it in plan bundles — list the appearance pack (@pwpack/phiwebs/appearance) instead.

Pack bundle model

Capabilities are not toggled individually. They follow the World’s plan bundle — the set of pwpacks installed at plan activation.

Plan activation
  → resolve plan.pack_bundle
    → install each pack
      → record one capability entitlement per capability atom
        → entitlement check: capability marked active?

Installed = entitled. Plan upgrade installs additional packs; downgrade soft-uninstalls; re-upgrade reactivates the existing rows.

Default plan bundles

PlanBundle
Basiccore-ui · persistence · entities
Pro+ navigation · interaction · input
TeamPro bundle + extended pwpacks
EnterprisePro + custom enterprise packs

Bundles are versioned with the plan; activating or downgrading a plan syncs the World’s pack set automatically.

Runtime resolution

The kernel registry starts empty per World. The first time a Surface references a capability:

  1. The runtime resolves a per-World capability lookup function with the signature (capabilityId, worldId) => Capability | null.
  2. The lookup reads the World’s active capability atoms.
  3. The bundle URL is dynamically imported on first use; the exported defineCapability builder runs.
  4. The resolved capability is cached per World (5-minute LRU).

This means installing a new pwpack reflects in the live World within five minutes without redeploying anything.

Authoring a capability

Capabilities use the same pwpack pipeline as blocks. The canonical builder is defineCapability(...) in @pwfabric/sdk — see the defineCapability() SDK reference for the full API.

See also