# @leumas/dynamic — the Dynamic layer

The Dynamic layer — a Studio owner's OWN code, added to their own instance. Three parts behind one /api/dynamic prefix: SSR (register components/pages by local path, compile + server-render them...


A Studio owner's **own code**, on the instance they own. Three surfaces behind one `/api/dynamic`
prefix; Studio's `Dynamic` domain is the UI.

- **SSR** — register a `.jsx`/page/file **by local path**; compile it, server-render it, serve it to
  any locally-connected app (React live+hydrated, a plain HTML page, or anything that speaks HTTP).
- **Routers** — register express routers, whole servers, static folders or proxy targets; answer on
  their mount paths from startup.
- **Scripts** — a per-user script library: write, edit, run with typed props, sandboxed by default.

Full narrative — the design decisions, the consumer snippets, the traps — lives in
**`shared/services/knowledge/build-knowledge/dynamic-layer.md`**. This file is the map.

## Mounting it

```js
import { createDynamicLayer } from '@leumas/dynamic';

// ONLY inside a caps.fileTools block. See "The one gate" below.
const dynamic = createDynamicLayer({
  collStore, requireAuth, requireAdmin: requireRole('admin'),
  isAdmin: (req) => hasRole(req, 'admin'),
  roots: toolRoots,                 // the host's path allow-list
  allowNative: caps.fileTools,
  adapters, workDir, onEvent, logger,
});

app.use('/api/dynamic/ssr', dynamic.publicSsrRouter);   // pre-gate: public components only
app.use('/api/dynamic', dynamic.router);
// …after every product route:
app.use((req, res, next) => dynamic.dispatch(req, res, next));
dynamic.start({ legacyReadStore }).catch(() => {});
```

## The one gate

Every part of this engine names a file on the host's disk and then **executes** it. It must mount
only where the caller owns the machine — `appliance` and `dev`, never `platform` or `control`. The
engine does not check that itself, on purpose: a capability check in two places eventually disagrees
with itself, and the API is where role lives. `pnpm check:dynamic` asserts the mount stayed there.

What the engine *does* enforce, everywhere, with no opt-out:

| Rule | Where |
|---|---|
| every path is inside the registered roots; empty list = refuse everything | `src/roots.js` `assertInsideRoots` |
| the compiler re-checks every file it *reads*, not just the entry | `src/index.js` `onFile` |
| no mount may shadow `/auth`, `/db`, `/api`, `/ws`… — refused at registration | `src/roots.js` `assertMountPath` |
| every execution is a worker or a child process with a hard timeout | `src/ssr/render.js`, `src/scripts/run.js` |

## Layout

```
src/roots.js            the ONE path allow-list + the reserved mount prefixes
src/routers/            store.js (4 kinds) · mount.js (one dispatcher) · router.js (CRUD)
src/ssr/                store.js · compile.js (sucrase) · render.js + renderWorker.mjs · embed.js · router.js
src/scripts/            store.js (lmx_scripts, extended) · run.js (LMX | child process) · router.js
client/index.jsx        <LeumasComponent> — the React consumer. @leumas/dynamic/client
```

## Collections

| Collection | Writes | Why |
|---|---|---|
| `dynamic_routers` | admin (`PLATFORM_COLLECTIONS`) | a row imports a module into this process, or spawns a program |
| `ssr_components` | admin (`PLATFORM_COLLECTIONS`) | the server compiles and renders the file it names |
| `lmx_scripts` | member | shared with the LMX Playground. Privilege is on the RUN, not the write |

## Environment

| Var | Effect |
|---|---|
| `DYNAMIC_ROOTS` | extra allowed trees (`;`-separated; **`;` only** on win32 — see `rootsFromEnv`) |
| `DYNAMIC_SCRIPTS_EXEC=1` | allows `node`/`python`/`shell` scripts (still needs admin + `caps.fileTools`) |
| `DYNAMIC_SSR_TIMEOUT_MS` | render deadline (default 5000, max 30000) |
| `DYNAMIC_SCRIPTS_TIMEOUT_MS` | native script deadline (default 30000, max 300000) |
| `PYTHON_BIN` · `POWERSHELL_BIN` · `SHELL_BIN` | interpreter overrides for the native lane |

## Proving a change

```sh
pnpm check:dynamic            # structural
pnpm check:dynamic:selftest   # proves each check still fires
pnpm smoke:dynamic            # 14 live checks against a booted API
```


---
Source: shared/engines/dynamic/README.md
Canonical: https://docs.leumas.tech/p/engines/dynamic
