An AI coding agent shouldn't just generate code. It should understand the task, plan the implementation, execute safely, verify its work, and recover when things go wrong.

We've all seen the evolution of AI coding tools.

First, autocomplete.

Then, conversational coding assistants.

Now, autonomous agents that can read repositories, modify files, execute commands, and orchestrate entire development workflows.

But there's a problem I keep coming back to:

What happens when an AI agent makes a mistake with access to your actual development environment?

What happens when two agents modify the same files? What happens when a process crashes halfway through a task? What happens when a model-generated command attempts to access something it shouldn't?

I wanted to approach these problems from a systems engineering perspective.

That's why I'm building "M31A" (https://github.com/eshanized/M31A).

It's an autonomous software-engineering runtime written in Rust, designed around controlled execution, policy enforcement, workflow orchestration, and verifiable outcomes.

This article explores some of the engineering decisions behind it.

  1. The problem with simply wrapping an LLM

A typical coding-agent architecture looks something like this:

  1. Send context to an LLM.
  2. Receive a tool call.
  3. Execute the tool.
  4. Return the result.
  5. Repeat until the model decides it's finished.

This works for simple tasks.

But it becomes considerably more complicated when you introduce:

  • Parallel agents.
  • Long-running engineering tasks.
  • Concurrent file modifications.
  • Persistent execution state.
  • Human approval requirements.
  • Crash recovery.
  • Security boundaries.
  • Reliable verification.

An LLM's decision to finish isn't proof that the task is complete.

M31A approaches this differently.

The model is responsible for reasoning and proposing actions. The runtime is responsible for enforcing execution rules and maintaining system integrity.

The distinction is important.

  1. A workflow engine instead of an infinite agent loop

M31A uses structured workflow orchestration rather than relying exclusively on an unstructured tool-calling loop.

The architecture is built around typed tasks and a Directed Acyclic Graph (DAG).

A workflow can contain different task categories:

  • Analysis
  • Implementation
  • Speculative execution
  • Integration
  • Verification
  • Delivery

Independent tasks can execute in parallel, while dependencies determine execution order.

Take a look at the implementation:

Source: "AUTONOMOUS_WORKFLOW_ARCHITECTURE.md" (https://github.com/eshanized/M31A/blob/master/docs/architecture/AUTONOMOUS_WORKFLOW_ARCHITECTURE.md)

The architecture includes:

  • DAG validation using Kahn's algorithm.
  • Topological execution waves.
  • Write-path conflict detection.
  • Bounded worker concurrency.
  • Durable task state.
  • Worker leases and recovery.

One particularly interesting implementation is:

"workflow_store.rs" (https://github.com/eshanized/M31A/blob/master/crates/m31a-storage/src/workflow_store.rs)

The "WorkflowStore::claim_ready_task" operation handles task claiming with dependency validation and worker lease semantics.

Why does that matter?

Imagine two workers attempting to execute the same task.

Or imagine a worker crashing and another worker taking over.

A simple in-memory task queue isn't sufficient for these scenarios.

M31A uses durable state and worker fencing to prevent stale workers from overwriting newer execution results.

This is the kind of infrastructure that becomes important when an agent needs to work beyond a single short interaction.

  1. Security is part of the runtime, not an optional feature

This is probably the area I've spent the most architectural attention on.

Giving an AI agent shell access is powerful.

It's also dangerous.

A permission prompt alone isn't a complete security architecture.

M31A implements an execution-policy subsystem with an 11-stage policy gate and a decision model covering:

  • "ALLOW"
  • "DENY"
  • "ASK"
  • "ESCALATE"

Policy resolution also incorporates precedence rules and fail-closed approval semantics.

Relevant implementation and documentation:

OS-level sandboxing

M31A also has a dedicated sandbox subsystem.

On Linux, it supports Bubblewrap isolation and Landlock-based filesystem restrictions.

The sandbox runner is implemented here:

"crates/m31a-sandbox/src/runner.rs" (https://github.com/eshanized/M31A/blob/master/crates/m31a-sandbox/src/runner.rs)

One interesting design decision is the use of a typed command representation:

pub enum SandboxCommand {
Shell(String),
Exec {
program: String,
args: Vec,
},
}

Why not simply accept a command string everywhere?

Because a shell command and a direct executable invocation have different semantics.

Keeping them distinct helps avoid argument-splitting and quoting problems.

The sandbox also uses platform-specific isolation backends and enforces failure behavior when required confinement is unavailable.

Additional implementation:

"landlock.rs" (https://github.com/eshanized/M31A/blob/master/crates/m31a-sandbox/src/landlock.rs)

My philosophy here is straightforward:

If the runtime cannot establish the security boundary required by a policy, it shouldn't silently pretend that execution is safe.

  1. Crash recovery and durable execution

Here's another problem that doesn't receive enough attention in AI coding tools.

What happens when an agent crashes halfway through a workflow?

Suppose an agent:

  1. Creates a task plan.
  2. Modifies three files.
  3. Runs tests.
  4. Crashes before recording the result.

Should the entire workflow start again?

Should another worker repeat completed operations?

Could a stale worker overwrite newer results?

These are distributed-systems problems, even when everything runs on a developer's local machine.

M31A addresses these through:

  • SQLite-backed workflow persistence.
  • Worker leases.
  • Lease renewal.
  • Stale task reconciliation.
  • Optimistic concurrency checks.
  • Durable workflow events.
  • Content-addressed artifacts.

The implementation is available in:

"workflow_store.rs" (https://github.com/eshanized/M31A/blob/master/crates/m31a-storage/src/workflow_store.rs)

The architectural explanation is documented in:

"AUTONOMOUS_WORKFLOW_ARCHITECTURE.md" (https://github.com/eshanized/M31A/blob/master/docs/architecture/AUTONOMOUS_WORKFLOW_ARCHITECTURE.md)

The objective is to make long-running agent execution recoverable and auditable instead of treating every interruption as a completely new session.

  1. It isn't tied to a single interface

I don't want the runtime to become inseparable from its terminal interface.

M31A exposes an App Server based on JSON-RPC 2.0.

This creates a separation between the execution engine and its clients.

The protocol supports:

  • Thread and session management.
  • Turn execution.
  • Streaming notifications.
  • Tool lifecycle events.
  • Human approval callbacks.
  • Checkpoint operations.
  • Agent coordination.

Architecture and protocol:

"docs/APP_SERVER_RPC.md" (https://github.com/eshanized/M31A/blob/master/docs/APP_SERVER_RPC.md)

The longer-term architectural direction is to make the same underlying runtime accessible through different clients, rather than implementing separate agent engines for every interface.

  1. Why Rust?

Rust wasn't selected simply because it's fashionable.

M31A has several requirements that make systems-level engineering particularly relevant:

  • Explicit ownership and resource management.
  • Strong type boundaries.
  • Concurrent execution.
  • Process isolation.
  • Predictable failure handling.
  • Reliable persistence.
  • Maintainable subsystem boundaries.

The repository is organized as a multi-crate Cargo workspace.

Instead of concentrating every responsibility in one enormous application module, subsystems have explicit boundaries.

You can explore the workspace here:

"Explore the M31A crates" (https://github.com/eshanized/M31A/tree/master/crates)

  1. What I'm trying to build

I don't think the next generation of coding agents should be judged exclusively by how impressive their generated code looks.

We should also ask:

  • Can the agent explain what it changed?
  • Can we constrain what it is allowed to execute?
  • Can we recover after an unexpected crash?
  • Can multiple agents collaborate without corrupting shared state?
  • Can we verify that the requested work was actually completed?
  • Can developers inspect the decisions and execution history?

These are the questions driving M31A.

It's an ongoing engineering project, and I don't want to pretend that every architectural challenge has been solved.

I'd rather build, test, expose the implementation, and invite people to challenge the design.

  1. Explore the project

Repository: https://github.com/eshanized/M31A

If you're interested in the implementation, I'd particularly recommend exploring:

Area| Source
Workflow orchestration| "crates/m31a-agent-engine/"
Execution policies| "crates/m31a-execpolicy/"
Sandbox runtime| "crates/m31a-sandbox/"
Workflow persistence| "crates/m31a-storage/"
App Server| "crates/m31a-app-server/"
Architecture documentation| "docs/architecture/"

Contributions, architectural criticism, bug reports, and security feedback are welcome.

Let's discuss something.

I have three questions for developers building autonomous coding systems:

  1. Execution security: Would you trust an AI coding agent with unrestricted shell access, or should every action pass through a runtime-enforced policy system?

  2. Architecture: Do you think DAG-based workflow orchestration is a better foundation for long-running autonomous engineering tasks than a conventional agent loop?

  3. Verification: Should an AI coding agent be allowed to declare a task complete, or should completion always require independently verifiable evidence?

I'd genuinely like to hear different engineering perspectives, especially from people building coding agents, developer infrastructure, and systems software.

M31A is open source. Let's build better autonomous engineering systems together.

— Eshan Roy

GitHub: https://github.com/eshanized/M31A