Documentation
¶
Index ¶
- Constants
- func EnsureDefaultGlobalConfig(path string)
- func ParseLogLevel(level string) slog.Level
- func RenderedInstructions(instructions string) string
- func ReviewPathInstructionsBytes(entries []PathInstruction) int
- func ValidateWorktreeRoots(roots map[string]string) error
- type AutoFix
- type AutoFixRaw
- type CI
- type CIRaw
- type Commands
- type Commit
- type CommitRaw
- type Config
- func (c *Config) AgentArgs() []string
- func (c *Config) AgentArgsFor(name types.AgentName) []string
- func (c *Config) AgentPath() string
- func (c *Config) AgentPathFor(name types.AgentName) string
- func (c *Config) AgentProfile() agentcfg.Profile
- func (c *Config) AgentProfileFor(name types.AgentName) agentcfg.Profile
- func (c *Config) AutoFixLimit(step types.StepName) int
- func (c *Config) EnableEvalProvenance(global *GlobalConfig, repo *RepoConfig) error
- func (c *Config) ResolveAgent(ctx context.Context, lookPath func(string) (string, error)) error
- type Document
- type DocumentRaw
- type Eval
- type EvalRaw
- type Evidence
- type EvidenceRaw
- type ForgeProfile
- type ForgeProfiles
- type GlobalConfig
- type GlobalConfigMapping
- type GlobalConfigMappingEntry
- type Intent
- type IntentRaw
- type PR
- type PRRaw
- type PathInstruction
- type RepoConfig
- type Review
- type ReviewRaw
- type Test
- type TestRaw
Constants ¶
const ( // DefaultCITimeout is the monitor's idle timeout when ci_timeout is unset. DefaultCITimeout = 7 * 24 * time.Hour // DefaultStepQuietWarning is how long a running/fixing step can go without // a new log or lifecycle activity before AXI status marks it quiet. DefaultStepQuietWarning = 10 * time.Minute // DefaultAgentTimeout bounds one pipeline agent invocation that does not // install a more specific deadline, so a stalled agent cannot leave a run // active forever. Review and Test keep their own knobs; this is the // default-by-construction budget for every other step. DefaultAgentTimeout = 30 * time.Minute // DefaultReviewAgentTimeout bounds one review round, including its optional // review-fix and rereview turns, so a stalled agent cannot leave a run // active forever. DefaultReviewAgentTimeout = 30 * time.Minute // DefaultTestAgentTimeout bounds one Test-step agent invocation, including // the post-test evidence-gathering turn and a Test-repair turn, so a stalled // agent cannot leave a run active forever. DefaultTestAgentTimeout = 30 * time.Minute // DefaultDaemonConnectTimeout bounds client IPC connection attempts to a // daemon socket that exists but is not accepting connections. DefaultDaemonConnectTimeout = 3 * time.Second // DefaultBranchSyncRemoteTimeout bounds each remote Git operation (ls-remote, fetch) in internal/branchsync. Global-config-only; a pushed branch cannot change it. Timeout still fails closed. DefaultBranchSyncRemoteTimeout = 60 * time.Second // CITimeoutUnlimited is the sentinel meaning "monitor until the PR is // merged, closed, or the run is aborted - never self-terminate". // Any non-positive ci_timeout, or the keywords "unlimited", "none", // "off", and "never", resolves to this. CITimeoutUnlimited = time.Duration(-1) // DefaultCIRerunTransient is the per-check rerun budget the CI step uses // when ci.rerun_transient is unset. It is 0 because GitHub's CANCELLED // conclusion does not carry a cause: the same value covers a provider // aborting its own infrastructure, a maintainer stopping a runaway or // unsafe job, and repository concurrency with cancel-in-progress. Until a // reliable cause signal exists, restarting on that ambiguity risks // re-running work a person deliberately stopped, so rerunning cancelled // checks is an explicit opt-in rather than a default. DefaultCIRerunTransient = 0 // MaxCIRerunTransient caps ci.rerun_transient. Reruns are cheap compared // with an agent round, but they are not free: each one keeps the monitor // polling the same commit, so the budget stays small by construction. MaxCIRerunTransient = 5 // DefaultEvalMaxCases caps the auto-captured local eval corpus. Cases // share one object pool per repository, so the marginal cost of a case is // its JSON records plus the objects its commits actually introduced, not a // copy of the repository. The cap exists to bound that JSON and to keep // the corpus a recent, representative window rather than an archive. DefaultEvalMaxCases = 200 // DefaultEvalDiversifiedSize caps the official gold-only eval set. // 0 means one gold case per stratum with no Hamilton bound. DefaultEvalDiversifiedSize = 32 // DefaultEvidenceRetention is how long a run's on-disk evidence survives // before the daemon reaps it. It is comfortably longer than typical PR // review latency because a PR body references these artifacts by local path // whenever publishing is off or the provider has no derivable links. This // is no-mistakes' own budget: the point of owning it is that no OS temp // timer decides when a user's screenshots disappear. DefaultEvidenceRetention = 14 * 24 * time.Hour // DefaultEvidenceMaxRuns caps how many run directories survive regardless // of age, so a burst of parallel runs that all land inside the retention // window still cannot grow the directory without bound. DefaultEvidenceMaxRuns = 200 )
CI monitor timeout constants.
CITimeout is interpreted by the CI step as the maximum time to babysit an open PR with no base-branch movement before giving up. The monitor re-arms this timer every time the base branch advances (see internal/pipeline/steps ci.go), so an actively-rebased PR keeps its monitor. The value is deliberately long because a green PR can legitimately wait days on a dependency PR or on review; a torn-down or abandoned run is reaped explicitly via `no-mistakes axi abort --run <id>` rather than by a short timeout.
const ( ReviewPathInstructionsHeading = "" /* 190-byte string literal not displayed */ ReviewPathInstructionsPathLabel = "path: " ReviewPathInstructionsFilesLabel = "matched files: " ReviewPathInstructionsRulesLabel = "instructions:" // ReviewPathInstructionsMaxFilesBytes bounds the matched-file list a single // block may print. A broad glob can match hundreds of files, so the review // step truncates the list deterministically and states the remaining count; // the accounting charges every entry this full allowance so the cap holds // for any diff rather than only for small ones. ReviewPathInstructionsMaxFilesBytes = 192 )
Review-prompt block frame for review.path_instructions.
The review step renders every matched entry as
path: <path> matched files: <files> instructions: <instructions>
so each rule travels with the scope it was selected for and no block can read as a global instruction. The labels live here rather than in the review step because the byte accounting below has to measure the real assembled section, not an estimate of it; internal/pipeline/steps builds its blocks from these same constants and TestReviewPathInstructionsSectionStaysWithinAccountedBytes is the drift check.
const ( // MaxReviewPathInstructions is the largest number of path_instructions // entries a repository may configure. MaxReviewPathInstructions = 32 // MaxReviewPathInstructionsBytes is the largest review-prompt section // path_instructions may produce, measured by ReviewPathInstructionsBytes. // It leaves room for the entry cap to be reached with a rule of ordinary // length, so neither cap makes the other unusable. MaxReviewPathInstructionsBytes = 16384 )
Bounds on review.path_instructions.
The injected text lands in the review prompt, which is already the largest gate prompt no-mistakes builds, and an oversized prompt fails the agent invocation outright instead of degrading. The budget is therefore validated when the config is parsed - before a run starts - rather than truncated silently at review time.
const DefaultFixMessageTemplate = "no-mistakes({{.Step}}): {{.Summary}}"
DefaultFixMessageTemplate preserves the built-in auto-fix commit subject.
const MaxFixMessageSummaryBytes = 4096
MaxFixMessageSummaryBytes bounds agent-provided fix summaries before rendering.
Variables ¶
This section is empty.
Functions ¶
func EnsureDefaultGlobalConfig ¶ added in v1.1.0
func EnsureDefaultGlobalConfig(path string)
EnsureDefaultGlobalConfig writes the default config file at path if it does not already exist. Failures are logged at debug level and silently ignored.
func ParseLogLevel ¶
ParseLogLevel converts a log level string to slog.Level. Accepted values: "debug", "info", "warn", "error". Defaults to slog.LevelInfo.
func RenderedInstructions ¶ added in v1.44.0
RenderedInstructions is the emptiness-agreement helper for instruction text, not a second copy of the prompt renderer. The real renderer is sanitizePromptMultilineText in internal/pipeline/steps, which additionally normalizes CR and collapses each line's runs of whitespace; internal/config cannot import that package, which is why the conflict-marker replacer above is duplicated here at all. Two invariants tie the two together, and the rest of this feature silently depends on both:
- Emptiness agrees exactly. This returns "" for precisely the inputs the prompt renderer reduces to "", so validation can reject a value that would otherwise reach the reviewer as an empty block.
- The prompt renderer never lengthens text, so the rendered instructions are no longer than strings.TrimSpace of the raw value and ReviewPathInstructionsBytes stays an upper bound on the assembled section.
A change to sanitizePromptMultilineText that can lengthen text (escaping, wrapping) or that strips a token this replacer keeps breaks one of them; TestPathInstructionRenderingAgreesWithConfigValidation is the drift check.
func ReviewPathInstructionsBytes ¶ added in v1.44.0
func ReviewPathInstructionsBytes(entries []PathInstruction) int
ReviewPathInstructionsBytes returns the largest review-prompt section these entries can produce: the leading blank line, the heading, and for every entry its labels, its path, its instructions, its full matched-file allowance, and the separator before it. Instruction text can only shrink on its way into the prompt (conflict markers are removed and whitespace is collapsed), and the matched-file list is truncated to its allowance, so the result is an upper bound on the real section for any diff.
func ValidateWorktreeRoots ¶ added in v1.56.0
ValidateWorktreeRoots checks a worktree_roots map before any placement is derived from it. Every entry must name an absolute checkout path and an absolute directory: a relative path would be interpreted against whatever working directory the daemon happens to have, so run worktrees would land somewhere different depending on who started it - the opposite of the deterministic placement the setting exists to provide.
Two entries may not name the same root, and two keys may not name the same checkout once canonicalized (a symlink and its target, "/x" and "/x/"). Both are rejected rather than resolved because the consequences are destructive, not cosmetic: cleanup and eject identify a run worktree by its position in a root, so two repositories sharing a root would delete each other's runs, and a duplicate key would pick an arbitrary winner. A root equal to its own checkout is rejected for the same reason - it would place run worktrees inside the repository they are validating.
Types ¶
type AutoFix ¶ added in v1.1.0
AutoFix holds resolved per-step auto-fix attempt limits. A value of 0 means auto-fix is disabled (requires manual approval).
type AutoFixRaw ¶ added in v1.1.0
type AutoFixRaw struct {
Lint *int `yaml:"lint"`
Test *int `yaml:"test"`
Review *int `yaml:"review"`
Document *int `yaml:"document"`
CI *int `yaml:"ci"`
Babysit *int `yaml:"babysit"`
Rebase *int `yaml:"rebase"`
}
AutoFixRaw is the YAML representation of auto-fix config. Pointer fields distinguish "not set" (nil) from "set to 0" (disabled).
type CI ¶ added in v1.45.0
type CI struct {
// RerunTransient is how many times the CI step may re-run a single check
// the provider reported as cancelled - the one terminal outcome it
// attributes to itself rather than to the job - before that check reaches
// an approval gate. 0 disables reruns and restores the behavior of
// escalating every failure on sight.
RerunTransient int
}
CI holds the resolved CI-step settings.
type CIRaw ¶ added in v1.45.0
type CIRaw struct {
RerunTransient *int `yaml:"rerun_transient"`
}
CIRaw is the YAML representation of CI-step settings. Pointer fields distinguish "not set" (nil) from "set to 0" (disabled).
type Commands ¶
type Commands struct {
Lint string `yaml:"lint"`
Test string `yaml:"test"`
Format string `yaml:"format"`
}
Commands holds optional per-repo command overrides.
type Commit ¶ added in v1.40.0
type Commit struct {
FixMessage string
}
Commit is the resolved auto-fix commit configuration.
type CommitRaw ¶ added in v1.40.0
type CommitRaw struct {
FixMessage *string `yaml:"fix_message"`
}
CommitRaw is the YAML representation of auto-fix commit settings.
type Config ¶
type Config struct {
ReplayGlobalYAML []byte
ReplayRepoYAML []byte
TrustedConfigSHA string
CaptureEvalProvenance bool
Agent types.AgentName
Agents []types.AgentName
ACPXPath string
ForgejoAXIPath string
ACPRegistryOverrides map[string]string
AgentPathOverride map[string]string
AgentArgsOverride map[string][]string
AgentConfig map[string]agentcfg.Profile
CITimeout time.Duration
StepQuietWarning time.Duration
AgentTimeout time.Duration
ReviewAgentTimeout time.Duration
TestAgentTimeout time.Duration
LogLevel string
SessionReuse bool
Eval Eval
Commands Commands
IgnorePatterns []string
AutoFix AutoFix
CI CI
Commit Commit
Intent Intent
Test Test
Document Document
Review Review
PR PR
ForgeProfiles ForgeProfiles
// DisableProjectSettings is the resolved, trusted-only opt-out (see the
// RepoConfig field). When true, gate agents are launched with their
// project-level settings/instructions suppressed; the daemon fails the run
// closed if the resolved harness has no verified suppression knob.
DisableProjectSettings bool
// NoCI is the resolved, trusted-only declaration that this repository
// intentionally has no CI (see the RepoConfig field). When true and the
// forge reports zero checks, the CI monitor treats that as all-checks-passed.
NoCI bool
}
Config is the merged result of global + per-repo configuration.
func Merge ¶
func Merge(global *GlobalConfig, repo *RepoConfig) *Config
Merge combines global and per-repo config. Per-repo agent values, including ordered fallback lists, override global agent values when non-empty. Commands and ignore patterns come from repo config only.
func (*Config) AgentArgs ¶ added in v1.10.0
AgentArgs returns extra CLI args for the configured native agent, as declared in agent_args_override. Returns nil when no override is set for this agent.
func (*Config) AgentArgsFor ¶ added in v1.34.0
func (*Config) AgentPath ¶
AgentPath returns the binary path for the configured agent. ACP agents and ACP aliases use acpx_path if set, otherwise acpx. Native agents use agent_path_override if set, otherwise the default binary name.
func (*Config) AgentPathFor ¶ added in v1.34.0
func (*Config) AgentProfile ¶ added in v1.57.0
AgentProfile returns the harness-neutral model/effort selection for the configured agent, as declared in agent_config. The zero Profile means the harness keeps its own defaults.
func (*Config) AgentProfileFor ¶ added in v1.57.0
func (*Config) AutoFixLimit ¶ added in v1.1.0
AutoFixLimit returns the max auto-fix attempts for a given step. Steps without auto-fix support return 0.
func (*Config) EnableEvalProvenance ¶ added in v1.49.0
func (c *Config) EnableEvalProvenance(global *GlobalConfig, repo *RepoConfig) error
EnableEvalProvenance pins the exact configuration this run reviews under so a later replay grades a candidate against identical conditions. The caller decides whether to call it (see Eval.CaptureProvenance); this is the single owner of what "exact provenance" contains.
func (*Config) ResolveAgent ¶ added in v1.1.0
ResolveAgent resolves configured agent names to available agents. A single explicit agent must be runnable; auto probes native agents, then ACP aliases; an ordered list is filtered to available agents, deduplicated by resolved identity, and kept as fallbacks. The lookPath function should behave like exec.LookPath.
type Document ¶ added in v1.35.0
type Document struct {
Instructions string
}
Document is the resolved document-step config. Instructions come from the trusted default-branch repo config and augment the built-in placement policy in the document prompt.
type DocumentRaw ¶ added in v1.35.0
type DocumentRaw struct {
// Instructions augment (never replace) the built-in documentation
// placement policy with the repository's ownership map or extra
// placement rules.
Instructions string `yaml:"instructions"`
}
DocumentRaw is the YAML representation of document-step settings.
type Eval ¶ added in v1.50.0
type Eval struct {
CaptureProvenance bool
AutoCapture bool
// MaxCases caps the auto-captured corpus. 0 keeps every case. Pruning is
// oldest-first and never removes a case that already has recorded
// candidate replays, so a corpus you have spent tokens on is never
// silently reclaimed underneath a comparison.
MaxCases int
// DiversifiedSize caps the official gold-only eval set. 0 means one gold
// case per stratum (no Hamilton bound). Unlabeled cases never fill it.
DiversifiedSize int
}
Eval is the resolved local evaluation-corpus config. It is deliberately a first-class configuration key rather than an environment variable: the daemon is a long-lived launchd/systemd service whose unit file is re-rendered on install and update, and only proxy variables survive that re-render, so an environment-gated corpus would silently stop collecting after an update.
CaptureProvenance is the upstream half: it makes every review round record the exact commit and configuration inputs a replay needs. A round written with it off can never be captured afterwards, because the pinned global configuration is a point-in-time snapshot that no longer exists anywhere.
AutoCapture is the downstream half: it freezes each finished run's review passes into the local corpus without anyone running a command. It has no effect while CaptureProvenance is off, since there is nothing to freeze.
type EvalRaw ¶ added in v1.50.0
type EvalRaw struct {
CaptureProvenance *bool `yaml:"capture_provenance"`
AutoCapture *bool `yaml:"auto_capture"`
MaxCases *int `yaml:"max_cases"`
DiversifiedSize *int `yaml:"diversified_size"`
}
EvalRaw is the YAML representation of local evaluation-corpus settings. Pointer fields distinguish "not set" (nil) from explicit zero/false values.
type Evidence ¶ added in v1.23.0
type Evidence struct {
StoreInRepo bool
Dir string
Branch string
// LocalRoot overrides the app-root default for on-disk evidence; empty
// means paths.EvidenceDir(). Retention and MaxRuns bound how much of it
// survives: no-mistakes reaps its own evidence rather than leaving that to
// an OS temp-directory timer. Zero disables the corresponding bound.
LocalRoot string
Retention time.Duration
MaxRuns int
}
Evidence is the resolved test-evidence config. When StoreInRepo is true, the run publishes its evidence artifacts to the orphan Branch of the same repository, under Dir, and links them from the pull request body. Evidence never enters the pushed code branch, so it never reaches the default branch's history. Otherwise evidence stays on local disk under LocalRoot, referenced only by local path.
type EvidenceRaw ¶ added in v1.23.0
type EvidenceRaw struct {
StoreInRepo *bool `yaml:"store_in_repo"`
Dir *string `yaml:"dir"`
// Branch selects the orphan evidence branch. It names a git ref the
// daemon pushes to with the maintainer's credentials, so it is honored
// ONLY from the trusted default-branch copy of .no-mistakes.yaml (see
// EffectiveRepoConfig): a contributor's pushed branch must not be able to
// aim evidence commits at another branch of the repository.
Branch *string `yaml:"branch"`
// LocalRoot, Retention, and MaxRuns describe this MACHINE's evidence
// storage: where the daemon writes artifacts on local disk and how long it
// keeps them. They are global-only - Merge resolves them straight from
// GlobalConfig and never from a repository, trusted copy included. A
// repository does not get to name a filesystem path the daemon writes to,
// nor to set the retention budget for a resource every other repository on
// the machine shares. (Contrast Branch, which is trusted-repo-settable
// because a branch genuinely is per-repository state.)
//
// LocalRoot must be absolute; see validateTestRaw.
LocalRoot *string `yaml:"local_root"`
Retention *string `yaml:"retention"`
MaxRuns *int `yaml:"max_runs"`
}
EvidenceRaw is the YAML representation of test-evidence settings. Pointer fields distinguish "not set" (nil) from explicit zero/false values.
type ForgeProfile ¶ added in v1.59.0
type ForgeProfile struct {
GHConfigDir string `yaml:"gh_config_dir"`
GLabConfigDir string `yaml:"glab_config_dir"`
ExpectedLogin string `yaml:"expected_login"`
}
ForgeProfile selects one isolated provider CLI configuration directory. ExpectedLogin optionally pins the account the profile must be signed in as; resolution fails closed when the profile's active login differs. It carries an account name only, never credentials.
type ForgeProfiles ¶ added in v1.59.0
type ForgeProfiles map[string]ForgeProfile
ForgeProfiles maps a remote host token to its machine-local provider profile.
type GlobalConfig ¶
type GlobalConfig struct {
SourceYAML []byte `yaml:"-"`
Agent types.AgentName `yaml:"agent"`
Agents []types.AgentName `yaml:"-"`
ACPXPath string `yaml:"acpx_path"`
ForgejoAXIPath string `yaml:"forgejo_axi_path"`
ACPRegistryOverrides map[string]string `yaml:"acp_registry_overrides"`
AgentPathOverride map[string]string `yaml:"agent_path_override"`
AgentArgsOverride map[string][]string `yaml:"agent_args_override"`
// AgentConfig is the harness-neutral per-agent tuning map (agent_config):
// model and reasoning effort stated once in a common spelling, mapped down
// to each harness's own mechanism by internal/agentcfg. It is additive to
// agent_args_override, which still wins for any knob it already pins
// natively, so every configuration written before this field keeps its exact
// previous behavior. Global-only for the same reason as
// agent_args_override: it describes this machine's agent setup and decides
// which model runs with the operator's credentials, so no pushed branch may
// set it.
AgentConfig map[string]agentcfg.Profile `yaml:"agent_config"`
// WorktreeRoots places a repository's pipeline run worktrees under a
// directory the operator chose instead of the default
// <NM_HOME>/worktrees/<repoID>. Keys are registered checkout paths
// (Repo.WorkingPath), values are absolute directories. It exists for
// directory-scoped toolchain configuration (mise, direnv), which resolves
// by path ancestry and therefore never reaches a worktree under NM_HOME.
// Placement is resolved for every consumer in internal/worktrees.
WorktreeRoots map[string]string `yaml:"worktree_roots"`
CITimeout time.Duration `yaml:"-"`
StepQuietWarning time.Duration `yaml:"-"`
AgentTimeout time.Duration `yaml:"-"`
ReviewAgentTimeout time.Duration `yaml:"-"`
TestAgentTimeout time.Duration `yaml:"-"`
DaemonConnectTimeout time.Duration `yaml:"-"`
BranchSyncRemoteTimeout time.Duration `yaml:"-"`
LogLevel string `yaml:"log_level"`
// SessionReuse controls per-run agent session reuse in the review loop:
// one durable fixer session across review-fix turns. Review turns always
// run session-free so the rereview never resumes the session whose
// findings prescribed the fixes it certifies. Default true; set
// session_reuse: false to force every invocation cold.
SessionReuse bool `yaml:"-"`
ForgeProfiles ForgeProfiles `yaml:"forge_profiles"`
AutoFix AutoFixRaw
// CI is the operator's own CI-step floor. It is the only place the rerun
// budget can be set for a repository whose default branch this machine's
// user does not control (the common case when contributing to someone
// else's project), and a trusted repo value still wins over it.
CI CIRaw
Commit CommitRaw
Intent IntentRaw
Test TestRaw
// Eval is resolved at load time because it is global-only: it describes
// this machine's local eval corpus (disk, retention, whether review rounds
// record replay provenance), never a repository policy. Keeping it out of
// RepoConfig means no pushed branch can enable, disable, or resize it.
Eval Eval
}
GlobalConfig represents ~/.no-mistakes/config.yaml.
func DefaultGlobalConfig ¶ added in v1.34.0
func DefaultGlobalConfig() *GlobalConfig
DefaultGlobalConfig returns the built-in global defaults.
func LoadGlobal ¶
func LoadGlobal(path string) (*GlobalConfig, error)
LoadGlobal reads global config from path. Returns defaults if file doesn't exist.
func LoadGlobalFromBytes ¶ added in v1.49.0
func LoadGlobalFromBytes(data []byte) (*GlobalConfig, error)
type GlobalConfigMapping ¶ added in v1.56.0
type GlobalConfigMapping struct {
// Present reports that the key is in the document, whatever its value.
Present bool
// AppendableBlock reports that one more indented entry line under the key is
// a valid edit.
AppendableBlock bool
// EntryIndent is the column the key's entries start at, counted from zero, so
// an added or replaced entry line matches its siblings. Zero when the key has
// no entries to match.
EntryIndent int
// Line is the document line that spells the key, as written, so guidance can
// name the line to replace. Empty when the key's value spans further lines.
Line string
// Entries are the key's entries in document order, so a replacement can
// carry the ones the operator already has.
Entries []GlobalConfigMappingEntry
}
GlobalConfigMapping describes how a top-level mapping key is written in the global config document. It is what decides which edit an operator can be told to make, and every field answers a question the parsed configuration cannot.
Presence: `key:` with nothing after it and `key: {}` both decode to a map of length zero, exactly like an absent key, so anything that must not duplicate a top-level key has to ask the document. YAML rejects a duplicate top-level key outright, leaving a configuration that no longer loads.
Shape: an entry line can be added under a key only when its value is a BLOCK mapping. After `key: {}` or `key: {a: b}` an indented entry line is not a continuation of the mapping at all - YAML rejects the document with "did not find expected key" - and after a valueless `key:` the safe edit is the same replacement, so both are reported as not appendable.
Indentation: siblings of a block mapping all sit at the same column, so an entry line added at a different one is rejected the same way. The document is hand-maintained, so its indentation is whatever its operator chose.
func InspectGlobalConfigMapping ¶ added in v1.56.0
func InspectGlobalConfigMapping(path, key string) GlobalConfigMapping
InspectGlobalConfigMapping describes the top-level key in the global config document at path.
It never fails: a missing or unreadable file has no key, and a file this package cannot parse is scanned for the key written at the start of a line, which is where a top-level key is - reported as present but not appendable, so guidance falls back to naming the whole replacement. Callers that must not write a second top-level key are the reason presence is still answered for a document nothing could parse; every caller in this repository refuses such a configuration before it asks.
type GlobalConfigMappingEntry ¶ added in v1.56.0
GlobalConfigMappingEntry is one entry of a top-level mapping, spelled the way the document spells it.
type IntentRaw ¶ added in v1.14.0
type IntentRaw struct {
Enabled *bool `yaml:"enabled"`
Threshold *float64 `yaml:"threshold"`
SlackDays *int `yaml:"slack_days"`
DisabledReaders []string `yaml:"disabled_readers"`
}
IntentRaw is the YAML representation of user-intent extraction settings. Pointer fields distinguish "not set" (nil) from explicit zero/false values.
type PR ¶ added in v1.56.0
type PR struct {
BaseBranch string
}
PR is the resolved pull-request configuration.
type PRRaw ¶ added in v1.56.0
type PRRaw struct {
// BaseBranch selects the forge branch a PR targets. It is gate-control
// configuration: the trusted default-branch copy wins unless the
// repository explicitly opts into pushed-branch settings with
// allow_repo_commands.
BaseBranch string `yaml:"base_branch"`
}
PRRaw is the YAML representation of pull-request settings.
type PathInstruction ¶ added in v1.44.0
PathInstruction is one glob-scoped block of review guidance. Path follows the same match rules as ignore_patterns: no slash matches by basename, a trailing "/**" matches an entire subtree, and anything else is a full-path glob.
type RepoConfig ¶
type RepoConfig struct {
Agent types.AgentName `yaml:"agent"`
Agents []types.AgentName `yaml:"-"`
Commands Commands `yaml:"commands"`
IgnorePatterns []string `yaml:"ignore_patterns"`
// AllowRepoCommands opts in to honoring the code-executing selection
// fields (commands.{test,lint,format} and agent) from a contributor's
// pushed branch instead of the trusted default-branch copy. It is read
// ONLY from the trusted default-branch copy of .no-mistakes.yaml (never
// the pushed SHA), so a contributor cannot self-enable. Default false:
// the pushed branch controls nothing that executes.
AllowRepoCommands bool `yaml:"allow_repo_commands"`
// PR carries pull-request routing settings. BaseBranch controls where a PR
// lands, so EffectiveRepoConfig treats it as trusted-only unless the
// repository explicitly opts into pushed settings.
AutoFix AutoFixRaw `yaml:"auto_fix"`
CI CIRaw `yaml:"ci"`
Commit CommitRaw `yaml:"commit"`
Intent IntentRaw `yaml:"intent"`
Test TestRaw `yaml:"test"`
PR PRRaw `yaml:"pr"`
// Document carries the repository's documentation placement policy. It
// steers the document step's gate prompt, so it is honored ONLY from the
// trusted default-branch copy of .no-mistakes.yaml (see
// EffectiveRepoConfig): a contributor's pushed branch must not be able to
// weaken documentation rules for its own review.
Document DocumentRaw `yaml:"document"`
// Review carries the repository's review-step settings. Its
// path_instructions steer the review gate prompt, so they are honored
// ONLY from the trusted default-branch copy of .no-mistakes.yaml (see
// EffectiveRepoConfig), regardless of allow_repo_commands: a contributor's
// pushed branch must not be able to inject or weaken the guidance that
// reviews it.
Review ReviewRaw `yaml:"review"`
// DisableProjectSettings opts the repository out of loading project-level
// agent settings/instructions (AGENTS.md/CLAUDE.md and the equivalent
// per-harness project settings) into gate agents. It exists for
// agent-orchestration repos (e.g. firstmate) whose project instructions
// would otherwise install a fleet-captain identity on a gate agent. It is a
// SECURITY boundary honored ONLY from the trusted default-branch copy of
// .no-mistakes.yaml (see EffectiveRepoConfig and the daemon's
// assertGateTrustedConfigReadable): a contributor's pushed branch must not be
// able to turn it off (or on). Default false; a plain bool so a missing key
// or a YAML/JSON null is falsy and preserves current loading.
DisableProjectSettings bool `yaml:"disable_project_settings"`
// NoCI declares that this repository intentionally has no CI. When true and
// the forge reports zero checks, the CI monitor treats that empty result as
// all-checks-passed. It is a readiness boundary honored ONLY from the trusted
// default-branch copy of .no-mistakes.yaml (see EffectiveRepoConfig): a
// contributor's pushed branch must not self-declare no-CI and bypass checks.
// Default false - absence means CI is expected, and an unproven empty check
// list remains not-ready regardless of elapsed time. If checks still appear,
// their actual states are processed normally; the declaration never waives a
// registered pending or failing check. No inference from workflow files,
// prior history, branch names, or grace-period expiry.
NoCI bool `yaml:"no_ci"`
}
RepoConfig represents .no-mistakes.yaml in a repo root.
func EffectiveRepoConfig ¶ added in v1.30.2
func EffectiveRepoConfig(pushed, trusted *RepoConfig, allowRepoCommands bool) *RepoConfig
EffectiveRepoConfig returns the repo config that should drive the pipeline given a pushed-branch copy and the trusted default-branch copy.
The code-executing selection fields - Commands (run verbatim via sh -c on the daemon host) and Agent/Agents (select which processes launch with the maintainer's credentials, including fallback lists and acp: targets) - are taken only from the trusted copy when it is present, so a contributor's pushed branch cannot inject shell or pick an agent. Document (the documentation placement policy injected into the document gate prompt) is trusted-only for the same reason: a pushed branch must not weaken the documentation rules that gate itself. Review (the path-scoped guidance injected into the review gate prompt) is trusted-only for the same reason: a pushed branch must not steer the reviewer that gates it. DisableProjectSettings is also trusted-only so a pushed branch cannot enable or defeat the gate-agent project-instruction boundary. NoCI is trusted-only so a pushed branch cannot self-declare no-CI and bypass its own checks, and CI (the transient-rerun budget) is trusted-only because every rerun it authorizes is another provider-side workflow run billed to the repository. These gate-control fields ignore allowRepoCommands. PR is the explicit exception: the allowRepoCommands opt-in also permits a pushed PR target because it controls where a maintainer-authorized PR lands, not code execution. When allowRepoCommands is true the maintainer has explicitly opted in (via allow_repo_commands on the TRUSTED default-branch copy) to honoring the pushed branch's commands and agent selection. When there is no trusted copy and the maintainer has not opted in, both fields are forced empty (Agent "" and nil Agents inherit the global agent; Commands{} yields built-in defaults) rather than falling back to the pushed branch - this blocks the supply-chain vector for repos that ship .no-mistakes.yaml only on feature branches.
Non-executing fields (ignore patterns, auto-fix, commit, intent, test) are always taken from the pushed copy, matching prior behavior, since they cannot run arbitrary shell, select a process, or spend the maintainer's CI minutes. The single exception inside test is evidence.branch, which names a git ref the daemon pushes to and is therefore trusted-only.
func LoadRepo ¶
func LoadRepo(dir string) (*RepoConfig, error)
LoadRepo reads per-repo config from dir/.no-mistakes.yaml. Returns zero-value config if file doesn't exist.
func LoadRepoFromBytes ¶ added in v1.30.2
func LoadRepoFromBytes(data []byte) (*RepoConfig, error)
LoadRepoFromBytes parses per-repo config from raw YAML bytes. It is the trusted-config entry point: callers that read .no-mistakes.yaml from a specific git ref (e.g. the default branch) use this to avoid honoring a contributor's checked-out copy.
func (*RepoConfig) UnmarshalYAML ¶ added in v1.34.0
func (c *RepoConfig) UnmarshalYAML(value *yaml.Node) error
type Review ¶ added in v1.44.0
type Review struct {
PathInstructions []PathInstruction
}
Review is the resolved review-step config. PathInstructions come from the trusted default-branch repo config and scope extra review guidance to the changed paths each glob matches.
type ReviewRaw ¶ added in v1.44.0
type ReviewRaw struct {
// PathInstructions scope extra review guidance to the paths a change
// actually touches. The review step appends the blocks whose glob matches
// at least one changed file; a run that touches nothing matching leaves
// the review prompt exactly as it is without this setting.
PathInstructions []PathInstruction `yaml:"path_instructions"`
}
ReviewRaw is the YAML representation of review-step settings.
type Test ¶ added in v1.23.0
type Test struct {
Evidence Evidence
}
Test is the resolved test-step config.
type TestRaw ¶ added in v1.23.0
type TestRaw struct {
Evidence EvidenceRaw `yaml:"evidence"`
}
TestRaw is the YAML representation of test-step settings.