Complete Guide to no-mistakes Environment Variables: Configuration and Testing

The no-mistakes CLI and daemon recognize over a dozen environment variables ranging from global configuration settings like NM_HOME and NM_DEMO to internal testing hooks such as NM_TEST_START_DAEMON and NM_CAPTURE_NM_HOME_FILE.

The kunchenguid/no-mistakes repository relies heavily on environment variables to control runtime behavior, daemon connectivity, and test execution. Understanding these no-mistakes environment variables is essential for customizing the tool's data directories, connection timeouts, and debugging test suites across different environments.

Global Runtime Configuration

Several variables control the fundamental behavior of no-mistakes in production environments.

NM_HOME

The NM_HOME variable defines the root directory for all no-mistakes state, including configuration files, databases, logs, Unix sockets, and worktrees. According to the source code in internal/paths/paths.go, this variable defaults to ~/.no-mistakes when unset. Changing NM_HOME effectively relocates the entire no-mistakes footprint, making it useful for isolated installations or CI/CD pipelines.

// internal/paths/paths.go
func NewPaths() *Paths {
    if env := os.Getenv("NM_HOME"); env != "" {
        return &Paths{Root: env}
    }
    return &Paths{Root: filepath.Join(os.Getenv("HOME"), ".no-mistakes")}
}

The daemon initialization code in internal/daemon/daemon.go and the CLI entry point in cmd/no-mistakes/main.go both respect this variable when establishing the runtime environment.

NM_DEMO

Set NM_DEMO=1 to enable demo mode, which causes the pipeline to use mock steps for recordings rather than executing real operations. The check occurs in internal/pipeline/steps/demo.go, allowing safe demonstration of no-mistakes workflows without side effects.

NM_DAEMON_CONNECT_TIMEOUT

This variable overrides the default 3-second timeout used by CLI clients when connecting to the daemon's Unix socket (or TCP on Windows). The implementation in internal/daemon/selfexec.go uses Go's time.ParseDuration to parse any valid duration string.

// internal/daemon/selfexec.go
connTimeout := 3 * time.Second
if s := os.Getenv("NM_DAEMON_CONNECT_TIMEOUT"); s != "" {
    if d, err := time.ParseDuration(s); err == nil {
        connTimeout = d
    }
}

NM_UPDATE_CHECK_SKIP

When set, this variable suppresses the automatic GitHub release check that normally runs on every CLI invocation except no-mistakes update. The check occurs in internal/update/helpers.go during CLI startup.

NM_TELEMETRY_DISABLED

Set this variable to disable all telemetry emission while still respecting rate limiting on read-only surfaces. The telemetry module in internal/telemetry/telemetry.go reads this flag during initialization.

Internal Testing Variables

The test suite uses several prefixed variables to control daemon behavior without modifying production code.

Daemon Testing Controls

NM_DAEMON_HELPER_PROCESS: When set to 1, the daemon launches a helper process that immediately exits, used by unit tests in internal/daemon/helpers_test.go and internal/daemon/service_test.go to avoid spawning real daemons during test runs.

NM_TEST_START_DAEMON: Forces the daemon's runWithOptions function in internal/daemon/service.go to start a test daemon instead of the production instance.

NM_TEST_DAEMON_START_TIMEOUT, NM_TEST_DAEMON_STOP_TIMEOUT, NM_TEST_DAEMON_START_POLL_INTERVAL: These variables control the back-off timings for test daemon lifecycle management, as implemented in internal/daemon/selfexec.go.

Capture and Verification

NM_CAPTURE_NM_HOME_FILE: When set to a file path, the test daemon writes the effective NM_HOME value it received to the specified file. This allows tests to assert that the daemon correctly respects environment variable inheritance. The implementation appears in internal/daemon/helpers_test.go.

// Example usage in tests
tmp := t.TempDir()
capture := filepath.Join(tmp, "nm_home.txt")
t.Setenv("NM_CAPTURE_NM_HOME_FILE", capture)

daemon.Start() // daemon writes its NM_HOME to capture file
data, _ := os.ReadFile(capture)

Shell Environment and Agent Testing

NM_SHELLENV_PIPE_HELPER and NM_SHELLENV_PIPE_READY: Used by shell-environment helpers in internal/shellenv/shell_command_unix_test.go to coordinate parent/child pipe readiness during tests.

NM_AGENT_NATIVE_PIPE_READY and NM_AGENT_NATIVE_PIPE_PID: Coordinate native agent pipe readiness in internal/agent/reap_unix_test.go.

NM_TEST_REAL_PI: When set to 1, enables integration tests that communicate with the real Pi-agent at ~/.pi/agent/sessions, as referenced in internal/intent/reader_pi_real_test.go.

Git Hook and Tooling Variables

Several variables support the Git hook infrastructure and binary stubbing:

  • NM_FAKE_BIN: Points to stub binaries for testing
  • NM_HOOK_HELPER: Used by the Git hook script in internal/git/hook.go
  • NM_BIN: Overrides the path to the no-mistakes binary in test scenarios

These appear in internal/git/hook.go and internal/cli/helpers_test.go to facilitate testing Git integrations without requiring actual repository modifications.

Environment Propagation Verification

NM_ENV_PROBE_*: Any environment variable with this prefix demonstrates that arbitrary variables are preserved when the daemon spawns subprocesses. The Git environment tests in internal/git/env_test.go verify that the entire environment—including these probe variables—is copied to child processes, ensuring that user environment settings persist through no-mistakes operations.

Summary

  • NM_HOME relocates all state directories from the default ~/.no-mistakes
  • NM_DEMO=1 enables mock recording mode for safe demonstrations
  • NM_DAEMON_CONNECT_TIMEOUT accepts any Go duration string to override the default 3-second connection timeout
  • NM_UPDATE_CHECK_SKIP and NM_TELEMETRY_DISABLED disable network checks and telemetry emission respectively
  • Test variables like NM_TEST_START_DAEMON and NM_CAPTURE_NM_HOME_FILE provide fine-grained control over daemon behavior during unit and integration tests
  • Git tooling variables (NM_FAKE_BIN, NM_HOOK_HELPER, NM_BIN) support hook testing and binary stubbing
  • The NM_ENV_PROBE_* prefix pattern verifies complete environment preservation across process boundaries

Frequently Asked Questions

How do I change the default location where no-mistakes stores its data?

Set the NM_HOME environment variable to your desired path. According to internal/paths/paths.go, this variable overrides the default ~/.no-mistakes directory, affecting where the daemon stores configuration files, databases, logs, and Unix sockets. Ensure this variable is set before starting the daemon or running CLI commands.

What environment variable controls how long the CLI waits for the daemon to respond?

NM_DAEMON_CONNECT_TIMEOUT controls the connection timeout between the CLI and daemon. The default is 3 seconds, but you can specify any valid Go duration string (e.g., 10s, 1m, 500ms). This is particularly useful on slower systems or when connecting over network file systems where socket creation might take longer.

Which environment variables are safe to use in production versus testing?

Production-safe variables include NM_HOME, NM_DEMO, NM_DEMON_CONNECT_TIMEOUT, NM_UPDATE_CHECK_SKIP, and NM_TELEMETRY_DISABLED. Variables prefixed with NM_TEST_, NM_DAEMON_HELPER_PROCESS, or NM_CAPTURE_NM_HOME_FILE are designed exclusively for the internal test suite and should not be used in production environments, as they modify daemon behavior in ways that could cause instability or data corruption.

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 →