How the Architecture of the no-mistakes Project Is Structured: A Layered Git-Proxy Design

The architecture of the no-mistakes project implements a Git-proxy pattern using a layered Go design where a thin CLI interfaces with a singleton daemon to orchestrate disposable worktrees through an AI-driven pipeline, persisting all state in SQLite while exposing both interactive TUI and programmable AXI surfaces.

The kunchenguid/no-mistakes repository provides a Git-proxy that validates code through an AI-driven pipeline before it reaches a remote. The architecture of the no-mistakes project follows a clean, modular design organized under the internal/ directory, separating concerns into distinct packages for CLI handling, daemon management, pipeline execution, and persistence.

Architectural Overview

At its core, no-mistakes intercepts Git operations to inject validation steps. The high-level data flow follows this pattern:


git push → no-mistakes (CLI) → daemon (background process)
              │                     │
              ▼                     ▼
   disposable worktree → pipeline → agents → DB ↔ UI

When a developer invokes no-mistakes, the CLI either attaches to an existing run or communicates with the daemon via Unix sockets (internal/ipc). The daemon manages disposable worktrees, executes pipeline steps, and persists findings to an SQLite database before finally pushing to the remote repository.

Core Layers by Package

Command-Line Interface (internal/cli)

The CLI layer parses sub-commands and serves as the entry point for all user interactions. Located entirely within internal/cli/, this package handles commands like init, push, axi, and sync.

Key files include:

  • root.go – Defines the root command wiring and the attachRun function that launches runs
  • daemon_cmd.go – Implements no-mistakes daemon run to start the background process
  • axi.go – Provides the non-interactive AXI API surface for skill integrations
  • init.go – Handles repository initialization and gate setup

Commands emit telemetry through trackCommand (defined in internal/cli/telemetry.go) before delegating to helpers like attachRun.

Daemon Process (internal/daemon)

The daemon operates as a singleton process that holds a lock file (daemon/lock.go) to ensure only one instance runs per $NM_HOME. It watches the gate repository and exposes RPC endpoints over a Unix socket for both the CLI and UI components.

Core responsibilities include:

  • Spawning new pipeline runs when pushes reach the gate
  • Creating disposable worktrees via Git helpers
  • Managing long-running agent sessions

Pipeline Orchestration (internal/pipeline)

The pipeline engine orchestrates a series of validation steps including review, test, lint, document, and push. Each step can produce a finding that is either auto-fixed or presented to the user for approval.

Step implementations reside in sub-folders:

Agent Abstraction (internal/agent)

The agent layer provides pluggable adapters for different coding agents including claude, codex, copilot, opencode, pi, and rovodev. This package handles session reuse, fallbacks, metric collection, and streaming of prompts and responses.

Key implementations:

  • agent.go – Defines the common interface for all agents
  • codex.go – Codex adapter with JSON response parsing
  • claude.go – Claude adapter implementation

Agents receive structured prompts from pipeline steps and return JSON output that the pipeline converts into findings.

Git Operations (internal/git)

The Git abstraction wraps raw git commands behind a thin layer that respects bare-gate repositories. It injects the correct --git-dir flags when needed and manages post-receive hooks.

Key files:

  • git.go – High-level Git helpers for operations like git run, git diff, and git branch
  • hook.go – Post-receive hook logic for the gate repository

This layer ensures safe manipulation of disposable worktrees without affecting the user's working directory.

Persistence (internal/db)

All state lives in an SQLite database located at <NM_HOME>/db.sqlite. The persistence layer stores run metadata, findings, agent invocations, and configuration.

Key components:

  • db.go – Database initialization and schema definition
  • run.go – Run record accessors
  • finding.go – Finding representation and storage

Typed accessors provide safe interaction with repos, runs, and findings data models.

Configuration (internal/config)

The configuration layer reads global settings from .no-mistakes.yaml and repo-local configuration files. It performs trusted-branch loading and resolves defaults for agents, commands, and policies.

  • config.go – Central configuration loader and validator

Infrastructure Utilities

Several supporting packages handle cross-cutting concerns:

Path Management (internal/paths)

  • paths.go – Resolves filesystem locations relative to $NM_HOME and abstracts OS-specific quirks

Branch Synchronization (internal/branchsync)

  • sync.go – Implements safe no-mistakes sync operations with fast-forwarding and worktree recovery

Shell Environment (internal/shellenv)

  • shell_command.go – Provides ConfigureShellCommand and RunShellCommand helpers that ensure proper context and cleanup of grandchild processes

Terminal UI (internal/tui)

  • tui.go – Implements the interactive TUI showing current runs, findings, and controls for accept/skip/patch actions

End-to-End Execution Flow

Understanding how these layers interact clarifies the no-mistakes architecture:

  1. Entry point – cmd/no-mistakes/main.go builds the CLI and executes cli.Execute()
  2. CLI parsing – Commands like init or push are parsed in internal/cli/root.go, with telemetry emitted via trackCommand
  3. Daemon communication – The CLI contacts the singleton daemon through internal/ipc sockets; if absent, it launches via daemon_cmd.go
  4. Run creation – Upon push, the daemon creates a disposable worktree using internal/git helpers and inserts a new Run record via internal/db
  5. Pipeline execution – The worktree is processed through internal/pipeline steps, each invoking agents from internal/agent to generate structured JSON output
  6. Findings generation – Auto-fixable findings are applied directly to the worktree; others are surfaced via TUI or AXI
  7. Finalization – Success triggers a push to the configured remote via the Git module, optionally opening a PR via GitHub API
  8. User interaction – Developers monitor runs through internal/tui or issue axi drive/axi query commands for programmatic access

Key Implementation Patterns

Repository Initialization

When running no-mistakes init, the system creates a gate repository and initializes the database:

// internal/cli/init.go
func runInit(ctx context.Context, out io.Writer, repoPath string) error {
    // Resolve paths, ensure directories.
    p, d, err := openResources()
    if err != nil { return err }
    defer d.Close()

    // Initialise the gate repository.
    gate, err := d.CreateGate(repoPath)
    if err != nil { return err }

    fmt.Fprintf(out, "✓ Gate initialized\n")
    fmt.Fprintf(out, "repo  %s\n", p.RepoRoot())
    fmt.Fprintf(out, "gate  %s → %s\n", gate.Name, gate.Path)
    return nil
}

Run Attachment Flow

The default command (no-mistakes without arguments) attaches to the current run via attachRun in internal/cli/root.go:

func attachRun(ctx context.Context, out io.Writer, branch string, interactive, autoYes bool, skip []string) error {
    // Find the repo, open DB, create a new run if needed.
    repo, err := findRepo(db)
    if err != nil { return err }

    // Create a disposable worktree, start the pipeline.
    run, err := daemon.StartRun(ctx, repo, branch, skip)
    if err != nil { return err }

    // If interactive, launch the TUI.
    if interactive {
        return tui.Start(run)
    }
    return nil
}

Agent Invocation

Pipeline steps invoke agents through the abstraction layer. The Codex adapter in internal/agent/codex.go demonstrates this pattern:

func (c *codexAgent) Invoke(ctx context.Context, prompt string) (AgentResult, error) {
    // Build the exec command (`codex exec --json`).
    cmd := exec.CommandContext(ctx, "codex", "exec", "--json")
    // Stream prompt via stdin.
    cmd.Stdin = strings.NewReader(prompt)

    out, err := cmd.Output()
    if err != nil { return AgentResult{}, err }

    // Decode the JSON output.
    var res codexResponse
    if err := json.Unmarshal(out, &res); err != nil { return AgentResult{}, err }
    return AgentResult{Text: res.Completion, Metrics: res.Metrics}, nil
}

Finding Persistence

Findings are stored via the database layer using prepared statements:

// internal/db/finding.go
func (d *DB) InsertFinding(runID int64, f Finding) error {
    _, err := d.Exec(`
        INSERT INTO findings (run_id, kind, severity, auto_fixable, data)
        VALUES (?, ?, ?, ?, ?)
    `, runID, f.Kind, f.Severity, f.AutoFixable, f.Data)
    return err
}

Summary

The architecture of the no-mistakes project delivers a robust, modular Git-proxy through these key design decisions:

  • Separation of concerns – Each component (CLI, daemon, pipeline, agents) lives in isolated packages under internal/
  • Singleton daemon pattern – Ensures serialized access to the gate repository via file locking in internal/daemon/lock.go
  • Pluggable agent system – Supports multiple AI providers through a common interface in internal/agent/agent.go
  • Disposable worktrees – Isolates validation from user working directories using Git abstraction layer
  • SQLite persistence – Centralizes state management in a single file database accessed via internal/db
  • Dual interface – Supports both interactive TUI and programmatic AXI surfaces for different workflows

Frequently Asked Questions

How does the CLI communicate with the daemon?

The CLI communicates with the daemon through Unix domain sockets implemented in the internal/ipc package. When a user runs a command like no-mistakes push, the CLI first attempts to connect to an existing daemon socket; if none exists, it spawns a new daemon process via internal/cli/daemon_cmd.go and then establishes the connection.

What database does no-mistakes use for persistence?

The project uses SQLite for all persistence needs, storing data in a file located at <NM_HOME>/db.sqlite. The internal/db/db.go file handles schema initialization and connection management, while finding.go and run.go provide typed accessors for specific entities.

How are AI agents integrated into the validation pipeline?

Agents are integrated through the internal/agent package, which defines a common interface that all providers (Claude, Codex, Copilot, etc.) must implement. Pipeline steps in internal/pipeline/steps/ invoke these agents by sending structured prompts and receiving JSON responses, which are then converted into findings that drive auto-fix logic or user approval workflows.

What is the purpose of the "gate repository" in no-mistakes?

The gate repository is a bare Git repository that acts as an intermediate staging area between the user's local commits and the remote. When users push, they actually push to this local gate, triggering the no-mistakes daemon to create a disposable worktree, run the validation pipeline, and only forward the commits to the true remote after all checks pass.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →