Architecture

Mentat is designed as a private workload platform with a small control plane, a host-level agent, and a CLI for operations. The goal is simple: keep deployment, scheduling, health, and service lifecycle in one system without the operational weight of a larger platform stack.

What Runs Where

mentat-server

The control plane. Receives jobs, stores state, schedules workloads, and coordinates deployments, rollbacks, and node state.

mentat-agent

Runs on each host. Starts workloads through Firecracker, Sandbox, Docker, exec, or Hull, reports status, and keeps runtime details close to the node.

mt

The operator interface. Teams use it to deploy, scale, inspect, and roll back services from a single command surface.

mentat-types

Shared types for service definitions, resources, deploy strategies, constraints, and runtime state.

Operating Model

The architecture is optimized for private infrastructure. The server decides where a workload should run, the agent materializes it on the host, and the CLI stays thin. This keeps the control plane small while still supporting mixed runtimes and deployment workflows.

1. Operator runs: mt run services.yaml
2. CLI validates the file and sends the job to mentat-server
3. Server stores desired state and picks a node
4. Server dispatches an allocation to mentat-agent
5. Agent starts the workload with the selected driver
6. Server records runtime state and returns status to the operator

Knowing What Is Wrong

A health monitor probes every registered endpoint every 10 seconds and writes a conclusion into the registry: healthy, starting, unhealthy. Past a threshold of consecutive failures it restarts the workload through the agent, with a cooldown so a slow boot does not turn into a restart storm.

The conclusion alone is rarely enough during an incident — it says what, not why. So the counters behind it are readable too: how many probes have failed in a row, whether a restart is in flight, how long ago the service was last restarted, and the condition of the node each endpoint sits on. mt diagnosereads those, probes the endpoints again on the spot, pulls the workload's recent output through the agent, and reports findings. Everything on that path is read-only, which is what makes it safe to run while something is already broken.

mt://services/{name}/health     status + the counters behind it
mt://services/{name}/diagnose  the above + live probes, logs, findings
mt://nodes                     lifecycle conditions per node
mt://registry                  every endpoint the agent registered

A workload started outside the agent is invisible here: the agent registers only what it spawned, ingress routes only what the registry knows, and a port answering on the host proves neither. That gap is itself one of the findings mt diagnose reports.

Why This Shape

Small control planeKeeps memory use and failure surface low
Host-level agentKeeps runtime-specific logic close to the node
Thin CLIEasy to automate from SSH, CI, or operator workflows
Shared typesOne config model across deploys, drivers, and status
Driver abstractionOne platform for VMs, containers, binaries, and Hull workloads

Service Definition Model

Services declare runtime, resources, constraints, and deploy strategy in one spec. That same model flows through scheduling, rollout, and status.

mentat-types/src/types.rs
pub enum Driver { Firecracker, Sandbox, Docker, Exec, Hull }

pub enum DeployStrategy { Rolling, BlueGreen, Canary }

pub enum DriverConfig {
    Firecracker(FirecrackerConfig),
    Sandbox(SandboxConfig),
    Docker(DockerConfig),
    Exec(ExecConfig),
    Hull(HullConfig),
}

pub struct ServiceSpec {
    pub name: String,
    pub replicas: u32,
    pub config: DriverConfig,
    pub resources: Resources,
    pub constraints: Vec<Constraint>,
    pub deploy: DeployConfig,
}

Implementation Stack

Runtimetokio 1.x
HTTP APIaxum 0.8
Serializationserde + serde_json + serde_yml
Statesled 0.34
HTTP Clientreqwest (rustls)
Unix Socketshyperlocal + hyper
CLIclap 4 (derive)
Error Handlingthiserror
IDsuuid v4