Skip to content

Mental Model

The SDK turns Core's static metadata into a persistent, secure, navigable platform. A handful of ideas carry it.

Layering

The eight layers of the SDKEight stacked layers. At the top the UI5 apps inside the LeanShell, then Http, the shell and intent domains, the stateful domains, Sync, the Core seam, LaravelUi5 Core, and the database at the bottom. Every layer depends only on the layers below it.UI5 appsyour capability apps, hosted by the LeanShellHttpshell, help and action routesShell · Intent · Weave · Actionnavigation, dispatch, cross-app doorways, the write pathSecurity · Settings · Partners · Tenancywho may, how configured, for whom — the stateful domainsSyncdeclared metadata → database, in foreign-key orderCore seamSdkRegistry · SdkContext — where the SDK meets CoreLaravelUi5 CoreUi5Registry · artifacts · routing · manifestsDatabaseone tenant, one databasedepends on
Dependencies run downward only. The SDK builds on Core; Core never learns about the SDK.

If you find yourself wanting Core to know about an SDK type, you are at the wrong layer — and the two bands the diagram singles out are where that pressure usually shows. Core seam is the only place the SDK is allowed to reach down: SdkRegistry extends Core's registry, SdkContext carries the actor, the partner and the resolved settings a Core artifact never knows about. Everything above it talks to the seam, not to Core.

Contracts-first

Every service is bound to an *Interface in the SDK's service provider and can be replaced through the container. There is no static façade in front of authorization, settings, navigation or partner resolution — rebind a service to change its behavior.

Time-aware everything

Authorization is f(App, Actor, Timestamp). Every grant — a direct ability, a role, a group — carries valid_from and valid_until, and neither is ever null. A new grant starts now and runs until 9999-12-31 23:59:59 unless you say otherwise. That is what lets you ask who could do what at any moment, past or future. See Resolution Engine.

One tenant per database

The SDK never adds a tenant_id column and never filters rows by tenant. Isolation is the deployment's job: one database per tenant. Inside a request the tenant is resolved once and does not change. Until you bind a resolver of your own, the tenant is the platform owner that ui5:intake created, so a single-tenant installation works out of the box (and fails loudly if no platform owner exists). See Tenancy.

Code declares, the database decides

Core's registry is the source of truth for what exists — apps, dashboards, actions, abilities, settings. ui5:sync projects that into the database catalog. Who may do what — partners, roles, grants, setting values — lives in the database and is managed at runtime. Authorization reads the database, not the code. See Sync Pipeline.

Discovery vs decision

The SDK enforces a hard separation between what can be discovered (search) and what is allowed (security). Search collectors never query security tables; visibility is enforced in the query itself by constrainers that delegate to security resolvers. See Visibility & CmdK Separation.

Reading order

If you're new, read in this order:

  1. What the SDK Adds
  2. Architecture Overview
  3. Security Domain Model
  4. Capability Mini-Apps
  5. Navigation
  6. Mutating Actions