# Modly Extension System Architecture: How Model Extensions Are Loaded and Validated

> Explore Modly's extension system architecture. Learn how it safely loads and validates model extensions using a three-layer approach with atomic operations and path traversal protection.

- Repository: [lightningpixel/modly](https://github.com/lightningpixel/modly)
- Tags: architecture
- Published: 2026-08-20

---

**Modly's extension system uses a three-layer architecture—type definitions, Electron preload API, and main-process handlers with path guards—to safely discover, install, and validate model extensions with atomic operations and path traversal protection.**

This deep dive examines the complete architecture of Modly's extension system, implemented in the `lightningpixel/modly` repository. The system enables secure loading and validation of **model extensions** through a carefully designed separation between renderer-side APIs and main-process filesystem operations.

## The Three-Layer Architecture

Modly's extension system architecture consists of tightly coupled layers that handle distinct responsibilities:

| Layer | Responsibility | Primary Location |
|-------|---------------|------------------|
| **Type definitions** | Declares the shape of model extensions including IDs, nodes, manifest fields, and validation flags | [`src/shared/types/electron.d.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/types/electron.d.ts) (lines 29-45) |
| **Electron preload API** | Exposes sandboxed `window.electron.extensions` API to the renderer; forwards calls to main process | [`src/shared/stores/extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/stores/extensionsStore.ts) (lines 45-58, 62-69, 80-99) |
| **Main-process handlers** | Performs filesystem operations, validates manifests, guards against path traversal, manages atomic installs | [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts) (lines 5-31, 34-45, 57-94) |

## Layer 1: Type Definitions and Manifest Schema

The foundation of the extension system is the `ModelExtension` interface declared in [`src/shared/types/electron.d.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/types/electron.d.ts) (lines 29-45). This TypeScript definition enforces the contract that every model extension must satisfy.

The interface includes:

- **Identification fields**: `id`, `name`, `version`
- **Structural data**: `nodes` array defining the extension's model nodes
- **Manifest metadata**: source information, dependencies, and compatibility flags
- **Validation state**: `corrupted` boolean and `manifestError` type (`'missing' | 'invalid' | 'incomplete'`)

These definitions enable compile-time safety and runtime validation throughout the system.

## Layer 2: Electron Preload API and Store Integration

The renderer process never touches the filesystem directly. Instead, [`src/shared/stores/extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/stores/extensionsStore.ts) provides a Zustand-based store that consumes a sandboxed API exposed through `window.electron.extensions`:

```typescript
import { useExtensionsStore } from '@shared/stores/extensionsStore'

await useExtensionsStore.getState().loadExtensions()
const models = useExtensionsStore.getState().modelExtensions

```

The store implements three core operations (lines 45-58, 62-69, 80-99):

- **`loadExtensions()`** → calls `window.electron.extensions.list()` and caches results
- **`installFromGitHub(url)`** → triggers download pipeline with progress tracking
- **`installFromLocal(path)`** → validates and installs from local filesystem

Progress events flow through `window.electron.extensions.onInstallProgress`, which the store maps to reactive state (`installProgress` at lines 14-20).

## Layer 3: Main-Process Handlers and Safety Mechanisms

The main process in [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts) contains the critical security and filesystem logic for the extension system architecture.

### Safe Extension ID Validation

The `assertSafeExtensionId` function (lines 5-30) enforces strict ID rules:

```typescript
// Valid: 'my-model-v2', 'extension123'
// Invalid: '../escape', 'UPPERCASE', 'id.with.dots', 'path/with/slashes'

```

This prevents directory traversal through malicious extension IDs.

### Root-Bounded Path Resolution

The `resolvePathWithinRoot` and `resolveExtensionPathWithinRoot` functions (lines 34-45) ensure all paths remain within the configured extensions directory:

```typescript
import { resolveExtensionPathWithinRoot } from '@electron/main/extension-path-guard'

const root = '/path/to/extensions'
const safePath = resolveExtensionPathWithinRoot(root, 'my-model-ext')
// Throws if ID is unsafe or escapes root

```

### Atomic Installation with Staging and Backup

The extension system implements crash-safe installation through three reserved prefixes (lines 57-94):

- **`EXT_STAGING_PREFIX`** (`.modly-staging-<id>-<suffix>`) — temporary extraction target
- **`EXT_BACKUP_PREFIX`** (`.modly-backup-<id>-<timestamp>`) — preserves previous version
- **`EXT_INCOMPLETE_MARKER`** — flags interrupted installations

The discovery code explicitly skips dot-prefixed directories (lines 52-66), hiding internal infrastructure from the UI.

## Extension Discovery Process

When `loadExtensions()` is invoked, the following sequence executes:

1. **Renderer** calls `window.electron.extensions.list()`
2. **Main process** walks the extensions directory
3. Each folder's [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) is parsed against the `ModelExtension` interface
4. Corrupted folders are flagged with `corrupted: true` and specific `manifestError` values
5. Results are cached in the Zustand store (lines 46-55 of [`extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/extensionsStore.ts))

## Extension Installation Pipeline

The **download → extract → validate → set-up** pipeline ensures reliable model extension installation:

| Stage | Implementation | Safety Measure |
|-------|---------------|--------------|
| Download | Fetches from GitHub URL or copies local folder | URL validation |
| Extract | Unpacks to staging directory with random suffix | Isolated from final location |
| Validate | Checks manifest schema and runs `assertSafeExtensionId` | Rejects malformed or malicious packages |
| Set-up | Atomic rename from staging to final; creates backup | Crash recovery via backup |

Progress events emit through `onInstallProgress` for UI feedback. Failures populate `installError` with actionable messages.

## Extension Reload and Repair Operations

The `reload()` API (lines 92-98) triggers complete re-scan of the extensions directory and updates the Python registry. Any scan errors accumulate in `loadErrors` for diagnostic display.

The `repair` API attempts to fix corrupted extensions, delegating to Python-side implementation for complex recovery scenarios.

## Complete Example: Installing from GitHub

```typescript
const url = 'https://github.com/user/my-model-ext/archive/refs/heads/main.zip'
const result = await useExtensionsStore.getState().installFromGitHub(url)

if (result.success) {
  console.log('Installed extension ID:', result.extensionId)
} else {
  console.error('Install failed:', result.error)
}

```

## Summary

- **Modly's extension system architecture** separates concerns across type definitions, preload APIs, and main-process handlers
- **Path traversal protection** is enforced at multiple levels: ID validation, root-bounded resolution, and reserved internal prefixes
- **Atomic installation** uses staging and backup directories to prevent partial or corrupted states
- **Validation occurs at every stage**: manifest schema, extension ID safety, and filesystem boundaries
- **The store pattern** (`useExtensionsStore`) provides reactive UI state while delegating all filesystem work to the main process

## Frequently Asked Questions

### How does Modly prevent malicious extensions from escaping the extensions directory?

Modly implements **defense in depth** through `assertSafeExtensionId` (rejecting path separators and dot-segments), `resolvePathWithinRoot` (verifying final resolved path), and the staging/backup system (limiting write targets). These mechanisms in [`electron/main/extension-path-guard.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-path-guard.ts) ensure no extension operation can access files outside the configured root.

### What happens if an extension installation is interrupted?

The staging directory persists with the `EXT_STAGING_PREFIX` or `EXT_INCOMPLETE_MARKER` prefix. On next reload, these are excluded from discovery (lines 52-66) and can be cleaned up or resumed depending on the specific failure mode. The previous version remains accessible via the backup directory if the atomic rename had not completed.

### Can the renderer process directly access extension files?

No. The renderer only interacts through `window.electron.extensions` methods exposed via Electron's context isolation. All filesystem operations execute in the main process, with results serialized back to the Zustand store. This architecture follows Electron security best practices by keeping Node.js APIs out of the renderer.

### How are corrupted extensions detected and handled?

During discovery, each folder's [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) is parsed and validated against the `ModelExtension` interface. Failures are categorized as `missing` (no manifest), `invalid` (unparseable JSON), or `incomplete` (missing required fields). Corrupted extensions appear in the store with `corrupted: true`, enabling UI warnings and repair workflows.