How to Configure no-mistakes for a Specific Repository: A Complete Guide
Configure no-mistakes for a specific repository by creating a .no-mistakes.yaml file in the repository root, which defines pipeline steps, trusted commands, and gate policies that the daemon merges with global defaults before execution.
The kunchenguid/no-mistakes tool relies on a per-repository configuration file to customize its continuous integration pipeline and security gates. To configure no-mistakes for a specific repository, you must create a .no-mistakes.yaml file at the repository root, which controls everything from test commands to auto-fix policies while maintaining strict security boundaries between trusted and untrusted configuration sources.
Where Configuration Lives
The configuration system spans three layers: global defaults hardcoded in the binary, repository-specific overrides in your local file, and trusted configuration fetched from the default branch.
The Repository Configuration File
Every repository protected by no-mistakes requires a .no-mistakes.yaml file in the Git root. This file is read by both the CLI when starting a run (internal/cli/daemon_cmd.go) and by the daemon process (internal/daemon/manager.go). The file uses YAML format and supports two distinct security zones: trusted keys (executable commands) and untrusted keys (informational settings).
Global Defaults
The internal/config/config.go file defines the DefaultConfig struct, which provides fallback values for all repositories. These defaults include settings like ci_timeout and auto_fix policies, stored in config.autoFixDefaults. When you configure no-mistakes for a specific repository, your .no-mistakes.yaml values override these globals.
Trusted vs Untrusted Configuration
Understanding the security model is critical when you configure no-mistakes for a specific repository. The system splits configuration into two trust zones to prevent malicious pull requests from executing arbitrary code.
Trusted fields—including commands.{test,lint,format}, agent, commands.post_push, and document.instructions—are read only from the default branch at a pinned SHA. The daemon implements this protection in loadTrustedRepoConfig and validates it via assertGateTrustedConfigReadable.
Untrusted fields—such as ignore_patterns, auto_fix settings, and intent—can be set by any branch and are read from the current checkout. This split ensures that only repository maintainers can define executable commands, while contributors can adjust informational settings.
Creating Your Repository Configuration
To initialize no-mistakes in a new repository, run no-mistakes init, which invokes the wizard in internal/wizard/wizard.go to generate a starter .no-mistakes.yaml file.
Minimal Configuration Example
A functional .no-mistakes.yaml file separates trusted executable commands from untrusted behavioral settings:
# .no-mistakes.yaml – repository-specific configuration
# Trusted-only keys (read from default branch)
commands:
test: go test ./...
lint: golint ./...
format: gofmt -w .
document:
instructions: |
# Documentation policy
* One owner per fact
* Stale docs become pointers
* No AGENTS.md post-mortems
# Untrusted (can be set by branch)
auto_fix:
review: 1 # enable auto-fix for review findings
lint: 0 # keep lint findings manual
steps:
test:
enabled: true
lint:
enabled: true
document:
enabled: true
The commands and document.instructions keys are trusted-only and must exist in the default branch to take effect. The steps and auto_fix maps can be adjusted per branch.
Common Customization Scenarios
When you configure no-mistakes for a specific repository, you typically need to customize pipeline steps, command hooks, or auto-fix behavior. The following patterns cover the most common use cases:
| Goal | Configuration snippet | Explanation |
|---|---|---|
| Use a different test command | commands.test: "gotestsum --format testname" |
Trusted field—must exist in default branch to be accepted. |
| Skip lint on PRs | steps.lint.enabled: false |
Disables the lint gate entirely. |
| Enable auto-fix for review findings | auto_fix.review: 1 |
Untrusted field—can be set per branch. |
| Add a custom post-push hook | commands.post_push: "./scripts/check.sh" |
Trusted hook that runs after a successful push. |
| Restrict repository-wide commands | allow_repo_commands: false |
Must be set in the trusted default branch; prevents contributors from enabling arbitrary commands. |
Each gate in the pipeline follows the model described in docs/concepts/gate-model.md, and you can enable or disable individual gates via steps.<name>.enabled.
Configuration Loading and Validation
The no-mistakes daemon follows a strict merge process when loading configuration to maintain security guarantees.
- Local Load:
config.LoadRepoConfigreads.no-mistakes.yamlfrom the current checkout to obtain untrusted fields and local preferences. - Trusted Fetch:
loadTrustedRepoConfigininternal/daemon/manager.gofetches the same file from the remote default branch at a fresh SHA, extracting only trusted fields likecommands.*andallow_repo_commands. - Merge: The executor (
internal/pipeline/executor.go) combines the trusted configuration with the local configuration, with trusted values taking precedence. - Validation: If
loadTrustedRepoConfigfails to fetch or parse the trusted configuration, the run aborts immediately (TestLoadTrustedRepoConfig_FailClosedOnFetchFailure), following a fail-closed security policy.
This process ensures that when you configure no-mistakes for a specific repository, the system never executes commands defined in unmerged feature branches.
Summary
- Create a
.no-mistakes.yamlfile in the repository root to configure no-mistakes for a specific repository. - Place executable commands under the
commandskey and documentation policies underdocument.instructions—these are trusted-only and must be committed to the default branch. - Adjust behavioral settings like
auto_fixandstepsin any branch, as these are untrusted and informational only. - Use
no-mistakes initto generate a starter configuration via the wizard ininternal/wizard/wizard.go. - The daemon validates configuration in
internal/daemon/manager.gobefore execution, ensuring trusted fields originate from the default branch.
Frequently Asked Questions
What is the difference between trusted and untrusted configuration keys?
Trusted keys include any configuration that results in code execution, such as commands.test, commands.lint, and agent. These are read exclusively from the default branch to prevent malicious PRs from injecting arbitrary shell commands. Untrusted keys, like auto_fix.review or steps.lint.enabled, control informational or behavioral settings and can be modified in any branch. This separation is enforced by the loadTrustedRepoConfig function in internal/daemon/manager.go.
Can I use environment variables in my .no-mistakes.yaml file?
The configuration parser in internal/config/config.go processes the YAML file directly. While the source code does not explicitly mention environment variable expansion in the default configuration struct, you should verify the specific implementation in your version. For dynamic values, use the commands hooks to export variables before running tests or linting.
How do I disable specific pipeline steps for my repository?
Set steps.<name>.enabled: false in your .no-mistakes.yaml file. For example, to disable the lint gate, add steps.lint.enabled: false. This is an untrusted field, meaning you can toggle it per branch without requiring default branch approval. The executor in internal/pipeline/executor.go consults this setting when scheduling pipeline steps.
What happens if the trusted configuration fails to load?
The daemon implements a fail-closed policy. If loadTrustedRepoConfig cannot fetch the .no-mistakes.yaml from the default branch, or if the file contains malformed trusted keys, the run aborts immediately with a clear error. This behavior is tested in TestLoadTrustedRepoConfig_FailClosedOnFetchFailure and ensures that the system never runs with incomplete or potentially compromised security settings.
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 →