.no-mistakes.yaml Configuration Options vs Global Config: Complete Reference

The .no-mistakes.yaml file controls repository-specific settings like custom commands and ignore patterns, while ~/.no-mistakes/config.yaml stores user-wide defaults for agents, binary paths, and CI timeouts, with the two configs merged via config.Merge() in internal/config/config.go.

The no-mistakes daemon uses a two-tier configuration system to balance flexibility with security. Understanding the difference between repository-specific .no-mistakes.yaml files and the global ~/.no-mistakes/config.yaml is essential for setting up automated code review pipelines securely.

Global Configuration (~/.no-mistakes/config.yaml)

The global configuration is defined by the GlobalConfig struct in internal/config/config.go (lines 40-53). These settings act as user-wide defaults that affect every repository unless overridden locally.

Core Global Options

The global config stores environment-wide defaults that rarely change between projects:

  • agent: Default agent selection (auto, claude, codex, open_code, pi, or acp:<target>)
  • acpx_path: Path to the acpx binary when using ACP agents
  • acp_registry_overrides: Map of per-target command overrides for custom ACP agents
  • agent_path_override: Map overriding binary paths for native agents like claude or codex
  • agent_args_override: Map of extra CLI arguments for native agents (validated via validateAgentArgsOverride)
  • ci_timeout / babysit_timeout: Duration string for maximum idle time during CI monitoring. Supports keywords unlimited, none, off, or never mapped via parseCITimeout (lines 22-39)
  • log_level: Logging verbosity (debug, info, warn, error)
  • auto_fix: Per-step auto-fix attempt limits (lint, test, review, document, CI, rebase)
  • intent: Settings for automatic user-intent extraction (enabled, threshold, slack days, disabled readers)
  • test: Test-step evidence configuration (store_in_repo, dir)

The default template written by EnsureDefaultGlobalConfig lives in defaultConfigYAML (lines 75-124).

Repository Configuration (.no-mistakes.yaml)

Repository-specific settings are defined by the RepoConfig struct in internal/config/config.go (lines 69-84). These options only make sense on a per-repo basis and include security-sensitive execution fields.

The repo config contains code-executing fields that require special security handling:

  • commands: Custom command strings for lint, test, and format that replace built-in defaults. These are sourced from the trusted default-branch copy unless allow_repo_commands is true (see EffectiveRepoConfig, lines 78-92)
  • allow_repo_commands: Boolean flag determining whether the daemon honors commands and agent from pushed branches. Defaults to false to prevent supply-chain injection
  • agent: Overrides the global agent for this specific repository
  • ignore_patterns: File-path globs that the pipeline should ignore (e.g., ["*.md", "docs/**"])

Per-Repository Overrides

Beyond execution fields, repos can override behavior-specific settings:

  • auto_fix: Repo-specific auto-fix limits that override global settings
  • intent: Repo-specific intent extraction settings
  • test: Repo-specific test evidence configuration

How Configurations Are Merged

The Merge() function (lines 441-475) produces the final Config used by the daemon through a specific precedence algorithm.

The Merge Algorithm

The merge process follows this priority:

  1. Starts with global defaults for Agent, ACPXPath, AgentPathOverride, AgentArgsOverride, CITimeout, LogLevel, AutoFix, Intent, and Test
  2. Overwrites with repository values where specified:
    • Agent (if non-empty) → repo-specific agent
    • Commands and IgnorePatterns come only from repo config
    • AutoFix, Intent, Test are deep-merged with repo overrides taking precedence

Trusted vs. Pushed Copies

Security-critical fields (commands, agent) behave differently based on allow_repo_commands:

  • When false (default): The daemon reads these fields only from the trusted default-branch SHA via loadTrustedRepoConfig in internal/daemon/manager.go
  • When true: The daemon honors values from the pushed branch copy

This design is tested in internal/e2e/repo_config_security_test.go, confirming that malicious commands in feature branches are ignored unless explicitly allowed.

Practical Configuration Examples

Global Config Example

Create ~/.no-mistakes/config.yaml with user-wide defaults:

agent: auto
log_level: info
ci_timeout: "168h"     # 7 days; use "unlimited" for no timeout

auto_fix:
  lint: 3
  test: 3
  review: 0
intent:
  enabled: true
  threshold: 0.2
  slack_days: 3

Repository Config Example

Place .no-mistakes.yaml in your repository root:

agent: claude
commands:
  lint: "golint ./..."
  test: "go test ./... -race"
ignore_patterns:
  - "*.md"
  - "docs/**"
allow_repo_commands: false   # keep defaults (recommended)

auto_fix:
  lint: 1          # be stricter on this repo

intent:
  enabled: false   # disable intent extraction for this repo

test:
  evidence:
    store_in_repo: true
    dir: ".no-mistakes/evidence"

When contributors push branches, the daemon reads the trusted default-branch copy. Because allow_repo_commands is false, the commands and agent values from pushed branches are ignored, protecting against malicious edits.

Loading Configuration Programmatically

The configuration loading process follows this pattern:

global, _ := config.LoadGlobal(filepath.Join(home, ".no-mistakes", "config.yaml"))
repo, _   := config.LoadRepo(repoRoot)                     // reads .no-mistakes.yaml
finalCfg := config.Merge(global, repo)                    // final Config used by the daemon

Relevant functions: LoadGlobal (lines 57-84), LoadRepo (lines 41-55), and Merge (lines 441-475).

Summary

  • Global config (~/.no-mistakes/config.yaml) stores user-wide defaults including agent binaries, timeout settings, and default auto-fix behavior via the GlobalConfig struct
  • Repository config (.no-mistakes.yaml) provides per-repo overrides for commands, ignore patterns, and security settings via the RepoConfig struct
  • Security model: The allow_repo_commands flag controls whether execution fields (commands, agent) are read from pushed branches or only from the trusted default-branch copy
  • Merging: The Merge() function combines both configs, with repository values taking precedence for overlapping fields
  • File locations: Global config lives in the user's home directory; repo config must be at the repository root

Frequently Asked Questions

What happens if I define the same option in both config files?

Repository-specific values in .no-mistakes.yaml override global settings during the merge process. For example, if auto_fix.lint is set to 3 globally but 1 in the repo config, the daemon uses 1. However, fields like commands and ignore_patterns only exist in the repository config and have no global equivalent.

Why does the no-mistakes daemon ignore my commands in pushed branches?

By default, allow_repo_commands is false in the trusted copy of .no-mistakes.yaml. The daemon loads execution fields (commands, agent) exclusively from the default-branch SHA to prevent supply-chain attacks where malicious commands could be injected via pull requests. Set allow_repo_commands: true only if you explicitly trust all branches to define custom commands.

Can I use different agents for different repositories?

Yes. While the global config sets a default agent (e.g., auto), any repository can override this in .no-mistakes.yaml by specifying a different agent like claude, codex, or acp:custom-target. This override is respected as long as the repository config is properly loaded via config.LoadRepo().

How do I set an unlimited CI timeout?

In ~/.no-mistakes/config.yaml, set ci_timeout or babysit_timeout to the string "unlimited", "none", "off", or "never". The parseCITimeout function maps these keywords to an unlimited sentinel value, while other values are parsed as duration strings like "168h" for 7 days.

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 →