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

> Master no-mistakes environment variables for seamless configuration and testing. Explore NM_HOME, NM_DEMO, NM_TEST_START_DAEMON, and more in this comprehensive guide.

- Repository: [Kun Chen/no-mistakes](https://github.com/kunchenguid/no-mistakes)
- Tags: how-to-guide
- Published: 2026-07-16

---

**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`](https://github.com/kunchenguid/no-mistakes/blob/main/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.

```go
// 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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/daemon.go) and the CLI entry point in [`cmd/no-mistakes/main.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/selfexec.go) uses Go's `time.ParseDuration` to parse any valid duration string.

```go
// 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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/helpers_test.go) and [`internal/daemon/service_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/helpers_test.go).

```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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/git/hook.go)
- **`NM_BIN`**: Overrides the path to the no-mistakes binary in test scenarios

These appear in [`internal/git/hook.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/git/hook.go) and [`internal/cli/helpers_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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`](https://github.com/kunchenguid/no-mistakes/blob/main/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.