> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rkat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Modules

> Subprocess capability boundaries, core MCP tools, discovery, and startup supervision.

*Mirrored from Meerkat Meta main at [26f5ae9da1fd](https://github.com/lukacf/meerkat/commit/26f5ae9da1fd3caac378f1cd847ce50f9ec5ac92) on 2026-11-03; Meta version 0.9.9 at that commit.*

Modules are application-supplied subprocess capability boundaries. Meta starts the configured modules, records startup health transitions, and routes module calls over either MCP or the generic JSON-line boundary.

Durable scheduling and gating are runtime services, not modules.

## Module configuration

`ModuleConfig` contains exactly four fields:

```rust theme={null}
ModuleConfig {
    id: "router".to_string(),
    command: "/opt/my-app/bin/router-module".to_string(),
    args: vec![],
    restart_policy: RestartPolicy::OnFailure,
}
```

| Field | Type | Description |
| - | - | - |
| `id` | `String` | Module identifier |
| `command` | `String` | Executable to spawn |
| `args` | `Vec<String>` | Arguments passed to the executable |
| `restart_policy` | `RestartPolicy` | `never`, `on_failure`, or `always` |

Restart budgets and backoff are runtime options. `OnFailure` retries a failed generic subprocess start within its budget. `Always` can also restart a successful generic subprocess start within its budget. MCP module startup is a one-shot tool probe and does not use those restart loops.

## Discovery

`DiscoverySpec` names a namespace and the configured module IDs the runtime should start:

```rust theme={null}
DiscoverySpec {
    namespace: "production".to_string(),
    modules: vec![
        "router".to_string(),
        "delivery".to_string(),
        "memory".to_string(),
    ],
}
```

At bootstrap, every ID in `discovery.modules` must have a matching `ModuleConfig`. A missing configuration is a startup error. A configured module that reaches a terminal start error instead contributes a `supervisor.warning` event and bootstrap continues to the next module.

## Pre-spawn environment

`PreSpawnData` associates environment entries with one module:

```rust theme={null}
PreSpawnData {
    module_id: "router".to_string(),
    env: vec![
        ("META_MODULE_BOUNDARY".to_string(), "mcp".to_string()),
    ],
}
```

Set `META_MODULE_BOUNDARY=mcp` to select the MCP boundary. Other environment entries can carry module-specific configuration or secret references.

## Core modules

Three module IDs have hard MCP requirements:

| Module ID | Runtime use | Required MCP tool |
| - | - | - |
| `router` | Resolve a recipient into a trusted route | `routing.resolve` |
| `delivery` | Dispatch a validated delivery request | `delivery.send` |
| `memory` | Read conflict state for runtime gating | `memory.conflict_read` |

For these IDs, a call fails closed if `META_MODULE_BOUNDARY=mcp` is absent or the required tool is unavailable.

The following related runtime surfaces are not module tools:

* Runtime-route list, add, and delete
* Delivery history and idempotency
* All gating evaluate, pending, decide, and audit operations
* The operational assertion and conflict ledger: `meta/memory/stores`, `meta/memory/index`, and `meta/memory/query`
* The separate identity agent-memory API: `meta/agent_memory/recall` when a provider is configured, plus `meta/agent_memory/remember`, `meta/agent_memory/forget`, `meta/agent_memory/update`, and `meta/agent_memory/manifest` when the provider supports each capability
* Agent-memory record-engine surfaces for quarantine review and steward consolidation

The operational ledger and the identity agent-memory record layer are distinct authorities. The ledger owns assertion and conflict index/query state consumed by gating. Quarantine review and steward consolidation belong to the agent-memory record-engine layer.

Non-core module IDs may use the MCP marker or the generic JSON-line subprocess boundary.

Scheduling is owned by Meerkat's `ScheduleService`. See [Scheduling](https://docs.rkat.ai/meta/concepts/scheduling.md).

## Startup health

`ModuleHealthState` has five values:

| State | Meaning during startup supervision |
| - | - |
| `Starting` | Startup or MCP probing began |
| `Healthy` | The generic boundary yielded its first valid event, or the MCP tool probe succeeded |
| `Failed` | A startup attempt or MCP probe failed |
| `Restarting` | A generic subprocess retry is about to run |
| `Stopped` | Startup ended without a live module |

Each `ModuleHealthTransition` records `module_id`, optional `from` state, `to` state, and attempt number. Transitions are retained in `SupervisorReport`; they are not emitted as `health_transition` unified events.

A successful MCP probe emits `event_type: "mcp.ready"` with the discovered tool names. A terminal startup error emits `event_type: "supervisor.warning"` with the error payload. The `ModulesStarted` lifecycle stage means startup attempts have completed, not that every module is healthy.

## Trusted module manifest

`load_trusted_meta_modules_from_toml` accepts a `[[modules]]` manifest:

```toml theme={null}
[[modules]]
id = "router"
command = "/opt/my-app/bin/router-module"
args = []
restart_policy = "on_failure"

[[modules]]
id = "delivery"
command = "/opt/my-app/bin/delivery-module"
```

The trusted-manifest loader validates non-empty IDs and commands, defaults missing `args` to an empty list, and defaults a missing `restart_policy` to `on_failure`. The executable names and their implementations belong to the host application.

## See also

* [Events](https://docs.rkat.ai/meta/concepts/events.md) - exact module event types and startup lifecycle
* [Architecture](https://docs.rkat.ai/meta/reference/architecture.md) - module ownership in the runtime
* [Configuration](https://docs.rkat.ai/meta/reference/configuration.md) - runtime options and manifests


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.