# How Apache Maka Manages Agent Lifecycle: A Deep Dive into RelayAgent

> Discover how Apache Maka manages agent lifecycle with RelayAgent's deterministic state machine for safe and isolated command execution. Learn about its process from setup to cleanup.

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

---

**Apache Maka manages agent lifecycle through a deterministic state machine implemented in `RelayAgent` that orchestrates construction, setup, execution, cancellation teardown, and final cleanup to ensure isolated command execution never leaves orphaned processes or resources.**

The `apache/maka` repository provides a hardened evaluation harness where agents execute untrusted commands inside isolated environments. Understanding the Maka agent lifecycle reveals how the framework guarantees resource cleanup, signal handling, and deterministic termination even when subjects misbehave or trials abort unexpectedly.

## Construction and Initialization

Every agent lifecycle begins in `RelayAgent.__init__` within [`packages/eval/harbor/relay_agent.py`](https://github.com/apache/maka/blob/main/packages/eval/harbor/relay_agent.py) (lines 86–103). The constructor stores relay connection parameters—including host, port, and authentication token—and validates the teardown timeout configuration that governs graceful shutdown attempts. This initialization phase establishes the agent's identity and timeout policies before any network activity occurs.

```python
from packages.eval.harbor.relay_agent import RelayAgent

agent = RelayAgent(
    relay_host="127.0.0.1",
    relay_port=5000,
    relay_token="abc123",
    teardown_timeout_ms=5000,
)

await agent.setup(env)  # No-op for eval agents

await agent.run(
    instruction="run my-test",
    environment=env,     # An object implementing BaseEnvironment

    context={},          # Optional context passed through the relay

)

```

## The Setup Phase

The `RelayAgent.setup` method (lines 111–113) serves as a contract hook defined by the abstract `BaseAgent` class. While the eval implementation leaves this as a no‑op, the method exists so specialized agents can perform environment preparation, credential validation, or resource pre‑allocation before the main execution loop begins. This design pattern ensures all Maka agent lifecycle implementations follow a consistent preparation protocol.

## Execution Flow in RelayAgent.run

The core orchestration happens inside `RelayAgent.run` (lines 114–182), which implements the "run‑execute‑report‑verify" protocol through several distinct phases.

### Connection and Validation

First, the agent opens an asynchronous TCP connection to the relay host using `asyncio.open_connection`. It resolves the task's working directory inside the sandbox and invokes `_require_constrained_subject` to verify the subject operates under the correct network namespace and capability set before execution starts. This constraint check prevents privilege escalation before the agent sends the **ready** message containing the token, instruction, and current working directory.

### Command Preparation and Launch

Upon receiving the **execute** request via `_receive` and `_require_message`, the agent builds a safe command string using `_prepare_command`. This helper injects credentials and constructs the execution context, then the agent launches the subject through `environment.exec`.

```python

# Inside the agent – how a subject is prepared and executed

command = await _prepare_command(
    environment,               # The sandbox environment

    request,                   # JSON from the relay containing `command`, `args`, etc.

    token="abc123",
    scope_path="/logs/agent/.maka-eval-abc123.pid",
)

# Launch the subject inside the container

execution = asyncio.create_task(environment.exec(command, cwd=working_dir))

```

### Concurrent Monitoring and Reporting

During execution, the agent simultaneously waits for either the subject to finish naturally or a **verify** control message from the relay. Once the subject completes, `_persist_subject_outputs` captures stdout and stderr artifacts, while `_project_result` and `_decode_result_carrier` decode the result payload. The agent then transmits an **executed** message containing the exit code, output streams, and diagnostic information, followed by blocking on the **verify** message to complete the round‑trip handshake.

## Cancellation and Teardown Handling

When the coroutine receives a cancellation signal—triggered by trial abortion or timeout—the Maka agent lifecycle enters its critical termination path (lines 183–225). The agent determines whether the subject remains active and invokes `_settle_or_destroy` to attempt graceful shutdown via SIGTERM followed by SIGKILL within the configured timeout window.

```python

# Graceful termination path (triggered by cancellation)

result = await _settle_or_destroy(
    environment,
    cwd=working_dir,
    scope_path="/logs/agent/.maka-eval-abc123.pid",
    execution=execution,
    timeout=5.0,
)

```

If the subject refuses to terminate gracefully, the agent forcibly stops the container and dispatches a final **executed** message indicating whether the shutdown was normal or forced. This ensures runaway subjects cannot survive a cancelled trial.

## Cleanup and Resource Management

Regardless of exit path—successful completion or cancellation—the agent executes a deterministic cleanup sequence (lines 226–274). It cancels any pending decision tasks, removes temporary scope files and environment artifacts from the container using `_quiesce_scope`, and gracefully closes the network writer. These steps ensure no stray files, zombie processes, or open sockets persist after the agent finishes, implementing the cleanup guarantee required by the `BaseAgent` contract.

## Summary

- **Initialization** occurs in `RelayAgent.__init__`, validating timeouts and storing relay connection details in [`packages/eval/harbor/relay_agent.py`](https://github.com/apache/maka/blob/main/packages/eval/harbor/relay_agent.py).
- **Setup** follows the `BaseAgent` contract through `RelayAgent.setup`, providing a hook for preparation logic even when unused by eval agents.
- **Execution** runs through `RelayAgent.run`, implementing the "run‑execute‑report‑verify" state machine with concurrent subject monitoring and relay communication.
- **Cancellation** triggers `_settle_or_destroy` to deliver SIGTERM/SIGKILL cascades and forcibly destroy containers that exceed the teardown timeout.
- **Cleanup** removes all temporary scopes, cancels pending tasks, and closes network connections to prevent resource leakage.

## Frequently Asked Questions

### What is the base class for Maka agents?

All concrete agents inherit from `BaseAgent`, defined in the harbor or pier agents base module. This abstract class establishes the `setup` and `run` interface contract that `RelayAgent` implements in [`packages/eval/harbor/relay_agent.py`](https://github.com/apache/maka/blob/main/packages/eval/harbor/relay_agent.py).

### How does RelayAgent handle runaway processes?

When a subject refuses to terminate gracefully, `_settle_or_destroy` sends SIGTERM, waits for the configured timeout, escalates to SIGKILL, and finally forcibly destroys the container if the process group remains active. This multi-stage escalation prevents zombie processes from surviving agent cancellation.

### What happens when a Maka agent is cancelled mid-execution?

The cancellation handler in `RelayAgent.run` (lines 183–225) intercepts the `asyncio.CancelledError`, checks subject status, initiates the settlement protocol via `_settle_or_destroy`, transmits a termination status message to the relay, and proceeds to cleanup. This ensures the relay receives notification even during abnormal termination.

### Where is the agent lifecycle state machine defined?

The deterministic state machine—progressing from `init` → `setup` → `run` → (normal completion or cancellation) → `cleanup`—is implemented entirely within the `RelayAgent` class in [`packages/eval/harbor/relay_agent.py`](https://github.com/apache/maka/blob/main/packages/eval/harbor/relay_agent.py), with state transitions managed through Python's `asyncio` event loop and structured exception handling.