# Architecture Decision Records Status: Accepted — 2026-09-15 ## ADR-001: Plugin Runtime Trust Model **Decision**: Reviewed-only trust model for the community marketplace. The plugin-worker executes third-party code in a dedicated child process within a hardened container (read-only fs, mem/pids caps, cap_drop ALL, no-new-privileges, internal-only network, process-group SIGKILL on timeout, strict IPC validation). This is adequate for **admin-reviewed, curated plugins** where the review process is the primary trust gate. **NOT adequate for arbitrary hostile JavaScript**. The child and parent share the same UID and container; `/proc//environ` readability depends on host kernel policy, and a sufficiently motivated plugin could attempt same-UID signal attacks. Per-plugin containers with separate UIDs, PID namespaces and cgroups are the path to hostile-code sandboxing — deferred until the marketplace scales beyond curated. **Marketplace policy**: submissions require human review before `approved` status; artifact hash pinning ensures reviewed bytes == installed bytes; dynamic plugin execution remains opt-in (`LOBBYFORGE_DYNAMIC_PLUGINS_ENABLED=true` + worker URL). ## ADR-002: Plugin Client UI Architecture **Decision**: Server-only for beta; sandboxed iframe as the target. Dynamic marketplace plugins currently have `renderClient: () => null` — they can manage server-side state, handle actions and use scoped storage, but cannot render their own UI components in the LobbyForge client. This is a **known functional gap**, not a bug. **Target architecture** (post-beta): - Each plugin UI runs in a sandboxed `