# Apache Maka Runtime Host: Understanding the Public Client/Protocol Boundary

> Understand the Apache Maka runtime host's public client/protocol boundary. Learn how its stable JSON API over WebSocket separates client communication into Protocol and Transport layers.

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

---

**The `packages/runtime-host` module in Apache Maka exposes a stable, JSON-based API over WebSocket, separating external client communication into a Protocol layer (types and validation) and a Transport layer (WebSocket implementation).**

The `runtime-host` package serves as the public edge of the Apache Maka runtime, enabling external clients—such as web front-ends, SDKs, and microservices—to communicate with the execution host without accessing internal implementation details. This boundary is explicitly defined by two architectural layers that enforce message schemas, size limits, and error handling while hiding the complexity of the underlying execution engine.

## Architecture of the Public Boundary

The boundary is strictly partitioned into declarative types and concrete transport logic. This separation allows the host to evolve its internal session management and policy engines while maintaining backward compatibility for connected clients.

### Protocol Definition Layer

The **Protocol layer** declares the wire format using TypeScript types, constants, and error classes. It defines the JSON schema that all messages must follow, enforces UTF-8 validity, and specifies size constraints.

Key exported symbols from [`src/protocol/index.ts`](https://github.com/apache/maka/blob/main/src/protocol/index.ts) include:

- **`EncodedProtocolMessage`** – The TypeScript type representing a serialized protocol message
- **`RUNTIME_HOST_MAX_MESSAGE_BYTES`** – The hard limit on incoming message payload size
- **`RuntimeHostProtocolError`** – Thrown when frames contain invalid JSON, oversized payloads, or malformed structure
- **`RuntimeHostTransportError`** – Raised for transport-level failures such as queue saturation

According to the Apache Maka source code, these definitions ensure that any compliant client can generate valid messages using only the protocol exports, without importing transport internals.

### Transport Implementation Layer

The **Transport layer** implements the bidirectional WebSocket channel that reads, writes, and validates protocol messages. The primary implementation resides in [`src/transport/websocket-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/websocket-transport.ts) and extends the abstract `FramedTransport` base class from [`src/transport/framed-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/framed-transport.ts).

Core components include:

- **`WebSocketTransport`** – The concrete class implementing the `RuntimeHostMessageTransport` interface defined in [`src/transport/message-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/message-transport.ts)
- **Back-pressure management** – Enforces `MAX_PENDING_WRITE_BYTES` to prevent memory exhaustion
- **Graceful shutdown** – Provides `closeAfterFlush()` to drain pending writes before closing and `abort()` for immediate termination

## How Messages Flow Across the Boundary

The client-to-host interaction follows a strict sequence that isolates protocol validation from socket management:

1. **Connection establishment** – The client opens a WebSocket to the host endpoint (e.g., `ws://<host>/runtime`).

2. **Transport instantiation** – The host creates a `WebSocketTransport` instance, wiring the socket’s `message`, `error`, and `close` events.

3. **Inbound decoding** – All incoming frames pass through `decodeMessage` in the protocol layer. This function:
   - Validates UTF-8 encoding
   - Parses JSON into an `EncodedProtocolMessage` object
   - Throws `RuntimeHostProtocolError` for malformed or oversized payloads

4. **Outbound encoding** – Responses are encoded as `Uint8Array` (or `Buffer`) and passed to `WebSocketTransport.write`. The transport checks the pending-write queue against `MAX_PENDING_WRITE_BYTES`, raising a `RuntimeHostTransportError` with code `outbound_queue_full` if the buffer is saturated.

5. **Lifecycle management** – The transport supports `closeAfterFlush()` for graceful shutdowns that complete pending writes, or `abort()` to terminate the connection immediately and propagate transport-level failures.

## Implementing a Client for the Public Boundary

Clients interact with the boundary using standard WebSocket clients and the protocol exports. The following examples demonstrate compliant interaction patterns.

### Connecting and Sending Messages

Clients must respect `RUNTIME_HOST_MAX_MESSAGE_BYTES` when serializing payloads:

```typescript
import WebSocket from 'ws';
import {
  RUNTIME_HOST_MAX_MESSAGE_BYTES,
  type EncodedProtocolMessage,
} from '@apache-maka/runtime-host/protocol';

const socket = new WebSocket('ws://localhost:8080/runtime');

function encode(msg: unknown): EncodedProtocolMessage {
  const json = JSON.stringify(msg);
  const size = new TextEncoder().encode(json).byteLength;
  
  if (size > RUNTIME_HOST_MAX_MESSAGE_BYTES) {
    throw new Error('Message exceeds host maximum size');
  }
  return Buffer.from(json);
}

socket.on('open', () => {
  const request = { operation: 'session.start', params: {} };
  socket.send(encode(request));
});

```

### Receiving and Decoding Messages

Inbound messages should be validated against the protocol schema:

```typescript
socket.on('message', (data) => {
  try {
    const text = data.toString('utf8');
    const message = JSON.parse(text); // Mirrors host decodeMessage
    console.log('Received:', message);
  } catch (e) {
    console.error('Protocol violation:', e);
  }
});

```

### Server-Side Transport Handling

Host implementations use the `WebSocketTransport` class directly to manage client sessions:

```typescript
import { WebSocketTransport } from '@apache-maka/runtime-host/transport';

// `ws` is a connected WebSocket instance from a client
const transport = new WebSocketTransport(ws);

// Read with a 5-second timeout
transport.read(5000)
  .then(msg => {
    console.log('Client message:', msg);
    return transport.write(encode({ echo: msg }));
  })
  .catch(err => {
    if (err instanceof RuntimeHostTransportError) {
      console.error('Transport failure:', err);
    }
  });

```

## Key Source Files in the Runtime Host Package

The boundary is implemented across five critical files in the `packages/runtime-host` directory:

| File Path | Responsibility |
|-----------|----------------|
| [`src/protocol/index.ts`](https://github.com/apache/maka/blob/main/src/protocol/index.ts) | Defines `EncodedProtocolMessage`, size constants, and protocol-level error constructors |
| [`src/protocol/errors.ts`](https://github.com/apache/maka/blob/main/src/protocol/errors.ts) | Implements `RuntimeHostProtocolError` and `RuntimeHostTransportError` classes |
| [`src/transport/message-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/message-transport.ts) | Declares the `RuntimeHostMessageTransport` interface abstracting read/write operations |
| [`src/transport/websocket-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/websocket-transport.ts) | Concrete WebSocket implementation enforcing protocol limits and connection lifecycle |
| [`src/transport/framed-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/framed-transport.ts) | Base class providing low-level framing and transport error handling |

## Summary

- The **public client/protocol boundary** in `packages/runtime-host` consists of a Protocol layer (types and validation) and a Transport layer (WebSocket implementation).
- **Protocol enforcement** occurs in [`src/protocol/index.ts`](https://github.com/apache/maka/blob/main/src/protocol/index.ts), which validates UTF-8, JSON structure, and payload sizes against `RUNTIME_HOST_MAX_MESSAGE_BYTES`.
- **`WebSocketTransport`** in [`src/transport/websocket-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/websocket-transport.ts) manages the physical connection, back-pressure via `MAX_PENDING_WRITE_BYTES`, and graceful shutdown through `closeAfterFlush()`.
- Clients communicate using standard WebSockets and JSON payloads, relying on `EncodedProtocolMessage` types for type safety without requiring internal host dependencies.

## Frequently Asked Questions

### What is the maximum message size for the Maka Runtime Host protocol?

The host enforces a hard limit defined by **`RUNTIME_HOST_MAX_MESSAGE_BYTES`** (exported from [`src/protocol/index.ts`](https://github.com/apache/maka/blob/main/src/protocol/index.ts)). Clients must ensure serialized JSON payloads do not exceed this threshold, or the host will throw a `RuntimeHostProtocolError` upon receipt.

### How does the host handle malformed or invalid client messages?

All inbound frames pass through the **`decodeMessage`** function, which validates UTF-8 encoding and JSON syntax. If validation fails, the host raises a **`RuntimeHostProtocolError`** before the message reaches internal business logic, ensuring the execution engine remains isolated from malformed input.

### Can I implement a custom transport other than WebSocket?

Yes. The **`RuntimeHostMessageTransport`** interface (defined in [`src/transport/message-transport.ts`](https://github.com/apache/maka/blob/main/src/transport/message-transport.ts)) abstracts the transport mechanism. While `WebSocketTransport` is the reference implementation, any class implementing `read()` and `write()` methods adhering to the interface can substitute for WebSocket in specialized deployment scenarios.

### What happens when the outbound message queue is full?

If pending writes exceed **`MAX_PENDING_WRITE_BYTES`**, the transport raises a **`RuntimeHostTransportError`** with the specific code `outbound_queue_full`. This back-pressure mechanism prevents memory exhaustion and signals to the host that it should apply flow control or shed load.