Policy & risk
Each repo’s .openloop/policy.yaml defines what agents may touch and how much autonomy they get. It is the contract between you and the loop, and it’s meant to be committed and code-reviewed like any other config.
The file
Section titled “The file”scope: allowGlobs: [] # if non-empty, changes must match at least one denyGlobs: [] # hard blocks, always enforced highRiskAreas: [] # touching these escalates the task's risk
riskClasses: low-risk: autoMergeAllowed: true requiresHumanReview: false medium-risk: autoMergeAllowed: false requiresHumanReview: true high-risk: autoMergeAllowed: false requiresHumanReview: true
selfHealing: enabled: true allowedTaskKinds: - lint-fix - type-fix - localized-test-fix
promotion: lowRiskMode: auto-merge mediumRiskMode: pull-request highRiskMode: pull-requestScope enforcement
Section titled “Scope enforcement”Scope is checked in two places:
- Before the run: the scheduler checks the task’s planned scope against
denyGlobsandhighRiskAreas. Denied work is blocked; risky areas escalate the risk class (and therefore the promotion mode). - After the run: with review enabled, the actual diff is compared against the globs. Drift outside allowed paths is a blocking finding and downgrades the promotion.
Globs are gitignore-style patterns:
scope: allowGlobs: - "src/**" - "tests/**" denyGlobs: - "infra/**" - ".github/workflows/**" highRiskAreas: - "src/auth/**" - "migrations/**"Tasks can additionally carry their own scope.paths (see tasks); the intersection applies.
Risk classes
Section titled “Risk classes”Risk decides two things: whether a task needs approval before running (requiresHumanReview puts it in awaiting-approval) and how its output may be promoted (autoMergeAllowed). The defaults encode one opinion you can reshape:
- low-risk: docs, comments, small fixes within allowed paths → may auto-merge with green validations.
- medium-risk: the default for new tasks → pull request.
- high-risk: auth, infra, migrations → pull request and explicit approval first.
Tasks whose scope doesn’t match any configured area get risk.defaultUnknownAreaClassification from project.json (default medium-risk), unknown means cautious.
The self-healing allowlist
Section titled “The self-healing allowlist”Unattended self-repair is restricted to the kinds in selfHealing.allowedTaskKinds. The defaults (lint-fix, type-fix, localized-test-fix) let the daemon clear small breakages on its own; anything else (a broken build, failing integration tests) is deliberately blocked from running unattended and surfaces for human review instead.
requirePolicyForAutoMerge
Section titled “requirePolicyForAutoMerge”With risk.requirePolicyForAutoMerge: true (default in project.json), auto-merge additionally requires a non-empty policy to exist. A repo without deliberate scope policy never merges autonomously.