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

> Explore the layered Git-proxy architecture of the no-mistakes project. Learn how its Go design, AI pipeline, and TUI/AXI surfaces streamline development workflows.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: architecture
- Published: 2026-07-20

---

**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`](https://github.com/kunchenguid/no-mistakes/blob/main/root.go)** – Defines the root command wiring and the `attachRun` function that launches runs
- **[`daemon_cmd.go`](https://github.com/kunchenguid/no-mistakes/blob/main/daemon_cmd.go)** – Implements `no-mistakes daemon run` to start the background process
- **[`axi.go`](https://github.com/kunchenguid/no-mistakes/blob/main/axi.go)** – Provides the non-interactive AXI API surface for skill integrations
- **[`init.go`](https://github.com/kunchenguid/no-mistakes/blob/main/init.go)** – Handles repository initialization and gate setup

Commands emit telemetry through `trackCommand` (defined in [`internal/cli/telemetry.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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:
- **[`pipeline/steps/review.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline/steps/review.go)** – Core review logic that interacts with AI agents
- **[`pipeline/steps/test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline/steps/test.go)** – Test gate execution
- **[`pipeline/steps/lint.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline/steps/lint.go)** – Linting validation
- **[`pipeline/steps/push.go`](https://github.com/kunchenguid/no-mistakes/blob/main/pipeline/steps/push.go)** – Final push gate to the remote

### 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`](https://github.com/kunchenguid/no-mistakes/blob/main/agent.go)** – Defines the common interface for all agents
- **[`codex.go`](https://github.com/kunchenguid/no-mistakes/blob/main/codex.go)** – Codex adapter with JSON response parsing
- **[`claude.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/git.go)** – High-level Git helpers for operations like `git run`, `git diff`, and `git branch`
- **[`hook.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/db.go)** – Database initialization and schema definition
- **[`run.go`](https://github.com/kunchenguid/no-mistakes/blob/main/run.go)** – Run record accessors
- **[`finding.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) and repo-local configuration files. It performs trusted-branch loading and resolves defaults for agents, commands, and policies.

- **[`config.go`](https://github.com/kunchenguid/no-mistakes/blob/main/config.go)** – Central configuration loader and validator

### Infrastructure Utilities

Several supporting packages handle cross-cutting concerns:

**Path Management (`internal/paths`)**
- **[`paths.go`](https://github.com/kunchenguid/no-mistakes/blob/main/paths.go)** – Resolves filesystem locations relative to `$NM_HOME` and abstracts OS-specific quirks

**Branch Synchronization (`internal/branchsync`)**
- **[`sync.go`](https://github.com/kunchenguid/no-mistakes/blob/main/sync.go)** – Implements safe `no-mistakes sync` operations with fast-forwarding and worktree recovery

**Shell Environment (`internal/shellenv`)**
- **[`shell_command.go`](https://github.com/kunchenguid/no-mistakes/blob/main/shell_command.go)** – Provides `ConfigureShellCommand` and `RunShellCommand` helpers that ensure proper context and cleanup of grandchild processes

**Terminal UI (`internal/tui`)**
- **[`tui.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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:

```go
// 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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/cli/root.go):

```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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/agent/codex.go) demonstrates this pattern:

```go
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:

```go
// 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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/lock.go)
- **Pluggable agent system** – Supports multiple AI providers through a common interface in [`internal/agent/agent.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/db/db.go) file handles schema initialization and connection management, while [`finding.go`](https://github.com/kunchenguid/no-mistakes/blob/main/finding.go) and [`run.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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.