Skip to content

Architecture

Eshan Roy edited this page Jun 16, 2026 · 4 revisions

Architecture

Overview

M31 Autonomous is a modular AI agent framework built in Go with a Bubble Tea TUI. It routes user prompts through a six-phase workflow engine, selects models by cost and quality, streams responses, and maintains full session history with cross-session learning.

The application is a single static binary compiled with CGO_ENABLED=0, ensuring maximum portability across platforms.

Directory Layout

.
├── cmd/m31a/              # Binary entry point
│   ├── main.go            # CLI flag parsing, dependency wiring, TUI launch
│   └── usage.go           # Usage/help text generation
├── docs/                  # User-facing documentation
├── internal/              # Private packages (not importable)
│   ├── codeintel/         # Code intelligence: project indexing, relevance scoring
│   ├── config/            # TOML config loader, validation, project context detection
│   ├── errors/            # Sentinel errors for the entire application
│   ├── fileutil/          # Atomic file write utilities
│   ├── git/               # Git operations abstraction (commit, diff, log, stash)
│   ├── log/               # Structured logging infrastructure (slog-based)
│   ├── provider/          # LLM provider abstraction layer
│   │   ├── openrouter/    # OpenRouter API client (300+ models)
│   │   └── zen/           # Zen API client (OpenCode gateway)
│   ├── tokens/            # tiktoken-based token counting and estimation
│   ├── tools/             # Tool registry, dispatcher, and all built-in tools
│   │   └── subagent/      # Parallel subagent manager with worktree isolation
│   ├── tui/               # Bubble Tea TUI — 29 screens, 5 themes
│   │   ├── commands/      # Slash command registry and built-in commands
│   │   ├── components/    # 40+ reusable TUI components
│   │   ├── layout/        # Responsive layout helpers
│   │   ├── streaming/     # Streaming response rendering and agent loop
│   │   ├── theme/         # Lipgloss theming (dark/light/auto/custom)
│   │   └── tuitypes/      # TUI-specific type definitions
│   ├── types/             # Core type definitions shared across all packages
│   └── workflow/          # Six-phase orchestration engine
│       └── prompts/       # Embedded markdown prompt templates
├── pkg/                   # Public, importable packages
│   ├── arbitrage/         # Model scoring, cost estimation, recommendation
│   ├── autodream/         # Context consolidation (AutoDream compressor)
│   ├── bisect/            # Git bisect wrapper for finding offending commits
│   ├── history/           # Session history store
│   ├── keychain/          # OS keychain abstraction (Linux/macOS/Windows)
│   ├── ledger/            # Cross-session learning ledger (markdown-backed)
│   ├── rollback/          # Commit-chain manager (soft/hard/safe reset)
│   ├── session/           # Session lifecycle, persistence, checkpointing
│   └── taskrunner/        # Sequential and parallel task executor
├── scripts/               # Acceptance test suite (verify_v1.sh)
├── install.sh             # One-liner installer script
├── Makefile               # Build, test, lint, cross-compile, release targets
└── .goreleaser.yaml       # Cross-compile and release configuration

Dependency Graph

cmd/m31a/main.go
    ├── internal/config        (load TOML config)
    ├── internal/log           (initialize structured logger)
    ├── pkg/keychain           (OS keychain for API keys)
    ├── internal/provider      (LLM provider registry)
    ├── pkg/session            (session manager)
    ├── internal/tools         (tool dispatcher)
    │   └── internal/tools/subagent (subagent manager)
    ├── internal/git           (git operations)
    ├── pkg/ledger             (learning ledger)
    ├── pkg/rollback           (commit rollback)
    ├── pkg/autodream          (context consolidation)
    └── internal/tui           (Bubble Tea TUI)
        ├── internal/tui/commands    (slash commands)
        ├── internal/tui/components  (UI components)
        ├── internal/tui/theme       (theming)
        ├── internal/tui/streaming   (response streaming)
        └── internal/workflow        (phase orchestration)

Core Types

Defined in internal/types/types.go:

Type Purpose
WorkflowPhase Enum: idle, initialize, discuss, plan, execute, verify, ship
TaskStatus Enum: pending, running, done, failed, skipped, unrecoverable
RiskLevel Enum: safe, medium, dangerous, destructive
ModelInfo Model metadata: ID, provider, pricing, context length, capabilities
Message Chat message with role, content, segments, tool calls, usage
ToolCall Structured tool invocation: ID, name, JSON input
ToolResult Tool execution outcome: output, error, duration, truncation flag
Tool Interface: Name, Description, RiskLevel, Execute
SchemaProvider Optional interface for tools providing JSON Schema parameters
Task Workflow task with ID, description, files, dependencies, acceptance criteria
StreamChunk SSE stream delta: text, thinking duration, tool call fragments
StreamIterator Cursor over streaming response with Next/Close functions

Constants

Defined in internal/types/constants.go:

Constant Value Purpose
MaxFileSize 5 MB Maximum file read size
MaxToolOutputChars 10,000 Maximum tool output characters
MaxHealAttempts 2 Self-healing retry limit per task
MaxPlanRetries 3 Plan generation retry limit
MaxPlanRefinements 5 Plan refinement limit
BashTimeout 30 min Maximum bash command duration
BashOutputLimit 50,000 Maximum bash output characters
MaxLLMResponseBytes 1 MB Maximum LLM response size
MaxSessionFileSize 50 MB Maximum session file size (OOM protection)
DefaultContextLength 128,000 Fallback context window size
MaxToolsPerCall 16 Maximum tool calls per LLM response
DefaultPermissionTimeout 300s Permission modal timeout
ModelCacheTTL 5 min Model cache time-to-live
DefaultMaxParallelTasks 4 Maximum concurrent task execution

Build System

The Makefile provides these key targets:

Target Description
make build Optimized binary with ldflags (version, commit, date)
make debug Debug binary with symbols (-gcflags "all=-N -l")
make test Race-enabled tests with coverage
make lint golangci-lint with 5-minute timeout
make check fmt + tidy + vet + test
make cross Build for linux/darwin/windows x amd64/arm64
make release GoReleaser snapshot

All binaries are compiled with CGO_ENABLED=0 for maximum portability. Version info is injected via ldflags at build time.

Key Design Decisions

  1. No CGO -- Static binary, no dynamic library dependencies, trivial cross-compilation.
  2. Bubble Tea TUI -- Elm-architecture with single-threaded Update() loop, preventing race conditions in state mutations.
  3. Embedded prompts -- Workflow prompt templates are compiled into the binary via //go:embed, eliminating runtime file dependencies.
  4. Project-local sessions -- Sessions live in <project>/.m31a/ instead of a global directory, keeping each project's state isolated.
  5. Atomic writes -- All file writes use temp-file-then-rename to prevent corruption on crash.
  6. Signal safety -- SIGTERM/SIGINT are routed through Bubble Tea's Send() channel, respecting the single-threaded model.

Clone this wiki locally