# How Runtime Policies Are Encoded and Managed in Apache Maka

> Discover how Apache Maka encodes and manages runtime policies as versioned JSON documents within workspaces, leveraging an immutable mutation pipeline for type-safe, reproducible changes.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: internals
- Published: 2026-09-09

---

**Apache Maka stores runtime policies as versioned JSON documents in each workspace, using an immutable mutation pipeline with optimistic concurrency control to ensure type-safe, reproducible policy changes.**

Apache Maka's runtime policy system provides a robust foundation for workspace configuration. Understanding how these policies are encoded, stored, and modified is essential for developers extending the platform or integrating with its runtime host.

## Runtime Policy Document Structure

Every workspace contains a **[`runtime-policy.json`](https://github.com/apache/maka/blob/main/runtime-policy.json)** file in its user-data directory. This file follows a strict schema defined in [`policy-document.ts`](https://github.com/apache/maka/blob/main/policy-document.ts) (lines 45-52) that includes:

- **Schema version** – for forward compatibility
- **Revision number** – monotonically increasing integer
- **`RuntimePolicy` object** – the actual policy configuration

The schema ensures that policy documents remain parseable across Maka versions while maintaining a clear audit trail of changes.

## Reading and Initializing Policies

When a workspace starts, the **`RuntimePolicyDocumentOwner`** class (lines 60-84 of [`policy-document.ts`](https://github.com/apache/maka/blob/main/policy-document.ts)) handles policy loading:

```typescript
// From policy-document.ts, line 60-84
class RuntimePolicyDocumentOwner {
  async loadPolicy(): Promise<RuntimePolicyDocument> {
    const doc = await readBoundedJsonDocument(this.filePath);
    if (!doc) {
      return createDefaultRuntimePolicy(); // line 64
    }
    return this.validateAndMigrate(doc);
  }
}

```

The **`readBoundedJsonDocument`** helper prevents parsing attacks by enforcing size and depth limits. If no policy exists, **`createDefaultRuntimePolicy()`** generates a sensible baseline configuration.

## The Mutation Pipeline

All policy changes flow through a four-stage pipeline that guarantees atomicity and consistency.

### Stage 1: Client Request

UI components invoke the **`mutateRuntimePolicy`** RPC method exposed by the Runtime Host. The input includes an expected revision and operation:

```typescript
// Example: set a new network proxy via mutation
await deps
  .client(uiScope)
  .mutateRuntimePolicy({
    expectedRevision: current.revision,
    operation: { 
      kind: 'set_network_proxy', 
      value: { uri: 'http://proxy:8080' } 
    },
  });

```

### Stage 2: Preparation

`RuntimePolicyDocumentOwner.prepareMutation` (lines 99-108) validates the expected revision against the current document. This **optimistic concurrency control** prevents lost updates when multiple clients modify the same policy:

```typescript
// Lines 99-108: revision validation
if (input.expectedRevision !== currentDocument.revision) {
  throw new PolicyConflictError(
    `Expected revision ${input.expectedRevision}, found ${currentDocument.revision}`
  );
}

```

### Stage 3: Apply Mutation

The **`applyMutation`** function (lines 136-180) pattern-matches on `RuntimePolicyMutation.kind`:

```typescript
// Lines 136-180: exhaustive mutation handling
function applyMutation(
  policy: RuntimePolicy,
  mutation: RuntimePolicyMutation
): RuntimePolicy {
  switch (mutation.kind) {
    case 'set_network_proxy':
      return { ...policy, networkProxy: mutation.value };
    case 'set_memory':
      return { ...policy, memory: mutation.value };
    case 'patch_agent_settings':
      return applyAgentSettingsPatch(policy, mutation.value);
    // ... additional mutation kinds
  }
}

```

Supported mutation kinds (defined in [`operations.ts`](https://github.com/apache/maka/blob/main/operations.ts)) include:

- **`set_network_proxy`** – Configure HTTP/HTTPS proxy settings
- **`set_memory`** – Adjust memory allocation and limits
- **`patch_agent_settings`** – Partial updates to agent personalization and retention
- Additional kinds for credential material and feature flags

### Stage 4: Commit

`commitMutation` writes the updated document atomically:

```typescript
// Line 127-128: atomic commit with frozen snapshot
await writeJsonDocument(this.filePath, nextDocument);
return deepFreeze(nextDocument); // immutable return value

```

The **`deepFreeze`** call ensures that returned policy objects cannot be accidentally modified, enabling safe sharing across threads and processes.

## In-Memory Caching

The Runtime Host maintains two lookup structures in [`runtime-host-boot.ts`](https://github.com/apache/maka/blob/main/runtime-host-boot.ts):

```typescript
// Line 857: WeakMap for UI scope-based lookups
runtimePolicyTargets: WeakMap<
  DesktopRuntimeHostTargetPolicy, 
  DesktopRuntimeHostTargetContext
>;

// Line 858: Map for epoch-based retrieval
runtimePolicyTargetsByEpoch: Map<string, DesktopRuntimeHostTargetContext>;

```

These caches (actively used in lines 610-888) minimize disk I/O while ensuring policy consistency. The **`WeakMap`** allows automatic cleanup when UI scopes are garbage collected, preventing memory leaks in long-running sessions.

## Batch Operations Example

Multiple settings can be updated atomically using `patch_agent_settings`:

```typescript
// Example: patch several settings at once
await deps
  .client(uiScope)
  .mutateRuntimePolicy({
    expectedRevision: current.revision,
    operation: {
      kind: 'patch_agent_settings',
      value: {
        personalization: { preferredLanguage: 'en' },
        memory: { retentionDays: 30 },
      },
    },
  });

```

This single mutation updates both personalization preferences and data retention policy without intermediate states.

## Querying Current Policy

Clients retrieve the current policy via **`queryRuntimePolicy`**:

```typescript
// Example: read current runtime policy from UI side
const { policy, revision } = await deps.client(uiScope).queryRuntimePolicy();
// Returns frozen {policy, revision} tuple

```

The returned revision must be used for subsequent mutations to maintain consistency.

## Summary

- Policies are stored as **versioned JSON documents** ([`runtime-policy.json`](https://github.com/apache/maka/blob/main/runtime-policy.json)) with schema validation
- **Optimistic concurrency control** via revision numbers prevents conflicting updates
- **Immutable mutation pipeline** (`prepareMutation` → `applyMutation` → `commitMutation`) guarantees consistency
- **`deepFreeze`** ensures safe sharing across UI, Runtime Host, and worker processes
- **Dual cache structure** (`WeakMap` + `Map`) provides fast lookup by UI scope or epoch

## Frequently Asked Questions

### What happens if two clients try to modify the same policy simultaneously?

The first successful commit increments the revision number. Subsequent attempts with the now-stale `expectedRevision` receive a `PolicyConflictError` and must re-query the current policy before retrying. This optimistic concurrency pattern is enforced in `prepareMutation` (lines 99-108).

### Where are runtime policy mutations defined?

All mutation kinds and their type definitions reside in [`packages/storage/src/runtime-policy/operations.ts`](https://github.com/apache/maka/blob/main/packages/storage/src/runtime-policy/operations.ts). This includes `RuntimePolicyMutation` discriminated unions and credential material interfaces. The core `RuntimePolicy` types are re-exported from [`packages/core/runtime-policy/index.ts`](https://github.com/apache/maka/blob/main/packages/core/runtime-policy/index.ts).

### How does Maka prevent policy documents from growing unbounded?

The `readBoundedJsonDocument` helper enforces maximum file size and nesting depth limits when parsing. Additionally, the mutation pipeline replaces entire policy sections rather than appending, keeping document size proportional to configuration complexity rather than edit history.

### Can runtime policies be migrated across schema versions?

Yes. The `RuntimePolicyDocumentOwner` class includes validation and migration logic (referenced in line 64's `validateAndMigrate`). The schema version field enables forward-compatible parsing and automatic upgrades when older documents are encountered.