Generic and bespoke frontends

Landing contract

The platform provides public backend APIs and headless client/session/form semantics. The generic frontend is one complete frontend implementation. It is not the parent of bespoke frontends, a component library, or a page-builder framework.

Every operational workflow is a configured generic application. Spell and Allocation Risk are bespoke applications with independent renderers and session controls. Allocation Risk deliberately remains bespoke to preserve its current user experience, even though much of its functionality could be expressed by a generic frontend later. A future conversion is a product decision.

Identity, implementation, address

@processos/applications separates an application's stable ID and workflow key from its frontend choice and deployment mounts. Changing an address does not migrate processes. Changing a frontend does not require changing its address. Generic/default address, generic/custom domain, bespoke/default address and bespoke/custom domain are all deployment choices, not skin features.

A mount has an exact trusted origin, normalized path prefix and explicit canonical choice when there are aliases. Host headers and forwarded headers are not destination authorization. Each request resolves its own immutable context; one application's branding cannot mutate another's. The configured frontend proxy always targets one trusted backend origin and retains the existing API permissions, sharing and status responses.

The neutral main host retains its legacy root routes and cross-workflow operator dashboard, templates/editor, records, database and docs. NEXT_PUBLIC_FRONTEND_ID selects a whole frontend implementation for legacy deployments; there is no component override registry. Operational applications are mounted at /apps/<workflow-key> (an injective encoded path is used for unusual keys). Newly published repository templates receive a generic application automatically. The /api/applications catalog uses the existing process-template listing permission.

Standalone generic, Spell and Risk frontends can each use their own public origin and the same backend. The standalone generic host receives its application definition as configuration; bespoke frontends own their fixed product definition. Reverse proxy/DNS and actual Auth0 callback settings must be configured by an operator; local synthetic verification never changes them.

Frontend/catalog identities alone are not security tenants. The required application-access policy assigns workflow resources to apps and confines email-based grants to them. Backend process/sharing/activity checks still apply inside that boundary; a frontend mount cannot grant membership. All deployed hosts and workers use this policy, without a legacy authorization fallback. Production activation still requires reviewed migration and cutover.

Bounded skin

A generic skin accepts only:

  • Palette: blue, violet or slate.
  • Spacing: comfortable or compact.
  • Layout: sidebar or focused.
  • Logo: builtin mark, none, or a trusted asset key served from the deployment’s public application-assets directory.

Unknown properties are rejected at runtime. There are no functions, JSX, arbitrary CSS, custom components, page replacement slots or declarative component/page trees. Process fields, validation and branching belong to the Template, not the skin. Identity and address configuration are separate from appearance.

Ownership and compatibility

The bespoke renderer copies intentionally start with the existing markup, forms/autosave/file behavior and product-specific callbacks. Duplication here buys independent ownership; it must not be removed by recreating a shared UI component framework. Headless semantics remain shared where appropriate. Each frontend can evolve its own visual implementation without changing its peers.

The old Allocation Risk data-brand="sky" treatment was not active in the actual root layout; extraction must not turn it on simply because historical comments described it as active. Spell's private CSS depends on existing markup; preserve that markup rather than redesigning it in this PR.

Verified locally before submission

  • Negative dependency tests: neither bespoke frontend can import generic UI; generic component internals and callback runtime are not public exports; Platform session code contains no visual UI.
  • Closed skin and trusted mount validation, canonical/alias/traversal tests, independent contexts.
  • Existing main build/HTTP/browser/worker tests for default, Spell and Allocation Risk deployments.
  • Independently installed generic, Spell and Risk frontend builds with packed public dependencies.
  • Canonical-backend journeys for process start, autosave/reload, completion, sharing, permissions, file upload, audit/export and unchanged deep links.
  • Synthetic OAuth round trips bind configured mounts and preserve origin-local session storage; callback HTML must not turn return paths into executable markup.

The complete combined gate passed on the frontend implementation at 1cb0803, followed by separate default/Allocation Risk deployment builds and compiled checks. See current status for counts and limits. Historical pixel parity, live providers and production tenant configuration remain unclaimed; no deployment or migration was performed.