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 theattachRunfunction that launches runsdaemon_cmd.go– Implementsno-mistakes daemon runto start the background processaxi.go– Provides the non-interactive AXI API surface for skill integrationsinit.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:
pipeline/steps/review.go– Core review logic that interacts with AI agentspipeline/steps/test.go– Test gate executionpipeline/steps/lint.go– Linting validationpipeline/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– Defines the common interface for all agentscodex.go– Codex adapter with JSON response parsingclaude.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 likegit run,git diff, andgit branchhook.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 definitionrun.go– Run record accessorsfinding.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_HOMEand abstracts OS-specific quirks
Branch Synchronization (internal/branchsync)
sync.go– Implements safeno-mistakes syncoperations with fast-forwarding and worktree recovery
Shell Environment (internal/shellenv)
shell_command.go– ProvidesConfigureShellCommandandRunShellCommandhelpers 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:
- Entry point –
cmd/no-mistakes/main.gobuilds the CLI and executescli.Execute() - CLI parsing – Commands like
initorpushare parsed ininternal/cli/root.go, with telemetry emitted viatrackCommand - Daemon communication – The CLI contacts the singleton daemon through
internal/ipcsockets; if absent, it launches viadaemon_cmd.go - Run creation – Upon push, the daemon creates a disposable worktree using
internal/githelpers and inserts a newRunrecord viainternal/db - Pipeline execution – The worktree is processed through
internal/pipelinesteps, each invoking agents frominternal/agentto generate structured JSON output - Findings generation – Auto-fixable findings are applied directly to the worktree; others are surfaced via TUI or AXI
- Finalization – Success triggers a push to the configured remote via the Git module, optionally opening a PR via GitHub API
- User interaction – Developers monitor runs through
internal/tuior issueaxi drive/axi querycommands 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →