# Repository Trust Boundary Model for .no-mistakes.yaml Configuration

> Learn about the repository trust boundary model for .no-mistakes.yaml config. Secure critical settings by reading exclusively from the default branch to prevent malicious overrides.

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

---

**The trust boundary ensures that security-critical settings in [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml), such as `disable_project_settings` and `allow_repo_commands`, are read exclusively from the default branch while ignoring potentially malicious versions on contributor branches.**

The `no-mistakes` CLI establishes a strict security boundary around its configuration file. According to the `kunchenguid/no-mistakes` source code, the tool treats the [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) file on the default branch as the sole authoritative source for security-sensitive settings, completely isolating these from potentially malicious contributions on pull request branches.

## Why the Trust Boundary Exists

The daemon executes arbitrary commands defined under the `commands:` key, such as tests, linters, and formatters. Without a trust boundary, a malicious contributor could modify [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) on their branch to inject harmful commands that compromise the runner.

Additionally, certain configuration fields control whether project-level settings are honored at all. These must be decided from a source that cannot be tampered with by untrusted contributors.

## How the Boundary Is Enforced in manager.go

The enforcement logic lives primarily in [`internal/daemon/manager.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/manager.go), which implements a six-step verification process:

1. **Resolve the trusted SHA** – When a run starts, the daemon fetches the default branch (usually `origin/main`) and records the exact commit SHA. This happens in lines 191-203: *"fetch default branch … obtain trustedSHA"*.

2. **Verify the trusted commit is readable** – The daemon checks that the SHA points to a valid commit and that the tree contains a [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml). If checks fail, the run aborts. See `assertGateTrustedConfigReadable` at lines 491-511.

3. **Load the trusted config** – The file is read from the trusted commit using `git.ShowFile` and parsed into a `RepoConfig`. This occurs in `loadTrustedRepoConfig` at lines 456-470.

4. **Apply the trust rules** – The effective configuration merges three sources: (a) global config, (b) untrusted repo config (PR branch), and (c) trusted repo config. Crucially, only the trusted copy can affect security-critical fields. The merge happens at lines 210-211 via `config.Merge`.

5. **Enforce the opt-out** – If `disable_project_settings: true` is present in the trusted config, the daemon ignores all agent-driven commands from the untrusted branch. This is the core security boundary.

6. **Respect `allow_repo_commands`** – This boolean is read only from the trusted config. When true, the daemon runs `commands.*` defined in the trusted file; otherwise, those commands are ignored regardless of the PR branch contents.

## Security-Critical Configuration Fields

Two fields in [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) are restricted to the trusted configuration:

### disable_project_settings

When set to `true` in the trusted config, this flag forces the daemon to ignore all project-wide settings from the untrusted branch. According to [`internal/config/config.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/config/config.go) (lines 119-148), this acts as a fail-safe that prevents arbitrary command execution from contributor branches.

### allow_repo_commands

This boolean determines whether repository-defined commands are executed at all. It is read exclusively from the trusted SHA. If the trusted config does not enable this flag, commands defined in a PR branch's [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) are completely ignored.

## Configuration Examples

### Trusted Configuration Structure

```yaml

# .no-mistakes.yaml (trusted copy, stored on the default branch)

commands:
  test:   "go test -race ./..."
  lint:   "make lint"
  format: "gofmt -w ."

# Opt-out of trusting the project-wide settings.

# When true, ANY commands from the PR branch are ignored.

disable_project_settings: true

# Explicitly enable repo-level commands (still read from the trusted copy only)

allow_repo_commands: true

```

### Go Implementation of Config Merge

```go
// Minimal snippet showing how the daemon merges configs.
// The trusted config (loaded from the default-branch SHA) is the only source for
// security-critical fields.
trustedCfg := loadTrustedRepoConfig(ctx, workDir, trustedSHA, runID)
allowRepoCmds := trustedCfg != nil && trustedCfg.AllowRepoCommands
effectiveCfg := config.Merge(globalCfg,
    config.EffectiveRepoConfig(untrustedRepoCfg, trustedCfg, allowRepoCmds))

```

## Validation and Testing

The trust boundary is validated by comprehensive test suites:

- [`internal/e2e/repo_config_security_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/e2e/repo_config_security_test.go) confirms that a pushed-branch `allow_repo_commands: true` is ignored when the trusted default-branch does not enable it.
- [`internal/daemon/manager_gate_optout_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/manager_gate_optout_test.go) verifies that the `disable_project_settings` opt-out flag must be present in the trusted config to be honored.

## Summary

Key takeaways from the `no-mistakes` trust boundary model:

- **Default branch authority**: Only the [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) on the default branch (e.g., `main`) controls security-critical settings.
- **Fail-closed design**: If the daemon cannot read the trusted config, the run aborts rather than falling back to untrusted data.
- **Immutable security fields**: Settings like `disable_project_settings` and `allow_repo_commands` cannot be overridden by contributor branches.
- **Explicit untrusted data marking**: Throughout the pipeline, user-generated content is explicitly marked as untrusted data in files like [`internal/pipeline/steps/intent_prompt.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/pipeline/steps/intent_prompt.go).

## Frequently Asked Questions

### What happens if the trusted [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml) is missing?

The run aborts immediately. The `assertGateTrustedConfigReadable` function in [`internal/daemon/manager.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/manager.go) (lines 491-511) verifies that the trusted SHA points to a valid commit containing the configuration file. If any check fails, the daemon fails closed rather than proceeding with untrusted defaults.

### Can a contributor override `disable_project_settings` on their PR branch?

No. The `disable_project_settings` flag is read exclusively from the trusted default-branch configuration. Even if a contributor sets this to `true` in their branch's [`.no-mistakes.yaml`](https://github.com/kunchenguid/no-mistakes/blob/main/.no-mistakes.yaml), the daemon ignores it unless the default branch version also contains the flag. This is verified in [`internal/daemon/manager_gate_optout_test.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/manager_gate_optout_test.go).

### How does the daemon distinguish between trusted and untrusted configuration?

The daemon resolves the default branch SHA at startup (lines 191-203 in [`manager.go`](https://github.com/kunchenguid/no-mistakes/blob/main/manager.go)) and loads the configuration from that specific commit using `git.ShowFile`. Security-critical fields are extracted only from this trusted snapshot, while the PR branch configuration is treated as untrusted data that can only provide benign metadata.

### Where are the security-critical fields defined in the codebase?

The `RepoConfig` struct and its security documentation are defined in [`internal/config/config.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/config/config.go) (lines 119-148). The merge logic that prioritizes the trusted copy is implemented in [`internal/daemon/manager.go`](https://github.com/kunchenguid/no-mistakes/blob/main/internal/daemon/manager.go) at lines 210-211, where `config.Merge` combines global, untrusted, and trusted configurations while restricting security fields to the trusted source.